503 Commits

Author SHA1 Message Date
5f34f1baaa Tagged 1.60 2006-07-19 20:28:23 +00:00
dc5e458d9e Updated installer script to 1.60 2005-09-22 07:06:28 +00:00
4feaa1449f Fixed bug in Makefile 2005-09-22 06:34:58 +00:00
25002f559a Fixed bad compiler build (oh my god, linux sucks) 2005-09-22 06:16:45 +00:00
41f38424ee Fix for linux 64bit filenames 2005-09-22 05:12:23 +00:00
862ee2029a Bumped version 2005-09-22 03:42:43 +00:00
cd30fb0c1c Bumped version numbers 2005-09-22 02:23:13 +00:00
59ad6c49e3 Bumped version 2005-09-22 02:14:21 +00:00
2d255829a6 bumped version 2005-09-22 02:13:45 +00:00
be762580b7 Bumped versions 2005-09-22 02:13:23 +00:00
ae8bf10746 Fixed bug at18021 (hondaman)
Fixed bug at18924 (Arnold)
2005-09-18 03:26:26 +00:00
324f4c58a8 cleaned revision for cstrike plugins 2005-09-18 03:19:34 +00:00
a816767abb Fixed bug at18919 2005-09-18 02:59:36 +00:00
164a47bde4 Import of windows version 2005-09-18 01:25:22 +00:00
545769e241 Bumped version number 2005-09-18 01:15:03 +00:00
dcf39196d5 Ugly hack to get around ELF garbage 2005-09-18 01:14:44 +00:00
58dd553d00 Loads from non-cwd now 2005-09-18 01:14:23 +00:00
f64ca6a827 Stupid ugly hack to get around ELF's garbage
Import of newer compiler
2005-09-18 01:13:18 +00:00
ebd4974c75 final cleaned revision (I hope) 2005-09-16 23:48:51 +00:00
4b1769f457 Added feature request at18988 2005-09-15 17:53:02 +00:00
f58c0f4508 added request for EKS at18961 2005-09-15 00:51:27 +00:00
4d7bdcde47 Fixed configs not being copied on Linux 2005-09-14 03:41:20 +00:00
c7a620424e *** empty log message *** 2005-09-14 02:38:19 +00:00
24260137ec hope to have fixed the spacings finally 2005-09-14 01:40:48 +00:00
315e69797d more fixes 2005-09-14 00:42:56 +00:00
dddc693369 Fixed spacing 2005-09-14 00:38:48 +00:00
13e654aafe small format changes 2005-09-13 16:05:57 +00:00
f02c73f94c Correct spacing! 2005-09-13 07:37:50 +00:00
92f79ffe88 left debug stuff in 2005-09-13 07:36:01 +00:00
db33e50f92 Fixed a bug where stocks using native names crashed 2005-09-13 07:32:07 +00:00
2ad557024e more cleanups 2005-09-13 01:00:19 +00:00
ddf3b6df32 new cleaned-up version of the plugins (no more OLOcode :D) 2005-09-12 21:06:24 +00:00
12bf140931 Fixed a small save bug 2005-09-12 16:08:45 +00:00
0d65bb64f9 Updated for latest version 2005-09-11 20:54:03 +00:00
c6e265b414 little changes 2005-09-11 20:35:35 +00:00
9ba597b5c1 Fixed bug at18791 (Maddo) 2005-09-11 19:15:49 +00:00
b6a4514bd0 Fixed bug at18763 (karlos) 2005-09-11 18:57:33 +00:00
a6daebe7d4 Made SQL changes by Lazarus Long 2005-09-11 18:37:55 +00:00
471ba0adbf Updated FTP function (now handles misunderstood SITE CHMOD commands) 2005-09-11 15:45:42 +00:00
7225aa3cc0 Fixed font bug 2005-09-11 14:32:16 +00:00
88b833f879 Updated version to 1.60 2005-09-11 11:52:19 +00:00
6f8816c13f Fixed another shortcut bug
Released 1.2
2005-09-11 11:15:22 +00:00
95ccd6078c Fixed bug at18607 (lantz69) 2005-09-11 07:19:06 +00:00
2e5c71f771 Fixed bug at18607 (lantz69) 2005-09-11 07:17:31 +00:00
eeb77395cd Fixed bug at18615 (Lazarus Long) 2005-09-11 07:13:44 +00:00
e3afe22a48 Fixed initialization bug in native filters
Fixed bug where address boundaries were not checked on arrays
2005-09-11 05:43:17 +00:00
73d70aff29 added module_exists 2005-09-11 04:43:40 +00:00
120c849e4b Added native filter 2005-09-11 04:32:40 +00:00
138b732e75 New plmenu 2005-09-11 04:31:13 +00:00
760e29e531 Finalized new debugging system 2005-09-11 03:58:38 +00:00
401ee3c97f Added another function or something 2005-09-11 03:55:48 +00:00
6e52ce7678 New natives 2005-09-11 03:13:45 +00:00
89aab62549 Removed them from AMXX-Studio 2005-09-10 21:58:40 +00:00
468d99ff70 Updated about dialog
Updated a few plugin commands
Removed splashscreen
Added some themes
Updated some captions
2005-09-10 21:55:22 +00:00
2d787f43de updated version of CString.h 2005-09-10 21:04:05 +00:00
f0c5e44985 fixed plugin location comments on stat plugins
replaced 0.20 with AMXX_VERSION_STR
removed all require_modules
2005-09-10 20:51:49 +00:00
76760b221d more cleaned-up code 2005-09-10 20:09:14 +00:00
612a86dbef Added new debugging functions 2005-09-10 18:26:13 +00:00
369ece2d56 ----------------------------------------------------------------------
Linux compatibility problem in debugger.cpp, made Makefile also compile
debugger.cpp
2005-09-10 18:19:02 +00:00
cc37f479aa Added Phase 3 of the debugger (debug tracing from plugins) 2005-09-10 07:24:26 +00:00
deaaf20713 Fixed preproc bugs 2005-09-10 05:30:24 +00:00
e566413224 Fixed MORE lines 2005-09-10 05:23:30 +00:00
368856f122 Fixed lines 2005-09-10 05:22:06 +00:00
52cc204787 Fixed numerous bugs in preprocessor (string literals being parsed, mismatched args being wiped) 2005-09-10 05:04:23 +00:00
52b1d67ca2 latest cleaned files for today (i cant read more :o ) 2005-09-10 03:39:23 +00:00
16ad8739e7 started the clean-up of cpp files 2005-09-10 00:59:24 +00:00
e67457440d cleaned-up versions of header files 2005-09-10 00:38:42 +00:00
fc955009da cleaned-up version of ccmd.h 2005-09-09 23:54:15 +00:00
0dc2ba85e8 Added set_error_filter() 2005-09-09 23:13:34 +00:00
de65e65854 added set_error_filter 2005-09-09 23:03:26 +00:00
d95f2cba37 Fixed another small shortcut bug
Updated "Select color" dialog
Removed "Do not restore caret" property, not useful
2005-09-09 23:01:09 +00:00
e2a521583a Fixed shortcut bugs
Fixed include bug
Changed a few small things in the core
2005-09-09 16:49:41 +00:00
f8aac5e88d Reworked code to support error handling, LogError() is separate from DisplayTrace() implementation 2005-09-09 16:04:44 +00:00
4738c92b8e Committed new debugger with AMX fixes 2005-09-09 03:23:31 +00:00
7ce59966fc Replaced with faluco's cleaned-up version of meta_api.cpp 2005-09-08 22:20:27 +00:00
afa1337e62 because gabe doesn't rollover, he just expands 2005-09-08 15:29:31 +00:00
cc34f468f0 Added a new math stock function. 2005-09-08 15:24:28 +00:00
3f9598fcbb Changed .amx in examples for pause() and callfunc_begin() to .amxx (as requested by XxAvalanchexX on the forums) 2005-09-08 13:05:44 +00:00
97b5391118 Logs the map name on mapchange (as requested by lantz69 on forums) 2005-09-08 13:03:38 +00:00
227c13d12c Added abs(x) stock 2005-09-08 12:58:17 +00:00
729932476b Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:31:31 +00:00
7c21deb0f2 Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:20:28 +00:00
80048eba61 Fixed memory leak
Updated Modified-Event (now only one parameter [the modified text])
2005-09-07 22:10:21 +00:00
0552e5ef58 Deprecated jghg2 include 2005-09-07 15:40:46 +00:00
ce881a7d30 Fixed bug at18558 (Nijule) 2005-09-07 00:11:10 +00:00
80dd7f034d version bump 2005-09-06 22:28:47 +00:00
5fac746feb compiler fix merge 2005-09-06 22:28:32 +00:00
67f012b74a Fixed bug where static declarations would crash 2005-09-06 21:34:33 +00:00
5705e69abb Fixed bug where level>1 arrays were walked incorrectly 2005-09-06 20:36:02 +00:00
bece1e6d0c Added float_to_str and str_to_float natives 2005-09-06 16:34:17 +00:00
f2527ecc86 The query_client_cvar native now checks for a non-zero g_engfuncs.pfnQueryClientCvarValue before proceeding 2005-09-06 16:31:54 +00:00
66b95f64a5 Now checks whether there is a non-zero g_engfuncs.pfnQueryClientCvarValue before setting newdll's pfnCvarValue function pointer 2005-09-06 16:31:07 +00:00
af79fe8e20 Added natives str_to_float and float_to_str; indents are now tabs 2005-09-06 16:29:27 +00:00
d3e2bad4e7 Added query_client_cvar native 2005-09-06 10:14:32 +00:00
6bebf37f1a An optional array parameter (LIKE TEH TASKS ONE) can be now passed to cvar query handlers 2005-09-06 10:12:02 +00:00
2f27b7da8d zomg! updated teh vectorz codeses a bit! Hopefully didn't break anything 2005-09-06 09:34:13 +00:00
824caab2c5 Fixed bug p1123143748 (Twilight Suzuka) 2005-09-06 03:00:01 +00:00
a105bc7402 Fixed bug at18003 (Geesu)
Fixed bug p1123149221 (Twilight Suzuka)
2005-09-06 01:55:41 +00:00
81ab33d794 Fixed shortcut bug in the settings dialog (couldn't set hotkeys to BkSp etc.)
Added "Reset" button to shortcuts page
2005-09-05 22:33:45 +00:00
e90364c17b Fixed bug at18525 (twistedeuphoria). 2005-09-05 22:05:23 +00:00
ac4014ff5a Fixed bug at18473 (Greenberet). 2005-09-05 21:59:44 +00:00
ad634924fa Fixed two bugs from at18519 (Lord of Destruction) 2005-09-05 21:43:05 +00:00
2d5f9ba181 Using the (*g_engfuncs.pfnQueryClientCvarValue) directlty instead of the macro so that it compiles on both metamod and metamod-p 2005-09-05 20:51:24 +00:00
aa0e4e121e Now properly cleaning up pending client cvar queries in the queue on client disconnect 2005-09-05 19:56:40 +00:00
f8227a09b4 updated to September 2005-09-04 22:40:43 +00:00
46130a6754 *** empty log message *** 2005-09-04 13:25:24 +00:00
58c006a9c8 Ready for release (1.1) 2005-09-04 13:03:34 +00:00
ea1d72401c Fixed switch bug, now even (much) faster
Updated aboutbox
2005-09-03 23:47:40 +00:00
fdbe0e2064 Upgraded plugin-system (other command call and now 93 commands)
Customizable IRC Paster
Updated version number from 1.01 to 1.1
2005-09-03 20:00:46 +00:00
e239801671 fixed get_map_info function 2005-09-03 13:59:33 +00:00
4be88a5015 version bump 2005-09-02 07:10:56 +00:00
ee02d0b13d this must be off! 2005-09-02 04:07:49 +00:00
2ec084ffa3 Patch for bug at18251 2005-09-02 04:06:47 +00:00
6636c20336 Fixed bug at18250 2005-09-02 03:44:15 +00:00
27c80b00f8 Fix for bug at18293. 2005-09-02 03:28:44 +00:00
6bcb72952c Applied patch for bug at18341 (jtp10181) 2005-09-02 02:46:42 +00:00
8c17be27dd Updated AMXx version 1.56 2005-09-01 17:11:48 +00:00
0232b0abee Bumped versions 2005-08-31 20:36:41 +00:00
12fd7a9f0d Added new DBI functions
Fixed bugs in field getting
2005-08-31 20:32:29 +00:00
71c6e70706 Updated for new API 2005-08-31 20:08:12 +00:00
c5cc94ba98 Added new natives 2005-08-31 04:36:25 +00:00
8220cc4c01 is_in_viewcone from in_view_cone 2005-08-30 23:22:27 +00:00
57ce74c4c7 Bumped version, lowered -O flag 2005-08-30 18:43:11 +00:00
5d6c72bf42 Patch for pausing issues 2005-08-30 07:18:47 +00:00
63b2bbc67e Made more de-allocation safety precautions 2005-08-30 07:15:27 +00:00
12f628e3d7 Fixed bug at18162 (vittu) 2005-08-30 07:00:49 +00:00
cd8d800eb7 Fixed bug at17920 (Grasshoper) 2005-08-30 06:59:50 +00:00
160ab3572b Fixed typo at18108 (FireStorm) 2005-08-30 06:57:41 +00:00
dc57ef1e0c Simple implementation for cvar queries 2005-08-27 23:00:44 +00:00
ca1544564c Upped to 3.2.5. 2005-08-27 21:27:35 +00:00
462916d00f Got rid of many annoying warnings MSVC7.1 was reporting 2005-08-27 09:55:32 +00:00
e15761b79a Updated plugin system 2005-08-27 01:47:15 +00:00
270d898f82 Fixed shortcut bug 2005-08-26 23:22:30 +00:00
2a2d5697b8 Fixed some bugs
Upgraded exception handler, now using madCollection
2005-08-26 22:59:25 +00:00
b17f277a1b Added AMXX-Studio to CVS 2005-08-26 19:07:54 +00:00
c15ed5741a Added AMXX-Studio to CVS 2005-08-26 18:53:19 +00:00
9e035dc744 Added AMXX-Studio to CVS 2005-08-26 18:29:39 +00:00
ac279b37e4 Removed old Makefile 2005-08-26 15:57:50 +00:00
974fdc950e Added new standard makefile 2005-08-26 15:54:42 +00:00
8bb01423b9 Updated api 2005-08-25 09:40:29 +00:00
401a23a298 Updated install script 2005-08-25 09:34:31 +00:00
7ac9ed4b80 *** empty log message *** 2005-08-25 09:27:32 +00:00
6fdcd8ffae Fixed NS build 2005-08-25 09:20:10 +00:00
d50a6302e0 ugh 2005-08-25 09:09:35 +00:00
5fd891bc32 Fixed version # 2005-08-25 08:34:26 +00:00
864f7c268e Fixed module for AMD64 2005-08-25 08:34:09 +00:00
4770f28a18 *** empty log message *** 2005-08-25 08:26:28 +00:00
51a4e2bf4e *** empty log message *** 2005-08-25 08:21:07 +00:00
c213c771d2 Fixed compression on Linux 2005-08-25 08:20:11 +00:00
0176d3a2ae Actual fix for compression! 2005-08-25 08:02:48 +00:00
92653ceebc Fixes for compression 2005-08-25 07:50:21 +00:00
c9051ad364 Fixed includes 2005-08-25 07:34:47 +00:00
94d350118d *** empty log message *** 2005-08-25 07:30:34 +00:00
2e22dde409 Removed extra forwards 2005-08-25 07:16:17 +00:00
4dad81af30 Merged in new ts includes 2005-08-25 07:13:48 +00:00
b271b01b13 Synced to Twilight's stuff 2005-08-25 07:12:52 +00:00
a17b879380 Merged in original TSFun 2005-08-25 07:09:16 +00:00
ea05af9fe8 updated to August 2005-08-25 01:15:30 +00:00
d661196429 Fixed bug at17860 2005-08-25 00:19:39 +00:00
1114443a43 Fixed for AMD64 compatibility 2005-08-24 18:13:40 +00:00
d802a3c961 gcc-3. compat 2005-08-24 07:32:01 +00:00
e2226ae809 Fixed linux compiling 2005-08-24 07:16:45 +00:00
fd8a27013b CVS Cleanup 2005-08-24 07:07:34 +00:00
b12224eabd CVS Cleanup 2005-08-24 07:01:02 +00:00
c30c3cf35c CVS cleanup 2005-08-24 06:57:32 +00:00
f828cde999 Updated ESF and CS 2005-08-24 06:56:02 +00:00
d05c381789 Added cstrike specific switch 2005-08-24 06:39:52 +00:00
245054cf48 Fixed bug at17739 (mysticssjgoku4) 2005-08-24 06:29:12 +00:00
da82ce757f Defaulted engine+fm on 2005-08-24 06:19:41 +00:00
4d74743138 Removed esf module 2005-08-24 06:15:41 +00:00
c1db39d086 Added Corona Byte's EvolutionX core 2005-08-24 06:13:55 +00:00
d516824936 Add copy exclusion filters
Repaired windows builder
Fixed /build to be /rebuild
2005-08-24 05:19:23 +00:00
10328f5f81 fixes 2005-08-24 05:08:05 +00:00
d4f09aac74 Wrong, look at the distro. And in the future change for all mod config sets if you do 2005-08-24 03:20:09 +00:00
8f97ed7934 Deleted bad file 2005-08-24 03:14:13 +00:00
1fcf7628a3 Added in real file 2005-08-24 03:13:57 +00:00
bdd740f8ab Added makefile 2005-08-24 02:54:39 +00:00
82fed37247 Updated to work on Linux, redesigned core 2005-08-24 02:53:38 +00:00
5b208eb9f5 gcc-3 compat 2005-08-24 02:36:05 +00:00
9be88ffa42 Linux compat, cleaned up newdll 2005-08-23 23:54:54 +00:00
f54d112bbb Language sync 2005-08-23 01:24:42 +00:00
96c4d33da4 - Updated to Sqlite 3.2.3. See sqlite.org for details about new stuff.
- Base dir for db files is now changed to the game mod dir. Update your config files!
2005-08-22 10:12:22 +00:00
bad4c02647 This file copied from mysql module... I assume this was forgotten during the last commit of amxxmodule.cpp... 2005-08-22 09:18:55 +00:00
70140ffc8f Fixed team menu. Should now work 100% to switch players between teams. However when client uses VGUI menus I haven't been able to close the class selecting window. It is (should be) only a cosmetic flaw though. 2005-08-22 08:01:01 +00:00
53e6bb6b50 No default sql 2005-08-22 01:04:41 +00:00
4cb7986426 admin.sma was "slightly" incompatible for people using sqlite. This version is courtesy of Lazarus Long who fixed this. Thanks. 2005-08-22 00:26:18 +00:00
18ba13be84 Removed the admin_sql.amxx line. It's all in admin.sma now, isn't it??? 2005-08-22 00:21:49 +00:00
dd371c4dbe no idea, I changed something though 2005-08-21 22:48:22 +00:00
7ea47c5a96 Fixed a deallocation mismatch with debug plugins in linux 2005-08-21 21:54:14 +00:00
5693d2629e Attempted fix at DEP 2005-08-21 19:30:27 +00:00
24d9e3266e wrong include, added pdata 2005-08-21 16:38:45 +00:00
b3b3ce4c2d added more pdata funcs 2005-08-21 16:36:40 +00:00
5882802a3e Added set/get pdata string 2005-08-21 16:33:38 +00:00
94e19aae0c Removed newdllfunc() and related NEWDLLFunc_* stuff. :-P (yes I finally read Alfred's post through) 2005-08-18 20:51:41 +00:00
7d51404aeb What!!! 2005-08-18 15:47:28 +00:00
1cdb12c4e4 Added NEW_DLL_FUNCTIONS to FM_* and a newdllfunc() native to call these... Although I'm not sure there is a reason to call those?
Anyway it will be needed later when client cvar query function is implemented.
2005-08-18 09:33:51 +00:00
e9993cce25 amd64 == no more libstdc++ 2005-08-18 08:44:01 +00:00
80bd845182 *** empty log message *** 2005-08-18 08:36:48 +00:00
f986202b06 AMD64 no stdc++ support 2005-08-18 08:33:21 +00:00
a4168a2096 version bump 2005-08-18 07:53:14 +00:00
3e85589930 Fix for bug at16876 (TheRising) 2005-08-18 07:05:33 +00:00
b5a57da29c Fixed linux build (I think) 2005-08-18 07:03:43 +00:00
58fec512e5 Now requires GCC-3 to compile, fixes retarded linking problem 2005-08-18 07:01:47 +00:00
a6ca045086 More SDK syncs 2005-08-18 06:41:59 +00:00
e401231d25 *** empty log message *** 2005-08-18 06:40:24 +00:00
9ddc24898f same win32 fix 2005-08-18 06:37:50 +00:00
f5350c0e0e fix for win32 2005-08-18 06:37:05 +00:00
fa64bef511 New SDK for gcc-3 compilations 2005-08-18 06:34:34 +00:00
29bfd81b36 New SDK for gcc-3 compilation 2005-08-18 06:32:59 +00:00
2d2506f1c4 Added memalign include 2005-08-18 01:04:52 +00:00
f334fec0a3 Added linux compile of altered JIT 2005-08-18 00:32:08 +00:00
03b6d3e77d Fixed alloc/dealloc mismatches 2005-08-18 00:29:43 +00:00
661f6c9851 Fixed bug at17357 (FireStorm) 2005-08-17 18:16:26 +00:00
593e013572 fixed typo 2005-08-17 17:53:11 +00:00
b04498cddb Experimental fix for bug at16815 (karlos) 2005-08-17 17:32:51 +00:00
8648bf32a3 Improved error reporting a bit 2005-08-17 17:21:57 +00:00
1768ae4b23 Fixed bug at17117 (Twilight Suzuka) 2005-08-17 17:07:41 +00:00
80e6d31998 updated sdks 2005-08-17 16:52:12 +00:00
381e331dda updated sdk 2005-08-17 16:50:01 +00:00
13c65f006b SDK no longer manages memory by default 2005-08-17 16:48:31 +00:00
4e8eff3e04 Fixed bug at17021. 2005-08-17 16:41:38 +00:00
572ad38366 Quick fix for bug at16854 (twistedeuphoria) 2005-08-17 16:16:56 +00:00
b2ade117ec Added bug fix at17218 (Freecode) 2005-08-17 16:12:45 +00:00
9eb36bd2bb Fixed bug where first call had wrong stack alignment
Tiny optimizations
2005-08-17 15:57:11 +00:00
85b7ac740b Experimental JIT fixes for linux crashing (no more xchg of esp) 2005-08-16 23:09:55 +00:00
98d3fb79d7 Fixed some mmgr bugs 2005-08-15 21:38:03 +00:00
bf092b4f95 Updated to Sqlite 3.2.2. 2005-08-11 19:06:54 +00:00
a4a9613f5b *** empty log message *** 2005-08-11 02:49:58 +00:00
ad86bf636f enabled statsx by default 2005-08-10 18:37:02 +00:00
d0b5886d7d Added cs_get_armoury_type and cs_set_armoury_type 2005-08-07 20:43:29 +00:00
aa75a143fc This should fix the problem where bots can't hit players using weapons other than the knife. 2005-08-07 13:38:34 +00:00
7144f5c794 updated error handler 2005-08-04 23:46:22 +00:00
befb651268 fixed design bug (adds now Skipped when file is skipped)
fixed ESF install bug (didn't install, invalid pathes)
2005-08-03 18:45:16 +00:00
c8fdea6216 Fixed bug found by T(+)rget 2005-08-03 16:33:52 +00:00
4a6a16c627 NADE_CATCHED changed to NADE_CAUGHT 2005-08-03 15:01:54 +00:00
6256687272 bumped 2005-08-03 01:54:16 +00:00
5be9ba4a68 Fixed esf 2005-08-03 01:17:27 +00:00
8f61073f43 Updated installer script 2005-08-03 01:14:17 +00:00
a973adb4f2 added library 2005-08-02 20:00:29 +00:00
96c9fc8bc8 Changes for linux compatibility 2005-08-02 19:05:51 +00:00
d472d5d309 Slightly buggy but acceptable for linux >:\ 2005-08-02 19:05:38 +00:00
a819a494b8 ugh, amd64-32 compat 2005-08-02 18:37:59 +00:00
f2c3dfa874 added AMXX_VERSION_NUM 2005-08-02 14:06:17 +00:00
fe3645d809 More gcc-3 whining 2005-08-02 11:51:31 +00:00
b9ff24171f AMD64+gcc-3 complains otherwise 2005-08-02 11:43:26 +00:00
59fb0a39b2 added desc box 2005-08-02 11:40:46 +00:00
94202eec34 tl sync 2005-08-02 11:38:57 +00:00
ef8715892b More hax 2005-08-02 11:19:56 +00:00
e5ce86d61a gaben 2005-08-02 11:19:08 +00:00
7825364e06 hax 2005-08-02 11:15:15 +00:00
5cba645e49 latest sdk 2005-08-02 11:13:23 +00:00
ef4d04a7e1 *** empty log message *** 2005-08-02 11:12:42 +00:00
0302803f38 rebuild jic 2005-08-02 10:37:23 +00:00
d57004c91f *** empty log message *** 2005-08-02 10:26:51 +00:00
f5fe076ec1 oops that was win32 2005-08-02 10:18:09 +00:00
7eaa8a1a39 Added makefiles, fixed template bug in nvault 2005-08-02 09:48:06 +00:00
de5abef49a New makefiles 2005-08-02 09:30:50 +00:00
edd9fa2879 New makefiles. 2005-08-02 09:29:14 +00:00
0686da47a6 Fixed crash bug 2005-08-02 08:39:17 +00:00
4f9f548a58 yasm -f elf -m amd64 -g stabs 2005-08-02 08:29:02 +00:00
2d79c6e634 *** empty log message *** 2005-08-02 08:23:36 +00:00
ad6c7d412a *** empty log message *** 2005-08-02 08:15:01 +00:00
686dadc9c5 New makefile 2005-08-02 08:12:47 +00:00
70bff9c430 Fixed AGAIN! 2005-08-02 08:10:04 +00:00
cefad23b72 new makefile 2005-08-02 08:06:28 +00:00
0447c39a97 forgot this 2005-08-02 07:53:59 +00:00
688c12ac8b fixed two bugs 2005-08-02 07:46:41 +00:00
5cbcd34bec update 2005-08-02 07:17:12 +00:00
f9563b5103 *** empty log message *** 2005-08-02 07:07:35 +00:00
38da105ac1 Few changes 2005-08-02 07:01:25 +00:00
cc393d0e8d committed C# releaser 2005-08-02 06:28:41 +00:00
25cbe60bf8 fixed metamod plugins.ini bug 2005-08-02 02:56:09 +00:00
6be3805841 ready for release 2005-08-01 23:25:02 +00:00
6e3de2c53a *** empty log message *** 2005-08-01 22:34:33 +00:00
cf274f7f50 changed project name 2005-08-01 22:33:28 +00:00
17cca4587c Fixed small bug 2005-08-01 22:29:19 +00:00
3014e60bdb Added TSFUN include 2005-08-01 22:21:47 +00:00
e5b4b5a53d Initial import of twilight's module 2005-08-01 22:14:14 +00:00
bc66a93fcf the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
- updated captions
- fixed configs-bug (configs weren't uploaded during FTP installations)
2005-08-01 21:54:28 +00:00
8f06e36d04 fixed a few bugs 2005-08-01 20:54:41 +00:00
e38b64ff82 yams 2005-08-01 20:22:01 +00:00
4687ecd99b Committed hopefully final version 2005-08-01 19:56:54 +00:00
b1718bc334 added cs_user_spawn 2005-08-01 19:25:25 +00:00
d7063435f4 added cs_user_spawn (thanks T(+)rget) 2005-08-01 19:24:48 +00:00
a7133501d5 Fixed comments 2005-08-01 19:05:10 +00:00
5078ed9d0f changed on advice from target 2005-08-01 19:01:25 +00:00
424a8c17b3 *** empty log message *** 2005-08-01 18:56:03 +00:00
90c0e32cb3 oops killed changes 2005-08-01 18:31:06 +00:00
d3acbcc319 (c) 2005-08-01 10:24:20 +00:00
a776e832dd New plugin file format, new zlib libraries 2005-08-01 09:02:52 +00:00
65bd10c47b Committed linux build of new compiler 2005-08-01 09:00:01 +00:00
9bdd0ba0a4 Windows build of new compiler 2005-08-01 08:51:26 +00:00
ff48a9076b *** empty log message *** 2005-08-01 08:50:14 +00:00
3f99ce7af5 New plugin file format 2005-08-01 08:47:54 +00:00
4451691aa2 Removed warning 219 2005-08-01 05:56:06 +00:00
bc64ae2712 name change 2005-08-01 05:15:57 +00:00
7f55873bfb Fixed name clash 2005-08-01 05:14:55 +00:00
d94016384a from the "check your changes to see if they compile" dept 2005-08-01 05:10:55 +00:00
eb87344a16 Fixed bug at16702, jtp10181 2005-08-01 05:06:40 +00:00
43c06b0e36 what 2005-08-01 05:03:50 +00:00
a35b96fb7e Finished correcting your stuff SidLuke 2005-08-01 04:55:55 +00:00
562633c040 SDK to update MF_AmxExec and add MF_AmxPush 2005-08-01 03:23:56 +00:00
71eac5c544 omg sidluke why was this using amxmod api still?!?! 2005-08-01 03:19:46 +00:00
4fe39dd5cc okay removed old forward stuff why was this defaulted?! 2005-08-01 03:05:53 +00:00
7605abc929 Updated for new API 2005-08-01 02:58:57 +00:00
0a4133b4d0 Added register_native 2005-08-01 02:36:09 +00:00
0086b58f39 Completed AMD64 compatibility 2005-08-01 02:23:42 +00:00
583b67dbb1 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
- updated captions
- fixed configs-bug (configs weren't uploaded during FTP installations)
2005-08-01 00:28:07 +00:00
a81f356835 *** empty log message *** 2005-08-01 00:25:47 +00:00
b2218661f8 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
- updated captions
- fixed configs-bug (configs weren't uploaded during FTP installations)
2005-08-01 00:24:40 +00:00
8234977fa9 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
- updated captions
- fixed configs-bug (configs weren't uploaded during FTP installations)
2005-08-01 00:19:25 +00:00
13ed6ed2d6 Touching up new system for linux support 2005-07-31 22:16:54 +00:00
a7fb4e85c9 Fixed bug where 64bit code was not browsed properly 2005-07-31 22:16:44 +00:00
abfca025d5 Committed new register_native system 2005-07-31 20:11:58 +00:00
34acc54cc9 Initial import of native hack for x86 2005-07-31 06:48:08 +00:00
b27eaab57f Initial import of new version :] 2005-07-31 06:07:48 +00:00
dd6c169994 Fixed c_str() 2005-07-31 06:04:42 +00:00
5751d381af Deleted old version 2005-07-31 06:03:54 +00:00
28998b5c14 initial import 2005-07-30 17:36:40 +00:00
a939cd0e2a added esf 2005-07-30 17:35:53 +00:00
d9d5446e86 updated 2005-07-30 17:34:07 +00:00
b91cc24d32 Finished 2005-07-30 17:33:49 +00:00
faae071ee8 version bump 2005-07-30 16:52:51 +00:00
cdbfa38391 some of the string functions twilight wanted 2005-07-30 16:47:48 +00:00
5d92972aad one more 2005-07-30 16:46:40 +00:00
ba17c8a75f version bump 2005-07-30 16:42:01 +00:00
389a593f9e ugh 2005-07-30 16:41:34 +00:00
b35e5dbd55 SDK sync, version bumps 2005-07-30 13:03:18 +00:00
0591c38d45 Updated SDK 2005-07-30 12:58:24 +00:00
041e73dc7e Updated notices 2005-07-30 01:52:50 +00:00
431eb72518 Updated twisty's code 2005-07-30 01:51:12 +00:00
75b63da66f Fixed output 2005-07-30 00:38:08 +00:00
51d54a96ff Added pc_printf to exports 2005-07-30 00:35:47 +00:00
df982ceb79 Fixed error output on compiler 2005-07-30 00:31:42 +00:00
ee978890b8 What? 2005-07-29 23:47:11 +00:00
fa46d2e1b5 Patched engine with non-constructing string 2005-07-29 21:30:52 +00:00
559d8bc7eb Quick patch for possible bug at15468 2005-07-29 20:23:08 +00:00
0d90a958ae Added request at16475
Fixed crash bug from bad allocation in construction
2005-07-29 20:15:08 +00:00
cb7bfbf642 Added request at16475 2005-07-29 19:37:07 +00:00
6cf6edb5b6 Fixed bug at16581, devicenull 2005-07-29 19:25:24 +00:00
b9ee99a3dc New plugin flags 2005-07-29 19:24:28 +00:00
a86302beea Changed function meaning 2005-07-29 19:20:59 +00:00
f6d647f614 Requested change at16639 2005-07-29 19:18:45 +00:00
32a42886dd Finished new menu system (for now)
Fixed bug where client_print did not add newlines properly
2005-07-29 19:13:55 +00:00
5b1d0dd2b9 removed old project file 2005-07-29 06:41:33 +00:00
166b5ca650 omg new menu system 2005-07-29 06:33:57 +00:00
044fa19470 Fixed bug where callfunc crashes 2005-07-29 06:12:23 +00:00
1d6b173e87 Fixed a bug where bad plugins could crash 2005-07-28 18:00:40 +00:00
eaf102d78f Fixed bug where JIT did not work on linux (memory alignment issues) 2005-07-27 19:43:54 +00:00
31436e3ecf Added linux compatibility 2005-07-27 17:28:06 +00:00
62cdaf5e10 Initial import of linux compiler builds 2005-07-27 17:27:20 +00:00
0de08a9452 Removed unused files 2005-07-27 17:00:57 +00:00
0de288139d Added linux support 2005-07-27 16:58:18 +00:00
94d3b31f40 Language sync for faluco :) 2005-07-27 16:32:39 +00:00
6d7442fb4f Fix for bug at8190 by faluco 2005-07-27 16:32:22 +00:00
68ad9c2b9a Ok makefile works on i386 now 2005-07-27 16:27:01 +00:00
191acd8e42 New Makefile, linux compatibility 2005-07-27 16:24:14 +00:00
ce043d0633 >:o 2005-07-27 00:51:35 +00:00
f18354807e Updated module SDK 2005-07-26 23:33:52 +00:00
6a97d73167 Committed brand new debugger system 2005-07-26 21:31:21 +00:00
586d09e533 I don't think I changed anything... 2005-07-26 21:30:35 +00:00
ba24020857 fixed amx_BrowseRelocate overwriting the flag state 2005-07-26 21:29:49 +00:00
4b9425cf3b Initial import of edited debug reader 2005-07-26 21:28:19 +00:00
ef2a9a2b34 Fixed switch case bug in JIT where no cases would crash 2005-07-26 21:28:04 +00:00
1a3a5331d1 *** empty log message *** 2005-07-26 18:47:11 +00:00
363e7e2270 updated to use amxxpc.exe 2005-07-26 18:45:37 +00:00
fdbee670c5 Uh, forgot... 2005-07-25 21:02:26 +00:00
a47ccb2a2a I'm high 2005-07-25 20:45:02 +00:00
9e46d2da47 WOW. 2005-07-25 20:39:58 +00:00
451a6d8464 PM STRIKES AGAIN (untested) 2005-07-25 19:09:49 +00:00
4abd7b4706 Now reads debug info correctly (cleaned some code up too) 2005-07-25 18:26:42 +00:00
09a08fd2f6 quick fixes before adding debugger again 2005-07-25 06:48:54 +00:00
4609cb409b Whoa! Merged in Pawn! (Small 3.0)
Removed debug handling (will add back in soon)
Ported all amx_Exec()s to forward systems
Deprecated AMX Mod module support (incompatible with Pawn anyway!)
Deprecated many file natives (unused)
Deprecated some functionality of pause/unpause
Fixed some memory deallocation bugs (thanks fysh)
Bumped module API version to 3 (no new M/SDK yet!)
Bumped AMX Mod X version to 1.5!
Merged in CVector changes
2005-07-25 06:03:43 +00:00
955aa04b41 Removed packed strings 2005-07-25 05:54:33 +00:00
69a5b5f410 Initial import of Pawn 3.0 compiler (win32) 2005-07-25 05:34:13 +00:00
b94fbb519a *** empty log message *** 2005-07-25 05:31:12 +00:00
832de07128 Removed Small compiler 2005-07-25 05:30:28 +00:00
f6b91f9258 Initial import of amxxpc 2005-07-25 00:01:54 +00:00
f9ca86cee6 *** empty log message *** 2005-07-25 00:01:50 +00:00
0ef9b80430 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...

hrm bail decided this will be AMX Mod X 1.5 so updated captions..
-> Basic-Master is now crazy o_><_O
2005-07-24 23:47:45 +00:00
057929e2f6 Fixed bug with sprintf widths 2005-07-24 22:42:34 +00:00
25d629083f Initial import of Pawn (Small 3.0) 2005-07-24 20:00:55 +00:00
c2502626e6 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
2005-07-24 19:27:36 +00:00
76505f172a fixed problems with wrong weapon id ( enfield & fg42 ) 2005-07-24 11:07:49 +00:00
79268c5316 ---------------------------------------------------------------------------
Fixed memory bug found by fysh
2005-07-24 07:06:25 +00:00
0c36613352 Deprecated file read natives until they can be rewritten 2005-07-24 03:23:35 +00:00
37a80e6ef6 Fixed bugs at8190, at16430 2005-07-24 02:52:15 +00:00
7fc97524e2 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
2005-07-23 21:25:25 +00:00
842813dcbb Fixed a few potential bugs, and set_msg_arg* no longer accepts type changes 2005-07-23 20:16:29 +00:00
9e194394c3 CVector fix - corrupt memory on size change 2005-07-23 16:58:10 +00:00
e188bf087a CVector fix - corrupt memory on size change
Version bumps
2005-07-23 16:57:21 +00:00
c5aae0d8aa little bug fix 2005-07-23 07:07:41 +00:00
25f1870020 the editor unindents now on pressing }. have fun!
- fixed bugs... lalala
- updated debug-list
- fixed comment-bug
- now final edition...
2005-07-22 22:21:16 +00:00
911e2ecefe New menu natives 2005-07-22 21:15:48 +00:00
b9131293c5 entity_set_owner accepts anything now 2005-07-22 20:47:13 +00:00
536a4f8472 Err, fixed these 2005-07-22 20:41:32 +00:00
29e1a5edc8 FAKEMETA IS GONE! SO LONG AND THANKS FOR THE FISH 2005-07-22 19:32:16 +00:00
34e5872881 *** empty log message *** 2005-07-22 17:37:27 +00:00
1d853b5fee because of bail I the editor unindents now on pressing }. have fun!
fixed bugs... lalala

updated debug-list
2005-07-22 17:36:51 +00:00
191824d72a new message system and string class 2005-07-22 09:26:37 +00:00
99f65175ff *** empty log message *** 2005-07-21 23:08:23 +00:00
2f8e311140 because of bail I the editor unindents now on pressing }. have fun!
fixed bugs... lalala
2005-07-21 22:29:08 +00:00
21551a6ea8 Fixed it for real <_< 2005-07-20 03:19:53 +00:00
c4f097bb36 Updated to PCRE 6.1 2005-07-19 16:48:16 +00:00
ffbf9fdca6 Saved a whole four bytes of memory 2005-07-19 16:14:52 +00:00
3863bd3ccc Fixed bug where not-found natives were still valid 2005-07-19 16:12:48 +00:00
a89e1ac536 Oops! Forgot to MF_Add pev 2005-07-19 16:08:00 +00:00
2f64226c6b Fixed bug at11988 reported by twilight suzuka 2005-07-15 20:50:23 +00:00
91da6f1631 Added is_in_viewcone, is_visible 2005-07-15 20:29:59 +00:00
e8c87f8d89 added is_visible, is_in_viewcone 2005-07-15 20:28:22 +00:00
3cba7811bd Committed new auto-module registering system
require_module is now DEPRECATED
2005-07-15 19:15:58 +00:00
70396a2fc1 new sdk version (bumped interface!!!!) 2005-07-15 19:13:50 +00:00
1a53b7bba7 Committed new SDK version 2005-07-15 19:05:44 +00:00
74ec2e75b8 New auto-module system 2005-07-15 19:05:31 +00:00
b312da8c63 Fixed bugs GCC caught 2005-07-15 16:28:41 +00:00
fe2d28f711 Ported the new dir commands to linux 2005-07-15 16:14:00 +00:00
1b09be51e1 Reverting JGHG's changes (forgot to commit this) 2005-07-15 07:59:26 +00:00
e1d1802cb9 Fixed bug at16027 2005-07-14 13:36:22 +00:00
db293cc451 Fixed memory leaks
Optimized message handling a bit
2005-07-14 04:50:46 +00:00
116984afed New dir reading natives, new memory outputs 2005-07-13 23:31:02 +00:00
a9d4e4e711 New natives for reading dirs 2005-07-13 23:30:28 +00:00
ef908ff4f5 Added get_distance_f, at15992 2005-07-13 22:16:30 +00:00
4631311905 Reverted pev changes 2005-07-13 18:05:52 +00:00
1106113f2b Recommitted pev - don't do this again without telling someone! 2005-07-13 17:35:47 +00:00
35ed810775 Patch for ifvers 5:11 (new MM API), eliminates fakemeta like mm-pext 2005-07-13 02:37:32 +00:00
e1a1153018 updated to July 2005-07-10 09:01:24 +00:00
e91cd0862e Added include files for new ESFMod module 2005-07-10 00:47:56 +00:00
5ac71db62d Tiny fixes 2005-07-10 00:45:42 +00:00
d270feb15f sawce forgot to add the shotgun to the list for retreiving reserve ammo. fixed. 2005-07-09 22:42:29 +00:00
1c8aca42eb Updated offsets for 3.0.5. With a couple of linux changes. 2005-07-09 22:26:38 +00:00
e0dbc031cc Committed initial import of the Earth's Special Forces module 2005-07-09 21:51:35 +00:00
39eba4134e Updated offsets for 3.0.5. Only windows offsets have been tested. I may update this again after testing linux. 2005-07-09 21:44:33 +00:00
9f77c8a4a2 oops 2005-07-09 15:38:07 +00:00
9b6fb64aba Bumped version # 2005-07-09 07:18:41 +00:00
82d6cb9de0 *** empty log message *** 2005-07-09 07:09:25 +00:00
8ae1d4ce27 New offsets from karlos (at15812) 2005-07-09 07:09:08 +00:00
21541fcc7f Decided to discontinue this module 2005-07-09 06:48:04 +00:00
e9e4ab69e6 Addressed report at15008 (twistedeuphoria) 2005-07-08 05:42:10 +00:00
35ecd40228 Fixed bug at15479 (karlos)
Fixed bug at11812 (Kamikaze)
Added new build_pathname implementation for reentracy.
build_pathname_r added to module API
2005-07-08 05:05:06 +00:00
e8d30a11d7 Patch for is_user_hltv (at14918 by Wallslide)
Fixed a few potential crash bugs
2005-07-08 02:01:01 +00:00
36d19dfe04 Fixed bug at15006 reported by EKS 2005-07-08 01:43:44 +00:00
5d90ccf088 Fix for bug at15759, from devicenull 2005-07-08 01:22:57 +00:00
de5eb6924a Added request at13457 from harbu. 2005-07-08 01:15:54 +00:00
0600e3357c Another resync :) 2005-07-08 00:44:09 +00:00
40f28a543e Resync 2005-07-07 20:08:35 +00:00
13b6c0764c Added request at15060 by twistedeuphoria 2005-07-07 19:53:02 +00:00
950d1b4a5f Fixed bug at13314 from XxAvalanchexX 2005-07-07 18:49:14 +00:00
85ed8468f8 Fix ap22177.2 from faluco 2005-07-07 18:46:04 +00:00
756a6a2b65 Fix ap22177.4 from faluco 2005-07-07 18:41:29 +00:00
e63ed1e3e0 Fix ap22177 from faluco 2005-07-07 18:40:59 +00:00
27c2978617 Synced language translation files 2005-07-07 18:38:29 +00:00
b0c9b868cd Fixed bug a13718 report by faluco 2005-07-07 18:37:33 +00:00
101c590f32 Removed mysql backwards compatibility
Removed stray character
2005-07-06 21:20:53 +00:00
943a75d7e1 Added requestfunction 2005-07-06 03:59:02 +00:00
611ad2be94 Malformat bug fixes, RC version bump 2005-07-06 03:20:00 +00:00
64b7c7b600 Malformat bug fixes 2005-07-06 03:19:27 +00:00
cc899d298d Modules can now intercommunicate through RegisterFunction() - UNTESTED
Registering a function will make it available through ReqFunc,
2005-07-05 22:01:29 +00:00
3f2c117039 because of bail I the editor unindents now on pressing }. have fun! 2005-06-26 02:10:33 +00:00
0d21377035 because of bail I the editor unindents now on pressing }. have fun! 2005-06-26 02:07:03 +00:00
48749382fb amx_addadmin added 2005-06-21 22:04:44 +00:00
996f461157 Fixed a memory leak on plugun unload 2005-06-16 20:20:24 +00:00
8d898ae459 fixed /stats command 2005-06-13 10:52:33 +00:00
b609eead1b fixed get area function 2005-06-01 13:49:49 +00:00
567ab19fe5 added cap_message to CP_ enum 2005-05-31 21:08:56 +00:00
1cc60fc9ad added new functions 2005-05-31 13:56:15 +00:00
959a5b9225 *** empty log message *** 2005-05-31 12:44:14 +00:00
9b8658606b fixed EndRound Stats 2005-05-31 12:35:13 +00:00
51ff0a2c49 Added stock file_copy to file.inc.
Also fixed fopen to return 0 on files that can't be opened.
Fixed native fopen to take const filename.
2005-05-29 16:36:35 +00:00
c1552aacd6 * May 18th, 2005: Starting to develop AMXX-Edit v2 as a kind of open source
* May 19th, 2005: Added debug dialog (only for developing)
2005-05-19 11:03:42 +00:00
ba245458de * May 18th, 2005: Starting to develop AMXX-Edit v2 as a kind of open source 2005-05-18 21:23:15 +00:00
c32e747dc1 *** empty log message *** 2005-05-18 21:04:34 +00:00
7ad84abb09 *** empty log message *** 2005-05-18 20:54:43 +00:00
dd6abc5487 * May 18th, 2005: Starting to develop AMXX-Edit v2 as a kind of open source 2005-05-18 20:53:06 +00:00
3642cedd2b delete it 2005-05-18 20:14:34 +00:00
df87bc06c2 fixed "dod_set_stamina" native 2005-05-12 10:28:40 +00:00
9d200888ff Initial import 2005-04-29 22:47:00 +00:00
ebf0945c6e Added numtostr and strtonum mappings... not adding this to string.inc ... but it's there now. :-P 2005-04-19 15:40:21 +00:00
7c6d869cb4 Moved
/* Sets player frags. */
native set_user_frags(index, frags);

from amxmodx.inc to fun.inc...
2005-04-19 14:49:16 +00:00
6de8178c30 Fixed a typo 2005-04-11 02:20:11 +00:00
1b80dd5584 updated to April 2005-04-10 15:47:14 +00:00
7ceaa4801d fixed wrong formatting when using non-english languages (thanks n-o-l-o) 2005-04-05 15:10:20 +00:00
15bd719cf5 FireStorm's fix 2005-04-05 14:48:06 +00:00
acb2b27852 Began AMXx bindings 2005-04-03 03:26:35 +00:00
abbb2f2cc2 Implementation of journaling 2005-04-03 02:01:42 +00:00
aa8beace98 added headers 2005-04-02 16:04:08 +00:00
d17d9103de Initial commit of hashtable stuff 2005-04-02 07:33:25 +00:00
85f5604d43 *** empty log message *** 2005-03-30 18:43:43 +00:00
fa42dbf011 Added stock admin_print(access, const DESTINATION, const MSG[]); 2005-03-30 11:37:41 +00:00
d1c27a7534 Goodbye pev. You've been great. Miss you. 2005-03-27 00:42:00 +00:00
8675d6a4a8 Pev -> Engine wrapper for backwards compatibility 2005-03-26 15:59:58 +00:00
1d770fd400 Removed pev 2005-03-25 22:05:41 +00:00
d6b704e74c Updated from http://www.amxmodx.org/forums/viewtopic.php?p=99878
To ban LAN:ers by IP and not authid.
2005-03-25 09:40:04 +00:00
eeee302722 Removed pev.cpp from build. These are excluded in vcproj from Windows builds. 2005-03-25 09:33:40 +00:00
81f4a505c1 Added FM_KeyValue and get_kv/set_kv natives.
Removed pev natives.

Probably fixed something in DLLFunc_ClientUserInfoChanged.
2005-03-25 09:30:45 +00:00
560f50eda7 *** empty log message *** 2005-03-24 11:37:00 +00:00
73f1e4d77e *** empty log message *** 2005-03-24 11:03:09 +00:00
87fd5e2b4e Added in-game cmd "amx_addadmin <playername> <flags> [password] - automatically add specified player as an admin to users.ini" 2005-03-24 10:59:46 +00:00
01cc4a1bad Fixed cs_set_user_armor() 2005-03-20 15:44:32 +00:00
ad732d7286 *** empty log message *** 2005-03-16 21:00:16 +00:00
448da8bd9e One more core skipping thingy 2005-03-11 19:16:00 +00:00
a4be1ac635 evilspy's fix 2005-03-11 16:31:49 +00:00
5e46f64d75 Updated hitzones.
Now allows setting individual hitzones between player A <-> player B.
2005-03-11 09:21:03 +00:00
f9281fe309 Removed last bug "fix" which did nothing except break a perfectly working plugin. Doh! 2005-03-10 10:47:09 +00:00
643 changed files with 143062 additions and 24285 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -30,17 +30,21 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h"
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes) CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
{ {
m_FuncName = name; m_FuncName = name;
m_ExecType = et; m_ExecType = et;
m_NumParams = numParams; m_NumParams = numParams;
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam)); memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
// find funcs // find funcs
int func; int func;
AMXForward *tmp = NULL; AMXForward *tmp = NULL;
m_Funcs.clear(); m_Funcs.clear();
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter) for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{ {
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE) if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
@ -70,47 +74,74 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{ {
if (iter->pPlugin->isExecutable(iter->func)) if (iter->pPlugin->isExecutable(iter->func))
{ {
// Get debug info
AMX *amx = (*iter).pPlugin->getAMX();
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
if (pDebugger)
pDebugger->BeginExec();
// handle strings & arrays // handle strings & arrays
int i; int i, ax = 0;
for (i = 0; i < m_NumParams; ++i) for (i = 0; i < m_NumParams; ++i)
{ {
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX) if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{ {
cell *tmp; cell *tmp;
amx_Allot(iter->pPlugin->getAMX(), amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH, amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
&realParams[i], &tmp);
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
physAddrs[i] = tmp; physAddrs[i] = tmp;
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
{ {
cell *tmp; cell *tmp;
amx_Allot(iter->pPlugin->getAMX(), preparedArrays[params[i]].size, amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
&realParams[i], &tmp);
physAddrs[i] = tmp; physAddrs[i] = tmp;
if (preparedArrays[params[i]].type == Type_Cell) if (preparedArrays[params[i]].type == Type_Cell)
{ {
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell)); memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
} } else {
else
{
char *data = (char*)preparedArrays[params[i]].ptr; char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j) for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*tmp++ = (static_cast<cell>(*data++)) & 0xFF; *tmp++ = (static_cast<cell>(*data++)) & 0xFF;
} }
} } else {
else
{
realParams[i] = params[i]; realParams[i] = params[i];
} }
} }
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
for (i = m_NumParams-1; i >= 0; i--)
{
amx_Push(amx, realParams[i]);
}
// exec // exec
cell retVal; cell retVal;
int err = amx_Execv(iter->pPlugin->getAMX(), &retVal, iter->func, m_NumParams, realParams); int err = amx_Exec(amx, &retVal, iter->func);
// log runtime error, if any // log runtime error, if any
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
LogError(iter->pPlugin->getAMX(), err, ""); {
//Did something else set an error?
if (pDebugger && pDebugger->ErrorExists())
{
//we don't care, something else logged the error.
}
else if (err != -1)
{
//nothing logged the error so spit it out anyway
LogError(amx, err, NULL);
}
}
amx->error = AMX_ERR_NONE;
if (pDebugger)
pDebugger->EndExec();
// cleanup strings & arrays // cleanup strings & arrays
for (i = 0; i < m_NumParams; ++i) for (i = 0; i < m_NumParams; ++i)
@ -122,7 +153,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
else if (m_ParamTypes[i] == FP_STRINGEX) else if (m_ParamTypes[i] == FP_STRINGEX)
{ {
// copy back // copy back
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0); amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
amx_Release(iter->pPlugin->getAMX(), realParams[i]); amx_Release(iter->pPlugin->getAMX(), realParams[i]);
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
@ -134,10 +165,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (preparedArrays[params[i]].type == Type_Cell) if (preparedArrays[params[i]].type == Type_Cell)
{ {
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell)); memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
} } else {
else
{
char *data = (char*)preparedArrays[params[i]].ptr; char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j) for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*data++ = static_cast<char>(*tmp++ & 0xFF); *data++ = static_cast<char>(*tmp++ & 0xFF);
} }
@ -167,6 +197,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
} }
} }
} }
return globRetVal; return globRetVal;
} }
@ -206,49 +237,67 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (!pPlugin->isExecutable(m_Func)) if (!pPlugin->isExecutable(m_Func))
return 0; return 0;
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
if (pDebugger)
pDebugger->BeginExec();
// handle strings & arrays // handle strings & arrays
int i; int i;
for (i = 0; i < m_NumParams; ++i) for (i = 0; i < m_NumParams; ++i)
{ {
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX) if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
{ {
cell *tmp; cell *tmp;
amx_Allot(m_Amx, amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH, amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
&realParams[i], &tmp);
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
physAddrs[i] = tmp; physAddrs[i] = tmp;
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
{ {
cell *tmp; cell *tmp;
amx_Allot(m_Amx, preparedArrays[params[i]].size, amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
&realParams[i], &tmp);
physAddrs[i] = tmp; physAddrs[i] = tmp;
if (preparedArrays[params[i]].type == Type_Cell) if (preparedArrays[params[i]].type == Type_Cell)
{ {
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell)); memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
} } else {
else
{
char *data = (char*)preparedArrays[params[i]].ptr; char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j) for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*tmp++ = (static_cast<cell>(*data++)) & 0xFF; *tmp++ = (static_cast<cell>(*data++)) & 0xFF;
} }
} } else {
else
{
realParams[i] = params[i]; realParams[i] = params[i];
} }
} }
for (i = m_NumParams - 1; i >= 0; i--)
amx_Push(m_Amx, realParams[i]);
// exec // exec
cell retVal; cell retVal;
int err = amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams); int err = amx_Exec(m_Amx, &retVal, m_Func);
// log runtime error, if any
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
LogError(m_Amx, err, ""); {
//Did something else set an error?
if (pDebugger && pDebugger->ErrorExists())
{
//we don't care, something else logged the error.
}
else if (err != -1)
{
//nothing logged the error so spit it out anyway
LogError(m_Amx, err, NULL);
}
}
if (pDebugger)
pDebugger->EndExec();
m_Amx->error = AMX_ERR_NONE;
// cleanup strings & arrays // cleanup strings & arrays
for (i = 0; i < m_NumParams; ++i) for (i = 0; i < m_NumParams; ++i)
@ -260,7 +309,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
else if (m_ParamTypes[i] == FP_STRINGEX) else if (m_ParamTypes[i] == FP_STRINGEX)
{ {
// copy back // copy back
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0); amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
amx_Release(m_Amx, realParams[i]); amx_Release(m_Amx, realParams[i]);
} }
else if (m_ParamTypes[i] == FP_ARRAY) else if (m_ParamTypes[i] == FP_ARRAY)
@ -272,10 +321,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (preparedArrays[params[i]].type == Type_Cell) if (preparedArrays[params[i]].type == Type_Cell)
{ {
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell)); memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
} } else {
else
{
char *data = (char*)preparedArrays[params[i]].ptr; char *data = (char*)preparedArrays[params[i]].ptr;
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j) for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
*data++ = static_cast<char>(*tmp++ & 0xFF); *data++ = static_cast<char>(*tmp++ & 0xFF);
} }
@ -291,9 +339,12 @@ int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int
{ {
int retVal = m_Forwards.size() << 1; int retVal = m_Forwards.size() << 1;
CForward *tmp = new CForward(funcName, et, numParams, paramTypes); CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
if (!tmp) if (!tmp)
return -1; // should be invalid return -1; // should be invalid
m_Forwards.push_back(tmp); m_Forwards.push_back(tmp);
return retVal; return retVal;
} }
@ -301,22 +352,26 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
{ {
int retVal = -1; int retVal = -1;
CSPForward *pForward; CSPForward *pForward;
if (!m_FreeSPForwards.empty()) if (!m_FreeSPForwards.empty())
{ {
retVal = m_FreeSPForwards.front(); retVal = m_FreeSPForwards.front();
pForward = m_SPForwards[retVal >> 1]; pForward = m_SPForwards[retVal >> 1];
pForward->Set(func, amx, numParams, paramTypes); pForward->Set(func, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0) if (pForward->getFuncsNum() == 0)
return -1; return -1;
m_FreeSPForwards.pop(); m_FreeSPForwards.pop();
} } else {
else
{
retVal = (m_SPForwards.size() << 1) | 1; retVal = (m_SPForwards.size() << 1) | 1;
pForward = new CSPForward(); pForward = new CSPForward();
if (!pForward) if (!pForward)
return -1; return -1;
pForward->Set(func, amx, numParams, paramTypes); pForward->Set(func, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0) if (pForward->getFuncsNum() == 0)
{ {
return -1; return -1;
@ -325,6 +380,7 @@ int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const For
m_SPForwards.push_back(pForward); m_SPForwards.push_back(pForward);
} }
return retVal; return retVal;
} }
@ -332,56 +388,58 @@ int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParam
{ {
int retVal = (m_SPForwards.size() << 1) | 1; int retVal = (m_SPForwards.size() << 1) | 1;
CSPForward *pForward; CSPForward *pForward;
if (!m_FreeSPForwards.empty()) if (!m_FreeSPForwards.empty())
{ {
retVal = m_FreeSPForwards.front(); retVal = m_FreeSPForwards.front();
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
pForward->Set(funcName, amx, numParams, paramTypes); pForward->Set(funcName, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0) if (pForward->getFuncsNum() == 0)
return -1; return -1;
m_FreeSPForwards.pop(); m_FreeSPForwards.pop();
} } else {
else
{
pForward = new CSPForward(); pForward = new CSPForward();
if (!pForward) if (!pForward)
return -1; return -1;
pForward->Set(funcName, amx, numParams, paramTypes); pForward->Set(funcName, amx, numParams, paramTypes);
if (pForward->getFuncsNum() == 0) if (pForward->getFuncsNum() == 0)
{ {
delete pForward; delete pForward;
return -1; return -1;
} }
m_SPForwards.push_back(pForward); m_SPForwards.push_back(pForward);
} }
return retVal; return retVal;
} }
bool CForwardMngr::isIdValid(int id) const bool CForwardMngr::isIdValid(int id) const
{ {
return (id >= 0) && ((id & 1) ? return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
(static_cast<size_t>(id >> 1) < m_SPForwards.size()) :
(static_cast<size_t>(id >> 1) < m_Forwards.size()));
} }
cell CForwardMngr::executeForwards(int id, cell *params) cell CForwardMngr::executeForwards(int id, cell *params)
{ {
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
m_TmpArraysNum = 0; m_TmpArraysNum = 0;
return retVal; return retVal;
} }
int CForwardMngr::getParamsNum(int id) const int CForwardMngr::getParamsNum(int id) const
{ {
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
m_Forwards[id >> 1]->getParamsNum();
} }
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
{ {
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
m_Forwards[id >> 1]->getParamType(paramNum);
} }
void CForwardMngr::clear() void CForwardMngr::clear()
@ -390,7 +448,9 @@ void CForwardMngr::clear()
{ {
delete *iter; delete *iter;
} }
SPForwardVec::iterator spIter; SPForwardVec::iterator spIter;
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter) for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
{ {
delete (*spIter); delete (*spIter);
@ -398,8 +458,10 @@ void CForwardMngr::clear()
m_Forwards.clear(); m_Forwards.clear();
m_SPForwards.clear(); m_SPForwards.clear();
while (!m_FreeSPForwards.empty()) while (!m_FreeSPForwards.empty())
m_FreeSPForwards.pop(); m_FreeSPForwards.pop();
m_TmpArraysNum = 0; m_TmpArraysNum = 0;
} }
@ -411,74 +473,97 @@ bool CForwardMngr::isSPForward(int id) const
void CForwardMngr::unregisterSPForward(int id) void CForwardMngr::unregisterSPForward(int id)
{ {
//make sure the id is valid //make sure the id is valid
if ( !isIdValid(id) || m_SPForwards.at(id >> 1)->isFree ) if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
return; return;
m_SPForwards.at(id >> 1)->isFree = true; m_SPForwards.at(id >> 1)->isFree = true;
m_FreeSPForwards.push(id); m_FreeSPForwards.push(id);
} }
int registerForward(const char *funcName, ForwardExecType et, ...) int registerForward(const char *funcName, ForwardExecType et, ...)
{ {
int curParam = 0; int curParam = 0;
va_list argptr; va_list argptr;
va_start(argptr, et); va_start(argptr, et);
ForwardParam params[FORWARD_MAX_PARAMS]; ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp; ForwardParam tmp;
while (true) while (true)
{ {
if (curParam == FORWARD_MAX_PARAMS) if (curParam == FORWARD_MAX_PARAMS)
break; break;
tmp = (ForwardParam)va_arg(argptr, int); tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE) if (tmp == FP_DONE)
break; break;
params[curParam] = tmp; params[curParam] = tmp;
++curParam; ++curParam;
} }
va_end(argptr); va_end(argptr);
return g_forwards.registerForward(funcName, et, curParam, params); return g_forwards.registerForward(funcName, et, curParam, params);
} }
int registerSPForwardByName(AMX *amx, const char *funcName, ...) int registerSPForwardByName(AMX *amx, const char *funcName, ...)
{ {
int curParam = 0; int curParam = 0;
va_list argptr; va_list argptr;
va_start(argptr, funcName); va_start(argptr, funcName);
ForwardParam params[FORWARD_MAX_PARAMS]; ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp; ForwardParam tmp;
while (true) while (true)
{ {
if (curParam == FORWARD_MAX_PARAMS) if (curParam == FORWARD_MAX_PARAMS)
break; break;
tmp = (ForwardParam)va_arg(argptr, int); tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE) if (tmp == FP_DONE)
break; break;
params[curParam] = tmp; params[curParam] = tmp;
++curParam; ++curParam;
} }
va_end(argptr); va_end(argptr);
return g_forwards.registerSPForward(funcName, amx, curParam, params); return g_forwards.registerSPForward(funcName, amx, curParam, params);
} }
int registerSPForward(AMX *amx, int func, ...) int registerSPForward(AMX *amx, int func, ...)
{ {
int curParam = 0; int curParam = 0;
va_list argptr; va_list argptr;
va_start(argptr, func); va_start(argptr, func);
ForwardParam params[FORWARD_MAX_PARAMS]; ForwardParam params[FORWARD_MAX_PARAMS];
ForwardParam tmp; ForwardParam tmp;
while (true) while (true)
{ {
if (curParam == FORWARD_MAX_PARAMS) if (curParam == FORWARD_MAX_PARAMS)
break; break;
tmp = (ForwardParam)va_arg(argptr, int); tmp = (ForwardParam)va_arg(argptr, int);
if (tmp == FP_DONE) if (tmp == FP_DONE)
break; break;
params[curParam] = tmp; params[curParam] = tmp;
++curParam; ++curParam;
} }
va_end(argptr); va_end(argptr);
return g_forwards.registerSPForward(func, amx, curParam, params); return g_forwards.registerSPForward(func, amx, curParam, params);
} }
@ -488,9 +573,12 @@ cell executeForwards(int id, ...)
return -1; return -1;
cell params[FORWARD_MAX_PARAMS]; cell params[FORWARD_MAX_PARAMS];
int paramsNum = g_forwards.getParamsNum(id); int paramsNum = g_forwards.getParamsNum(id);
va_list argptr; va_list argptr;
va_start(argptr, id); va_start(argptr, id);
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i) for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
{ {
if (g_forwards.getParamType(id, i) == FP_FLOAT) if (g_forwards.getParamType(id, i) == FP_FLOAT)
@ -501,7 +589,9 @@ cell executeForwards(int id, ...)
else else
params[i] = (cell)va_arg(argptr, cell); params[i] = (cell)va_arg(argptr, cell);
} }
va_end(argptr); va_end(argptr);
return g_forwards.executeForwards(id, params); return g_forwards.executeForwards(id, params);
} }
@ -509,13 +599,16 @@ cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemTy
{ {
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS) if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
{ {
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
m_validateAllAllocUnits(); m_validateAllAllocUnits();
#endif // MEMORY_TEST #endif // MEMORY_TEST
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1); AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
m_TmpArraysNum = 0; m_TmpArraysNum = 0;
return -1; return -1;
} }
m_TmpArrays[m_TmpArraysNum].ptr = ptr; m_TmpArrays[m_TmpArraysNum].ptr = ptr;
m_TmpArrays[m_TmpArraysNum].size = size; m_TmpArrays[m_TmpArraysNum].size = size;
m_TmpArrays[m_TmpArraysNum].type = type; m_TmpArrays[m_TmpArraysNum].type = type;

View File

@ -77,7 +77,9 @@ enum ForwardArrayElemType
struct ForwardPreparedArray struct ForwardPreparedArray
{ {
void *ptr; void *ptr;
ForwardArrayElemType type; ForwardArrayElemType type;
unsigned int size; unsigned int size;
bool copyBack; bool copyBack;
}; };
@ -88,31 +90,39 @@ class CForward
const char *m_FuncName; const char *m_FuncName;
ForwardExecType m_ExecType; ForwardExecType m_ExecType;
int m_NumParams; int m_NumParams;
struct AMXForward struct AMXForward
{ {
CPluginMngr::CPlugin *pPlugin; CPluginMngr::CPlugin *pPlugin;
int func; int func;
}; };
typedef CVector<AMXForward> AMXForwardList; typedef CVector<AMXForward> AMXForwardList;
AMXForwardList m_Funcs; AMXForwardList m_Funcs;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS]; ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
public: public:
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes); CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
CForward() CForward() {} // leaves everything unitialized'
{ } // leaves everything unitialized'
cell execute(cell *params, ForwardPreparedArray *preparedArrays); cell execute(cell *params, ForwardPreparedArray *preparedArrays);
int getParamsNum() const int getParamsNum() const
{ {
return m_NumParams; return m_NumParams;
} }
int getFuncsNum() const int getFuncsNum() const
{ {
return m_Funcs.size(); return m_Funcs.size();
} }
ForwardParam getParamType(int paramId) const ForwardParam getParamType(int paramId) const
{ {
if (paramId < 0 || paramId >= m_NumParams) if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE; return FP_DONE;
return m_ParamTypes[paramId]; return m_ParamTypes[paramId];
} }
}; };
@ -122,10 +132,13 @@ class CSPForward
{ {
const char *m_FuncName; const char *m_FuncName;
int m_NumParams; int m_NumParams;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS]; ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
AMX *m_Amx; AMX *m_Amx;
int m_Func; int m_Func;
bool m_HasFunc; bool m_HasFunc;
public: public:
bool isFree; bool isFree;
public: public:
@ -134,18 +147,22 @@ public:
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes); void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
cell execute(cell *params, ForwardPreparedArray *preparedArrays); cell execute(cell *params, ForwardPreparedArray *preparedArrays);
int getParamsNum() const int getParamsNum() const
{ {
return m_NumParams; return m_NumParams;
} }
int getFuncsNum() const int getFuncsNum() const
{ {
return (m_HasFunc) ? 1 : 0; return (m_HasFunc) ? 1 : 0;
} }
ForwardParam getParamType(int paramId) const ForwardParam getParamType(int paramId) const
{ {
if (paramId < 0 || paramId >= m_NumParams) if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE; return FP_DONE;
return m_ParamTypes[paramId]; return m_ParamTypes[paramId];
} }
}; };
@ -167,8 +184,7 @@ public:
CForwardMngr() CForwardMngr()
{ m_TmpArraysNum = 0; } { m_TmpArraysNum = 0; }
~CForwardMngr() ~CForwardMngr() {}
{ }
// Interface // Interface
// Register normal forward // Register normal forward
@ -176,18 +192,21 @@ public:
// Register single plugin forward // Register single plugin forward
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes); int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes); int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
// Unregister single plugin forward // Unregister single plugin forward
void unregisterSPForward(int id); void unregisterSPForward(int id);
// execute forward // execute forward
cell executeForwards(int id, cell *params); cell executeForwards(int id, cell *params);
void clear(); // delete all forwards void clear(); // delete all forwards
bool isIdValid(int id) const; // check whether forward id is valid bool isIdValid(int id) const; // check whether forward id is valid
bool isSPForward(int id) const; // check whether forward is single plugin bool isSPForward(int id) const; // check whether forward is single plugin
int getParamsNum(int id) const; // get num of params of a forward int getParamsNum(int id) const; // get num of params of a forward
int getFuncsNum(int id) const; // get num of found functions of a forward int getFuncsNum(int id) const; // get num of found functions of a forward
ForwardParam getParamType(int id, int paramId) const; ForwardParam getParamType(int id, int paramId) const;
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
bool copyBack); // prepare array
}; };
// (un)register forward // (un)register forward
@ -202,5 +221,4 @@ cell executeForwards(int id, ...);
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false); cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false); cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
#endif #endif //FORWARD_H

View File

@ -33,6 +33,10 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "CLang.h" #include "CLang.h"
#ifdef __linux__
#define _snprintf snprintf
#endif
#define LITIDX_NONE 0 #define LITIDX_NONE 0
#define LITIDX_BRACKET 1 #define LITIDX_BRACKET 1
#define LITIDX_DEFINITION 2 #define LITIDX_DEFINITION 2
@ -153,7 +157,7 @@ size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
int flag = 0; int flag = 0;
size_t strln = strlen(str); size_t strln = strlen(str);
for (i=strln-1; i>=0; i--) for (i = strln - 1; i >= 0; i--)
{ {
if (str[i] == '\n' || str[i] == ' ' || str[i] == '\t') if (str[i] == '\n' || str[i] == ' ' || str[i] == '\t')
{ {
@ -180,6 +184,7 @@ size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
} }
newstr[pos] = 0; newstr[pos] = 0;
return ptr - str + 1; return ptr - str + 1;
} }
@ -275,7 +280,7 @@ CLangMngr::CLang::CLang(const char *lang)
{ {
m_LookUpTable.clear(); m_LookUpTable.clear();
strncpy(m_LanguageName, lang, 2); strncpy(m_LanguageName, lang, 2);
m_LanguageName[2]=0; m_LanguageName[2] = 0;
} }
CLangMngr::CLang::LangEntry *CLangMngr::CLang::AddEntry(int pKey, uint32_t defHash, const char *def, bool cache) CLangMngr::CLang::LangEntry *CLangMngr::CLang::AddEntry(int pKey, uint32_t defHash, const char *def, bool cache)
@ -296,11 +301,12 @@ CLangMngr::CLang::~CLang()
void CLangMngr::CLang::Clear() void CLangMngr::CLang::Clear()
{ {
for (unsigned int i=0; i<m_LookUpTable.size(); i++) for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
{ {
if (m_LookUpTable[i]) if (m_LookUpTable[i])
delete m_LookUpTable[i]; delete m_LookUpTable[i];
} }
m_LookUpTable.clear(); m_LookUpTable.clear();
} }
@ -308,7 +314,7 @@ CLangMngr::CLang::LangEntry * CLangMngr::CLang::GetEntry(int pkey)
{ {
unsigned int i; unsigned int i;
for (i=0; i<m_LookUpTable.size(); i++) for (i = 0; i < m_LookUpTable.size(); i++)
{ {
if (m_LookUpTable[i]->GetKey() == pkey) if (m_LookUpTable[i]->GetKey() == pkey)
{ {
@ -328,11 +334,13 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
{ {
const char *def = 0; const char *def = 0;
int key = -1; int key = -1;
while (!vec.empty()) while (!vec.empty())
{ {
key = vec.front()->key; key = vec.front()->key;
def = vec.front()->def->c_str(); def = vec.front()->def->c_str();
LangEntry *entry = GetEntry(key); LangEntry *entry = GetEntry(key);
if (entry->GetDefHash() != MakeHash(def)) if (entry->GetDefHash() != MakeHash(def))
{ {
if (entry->GetCache()) if (entry->GetCache())
@ -344,6 +352,7 @@ void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef*> &vec)
//AMXXLOG_Log("[AMXX] Language key %s[%s] defined twice", m_LMan->GetKey(key), m_LanguageName); //AMXXLOG_Log("[AMXX] Language key %s[%s] defined twice", m_LMan->GetKey(key), m_LanguageName);
} }
} }
delete vec.front(); delete vec.front();
vec.pop(); vec.pop();
} }
@ -353,20 +362,22 @@ const char * CLangMngr::CLang::GetDef(const char *key)
{ {
static char nfind[1024] = "ML_NOTFOUND(KEY)"; static char nfind[1024] = "ML_NOTFOUND(KEY)";
int ikey = m_LMan->GetKeyEntry(key); int ikey = m_LMan->GetKeyEntry(key);
if (ikey == -1) if (ikey == -1)
{ {
sprintf(nfind, "ML_NOTFOUND: %s", key); sprintf(nfind, "ML_NOTFOUND: %s", key);
return nfind; return nfind;
} }
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
{ {
if (m_LookUpTable[i]->GetKey() == ikey) if (m_LookUpTable[i]->GetKey() == ikey)
return m_LookUpTable[i]->GetDef(); return m_LookUpTable[i]->GetDef();
} }
return NULL; return NULL;
} }
struct OffsetPair struct OffsetPair
{ {
uint32_t defOffset; uint32_t defOffset;
@ -377,7 +388,8 @@ struct OffsetPair
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset) bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
{ {
unsigned short defLen = 0; unsigned short defLen = 0;
for (unsigned int i = 0; i<m_LookUpTable.size(); i++)
for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
{ {
defLen = m_LookUpTable[i]->GetDefLength(); defLen = m_LookUpTable[i]->GetDefLength();
fwrite((void *)&defLen, sizeof(unsigned short), 1, fp); fwrite((void *)&defLen, sizeof(unsigned short), 1, fp);
@ -399,7 +411,7 @@ bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
fwrite((void*)&size, sizeof(uint32_t), 1, fp); fwrite((void*)&size, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t); curOffset += sizeof(uint32_t);
for (unsigned int i = 0; i<m_LookUpTable.size(); i++) for (unsigned int i = 0; i < m_LookUpTable.size(); i++)
{ {
keynum = m_LookUpTable[i]->GetKey(); keynum = m_LookUpTable[i]->GetKey();
defhash = m_LookUpTable[i]->GetDefHash(); defhash = m_LookUpTable[i]->GetDefHash();
@ -419,7 +431,6 @@ bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
// assumes fp is set to the right position // assumes fp is set to the right position
bool CLangMngr::CLang::Load(FILE *fp) bool CLangMngr::CLang::Load(FILE *fp)
{ {
return true; return true;
} }
@ -457,9 +468,10 @@ int CLangMngr::GetKeyEntry(const char *key)
return -1; return -1;
} }
for (i = 0; i<KeyList.size(); i++) for (i = 0; i < KeyList.size(); i++)
{ {
cmpKey = KeyList[i]->hash; cmpKey = KeyList[i]->hash;
if (hKey == cmpKey) if (hKey == cmpKey)
{ {
return i; return i;
@ -486,7 +498,7 @@ int CLangMngr::GetKeyEntry(String &key)
uint32_t hKey = MakeHash(key.c_str(), true); uint32_t hKey = MakeHash(key.c_str(), true);
unsigned int i = 0; unsigned int i = 0;
for (i = 0; i<KeyList.size(); i++) for (i = 0; i < KeyList.size(); i++)
{ {
if (hKey == KeyList[i]->hash) if (hKey == KeyList[i]->hash)
{ {
@ -517,6 +529,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
{ {
// number of parameters ( for NEXT_PARAM macro ) // number of parameters ( for NEXT_PARAM macro )
int paramCount = *params / sizeof(cell); int paramCount = *params / sizeof(cell);
// the output buffer // the output buffer
static char outbuf[4096]; static char outbuf[4096];
char *outptr = outbuf; char *outptr = outbuf;
@ -527,13 +540,14 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
if (*src == '%') if (*src == '%')
{ {
++src; ++src;
if (*src=='L') if (*src == 'L')
{ {
cell langName = params[parm]; // "en" case (langName contains the address to the string) cell langName = params[parm]; // "en" case (langName contains the address to the string)
NEXT_PARAM(); NEXT_PARAM();
cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases cell *pAmxLangName = get_amxaddr(amx, params[parm++]); // other cases
const char *cpLangName=NULL; const char *cpLangName=NULL;
// Handle player ids (1-32) and server language // Handle player ids (1-32) and server language
if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER if (*pAmxLangName == LANG_PLAYER) // LANG_PLAYER
{ {
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0) if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
@ -542,9 +556,13 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
} else { } else {
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang"); cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
} }
} else if (*pAmxLangName == LANG_SERVER) { // LANG_SERVER }
else if (*pAmxLangName == LANG_SERVER) // LANG_SERVER
{
cpLangName = g_vault.get("server_language"); cpLangName = g_vault.get("server_language");
} else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) { // Direct Client Id }
else if (*pAmxLangName >= 1 && *pAmxLangName <= 32) // Direct Client Id
{
if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0) if ((int)CVAR_GET_FLOAT("amx_client_languages") == 0)
{ {
cpLangName = g_vault.get("server_language"); cpLangName = g_vault.get("server_language");
@ -555,30 +573,34 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
int tmplen = 0; int tmplen = 0;
cpLangName = get_amxstring(amx, langName, 2, tmplen); cpLangName = get_amxstring(amx, langName, 2, tmplen);
} }
if (!cpLangName || strlen(cpLangName) < 1) if (!cpLangName || strlen(cpLangName) < 1)
cpLangName = "en"; cpLangName = "en";
int tmplen = 0; int tmplen = 0;
NEXT_PARAM(); NEXT_PARAM();
char *key = get_amxstring(amx, params[parm++], 1, tmplen); char *key = get_amxstring(amx, params[parm++], 1, tmplen);
const char *def = GetDef(cpLangName, key); const char *def = GetDef(cpLangName, key);
if (def == NULL) if (def == NULL)
{ {
if (*pAmxLangName != LANG_SERVER) if (*pAmxLangName != LANG_SERVER)
{ {
def = GetDef(g_vault.get("server_language"), key); def = GetDef(g_vault.get("server_language"), key);
} }
if (strcmp(cpLangName, "en")!=0 && strcmp(g_vault.get("server_language"), "en")!=0) if (strcmp(cpLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0)
{ {
def = GetDef("en", key); def = GetDef("en", key);
} }
if (!def) if (!def)
{ {
static char buf[512]; static char buf[512];
CHECK_PTR((char*)(buf+17+strlen(key)), buf, sizeof(buf)); CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
sprintf(buf, "ML_LNOTFOUND: %s", key); sprintf(buf, "ML_LNOTFOUND: %s", key);
def = buf; def = buf;
} }
} }
while (*def) while (*def)
{ {
if (*def == '%') if (*def == '%')
@ -588,19 +610,18 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
{ {
*outptr++ = '%'; *outptr++ = '%';
++def; ++def;
} } else {
else
{
static char format[32]; static char format[32];
format[0] = '%'; format[0] = '%';
char *ptr = format+1; char *ptr = format + 1;
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++)) while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
/*nothing*/; /*nothing*/;
ZEROTERM(format); ZEROTERM(format);
*ptr = 0; *ptr = 0;
switch ( *(ptr-1) )
switch (*(ptr - 1))
{ {
case 's': case 's':
{ {
@ -609,10 +630,9 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
NEXT_PARAM(); NEXT_PARAM();
cell *tmpCell = get_amxaddr(amx, params[parm++]); cell *tmpCell = get_amxaddr(amx, params[parm++]);
while (tmpPtr-tmpString < sizeof(tmpString) && *tmpCell) while (tmpPtr-tmpString < sizeof(tmpString) && *tmpCell)
*tmpPtr++ = *tmpCell++; *tmpPtr++ = static_cast<char>(*tmpCell++);
*tmpPtr = 0; *tmpPtr = 0;
sprintf(outptr, format, tmpString); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
ZEROTERM(outbuf); ZEROTERM(outbuf);
break; break;
} }
@ -620,7 +640,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
case 'f': case 'f':
{ {
NEXT_PARAM(); NEXT_PARAM();
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++])); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
ZEROTERM(outbuf); ZEROTERM(outbuf);
break; break;
} }
@ -629,23 +649,25 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
case 'c': case 'c':
{ {
NEXT_PARAM(); NEXT_PARAM();
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++])); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
ZEROTERM(outbuf); ZEROTERM(outbuf);
break; break;
} }
default: default:
{ {
CHECK_OUTPTR(strlen(format)+1); CHECK_OUTPTR(strlen(format) + 1);
strcpy(outptr, format); strcpy(outptr, format);
break; break;
} }
} }
outptr += strlen(outptr); outptr += strlen(outptr);
} }
} }
else if (*def == '^') else if (*def == '^')
{ {
++def; ++def;
switch (*def) switch (*def)
{ {
case 'n': case 'n':
@ -666,39 +688,38 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
*outptr++ = *def; *outptr++ = *def;
break; break;
} }
++def; ++def;
} } else {
else
{
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = *def++; *outptr++ = *def++;
} }
} }
} } else {
else
{
static char tmpString[4096]; static char tmpString[4096];
char *tmpPtr = tmpString; char *tmpPtr = tmpString;
int tmpLen = 0; int tmpLen = 0;
static char format[32] = {'%'}; static char format[32] = {'%'};
char *ptr = format+1; char *ptr = format + 1;
if (*src != '%') if (*src != '%')
{ {
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = *src++)) while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = static_cast<char>(*src++)))
/*nothing*/; /*nothing*/;
*ptr = 0; *ptr = 0;
ZEROTERM(format); ZEROTERM(format);
--src; --src;
switch ( *(ptr-1) )
switch (*(ptr - 1))
{ {
case 's': case 's':
{ {
NEXT_PARAM(); NEXT_PARAM();
cell *tmpCell = get_amxaddr(amx, params[parm++]); cell *tmpCell = get_amxaddr(amx, params[parm++]);
while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell) while (tmpPtr-tmpString<sizeof(tmpString) && *tmpCell)
*tmpPtr++ = *tmpCell++; *tmpPtr++ = static_cast<char>(*tmpCell++);
*tmpPtr = 0; *tmpPtr = 0;
sprintf(outptr, format, tmpString); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
ZEROTERM(outbuf); ZEROTERM(outbuf);
break; break;
} }
@ -706,7 +727,7 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
case 'f': case 'f':
{ {
NEXT_PARAM(); NEXT_PARAM();
sprintf(outptr, format, *(REAL*)get_amxaddr(amx, params[parm++])); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, *(REAL*)get_amxaddr(amx, params[parm++]));
break; break;
} }
case 'i': case 'i':
@ -714,33 +735,34 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
case 'c': case 'c':
{ {
NEXT_PARAM(); NEXT_PARAM();
sprintf(outptr, format, (int)*get_amxaddr(amx, params[parm++])); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, (int)*get_amxaddr(amx, params[parm++]));
break; break;
} }
default: default:
{ {
CHECK_OUTPTR(strlen(format)+1); CHECK_OUTPTR(strlen(format) + 1);
strcpy(outptr, format); strcpy(outptr, format);
break; break;
} }
} }
outptr += strlen(outptr); outptr += strlen(outptr);
} else { } else {
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = '%'; *outptr++ = '%';
} }
} }
} } else {
else
{
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = *src; *outptr++ = static_cast<char>(*src);
} }
++src; ++src;
} }
len = outptr - outbuf; len = outptr - outbuf;
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = 0; *outptr++ = 0;
return outbuf; return outbuf;
} }
@ -750,6 +772,7 @@ const char *CLangMngr::Format(const char *fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
const char *retVal = FormatString(fmt, ap); const char *retVal = FormatString(fmt, ap);
va_end(ap); va_end(ap);
return retVal; return retVal;
} }
@ -778,12 +801,13 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
if (*src == '%') if (*src == '%')
{ {
++src; ++src;
if (*src=='L') if (*src == 'L')
{ {
NEXT_PARAM(); NEXT_PARAM();
const char *pAmxLangName = va_arg(ap, const char*); const char *pAmxLangName = va_arg(ap, const char*);
const char *cpLangName=NULL; const char *cpLangName=NULL;
// Handle player ids (1-32) and server language // Handle player ids (1-32) and server language
if (pAmxLangName == (const char *)LANG_PLAYER) // LANG_PLAYER if (pAmxLangName == (const char *)LANG_PLAYER) // LANG_PLAYER
{ {
if ((int)CVAR_GET_FLOAT("amx_client_languages")) if ((int)CVAR_GET_FLOAT("amx_client_languages"))
@ -792,9 +816,13 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
} else { } else {
cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang"); cpLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(m_CurGlobId)->pEdict, "lang");
} }
} else if (pAmxLangName == (const char *)LANG_SERVER) { // LANG_SERVER }
else if (pAmxLangName == (const char *)LANG_SERVER) // LANG_SERVER
{
cpLangName = g_vault.get("server_language"); cpLangName = g_vault.get("server_language");
} else if (pAmxLangName >= (const char *)1 && pAmxLangName <= (const char *)32) { // Direct Client Id }
else if (pAmxLangName >= (const char *)1 && pAmxLangName <= (const char *)32) // Direct Client Id
{
if ((int)CVAR_GET_FLOAT("amx_client_languages")) if ((int)CVAR_GET_FLOAT("amx_client_languages"))
{ {
cpLangName = g_vault.get("server_language"); cpLangName = g_vault.get("server_language");
@ -805,29 +833,33 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
int tmplen = 0; int tmplen = 0;
cpLangName = pAmxLangName; cpLangName = pAmxLangName;
} }
if (!cpLangName || strlen(cpLangName) < 1) if (!cpLangName || strlen(cpLangName) < 1)
cpLangName = "en"; cpLangName = "en";
int tmplen = 0; int tmplen = 0;
const char *key = va_arg(ap, const char *); const char *key = va_arg(ap, const char *);
const char *def = GetDef(cpLangName, key); const char *def = GetDef(cpLangName, key);
if (def == NULL) if (def == NULL)
{ {
if (pAmxLangName != LANG_SERVER) if (pAmxLangName != LANG_SERVER)
{ {
def = GetDef(g_vault.get("server_language"), key); def = GetDef(g_vault.get("server_language"), key);
} }
if (strcmp(cpLangName, "en")!=0 && strcmp(g_vault.get("server_language"), "en")!=0) if (strcmp(cpLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0)
{ {
def = GetDef("en", key); def = GetDef("en", key);
} }
if (!def) if (!def)
{ {
static char buf[512]; static char buf[512];
CHECK_PTR((char*)(buf+17+strlen(key)), buf, sizeof(buf)); CHECK_PTR((char*)(buf + 17 + strlen(key)), buf, sizeof(buf));
sprintf(buf, "ML_LNOTFOUND: %s", key); sprintf(buf, "ML_LNOTFOUND: %s", key);
def = buf; def = buf;
} }
} }
while (*def) while (*def)
{ {
if (*def == '%') if (*def == '%')
@ -835,7 +867,7 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
++def; ++def;
static char format[32]; static char format[32];
format[0] = '%'; format[0] = '%';
char *ptr = format+1; char *ptr = format + 1;
while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++)) while (ptr-format<sizeof(format) && !isalpha(*ptr++ = *def++))
/*nothing*/; /*nothing*/;
ZEROTERM(format); ZEROTERM(format);
@ -843,7 +875,8 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
*ptr = 0; *ptr = 0;
vsprintf(outptr, format, ap); vsprintf(outptr, format, ap);
// vsprintf doesnt alter the ap, increment here // vsprintf doesnt alter the ap, increment here
switch (*(ptr-1))
switch (*(ptr - 1))
{ {
case 'f': case 'f':
va_arg(ap, double); va_arg(ap, double);
@ -858,11 +891,13 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
va_arg(ap, int); va_arg(ap, int);
break; break;
} }
outptr += strlen(outptr); outptr += strlen(outptr);
} }
else if (*def == '^') else if (*def == '^')
{ {
++def; ++def;
switch (*def) switch (*def)
{ {
case 'n': case 'n':
@ -883,29 +918,28 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
*outptr++ = *def; *outptr++ = *def;
break; break;
} }
++def; ++def;
} } else {
else
{
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = *def++; *outptr++ = *def++;
} }
} }
} } else {
else
{
static char format[32] = {'%'}; static char format[32] = {'%'};
char *ptr = format+1; char *ptr = format + 1;
if (*src != '%') if (*src != '%')
{ {
while (*src != 0 && ptr-format<sizeof(format) && !isalpha(*ptr++ = *src++)) while (*src != 0 && ptr-format < sizeof(format) && !isalpha(*ptr++ = *src++))
/*nothing*/; /*nothing*/;
*ptr = 0; *ptr = 0;
ZEROTERM(format); ZEROTERM(format);
--src; --src;
vsprintf(outptr, format, ap); vsprintf(outptr, format, ap);
// vsprintf doesnt alter the ap, increment here // vsprintf doesnt alter the ap, increment here
switch (*(ptr-1))
switch (*(ptr - 1))
{ {
case 'f': case 'f':
va_arg(ap, double); va_arg(ap, double);
@ -920,24 +954,26 @@ char *CLangMngr::FormatString(const char *fmt, va_list &ap)
va_arg(ap, int); va_arg(ap, int);
break; break;
} }
outptr += strlen(outptr); outptr += strlen(outptr);
} else { } else {
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = '%'; *outptr++ = '%';
} }
} }
} } else {
else
{
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = *src; *outptr++ = *src;
} }
++src; ++src;
} }
CHECK_OUTPTR(1); CHECK_OUTPTR(1);
*outptr++ = 0; *outptr++ = 0;
return outbuf; return outbuf;
} }
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef*> &tmpVec) void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef*> &tmpVec)
{ {
CLang * language = GetLang(lang); CLang * language = GetLang(lang);
@ -953,9 +989,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
if (!fp) if (!fp)
{ {
CVector<md5Pair *>::iterator iter; CVector<md5Pair *>::iterator iter;
for (iter=FileList.begin(); iter!=FileList.end(); ++iter) for (iter = FileList.begin(); iter != FileList.end(); ++iter)
{ {
if ( (*iter)->file.compare(file) == 0 ) if ((*iter)->file.compare(file) == 0)
{ {
char buf[33] = {0}; char buf[33] = {0};
(*iter)->val.assign(buf); (*iter)->val.assign(buf);
@ -965,6 +1001,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file); AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file);
return 0; return 0;
} }
MD5 md5; MD5 md5;
md5.update(fp); // closes for us md5.update(fp); // closes for us
md5.finalize(); md5.finalize();
@ -973,11 +1010,11 @@ int CLangMngr::MergeDefinitionFile(const char *file)
bool foundFlag = false; bool foundFlag = false;
CVector<md5Pair *>::iterator iter; CVector<md5Pair *>::iterator iter;
for (iter=FileList.begin(); iter!=FileList.end(); ++iter) for (iter = FileList.begin(); iter != FileList.end(); ++iter)
{ {
if ( (*iter)->file.compare(file) == 0 ) if ((*iter)->file.compare(file) == 0)
{ {
if ( (*iter)->val.compare(md5buffer) == 0 ) if ((*iter)->val.compare(md5buffer) == 0)
{ {
return -1; return -1;
} else { } else {
@ -1018,6 +1055,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
buf.trim(); buf.trim();
if (buf[0] == 0) if (buf[0] == 0)
continue; continue;
if ((buf[0] == ';') || (buf[0] == '/' && buf[1] == '/'))
continue;
if (buf[0] == '[' && buf.size() >= 3) if (buf[0] == '[' && buf.size() >= 3)
{ {
if (multiline) if (multiline)
@ -1027,10 +1067,12 @@ int CLangMngr::MergeDefinitionFile(const char *file)
delete tmpEntry; delete tmpEntry;
tmpEntry = 0; tmpEntry = 0;
} }
if (!Defq.empty()) if (!Defq.empty())
{ {
MergeDefinitions(language, Defq); MergeDefinitions(language, Defq);
} }
language[0] = buf[1]; language[0] = buf[1];
language[1] = buf[2]; language[1] = buf[2];
language[2] = 0; language[2] = 0;
@ -1038,13 +1080,14 @@ int CLangMngr::MergeDefinitionFile(const char *file)
if (!multiline) if (!multiline)
{ {
pos = buf.find('='); pos = buf.find('=');
if (pos > String::npos) if (pos > String::npos)
{ {
tmpEntry = new sKeyDef; tmpEntry = new sKeyDef;
String key; String key;
key.assign(buf.substr(0, pos).c_str()); key.assign(buf.substr(0, pos).c_str());
String def; String def;
def.assign(buf.substr(pos+1).c_str()); def.assign(buf.substr(pos + 1).c_str());
key.trim(); key.trim();
key.toLower(); key.toLower();
int iKey = GetKeyEntry(key); int iKey = GetKeyEntry(key);
@ -1058,6 +1101,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
tmpEntry = 0; tmpEntry = 0;
} else { } else {
pos = buf.find(':'); pos = buf.find(':');
if (pos > String::npos) if (pos > String::npos)
{ {
tmpEntry = new sKeyDef; tmpEntry = new sKeyDef;
@ -1088,6 +1132,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
} // if !multiline } // if !multiline
} //if - main } //if - main
} }
// merge last section // merge last section
if (!Defq.empty()) if (!Defq.empty())
{ {
@ -1101,9 +1146,9 @@ int CLangMngr::MergeDefinitionFile(const char *file)
CLangMngr::CLang * CLangMngr::GetLang(const char *name) CLangMngr::CLang * CLangMngr::GetLang(const char *name)
{ {
LangVecIter iter; LangVecIter iter;
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter) for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
{ {
if ( strcmp((*iter)->GetName(), name)==0 ) if (strcmp((*iter)->GetName(), name) == 0)
return (*iter); return (*iter);
} }
@ -1118,9 +1163,9 @@ CLangMngr::CLang * CLangMngr::GetLang(const char *name)
CLangMngr::CLang * CLangMngr::GetLangR(const char *name) CLangMngr::CLang * CLangMngr::GetLangR(const char *name)
{ {
LangVecIter iter; LangVecIter iter;
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter) for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
{ {
if ( strcmp((*iter)->GetName(), name)==0 ) if (strcmp((*iter)->GetName(), name) == 0)
return (*iter); return (*iter);
} }
@ -1132,6 +1177,7 @@ const char *CLangMngr::GetDef(const char *langName, const char *key)
CLang *lang = GetLangR(langName); CLang *lang = GetLangR(langName);
if (lang) if (lang)
return lang->GetDef(key); return lang->GetDef(key);
return "ML_NOTFOUND(LANG)"; return "ML_NOTFOUND(LANG)";
} }
@ -1162,7 +1208,7 @@ bool CLangMngr::Save(const char *filename)
curOffset += sizeof(uint32_t); curOffset += sizeof(uint32_t);
uint32_t langOffset = curOffset + ktbSize + ltbSize; uint32_t langOffset = curOffset + ktbSize + ltbSize;
for (unsigned int i = 0; i<m_Languages.size(); i++) for (unsigned int i = 0; i < m_Languages.size(); i++)
{ {
langName = m_Languages[i]->GetName(); langName = m_Languages[i]->GetName();
fwrite(langName, sizeof(char), 2, fp); fwrite(langName, sizeof(char), 2, fp);
@ -1175,7 +1221,7 @@ bool CLangMngr::Save(const char *filename)
//Note - langOffset now points to the start of key lookup table //Note - langOffset now points to the start of key lookup table
uint32_t keyHash = 0; uint32_t keyHash = 0;
uint32_t keyOffset = langOffset; uint32_t keyOffset = langOffset;
for (unsigned int i = 0; i<KeyList.size(); i++) for (unsigned int i = 0; i < KeyList.size(); i++)
{ {
keyHash = KeyList[i]->hash; keyHash = KeyList[i]->hash;
fwrite((void*)&keyHash, sizeof(uint32_t), 1, fp); fwrite((void*)&keyHash, sizeof(uint32_t), 1, fp);
@ -1188,7 +1234,7 @@ bool CLangMngr::Save(const char *filename)
//Note - now keyOffset points toward the start of the def table //Note - now keyOffset points toward the start of the def table
int defOffset = keyOffset; int defOffset = keyOffset;
for (unsigned int i = 0; i<m_Languages.size(); i++) for (unsigned int i = 0; i < m_Languages.size(); i++)
{ {
m_Languages[i]->Save(fp, defOffset, curOffset); m_Languages[i]->Save(fp, defOffset, curOffset);
} }
@ -1196,7 +1242,7 @@ bool CLangMngr::Save(const char *filename)
//Now, defOffset points toward the END of the file //Now, defOffset points toward the END of the file
//curoffset should point toward the key table, so... //curoffset should point toward the key table, so...
unsigned char keyLen = 0; unsigned char keyLen = 0;
for (unsigned int i = 0; i<KeyList.size(); i++) for (unsigned int i = 0; i < KeyList.size(); i++)
{ {
keyLen = KeyList[i]->key.size(); keyLen = KeyList[i]->key.size();
fwrite((void*)&keyLen, sizeof(unsigned char), 1, fp); fwrite((void*)&keyLen, sizeof(unsigned char), 1, fp);
@ -1207,7 +1253,7 @@ bool CLangMngr::Save(const char *filename)
//Finally, write the def table //Finally, write the def table
// It's assumed no orders changed... // It's assumed no orders changed...
for (unsigned int i = 0; i<m_Languages.size(); i++) for (unsigned int i = 0; i < m_Languages.size(); i++)
{ {
m_Languages[i]->SaveDefinitions(fp, curOffset); m_Languages[i]->SaveDefinitions(fp, curOffset);
} }
@ -1232,7 +1278,7 @@ bool CLangMngr::SaveCache(const char *filename)
fwrite((void *)&dictCount, sizeof(short), 1, fp); fwrite((void *)&dictCount, sizeof(short), 1, fp);
for (i=FileList.begin(); i!=FileList.end(); i++) for (i = FileList.begin(); i != FileList.end(); i++)
{ {
len = (*i)->file.size(); len = (*i)->file.size();
fwrite((void *)&len, sizeof(char), 1, fp); fwrite((void *)&len, sizeof(char), 1, fp);
@ -1260,8 +1306,7 @@ bool CLangMngr::LoadCache(const char *filename)
fread((void*)&dictCount, sizeof(short), 1, fp); fread((void*)&dictCount, sizeof(short), 1, fp);
md5Pair *p = 0; md5Pair *p = 0;
for (int i = 1; i <= dictCount; i++)
for (int i=1; i<=dictCount; i++)
{ {
fread((void*)&len, sizeof(char), 1, fp); fread((void*)&len, sizeof(char), 1, fp);
fread(buf, sizeof(char), len, fp); fread(buf, sizeof(char), len, fp);
@ -1307,7 +1352,8 @@ bool CLangMngr::Load(const char *filename)
uint32_t *LangOffsets = new uint32_t[langCount]; uint32_t *LangOffsets = new uint32_t[langCount];
char langname[3]; char langname[3];
for (unsigned int i=0; i<langCount; i++)
for (unsigned int i = 0; i < langCount; i++)
{ {
fread(langname, sizeof(char), 2, fp); fread(langname, sizeof(char), 2, fp);
langname[2] = 0; langname[2] = 0;
@ -1320,7 +1366,8 @@ bool CLangMngr::Load(const char *filename)
keyEntry *e = 0; keyEntry *e = 0;
unsigned char keylen; unsigned char keylen;
uint32_t keyoffset, save; uint32_t keyoffset, save;
for (unsigned i=0; i<keycount; i++)
for (unsigned i = 0; i < keycount; i++)
{ {
e = new keyEntry; e = new keyEntry;
fread((void*)&(e->hash), sizeof(uint32_t), 1, fp); fread((void*)&(e->hash), sizeof(uint32_t), 1, fp);
@ -1328,7 +1375,7 @@ bool CLangMngr::Load(const char *filename)
save = ftell(fp); save = ftell(fp);
fseek(fp, keyoffset, SEEK_SET); fseek(fp, keyoffset, SEEK_SET);
fread((void*)&keylen, sizeof(char), 1, fp); fread((void*)&keylen, sizeof(char), 1, fp);
char *data = new char[keylen+1]; char *data = new char[keylen + 1];
fread(data, sizeof(char), keylen, fp); fread(data, sizeof(char), keylen, fp);
data[keylen] = 0; data[keylen] = 0;
e->key.assign(data); e->key.assign(data);
@ -1343,10 +1390,12 @@ bool CLangMngr::Load(const char *filename)
uint32_t defhash; uint32_t defhash;
uint32_t defoffset; uint32_t defoffset;
unsigned short deflen; unsigned short deflen;
for (unsigned int i=0; i<langCount; i++)
for (unsigned int i = 0; i < langCount; i++)
{ {
fread((void*)&numentries, sizeof(uint32_t), 1, fp); fread((void*)&numentries, sizeof(uint32_t), 1, fp);
for (unsigned int j=0; j<numentries; j++)
for (unsigned int j = 0; j < numentries; j++)
{ {
fread((void *)&keynum, sizeof(uint32_t), 1, fp); fread((void *)&keynum, sizeof(uint32_t), 1, fp);
fread((void *)&defhash, sizeof(uint32_t), 1, fp); fread((void *)&defhash, sizeof(uint32_t), 1, fp);
@ -1354,7 +1403,7 @@ bool CLangMngr::Load(const char *filename)
save = ftell(fp); save = ftell(fp);
fseek(fp, defoffset, SEEK_SET); fseek(fp, defoffset, SEEK_SET);
fread((void *)&deflen, sizeof(unsigned short), 1, fp); fread((void *)&deflen, sizeof(unsigned short), 1, fp);
char *data = new char[deflen+1]; char *data = new char[deflen + 1];
fread(data, sizeof(char), deflen, fp); fread(data, sizeof(char), deflen, fp);
data[deflen] = 0; data[deflen] = 0;
m_Languages[i]->AddEntry(keynum, defhash, data, true); m_Languages[i]->AddEntry(keynum, defhash, data, true);
@ -1379,19 +1428,20 @@ CLangMngr::~CLangMngr()
void CLangMngr::Clear() void CLangMngr::Clear()
{ {
unsigned int i = 0; unsigned int i = 0;
for (i=0; i<m_Languages.size(); i++)
for (i = 0; i < m_Languages.size(); i++)
{ {
if (m_Languages[i]) if (m_Languages[i])
delete m_Languages[i]; delete m_Languages[i];
} }
for (i=0; i<FileList.size(); i++) for (i = 0; i < FileList.size(); i++)
{ {
if (FileList[i]) if (FileList[i])
delete FileList[i]; delete FileList[i];
} }
for (i=0; i<KeyList.size(); i++) for (i = 0; i < KeyList.size(); i++)
{ {
if (KeyList[i]) if (KeyList[i])
delete KeyList[i]; delete KeyList[i];
@ -1411,7 +1461,8 @@ const char *CLangMngr::GetLangName(int langId)
{ {
int i = 0; int i = 0;
LangVecIter iter; LangVecIter iter;
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
{ {
if (i == langId) if (i == langId)
{ {
@ -1419,13 +1470,15 @@ const char *CLangMngr::GetLangName(int langId)
} }
i++; i++;
} }
return ""; return "";
} }
bool CLangMngr::LangExists(const char *langName) bool CLangMngr::LangExists(const char *langName)
{ {
char buf[3] = { 0 }; char buf[3] = {0};
int i = 0; int i = 0;
while (buf[i] = tolower(*langName++)) while (buf[i] = tolower(*langName++))
{ {
if (++i == 2) if (++i == 2)
@ -1433,11 +1486,13 @@ bool CLangMngr::LangExists(const char *langName)
} }
LangVecIter iter; LangVecIter iter;
for (iter=m_Languages.begin(); iter!=m_Languages.end(); ++iter)
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
{ {
if ( strcmp((*iter)->GetName(), buf)==0 ) if (strcmp((*iter)->GetName(), buf) == 0)
return true; return true;
} }
return false; return false;
} }

View File

@ -51,6 +51,7 @@ struct sKeyDef
{ {
sKeyDef() { key = -1; def = 0; } sKeyDef() { key = -1; def = 0; }
~sKeyDef() { if (def) delete def; } ~sKeyDef() { if (def) delete def; }
int key; int key;
String *def; String *def;
}; };
@ -77,8 +78,9 @@ class CLangMngr
// compare this language to a language name // compare this language to a language name
friend bool operator == (const CLang &left, const char *right) friend bool operator == (const CLang &left, const char *right)
{ {
return strcmp(left.m_LanguageName, right)==0 ? true : false; return strcmp(left.m_LanguageName, right) == 0 ? true : false;
} }
// Get language name // Get language name
const char *GetName() { return m_LanguageName; } const char *GetName() { return m_LanguageName; }
// Save to file // Save to file
@ -91,8 +93,8 @@ class CLangMngr
int Entries() { return m_LookUpTable.size(); } int Entries() { return m_LookUpTable.size(); }
// Make a hash from a string; convert to lowercase first if needed // Make a hash from a string; convert to lowercase first if needed
static uint32_t MakeHash(const char *src, bool makeLower = false); static uint32_t MakeHash(const char *src, bool makeLower = false);
protected:
protected:
// An entry in the language // An entry in the language
class LangEntry class LangEntry
{ {
@ -145,7 +147,7 @@ class CLangMngr
// Merge definitions into a language // 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 // strip lowercase; make lower if needed
static size_t strip(char *str, char *newstr, bool makelower=false); static size_t strip(char *str, char *newstr, bool makelower = false);
typedef CVector<CLang*> LangVec; typedef CVector<CLang*> LangVec;
typedef CVector<CLang*>::iterator LangVecIter; typedef CVector<CLang*>::iterator LangVecIter;

View File

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

View File

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

View File

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

View File

@ -35,7 +35,8 @@
// ***************************************************** // *****************************************************
// class MenuMngr // class MenuMngr
// ***************************************************** // *****************************************************
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) { MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
{
plugin = a; plugin = a;
keys = k; keys = k;
menuid = mi; menuid = mi;
@ -50,28 +51,35 @@ MenuMngr::~MenuMngr()
int MenuMngr::findMenuId(const char* name, AMX* amx) int MenuMngr::findMenuId(const char* name, AMX* amx)
{ {
for( MenuIdEle* b = headid; b ; b = b->next) { for (MenuIdEle* b = headid; b; b = b->next)
if ( (!b->amx || amx == b->amx) && strstr(name,b->name.c_str()) ) {
if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
return b->id; return b->id;
} }
return 0; return 0;
} }
int MenuMngr::registerMenuId(const char* n, AMX* a ) int MenuMngr::registerMenuId(const char* n, AMX* a)
{ {
int id = findMenuId( n, a ); int id = findMenuId(n, a);
if (id) return id;
headid = new MenuIdEle( n, a , headid ); if (id)
return id;
headid = new MenuIdEle(n, a, headid);
if (!headid) if (!headid)
return 0; // :TODO: Better error report return 0; // :TODO: Better error report
return headid->id; return headid->id;
} }
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f ) void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f)
{ {
MenuCommand** temp = &headcmd; MenuCommand** temp = &headcmd;
while(*temp) temp = &(*temp)->next; while (*temp) temp = &(*temp)->next;
*temp = new MenuCommand(a,mi, k,f); *temp = new MenuCommand(a, mi, k, f);
} }
void MenuMngr::clear() void MenuMngr::clear()

View File

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

View File

@ -33,7 +33,7 @@
// class CPlayer // class CPlayer
// ***************************************************** // *****************************************************
void CPlayer::Init( edict_t* e , int i ) void CPlayer::Init(edict_t* e, int i)
{ {
index = i; index = i;
pEdict = e; pEdict = e;
@ -55,46 +55,63 @@ void CPlayer::Init( edict_t* e , int i )
team.clear(); team.clear();
} }
void CPlayer::Disconnect() { void CPlayer::Disconnect()
{
ingame = false; ingame = false;
initialized = false; initialized = false;
authorized = false; authorized = false;
while (!cvarQueryQueue.empty())
{
ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
unregisterSPForward(pQuery->resultFwd);
if (pQuery->params)
delete [] pQuery->params;
delete pQuery;
cvarQueryQueue.pop();
}
bot = 0; bot = 0;
} }
void CPlayer::PutInServer() { void CPlayer::PutInServer()
{
playtime = gpGlobals->time; playtime = gpGlobals->time;
ingame = true; ingame = true;
} }
bool CPlayer::Connect(const char* connectname,const char* ipaddress) {
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
{
name.assign(connectname); name.assign(connectname);
ip.assign(ipaddress); ip.assign(ipaddress);
time = gpGlobals->time; time = gpGlobals->time;
bot = IsBot(); bot = IsBot();
death_killer = 0; death_killer = 0;
memset(flags,0,sizeof(flags));
memset(weapons,0,sizeof(weapons)); memset(flags, 0, sizeof(flags));
memset(weapons, 0, sizeof(weapons));
initialized = true; initialized = true;
authorized = false; authorized = false;
const char* authid = GETPLAYERAUTHID( pEdict ); const char* authid = GETPLAYERAUTHID(pEdict);
if ( (authid == 0) || (*authid == 0) if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
|| (strcmp( authid , "STEAM_ID_PENDING") == 0) )
return true; return true;
return false; return false;
} }
// ***************************************************** // *****************************************************
// class Grenades // class Grenades
// ***************************************************** // *****************************************************
void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
void Grenades::put(edict_t* grenade, float time, int type, CPlayer* player)
{ {
Obj* a = new Obj; Obj* a = new Obj;
if ( a == 0 ) return; if (a == 0) return;
a->player = player; a->player = player;
a->grenade = grenade; a->grenade = grenade;
a->time = gpGlobals->time + time; a->time = gpGlobals->time + time;
@ -103,34 +120,37 @@ void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
head = a; head = a;
} }
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type ) bool Grenades::find(edict_t* enemy, CPlayer** p, int& type)
{ {
bool found = false; bool found = false;
Obj** a = &head; Obj** a = &head;
while ( *a ){
if ( (*a)->time > gpGlobals->time ) { while (*a)
if ( (*a)->grenade == enemy ) { {
if ((*a)->time > gpGlobals->time)
{
if ((*a)->grenade == enemy)
{
found = true; found = true;
(*p) = (*a)->player; (*p) = (*a)->player;
type = (*a)->type; type = (*a)->type;
} }
} } else {
else {
Obj* b = (*a)->next; Obj* b = (*a)->next;
delete *a; delete *a;
*a = b; *a = b;
continue; continue;
} }
a = &(*a)->next; a = &(*a)->next;
} }
return found; return found;
} }
void Grenades::clear() void Grenades::clear()
{ {
while(head){ while (head)
{
Obj* a = head->next; Obj* a = head->next;
delete head; delete head;
head = a; head = a;
@ -140,93 +160,119 @@ void Grenades::clear()
// ***************************************************** // *****************************************************
// class XVars // class XVars
// ***************************************************** // *****************************************************
void XVars::clear() {
void XVars::clear()
{
delete[] head; delete[] head;
head = 0; head = 0;
num = 0; num = 0;
size = 0; size = 0;
} }
int XVars::put( AMX* p, cell* v ) int XVars::put(AMX* p, cell* v)
{ {
for(int a = 0; a < num; ++a) { for (int a = 0; a < num; ++a)
if ( (head[a].amx == p) && (head[a].value == v) ) {
if ((head[a].amx == p) && (head[a].value == v))
return a; return a;
} }
if ( (num >= size) && realloc_array( size ? (size * 2) : 8 ) ) if ((num >= size) && realloc_array(size ? (size * 2) : 8))
return -1; return -1;
head[num].value = v; head[num].value = v;
head[num].amx = p; head[num].amx = p;
return num++; return num++;
} }
int XVars::realloc_array( int nsize ) int XVars::realloc_array(int nsize)
{ {
XVarEle* me = new XVarEle[nsize]; XVarEle* me = new XVarEle[nsize];
if ( me ){
for(int a = 0 ; a < num; ++a) if (me)
{
for (int a = 0 ; a < num; ++a)
me[a] = head[a]; me[a] = head[a];
delete[] head; delete[] head;
head = me; head = me;
size = nsize; size = nsize;
return 0; return 0;
} }
return 1; return 1;
} }
// ***************************************************** // *****************************************************
// class TeamIds // class TeamIds
// ***************************************************** // *****************************************************
TeamIds::TeamIds() { head = 0; newTeam = 0; } TeamIds::TeamIds() { head = 0; newTeam = 0; }
TeamIds::~TeamIds() {
while( head ) { TeamIds::~TeamIds()
{
while (head)
{
TeamEle* a = head->next; TeamEle* a = head->next;
delete head; delete head;
head = a; head = a;
} }
} }
void TeamIds::registerTeam( const char* n ,int s ) void TeamIds::registerTeam(const char* n, int s)
{ {
TeamEle** a = &head; TeamEle** a = &head;
while( *a ){
if ( strcmp((*a)->name.c_str(),n) == 0 ){ while (*a)
if (s != -1){ {
if (strcmp((*a)->name.c_str(),n) == 0)
{
if (s != -1)
{
(*a)->id = s; (*a)->id = s;
newTeam &= ~(1<<(*a)->tid); newTeam &= ~(1<<(*a)->tid);
} }
return; return;
} }
a = &(*a)->next; a = &(*a)->next;
} }
*a = new TeamEle( n , s );
if ( *a == 0 ) return; *a = new TeamEle(n, s);
if (*a == 0)
return;
newTeam |= (1<<(*a)->tid); newTeam |= (1<<(*a)->tid);
} }
int TeamIds::findTeamId( const char* n ) int TeamIds::findTeamId(const char* n)
{ {
TeamEle* a = head; TeamEle* a = head;
while( a ){
if ( !strcmpi(a->name.c_str(),n) ) while (a)
{
if (!stricmp(a->name.c_str(), n))
return a->id; return a->id;
a = a->next; a = a->next;
} }
return -1; return -1;
} }
int TeamIds::findTeamIdCase( const char* n) int TeamIds::findTeamIdCase(const char* n)
{ {
TeamEle* a = head; TeamEle* a = head;
while( a ){
if ( !strcmp(a->name.c_str(), n) ) while (a)
{
if (!strcmp(a->name.c_str(), n))
return a->id; return a->id;
a = a->next; a = a->next;
} }
return -1; return -1;
} }
char TeamIds::TeamEle::uid = 0; char TeamIds::TeamEle::uid = 0;

View File

@ -37,34 +37,44 @@
// ***************************************************** // *****************************************************
// class CCVar // class CCVar
// ***************************************************** // *****************************************************
class CCVar class CCVar
{ {
cvar_t cvar; cvar_t cvar;
String name; String name;
String plugin; String plugin;
public: public:
CCVar( const char* pname, const char* pplugin, CCVar(const char* pname, const char* pplugin, int pflags, float pvalue) : name(pname), plugin(pplugin)
int pflags, float pvalue ) : name(pname) , plugin(pplugin ) { {
cvar.name = (char*)name.c_str(); cvar.name = (char*)name.c_str();
cvar.flags = pflags; cvar.flags = pflags;
cvar.string = ""; cvar.string = "";
cvar.value = pvalue; cvar.value = pvalue;
} }
inline cvar_t* getCvar() { return &cvar; } inline cvar_t* getCvar() { return &cvar; }
inline const char* getPluginName() { return plugin.c_str(); } inline const char* getPluginName() { return plugin.c_str(); }
inline const char* getName() { return name.c_str(); } inline const char* getName() { return name.c_str(); }
inline bool operator == ( const char* string ) { return (strcmp(name.c_str(),string)==0); } inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); }
}; };
// ***************************************************** // *****************************************************
// class CPlayer // class CPlayer
// ***************************************************** // *****************************************************
struct ClientCvarQuery_Info
{
bool querying; // Are we actually waiting for a response at the moment?
String cvarName;
int resultFwd;
int paramLen;
cell *params;
};
class CPlayer class CPlayer
{ {
public: public:
edict_t* pEdict; edict_t* pEdict;
@ -80,7 +90,8 @@ public:
float time; float time;
float playtime; float playtime;
struct { struct
{
int ammo; int ammo;
int clip; int clip;
} weapons[MAX_WEAPONS]; } weapons[MAX_WEAPONS];
@ -99,22 +110,29 @@ public:
int death_victim; int death_victim;
bool death_tk; bool death_tk;
String death_weapon; String death_weapon;
int newmenu;
int page;
Vector lastTrace; Vector lastTrace;
Vector thisTrace; Vector thisTrace;
Vector lastHit; Vector lastHit;
void Init( edict_t* e , int i ); CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
void Init(edict_t* e, int i);
void Disconnect(); void Disconnect();
void PutInServer(); void PutInServer();
bool Connect(const char* connectname,const char* ipaddress);
inline bool IsBot(){ bool Connect(const char* connectname, const char* ipaddress);
return ((pEdict->v.flags & FL_FAKECLIENT)?true:false);
inline bool IsBot()
{
return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
} }
inline bool IsAlive(){ inline bool IsAlive()
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0)); {
return ((pEdict->v.deadflag == DEAD_NO) && (pEdict->v.health > 0));
} }
inline void Authorize() { authorized = true; } inline void Authorize() { authorized = true; }
@ -136,31 +154,35 @@ class Grenades
Obj* next; Obj* next;
} *head; } *head;
public: public:
Grenades() { head = 0; } Grenades() { head = 0; }
~Grenades() { clear(); } ~Grenades() { clear(); }
void put( edict_t* grenade, float time, int type, CPlayer* player );
bool find( edict_t* enemy, CPlayer** p, int& type ); void put(edict_t* grenade, float time, int type, CPlayer* player);
bool find(edict_t* enemy, CPlayer** p, int& type);
void clear(); void clear();
}; };
// ***************************************************** // *****************************************************
// class ForceObject // class ForceObject
// ***************************************************** // *****************************************************
class ForceObject {
class ForceObject
{
String filename; String filename;
FORCE_TYPE type; FORCE_TYPE type;
Vector mins; Vector mins;
Vector maxs; Vector maxs;
AMX* amx; AMX* amx;
public: public:
ForceObject(const char* n, FORCE_TYPE c,Vector& mi, Vector& ma, AMX* a) : ForceObject(const char* n, FORCE_TYPE c, Vector& mi, Vector& ma, AMX* a) : filename(n), type(c), mins(mi), maxs(ma), amx(a) {}
filename(n) , type(c), mins(mi), maxs(ma), amx(a) {}
inline const char* getFilename() { return filename.c_str(); } inline const char* getFilename() { return filename.c_str(); }
inline AMX* getAMX() { return amx; } inline AMX* getAMX() { return amx; }
Vector& getMin() { return mins; } Vector& getMin() { return mins; }
Vector& getMax() { return maxs; } Vector& getMax() { return maxs; }
inline FORCE_TYPE getForceType() { return type; } inline FORCE_TYPE getForceType() { return type; }
}; };
@ -170,30 +192,38 @@ public:
class XVars class XVars
{ {
struct XVarEle { struct XVarEle
{
AMX* amx; AMX* amx;
cell* value; cell* value;
}; };
XVarEle* head; XVarEle* head;
int size; int size;
int num; int num;
int realloc_array(int nsize);
int realloc_array( int nsize );
public: public:
XVars() { num = 0; size = 0; head = 0; } XVars() { num = 0; size = 0; head = 0; }
~XVars() { clear(); } ~XVars() { clear(); }
void clear(); void clear();
int put( AMX* a, cell* v ); int put(AMX* a, cell* v);
inline cell getValue( int a ) {
return ( a >= 0 && a < num ) ? *(head[a].value) : 0; inline cell getValue(int a)
{
return (a >= 0 && a < num) ? *(head[a].value) : 0;
} }
inline int setValue( int a, cell v ) {
if ( a >= 0 && a < num ){ inline int setValue(int a, cell v)
{
if (a >= 0 && a < num)
{
*(head[a].value) = v; *(head[a].value) = v;
return 0; return 0;
} }
return 1; return 1;
} }
}; };
@ -201,34 +231,41 @@ public:
// ***************************************************** // *****************************************************
// class CScript // class CScript
// ***************************************************** // *****************************************************
class CScript class CScript
{ {
String filename; String filename;
AMX* amx; AMX* amx;
void* code; void* code;
public: public:
CScript(AMX* aa, void* cc,const char* ff):filename(ff),amx(aa),code(cc){} CScript(AMX* aa, void* cc, const char* ff) : filename(ff), amx(aa), code(cc) {}
inline AMX* getAMX() { return amx; } inline AMX* getAMX() { return amx; }
inline const char* getName() { return filename.c_str(); } inline const char* getName() { return filename.c_str(); }
inline bool operator==( void* a ) { return (amx == (AMX*)a); } inline bool operator==(void* a) { return (amx == (AMX*)a); }
inline void* getCode() { return code; } inline void* getCode() { return code; }
}; };
// ***************************************************** // *****************************************************
// class TeamIds // class TeamIds
// ***************************************************** // *****************************************************
class TeamIds class TeamIds
{ {
struct TeamEle { struct TeamEle
{
String name; String name;
int id; int id;
char tid; char tid;
static char uid; static char uid;
TeamEle* next; TeamEle* next;
TeamEle(const char* n, int& i) : name(n) , id(i) , next(0) {
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
{
tid = uid++; tid = uid++;
}; }
~TeamEle(){ --uid; }
~TeamEle() { --uid; }
} *head; } *head;
int newTeam; int newTeam;
@ -236,15 +273,11 @@ class TeamIds
public: public:
TeamIds(); TeamIds();
~TeamIds(); ~TeamIds();
void registerTeam( const char* n ,int s );
int findTeamId( const char* n); void registerTeam(const char* n, int s);
int findTeamIdCase( const char* n); int findTeamId(const char* n);
int findTeamIdCase(const char* n);
inline bool isNewTeam() { return newTeam ? true : false; } inline bool isNewTeam() { return newTeam ? true : false; }
}; };
#endif //CMISC_H
#endif

View File

@ -32,14 +32,9 @@
#include "amxmodx.h" #include "amxmodx.h"
#ifndef FAR #ifndef FAR
#define FAR #define FAR
#endif #endif
// Old
typedef int (FAR *QUERYMOD)(module_info_s**);
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
typedef int (FAR *DETACHMOD)(void);
// New // New
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/); typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/); typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
@ -47,81 +42,6 @@ typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
typedef int (FAR *DETACHMOD_NEW)(void); typedef int (FAR *DETACHMOD_NEW)(void);
typedef void (FAR *PLUGINSLOADED_NEW)(void); typedef void (FAR *PLUGINSLOADED_NEW)(void);
// Old
// These functions are needed since Small Abstract Machine 2.5.0
int wamx_FindPublic(AMX *amx, char *name, int *index)
{ return amx_FindPublic(amx, name, index); }
int wamx_FindPubVar(AMX *amx, char *varname, cell *amx_addr)
{ return amx_FindPubVar(amx, varname, amx_addr); }
int wamx_GetString(char *dest, cell *source)
{ return amx_GetString(dest, source, 0); }
AMX_NATIVE_INFO *wamx_NativeInfo(char *name, AMX_NATIVE func)
{ return amx_NativeInfo(name, func); }
int wamx_SetString(cell *dest, char *source, int pack)
{ return amx_SetString(dest, source, pack, 0); }
pfnamx_engine_g engAmxFunc = {
amx_Align16,
amx_Align32,
amx_Allot,
amx_Callback,
amx_Clone,
amx_Debug,
amx_Exec,
amx_Execv,
wamx_FindPublic,
wamx_FindPubVar,
amx_FindTagId,
amx_Flags,
amx_GetAddr,
amx_GetPublic,
amx_GetPubVar,
wamx_GetString,
amx_GetTag,
amx_GetUserData,
amx_Init,
amx_InitJIT,
amx_MemInfo,
amx_NameLength,
wamx_NativeInfo,
amx_NumPublics,
amx_NumPubVars,
amx_NumTags,
amx_RaiseError,
amx_Register,
amx_Release,
amx_SetCallback,
amx_SetDebugHook,
wamx_SetString,
amx_SetUserData,
amx_StrLen,
};
pfnmodule_engine_g engModuleFunc = {
add_amxnatives,
build_pathname,
copy_amxmemory,
format_amxstring,
get_amxaddr,
get_amxscript,
get_amxscriptname,
get_amxstring,
get_modname,
load_amxscript,
print_srvconsole,
report_error,
set_amxnatives,
set_amxstring,
amxstring_len,
unload_amxscript,
alloc_amxmemory,
free_amxmemory,
};
// ***************************************************** // *****************************************************
// class CModule // class CModule
// ***************************************************** // *****************************************************
@ -135,7 +55,7 @@ CModule::CModule(const char* fname)
CModule::~CModule() CModule::~CModule()
{ {
// old & new // old & new
if ( m_Handle ) if (m_Handle)
DLFREE(m_Handle); DLFREE(m_Handle);
clear(); clear();
@ -147,11 +67,10 @@ void CModule::clear(bool clearFilename)
m_Metamod = false; m_Metamod = false;
m_Handle = NULL; m_Handle = NULL;
m_Status = MODULE_NONE; m_Status = MODULE_NONE;
if (clearFilename) if (clearFilename)
m_Filename.assign("unknown"); m_Filename.assign("unknown");
// old
m_InfoOld = NULL;
// new // new
m_Amxx = false; m_Amxx = false;
m_InfoNew.author = "unknown"; m_InfoNew.author = "unknown";
@ -163,6 +82,26 @@ void CModule::clear(bool clearFilename)
m_Natives.clear(); m_Natives.clear();
} }
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
{
void **handle;
void *dummy = NULL;
if (!m_Handle)
handle = &dummy;
else
handle = (void **)&m_Handle;
int res = LoadMetamodPlugin(mmfile, handle, now);
if (!res)
{
m_Metamod = false;
}
return true;
}
bool CModule::attachModule() bool CModule::attachModule()
{ {
// old & new // old & new
@ -176,6 +115,7 @@ bool CModule::attachModule()
if (!AttachFunc_New) if (!AttachFunc_New)
return false; return false;
g_ModuleCallReason = ModuleCall_Attach; g_ModuleCallReason = ModuleCall_Attach;
g_CurrentlyCalledModule = this; g_CurrentlyCalledModule = this;
int retVal = (*AttachFunc_New)(Module_ReqFnptr); int retVal = (*AttachFunc_New)(Module_ReqFnptr);
@ -200,17 +140,11 @@ bool CModule::attachModule()
m_Status = MODULE_BADLOAD; m_Status = MODULE_BADLOAD;
return false; return false;
} }
} else {
m_Status = MODULE_BADLOAD;
} }
else
{
// old
ATTACHMOD AttachFunc = (ATTACHMOD)DLPROC(m_Handle, "AMX_Attach");
if (AttachFunc) return false;
(*AttachFunc)(&engAmxFunc,&engModuleFunc);
m_Status = MODULE_LOADED;
return true;
}
} }
bool CModule::queryModule() bool CModule::queryModule()
@ -231,6 +165,7 @@ bool CModule::queryModule()
// Try new interface first // Try new interface first
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query"); QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
if (queryFunc_New) if (queryFunc_New)
{ {
m_Amxx = true; m_Amxx = true;
@ -240,6 +175,7 @@ bool CModule::queryModule()
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew); int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
g_CurrentlyCalledModule = NULL; g_CurrentlyCalledModule = NULL;
g_ModuleCallReason = ModuleCall_NotCalled; g_ModuleCallReason = ModuleCall_NotCalled;
switch (retVal) switch (retVal)
{ {
case AMXX_PARAM: case AMXX_PARAM:
@ -269,48 +205,11 @@ bool CModule::queryModule()
m_Status = MODULE_QUERY; m_Status = MODULE_QUERY;
return true; return true;
} } else {
else
{
// old interface not 64 bit compatible
#if SMALL_CELL_SIZE == 64
m_Status = MODULE_NOT64BIT;
return false;
#else
// Try old interface
QUERYMOD queryFunc_Old = (QUERYMOD)DLPROC(m_Handle,"AMX_Query"); // check what version
if (!queryFunc_Old)
{
m_Status = MODULE_NOQUERY; m_Status = MODULE_NOQUERY;
m_Amxx = false;
return false; return false;
} }
(*queryFunc_Old)(&m_InfoOld);
if (!m_InfoOld)
{
m_Status = MODULE_NOINFO;
return false;
}
if (m_InfoOld->ivers != AMX_INTERFACE_VERSION)
{
m_Status = MODULE_OLD;
return false;
}
// Check for attach
if (!DLPROC(m_Handle, "AMX_Attach"))
{
m_Status = MODULE_NOATTACH;
return false;
}
m_InfoOld->serial = (long int)this;
m_Status = MODULE_QUERY;
return true;
#endif
}
} }
bool CModule::detachModule() bool CModule::detachModule()
@ -321,6 +220,7 @@ bool CModule::detachModule()
if (m_Amxx) if (m_Amxx)
{ {
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach"); DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
if (detachFunc_New) if (detachFunc_New)
{ {
g_ModuleCallReason = ModuleCall_Detach; g_ModuleCallReason = ModuleCall_Detach;
@ -330,14 +230,17 @@ bool CModule::detachModule()
g_ModuleCallReason = ModuleCall_NotCalled; g_ModuleCallReason = ModuleCall_NotCalled;
} }
} }
else
#ifndef FAKEMETA
if (IsMetamod())
{ {
DETACHMOD detachFunc_Old = (DETACHMOD)DLPROC(m_Handle, "AMX_Detach"); UnloadMetamodPlugin(m_Handle);
if (detachFunc_Old)
(*detachFunc_Old)();
} }
#endif
DLFREE(m_Handle); DLFREE(m_Handle);
clear(); clear();
return true; return true;
} }
@ -350,14 +253,16 @@ void CModule::CallPluginsLoaded()
return; return;
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded"); PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
if (!func) if (!func)
return; return;
func(); func();
} }
const char* CModule::getStatus() const const char* CModule::getStatus() const
{ {
switch(m_Status) switch (m_Status)
{ {
case MODULE_NONE: return "error"; case MODULE_NONE: return "error";
case MODULE_QUERY: return "pending"; case MODULE_QUERY: return "pending";
@ -373,5 +278,6 @@ const char* CModule::getStatus() const
case MODULE_NOT64BIT: return "not 64bit"; case MODULE_NOT64BIT: return "not 64bit";
default: break; default: break;
} }
return "unknown"; return "unknown";
} }

View File

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

View File

@ -33,28 +33,61 @@
#include "CPlugin.h" #include "CPlugin.h"
#include "CForward.h" #include "CForward.h"
#include "CFile.h" #include "CFile.h"
#include "amx.h"
#include "natives.h"
#include "debugger.h"
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) { extern const char *no_function;
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
{
CPlugin** a = &head; CPlugin** a = &head;
while( *a ) a = &(*a)->next;
*a = new CPlugin( pCounter++ ,path,name,error, debug); while (*a)
a = &(*a)->next;
*a = new CPlugin(pCounter++, path, name, error, debug);
return (*a); return (*a);
} }
void CPluginMngr::unloadPlugin( CPlugin** a ) { void CPluginMngr::unloadPlugin(CPlugin** a)
{
CPlugin* next = (*a)->next; CPlugin* next = (*a)->next;
delete *a; delete *a;
*a = next; *a = next;
--pCounter; --pCounter;
} }
int CPluginMngr::loadPluginsFromFile( const char* filename ) void CPluginMngr::Finalize()
{ {
FILE *fp = fopen(build_pathname("%s",filename) , "rt"); if (m_Finalized)
return;
if ( !fp ) pNatives = BuildNativeTable();
CPlugin *a = head;
while (a)
{ {
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename); if (a->getStatusCode() == ps_running)
{
amx_Register(a->getAMX(), pNatives, -1);
a->Finalize();
}
a = a->next;
}
m_Finalized = true;
}
int CPluginMngr::loadPluginsFromFile(const char* filename)
{
char file[256];
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
if (!fp)
{
AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
return 1; return 1;
} }
@ -65,22 +98,26 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
String line; String line;
while ( !feof(fp) ) while (!feof(fp))
{ {
*pluginName = 0; pluginName[0] = '\0';
*debug = 0;
debug[0] = '\0';
debugFlag = 0; debugFlag = 0;
line.clear(); line.clear();
line._fread(fp); line._fread(fp);
sscanf(line.c_str(),"%s %s",pluginName, debug); sscanf(line.c_str(), "%s %s", pluginName, debug);
if (!isalnum(*pluginName)) continue;
if (!isalnum(*pluginName))
continue;
if (isalnum(*debug) && strcmp(debug, "debug") == 0) if (isalnum(*debug) && strcmp(debug, "debug") == 0)
{ {
debugFlag = 1; debugFlag = 1;
} }
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error, debugFlag); CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
if (plugin->getStatusCode() == ps_bad_load) if (plugin->getStatusCode() == ps_bad_load)
{ {
@ -96,46 +133,72 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
return pCounter; return pCounter;
} }
void CPluginMngr::clear() { void CPluginMngr::clear()
{
CPlugin**a = &head; CPlugin**a = &head;
while ( *a )
while (*a)
unloadPlugin(a); unloadPlugin(a);
m_Finalized = false;
if (pNatives)
{
delete [] pNatives;
pNatives = NULL;
}
} }
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx) CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
{ {
return (CPlugin*)(amx->userdata[3]); return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
} }
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) { CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
{
CPlugin*a = head; CPlugin*a = head;
while ( a && &a->amx != amx )
a=a->next; while (a && &a->amx != amx)
a = a->next;
return a; return a;
} }
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){ CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index)
{
CPlugin*a = head; CPlugin*a = head;
while ( a && index--)
a=a->next; while (a && index--)
a = a->next;
return a; return a;
} }
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) { CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
if (!name) return 0; {
if (!name)
return 0;
int len = strlen(name); int len = strlen(name);
if (!len) return 0;
if (!len)
return 0;
CPlugin*a = head; CPlugin*a = head;
while( a && strncmp(a->name.c_str(), name,len) )
a=a->next; while (a && strncmp(a->name.c_str(), name, len))
a = a->next;
return a; return a;
} }
const char* CPluginMngr::CPlugin::getStatus() const { const char* CPluginMngr::CPlugin::getStatus() const
switch(status){ {
switch (status)
{
case ps_running: case ps_running:
{ {
if (getAMX()->flags & AMX_FLAG_DEBUG) if (m_Debug)
{ {
return "debug"; return "debug";
} else { } else {
@ -148,47 +211,152 @@ const char* CPluginMngr::CPlugin::getStatus() const {
case ps_stopped: return "stopped"; case ps_stopped: return "stopped";
case ps_locked: return "locked"; case ps_locked: return "locked";
} }
return "error"; return "error";
} }
CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d) : name(n), title(n) { CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n)
{
const char* unk = "unknown"; const char* unk = "unknown";
title.assign(unk); title.assign(unk);
author.assign(unk); author.assign(unk);
version.assign(unk); version.assign(unk);
char* path = build_pathname("%s/%s",p,n);
char file[256];
char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
code = 0; code = 0;
int err = load_amxscript(&amx,&code,path,e, d); memset(&amx, 0, sizeof(AMX));
if ( err == AMX_ERR_NONE ) int err = load_amxscript(&amx, &code, path, e, d);
if (err == AMX_ERR_NONE)
{ {
status = ps_running; status = ps_running;
} else { } else {
status = ps_bad_load; status = ps_bad_load;
} }
amx.userdata[3] = this;
amx.userdata[UD_FINDPLUGIN] = this;
paused_fun = 0; paused_fun = 0;
next = 0; next = 0;
id = i; id = i;
}
CPluginMngr::CPlugin::~CPlugin( ){
unload_amxscript( &amx, &code );
}
void CPluginMngr::CPlugin::pauseFunction( int id ) { if (status == ps_running)
if (isValid()){ {
paused_fun |= (1<<id); m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
g_commands.clearBufforedInfo(); m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
if (amx.flags & AMX_FLAG_DEBUG)
{
m_Debug = true;
} else {
m_Debug = false;
}
} }
} }
void CPluginMngr::CPlugin::unpauseFunction( int id ) { CPluginMngr::CPlugin::~CPlugin()
if (isValid()) { {
paused_fun &= ~(1<<id); unload_amxscript(&amx, &code);
g_commands.clearBufforedInfo(); }
int AMXAPI native_handler(AMX *amx, int index)
{
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
char name[sNAMEMAX + 1];
amx_GetNative(amx, index, name);
return pHandler->HandleNative(name, index, 0);
}
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
{
//A script has accidentally called an invalid native! give them a
// first chance to block the resulting error.
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
//this should never happen
if (!pHandler)
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
//this should never happen because this native won't be called
// if the plugin isn't filtering.
if (!pHandler->IsNativeFiltering())
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
char name[sNAMEMAX + 1];
int native = amx->usertags[UT_NATIVE];
int err = amx_GetNative(amx, native, name);
if (err != AMX_ERR_NONE)
name[0] = '\0';
//1 - because we're trapping usage
if (!pHandler->HandleNative(name, native, 1))
{
LogError(amx, AMX_ERR_INVNATIVE, NULL);
return 0;
}
//Someday maybe allow native filters to write their own return value?
return 0;
}
void CPluginMngr::CPlugin::Finalize()
{
char buffer[128];
int old_status = status;
if (CheckModules(&amx, buffer))
{
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
{
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
int res = 0;
if (pHandler->IsNativeFiltering())
res = amx_CheckNatives(&amx, native_handler);
if (!res)
{
status = ps_bad_load;
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND;
} else {
amx_RegisterToAny(&amx, invalid_native);
}
}
} else {
status = ps_bad_load;
errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND;
}
if (old_status != status)
{
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
} }
} }
void CPluginMngr::CPlugin::setStatus( int a ) { void CPluginMngr::CPlugin::pauseFunction(int id)
{
}
void CPluginMngr::CPlugin::unpauseFunction(int id)
{
}
void CPluginMngr::CPlugin::setStatus(int a)
{
status = a; status = a;
g_commands.clearBufforedInfo(); // ugly way g_commands.clearBufforedInfo(); // ugly way
} }
@ -199,16 +367,8 @@ void CPluginMngr::CPlugin::pausePlugin()
if (isValid()) if (isValid())
{ {
// call plugin_pause if provided // call plugin_pause if provided
int func; if (m_PauseFwd != -1)
cell retval; executeForwards(m_PauseFwd);
if (amx_FindPublic(&amx, "plugin_pause", &func) == AMX_ERR_NONE)
{
if (isExecutable(func))
{
amx_Exec(&amx, &retval, func, 0);
}
}
setStatus(ps_paused); setStatus(ps_paused);
} }
@ -220,17 +380,10 @@ void CPluginMngr::CPlugin::unpausePlugin()
if (isValid()) if (isValid())
{ {
// set status first so the function will be marked executable // set status first so the function will be marked executable
setStatus(ps_running); setStatus(ps_running);
// call plugin_unpause if provided // call plugin_unpause if provided
int func; if (m_UnpauseFwd != -1)
cell retval; executeForwards(m_UnpauseFwd);
if (amx_FindPublic(&amx, "plugin_unpause", &func) == AMX_ERR_NONE)
{
if (isExecutable(func))
{
amx_Exec(&amx, &retval, func, 0);
}
}
} }
} }

View File

@ -36,18 +36,18 @@
// class CPluginMngr // class CPluginMngr
// ***************************************************** // *****************************************************
enum { enum
{
ps_bad_load, ps_bad_load,
ps_error, ps_error,
ps_locked,
ps_paused, ps_paused,
ps_running,
ps_stopped, ps_stopped,
ps_locked ps_running,
}; };
class CPluginMngr class CPluginMngr
{ {
public: public:
class iterator; class iterator;
@ -59,20 +59,25 @@ public:
AMX amx; AMX amx;
void* code; void* code;
String name; String name;
String version; String version;
String title; String title;
String author; String author;
String errorMsg; String errorMsg;
int m_PauseFwd;
int m_UnpauseFwd;
int paused_fun; int paused_fun;
int status; int status;
CPlugin* next; CPlugin* next;
int id; int id;
CPlugin(int i , const char* p,const char* n, char* e, int d);
~CPlugin( );
CPlugin(int i, const char* p, const char* n, char* e, int d);
~CPlugin();
bool m_Debug;
public: public:
inline const char* getName() { return name.c_str();} inline const char* getName() { return name.c_str();}
inline const char* getVersion() { return version.c_str();} inline const char* getVersion() { return version.c_str();}
inline const char* getTitle() { return title.c_str();} inline const char* getTitle() { return title.c_str();}
@ -82,44 +87,52 @@ public:
inline int getId() const { return id; } inline int getId() const { return id; }
inline AMX* getAMX() { return &amx; } inline AMX* getAMX() { return &amx; }
inline const AMX* getAMX() const { return &amx; } inline const AMX* getAMX() const { return &amx; }
inline void setTitle( const char* n ) { title.assign(n); } inline void setTitle(const char* n) { title.assign(n); }
inline void setAuthor( const char* n ) { author.assign(n); } inline void setAuthor(const char* n) { author.assign(n); }
inline void setVersion( const char* n ) { version.assign(n); } inline void setVersion(const char* n) { version.assign(n); }
inline void setError( const char* n ) { errorMsg.assign(n); } inline void setError(const char* n) { errorMsg.assign(n); }
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); } inline bool isValid() const { return (status >= ps_paused); }
inline bool isPaused() const { return ( (status == ps_paused) || (status == ps_stopped)); } inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
inline bool isFunctionPaused( int id ) const { return (paused_fun & (1<<id)) ? true : false; } inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
inline bool isExecutable(int id) const { return (isValid() && !isPaused() && !isFunctionPaused(id)); }
void Finalize();
void pausePlugin(); void pausePlugin();
void unpausePlugin(); void unpausePlugin();
void pauseFunction( int id ); void pauseFunction(int id);
void unpauseFunction( int id ); void unpauseFunction(int id);
void setStatus( int a ); void setStatus(int a);
const char* getStatus() const; const char* getStatus() const;
inline bool isDebug() const { return m_Debug; }
}; };
private: private:
CPlugin *head; CPlugin *head;
int pCounter; int pCounter;
public: public:
CPluginMngr() { head = 0; pCounter = 0; } CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
~CPluginMngr() { clear(); } ~CPluginMngr() { clear(); }
bool m_Finalized;
AMX_NATIVE_INFO *pNatives;
// Interface // Interface
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug); CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
void unloadPlugin( CPlugin** a ); void unloadPlugin(CPlugin** a);
int loadPluginsFromFile( const char* filename ); int loadPluginsFromFile(const char* filename);
CPlugin* findPluginFast(AMX *amx); CPlugin* findPluginFast(AMX *amx);
CPlugin* findPlugin(AMX *amx); CPlugin* findPlugin(AMX *amx);
CPlugin* findPlugin(int index); CPlugin* findPlugin(int index);
CPlugin* findPlugin(const char* name); CPlugin* findPlugin(const char* name);
inline int getPluginsNum() const { return pCounter; } inline int getPluginsNum() const { return pCounter; }
void Finalize();
void clear(); void clear();
class iterator { class iterator
{
CPlugin *a; CPlugin *a;
public: public:
iterator(CPlugin*aa) : a(aa) {} iterator(CPlugin*aa) : a(aa) {}
@ -129,10 +142,9 @@ public:
operator bool () const { return a ? true : false; } operator bool () const { return a ? true : false; }
CPlugin& operator*() { return *a; } CPlugin& operator*() { return *a; }
}; };
inline iterator begin() const { return iterator(head); } inline iterator begin() const { return iterator(head); }
inline iterator end() const { return iterator(0); } inline iterator end() const { return iterator(0); }
}; };
#endif #endif //PLUGIN_H

View File

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

105
amxmodx/CStack.h Executable file
View File

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

@ -32,6 +32,9 @@
#ifndef _INCLUDE_CSTRING_H #ifndef _INCLUDE_CSTRING_H
#define _INCLUDE_CSTRING_H #define _INCLUDE_CSTRING_H
#include <string.h>
#include <stdio.h>
//by David "BAILOPAN" Anderson //by David "BAILOPAN" Anderson
class String class String
{ {
@ -39,10 +42,8 @@ public:
String() String()
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0; //assign("");
Grow(2);
assign("");
} }
~String() ~String()
@ -54,41 +55,45 @@ public:
String(const char *src) String(const char *src)
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0; assign(src); assign(src);
}
const char * _fread(FILE *fp)
{
Grow(512, false);
char *ret = fgets(v, 511, fp);
return ret;
} }
String(String &src) String(String &src)
{ {
v = NULL; v = NULL;
mSize = 0; a_size = 0;
cSize = 0;
assign(src.c_str()); assign(src.c_str());
} }
const char *c_str() { return v?v:""; } const char *c_str() { return v?v:""; }
const char *c_str() const { return v?v:""; } const char *c_str() const { return v?v:""; }
void append(const char *t) void append(const char *t)
{ {
Grow(cSize + strlen(t) + 1); Grow(size() + strlen(t) + 1);
strcat(v, t); strcat(v, t);
cSize = strlen(v);
} }
void append(const char c) void append(const char c)
{ {
Grow(cSize + 2); size_t len = size();
v[cSize] = c; Grow(len + 2);
v[++cSize] = 0; v[len] = c;
v[len + 1] = '\0';
} }
void append(String &d) void append(String &d)
{ {
const char *t = d.c_str(); append(d.c_str());
Grow(cSize + strlen(t));
strcat(v, t);
cSize = strlen(v);
} }
void assign(const String &src) void assign(const String &src)
@ -100,79 +105,56 @@ public:
{ {
if (!d) if (!d)
{ {
Grow(1); clear();
cSize = 0;
strcpy(v, "");
return;
}
Grow(strlen(d));
if (v)
{
strcpy(v, d);
cSize = strlen(v);
} else { } else {
cSize = 0; Grow(strlen(d) + 1, false);
strcpy(v, d);
} }
} }
void clear() void clear()
{ {
if (v) if (v)
{ v[0] = '\0';
v[0] = 0;
cSize = 0;
}
} }
int compare (const char *d) int compare (const char *d)
{ {
if (v) { if (!v)
if (d) { return strcmp("", d);
else
return strcmp(v, d); return strcmp(v, d);
} else {
return strlen(v);
}
} else {
if (d) {
return strlen(d);
} else {
return 0;
}
}
} }
//Added this for amxx inclusion //Added this for amxx inclusion
bool empty() bool empty()
{ {
if (!v || !cSize) if (!v)
return true;
if (v[0] == '\0')
return true; return true;
return false; return false;
} }
int size() size_t size()
{ {
if (!v) if (v)
return strlen(v);
else
return 0; return 0;
return cSize;
}
const char * _fread(FILE *fp)
{
Grow(512);
char * ret = fgets(v, 511, fp);
cSize = strlen(v);
return ret;
} }
int find(const char c, int index = 0) int find(const char c, int index = 0)
{ {
if (!v) size_t len = size();
if (len < 1)
return npos; return npos;
if (index >= (int)cSize || index < 0) if (index >= (int)len || index < 0)
return npos; return npos;
unsigned int i = 0; unsigned int i = 0;
for (i=index; i<cSize; i++) for (i=index; i<(int)len; i++)
{ {
if (v[i] == c) if (v[i] == c)
{ {
@ -199,10 +181,12 @@ public:
{ {
if (!v) if (!v)
return; return;
unsigned int i = 0; unsigned int i = 0;
unsigned int j = 0; unsigned int j = 0;
size_t len = strlen(v);
if (cSize == 1) if (len == 1)
{ {
if (is_space(v[i])) if (is_space(v[i]))
{ {
@ -215,9 +199,9 @@ public:
if (is_space(c0)) if (is_space(c0))
{ {
for (i=0; i<cSize; i++) for (i=0; i<len; i++)
{ {
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==cSize-1))) if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
{ {
erase(0, i); erase(0, i);
break; break;
@ -225,16 +209,16 @@ public:
} }
} }
cSize = strlen(v); len = strlen(v);
if (cSize < 1) if (len < 1)
{ {
return; return;
} }
if (is_space(v[cSize-1])) if (is_space(v[len-1]))
{ {
for (i=cSize-1; i>=0; i--) for (i=len-1; i>=0; i--)
{ {
if (!is_space(v[i]) if (!is_space(v[i])
|| (is_space(v[i]) && i==0)) || (is_space(v[i]) && i==0))
@ -246,7 +230,7 @@ public:
} }
} }
if (cSize == 1) if (len == 1)
{ {
if (is_space(v[0])) if (is_space(v[0]))
{ {
@ -256,21 +240,22 @@ public:
} }
} }
String & erase(unsigned int start, int num = npos) void erase(unsigned int start, int num = npos)
{ {
if (!v) if (!v)
return (*this); return;
unsigned int i = 0; unsigned int i = 0;
size_t len = size();
//check for bounds //check for bounds
if (num == npos || start+num > cSize-num+1) if (num == npos || start+num > len-num+1)
num = cSize - start; num = len - start;
//do the erasing //do the erasing
bool copyflag = false; bool copyflag = false;
for (i=0; i<cSize; i++) for (i=0; i<len; i++)
{ {
if (i>=start && i<start+num) if (i>=start && i<start+num)
{ {
if (i+num < cSize) if (i+num < len)
{ {
v[i] = v[i+num]; v[i] = v[i+num];
} else { } else {
@ -278,7 +263,7 @@ public:
} }
copyflag = true; copyflag = true;
} else if (copyflag) { } else if (copyflag) {
if (i+num < cSize) if (i+num < len)
{ {
v[i] = v[i+num]; v[i] = v[i+num];
} else { } else {
@ -286,38 +271,39 @@ public:
} }
} }
} }
cSize -= num; len -= num;
v[cSize] = 0; v[len] = 0;
return (*this);
} }
String substr(unsigned int index, int num = npos) String substr(unsigned int index, int num = npos)
{ {
if (!v)
{
String b("");
return b;
}
String ns; String ns;
if (index >= cSize || !v) size_t len = size();
if (index >= len || !v)
return ns; return ns;
if (num == npos) if (num == npos)
{ {
num = cSize - index; num = len - index;
} else if (index+num >= cSize) { } else if (index+num >= len) {
num = cSize - index; num = len - index;
} }
unsigned int i = 0, j=0; unsigned int i = 0, j=0;
char *s = new char[cSize+1]; unsigned int nslen = num + 2;
ns.Grow(nslen);
for (i=index; i<index+num; i++) for (i=index; i<index+num; i++)
{ ns.append(v[i]);
s[j++] = v[i];
}
s[j] = 0;
ns.assign(s);
delete [] s;
return ns; return ns;
} }
@ -327,10 +313,11 @@ public:
if (!v) if (!v)
return; return;
unsigned int i = 0; unsigned int i = 0;
for (i=0; i<cSize; i++) size_t len = strlen(v);
for (i=0; i<len; i++)
{ {
if (v[i] >= 65 && v[i] <= 90) if (v[i] >= 65 && v[i] <= 90)
v[i] |= 32; v[i] &= ~(1<<5);
} }
} }
@ -349,7 +336,7 @@ public:
char operator [] (unsigned int index) char operator [] (unsigned int index)
{ {
if (index > cSize) if (index > size() || !v)
{ {
return -1; return -1;
} else { } else {
@ -359,7 +346,7 @@ public:
int at(int a) int at(int a)
{ {
if (a < 0 || a >= (int)cSize) if (a < 0 || a >= (int)size() || !v)
return -1; return -1;
return v[a]; return v[a];
@ -367,7 +354,7 @@ public:
bool at(int at, char c) bool at(int at, char c)
{ {
if (at < 0 || at >= (int)cSize) if (at < 0 || at >= (int)size() || !v)
return false; return false;
v[at] = c; v[at] = c;
@ -376,27 +363,23 @@ public:
} }
private: private:
void Grow(unsigned int d) void Grow(unsigned int d, bool copy=true)
{ {
if (d<1) if (d <= a_size)
return; return;
if (d > mSize) char *n = new char[d + 1];
{ if (copy && v)
mSize = d + 16; // allocate a buffer strcpy(n, v);
char *t = new char[d+1]; if (v)
if (v) {
strcpy(t, v);
t[cSize] = 0;
delete [] v; delete [] v;
} else
v = t; strcpy(n, "");
mSize = d; v = n;
} a_size = d + 1;
} }
char *v; char *v;
unsigned int mSize; unsigned int a_size;
unsigned int cSize;
public: public:
static const int npos = -1; static const int npos = -1;
}; };

View File

@ -33,6 +33,7 @@
#include "CTask.h" #include "CTask.h"
/*********************** CTask ***********************/ /*********************** CTask ***********************/
int CTaskMngr::CTask::getTaskId() const int CTaskMngr::CTask::getTaskId() const
{ {
return m_iId; return m_iId;
@ -45,6 +46,7 @@ CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
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, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
{ {
clear();
m_bFree = false; m_bFree = false;
m_pPlugin = pPlugin; m_pPlugin = pPlugin;
@ -52,8 +54,17 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
m_iId = iId; m_iId = iId;
m_fBase = fBase; m_fBase = fBase;
m_iRepeat = (iFlags & 1) ? iRepeat : 0; if (iFlags & 2)
m_bLoop = (iFlags & 2) ? true : false; {
m_bLoop = true;
m_iRepeat = -1;
}
else if (iFlags & 1)
{
m_bLoop = true;
m_iRepeat = iRepeat;
}
m_bAfterStart = (iFlags & 4) ? true : false; m_bAfterStart = (iFlags & 4) ? true : false;
m_bBeforeEnd = (iFlags & 8) ? true : false; m_bBeforeEnd = (iFlags & 8) ? true : false;
@ -73,17 +84,30 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
void CTaskMngr::CTask::clear() void CTaskMngr::CTask::clear()
{ {
m_bFree = true;
if (m_iFunc >= 0) if (m_iFunc >= 0)
{ {
unregisterSPForward(m_iFunc); unregisterSPForward(m_iFunc);
m_iFunc = -1; m_iFunc = -1;
} }
m_bFree = true;
if (m_pParams) if (m_pParams)
{ {
delete [] m_pParams; delete [] m_pParams;
m_pParams = NULL; m_pParams = NULL;
} }
m_pPlugin = NULL;
m_iId = 0;
m_fBase = 0.0f;
m_iRepeat = 0;
m_bLoop = false;
m_bAfterStart = false;
m_bBeforeEnd = false;
m_fNextExecTime = 0.0f;
} }
bool CTaskMngr::CTask::isFree() const bool CTaskMngr::CTask::isFree() const
@ -103,7 +127,9 @@ void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft) void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
{ {
bool execute=false; bool execute = false;
bool done = false;
if (m_bAfterStart) if (m_bAfterStart)
{ {
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase) if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
@ -115,9 +141,14 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
execute = true; execute = true;
} }
else if (m_fNextExecTime <= fCurrentTime) else if (m_fNextExecTime <= fCurrentTime)
{
execute = true; execute = true;
}
if (execute) if (execute)
{
//only bother calling if we have something to call
if (!(m_bLoop && !m_iRepeat))
{ {
if (m_iParamLen) // call with parameters if (m_iParamLen) // call with parameters
{ {
@ -126,20 +157,25 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
} else { } else {
executeForwards(m_iFunc, m_iId); executeForwards(m_iFunc, m_iId);
} }
}
if (isFree()) if (isFree())
return; return;
// set new exec time OR remove the task if needed // set new exec time OR remove the task if needed
if (m_bLoop || (--m_iRepeat > 0)) if (m_bLoop)
{ {
m_fNextExecTime += m_fBase; if (m_iRepeat != -1 && --m_iRepeat <= 0)
done = true;
} else {
done = true;
} }
else
if (done)
{ {
unregisterSPForward(m_iFunc); clear();
m_iFunc = -1; } else {
m_bFree = true; m_fNextExecTime += m_fBase;
} }
} }
} }
@ -147,6 +183,21 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
CTaskMngr::CTask::CTask() CTaskMngr::CTask::CTask()
{ {
m_bFree = true; m_bFree = true;
m_pPlugin = NULL;
m_iFunc = -1;
m_iId = 0;
m_fBase = 0.0f;
m_iRepeat = 0;
m_bLoop = false;
m_bAfterStart = false;
m_bBeforeEnd = false;
m_fNextExecTime = 0.0f;
m_iParamLen = 0;
m_pParams = NULL;
} }
CTaskMngr::CTask::~CTask() CTaskMngr::CTask::~CTask()
@ -155,6 +206,7 @@ CTaskMngr::CTask::~CTask()
} }
/*********************** CTaskMngr ***********************/ /*********************** CTaskMngr ***********************/
CTaskMngr::CTaskMngr() CTaskMngr::CTaskMngr()
{ {
m_pTmr_CurrentTime = NULL; m_pTmr_CurrentTime = NULL;
@ -162,6 +214,11 @@ CTaskMngr::CTaskMngr()
m_pTmr_TimeLeft = NULL; m_pTmr_TimeLeft = NULL;
} }
CTaskMngr::~CTaskMngr()
{
clear();
}
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft) void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
{ {
m_pTmr_CurrentTime = pCurrentTime; m_pTmr_CurrentTime = pCurrentTime;
@ -173,17 +230,18 @@ void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlag
{ {
// first, search for free tasks // first, search for free tasks
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true)); TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
if (iter) if (iter)
{ {
// found: reuse it // found: reuse it
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
} } else {
else
{
// not found: make a new one // not found: make a new one
CTask *pTmp = new CTask; CTask *pTmp = new CTask;
if (!pTmp) if (!pTmp)
return; return;
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime); pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
m_Tasks.put(pTmp); m_Tasks.put(pTmp);
} }
@ -193,13 +251,15 @@ int CTaskMngr::removeTasks(int iId, AMX *pAmx)
{ {
CTaskDescriptor descriptor(iId, pAmx); CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor); TaskListIter iter = m_Tasks.find(descriptor);
int i=0; int i = 0;
while (iter) while (iter)
{ {
iter->clear(); iter->clear();
++i; ++i;
iter = m_Tasks.find(++iter, descriptor); iter = m_Tasks.find(++iter, descriptor);
} }
return i; return i;
} }
@ -207,7 +267,8 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
{ {
CTaskDescriptor descriptor(iId, pAmx); CTaskDescriptor descriptor(iId, pAmx);
TaskListIter iter = m_Tasks.find(descriptor); TaskListIter iter = m_Tasks.find(descriptor);
int i=0; int i = 0;
while (iter) while (iter)
{ {
iter->changeBase(fNewBase); iter->changeBase(fNewBase);
@ -215,6 +276,7 @@ int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
++i; ++i;
iter = m_Tasks.find(++iter, descriptor); iter = m_Tasks.find(++iter, descriptor);
} }
return i; return i;
} }

View File

@ -39,15 +39,18 @@ private:
class CTask class CTask
{ {
// task settings // task settings
CPluginMngr::CPlugin *m_pPlugin; CPluginMngr::CPlugin *m_pPlugin;
int m_iId; int m_iId;
int m_iFunc; int m_iFunc;
int m_iRepeat; int m_iRepeat;
bool m_bLoop; bool m_bLoop;
bool m_bAfterStart; bool m_bAfterStart;
bool m_bBeforeEnd; bool m_bBeforeEnd;
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
int m_iParamLen; int m_iParamLen;
cell *m_pParams; cell *m_pParams;
bool m_bFree; bool m_bFree;
@ -91,31 +94,32 @@ private:
if (right.m_bFree) if (right.m_bFree)
return left.isFree(); return left.isFree();
return !left.isFree() && return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
(right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) &&
left.getTaskId() == right.m_iId;
} }
}; };
/*** CTaskMngr priv members ***/ /*** CTaskMngr priv members ***/
typedef CList<CTask, CTaskDescriptor> TaskList; typedef CList<CTask, CTaskDescriptor> TaskList;
typedef TaskList::iterator TaskListIter; typedef TaskList::iterator TaskListIter;
TaskList m_Tasks; TaskList m_Tasks;
float *m_pTmr_CurrentTime; float *m_pTmr_CurrentTime;
float *m_pTmr_TimeLimit; float *m_pTmr_TimeLimit;
float *m_pTmr_TimeLeft; float *m_pTmr_TimeLeft;
public: public:
CTaskMngr(); CTaskMngr();
~CTaskMngr();
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value 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, int 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 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 int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
bool taskExists(int iId, AMX *pAmx); bool taskExists(int iId, AMX *pAmx);
void startFrame(); void startFrame();
void clear(); void clear();
}; };
#endif #endif //CTASK_H

View File

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

View File

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

View File

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

BIN
amxmodx/JIT/amxexecn.o Executable file

Binary file not shown.

BIN
amxmodx/JIT/amxexecn.obj Executable file

Binary file not shown.

BIN
amxmodx/JIT/amxjitsn.o Executable file

Binary file not shown.

BIN
amxmodx/JIT/amxjitsn.obj Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
amxmodx/JIT/natives-amd64.o Executable file

Binary file not shown.

BIN
amxmodx/JIT/natives-x86.o Executable file

Binary file not shown.

BIN
amxmodx/JIT/natives-x86.obj Executable file

Binary file not shown.

View File

@ -1,123 +1,95 @@
MODNAME = amxx_mm #(C)2004-2005 AMX Mod X Development Team
SRCFILES = meta_api.cpp CFile.cpp CString.cpp CVault.cpp vault.cpp\ # Makefile written by David "BAILOPAN" Anderson
float.cpp file.cpp modules.cpp CMisc.cpp CTask.cpp string.cpp\
amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp srvcmd.cpp strptime.cpp\
CForward.cpp CPlugin.cpp CModule.cpp CMenu.cpp emsg.cpp util.cpp \
amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp mmgr/mmgr.cpp \
amxxfile.cpp CLang.cpp md5.cpp amx.cpp
#use this for amd64, remove the above amx.cpp, and rename amx.cpp to amx.c
#CSRCFILES = amx.c minilzo/minilzo.c
CSRCFILES = minilzo/minilzo.c
EXTRA_LIBS_LINUX = HLSDK = ../hlsdk/SourceCode
EXTRA_LIBS_WIN32 = MM_ROOT = ../metamod/metamod
EXTRA_LIBDIRS_LINUX = -Lextra/lib_linux
EXTRA_LIBDIRS_WIN32 = -Lextra/lib_win32
EXTRA_INCLUDEDIRS = -Iextra/include ### EDIT BELOW FOR OTHER PROJECTS ###
EXTRA_FLAGS = -Dstrcmpi=strcasecmp OPT_FLAGS = -O2 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = gcc
NAME = amxmodx_mm
SDKTOP=../hlsdk OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
METADIR=../metamod/metamod 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
LINK = -lz
SDKSRC=$(SDKTOP)/SourceCode INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
OBJDIR_LINUX=obj.linux -I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
OBJDIR_WIN32=obj.win32
SRCDIR=.
ifdef windir ifeq "$(DEBUG)" "true"
OS=WIN32 BIN_DIR = Debug
CFLAGS = $(DEBUG_FLAGS)
else else
OS=LINUX BIN_DIR = Release
CFLAGS = $(OPT_FLAGS)
endif endif
CC_LINUX=gcc ifeq "$(MMGR)" "true"
ifeq "$(OS)" "WIN32" OBJECTS += mmgr/mmgr.cpp
CC_WIN32=gcc CFLAGS += -DMEMORY_TEST
LD_WINDLL=dllwrap
DEFAULT=win32
CLEAN=clean_win32
else
CC_WIN32=/usr/local/cross-tools/i386-mingw32msvc/bin/gcc
LD_WINDLL=/usr/local/cross-tools/bin/i386-mingw32msvc-dllwrap
DEFAULT=linux win32
CLEAN=clean_both
endif endif
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
#use this for AMD64 ifeq "$(AMD64)" "true"
#LIBFILE_LINUX = $(MODNAME)_amd64.so BINARY = $(NAME)_amd64.so
LIBFILE_LINUX = $(MODNAME)_i386.so CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LIBFILE_WIN32 = $(MODNAME).dll OBJECTS += JIT/natives-amd64.o
TARGET_LINUX = $(OBJDIR_LINUX)/$(LIBFILE_LINUX)
TARGET_WIN32 = $(OBJDIR_WIN32)/$(LIBFILE_WIN32)
FILES_ALL = *.cpp *.h [A-Z]* *.rc
ifeq "$(OS)" "LINUX"
ASRCFILES := $(shell ls -t $(SRCFILES))
else else
ASRCFILES := $(shell dir /b) BINARY = $(NAME)_i386.so
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
OPT_FLAGS += -march=i686
endif endif
OBJ_LINUX := $(SRCFILES:%.cpp=$(OBJDIR_LINUX)/%.o)
OBJC_LINUX := $(CSRCFILES:%.c=$(OBJDIR_LINUX)/%.o)
OBJ_WIN32 := $(SRCFILES:%.cpp=$(OBJDIR_WIN32)/%.o)
OBJC_WIN32 := $(CSRCFILES:%.c=$(OBJDIR_WIN32)/%.o)
#use this for amd64 OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
#CCOPT = -m64 -g -ggdb3 -DHAVE_I64 -DSMALL_CELL_SIZE=64
CCOPT = -march=i386 -s -DNDEBUG -O2 -fomit-frame-pointer -fno-exceptions -fno-rtti -ffast math
INCLUDEDIRS=-I../curl/include -I$(SRCDIR) -I$(METADIR) -I$(SDKSRC)/engine -I$(SDKSRC)/common -I$(SDKSRC)/pm_shared -I$(SDKSRC)/dlls -I$(SDKSRC) $(EXTRA_INCLUDEDIRS) $(BIN_DIR)/%.o: %.cpp
CFLAGS=-Wall -Wno-unknown-pragmas $(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
ODEF = -DOPT_TYPE=\"optimized\"
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
DO_CC_LINUX=$(CC_LINUX) $(CFLAGS) -fPIC $(INCLUDEDIRS) -o $@ -c $< all:
DO_CC_WIN32=$(CC_WIN32) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $< mkdir -p $(BIN_DIR)
LINK_LINUX=$(CC_LINUX) $(CFLAGS) -shared -ldl -lm $(OBJ_LINUX) $(OBJC_LINUX) $(EXTRA_LIBDIRS_LINUX) $(EXTRA_LIBS_LINUX) -o $@ $(MAKE) amxmodx
LINK_WIN32=$(LD_WINDLL) -mwindows --def $(MODNAME).def --add-stdcall-alias $(OBJ_WIN32) $(OBJC_WIN32) $(EXTRA_LIBDIRS_WIN32) $(EXTRA_LIBS_WIN32) -o $@
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c amd64:
$(DO_CC_LINUX) rm -f zlib/libz.a
$(MAKE) all AMD64=true
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp amd64_mmgr:
$(DO_CC_LINUX) rm -f zlib/libz.a
$(MAKE) all AMD64=true MMGR=true
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c amd64_debug_mmgr:
$(DO_CC_WIN32) rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true MMGR=true
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.cpp amd64_debug:
$(DO_CC_WIN32) rm -f zlib/libz.a
$(MAKE) all AMD64=true DEBUG=true
default: $(DEFAULT) mmgr:
$(MAKE) all MMGR=true
$(TARGET_LINUX): $(OBJDIR_LINUX) $(OBJ_LINUX) $(OBJC_LINUX) debug_mmgr:
$(LINK_LINUX) $(MAKE) all MMGR=true DEBUG=true
$(TARGET_WIN32): $(OBJDIR_WIN32) $(OBJ_WIN32) $(OBJC_WIN32) amxmodx: $(OBJ_LINUX)
$(LINK_WIN32) $(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
$(OBJDIR_LINUX): debug:
mkdir $@ $(MAKE) all DEBUG=true
mkdir $@/mmgr
$(OBJDIR_WIN32): default: all
mkdir $@
mkdir $@/mmgr
win32: $(TARGET_WIN32)
linux: $(TARGET_LINUX)
clean: $(CLEAN)
clean_both:
-rm -f $(OBJDIR_LINUX)/*
-rm -f $(OBJDIR_WIN32)/*
clean_win32:
del /q $(OBJDIR_WIN32)
clean:
rm -rf Release/*.o
rm -rf Release/$(BINARY)
rm -rf Debug/*.o
rm -rf Debug/$(BINARY)

View File

@ -1,256 +0,0 @@
#!/usr/bin/perl
#(C)2004 AMX Mod X Development Team
# by David "BAILOPAN" Anderson
# output will occur in bin.x.proc
# where x is debug or opt and proc is ix86 or amd64
# You must use this script from the amxmodx src dir
#options =
# jit - use the JIT
# debug - enable gdb debugging
# amd64 - compile for AMD64 (impiles no jit)
# proc=ix86 - assumed not amd64
# clean - clean the specifications above
# asm - for ASM implementation
# !! TODO - add memory mananger support
# lineop - for JIT only, uses slow version
$PROJECT = "amxmodx_mm";
$sdk = "../hlsdk/SourceCode";
$mm = "../metamod/metamod";
$gccf = "gcc";
$ccf = "cc";
$amd64_lstdc = "-lstdc++";
@CPP_SOURCE_FILES = ("meta_api.cpp", "CFile.cpp", "CVault.cpp", "vault.cpp", "float.cpp", "file.cpp", "modules.cpp", "CMisc.cpp", "CTask.cpp", "string.cpp", "amxmodx.cpp", "CEvent.cpp", "CCmd.cpp", "CLogEvent.cpp", "srvcmd.cpp", "strptime.cpp", "amxcore.cpp", "amxtime.cpp", "power.cpp", "amxxlog.cpp", "fakemeta.cpp", "amxxfile.cpp", "CLang.cpp", "md5.cpp", "emsg.cpp", "CForward.cpp", "CPlugin.cpp", "CModule.cpp", "CMenu.cpp", "util.cpp");
@C_SOURCE_FILES = ();
my %OPTIONS, %OPT;
$OPT{"debug"} = "-g -ggdb";
$OPT{"opt"} = "-O2 -ffast-math -funroll-loops -fomit-frame-pointer -s -DNDEBUG -Wall -Wno-unknown-pragmas -DOPT_TYPE=\"optimized\" -fno-exceptions -fno-rtti";
$OPTIONS{"include"} = "-I$sdk -I. -I$mm -I$sdk/engine -I$sdk/common -I$sdk/pm_shared -I$sdk/dlls";
while ($cmd = shift)
{
if ($cmd =~ /asm/)
{
if ($OPTIONS{"amd64"})
{
die "You cannot compile the ASM core with AMD64 yet.\n";
} else {
$OPTIONS{"asm"} = 1;
}
}
if ($cmd =~ /jit/)
{
if ($OPTIONS{"amd64"})
{
die "You cannot compile the JIT and AMD64 yet.\n";
} else {
$OPTIONS{"jit"} = 1;
}
} elsif ($cmd =~ /amd64/) {
if ($OPTIONS{"jit"} || $OPTIONS{"asm"})
{
die "You cannot compile the JIT or ASM and AMD64 yet.\n";
} else {
$OPTIONS{"amd64"} = 1;
}
} elsif ($cmd =~ /debug/) {
$OPTIONS{"debug"} = 1;
} elsif ($cmd =~ /proc=i(\d)86/) {
$proc = $1;
if ($OPTIONS{"amd64"})
{
die "You cannot compile for i".$proc."86 and AMD64.\n";
} else {
$OPTIONS{"proc"} = "i".$proc."86";
}
} elsif ($cmd =~ /clean/) {
$OPTIONS{"clean"} = 1;
} elsif ($cmd =~ /lineop/) {
$OPTIONS{"lineop"} = 1;
}
}
$gcc = `$gccf --version`;
if ($gcc =~ /2\.9/)
{
#if ($OPTIONS{"jit"})
#{
# push(@CPP_SOURCE_FILES, "amx.cpp");
# $OPT{"opt"} .= " -malign-loops=2 -malign-jumps=2 -malign-functions=2";
# } else {
`ln -s amx.cpp amx.c`;
push(@C_SOURCE_FILES, "amx.c");
# }
} else {
if ($OPTIONS{"amd64"})
{
`ln -s amx.cpp amx.c`;
push(@C_SOURCE_FILES, "amx.c");
} else {
push(@CPP_SOURCE_FILES, "amx.cpp");
}
$OPT{"opt"} .= " -falign-loops=2 -falign-jumps=2 -falign-functions=2";
}
if ($OPTIONS{"debug"})
{
$cflags = $OPT{"debug"};
} else {
if (!$OPTIONS{"amd64"})
{
$proc = $OPTIONS{"proc"};
if (!$proc)
{
$proc = 3;
}
$cflags = "-march=i".$proc."86 ".$OPT{"opt"};
} else {
$cflags = $OPT{"opt"};
}
}
if ($OPTIONS{"amd64"})
{
$cflags = " -m64 -DSMALL_CELL_SIZE=64 -DHAVE_I64 $cflags";
}
if ($OPTIONS{"jit"})
{
$cflags .= " -DJIT";
}
if ($OPTIONS{"asm"})
{
$cflags .= " -DASM32";
}
if ($OPTIONS{"debug"})
{
$outdir = "bin.debug";
} else {
$outdir = "bin.opt";
}
if ($OPTIONS{"amd64"})
{
$outdir .= ".amd64";
$bin = $PROJECT."_amd64.so";
} else {
$proc = $OPTIONS{"proc"};
if ($proc)
{
$outdir .= ".i".$proc."86";
$bin = $PROJECT."_i".$proc."86.so";
} else {
$outdir .= ".i386";
$bin = $PROJECT."_i386.so";
}
}
if ($OPTIONS{"clean"})
{
`rm $outdir/*.o`;
`rm $outdir/$bin`;
die("Project cleaned.\n");
}
#create the dirs
#build link list
my @LINK;
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
{
$file = $CPP_SOURCE_FILES[$i];
$file =~ s/\.cpp/\.o/;
push(@LINK, $outdir."/".$file);
}
for ($i=0; $i<=$#C_SOURCE_FILES; $i++)
{
$file = $C_SOURCE_FILES[$i];
$file =~ s/\.c/\.o/;
push(@LINK, $outdir."/".$file);
}
if ($OPTIONS{"jit"})
{
if ($OPTIONS{"lineop"}) {
push(@LINK, "JIT/jits-lineop.o");
} else {
push(@LINK, "JIT/jits.o");
}
}
if ($OPTIONS{"amd64"})
{
push(@LINK, "zlib/libz64.a");
push(@LINK, $amd64_lstdc);
} else {
push(@LINK, "zlib/libz.a");
}
if ($OPTIONS{"asm"})
{
push(@LINK, "amxexecn.o");
}
if (!(-d $outdir))
{
mkdir($outdir);
}
if (!(-d "$outdir/JIT"))
{
mkdir("$outdir/JIT");
}
$inc = $OPTIONS{"include"};
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
{
$file = $CPP_SOURCE_FILES[$i];
$ofile = $file;
$ofile =~ s/\.cpp/\.o/;
$ofile = "$outdir/$ofile";
$gcc = "$gccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
if (-e $ofile)
{
$file_time = (stat($file))[9];
$ofile_time = (stat($ofile))[9];
if ($file_time > $ofile_time)
{
`rm $ofile`;
print "$gcc\n";
`$gcc`;
}
} else {
print "$gcc\n";
`$gcc`;
}
}
for ($i=0; $i<=$#CPP_SOURCE_FILES; $i++)
{
$file = $C_SOURCE_FILES[$i];
$ofile = $file;
$ofile =~ s/\.c/\.o/;
$ofile = "$outdir/$ofile";
$gcc = "$ccf $cflags -Dstrcmpi=strcasecmp -fPIC $inc -c $file -o $ofile";
if (-e $ofile)
{
$file_time = (stat($file))[9];
$ofile_time = (stat($ofile))[9];
if ($file_time > $ofile_time)
{
print "$gcc\n";
`$gcc`;
}
} else {
print "$gcc\n";
`$gcc`;
}
}
$gcc = "$gccf $cflags -shared -ldl -lm @LINK -o $outdir/$bin";
print "$gcc\n";
`$gcc`;

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* Abstract Machine for the Small compiler /* Pawn Abstract Machine (for the Pawn language)
* *
* Copyright (c) ITB CompuPhase, 1997-2004 * Copyright (c) ITB CompuPhase, 1997-2005
* *
* This software is provided "as-is", without any express or implied warranty. * This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from * In no event will the authors be held liable for any damages arising from
@ -21,20 +21,34 @@
* Version: $Id$ * Version: $Id$
*/ */
#if defined __linux__ #if defined FREEBSD && !defined __FreeBSD__
#define __FreeBSD__
#endif
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
#include <sclinux.h> #include <sclinux.h>
#endif #endif
#ifndef AMX_H_INCLUDED #ifndef AMX_H_INCLUDED
#define AMX_H_INCLUDED #define AMX_H_INCLUDED
#if defined __LCC__ || defined __DMC__ || defined __linux__ #if defined HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L #else
#if defined __LCC__ || defined __DMC__ || defined LINUX
#if defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got /* The ISO C99 defines the int16_t and int_32t types. If the compiler got
* here, these types are probably undefined. * here, these types are probably undefined.
*/ */
#if defined __FreeBSD__ #if defined __MACH__
#include <ppc/types.h>
typedef unsigned short int uint16_t;
typedef unsigned long int uint32_t;
#elif defined __FreeBSD__
#include <inttypes.h> #include <inttypes.h>
#else #else
typedef short int int16_t; typedef short int int16_t;
@ -46,29 +60,51 @@
typedef long int int32_t; typedef long int int32_t;
typedef unsigned long int uint32_t; typedef unsigned long int uint32_t;
#endif #endif
// evilspy's fix for mingw #if defined __WIN32__ || defined _WIN32 || defined WIN32
#if defined __GNUC__
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define HAVE_I64
#elif defined __WIN32__ || defined _WIN32 || defined WIN32
typedef __int64 int64_t; typedef __int64 int64_t;
typedef unsigned __int64 uint64_t; typedef unsigned __int64 uint64_t;
#define HAVE_I64 #define HAVE_I64
#elif defined __GNUC__
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define HAVE_I64
#endif #endif
#endif #endif
#endif
#define HAVE_STDINT_H
#endif
#if defined _LP64 || defined WIN64 || defined _WIN64
#if !defined __64BIT__
#define __64BIT__
#endif
#endif #endif
#if HAVE_ALLOCA_H
#include <alloca.h>
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */ #if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
#if !defined alloca #if !defined alloca
#define alloca(n) _alloca(n) #define alloca(n) _alloca(n)
#endif #endif
#endif #endif
#if !defined arraysize
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if defined PAWN_DLL
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL __stdcall
#endif
#if !defined AMXAPI
#define AMXAPI __stdcall
#endif
#endif
/* calling convention for native functions */ /* calling convention for native functions */
#if !defined AMX_NATIVE_CALL #if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL #define AMX_NATIVE_CALL
@ -79,6 +115,8 @@ extern "C" {
#define AMXAPI __stdcall #define AMXAPI __stdcall
#elif defined CDECL #elif defined CDECL
#define AMXAPI __cdecl #define AMXAPI __cdecl
#elif defined GCC_HASCLASSVISIBILITY
#define AMXAPI __attribute__ ((visibility("default")))
#else #else
#define AMXAPI #define AMXAPI
#endif #endif
@ -96,46 +134,39 @@ extern "C" {
* 5 (tagnames table) 4 * 5 (tagnames table) 4
* 6 (reformatted header) 6 * 6 (reformatted header) 6
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7 * 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
* 8 (opcode STMT, renewed debug interface) 8
*/ */
#define CUR_FILE_VERSION 7 /* current file version; also the current AMX version */ #define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */ #define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
#define MIN_AMX_VERSION 7 /* minimum AMX version needed to support the current file format */ #define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
#if defined BIT16 #if !defined PAWN_CELL_SIZE
#define SMALL_CELL_SIZE 16 /* for backward compatibility */ #define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
#endif #endif
#if !defined SMALL_CELL_SIZE #if PAWN_CELL_SIZE==16
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
#endif
#if SMALL_CELL_SIZE==16
typedef uint16_t ucell; typedef uint16_t ucell;
typedef int16_t cell; typedef int16_t cell;
#elif SMALL_CELL_SIZE==32 #elif PAWN_CELL_SIZE==32
typedef uint32_t ucell; typedef uint32_t ucell;
typedef int32_t cell; typedef int32_t cell;
#elif SMALL_CELL_SIZE==64 #define REAL float
#elif PAWN_CELL_SIZE==64
typedef uint64_t ucell; typedef uint64_t ucell;
typedef int64_t cell; typedef int64_t cell;
#define REAL double
#else #else
#error Unsupported cell size (SMALL_CELL_SIZE) #error Unsupported cell size (PAWN_CELL_SIZE)
#endif #endif
#if SMALL_CELL_SIZE==32 #define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
#define REAL float #define UNLIMITED (~1u >> 1)
#elif SMALL_CELL_SIZE==64
#define REAL double
#else
#error Unsupported cell size
#endif
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
struct tagAMX; struct tagAMX;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params); typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index, typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
cell *result, cell *params); cell *result, cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx); typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode); typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
#if !defined _FAR #if !defined _FAR
#define _FAR #define _FAR
#endif #endif
@ -149,7 +180,7 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
/* Some compilers do not support the #pragma align, which should be fine. Some /* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine... * compilers give a warning on unknown #pragmas, which is not so fine...
*/ */
#if defined SN_TARGET_PS2 || defined __GNUC__ #if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
#define AMX_NO_ALIGN #define AMX_NO_ALIGN
#endif #endif
@ -160,8 +191,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
#endif #endif
#if !defined AMX_NO_ALIGN #if !defined AMX_NO_ALIGN
#if defined __linux__ #if defined LINUX || defined __FreeBSD__
#pragma pack(1) /* structures must be packed (byte-aligned) */ #pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else #else
#pragma pack(push) #pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */ #pragma pack(1) /* structures must be packed (byte-aligned) */
@ -171,10 +204,10 @@ typedef int (AMXAPI *AMX_DEBUGCALL)(struct tagAMX *amx, int mode);
#endif #endif
#endif #endif
typedef struct { typedef struct tagAMX_NATIVE_INFO {
const char _FAR *name PACKED; const char _FAR *name PACKED;
AMX_NATIVE func PACKED; AMX_NATIVE func PACKED;
} AMX_NATIVE_INFO; } PACKED AMX_NATIVE_INFO;
#define AMX_USERNUM 4 #define AMX_USERNUM 4
#define sEXPMAX 19 /* maximum name length for file version <= 6 */ #define sEXPMAX 19 /* maximum name length for file version <= 6 */
@ -182,14 +215,19 @@ typedef struct {
typedef struct tagAMX_FUNCSTUB { typedef struct tagAMX_FUNCSTUB {
ucell address PACKED; ucell address PACKED;
const char name[sEXPMAX+1] PACKED; char name[sEXPMAX+1] PACKED;
} AMX_FUNCSTUB; } PACKED AMX_FUNCSTUB;
typedef struct tagFUNCSTUBNT {
ucell address PACKED;
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
} PACKED AMX_FUNCSTUBNT;
/* The AMX structure is the internal structure for many functions. Not all /* The AMX structure is the internal structure for many functions. Not all
* fields are valid at all times; many fields are cached in local variables. * fields are valid at all times; many fields are cached in local variables.
*/ */
typedef struct tagAMX { typedef struct tagAMX {
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */ unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */ unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
AMX_CALLBACK callback PACKED; AMX_CALLBACK callback PACKED;
AMX_DEBUG debug PACKED; /* debug callback */ AMX_DEBUG debug PACKED; /* debug callback */
@ -201,18 +239,16 @@ typedef struct tagAMX {
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */ cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
int flags PACKED; /* current status, see amx_Flags() */ int flags PACKED; /* current status, see amx_Flags() */
/* for assertions and debug hook */
cell curline PACKED;
cell curfile PACKED;
int dbgcode PACKED;
cell dbgaddr PACKED;
cell dbgparam PACKED;
char _FAR *dbgname PACKED;
/* user data */ /* user data */
long usertags[AMX_USERNUM] PACKED; long usertags[AMX_USERNUM] PACKED;
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
//we're also gonna set userdata[2] to a special debug structure
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
void _FAR *userdata[AMX_USERNUM] PACKED; void _FAR *userdata[AMX_USERNUM] PACKED;
/* native functions can raise an error */ /* native functions can raise an error */
int error PACKED; int error PACKED;
/* passing parameters requires a "count" field */
int paramcount;
/* the sleep opcode needs to store the full AMX status */ /* the sleep opcode needs to store the full AMX status */
cell pri PACKED; cell pri PACKED;
cell alt PACKED; cell alt PACKED;
@ -222,7 +258,7 @@ typedef struct tagAMX {
/* support variables for the JIT */ /* support variables for the JIT */
int reloc_size PACKED; /* required temporary buffer for relocations */ int reloc_size PACKED; /* required temporary buffer for relocations */
long code_size PACKED; /* estimated memory footprint of the native code */ long code_size PACKED; /* estimated memory footprint of the native code */
} AMX; } PACKED AMX;
/* The AMX_HEADER structure is both the memory format as the file format. The /* The AMX_HEADER structure is both the memory format as the file format. The
* structure is used internaly. * structure is used internaly.
@ -244,27 +280,12 @@ typedef struct tagAMX_HEADER {
int32_t libraries PACKED; /* offset to the table of libraries */ int32_t libraries PACKED; /* offset to the table of libraries */
int32_t pubvars PACKED; /* the "public variables" table */ int32_t pubvars PACKED; /* the "public variables" table */
int32_t tags PACKED; /* the "public tagnames" table */ int32_t tags PACKED; /* the "public tagnames" table */
int32_t nametable PACKED; /* name table, file version 7 only */ int32_t nametable PACKED; /* name table */
} AMX_HEADER PACKED; } PACKED AMX_HEADER;
//This is always the same for us
#define AMX_MAGIC 0xf1e0 #define AMX_MAGIC 0xf1e0
//double linked list for stack
typedef struct tagAMX_TRACE
{
cell line PACKED;
cell file PACKED;
struct tagAMX_TRACE *next PACKED;
struct tagAMX_TRACE *prev PACKED;
} AMX_TRACE PACKED;
typedef struct tagAMX_DBG
{
int32_t numFiles PACKED; /* number of chars in array */
char **files PACKED; /* array of files */
AMX_TRACE *head PACKED; /* begin of link list */
AMX_TRACE *tail PACKED; /* end of link list */
} AMX_DBG PACKED;
enum { enum {
AMX_ERR_NONE, AMX_ERR_NONE,
/* reserve the first 15 error codes for exit codes of the abstract machine */ /* reserve the first 15 error codes for exit codes of the abstract machine */
@ -280,6 +301,8 @@ enum {
AMX_ERR_NATIVE, /* native function failed */ AMX_ERR_NATIVE, /* native function failed */
AMX_ERR_DIVIDE, /* divide by zero */ AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */ AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_INVSTATE, /* invalid state for this access */
AMX_ERR_INVNATIVE, /* invalid native was used */
AMX_ERR_MEMORY = 16, /* out of memory */ AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */ AMX_ERR_FORMAT, /* invalid file format */
@ -292,29 +315,18 @@ enum {
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */ AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
AMX_ERR_PARAMS, /* parameter error */ AMX_ERR_PARAMS, /* parameter error */
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */ AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
}; AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
enum {
DBG_INIT, /* query/initialize */
DBG_FILE, /* file number in curfile, filename in name */
DBG_LINE, /* line number in curline, file number in curfile */
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
DBG_CALL, /* function call, address jumped to in dbgaddr */
DBG_RETURN, /* function returns */
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
DBG_SYMTAG, /* tag of the most recent symbol (if non-zero), tag in dbgparam */
}; };
/* AMX_FLAG_CHAR16 0x01 no longer used */ /* AMX_FLAG_CHAR16 0x01 no longer used */
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */ #define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */ #define AMX_FLAG_COMPACT 0x04 /* compact encoding */
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */ #define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */ #define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
#define AMX_FLAG_LINEOPS 0x20 /* line ops are parsed by the JIT [loadtime only flag] */ #define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
#define AMX_FLAG_TRACED 0x40 /* the file has already been traced */ #define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */ #define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */ #define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
#define AMX_EXEC_MAIN -1 /* start at program entry point */ #define AMX_EXEC_MAIN -1 /* start at program entry point */
@ -322,16 +334,24 @@ enum {
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24)) #define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
#define AMX_EXPANDMARGIN 64 #if !defined AMX_COMPACTMARGIN
#define AMX_COMPACTMARGIN 64
#endif
#define UD_FINDPLUGIN 3
#define UD_DEBUGGER 2
#define UD_OPCODELIST 1
#define UD_HANDLER 0
#define UT_NATIVE 3
/* for native functions that use floating point parameters, the following /* for native functions that use floating point parameters, the following
* two macros are convenient for casting a "cell" into a "float" type _without_ * two macros are convenient for casting a "cell" into a "float" type _without_
* changing the bit pattern * changing the bit pattern
*/ */
#if SMALL_CELL_SIZE==32 #if PAWN_CELL_SIZE==32
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */ #define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
#elif SMALL_CELL_SIZE==64 #elif PAWN_CELL_SIZE==64
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */ #define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */ #define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
#else #else
@ -345,7 +365,7 @@ enum {
amx_StrLen(amx_cstr_, &amx_length_); \ amx_StrLen(amx_cstr_, &amx_length_); \
if (amx_length_ > 0 && \ if (amx_length_ > 0 && \
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \ ((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1); \ amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
else (result) = NULL; \ else (result) = NULL; \
} while (0) } while (0)
@ -354,23 +374,12 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
#if defined _I64_MAX || defined HAVE_I64 #if defined _I64_MAX || defined HAVE_I64
uint64_t * AMXAPI amx_Align64(uint64_t *v); uint64_t * AMXAPI amx_Align64(uint64_t *v);
#endif #endif
#if SMALL_CELL_SIZE==32
#define amx_AlignCell amx_Align32
#elif SMALL_CELL_SIZE==64
#define amx_AlignCell amx_Align64
#else
#error Unsupported cell size
#endif
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr); int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params); int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf);
int AMXAPI amx_Cleanup(AMX *amx); int AMXAPI amx_Cleanup(AMX *amx);
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data); int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
int AMXAPI amx_DebugCall(AMX *amx, int mode);
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index); int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index); int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr); int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
@ -380,34 +389,57 @@ int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname); int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname); int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr); int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar); int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id); int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr); int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
int AMXAPI amx_Init(AMX *amx, void *program); int AMXAPI amx_Init(AMX *amx, void *program);
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code); int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap); int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
int AMXAPI amx_NameLength(AMX *amx, int *length); int AMXAPI amx_NameLength(AMX *amx, int *length);
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name,AMX_NATIVE func); AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
int AMXAPI amx_NumNatives(AMX *amx, int *number); int AMXAPI amx_NumNatives(AMX *amx, int *number);
int AMXAPI amx_NumPublics(AMX *amx, int *number); int AMXAPI amx_NumPublics(AMX *amx, int *number);
int AMXAPI amx_NumPubVars(AMX *amx, int *number); int AMXAPI amx_NumPubVars(AMX *amx, int *number);
int AMXAPI amx_NumTags(AMX *amx, int *number); int AMXAPI amx_NumTags(AMX *amx, int *number);
int AMXAPI amx_Push(AMX *amx, cell value);
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
int AMXAPI amx_RaiseError(AMX *amx, int error); int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number); int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
int AMXAPI amx_Release(AMX *amx, cell amx_addr); int AMXAPI amx_Release(AMX *amx, cell amx_addr);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback); int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug); int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar); int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr); int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
int AMXAPI amx_StrLen(cell *cstring, int *length); int AMXAPI amx_StrLen(const cell *cstring, int *length);
int AMXAPI amx_UTF8Check(const char *string, int *length);
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value); int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value); int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
int AMXAPI amx_UTF8Check(const char *string); int AMXAPI amx_GetLibraries(AMX *amx);
void amx_NullNativeTable(AMX *amx); const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
int AMXAPI amx_SetStringOld(cell *dest,const char *source,int pack,int use_wchar);
int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
#if PAWN_CELL_SIZE==16
#define amx_AlignCell(v) amx_Align16(v)
#elif PAWN_CELL_SIZE==32
#define amx_AlignCell(v) amx_Align32(v)
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
#define amx_AlignCell(v) amx_Align64(v)
#else
#error Unsupported cell size
#endif
#define amx_RegisterFunc(amx, name, func) \
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
#if !defined AMX_NO_ALIGN #if !defined AMX_NO_ALIGN
#if defined __linux__ #if defined LINUX || defined __FreeBSD__
#pragma pack() /* reset default packing */ #pragma pack() /* reset default packing */
#elif defined MACOS && defined __MWERKS__
#pragma options align=reset
#else #else
#pragma pack(pop) /* reset previous packing */ #pragma pack(pop) /* reset previous packing */
#endif #endif

View File

@ -1,6 +1,6 @@
/* Core module for the Small AMX /* Core module for the Pawn AMX
* *
* Copyright (c) ITB CompuPhase, 1997-2004 * Copyright (c) ITB CompuPhase, 1997-2005
* *
* This software is provided "as-is", without any express or implied warranty. * This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from * In no event will the authors be held liable for any damages arising from
@ -34,14 +34,7 @@
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
#include <assert.h> #include <assert.h>
// this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST
#include "mmgr/mmgr.h"
#endif // MEMORY_TEST
#include "amx.h" #include "amx.h"
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows #if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
#include <windows.h> #include <windows.h>
#endif #endif
@ -60,14 +53,13 @@
# define _tcscpy strcpy # define _tcscpy strcpy
# define _tcsdup strdup # define _tcsdup strdup
# define _tcslen strlen # define _tcslen strlen
# define _stprintf sprintf
#endif #endif
#define CHARBITS (8*sizeof(char)) #define CHARBITS (8*sizeof(char))
typedef unsigned char uchar; typedef unsigned char uchar;
#if !defined NOPROPLIST #if !defined AMX_NOPROPLIST
typedef struct _property_list { typedef struct _property_list {
struct _property_list *next; struct _property_list *next;
cell id; cell id;
@ -76,7 +68,7 @@ typedef struct _property_list {
//??? safe AMX (owner of the property) //??? safe AMX (owner of the property)
} proplist; } proplist;
static proplist proproot = { NULL }; static proplist proproot = { NULL, 0, NULL, 0 };
static proplist *list_additem(proplist *root) static proplist *list_additem(proplist *root)
{ {
@ -142,15 +134,13 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
} }
#endif #endif
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params) static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
{ {
AMX_HEADER *hdr; AMX_HEADER *hdr;
uchar *data; uchar *data;
cell bytes; cell bytes;
(void)params;
hdr=(AMX_HEADER *)amx->base; hdr=(AMX_HEADER *)amx->base;
data=amx->data ? amx->data : amx->base+(int)hdr->dat; data=amx->data ? amx->data : amx->base+(int)hdr->dat;
/* the number of bytes is on the stack, at "frm + 2*cell" */ /* the number of bytes is on the stack, at "frm + 2*cell" */
@ -190,18 +180,16 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
/* adjust the address in "value" in case of an array access */ /* adjust the address in "value" in case of an array access */
value+=params[2]*sizeof(cell); value+=params[2]*sizeof(cell);
/* verify the address */ /* verify the address */
if (value<0 || (value>=amx->hea && value<amx->stk)) if (value<0 || value>=amx->hea && value<amx->stk)
return 0; return 0;
/* set the value indirectly */ /* set the value indirectly */
* (cell *)(data+(int)value) = params[3]; * (cell *)(data+(int)value) = params[3];
return 1; return 1;
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params) static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
{ {
(void)params;
return amx->stk - amx->hea; return amx->stk - amx->hea;
} }
@ -220,142 +208,22 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
return 0; return 0;
} /* if */ } /* if */
amx_GetString(name,cstr,0); amx_GetString(name,cstr,0,UNLIMITED);
err=amx_FindPublic(amx,name,&index); err=amx_FindPublic(amx,name,&index);
if (err!=AMX_ERR_NONE) if (err!=AMX_ERR_NONE)
index=-1; /* this is not considered a fatal error */ index=-1; /* this is not considered a fatal error */
return index; return index;
} }
int amx_StrPack(cell *dest,cell *source)
{
int len;
amx_StrLen(source,&len);
if ((ucell)*source>UNPACKEDMAX) {
/* source string is already packed */
while (len >= 0) {
*dest++ = *source++;
len-=sizeof(cell);
} /* while */
} else {
/* pack string, from bottom up */
cell c;
int i;
for (c=0,i=0; i<len; i++) {
assert((*source & ~0xffL)==0);
c=(c<<CHARBITS) | *source++;
if (i%sizeof(cell) == sizeof(cell)-1) {
*dest++=c;
c=0;
} /* if */
} /* for */
if (i%sizeof(cell) != 0) /* store remaining packed characters */
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
else
*dest=0; /* store full cell of zeros */
} /* if */
return AMX_ERR_NONE;
}
int amx_StrUnpack(cell *dest,cell *source)
{
if ((ucell)*source>UNPACKEDMAX) {
/* unpack string, from top down (so string can be unpacked in place) */
cell c;
int i,len;
amx_StrLen(source,&len);
dest[len]=0;
for (i=len-1; i>=0; i--) {
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
dest[i]=c & UCHAR_MAX;
} /* for */
} else {
/* source string is already unpacked */
while ((*dest++ = *source++) != 0)
/* nothing */;
} /* if */
return AMX_ERR_NONE;
}
static int verify_addr(AMX *amx,cell addr)
{
int err;
cell *cdest;
err=amx_GetAddr(amx,addr,&cdest);
if (err!=AMX_ERR_NONE)
amx_RaiseError(amx,err);
return err;
}
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
{
cell *cptr;
int len = 0;
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
amx_StrLen(cptr,&len);
return len;
}
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
{
cell *cdest,*csrc;
int len,needed,err;
size_t lastaddr;
/* calculate number of cells needed for (packed) destination */
amx_GetAddr(amx,params[2],&csrc);
amx_StrLen(csrc,&len);
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
assert(needed>0);
lastaddr=(size_t)(params[1]+sizeof(cell)*needed-1);
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
return 0;
amx_GetAddr(amx,params[1],&cdest);
err=amx_StrPack(cdest,csrc);
if (err!=AMX_ERR_NONE)
return amx_RaiseError(amx,err);
return len;
}
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
{
cell *cdest,*csrc;
int len,err;
size_t lastaddr;
/* calculate number of cells needed for (packed) destination */
amx_GetAddr(amx,params[2],&csrc);
amx_StrLen(csrc,&len);
assert(len>=0);
lastaddr=(size_t)(params[1]+sizeof(cell)*(len+1)-1);
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
return 0;
amx_GetAddr(amx,params[1],&cdest);
err=amx_StrUnpack(cdest,csrc);
if (err!=AMX_ERR_NONE)
return amx_RaiseError(amx,err);
return len;
}
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params) static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
{ {
union { union {
cell c; cell c;
#if SMALL_CELL_SIZE==16 #if PAWN_CELL_SIZE==16
uchar b[2]; uchar b[2];
#elif SMALL_CELL_SIZE==32 #elif PAWN_CELL_SIZE==32
uchar b[4]; uchar b[4];
#elif SMALL_CELL_SIZE==64 #elif PAWN_CELL_SIZE==64
uchar b[8]; uchar b[8];
#else #else
#error Unsupported cell size #error Unsupported cell size
@ -363,20 +231,21 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
} value; } value;
uchar t; uchar t;
(void)amx;
assert((size_t)params[0]==sizeof(cell)); assert((size_t)params[0]==sizeof(cell));
value.c = params[1]; value.c = params[1];
#if SMALL_CELL_SIZE==16 #if PAWN_CELL_SIZE==16
t = value.b[0]; t = value.b[0];
value.b[0] = value.b[1]; value.b[0] = value.b[1];
value.b[1] = t; value.b[1] = t;
#elif SMALL_CELL_SIZE==32 #elif PAWN_CELL_SIZE==32
t = value.b[0]; t = value.b[0];
value.b[0] = value.b[3]; value.b[0] = value.b[3];
value.b[3] = t; value.b[3] = t;
t = value.b[1]; t = value.b[1];
value.b[1] = value.b[2]; value.b[1] = value.b[2];
value.b[2] = t; value.b[2] = t;
#elif SMALL_CELL_SIZE==64 #elif PAWN_CELL_SIZE==64
t = value.b[0]; t = value.b[0];
value.b[0] = value.b[7]; value.b[0] = value.b[7];
value.b[7] = t; value.b[7] = t;
@ -395,11 +264,9 @@ static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
return value.c; return value.c;
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params) static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
{ {
(void)amx;
#if defined __WIN32__ || defined _WIN32 || defined WIN32 #if defined __WIN32__ || defined _WIN32 || defined WIN32
return (cell)CharLower((LPTSTR)params[1]); return (cell)CharLower((LPTSTR)params[1]);
#elif defined _Windows #elif defined _Windows
@ -409,11 +276,9 @@ static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
#endif #endif
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params) static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
{ {
(void)amx;
#if defined __WIN32__ || defined _WIN32 || defined WIN32 #if defined __WIN32__ || defined _WIN32 || defined WIN32
return (cell)CharUpper((LPTSTR)params[1]); return (cell)CharUpper((LPTSTR)params[1]);
#elif defined _Windows #elif defined _Windows
@ -423,19 +288,15 @@ static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
#endif #endif
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params) static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
{ {
(void)amx;
return params[1] <= params[2] ? params[1] : params[2]; return params[1] <= params[2] ? params[1] : params[2];
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params) static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
{ {
(void)amx;
return params[1] >= params[2] ? params[1] : params[2]; return params[1] >= params[2] ? params[1] : params[2];
} }
@ -451,7 +312,7 @@ static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
return value; return value;
} }
#if !defined NOPROPLIST #if !defined AMX_NOPROPLIST
static char *MakePackedString(cell *cptr) static char *MakePackedString(cell *cptr)
{ {
int len; int len;
@ -459,10 +320,21 @@ static char *MakePackedString(cell *cptr)
amx_StrLen(cptr,&len); amx_StrLen(cptr,&len);
dest=(char *)malloc(len+sizeof(cell)); dest=(char *)malloc(len+sizeof(cell));
amx_GetString(dest,cptr,0); amx_GetString(dest,cptr,0,UNLIMITED);
return dest; return dest;
} }
static int verify_addr(AMX *amx,cell addr)
{
int err;
cell *cdest;
err=amx_GetAddr(amx,addr,&cdest);
if (err!=AMX_ERR_NONE)
amx_RaiseError(amx,err);
return err;
}
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params) static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
{ {
cell *cstr; cell *cstr;
@ -480,7 +352,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
return 0; return 0;
} /* if */ } /* if */
amx_GetAddr(amx,params[4],&cstr); amx_GetAddr(amx,params[4],&cstr);
amx_SetString(cstr,item->name,1,0); amx_SetString(cstr,item->name,1,0,UNLIMITED);
} /* if */ } /* if */
free(name); free(name);
return (item!=NULL) ? item->value : 0; return (item!=NULL) ? item->value : 0;
@ -545,12 +417,14 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
} }
#endif #endif
#if !defined AMX_NORANDOM
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley /* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number * (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
* generator" that has been extended to 31-bits (the standard C version returns * generator" that has been extended to 31-bits (the standard C version returns
* only 15-bits). * only 15-bits).
*/ */
static unsigned long IL_StandardRandom_seed = 0L; #define INITIAL_SEED 0xcaa938dbL
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
#define IL_RMULT 1103515245L #define IL_RMULT 1103515245L
#if defined __BORLANDC__ || defined __WATCOMC__ #if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused #pragma argsused
@ -562,7 +436,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
/* one-time initialization (or, mostly one-time) */ /* one-time initialization (or, mostly one-time) */
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE #if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
if (IL_StandardRandom_seed == 0L) if (IL_StandardRandom_seed == INITIAL_SEED)
IL_StandardRandom_seed=(unsigned long)time(NULL); IL_StandardRandom_seed=(unsigned long)time(NULL);
#endif #endif
@ -579,6 +453,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
result %= params[1]; result %= params[1];
return (cell)result; return (cell)result;
} }
#endif
AMX_NATIVE_INFO core_Natives[] = { AMX_NATIVE_INFO core_Natives[] = {
@ -587,22 +462,13 @@ AMX_NATIVE_INFO core_Natives[] = {
{ "setarg", setarg }, { "setarg", setarg },
{ "heapspace", heapspace }, { "heapspace", heapspace },
{ "funcidx", funcidx }, { "funcidx", funcidx },
{ "strlen", core_strlen },
{ "strpack", strpack },
{ "strunpack", strunpack },
{ "swapchars", swapchars }, { "swapchars", swapchars },
{ "tolower", core_tolower }, { "tolower", core_tolower },
{ "toupper", core_toupper }, { "toupper", core_toupper },
{ "random", core_random },
{ "min", core_min }, { "min", core_min },
{ "max", core_max }, { "max", core_max },
{ "clamp", core_clamp }, { "clamp", core_clamp },
#if !defined NOPROPLIST { "random", core_random },
{ "getproperty", getproperty },
{ "setproperty", setproperty },
{ "deleteproperty",delproperty },
{ "existproperty", existproperty },
#endif
{ NULL, NULL } /* terminator */ { NULL, NULL } /* terminator */
}; };
@ -611,12 +477,10 @@ int AMXEXPORT amx_CoreInit(AMX *amx)
return amx_Register(amx, core_Natives, -1); return amx_Register(amx, core_Natives, -1);
} }
#if defined __BORLANDC__ || defined __WATCOMC__
#pragma argsused
#endif
int AMXEXPORT amx_CoreCleanup(AMX *amx) int AMXEXPORT amx_CoreCleanup(AMX *amx)
{ {
#if !defined NOPROPLIST (void)amx;
#if !defined AMX_NOPROPLIST
//??? delete only the properties owned by the AMX //??? delete only the properties owned by the AMX
while (proproot.next!=NULL) while (proproot.next!=NULL)
list_delete(&proproot,proproot.next); list_delete(&proproot,proproot.next);

498
amxmodx/amxdbg.cpp Executable file
View File

@ -0,0 +1,498 @@
/* Pawn debugger interface
*
* Support functions for debugger applications
*
* Copyright (c) ITB CompuPhase, 2005
*
* This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Version: $Id$
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "osdefs.h" /* for _MAX_PATH */
#include "amx.h"
#include "amxdbg.h"
// this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST
#include "mmgr/mmgr.h"
#endif // MEMORY_TEST
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg)
{
assert(amxdbg != NULL);
if (amxdbg->hdr != NULL)
free(amxdbg->hdr);
if (amxdbg->filetbl != NULL)
free(amxdbg->filetbl);
if (amxdbg->symboltbl != NULL)
free(amxdbg->symboltbl);
if (amxdbg->tagtbl != NULL)
free(amxdbg->tagtbl);
if (amxdbg->automatontbl != NULL)
free(amxdbg->automatontbl);
if (amxdbg->statetbl != NULL)
free(amxdbg->statetbl);
memset(amxdbg, 0, sizeof(AMX_DBG));
return AMX_ERR_NONE;
}
void memread(void *dest, char **src, size_t size)
{
void *ptr = *src;
memcpy(dest, ptr, size);
*src += size;
}
const char *ClipFileName(const char *inp)
{
static char buffer[256];
size_t len = strlen(inp);
const char *ptr = inp;
for (size_t i=0; i<len; i++)
{
if ((inp[i] == '\\' || inp[i] == '/') && (i != len-1))
ptr = inp + i + 1;
}
strcpy(buffer, ptr);
return buffer;
}
//Note - I changed this function to read from memory instead.
// -- BAILOPAN
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr)
{
AMX_DBG_HDR dbghdr;
unsigned char *ptr;
int index, dim;
AMX_DBG_SYMDIM *symdim;
assert(amxdbg != NULL);
char *addr = (char *)(dbg_addr);
memset(&dbghdr, 0, sizeof(AMX_DBG_HDR));
memread(&dbghdr, &addr, sizeof(AMX_DBG_HDR));
//brabbby graa gragghty graaahhhh
#if BYTE_ORDER==BIG_ENDIAN
amx_Align32((uint32_t*)&dbghdr.size);
amx_Align16(&dbghdr.magic);
amx_Align16(&dbghdr.flags);
amx_Align16(&dbghdr.files);
amx_Align16(&dbghdr.lines);
amx_Align16(&dbghdr.symbols);
amx_Align16(&dbghdr.tags);
amx_Align16(&dbghdr.automatons);
amx_Align16(&dbghdr.states);
#endif
if (dbghdr.magic != AMX_DBG_MAGIC)
return AMX_ERR_FORMAT;
/* allocate all memory */
memset(amxdbg, 0, sizeof(AMX_DBG));
amxdbg->hdr = (AMX_DBG_HDR *)malloc((size_t)dbghdr.size);
if (dbghdr.files > 0)
amxdbg->filetbl = (AMX_DBG_FILE **)malloc(dbghdr.files * sizeof(AMX_DBG_FILE *));
if (dbghdr.symbols > 0)
amxdbg->symboltbl = (AMX_DBG_SYMBOL **)malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *));
if (dbghdr.tags > 0)
amxdbg->tagtbl = (AMX_DBG_TAG **)malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *));
if (dbghdr.automatons > 0)
amxdbg->automatontbl = (AMX_DBG_MACHINE **)malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *));
if (dbghdr.states > 0)
amxdbg->statetbl = (AMX_DBG_STATE **)malloc(dbghdr.states * sizeof(AMX_DBG_STATE *));
if (amxdbg->hdr == NULL
|| (dbghdr.files > 0 && amxdbg->filetbl == NULL)
|| (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL)
|| (dbghdr.tags > 0 && amxdbg->tagtbl == NULL)
|| (dbghdr.states > 0 && amxdbg->statetbl == NULL)
|| (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL))
{
dbg_FreeInfo(amxdbg);
return AMX_ERR_MEMORY;
} /* if */
/* load the entire symbolic information block into memory */
memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr);
ptr = (unsigned char *)(amxdbg->hdr + 1);
memread(ptr, &addr, (size_t)(dbghdr.size-sizeof(dbghdr)));
/* file table */
for (index = 0; index < dbghdr.files; index++) {
assert(amxdbg->filetbl != NULL);
amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr;
#if BYTE_ORDER==BIG_ENDIAN
amx_AlignCell(&amxdbg->filetbl[index]->address);
#endif
for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++)
/* nothing */;
ptr++; /* skip '\0' too */
} /* for */
//debug("Files: %d\n", amxdbg->hdr->files);
for (index=0;index<amxdbg->hdr->files; index++)
{
strcpy((char *)amxdbg->filetbl[index]->name, ClipFileName(amxdbg->filetbl[index]->name));
//debug(" [%d] %s\n", index, amxdbg->filetbl[index]->name);
}
/* line table */
amxdbg->linetbl = (AMX_DBG_LINE*)ptr;
#if BYTE_ORDER==BIG_ENDIAN
for (index = 0; index < dbghdr.lines; index++) {
amx_AlignCell(&amxdbg->linetbl[index].address);
amx_Align32((uint32_t*)&amxdbg->linetbl[index].line);
} /* for */
#endif
ptr += dbghdr.lines * sizeof(AMX_DBG_LINE);
/* symbol table (plus index tags) */
for (index = 0; index < dbghdr.symbols; index++) {
assert(amxdbg->symboltbl != NULL);
amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr;
#if BYTE_ORDER==BIG_ENDIAN
amx_AlignCell(&amxdbg->symboltbl[index]->address);
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag);
amx_AlignCell(&amxdbg->symboltbl[index]->codestart);
amx_AlignCell(&amxdbg->symboltbl[index]->codeend);
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim);
#endif
for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++)
/* nothing */;
ptr++; /* skip '\0' too */
for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) {
symdim = (AMX_DBG_SYMDIM *)ptr;
amx_Align16((uint16_t*)&symdim->tag);
amx_AlignCell(&symdim->size);
ptr += sizeof(AMX_DBG_SYMDIM);
} /* for */
} /* for */
/* tag name table */
for (index = 0; index < dbghdr.tags; index++) {
assert(amxdbg->tagtbl != NULL);
amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr;
#if BYTE_ORDER==BIG_ENDIAN
amx_Align16(&amxdbg->tagtbl[index]->tag);
#endif
for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++)
/* nothing */;
ptr++; /* skip '\0' too */
} /* for */
/* automaton name table */
for (index = 0; index < dbghdr.automatons; index++) {
assert(amxdbg->automatontbl != NULL);
amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr;
#if BYTE_ORDER==BIG_ENDIAN
amx_Align16(&amxdbg->automatontbl[index]->automaton);
amx_AlignCell(&amxdbg->automatontbl[index]->address);
#endif
for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++)
/* nothing */;
ptr++; /* skip '\0' too */
} /* for */
/* state name table */
for (index = 0; index < dbghdr.states; index++) {
assert(amxdbg->statetbl != NULL);
amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr;
#if BYTE_ORDER==BIG_ENDIAN
amx_Align16(&amxdbg->statetbl[index]->state);
amx_Align16(&amxdbg->automatontbl[index]->automaton);
#endif
for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++)
/* nothing */;
ptr++; /* skip '\0' too */
} /* for */
return AMX_ERR_NONE;
}
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename)
{
int index;
assert(amxdbg != NULL);
assert(filename != NULL);
*filename = NULL;
/* this is a simple linear look-up; a binary search would be possible too */
for (index = 0; index < amxdbg->hdr->files && amxdbg->filetbl[index]->address <= address; index++)
/* nothing */;
/* reset for overrun */
if (--index < 0)
return AMX_ERR_NOTFOUND;
*filename = amxdbg->filetbl[index]->name;
return AMX_ERR_NONE;
}
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line)
{
int index;
assert(amxdbg != NULL);
assert(line != NULL);
*line = 0;
/* this is a simple linear look-up; a binary search would be possible too */
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address <= address; index++)
/* nothing */;
/* reset for overrun */
if (--index < 0)
return AMX_ERR_NOTFOUND;
*line = (long)amxdbg->linetbl[index].line;
return AMX_ERR_NONE;
}
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname)
{
/* dbg_LookupFunction() finds the function a code address is in. It can be
* used for stack walking, and for stepping through a function while stepping
* over sub-functions
*/
int index;
assert(amxdbg != NULL);
assert(funcname != NULL);
*funcname = NULL;
for (index = 0; index < amxdbg->hdr->symbols; index++) {
if (amxdbg->symboltbl[index]->ident == iFUNCTN
&& amxdbg->symboltbl[index]->codestart <= address
&& amxdbg->symboltbl[index]->codeend > address)
break;
} /* for */
if (index >= amxdbg->hdr->symbols)
return AMX_ERR_NOTFOUND;
*funcname = amxdbg->symboltbl[index]->name;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name)
{
int index;
assert(amxdbg != NULL);
assert(name != NULL);
*name = NULL;
for (index = 0; index < amxdbg->hdr->tags && amxdbg->tagtbl[index]->tag != tag; index++)
/* nothing */;
if (index >= amxdbg->hdr->tags)
return AMX_ERR_NOTFOUND;
*name = amxdbg->tagtbl[index]->name;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name)
{
int index;
assert(amxdbg != NULL);
assert(name != NULL);
*name = NULL;
for (index = 0; index < amxdbg->hdr->automatons && amxdbg->automatontbl[index]->automaton != automaton; index++)
/* nothing */;
if (index >= amxdbg->hdr->automatons)
return AMX_ERR_NOTFOUND;
*name = amxdbg->automatontbl[index]->name;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name)
{
int index;
assert(amxdbg != NULL);
assert(name != NULL);
*name = NULL;
for (index = 0; index < amxdbg->hdr->states && amxdbg->statetbl[index]->state != state; index++)
/* nothing */;
if (index >= amxdbg->hdr->states)
return AMX_ERR_NOTFOUND;
*name = amxdbg->statetbl[index]->name;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address)
{
/* Find a suitable "breakpoint address" close to the indicated line (and in
* the specified file). The address is moved up to the next "breakable" line
* if no "breakpoint" is available on the specified line. You can use function
* dbg_LookupLine() to find out at which precise line the breakpoint was set.
*
* The filename comparison is strict (case sensitive and path sensitive); the
* "filename" parameter should point into the "filetbl" of the AMX_DBG
* structure.
*/
int file, index;
ucell bottomaddr,topaddr;
assert(amxdbg != NULL);
assert(filename != NULL);
assert(address != NULL);
*address = 0;
index = 0;
for (file = 0; file < amxdbg->hdr->files; file++) {
/* find the (next) mathing instance of the file */
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
continue;
/* get address range for the current file */
bottomaddr = amxdbg->filetbl[file]->address;
topaddr = (file + 1 < amxdbg->hdr->files) ? amxdbg->filetbl[file+1]->address : (ucell)(cell)-1;
/* go to the starting address in the line table */
while (index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < bottomaddr)
index++;
/* browse until the line is found or until the top address is exceeded */
while (index < amxdbg->hdr->lines
&& amxdbg->linetbl[index].line < line
&& amxdbg->linetbl[index].address < topaddr)
index++;
if (index >= amxdbg->hdr->lines)
return AMX_ERR_NOTFOUND;
if (amxdbg->linetbl[index].line >= line)
break;
/* if not found (and the line table is not yet exceeded) try the next
* instance of the same file (a file may appear twice in the file table)
*/
} /* for */
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
return AMX_ERR_NOTFOUND;
assert(index < amxdbg->hdr->lines);
*address = amxdbg->linetbl[index].address;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address)
{
/* Find a suitable "breakpoint address" close to the indicated line (and in
* the specified file). The address is moved up to the first "breakable" line
* in the function. You can use function dbg_LookupLine() to find out at which
* precise line the breakpoint was set.
*
* The filename comparison is strict (case sensitive and path sensitive); the
* "filename" parameter should point into the "filetbl" of the AMX_DBG
* structure. The function name comparison is case sensitive too.
*/
int index, err;
const char *tgtfile;
ucell funcaddr;
assert(amxdbg != NULL);
assert(funcname != NULL);
assert(filename != NULL);
assert(address != NULL);
*address = 0;
index = 0;
for ( ;; ) {
/* find (next) matching function */
while (index < amxdbg->hdr->symbols
&& (amxdbg->symboltbl[index]->ident != iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, funcname) != 0))
index++;
if (index >= amxdbg->hdr->symbols)
return AMX_ERR_NOTFOUND;
/* verify that this line falls in the appropriate file */
err = dbg_LookupFile(amxdbg, amxdbg->symboltbl[index]->address, &tgtfile);
if (err == AMX_ERR_NONE || strcmp(filename, tgtfile) == 0)
break;
index++; /* line is the wrong file, search further */
} /* for */
/* now find the first line in the function where we can "break" on */
assert(index < amxdbg->hdr->symbols);
funcaddr = amxdbg->symboltbl[index]->address;
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < funcaddr; index++)
/* nothing */;
if (index >= amxdbg->hdr->lines)
return AMX_ERR_NOTFOUND;
*address = amxdbg->linetbl[index].address;
return AMX_ERR_NONE;
}
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym)
{
ucell codestart,codeend;
int index;
assert(amxdbg != NULL);
assert(symname != NULL);
assert(sym != NULL);
*sym = NULL;
codestart = codeend = 0;
index = 0;
for ( ;; ) {
/* find (next) matching variable */
while (index < amxdbg->hdr->symbols
&& (amxdbg->symboltbl[index]->ident == iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, symname) != 0)
&& (amxdbg->symboltbl[index]->codestart > scopeaddr || amxdbg->symboltbl[index]->codeend < scopeaddr))
index++;
if (index >= amxdbg->hdr->symbols)
break;
/* check the range, keep a pointer to the symbol with the smallest range */
if (strcmp(amxdbg->symboltbl[index]->name, symname) == 0
&& (codestart == 0 && codeend == 0
|| amxdbg->symboltbl[index]->codestart >= codestart && amxdbg->symboltbl[index]->codeend <= codeend))
{
*sym = amxdbg->symboltbl[index];
codestart = amxdbg->symboltbl[index]->codestart;
codeend = amxdbg->symboltbl[index]->codeend;
} /* if */
index++;
} /* for */
return (*sym == NULL) ? AMX_ERR_NOTFOUND : AMX_ERR_NONE;
}
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim)
{
/* retrieves a pointer to the array dimensions structures of an array symbol */
const char *ptr;
assert(amxdbg != NULL);
assert(sym != NULL);
assert(symdim != NULL);
*symdim = NULL;
if (sym->ident != iARRAY && sym->ident != iREFARRAY)
return AMX_ERR_PARAMS;
assert(sym->dim > 0); /* array must have at least one dimension */
/* find the end of the symbol name */
for (ptr = sym->name; *ptr != '\0'; ptr++)
/* nothing */;
*symdim = (AMX_DBG_SYMDIM *)(ptr + 1);/* skip '\0' too */
return AMX_ERR_NONE;
}

172
amxmodx/amxdbg.h Executable file
View File

@ -0,0 +1,172 @@
/* Abstract Machine for the Pawn compiler, debugger support
*
* This file contains extra definitions that are convenient for debugger
* support.
*
* Copyright (c) ITB CompuPhase, 2005
*
* This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Version: $Id$
*/
#ifndef AMXDBG_H_INCLUDED
#define AMXDBG_H_INCLUDED
#ifndef AMX_H_INCLUDED
#include "amx.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if defined SN_TARGET_PS2 || defined __GNUC__
#define AMX_NO_ALIGN
#endif
#if defined __GNUC__
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#if defined __TURBOC__
#pragma option -a- /* "pack" pragma for older Borland compilers */
#endif
#endif
#endif
typedef struct tagAMX_DBG_HDR {
int32_t size PACKED; /* size of the debug information chunk */
uint16_t magic PACKED; /* signature, must be 0xf1ef */
char file_version PACKED; /* file format version */
char amx_version PACKED; /* required version of the AMX */
int16_t flags PACKED; /* currently unused */
int16_t files PACKED; /* number of entries in the "file" table */
int16_t lines PACKED; /* number of entries in the "line" table */
int16_t symbols PACKED; /* number of entries in the "symbol" table */
int16_t tags PACKED; /* number of entries in the "tag" table */
int16_t automatons PACKED; /* number of entries in the "automaton" table */
int16_t states PACKED; /* number of entries in the "state" table */
} AMX_DBG_HDR PACKED;
#define AMX_DBG_MAGIC 0xf1ef
typedef struct tagAMX_DBG_FILE {
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_FILE PACKED;
typedef struct tagAMX_DBG_LINE {
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
int32_t line PACKED; /* line number */
} AMX_DBG_LINE PACKED;
typedef struct tagAMX_DBG_SYMBOL {
ucell address PACKED; /* address in the data segment or relative to the frame */
int16_t tag PACKED; /* tag for the symbol */
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
char ident PACKED; /* kind of symbol (function/variable) */
char vclass PACKED; /* class of symbol (global/local) */
int16_t dim PACKED; /* number of dimensions */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_SYMBOL PACKED;
typedef struct tagAMX_DBG_SYMDIM {
int16_t tag PACKED; /* tag for the array dimension */
ucell size PACKED; /* size of the array dimension */
} AMX_DBG_SYMDIM PACKED;
typedef struct tagAMX_DBG_TAG {
int16_t tag PACKED; /* tag id */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_TAG PACKED;
typedef struct tagAMX_DBG_MACHINE {
int16_t automaton PACKED; /* automaton id */
ucell address PACKED; /* address of state variable */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_MACHINE PACKED;
typedef struct tagAMX_DBG_STATE {
int16_t state PACKED; /* state id */
int16_t automaton PACKED; /* automaton id */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_STATE PACKED;
typedef struct tagAMX_DBG {
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
AMX_DBG_FILE _FAR **filetbl PACKED;
AMX_DBG_LINE _FAR *linetbl PACKED;
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
AMX_DBG_TAG _FAR **tagtbl PACKED;
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
AMX_DBG_STATE _FAR **statetbl PACKED;
} AMX_DBG PACKED;
#if !defined iVARIABLE
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
#define iARRAY 3
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
#define iFUNCTN 9
#endif
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr);
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack() /* reset default packing */
#elif defined MACOS && defined __MWERKS__
#pragma options align=reset
#else
#pragma pack(pop) /* reset previous packing */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* AMXDBG_H_INCLUDED */

86
amxmodx/amxdefn.asm Executable file
View File

@ -0,0 +1,86 @@
; Definition of the AMX structure for assembler syntax (NASM)
struc amx_s
_base: resd 1
_dataseg: resd 1
_callback: resd 1
_debug: resd 1
_cip: resd 1
_frm: resd 1
_hea: resd 1
_hlw: resd 1
_stk: resd 1
_stp: resd 1
_flags: resd 1
_usertags: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
_userdata: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
_error: resd 1
_paramcount: resd 1
_pri: resd 1
_alt: resd 1
_reset_stk: resd 1
_reset_hea: resd 1
_syscall_d: resd 1
%ifdef JIT
; the two fields below are for the JIT; they do not exist in
; the non-JIT version of the abstract machine
_reloc_size: resd 1 ; memory block for relocations
_code_size: resd 1 ; memory size of the native code
%endif
endstruc
struc amxhead_s
_size: resd 1 ; size of the "file"
_magic: resw 1 ; signature
_file_version: resb 1; file format version
_amx_version: resb 1 ; required version of the AMX
_h_flags: resw 1
_defsize: resw 1 ; size of one public/native function entry
_cod: resd 1 ; initial value of COD - code block
_dat: resd 1 ; initial value of DAT - data block
_h_hea: resd 1 ; initial value of HEA - start of the heap
_h_stp: resd 1 ; initial value of STP - stack top
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
_publics: resd 1 ; offset to the "public functions" table
_natives: resd 1 ; offset to the "native functions" table
_libraries: resd 1 ; offset to the "library" table
_pubvars: resd 1 ; offset to the "public variables" table
_tags: resd 1 ; offset to the "public tagnames" table
_nametable: resd 1 ; offset to the name table, file version 7 only
endstruc
AMX_ERR_NONE EQU 0
AMX_ERR_EXIT EQU 1
AMX_ERR_ASSERT EQU 2
AMX_ERR_STACKERR EQU 3
AMX_ERR_BOUNDS EQU 4
AMX_ERR_MEMACCESS EQU 5
AMX_ERR_INVINSTR EQU 6
AMX_ERR_STACKLOW EQU 7
AMX_ERR_HEAPLOW EQU 8
AMX_ERR_CALLBACK EQU 9
AMX_ERR_NATIVE EQU 10
AMX_ERR_DIVIDE EQU 11 ; for catching divide errors
AMX_ERR_SLEEP EQU 12
AMX_ERR_MEMORY EQU 16
AMX_ERR_FORMAT EQU 17
AMX_ERR_VERSION EQU 18
AMX_ERR_NOTFOUND EQU 19
AMX_ERR_INDEX EQU 20
AMX_ERR_DEBUG EQU 21
AMX_ERR_INIT EQU 22
AMX_ERR_USERDATA EQU 23
AMX_ERR_INIT_JIT EQU 24
AMX_ERR_PARAMS EQU 25
AMX_ERR_DOMAIN EQU 26
AMX_ERR_GENERAL EQU 27
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
AMX_FLAG_COMPACT EQU 0004h
AMX_FLAG_BYTEOPC EQU 0008h
AMX_FLAG_NOCHECKS EQU 0010h
AMX_FLAG_BROWSE EQU 4000h
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated

View File

@ -1,4 +1,4 @@
; AMXEXECN.ASM Abstract Machine for the "Small" language ; AMXEXECN.ASM Abstract Machine for the "Pawn" language
; ;
;Some notes: ;Some notes:
@ -25,7 +25,7 @@
; ;
;Copyright and license of use, please read ;Copyright and license of use, please read
;----------------------------------------- ;-----------------------------------------
;The assembler implementation of the abstract machine for the Small language, ;The assembler implementation of the abstract machine for the Pawn language,
;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter. ;specifically the file AMXEXEC.ASM, is copyright (c) 1998-2000 by Marc Peter.
; ;
;Permission is hereby granted, without written agreement and without paid ;Permission is hereby granted, without written agreement and without paid
@ -56,6 +56,8 @@
; ;
;History (list of changes) ;History (list of changes)
;------------------------- ;-------------------------
; 17 february 2005 by Thiadmer Riemersms
; Addition of the BREAK opcode, removal of the older debugging opcode table.
; 6 march 2004 by Thiadmer Riemersma ; 6 march 2004 by Thiadmer Riemersma
; Corrected a bug in OP_FILL, where a cell preceding the array would ; Corrected a bug in OP_FILL, where a cell preceding the array would
; be overwritten (zero'ed out). This bug was brought to my attention ; be overwritten (zero'ed out). This bug was brought to my attention
@ -95,92 +97,7 @@
%endif %endif
%endmacro %endmacro
%include "amxdefn.asm"
; I could not get NASM's structure definition to work (it appears to confuse
; ENDSTRUC with "end segment"). So the definition below uses constants for
; the field offsets.
;amx_s STRUC
_base EQU 00h ;DD ?
_dataseg EQU 04h ;DD ?
_callback EQU 08h ;DD ?
_debug EQU 0ch ;DD ?
_cip EQU 10h ;DD ?
_frm EQU 14h ;DD ?
_hea EQU 18h ;DD ?
_hlw EQU 1ch ;DD ?
_stk EQU 20h ;DD ?
_stp EQU 24h ;DD ?
_flags EQU 28h ;DD ?
_curline EQU 2ch ;DD ?
_curfile EQU 30h ;DD ?
_dbgcode EQU 34h ;DD ?
_dbgaddr EQU 38h ;DD ?
_dbgparam EQU 3ch ;DD ?
_dbgname EQU 40h ;DD ?
_usertags1 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_usertags2 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_usertags3 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_usertags4 EQU 44h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_userdata1 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_userdata2 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_userdata3 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_userdata4 EQU 54h ;DD 4 DUP (?) ; 4 = AMX_USERNUM (#define'd in amx.h)
_error EQU 64h ;DD ?
_pri EQU 68h ;DD ?
_alt EQU 6ch ;DD ?
_reset_stk EQU 70h ;DD ?
_reset_hea EQU 74h ;DD ?
_syscall_d EQU 78h ;DD ?
; the two fields below are for the JIT; they do not exist in
; the non-JIT version of the abstract machine
; _reloc_size EQU 7ch ;DD ? ; memory block for relocations
; _code_size EQU 80h ;DD ? ; memory size of the native code
;amx_s ENDS
AMX_ERR_NONE EQU 0
AMX_ERR_EXIT EQU 1
AMX_ERR_ASSERT EQU 2
AMX_ERR_STACKERR EQU 3
AMX_ERR_BOUNDS EQU 4
AMX_ERR_MEMACCESS EQU 5
AMX_ERR_INVINSTR EQU 6
AMX_ERR_STACKLOW EQU 7
AMX_ERR_HEAPLOW EQU 8
AMX_ERR_CALLBACK EQU 9
AMX_ERR_NATIVE EQU 10
AMX_ERR_DIVIDE EQU 11 ; MP: added for catching divide errors
AMX_ERR_SLEEP EQU 12 ; (TR)
AMX_ERR_MEMORY EQU 16
AMX_ERR_FORMAT EQU 17
AMX_ERR_VERSION EQU 18
AMX_ERR_NOTFOUND EQU 19
AMX_ERR_INDEX EQU 20
AMX_ERR_DEBUG EQU 21
AMX_ERR_INIT EQU 22
AMX_ERR_USERDATA EQU 23
AMX_ERR_INIT_JIT EQU 24
AMX_ERR_PARAMS EQU 25
AMX_ERR_DOMAIN EQU 26
DBG_INIT EQU 0
DBG_FILE EQU 1
DBG_LINE EQU 2
DBG_SYMBOL EQU 3
DBG_CLRSYM EQU 4
DBG_CALL EQU 5
DBG_RETURN EQU 6
DBG_TERMINATE EQU 7
DBG_SRANGE EQU 8 ; (TR)
DBG_SYMTAG EQU 9 ; (TR)
AMX_FLAG_CHAR16 EQU 0001h ; characters are 16-bit
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
AMX_FLAG_LINEOPS EQU 0020h ; line op information
AMX_FLAG_TRACED EQU 0040h ;
AMX_FLAG_BROWSE EQU 4000h
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v ) ;#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
%macro _PUSH 1 %macro _PUSH 1
@ -212,6 +129,28 @@
jg near err_stack jg near err_stack
%endmacro %endmacro
;Normal abort, saves pri/alt
%macro _ABORT 1
mov ebp,amx
mov [ebp+_pri], dword eax ; store values in AMX structure (PRI, ALT)
mov [ebp+_alt], dword edx ; store values in AMX structure (PRI, ALT)
mov [ebp+_error], dword %1
jmp _return
%endmacro
;Checked abort, saves nothing and uses a conditional
%macro _CHKABORT 1
mov ebp,amx
mov [ebp+_error], %1
cmp %1, AMX_ERR_NONE
jne _return
%endmacro
;Fast abort, only aborts, nothing else
%macro _FASTABORT 0
jmp _return
%endmacro
%macro _CHKHEAP 0 %macro _CHKHEAP 0
mov ebp,amx mov ebp,amx
mov ebp,[ebp+_hlw] mov ebp,[ebp+_hlw]
@ -659,29 +598,6 @@ OP_POP_ALT:
;good ;good
OP_STACK: OP_STACK:
mov edx,ecx
add ecx,[esi+4]
_CHKMARGIN
_CHKSTACK
mov ebp,amx
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
jz short op_stk_goon
; update several structure fields and call the debug hook
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
mov [ebp+_stk],ecx
push eax
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax ; pass parameter via the stack
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop eax
op_stk_goon:
add esi,8
GO_ON
OP_STACK_nodebug:
mov edx,ecx mov edx,ecx
add ecx,[esi+4] add ecx,[esi+4]
_CHKMARGIN _CHKMARGIN
@ -711,35 +627,6 @@ OP_PROC:
GO_ON GO_ON
OP_RET: OP_RET:
_POP ebx
_POP esi
cmp esi,code ; verify ESI>=code
jb err_memaccess
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
jae err_memaccess
mov frm,ebx
add ebx,edi
mov ebp,amx
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_ret_goon
; update several structure fields and call the debug hook
mov DWORD [ebp+_dbgcode],DBG_RETURN
mov [ebp+_dbgparam],eax
push eax
mov [ebp+_stk],ecx ; store STK
mov eax,hea
mov [ebp+_hea],eax ; store HEA
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop eax
op_ret_goon:
GO_ON
OP_RET_nodebug:
_POP ebx _POP ebx
_POP esi _POP esi
cmp esi,code ; verify ESI>=code cmp esi,code ; verify ESI>=code
@ -760,107 +647,17 @@ OP_RETN:
jae err_memaccess jae err_memaccess
mov frm,ebx mov frm,ebx
add ebx,edi add ebx,edi
mov ebp,amx
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_retn_goon
; update several structure fields and call the debug hook
mov DWORD [ebp+_dbgcode],DBG_RETURN
mov [ebp+_dbgparam],eax
push eax
mov [ebp+_stk],ecx ; store STK
mov eax,hea
mov [ebp+_hea],eax ; store HEA
mov eax,ebp ; parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
; also send the DBG_CLRSYM code
mov eax,[edi+ecx]
lea ecx,[ecx+eax+4]
mov DWORD [ebp+_dbgcode],DBG_CLRSYM
mov [ebp+_stk],ecx
mov eax,ebp ; parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop eax
; ECX already adjusted
GO_ON
op_retn_goon:
mov ebp,[edi+ecx] mov ebp,[edi+ecx]
lea ecx,[ecx+ebp+4] lea ecx,[ecx+ebp+4]
GO_ON GO_ON
OP_RETN_nodebug:
_POP ebx
_POP esi
cmp esi,code ; verify ESI>=code
jb err_memaccess
cmp esi,codesiz ; verify ESI<codesiz ("end-of-code" pointer)
jae err_memaccess
mov frm,ebx
mov ebp,[edi+ecx]
add ebx,edi
lea ecx,[ecx+ebp+4]
GO_ON
;good
OP_CALL: OP_CALL:
lea ebp,[esi+8]
mov esi,[esi+4]
_PUSH ebp
mov ebp,amx
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_call_goon
; update several structure fields and call the debug hook
push eax
mov eax,[esp+24] ; this is "code", but ESP moved
mov [ebp+_dbgaddr],esi
sub [ebp+_dbgaddr],eax ; dbgaddr = cip - code
mov DWORD [ebp+_dbgcode],DBG_CALL
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop eax
op_call_goon:
GO_ON
OP_CALL_nodebug:
lea ebp,[esi+8] lea ebp,[esi+8]
mov esi,[esi+4] mov esi,[esi+4]
_PUSH ebp _PUSH ebp
GO_ON GO_ON
OP_CALL_PRI: OP_CALL_PRI:
lea ebp,[esi+4]
mov esi,eax
add esi,code ; cip = PRI + code
_PUSH ebp
mov ebp,amx
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_calli_goon
; update several structure fields and call the debug hook
mov [ebp+_dbgaddr],eax ; dbgaddr = PRI (== cip - code)
mov DWORD [ebp+_dbgcode],DBG_CALL
push eax
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop eax
op_calli_goon:
GO_ON
OP_CALL_PRI_nodebug:
lea ebp,[esi+4] lea ebp,[esi+4]
mov esi,eax mov esi,eax
add esi,code ; cip = PRI + code add esi,code ; cip = PRI + code
@ -941,13 +738,13 @@ OP_JSLESS:
;good ;good
OP_JSLEQ: OP_JSLEQ:
cmp eax,edx cmp eax,edx
jle short jump_taken jle near jump_taken
add esi,8 add esi,8
GO_ON GO_ON
OP_JSGRTR: OP_JSGRTR:
cmp eax,edx cmp eax,edx
jg short jump_taken jg near jump_taken
add esi,8 add esi,8
GO_ON GO_ON
@ -1350,12 +1147,11 @@ OP_CMPS:
_VERIFYADDRESS eax ; PRI _VERIFYADDRESS eax ; PRI
_VERIFYADDRESS edx ; ALT _VERIFYADDRESS edx ; ALT
mov ebp,eax mov ebp,eax
add ebp,[esi+4] add ebp,[esi+4] ; size in bytes
dec ebp dec ebp ; EBP = PRI + size - 1
_VERIFYADDRESS ebp ; PRI + size - 1 _VERIFYADDRESS ebp ; PRI + size - 1
mov ebp,edx sub ebp,eax ; EBP = size - 1
add ebp,[esi+4] add ebp,edx ; EBP = ALT + size - 1
dec ebp
_VERIFYADDRESS ebp ; ALT + size - 1 _VERIFYADDRESS ebp ; ALT + size - 1
push ecx push ecx
@ -1422,21 +1218,7 @@ OP_HALT:
mov eax,esi ; EAX=CIP mov eax,esi ; EAX=CIP
sub eax,code sub eax,code
mov [ebp+_cip],eax mov [ebp+_cip],eax
; optionally call the debug hook _ABORT ebx
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short halt_goon
mov DWORD [ebp+_dbgcode],DBG_TERMINATE
mov [ebp+_dbgaddr],eax
mov [ebp+_dbgparam],ebx
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
halt_goon:
mov eax,ebx ; return the parameter of the HALT opcode
jmp _return
OP_BOUNDS: OP_BOUNDS:
@ -1460,6 +1242,7 @@ OP_SYSREQ_PRI:
mov alt,edx ; save ALT mov alt,edx ; save ALT
mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM) mov [ebp+_stk],ecx ; store values in AMX structure (STK, HEA, FRM)
;we don't save regs since they're useless after this
mov ecx,hea mov ecx,hea
mov ebx,frm mov ebx,frm
mov [ebp+_hea],ecx mov [ebp+_hea],ecx
@ -1490,8 +1273,7 @@ OP_SYSREQ_PRI:
pop edi ; restore saved registers pop edi ; restore saved registers
pop esi pop esi
pop ebp pop ebp
cmp eax,AMX_ERR_NONE _CHKABORT eax ; if result was invalid, leave
jne near _return ; return error code, if any
mov eax,pri ; get retval into eax (PRI) mov eax,pri ; get retval into eax (PRI)
mov edx,alt ; restore ALT mov edx,alt ; restore ALT
@ -1532,8 +1314,8 @@ OP_SYSREQ_D: ; (TR)
pop edi ; restore saved registers pop edi ; restore saved registers
pop esi pop esi
pop ebp pop ebp
cmp DWORD [ebp+_error],AMX_ERR_NONE mov eax,[ebp+_error]
jne near _return ; return error code, if any _CHKABORT eax
; function result is in eax (PRI) ; function result is in eax (PRI)
mov edx,alt ; restore ALT mov edx,alt ; restore ALT
@ -1549,159 +1331,21 @@ OP_FILE:
OP_LINE: OP_LINE:
add esi,12 add esi,12
mov ebp,amx
push eax
push edx
mov eax,[esi-8] ; get curline
mov edx,[esi-4] ; get curfile
mov [ebp+_curline],eax
mov [ebp+_curfile],edx
pop edx
pop eax
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short line_goon
; update several structure fields
mov [ebp+_pri],eax
mov [ebp+_alt],edx ; EAX and EDX are now free to use
mov eax,frm
mov edx,hea
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
mov [ebp+_hea],edx
mov [ebp+_stk],ecx
mov eax,esi
sub eax,code ; EAX = CIP (relative to start of code segment)
mov [ebp+_cip],eax
; call the debugger hook
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
cmp eax,AMX_ERR_NONE
je short line_noabort ; continue running
mov [ebp+_dbgcode],eax ; save EAX (error code) before restoring all regs
_RESTOREREGS ; abort run, but restore stack first
mov eax,[ebp+_dbgcode] ; get error code in EAX back again
jmp _return ; return error code
line_noabort:
_RESTOREREGS
mov eax,[ebp+_pri] ; restore PRI and ALT
mov edx,[ebp+_alt]
line_goon:
GO_ON
OP_LINE_nodebug:
add esi,12
mov ebp,amx
push eax
push edx
mov eax,[esi-8] ; get curline
mov edx,[esi-4] ; get curfile
mov [ebp+_curline],eax
mov [ebp+_curfile],edx
pop edx
pop eax
GO_ON GO_ON
OP_SYMBOL: OP_SYMBOL:
mov ebp,amx
test DWORD [ebp+_flags],AMX_FLAG_DEBUG
jz short op_symbol_goon
push eax
push edx
mov eax,[esi+8] ; address
mov edx,[esi+12] ; flags
mov [ebp+_dbgaddr],eax
mov [ebp+_dbgparam],edx
mov DWORD [ebp+_dbgcode],DBG_SYMBOL
mov eax,esi
add eax,16 ; start of symbol name
mov [ebp+_dbgname],eax
mov edx,[esp+8] ; this is FRM, but offset by two PUSH'es
mov [ebp+_frm],edx
mov eax,ebp ; parameter of the debugger hook
_SAVEREGS
push eax
call [ebp+_debug] ; call debugger hook
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop edx
pop eax
op_symbol_goon:
add esi,[esi+4]
add esi,8 ; skip "fixed" part
GO_ON
OP_SYMBOL_nodebug:
add esi,[esi+4] add esi,[esi+4]
add esi,8 ; skip "fixed" part add esi,8 ; skip "fixed" part
GO_ON GO_ON
OP_SRANGE: OP_SRANGE:
mov ebp,amx
add esi,12
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_srange_goon
push eax
push edx
mov eax,[esi-8] ; get dimensions
mov edx,[esi-4] ; get size
mov [ebp+_dbgaddr],eax
mov [ebp+_dbgparam],edx
mov DWORD [ebp+_dbgcode],DBG_SRANGE
mov edx,frm
mov [ebp+_frm],edx
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
; call the debugger hook
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop edx
pop eax
op_srange_goon:
GO_ON
OP_SRANGE_nodebug:
add esi,12 add esi,12
GO_ON GO_ON
OP_SYMTAG: OP_SYMTAG:
mov ebp,amx
add esi,8
test DWORD [ebp+_flags], AMX_FLAG_DEBUG
jz short op_symtag_goon
mov ebp,amx
push eax
push edx
mov eax,[esi-4] ; get tag
mov edx,frm
mov DWORD [ebp+_dbgcode],DBG_SRANGE
mov [ebp+_dbgparam],eax
mov [ebp+_frm],edx
mov [ebp+_stk],ecx ; store values in AMX structure (STK & FRM)
; call the debugger hook
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
_RESTOREREGS
pop edx
pop eax
op_symtag_goon:
GO_ON
OP_SYMTAG_nodebug: ; (TR)
add esi,8 add esi,8
GO_ON GO_ON
@ -1759,47 +1403,77 @@ OP_PUSHADDR:
OP_NOP: OP_NOP:
add esi,4
GO_ON
OP_BREAK:
mov ebp,amx ; get amx into ebp
add esi,4
cmp DWORD [ebp+_debug], 0
jnz break_calldebug
GO_ON ; debug hook not active, ignore
break_calldebug:
; store the status in the AMX (FRM, STK, HEA, CIP, and PRI + ALT)
mov [ebp+_pri],eax
mov [ebp+_alt],edx ; EAX and EDX are now free to use
mov eax,frm
mov edx,hea
mov [ebp+_frm],eax ; store values in AMX structure (STK, FRM & HEA)
mov [ebp+_hea],edx
mov [ebp+_stk],ecx
mov eax,esi
sub eax,code ; EAX = CIP (relative to start of code segment)
mov [ebp+_cip],eax
; call the debug hook
mov eax,ebp ; 1st parm: amx
_SAVEREGS
push eax
call [ebp+_debug] ; call debug function
_DROPARGS 4 ; remove arguments from stack
cmp eax,AMX_ERR_NONE
je short break_noabort; continue running
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
_RESTOREREGS ; abort run, but restore stack first
mov eax,[ebp+_error] ; get error code in EAX back again
_FASTABORT
break_noabort:
_RESTOREREGS
mov eax,[ebp+_pri] ; restore PRI and ALT
mov edx,[ebp+_alt]
GO_ON GO_ON
OP_INVALID: OP_INVALID:
mov eax,AMX_ERR_INVINSTR _ABORT AMX_ERR_INVINSTR
jmp _return
err_call: err_call:
mov eax,AMX_ERR_CALLBACK _ABORT AMX_ERR_CALLBACK
jmp _return
err_stack: err_stack:
mov eax,AMX_ERR_STACKERR _ABORT AMX_ERR_STACKERR
jmp _return
err_stacklow: err_stacklow:
mov eax,AMX_ERR_STACKLOW _ABORT AMX_ERR_STACKLOW
jmp _return
err_memaccess: err_memaccess:
mov eax,AMX_ERR_MEMACCESS _ABORT AMX_ERR_MEMACCESS
jmp _return
err_bounds: err_bounds:
mov eax,AMX_ERR_BOUNDS _ABORT AMX_ERR_BOUNDS
jmp _return
err_heaplow: err_heaplow:
mov eax,AMX_ERR_HEAPLOW _ABORT AMX_ERR_HEAPLOW
jmp _return
err_divide: err_divide:
mov eax,AMX_ERR_DIVIDE _ABORT AMX_ERR_DIVIDE
jmp _return
_return: _return:
; save a few paraneters, mostly for the "sleep"function ; save a few parameters, mostly for the "sleep"function
mov ebp,amx ; get amx into ebp mov ebp,amx ; get amx into ebp
mov [ebp+_pri],eax ; store values in AMX structure (PRI, ALT) mov [ebp+_cip],esi ; get corrected cip for amxmodx
mov [ebp+_alt],edx ; store values in AMX structure (PRI, ALT) mov eax,[ebp+_error]; get error code
pop esi ; remove FRM from stack pop esi ; remove FRM from stack
@ -1967,144 +1641,5 @@ _amx_opcodelist DD OP_INVALID
DD OP_NOP DD OP_NOP
DD OP_SYSREQ_D DD OP_SYSREQ_D
DD OP_SYMTAG DD OP_SYMTAG
DD OP_BREAK
GLOBAL amx_opcodelist_nodebug
GLOBAL _amx_opcodelist_nodebug
amx_opcodelist_nodebug:
_amx_opcodelist_nodebug DD OP_INVALID
DD OP_LOAD_PRI
DD OP_LOAD_ALT
DD OP_LOAD_S_PRI
DD OP_LOAD_S_ALT
DD OP_LREF_PRI
DD OP_LREF_ALT
DD OP_LREF_S_PRI
DD OP_LREF_S_ALT
DD OP_LOAD_I
DD OP_LODB_I
DD OP_CONST_PRI
DD OP_CONST_ALT
DD OP_ADDR_PRI
DD OP_ADDR_ALT
DD OP_STOR_PRI
DD OP_STOR_ALT
DD OP_STOR_S_PRI
DD OP_STOR_S_ALT
DD OP_SREF_PRI
DD OP_SREF_ALT
DD OP_SREF_S_PRI
DD OP_SREF_S_ALT
DD OP_STOR_I
DD OP_STRB_I
DD OP_LIDX
DD OP_LIDX_B
DD OP_IDXADDR
DD OP_IDXADDR_B
DD OP_ALIGN_PRI
DD OP_ALIGN_ALT
DD OP_LCTRL
DD OP_SCTRL
DD OP_MOVE_PRI
DD OP_MOVE_ALT
DD OP_XCHG
DD OP_PUSH_PRI
DD OP_PUSH_ALT
DD OP_PUSH_R_PRI
DD OP_PUSH_C
DD OP_PUSH
DD OP_PUSH_S
DD OP_POP_PRI
DD OP_POP_ALT
DD OP_STACK_nodebug
DD OP_HEAP
DD OP_PROC
DD OP_RET_nodebug
DD OP_RETN_nodebug
DD OP_CALL_nodebug
DD OP_CALL_PRI_nodebug
DD OP_JUMP
DD OP_JREL
DD OP_JZER
DD OP_JNZ
DD OP_JEQ
DD OP_JNEQ
DD OP_JLESS
DD OP_JLEQ
DD OP_JGRTR
DD OP_JGEQ
DD OP_JSLESS
DD OP_JSLEQ
DD OP_JSGRTR
DD OP_JSGEQ
DD OP_SHL
DD OP_SHR
DD OP_SSHR
DD OP_SHL_C_PRI
DD OP_SHL_C_ALT
DD OP_SHR_C_PRI
DD OP_SHR_C_ALT
DD OP_SMUL
DD OP_SDIV
DD OP_SDIV_ALT
DD OP_UMUL
DD OP_UDIV
DD OP_UDIV_ALT
DD OP_ADD
DD OP_SUB
DD OP_SUB_ALT
DD OP_AND
DD OP_OR
DD OP_XOR
DD OP_NOT
DD OP_NEG
DD OP_INVERT
DD OP_ADD_C
DD OP_SMUL_C
DD OP_ZERO_PRI
DD OP_ZERO_ALT
DD OP_ZERO
DD OP_ZERO_S
DD OP_SIGN_PRI
DD OP_SIGN_ALT
DD OP_EQ
DD OP_NEQ
DD OP_LESS
DD OP_LEQ
DD OP_GRTR
DD OP_GEQ
DD OP_SLESS
DD OP_SLEQ
DD OP_SGRTR
DD OP_SGEQ
DD OP_EQ_C_PRI
DD OP_EQ_C_ALT
DD OP_INC_PRI
DD OP_INC_ALT
DD OP_INC
DD OP_INC_S
DD OP_INC_I
DD OP_DEC_PRI
DD OP_DEC_ALT
DD OP_DEC
DD OP_DEC_S
DD OP_DEC_I
DD OP_MOVS
DD OP_CMPS
DD OP_FILL
DD OP_HALT
DD OP_BOUNDS
DD OP_SYSREQ_PRI
DD OP_SYSREQ_C
DD OP_FILE
DD OP_LINE_nodebug
DD OP_SYMBOL_nodebug
DD OP_SRANGE_nodebug
DD OP_JUMP_PRI
DD OP_SWITCH
DD OP_CASETBL
DD OP_SWAP_PRI
DD OP_SWAP_ALT
DD OP_PUSHADDR
DD OP_NOP
DD OP_SYSREQ_D
DD OP_SYMTAG_nodebug

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -32,10 +32,10 @@
#ifndef AMXMODX_H #ifndef AMXMODX_H
#define AMXMODX_H #define AMXMODX_H
#ifdef __linux__ #ifdef __linux__
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include "sclinux.h"
#endif #endif
#include <ctype.h> //tolower, etc #include <ctype.h> //tolower, etc
#include "string.h" #include "string.h"
@ -44,7 +44,7 @@
#include "mm_pextensions.h" // metamod-p extensions #include "mm_pextensions.h" // metamod-p extensions
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
#include "mmgr/mmgr.h" #include "mmgr/mmgr.h"
#endif #endif
#include "md5.h" #include "md5.h"
@ -68,32 +68,31 @@
#include "amxxlog.h" #include "amxxlog.h"
#define AMXXLOG_Log g_log.Log #define AMXXLOG_Log g_log.Log
#define AMX_VERSION "1.01" #define AMX_VERSION "1.60"
extern AMX_NATIVE_INFO core_Natives[]; extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[]; extern AMX_NATIVE_INFO time_Natives[];
extern AMX_NATIVE_INFO power_Natives[]; extern AMX_NATIVE_INFO power_Natives[];
extern AMX_NATIVE_INFO amxmod_Natives[]; extern AMX_NATIVE_INFO amxmodx_Natives[];
extern AMX_NATIVE_INFO file_Natives[]; extern AMX_NATIVE_INFO file_Natives[];
extern AMX_NATIVE_INFO float_Natives[]; extern AMX_NATIVE_INFO float_Natives[];
extern AMX_NATIVE_INFO string_Natives[]; extern AMX_NATIVE_INFO string_Natives[];
extern AMX_NATIVE_INFO vault_Natives[]; extern AMX_NATIVE_INFO vault_Natives[];
#ifndef __linux__ #ifndef __linux__
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path) #define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
#define DLPROC(m,func) GetProcAddress(m,func) #define DLPROC(m, func) GetProcAddress(m, func)
#define DLFREE(m) FreeLibrary(m) #define DLFREE(m) FreeLibrary(m)
#else #else
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW) #define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW)
#define DLPROC(m,func) dlsym(m,func) #define DLPROC(m, func) dlsym(m, func)
#define DLFREE(m) dlclose(m) #define DLFREE(m) dlclose(m)
#endif #endif
#ifndef __linux__ #ifndef __linux__
typedef HINSTANCE DLHANDLE; typedef HINSTANCE DLHANDLE;
#else #else
typedef void* DLHANDLE; typedef void* DLHANDLE;
#endif #endif
#ifndef GETPLAYERAUTHID #ifndef GETPLAYERAUTHID
@ -109,33 +108,38 @@ typedef void* DLHANDLE;
char* UTIL_SplitHudMessage(register const char *src); char* UTIL_SplitHudMessage(register const char *src);
int UTIL_ReadFlags(const char* c); int UTIL_ReadFlags(const char* c);
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg );
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg);
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL); void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL);
void UTIL_GetFlags(char* flags,int flag); void UTIL_GetFlags(char* flags, int flag);
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage); void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
void UTIL_IntToString(int value, char *output); void UTIL_IntToString(int value, char *output);
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name); void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name);
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen ); void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen);
char *UTIL_VarArgs(const char *fmt, ...);
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)]) #define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t ))]) //#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t))])
#define GET_PLAYER_POINTER_I(i) (&g_players[i]) #define GET_PLAYER_POINTER_I(i) (&g_players[i])
struct WeaponsVault { struct WeaponsVault
{
String fullName; String fullName;
short int iId; short int iId;
short int ammoSlot; short int ammoSlot;
}; };
struct fakecmd_t { struct fakecmd_t
{
char args[256]; char args[256];
const char *argv[3]; const char *argv[3];
//char argv[3][128];
int argc; int argc;
bool fake; bool fake;
}; };
extern bool g_IsNewMM;
extern pextension_funcs_t *gpMetaPExtFuncs; extern pextension_funcs_t *gpMetaPExtFuncs;
extern CLog g_log; extern CLog g_log;
extern CPluginMngr g_plugins; extern CPluginMngr g_plugins;
@ -147,7 +151,8 @@ extern CList<CCVar> g_cvars;
extern CList<ForceObject> g_forcemodels; extern CList<ForceObject> g_forcemodels;
extern CList<ForceObject> g_forcesounds; extern CList<ForceObject> g_forcesounds;
extern CList<ForceObject> g_forcegeneric; extern CList<ForceObject> g_forcegeneric;
extern CList<CModule,const char *> g_modules; extern CList<CModule, const char *> g_modules;
extern CList<CScript, AMX*> g_loadedscripts;
extern CList<CPlayer*> g_auth; extern CList<CPlayer*> g_auth;
extern EventsMngr g_events; extern EventsMngr g_events;
extern Grenades g_grenades; extern Grenades g_grenades;
@ -173,6 +178,7 @@ extern float g_game_restarting;
extern float g_game_timeleft; extern float g_game_timeleft;
extern float g_task_time; extern float g_task_time;
extern float g_auth_time; extern float g_auth_time;
extern bool g_NewDLL_Available;
extern hudtextparms_t g_hudset; extern hudtextparms_t g_hudset;
//extern int g_edict_point; //extern int g_edict_point;
extern int g_players_num; extern int g_players_num;
@ -221,14 +227,16 @@ void Client_DeathMsg(void*);
void amx_command(); void amx_command();
void plugin_srvcmd(); void plugin_srvcmd();
const char* stristr(const char* a,const char* b); const char* stristr(const char* a, const char* b);
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem); char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
int loadModules(const char* filename); int loadModules(const char* filename, PLUG_LOADTIME now);
void detachModules(); void detachModules();
void detachReloadModules(); void detachReloadModules();
void attachModules();
void attachMetaModModules(PLUG_LOADTIME now, const char* filename); #ifdef FAKEMETA
void attachModules();
#endif
// Count modules // Count modules
enum CountModulesMode enum CountModulesMode
@ -241,26 +249,28 @@ enum CountModulesMode
int countModules(CountModulesMode mode); int countModules(CountModulesMode mode);
void modules_callPluginsLoaded(); void modules_callPluginsLoaded();
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives); cell* get_amxaddr(AMX *amx, cell amx_addr);
cell* get_amxaddr(AMX *amx,cell amx_addr); char* build_pathname(char *fmt, ...);
char* build_pathname(char *fmt, ... ); char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
char* format_amxstring(AMX *amx, cell *params, int parm,int& len); char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
AMX* get_amxscript(int, void**,const char**); AMX* get_amxscript(int, void**, const char**);
const char* get_amxscriptname(AMX* amx); const char* get_amxscriptname(AMX* amx);
char* get_amxstring(AMX *amx,cell amx_addr,int id,int& len); char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
int amxstring_len(cell* cstr); int amxstring_len(cell* cstr);
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug); int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
int set_amxnatives(AMX* amx,char error[64]); int set_amxnatives(AMX* amx, char error[64]);
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max); int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max);
int unload_amxscript(AMX* amx,void** program); int unload_amxscript(AMX* amx, void** program);
void copy_amxmemory(cell* dest,cell* src,int len);
void copy_amxmemory(cell* dest, cell* src, int len);
void get_modname(char*); void get_modname(char*);
void print_srvconsole( char *fmt, ... ); void print_srvconsole(char *fmt, ...);
void report_error( int code, char* fmt, ... ); void report_error(int code, char* fmt, ...);
void* alloc_amxmemory(void**, int size); void* alloc_amxmemory(void**, int size);
void free_amxmemory(void **ptr); void free_amxmemory(void **ptr);
// get_localinfo // get_localinfo
const char* get_localinfo( const char* name , const char* def ); const char* get_localinfo(const char* name, const char* def);
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params); cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
void LogError(AMX *amx, int err, const char *fmt, ...); void LogError(AMX *amx, int err, const char *fmt, ...);
@ -275,7 +285,9 @@ enum ModuleCallReason
extern ModuleCallReason g_ModuleCallReason; // modules.cpp extern ModuleCallReason g_ModuleCallReason; // modules.cpp
extern CModule *g_CurrentlyCalledModule; // modules.cpp extern CModule *g_CurrentlyCalledModule; // modules.cpp
extern const char *g_LastRequestedFunc; // modules.cpp extern const char *g_LastRequestedFunc; // modules.cpp
extern CQueue<String> CurModuleList;
void Module_CacheFunctions();
void Module_UncacheFunctions();
void *Module_ReqFnptr(const char *funcName); // modules.cpp void *Module_ReqFnptr(const char *funcName); // modules.cpp
@ -293,7 +305,16 @@ extern int FF_PluginLog;
extern int FF_PluginEnd; extern int FF_PluginEnd;
extern int FF_InconsistentFile; extern int FF_InconsistentFile;
extern int FF_ClientAuthorized; extern int FF_ClientAuthorized;
extern bool g_coloredmenus;
#ifdef FAKEMETA
extern CFakeMeta g_FakeMeta;
#endif
struct func_s
{
void *pfn;
const char *desc;
};
extern CFakeMeta g_FakeMeta;
#endif // AMXMODX_H #endif // AMXMODX_H

View File

@ -18,6 +18,8 @@
# endif # endif
#endif #endif
#include <stdlib.h>
// this file does not include amxmodx.h, so we have to include the memory manager here // this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
#include "mmgr/mmgr.h" #include "mmgr/mmgr.h"

View File

@ -3,7 +3,6 @@
* by the AMX Mod X Development Team * by the AMX Mod X Development Team
* originally developed by OLO * originally developed by OLO
* *
*
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at * Free Software Foundation; either version 2 of the License, or (at
@ -36,6 +35,7 @@
/********************** /**********************
****** AMXXFILE ****** ****** AMXXFILE ******
**********************/ **********************/
#if defined __GNUC__ #if defined __GNUC__
#define PACKED __attribute__((packed)) #define PACKED __attribute__((packed))
#else #else
@ -51,10 +51,6 @@
#endif #endif
#endif #endif
typedef char mint8_t;
typedef int16_t mint16_t;
typedef int32_t mint32_t;
struct TableEntry struct TableEntry
{ {
mint8_t cellSize PACKED; mint8_t cellSize PACKED;
@ -76,6 +72,9 @@ struct TableEntry
CAmxxReader::CAmxxReader(const char *filename, int cellsize) CAmxxReader::CAmxxReader(const char *filename, int cellsize)
{ {
m_Bh.plugins = NULL;
m_AmxxFile = false;
if (!filename) if (!filename)
{ {
m_Status = Err_InvalidParam; m_Status = Err_InvalidParam;
@ -84,8 +83,8 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
m_Status = Err_None; m_Status = Err_None;
m_CellSize = cellsize; m_CellSize = cellsize;
m_pFile = fopen(filename, "rb"); m_pFile = fopen(filename, "rb");
if (!m_pFile) if (!m_pFile)
{ {
m_Status = Err_FileOpen; m_Status = Err_FileOpen;
@ -96,42 +95,71 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
DATAREAD(&magic, sizeof(magic), 1); DATAREAD(&magic, sizeof(magic), 1);
m_OldFile = false; m_OldFile = false;
if (magic != 0x414D5842)
{
// check for old file
AMX_HEADER hdr;
rewind(m_pFile);
fread(&hdr, sizeof(hdr), 1, m_pFile);
amx_Align16(&hdr.magic);
if (hdr.magic == AMX_MAGIC)
{
if (cellsize != 4)
{
m_Status = Err_SectionNotFound;
fclose(m_pFile);
m_pFile = NULL;
return;
}
m_OldFile = true; if (magic == 0x524C4542)
return;
}
else
{ {
// no known file format
m_Status = Err_FileInvalid;
fclose(m_pFile);
m_pFile = NULL;
return;
}
} else if ( magic == 0x524C4542 ) {
//we have an invalid, old, RLEB file //we have an invalid, old, RLEB file
m_Status = Err_OldFile; m_Status = Err_OldFile;
fclose(m_pFile); fclose(m_pFile);
m_pFile = NULL; m_pFile = NULL;
return;
} else {
return;
}
else if (magic == MAGIC_HEADER2)
{
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
if (m_Bh.version != MAGIC_VERSION)
{
m_Status = Err_OldFile;
fclose(m_pFile);
m_pFile = NULL;
return;
}
m_AmxxFile = true;
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
PluginEntry *pe;
m_SectionHdrOffset = 0;
m_Entry = -1;
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
{
pe = &(m_Bh.plugins[i]);
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
DATAREAD(&pe->disksize, sizeof(int32_t), 1);
DATAREAD(&pe->imagesize, sizeof(int32_t), 1);
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
DATAREAD(&pe->offs, sizeof(int32_t), 1);
}
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
{
pe = &(m_Bh.plugins[i]);
if (pe->cellsize == m_CellSize)
{
m_Entry = i;
break;
}
}
if (m_Entry == -1)
{
m_Status = Err_SectionNotFound;
fclose(m_pFile);
m_pFile = NULL;
return;
}
pe = &(m_Bh.plugins[m_Entry]);
m_SectionLength = pe->disksize;
}
else if (magic == MAGIC_HEADER)
{
// try to find the section // try to find the section
mint8_t numOfPlugins; mint8_t numOfPlugins;
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1); DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
@ -140,6 +168,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
m_SectionHdrOffset = 0; m_SectionHdrOffset = 0;
int i = 0; int i = 0;
for (i = 0; i < static_cast<int>(numOfPlugins); ++i) for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
{ {
DATAREAD(&entry, sizeof(entry), 1); DATAREAD(&entry, sizeof(entry), 1);
@ -149,6 +178,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
break; break;
} }
} }
if (!m_SectionHdrOffset) if (!m_SectionHdrOffset)
{ {
m_Status = Err_SectionNotFound; m_Status = Err_SectionNotFound;
@ -158,18 +188,45 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
} }
// compute section length // compute section length
if ((i+1) < static_cast<int>(numOfPlugins)) if ((i + 1) < static_cast<int>(numOfPlugins))
{ {
// there is a next section // there is a next section
TableEntry nextEntry; TableEntry nextEntry;
DATAREAD(&nextEntry, sizeof(nextEntry), 1); DATAREAD(&nextEntry, sizeof(nextEntry), 1);
m_SectionLength = nextEntry.offset - entry.offset; m_SectionLength = nextEntry.offset - entry.offset;
} } else {
else
{
fseek(m_pFile, 0, SEEK_END); fseek(m_pFile, 0, SEEK_END);
m_SectionLength = ftell(m_pFile) - (long)entry.offset; m_SectionLength = ftell(m_pFile) - (long)entry.offset;
} }
} else {
// check for old file
AMX_HEADER hdr;
rewind(m_pFile);
fread(&hdr, sizeof(hdr), 1, m_pFile);
amx_Align16(&hdr.magic);
if (hdr.magic == AMX_MAGIC)
{
if (cellsize != 4)
{
m_Status = Err_SectionNotFound;
fclose(m_pFile);
m_pFile = NULL;
return;
}
m_OldFile = true;
return;
} else {
// no known file format
m_Status = Err_FileInvalid;
fclose(m_pFile);
m_pFile = NULL;
return;
}
} }
} }
@ -180,6 +237,12 @@ CAmxxReader::~CAmxxReader()
fclose(m_pFile); fclose(m_pFile);
m_pFile = NULL; m_pFile = NULL;
} }
if (m_Bh.plugins)
{
delete [] m_Bh.plugins;
m_Bh.plugins = NULL;
}
} }
CAmxxReader::Error CAmxxReader::GetStatus() CAmxxReader::Error CAmxxReader::GetStatus()
@ -205,7 +268,6 @@ size_t CAmxxReader::GetBufferSize()
if (!m_pFile) if (!m_pFile)
return 0; return 0;
long save = ftell(m_pFile); long save = ftell(m_pFile);
if (m_OldFile) if (m_OldFile)
@ -214,14 +276,25 @@ size_t CAmxxReader::GetBufferSize()
AMX_HEADER hdr; AMX_HEADER hdr;
DATAREAD(&hdr, sizeof(hdr), 1); DATAREAD(&hdr, sizeof(hdr), 1);
fseek(m_pFile, save, SEEK_SET); fseek(m_pFile, save, SEEK_SET);
return hdr.stp; return hdr.stp;
} }
else if (m_AmxxFile)
{
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
if (pe->imagesize > pe->memsize)
return pe->imagesize + 1;
return pe->memsize + 1;
}
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET); fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
TableEntry entry; TableEntry entry;
DATAREAD(&entry, sizeof(entry), 1); DATAREAD(&entry, sizeof(entry), 1);
fseek(m_pFile, save, SEEK_SET); fseek(m_pFile, save, SEEK_SET);
return entry.origSize + 1; // +1 : safe return entry.origSize + 1; // +1 : safe
} }
@ -251,31 +324,51 @@ CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
rewind(m_pFile); rewind(m_pFile);
DATAREAD(buffer, 1, filesize); DATAREAD(buffer, 1, filesize);
m_Status = Err_None; m_Status = Err_None;
return m_Status; return m_Status;
} }
else if (m_AmxxFile)
{
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
char *tempBuffer = new char[m_SectionLength + 1];
fseek(m_pFile, pe->offs, SEEK_SET);
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
uLongf destLen = GetBufferSize();
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
delete [] tempBuffer;
if (result != Z_OK)
{
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
m_Status = Err_Decompress;
return Err_Decompress;
}
return Err_None;
} else {
// new file type: go to the section table entry // new file type: go to the section table entry
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET); fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
// go to the offset // go to the offset
TableEntry entry; TableEntry entry;
DATAREAD(&entry, sizeof(entry), 1); DATAREAD(&entry, sizeof(entry), 1);
fseek(m_pFile, entry.offset, SEEK_SET); fseek(m_pFile, entry.offset, SEEK_SET);
// AMXXLOG_Log("|||| Offset needed: %d At: %d", entry.offset, ftell(m_pFile));
uLongf destLen = GetBufferSize(); uLongf destLen = GetBufferSize();
// read the data to a temporary buffer // read the data to a temporary buffer
char *tempBuffer = new char[m_SectionLength + 1]; char *tempBuffer = new char[m_SectionLength + 1];
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile); //fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
DATAREAD((void*)tempBuffer, 1, m_SectionLength); DATAREAD((void*)tempBuffer, 1, m_SectionLength);
// decompress // decompress
// AMXXLOG_Log("|||| First Bytes: %d %d %d %d", tempBuffer[0], tempBuffer[1], tempBuffer[2], tempBuffer[3]); int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
int result = uncompress((Bytef *)buffer, &destLen,
(Bytef *)tempBuffer, m_SectionLength);
delete [] tempBuffer; delete [] tempBuffer;
// AMXXLOG_Log("|||| Result: %d, m_SectionLength=%d, destLen=%d", result, m_SectionLength, destLen);
if (result != Z_OK) if (result != Z_OK)
{ {
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
m_Status = Err_Decompress; m_Status = Err_Decompress;
return Err_Decompress; return Err_Decompress;
} }
return Err_None; return Err_None;
}
} }

View File

@ -32,6 +32,31 @@
#ifndef __AMXXFILE_H__ #ifndef __AMXXFILE_H__
#define __AMXXFILE_H__ #define __AMXXFILE_H__
#define MAGIC_HEADER 0x414D5842
#define MAGIC_HEADER2 0x414D5858
#define MAGIC_VERSION 0x0300
typedef char mint8_t;
typedef int16_t mint16_t;
typedef int32_t mint32_t;
struct PluginEntry
{
mint8_t cellsize; //cell size
int32_t imagesize; //uncompressed image size
int32_t disksize; //compressed image size
int32_t memsize; //memory image size
int32_t offs; //file offset
};
struct BinHeader
{
int32_t magic;
mint16_t version;
mint8_t numPlugins;
PluginEntry *plugins;
};
class CAmxxReader class CAmxxReader
{ {
public: public:
@ -53,6 +78,9 @@ private:
FILE *m_pFile; FILE *m_pFile;
bool m_OldFile; // old .amx file bool m_OldFile; // old .amx file
bool m_AmxxFile; // new 'AMXX' header format
BinHeader m_Bh; // binary header
int m_Entry; // entry #
int m_CellSize; int m_CellSize;
int m_SectionHdrOffset; // offset to the table in the header that describes the required section int m_SectionHdrOffset; // offset to the table in the header that describes the required section
@ -66,6 +94,4 @@ public:
Error GetSection(void *buffer); // Copy the currently selected section to the buffer Error GetSection(void *buffer); // Copy the currently selected section to the buffer
}; };
#endif // __AMXXFILE_H__ #endif // __AMXXFILE_H__

View File

@ -36,12 +36,12 @@
#include <time.h> #include <time.h>
#ifndef __linux__ #ifndef __linux__
#include <io.h> #include <io.h>
#endif #endif
#include "amxmodx.h" #include "amxmodx.h"
#ifndef __linux__ #ifndef __linux__
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#endif #endif
CLog::CLog() CLog::CLog()
@ -61,6 +61,7 @@ void CLog::CloseFile()
if (!m_LogFile.empty()) if (!m_LogFile.empty())
{ {
FILE *fp = fopen(m_LogFile.c_str(), "r"); FILE *fp = fopen(m_LogFile.c_str(), "r");
if (fp) if (fp)
{ {
fclose(fp); fclose(fp);
@ -77,6 +78,7 @@ void CLog::CloseFile()
fprintf(fp, "L %s: %s\n", date, "Log file closed."); fprintf(fp, "L %s: %s\n", date, "Log file closed.");
fclose(fp); fclose(fp);
} }
m_LogFile.clear(); m_LogFile.clear();
} }
} }
@ -84,30 +86,33 @@ void CLog::CloseFile()
void CLog::CreateNewFile() void CLog::CreateNewFile()
{ {
CloseFile(); CloseFile();
// build filename // build filename
time_t td; time_t td;
time(&td); time(&td);
tm *curTime = localtime(&td); tm *curTime = localtime(&td);
int i = 0; int i = 0;
while (true) while (true)
{ {
m_LogFile.assign(build_pathname("%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i));
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
if (!pTmpFile) if (!pTmpFile)
break; break;
fclose(pTmpFile); fclose(pTmpFile);
++i; ++i;
} }
// Log logfile start // Log logfile start
FILE *fp = fopen(m_LogFile.c_str(), "w"); FILE *fp = fopen(m_LogFile.c_str(), "w");
if (!fp) if (!fp)
{ {
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n"); ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
SET_LOCALINFO("amxx_logging", "0"); SET_LOCALINFO("amxx_logging", "0");
} } else {
else
{
fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION); fprintf(fp, "AMX Mod X log file started (file \"%s/L%02d%02d%03d.log\") (version \"%s\")\n", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i, AMX_VERSION);
fclose(fp); fclose(fp);
} }
@ -115,19 +120,22 @@ void CLog::CreateNewFile()
void CLog::UseFile(const String &fileName) void CLog::UseFile(const String &fileName)
{ {
m_LogFile.assign(build_pathname("%s/%s", g_log_dir.c_str(), fileName.c_str())); static char file[256];
m_LogFile.assign(build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), fileName.c_str()));
} }
void CLog::MapChange() void CLog::MapChange()
{ {
// create dir if not existing // create dir if not existing
char file[256];
#ifdef __linux #ifdef __linux
mkdir(build_pathname("%s", g_log_dir.c_str()), 0700); mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
#else #else
mkdir(build_pathname("%s", g_log_dir.c_str())); mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
#endif #endif
m_LogType = atoi(get_localinfo("amxx_logging", "1")); m_LogType = atoi(get_localinfo("amxx_logging", "1"));
if (m_LogType < 0 || m_LogType > 3) if (m_LogType < 0 || m_LogType > 3)
{ {
SET_LOCALINFO("amxx_logging", "1"); SET_LOCALINFO("amxx_logging", "1");
@ -142,7 +150,7 @@ void CLog::MapChange()
} }
else if (m_LogType == 1) else if (m_LogType == 1)
{ {
Log("-------- Mapchange --------"); Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
} }
else else
return; return;
@ -150,6 +158,8 @@ void CLog::MapChange()
void CLog::Log(const char *fmt, ...) void CLog::Log(const char *fmt, ...)
{ {
static char file[256];
if (m_LogType == 1 || m_LogType == 2) if (m_LogType == 1 || m_LogType == 2)
{ {
// get time // get time
@ -161,14 +171,14 @@ void CLog::Log(const char *fmt, ...)
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime); strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
// msg // msg
char msg[3072]; static char msg[3072];
va_list arglst; va_list arglst;
va_start(arglst, fmt); va_start(arglst, fmt);
vsnprintf(msg, 3071, fmt, arglst); vsnprintf(msg, 3071, fmt, arglst);
va_end(arglst); va_end(arglst);
FILE *pF; FILE *pF = NULL;
if (m_LogType == 2) if (m_LogType == 2)
{ {
pF = fopen(m_LogFile.c_str(), "a+"); pF = fopen(m_LogFile.c_str(), "a+");
@ -176,6 +186,7 @@ void CLog::Log(const char *fmt, ...)
{ {
CreateNewFile(); CreateNewFile();
pF = fopen(m_LogFile.c_str(), "a+"); pF = fopen(m_LogFile.c_str(), "a+");
if (!pF) if (!pF)
{ {
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str()); ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
@ -183,19 +194,17 @@ void CLog::Log(const char *fmt, ...)
return; return;
} }
} }
} else {
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
pF = fopen(file, "a+");
} }
else
{
pF = fopen(build_pathname("%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday), "a+");
}
if (pF) if (pF)
{ {
fprintf(pF, "L %s: %s\n", date, msg); fprintf(pF, "L %s: %s\n", date, msg);
fclose(pF); fclose(pF);
} } else {
else ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
{
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
m_LogType = 0; m_LogType = 0;
return; return;
} }
@ -206,12 +215,11 @@ void CLog::Log(const char *fmt, ...)
else if (m_LogType == 3) else if (m_LogType == 3)
{ {
// build message // build message
// :TODO: Overflow possible here static char msg_[3072];
char msg[3072];
va_list arglst; va_list arglst;
va_start(arglst, fmt); va_start(arglst, fmt);
vsnprintf(msg, 3071, fmt, arglst); vsnprintf(msg_, 3071, fmt, arglst);
va_end(arglst); va_end(arglst);
ALERT(at_logged, "%s\n", msg); ALERT(at_logged, "%s\n", msg_);
} }
} }

View File

@ -42,6 +42,7 @@ private:
public: public:
CLog(); CLog();
~CLog(); ~CLog();
void CreateNewFile(); void CreateNewFile();
void CloseFile(); void CloseFile();
void MapChange(); void MapChange();
@ -49,4 +50,3 @@ public:
}; };
#endif // __AMXXLOG_H__ #endif // __AMXXLOG_H__

1230
amxmodx/debugger.cpp Executable file

File diff suppressed because it is too large Load Diff

201
amxmodx/debugger.h Executable file
View File

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

View File

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

View File

@ -28,10 +28,53 @@
* version. * version.
*/ */
// Fake metamod api
#include "amxmodx.h" #include "amxmodx.h"
#include "fakemeta.h" #include "fakemeta.h"
#ifndef FAKEMETA
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now)
{
if (gpMetaPExtFuncs)
{
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, path, now, handle) || !*handle)
{
LOG_MESSAGE(PLID, "Can't Attach metamod-module \"%s\".", path);
return 0;
}
return 1;
} else if (g_IsNewMM) {
int err = 0;
if ( (err = LOAD_PLUGIN(PLID, path, now, handle)) || !*handle)
{
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", path);
return 0;
}
return 1;
}
return 0;
}
int UnloadMetamodPlugin(void *handle)
{
if (gpMetaPExtFuncs)
{
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)handle, PT_ANYTIME, PNL_PLUGIN)) {
return 0;
}
return 1;
} else if (g_IsNewMM) {
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)handle, PT_ANYTIME, PNL_PLUGIN))
{
return 0;
}
return 1;
}
return 0;
}
#else
// Fake metamod api
// for varargs // for varargs
#define MAX_STRBUF_LEN 512 #define MAX_STRBUF_LEN 512
@ -2355,7 +2398,7 @@ void FakeMeta_New_CVarRegister(cvar_t *pCVar)
int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs) int CFakeMeta::CFakeMetaPlugin::Query(mutil_funcs_t *pMetaUtilFuncs)
{ {
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) if(gpMetaPExtFuncs || g_IsNewMM)
{ {
//load plugins in meta_attach //load plugins in meta_attach
m_Status = PL_OPENED; m_Status = PL_OPENED;
@ -2429,8 +2472,22 @@ int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlob
{ {
// evilspy's patch: // evilspy's patch:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if (gpMetaPExtFuncs)
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, m_Path.c_str(), now, (void**)&m_Handle) || !m_Handle) { {
if(PEXT_LOAD_PLUGIN_BY_NAME(PLID, m_Path.c_str(), now, (void**)&m_Handle) || !m_Handle)
{
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
m_Status = PL_FAILED;
return 0;
}
m_Status = PL_RUNNING;
return 1;
} else if (g_IsNewMM) {
int err = 0;
if ( (err = LOAD_PLUGIN(PLID, m_Path.c_str(), now, (void **)&m_Handle)) || !m_Handle)
{
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
m_Status = PL_FAILED; m_Status = PL_FAILED;
return 0; return 0;
} }
@ -2441,6 +2498,7 @@ int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlob
if (!m_Handle) if (!m_Handle)
return 0; return 0;
META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach"); META_ATTACH_FN attachFn = (META_ATTACH_FN)DLSYM(m_Handle, "Meta_Attach");
if (!attachFn) if (!attachFn)
{ {
@ -2450,7 +2508,7 @@ int CFakeMeta::CFakeMetaPlugin::Attach(PLUG_LOADTIME now, meta_globals_t *pMGlob
} }
if (attachFn(now, &m_MetaFuncTable, pMGlobals, pGameDllFuncs) != 1) if (attachFn(now, &m_MetaFuncTable, pMGlobals, pGameDllFuncs) != 1)
{ {
AMXXLOG_Log("[AMXX] Can't Attach Module \"%s\" (\"%s\").", m_Info->name, m_Path.c_str()); LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", m_Path.c_str());
m_Status = PL_FAILED; m_Status = PL_FAILED;
return 0; return 0;
} }
@ -2466,7 +2524,8 @@ int CFakeMeta::CFakeMetaPlugin::Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reaso
// evilspy's patch: // evilspy's patch:
//using metamod p-extensions? //using metamod p-extensions?
if (gpMetaPExtFuncs) { if (gpMetaPExtFuncs)
{
if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)m_Handle, now, reason)) { if(PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, (void*)m_Handle, now, reason)) {
m_Status = PL_FAILED; m_Status = PL_FAILED;
return 0; return 0;
@ -2474,6 +2533,15 @@ int CFakeMeta::CFakeMetaPlugin::Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reaso
m_Status = PL_OPENED; m_Status = PL_OPENED;
m_Handle = NULL; m_Handle = NULL;
return 1; return 1;
} else if (g_IsNewMM) {
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)m_Handle, now, reason))
{
m_Status = PL_FAILED;
return 0;
}
m_Status = PL_OPENED;
m_Handle = NULL;
return 1;
} }
META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach"); META_DETACH_FN detachFn = (META_DETACH_FN)DLSYM(m_Handle, "Meta_Detach");
@ -2568,7 +2636,7 @@ bool CFakeMeta::AddCorePlugin()
{ {
// evilspy: // evilspy:
// not needed when using metamod p-extensions // not needed when using metamod p-extensions
if(gpMetaPExtFuncs) if(gpMetaPExtFuncs || g_IsNewMM)
return true; return true;
// Check whether there already is a core plugin // Check whether there already is a core plugin
@ -2592,7 +2660,12 @@ void CFakeMeta::Meta_Query(mutil_funcs_t *pMetaUtilFuncs)
// Query all plugins except core // Query all plugins except core
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin(); CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
// evilspy:
// using metamod p-extensions?
if(!gpMetaPExtFuncs && !g_IsNewMM)
++iter; // Skip core ++iter; // Skip core
for (; iter; ++iter) for (; iter; ++iter)
{ {
(*iter).Query(pMetaUtilFuncs); (*iter).Query(pMetaUtilFuncs);
@ -2606,7 +2679,11 @@ void CFakeMeta::Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedl
// Attach all plugins except core // Attach all plugins except core
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin(); CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
// evilspy:
// using metamod p-extensions?
if(!gpMetaPExtFuncs && !g_IsNewMM)
++iter; // Skip core ++iter; // Skip core
for (; iter; ++iter) for (; iter; ++iter)
{ {
(*iter).Attach(now, pMGlobals, pGamedllFuncs); (*iter).Attach(now, pMGlobals, pGamedllFuncs);
@ -2618,7 +2695,11 @@ void CFakeMeta::Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
{ {
// Detach all plugins except core // Detach all plugins except core
CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin(); CList<CFakeMetaPlugin>::iterator iter = m_Plugins.begin();
// evilspy:
// using metamod p-extensions?
if(!gpMetaPExtFuncs && !g_IsNewMM)
++iter; // Skip core ++iter; // Skip core
for (; iter; ++iter) for (; iter; ++iter)
{ {
(*iter).Detach(now, reason); (*iter).Detach(now, reason);
@ -2637,7 +2718,8 @@ int CFakeMeta::GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int
// evilspy: // evilspy:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) ); memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
return TRUE; return TRUE;
} }
@ -2674,7 +2756,8 @@ int CFakeMeta::GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/
// evilspy // evilspy
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) ); memcpy( pFunctionTable, pAMXXFunctionTable, sizeof( DLL_FUNCTIONS ) );
return TRUE; return TRUE;
} }
@ -2711,7 +2794,8 @@ int CFakeMeta::GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *inter
// evilspy: // evilspy:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) ); memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
return TRUE; return TRUE;
} }
@ -2747,7 +2831,8 @@ int CFakeMeta::GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *
// evilspy: // evilspy:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) ); memcpy( pengfuncsFromEngine, pAMXXFunctionTable, sizeof( enginefuncs_t ) );
return TRUE; return TRUE;
} }
@ -2790,7 +2875,8 @@ int CFakeMeta::GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *int
// evilspy: // evilspy:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) ); memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
return TRUE; return TRUE;
} }
@ -2833,7 +2919,8 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
// evilspy: // evilspy:
//using metamod p-extensions? //using metamod p-extensions?
if(gpMetaPExtFuncs) { if(gpMetaPExtFuncs || g_IsNewMM)
{
memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) ); memcpy( pNewFunctionTable, pAMXXFunctionTable, sizeof( NEW_DLL_FUNCTIONS ) );
return TRUE; return TRUE;
} }
@ -2857,3 +2944,5 @@ int CFakeMeta::GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int
return TRUE; return TRUE;
} }
#endif //FAKEMETA

View File

@ -31,6 +31,10 @@
#ifndef __FAKEMETA_H__ #ifndef __FAKEMETA_H__
#define __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 // Fake metamod api for modules
#include "CList.h" #include "CList.h"
@ -38,7 +42,8 @@
// from mplugin.h (metamod) // from mplugin.h (metamod)
// Flags to indicate current "load" state of plugin. // Flags to indicate current "load" state of plugin.
// NOTE: order is important, as greater/less comparisons are made. // NOTE: order is important, as greater/less comparisons are made.
typedef enum { typedef enum
{
PL_EMPTY = 0, // empty slot PL_EMPTY = 0, // empty slot
PL_VALID, // has valid info in it PL_VALID, // has valid info in it
PL_BADFILE, // nonexistent file (open failed), PL_BADFILE, // nonexistent file (open failed),
@ -51,11 +56,10 @@ typedef enum {
// from h_export.h (metamod) // from h_export.h (metamod)
// Our GiveFnptrsToDll, called by engine. // Our GiveFnptrsToDll, called by engine.
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals);
*pengfuncsFromEngine, globalvars_t *pGlobals);
// *** CFakeMeta // *** CFakeMeta
class CFakeMeta class CFakeMeta
{ {
private: private:
@ -96,7 +100,6 @@ public:
inline void SetStatus(PLUG_STATUS newStatus) inline void SetStatus(PLUG_STATUS newStatus)
{ m_Status = newStatus; } { m_Status = newStatus; }
inline plugin_info_t * GetInfo() inline plugin_info_t * GetInfo()
{ return m_Info; } { return m_Info; }
inline const plugin_info_t * GetInfo() const inline const plugin_info_t * GetInfo() const
@ -225,5 +228,6 @@ public:
// defined in meta_api.cpp // defined in meta_api.cpp
extern CFakeMeta g_FakeMeta; extern CFakeMeta g_FakeMeta;
#endif // #ifndef __FAKEMETA_H__ #endif //FAKEMETA
#endif // #ifndef __FAKEMETA_H__

File diff suppressed because it is too large Load Diff

View File

@ -96,7 +96,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
return 0; return 0;
/* Now convert the Small String into a C type null terminated string */ /* Now convert the Small String into a C type null terminated string */
amx_GetString(szSource, pString, 0); amx_GetStringOld(szSource, pString, 0);
/* Now convert this to a float. */ /* Now convert this to a float. */
fNum = (REAL)atof(szSource); fNum = (REAL)atof(szSource);

File diff suppressed because it is too large Load Diff

View File

@ -930,7 +930,11 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
// Danger Will Robinson! // Danger Will Robinson!
if (reservoir == NULL) throw "Unable to allocate RAM for internal memory tracking data"; if (reservoir == NULL)
{
log("%s: Unable to allocate RAM for internal memory tracking data", ownerString(sourceFile, sourceLine, sourceFunc));
throw "Unable to allocate RAM for internal memory tracking data";
}
// Build a linked-list of the elements in our reservoir // Build a linked-list of the elements in our reservoir
@ -998,6 +1002,7 @@ void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const c
if (au->actualAddress == NULL) if (au->actualAddress == NULL)
{ {
log("%s: Request for allocation failed. Out of memory.", ownerString(sourceFile, sourceLine, sourceFunc));
throw "Request for allocation failed. Out of memory."; throw "Request for allocation failed. Out of memory.";
} }
@ -1108,7 +1113,11 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
// If you hit this assert, you tried to reallocate RAM that wasn't allocated by this memory manager. // If you hit this assert, you tried to reallocate RAM that wasn't allocated by this memory manager.
m_assert(au != NULL); m_assert(au != NULL);
if (au == NULL) throw "Request to reallocate RAM that was never allocated"; if (au == NULL)
{
log("%s: Request to reallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
throw "Request to reallocate RAM that was never allocated";
}
// If you hit this assert, then the allocation unit that is about to be reallocated is damaged. But you probably // If you hit this assert, then the allocation unit that is about to be reallocated is damaged. But you probably
// already know that from a previous assert you should have seen in validateAllocUnit() :) // already know that from a previous assert you should have seen in validateAllocUnit() :)
@ -1162,7 +1171,11 @@ void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const
m_assert(newActualAddress); m_assert(newActualAddress);
#endif #endif
if (!newActualAddress) throw "Request for reallocation failed. Out of memory."; if (!newActualAddress)
{
log("%s: Request for reallocation failed. Out of memory", ownerString(sourceFile, sourceLine, sourceFunc));
throw "Request for reallocation failed. Out of memory.";
}
// Remove this allocation from our stats (we'll add the new reallocation again later) // Remove this allocation from our stats (we'll add the new reallocation again later)
@ -1291,7 +1304,11 @@ void m_deallocator(const char *sourceFile, const unsigned int sourceLine, const
// If you hit this assert, you tried to deallocate RAM that wasn't allocated by this memory manager. // If you hit this assert, you tried to deallocate RAM that wasn't allocated by this memory manager.
m_assert(au != NULL); m_assert(au != NULL);
if (au == NULL) throw "Request to deallocate RAM that was never allocated"; if (au == NULL)
{
log("%s: Request to deallocate RAM that was never allocated", ownerString(sourceFile, sourceLine, sourceFunc));
throw "Request to deallocate RAM that was never allocated";
}
// If you hit this assert, then the allocation unit that is about to be deallocated is damaged. But you probably // If you hit this assert, then the allocation unit that is about to be deallocated is damaged. But you probably
// already know that from a previous assert you should have seen in validateAllocUnit() :) // already know that from a previous assert you should have seen in validateAllocUnit() :)

File diff suppressed because it is too large Load Diff

View File

@ -45,135 +45,10 @@
#undef C_DLLEXPORT #undef C_DLLEXPORT
#define C_DLLEXPORT extern "C" DLLEXPORT #define C_DLLEXPORT extern "C" DLLEXPORT
#define AMX_INTERFACE_VERSION 6
#define RELOAD_MODULE 0 #define RELOAD_MODULE 0
#define STATIC_MODULE 1 #define STATIC_MODULE 1
struct module_info_s { int CheckModules(AMX *amx, char error[128]);
const char* name; const char *StrCaseStr(const char *as, const char *bs);
const char* author;
const char* version;
int ivers;
int type;
long int serial;
};
// Small scripting language
struct pfnamx_engine_g {
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
int (*pfnamx_Init)(AMX*, void *); // amx, program
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
};
extern pfnamx_engine_g* g_engAmxFunc;
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
// Modules API
struct pfnmodule_engine_g {
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
char* (*pfnbuild_pathname)(char*, ...); // format, ....
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
void (*pfnget_modname)(char*); // modname
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64], int); // amx, code, path, error info
void (*pfnprint_console)(char*, ...); // format, ....
void (*pfnreport_error)(int code, char*, ... );
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
int (*pfnamxstring_length)(cell*); // src
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
void* (*pfnalloc_amxmemory)(void**,int size);
void (*pfnfree_amxmemory)(void**);
};
extern pfnmodule_engine_g* g_engModuleFunc;
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
#endif // __MODULES_H__ #endif // __MODULES_H__

View File

@ -1,804 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="amxmodx"
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\debug/amxmodx.pch"
AssemblerListingLocation=".\debug/"
ObjectFile=".\debug/"
ProgramDataBaseFileName=".\debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="debug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
ImportLibrary=".\debug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\release/amxmodx.pch"
AssemblerListingLocation=".\release/"
ObjectFile=".\release/"
ProgramDataBaseFileName=".\release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="release/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\release/amxx_mm.pdb"
ImportLibrary=".\release/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestDebug|Win32"
OutputDirectory="MemtestDebug"
IntermediateDirectory="MemtestDebug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
AssemblerListingLocation=".\memtestdebug/"
ObjectFile=".\memtestdebug/"
ProgramDataBaseFileName=".\memtestdebug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MemtestRelease|Win32"
OutputDirectory="MemtestRelease"
IntermediateDirectory="MemtestRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
AssemblerListingLocation=".\memtestrelease/"
ObjectFile=".\memtestrelease/"
ProgramDataBaseFileName=".\memtestrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib"
OutputFile="memtestrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITDebug|Win32"
OutputDirectory="JITDebug"
IntermediateDirectory="JITDebug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\dlls&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\engine&quot;;&quot;C:\Hry\Half-Life\SDK\Multiplayer Source\common&quot;;C:\Files\Programming\metamod\metamod"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
AssemblerListingLocation=".\jitdebug/"
ObjectFile=".\jitdebug/"
ProgramDataBaseFileName=".\jitdebug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
ImportLibrary=".\jitdebug/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="JITRelease|Win32"
OutputDirectory="JITRelease"
IntermediateDirectory="JITRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
AssemblerListingLocation=".\jitrelease/"
ObjectFile=".\jitrelease/"
ProgramDataBaseFileName=".\jitrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib"
OutputFile="jitrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITMemtestRelease|Win32"
OutputDirectory="JITMemtestRelease"
IntermediateDirectory="JITMemtestRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
AssemblerListingLocation=".\jitmemtestrelease/"
ObjectFile=".\jitmemtestrelease/"
ProgramDataBaseFileName=".\jitmemtestrelease/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="MaximalSpeed|Win32"
OutputDirectory="MaximalSpeed"
IntermediateDirectory="MaximalSpeed"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OptimizeForProcessor="2"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
AssemblerListingLocation=".\MaximalSpeed/"
ObjectFile=".\MaximalSpeed/"
ProgramDataBaseFileName=".\MaximalSpeed/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
OutputFile="MaximalSpeed/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
ModuleDefinitionFile=""
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
ImportLibrary=".\jitrelease/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>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="..\amx.cpp">
</File>
<File
RelativePath="..\amxcore.cpp">
</File>
<File
RelativePath="..\amxmodx.cpp">
</File>
<File
RelativePath="..\amxtime.cpp">
</File>
<File
RelativePath="..\amxxfile.cpp">
</File>
<File
RelativePath="..\amxxlog.cpp">
</File>
<File
RelativePath="..\CCmd.cpp">
</File>
<File
RelativePath="..\CEvent.cpp">
</File>
<File
RelativePath="..\CFile.cpp">
</File>
<File
RelativePath="..\CForward.cpp">
</File>
<File
RelativePath="..\CLang.cpp">
</File>
<File
RelativePath="..\CLogEvent.cpp">
</File>
<File
RelativePath="..\CMenu.cpp">
</File>
<File
RelativePath="..\CMisc.cpp">
</File>
<File
RelativePath="..\CModule.cpp">
</File>
<File
RelativePath="..\CPlugin.cpp">
</File>
<File
RelativePath="..\CTask.cpp">
</File>
<File
RelativePath="..\CVault.cpp">
</File>
<File
RelativePath="..\emsg.cpp">
</File>
<File
RelativePath="..\fakemeta.cpp">
<FileConfiguration
Name="MemtestDebug|Win32">
<Tool
Name="VCCLCompilerTool"
GeneratePreprocessedFile="0"/>
</FileConfiguration>
</File>
<File
RelativePath="..\file.cpp">
</File>
<File
RelativePath="..\float.cpp">
</File>
<File
RelativePath="..\md5.cpp">
</File>
<File
RelativePath="..\meta_api.cpp">
</File>
<File
RelativePath="..\modules.cpp">
</File>
<File
RelativePath="..\power.cpp">
</File>
<File
RelativePath="..\srvcmd.cpp">
</File>
<File
RelativePath="..\string.cpp">
</File>
<File
RelativePath="..\strptime.cpp">
</File>
<File
RelativePath="..\util.cpp">
</File>
<File
RelativePath="..\vault.cpp">
</File>
<Filter
Name="mmgr"
Filter="">
<File
RelativePath="..\mmgr\mmgr.cpp">
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITDebug|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITRelease|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="MaximalSpeed|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File>
</Filter>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="..\amx.h">
</File>
<File
RelativePath="..\amxmodx.h">
</File>
<File
RelativePath="..\amxxfile.h">
</File>
<File
RelativePath="..\amxxlog.h">
</File>
<File
RelativePath="..\CCmd.h">
</File>
<File
RelativePath="..\CEvent.h">
</File>
<File
RelativePath="..\CFile.h">
</File>
<File
RelativePath="..\CForward.h">
</File>
<File
RelativePath="..\CLang.h">
</File>
<File
RelativePath="..\CList.h">
</File>
<File
RelativePath="..\CLogEvent.h">
</File>
<File
RelativePath="..\CMenu.h">
</File>
<File
RelativePath="..\CMisc.h">
</File>
<File
RelativePath="..\CModule.h">
</File>
<File
RelativePath="..\CPlugin.h">
</File>
<File
RelativePath="..\CQueue.h">
</File>
<File
RelativePath="..\CRList.h">
</File>
<File
RelativePath="..\CString.h">
</File>
<File
RelativePath="..\CTask.h">
</File>
<File
RelativePath="..\CVault.h">
</File>
<File
RelativePath="..\CVector.h">
</File>
<File
RelativePath="..\fakemeta.h">
</File>
<File
RelativePath="..\md5.h">
</File>
<File
RelativePath="..\modules.h">
</File>
<Filter
Name="mmgr"
Filter="">
<File
RelativePath="..\mmgr\mmgr.h">
</File>
<File
RelativePath="..\mmgr\nommgr.h">
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="rc">
<File
RelativePath="..\version.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

39
amxmodx/msvc/amxmodx_mm.sln Executable file
View File

@ -0,0 +1,39 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
JITDebug = JITDebug
JITMemtestRelease = JITMemtestRelease
JITRelease = JITRelease
MaximalSpeed = MaximalSpeed
MemtestDebug = MemtestDebug
MemtestRelease = MemtestRelease
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -42,12 +42,13 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib" AdditionalDependencies="..\JIT\natives-x86.obj ..\zlib\zlib.lib"
OutputFile="debug/amxmodx_mm.dll" OutputFile="debug/amxmodx_mm.dll"
Version="0.1" Version="0.1"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\debug/amxx_mm.pdb" ProgramDatabaseFile=".\debug/amxx_mm.pdb"
@ -112,11 +113,12 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib" AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="release/amxmodx_mm.dll" OutputFile="release/amxmodx_mm.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="LIBC"
ModuleDefinitionFile="" ModuleDefinitionFile=""
ProgramDatabaseFile=".\release/amxx_mm.pdb" ProgramDatabaseFile=".\release/amxx_mm.pdb"
ImportLibrary=".\release/amxx_mm.lib"/> ImportLibrary=".\release/amxx_mm.lib"/>
@ -179,12 +181,13 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib" AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestdebug/amxmodx_mm.dll" OutputFile="memtestdebug/amxmodx_mm.dll"
Version="0.1" Version="0.1"
LinkIncremental="2" LinkIncremental="2"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb" ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
@ -249,13 +252,17 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib" AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
OutputFile="memtestrelease/amxmodx_mm.dll" OutputFile="memtestrelease/amxmodx_mm.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="LIBC"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb" ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
GenerateMapFile="TRUE"
MapExports="TRUE"
ImportLibrary=".\memtestrelease/amxx_mm.lib"/> ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
@ -297,7 +304,7 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
Optimization="0" 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="&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;JIT" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="5" RuntimeLibrary="5"
StructMemberAlignment="3" StructMemberAlignment="3"
@ -316,12 +323,13 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebug/amxmodx_mm.dll" OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1" Version="0.1"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb" ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
@ -367,8 +375,10 @@
GlobalOptimizations="TRUE" GlobalOptimizations="TRUE"
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include" AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
IgnoreStandardIncludePath="FALSE"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
@ -386,13 +396,16 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\jit\jits.obj ..\zlib\zlib.lib" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitrelease/amxmodx_mm.dll" OutputFile="jitrelease/amxmodx_mm.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb" ProgramDatabaseFile=".\jitrelease/amxx_mm.pdb"
GenerateMapFile="FALSE"
ImportLibrary=".\jitrelease/amxx_mm.lib"/> ImportLibrary=".\jitrelease/amxx_mm.lib"/>
<Tool <Tool
Name="VCMIDLTool" Name="VCMIDLTool"
@ -436,7 +449,7 @@
InlineFunctionExpansion="1" InlineFunctionExpansion="1"
FavorSizeOrSpeed="1" FavorSizeOrSpeed="1"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include" AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="4" RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="TRUE"
@ -454,12 +467,14 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitmemtestrelease/amxmodx_mm.dll" OutputFile="jitmemtestrelease/amxmodx_mm.dll"
LinkIncremental="1" LinkIncremental="1"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile="" ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb" ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/> ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
<Tool <Tool
@ -574,6 +589,9 @@
<File <File
RelativePath="..\amxcore.cpp"> RelativePath="..\amxcore.cpp">
</File> </File>
<File
RelativePath="..\amxdbg.cpp">
</File>
<File <File
RelativePath="..\amxmodx.cpp"> RelativePath="..\amxmodx.cpp">
</File> </File>
@ -622,6 +640,9 @@
<File <File
RelativePath="..\CVault.cpp"> RelativePath="..\CVault.cpp">
</File> </File>
<File
RelativePath="..\debugger.cpp">
</File>
<File <File
RelativePath="..\emsg.cpp"> RelativePath="..\emsg.cpp">
</File> </File>
@ -649,6 +670,12 @@
<File <File
RelativePath="..\modules.cpp"> RelativePath="..\modules.cpp">
</File> </File>
<File
RelativePath="..\natives.cpp">
</File>
<File
RelativePath="..\newmenus.cpp">
</File>
<File <File
RelativePath="..\power.cpp"> RelativePath="..\power.cpp">
</File> </File>
@ -711,6 +738,9 @@
<File <File
RelativePath="..\amx.h"> RelativePath="..\amx.h">
</File> </File>
<File
RelativePath="..\amxdbg.h">
</File>
<File <File
RelativePath="..\amxmodx.h"> RelativePath="..\amxmodx.h">
</File> </File>
@ -757,7 +787,7 @@
RelativePath="..\CQueue.h"> RelativePath="..\CQueue.h">
</File> </File>
<File <File
RelativePath="..\CRList.h"> RelativePath="..\CStack.h">
</File> </File>
<File <File
RelativePath="..\CString.h"> RelativePath="..\CString.h">
@ -771,18 +801,36 @@
<File <File
RelativePath="..\CVector.h"> RelativePath="..\CVector.h">
</File> </File>
<File
RelativePath="..\debugger.h">
</File>
<File <File
RelativePath="..\fakemeta.h"> RelativePath="..\fakemeta.h">
</File> </File>
<File <File
RelativePath="..\md5.h"> RelativePath="..\md5.h">
</File> </File>
<File
RelativePath="..\menus.h">
</File>
<File <File
RelativePath="..\modules.h"> RelativePath="..\modules.h">
</File> </File>
<File
RelativePath="..\natives.h">
</File>
<File
RelativePath="..\newmenus.h">
</File>
<File <File
RelativePath="..\resource.h"> RelativePath="..\resource.h">
</File> </File>
<File
RelativePath="..\zlib\zconf.h">
</File>
<File
RelativePath="..\zlib\zlib.h">
</File>
<Filter <Filter
Name="mmgr" Name="mmgr"
Filter=""> Filter="">
@ -801,6 +849,25 @@
RelativePath="..\version.rc"> RelativePath="..\version.rc">
</File> </File>
</Filter> </Filter>
<Filter
Name="Assembly"
Filter="">
<File
RelativePath="..\amxdefn.asm">
</File>
<File
RelativePath="..\amxexecn.asm">
</File>
<File
RelativePath="..\amxjitsn.asm">
</File>
<File
RelativePath="..\natives-amd64.asm">
</File>
<File
RelativePath="..\natives-x86.asm">
</File>
</Filter>
</Files> </Files>
<Globals> <Globals>
</Globals> </Globals>

91
amxmodx/natives-amd64.asm Executable file
View File

@ -0,0 +1,91 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (C)2005 by David "BAILOPAN" Anderson ;
; register_native functions for amd64 ;;;;;;
; Based on the concept by Julien "dJeyL" Laurent ;
; Thanks to T(+)rget for pushing me to implement this ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;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.
;;Initializes the global variable
BITS 64
section .text
global amxx_DynaInit, _amxx_DynaInit
;void amxx_DynaInit(void *ptr);
amxx_DynaInit:
_amxx_DynaInit:
mov [GLOBAL_GATE wrt rip], rdi
ret
;;Assembles the gateway function
global amxx_DynaMake, _amxx_DynaMake
;int amxx_DynaMake(char *buffer, int id);
amxx_DynaMake:
_amxx_DynaMake:
;we're not damaging the stack I think so we should be safe with no prologue
;save these two we're about to destroy them
push rsi ;push id
push rdi ;push buffer
mov rsi, _amxx_DynaFuncStart
mov rcx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
cld ;clear direction flag (just in case)
rep movsb
pop rdi ;get buffer as destination
pop rax ;get id
;align us to mov rsi, 1234... - on x86-64 this is 2 bytes after the differential
add rdi, (_amxx_DynaFuncStart.move-_amxx_DynaFuncStart) + 2
mov [rdi], qword rax
;align rdi to the call
add rdi, (_amxx_DynaFuncStart.call-_amxx_DynaFuncStart.move)
mov rax, qword [GLOBAL_GATE wrt rip]
;copy the real address
mov [rdi], rax
ret
;;The gateway function we will re-assemble
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
;; and NASM > GAS :')
global amxx_DynaFunc, _amxx_DynaFunc
;int amxx_DynaFunc(AMX *amx, cell *params);
amxx_DynaFunc:
_amxx_DynaFunc:
_amxx_DynaFuncStart:
push rbp
mov rbp, rsp
;we're given an amx and params... we're also hardcoded for this though:
mov rdx, rsi ;move 2nd param to 3rd
mov rsi, rdi ;move 1st param to 2nd
;this old trick, we'll move in the real pointer in a bit.
.move:
mov rdi, qword 1234567812345678h
.call:
mov rcx, qword 1234567812345678h
call rcx
pop rbp
ret
_amxx_DynaFuncEnd:
;;Just returns the buffer size required
global _amxx_DynaCodesize, amxx_DynaCodesize
;int amxx_DynaCodesize()
amxx_DynaCodesize:
_amxx_DynaCodesize:
; on x86-64 this is 34 bytes
mov rax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
ret
section .data
GLOBAL_GATE DQ 0

100
amxmodx/natives-x86.asm Executable file
View File

@ -0,0 +1,100 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (C)2005 by David "BAILOPAN" Anderson ;
; register_native functions for x86 ;;;;;;
; Based on the concept by Julien "dJeyL" Laurent ;
; Thanks to T(+)rget for pushing me to implement this ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;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.
;;Initializes the global variable
section .text
global amxx_DynaInit, _amxx_DynaInit
;void amxx_DynaInit(void *ptr);
amxx_DynaInit:
_amxx_DynaInit:
push ebp
mov ebp, esp
mov eax, [ebp+8] ;get pointer
mov [GLOBAL_GATE], eax ;store
mov eax, 1
pop ebp
ret
;;Assembles the gateway function
global amxx_DynaMake, _amxx_DynaMake
;int amxx_DynaMake(char *buffer, int id);
amxx_DynaMake:
_amxx_DynaMake:
push ebp
mov ebp, esp
push edi
push esi
mov edi, [ebp+8] ;buffer
mov esi, _amxx_DynaFuncStart
mov ecx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
cld ;clear direction flag (just in case)
rep movsb
mov edi, [ebp+8] ;get buffer again
;align us to mov eax, 1234 - on x86 this is 4 bytes
add edi, (_amxx_DynaMoveOffset-_amxx_DynaFuncStart) + 1
mov eax, [ebp+12]
mov [edi], eax
pop esi
pop edi
mov eax, 1
pop ebp
ret
;;The gateway function we will re-assemble
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
;; and NASM > GAS :')
global amxx_DynaFunc, _amxx_DynaFunc
;int amxx_DynaFunc(AMX *amx, cell *params);
amxx_DynaFunc:
_amxx_DynaFunc:
_amxx_DynaFuncStart:
push ebp
mov ebp, esp
;we're given an amx and params... we're also hardcoded for this though:
_amxx_DynaMoveOffset:
mov eax, 12345678h ;this old trick, we'll move in the real pointer in a bit.
push dword [ebp+12] ;push params
push dword [ebp+8] ;push amx
push eax ;push the id
call [GLOBAL_GATE] ;pass through teh global gateway.
add esp, 12 ;reset stack oops
pop ebp
ret
_amxx_DynaFuncEnd:
;;Just returns the buffer size required
global _amxx_DynaCodesize, amxx_DynaCodesize
;int amxx_DynaCodesize()
amxx_DynaCodesize:
_amxx_DynaCodesize:
push ebp
mov ebp, esp
; on x86 is this 17 bytes
mov eax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
pop ebp
ret
section .data
GLOBAL_GATE DD 0

436
amxmodx/natives.cpp Executable file
View File

@ -0,0 +1,436 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#include "CStack.h"
#include "natives.h"
#ifdef __linux__
#include <malloc.h>
#include <stdlib.h>
#include <sys/mman.h>
#include "sclinux.h"
#endif
//Written by David "BAILOPAN" Anderson
//With the exception for param_convert, which was written by
// Julien "dJeyL" Laurent
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)
{
if (idx < 0 || idx >= (int)g_RegNatives.size())
{
LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
return 0;
}
regnative *pNative = g_RegNatives[idx];
int numParams = params[0] / sizeof(cell);
if (numParams > CALLFUNC_MAXPARAMS)
{
LogError(amx, AMX_ERR_NATIVE, "Called dynanative with too many parameters (%d)", CALLFUNC_MAXPARAMS);
return 0;
}
//parameter stack
pNative->caller = amx;
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
int err = 0;
cell ret = 0;
g_errorNum = 0;
g_NativeStack.push(pNative);
if (pNative->style == 0)
{
amx_Push(pNative->amx, numParams);
amx_Push(pNative->amx, pPlugin->getId());
for (int i=numParams; i>=1; i--)
pNative->params[i] = params[i];
} else if (pNative->style == 1) {
//use dJeyL's system .. very clever!
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)
{
g_NativeStack.pop();
LogError(pNative->amx, err, "");
return 0;
}
if (g_errorNum)
{
g_NativeStack.pop();
LogError(amx, g_errorNum, g_errorStr);
return ret;
}
g_NativeStack.pop();
return ret;
}
AMX_NATIVE_INFO *BuildNativeTable()
{
if (g_RegNatives.size() < 1)
return NULL;
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
AMX_NATIVE_INFO info;
regnative *pNative;
for (size_t i=0; i<g_RegNatives.size(); i++)
{
pNative = g_RegNatives[i];
info.name = pNative->name.c_str();
info.func = (AMX_NATIVE)((void *)(pNative->pfn));
pNatives[i] = info;
}
pNatives[g_RegNatives.size()].name = NULL;
pNatives[g_RegNatives.size()].func = NULL;
//this needs to be deleted
return pNatives;
}
static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
{
int len;
char *err = format_amxstring(amx, params, 2, len);
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
g_errorNum = params[1];
return 1;
}
//get_string(param, dest[], len)
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
int len;
char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
return set_amxstring(amx, params[2], str, params[3]);
}
//set_string(param, source[], maxlen)
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
int len;
char *str = get_amxstring(amx, params[2], 0, len);
return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
}
//get a byvalue parameter
//get_param(num)
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
return pNative->params[p];
}
//get_param_byref(num)
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
return addr[0];
}
//set_param_byref(num, val)
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
addr[0] = params[2];
return 1;
}
//get_array(param, dest[], size)
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
cell *source = get_amxaddr(pNative->caller, pNative->params[p]);
cell *dest = get_amxaddr(amx, params[2]);
int size = params[3];
memcpy(dest, source, size * sizeof(cell));
return 1;
}
//set_array(param, source[], size)
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
int p = params[1];
cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
cell *source = get_amxaddr(amx, params[2]);
int size = params[3];
memcpy(dest, source, size * sizeof(cell));
return 1;
}
//This is basically right from dJeyL's lib_convert function
//This awesome hack modifies the stack frame to have an address offset
// that will align to the other plugin's memory.
//I've no idea how he thought of this, but it's great. No idea how well it works.
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
{
if (!g_NativeStack.size())
{
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
return 0;
}
regnative *pNative = g_NativeStack.top();
if (pNative->style != 1)
{
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
return 0;
}
cell p = params[1];
AMX *caller = pNative->caller;
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
* (cell *)(data+(int)amx->frm+(p+2)*sizeof(cell)) -= (cell)data-(cell)realdata;
return 1;
}
static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
{
int len;
char *lib = get_amxstring(amx, params[1], 0, len);
AddPluginLibrary(lib);
return 1;
}
//register_native(const name[], const handler[])
static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
{
if (!g_Initialized)
amxx_DynaInit((void *)(amxx_DynaCallback));
g_Initialized = true;
int len;
char *name = get_amxstring(amx, params[1], 0, len);
char *func = get_amxstring(amx, params[2], 1, len);
int idx, err;
if ( (err=amx_FindPublic(amx, func, &idx)) != AMX_ERR_NONE)
{
LogError(amx, err, "Function \"%s\" was not found", func);
return 0;
}
regnative *pNative = new regnative;
pNative->amx = amx;
pNative->func = idx;
//we'll apply a safety buffer too
//make our function
int size = amxx_DynaCodesize();
#ifndef __linux__
DWORD temp;
pNative->pfn = new char[size + 10];
VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
#else
pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
#endif
int id = (int)g_RegNatives.size();
amxx_DynaMake(pNative->pfn, id);
pNative->func = idx;
pNative->style = params[3];
g_RegNatives.push_back(pNative);
pNative->name.assign(name);
return 1;
}
bool LibraryExists(const char *name)
{
for (size_t i=0; i<g_Libraries.size(); i++)
{
if (stricmp(g_Libraries[i].c_str(), name)==0)
return true;
}
return false;
}
void AddPluginLibrary(const char *name)
{
String f(name);
g_Libraries.push_back(f);
}
void ClearPluginLibraries()
{
g_Libraries.clear();
for (size_t i=0; i<g_RegNatives.size(); i++)
{
delete [] g_RegNatives[i]->pfn;
delete g_RegNatives[i];
}
g_RegNatives.clear();
}
AMX_NATIVE_INFO g_NativeNatives[] = {
{"register_native", register_native},
{"log_error", log_error},
{"register_library",register_library},
{"get_string", get_string},
{"set_string", set_string},
{"get_param", get_param},
{"get_param_byref", get_param_byref},
{"set_param_byref", set_param_byref},
{"get_array", get_array},
{"set_array", set_array},
//these are dummy functions for floats ;p
{"get_param_f", get_param},
{"get_float_byref", get_param_byref},
{"set_float_byref", set_param_byref},
{"get_array_f", get_array},
{"set_array_f", set_array},
{"param_convert", param_convert},
//////////////////////////
{NULL, NULL},
};

69
amxmodx/natives.h Executable file
View File

@ -0,0 +1,69 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef _INCLUDE_NATIVES_H
#define _INCLUDE_NATIVES_H
//only 16 for now sorry
#define CALLFUNC_MAXPARAMS 16
#define CALLFUNC_FLAG_BYREF 1
#define CALLFUNC_FLAG_BYREF_REUSED 2
#define N_CELL 1
#define N_ARRAY 2
#define N_BYREF 3
#define N_VARARG 4
struct regnative
{
AMX *amx;
String name;
char *pfn;
int func;
AMX *caller;
int style;
cell params[CALLFUNC_MAXPARAMS];
};
extern "C" void amxx_DynaInit(void *ptr);
extern "C" void amxx_DynaMake(char *buffer, int id);
extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
extern "C" int amxx_DynaCodesize();
AMX_NATIVE_INFO *BuildNativeTable();
void AddPluginLibrary(const char *name);
void ClearPluginLibraries();
bool LibraryExists(const char *name);
//I couldn't resist :)
extern AMX_NATIVE_INFO g_NativeNatives[];
#endif //_INCLUDE_NATIVES_H

484
amxmodx/newmenus.cpp Executable file
View File

@ -0,0 +1,484 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#include "amxmodx.h"
#include "newmenus.h"
CVector<Menu *> g_NewMenus;
void ClearMenus()
{
for (size_t i = 0; i < g_NewMenus.size(); i++)
delete g_NewMenus[i];
g_NewMenus.clear();
}
Menu::Menu(const char *title, int mid, int tid)
{
m_Title.assign(title);
menuId = mid;
thisId = tid;
}
Menu::~Menu()
{
for (size_t i = 0; i < m_Items.size(); i++)
delete m_Items[i];
m_Items.clear();
}
menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
{
menuitem *pItem = new menuitem;
pItem->name.assign(name);
pItem->cmd.assign(cmd);
pItem->access = access;
pItem->id = m_Items.size();
pItem->handler = -1;
pItem->pfn = NULL;
m_Items.push_back(pItem);
return pItem;
}
menuitem *Menu::GetMenuItem(item_t item)
{
if (item >= m_Items.size())
return NULL;
return m_Items[item];
}
size_t Menu::GetItemCount()
{
return m_Items.size();
}
size_t Menu::GetPageCount()
{
size_t items = GetItemCount();
page_t numPages = (items / MENUITEMS) + 1;
if (!items)
return 0;
if (numPages % MENUITEMS == 0)
numPages--;
return numPages;
}
int Menu::PagekeyToItem(page_t page, item_t key)
{
page_t pages = GetPageCount();
item_t numItems = GetItemCount();
if (page >= pages)
return MENU_EXIT;
item_t start = page * 7;
if (page == 0)
{
item_t rem = numItems >= 7 ? 7 : numItems;
if (key == rem)
{
if (pages > 1)
return MENU_MORE;
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 MENU_BACK;
}
} else {
if (key == 7)
{
return MENU_MORE;
}
else if (key == 8)
{
return MENU_BACK;
}
}
return (start + key);
}
bool Menu::Display(int player, page_t page)
{
int keys = 0;
const char *str = GetTextString(player, page, keys);
if (!str)
return false;
static char buffer[2048];
int len = _snprintf(buffer, sizeof(buffer)-1, "%s", str);
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
pPlayer->keys = keys;
pPlayer->menu = menuId;
pPlayer->newmenu = thisId;
pPlayer->page = (int)page;
UTIL_ShowMenu(pPlayer->pEdict, keys, -1, buffer, len);
return true;
}
const char *Menu::GetTextString(int player, page_t page, int &keys)
{
page_t pages = GetPageCount();
item_t numItems = GetItemCount();
if (page >= pages)
return NULL;
m_Text.clear();
char buffer[255];
if (g_coloredmenus)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
m_Text.append(buffer);
item_t start = page * 7;
item_t end = 0;
if (start + 7 <= numItems)
{
end = start + 7;
} else {
end = numItems;
}
menuitem *pItem = NULL;
int option = 0;
keys = 0;
bool enabled = true;
int ret = 0;
for (item_t i = start; i < end; i++)
{
pItem = m_Items[i];
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
enabled = false;
if (pItem->handler != -1)
{
ret = executeForwards(pItem->handler, player, thisId, i);
if (ret == ITEM_ENABLED)
enabled = true;
else if (ret == ITEM_DISABLED)
enabled = false;
}
if (pItem->pfn)
{
ret = (pItem->pfn)(player, thisId, i);
if (ret == ITEM_ENABLED)
enabled = true;
else if (ret == ITEM_DISABLED)
enabled = false;
}
if (enabled)
{
keys |= (1<<option);
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
} else {
if (g_coloredmenus)
{
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
} else {
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
option++;
}
}
m_Text.append(buffer);
}
//now for a weird part >:o
//this will either be MORE or BACK..
keys |= (1<<option++);
if ((page < pages - 1) && (pages > 1))
{
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
} else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
}
m_Text.append(buffer);
if (pages > 1)
{
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");
}
m_Text.append(buffer);
}
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); \
return 0; } \
Menu *pMenu = g_NewMenus[p];
//Makes a new menu handle (-1 for failure)
//native csdm_makemenu(title[]);
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
{
int len;
char *title = get_amxstring(amx, params[1], 0, len);
char *handler = get_amxstring(amx, params[2], 1, len);
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (func == -1)
{
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
return 0;
}
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);
return (int)g_NewMenus.size() - 1;
}
//Adds an item to the menu (returns current item count - 1)
//native menu_additem(menu, const name[], const command[]="", access=0);
static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
{
int len;
char *name, *cmd;
int access;
GETMENU(params[1]);
name = get_amxstring(amx, params[2], 0, len);
cmd = get_amxstring(amx, params[3], 1, len);
access = params[4];
menuitem *pItem = pMenu->AddItem(name, cmd, access);
pItem->handler = params[5];
return 1;
}
//Returns the number of pages in a menu
//native csdm_menu_pages(menu);
static cell AMX_NATIVE_CALL menu_pages(AMX *amx, cell *params)
{
GETMENU(params[1]);
return pMenu->GetPageCount();
}
//Returns the number of items in a menu
//native csdm_menu_items(menu);
static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
{
GETMENU(params[1]);
return pMenu->GetItemCount();
}
//Builds the menu string for a specific page (set title to 0 to not include title)
//page indices start at 0!
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
{
GETMENU(params[2]);
int player = params[1];
int page = params[3];
return pMenu->Display(player, page);
}
//Finds the id of a menu item for a specific page and key value.
//Note that key should be from 0-6, as it only displays 7 per page.
//page indices start at 0
//native menu_keyid(menu, page, key);
static cell AMX_NATIVE_CALL menu_find_id(AMX *amx, cell *params)
{
GETMENU(params[1]);
page_t page = static_cast<page_t>(params[2]);
item_t key = static_cast<item_t>(params[3]);
return pMenu->PagekeyToItem(page, key);
}
//Gets info about a menu option
//native menu_item_getinfo(menu, item, &access, command[], cmdlen, name[]="", namelen=0, &callback);
static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
cell *addr = get_amxaddr(amx, params[3]);
addr[0] = pItem->access;
set_amxstring(amx, params[4], pItem->cmd.c_str(), params[5]);
set_amxstring(amx, params[6], pItem->name.c_str(), params[7]);
if (params[8])
{
addr = get_amxaddr(amx, params[8]);
if (addr)
addr[0] = pItem->handler;
}
return 1;
}
static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
{
int len;
char *name = get_amxstring(amx, params[1], 0, len);
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (id == -1)
{
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function %s", name);
return -1;
}
return id;
}
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
int len;
char *name;
name = get_amxstring(amx, params[3], 0, len);
pItem->name.assign(name);
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
int len;
char *cmd;
cmd = get_amxstring(amx, params[3], 0, len);
pItem->cmd.assign(cmd);
return 1;
}
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
{
GETMENU(params[1]);
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
if (!pItem)
return 0;
pItem->handler = params[3];
return 1;
}
AMX_NATIVE_INFO g_NewMenuNatives[] =
{
{"menu_create", menu_create},
{"menu_additem", menu_additem},
{"menu_pages", menu_pages},
{"menu_items", menu_items},
{"menu_display", menu_display},
{"menu_find_id", menu_find_id},
{"menu_item_getinfo", menu_item_getinfo},
{"menu_makecallback", menu_makecallback},
{"menu_item_setcall", menu_item_setcall},
{"menu_item_setcmd", menu_item_setcmd},
{"menu_item_setname", menu_item_setname},
{NULL, NULL},
};

106
amxmodx/newmenus.h Executable file
View File

@ -0,0 +1,106 @@
/* AMX Mod X
*
* by the AMX Mod X Development Team
* originally developed by OLO
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* In addition, as a special exception, the author gives permission to
* link the code of this program with the Half-Life Game Engine ("HL
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
* L.L.C ("Valve"). You must obey the GNU General Public License in all
* respects for all of the code used other than the HL Engine and MODs
* from Valve. If you modify this file, you may extend this exception
* to your version of the file, but you are not obligated to do so. If
* you do not wish to do so, delete this exception statement from your
* version.
*/
#ifndef _INCLUDE_NEWMENUS_H
#define _INCLUDE_NEWMENUS_H
#define MENU_EXIT -3
#define MENU_BACK -2
#define MENU_MORE -1
#define ITEM_IGNORE 0
#define ITEM_ENABLED 1
#define ITEM_DISABLED 2
#define MENUITEMS 7
typedef int (*MENUITEM_CALLBACK)(int, int, int);
struct menuitem
{
String name;
String cmd;
int access;
int handler;
MENUITEM_CALLBACK pfn;
size_t id;
};
typedef unsigned int menu_t;
typedef unsigned int item_t;
typedef unsigned int page_t;
class Menu
{
public:
Menu(const char *title, int menuId, int thisId);
~Menu();
menuitem *GetMenuItem(item_t item);
size_t GetPageCount();
size_t GetItemCount();
menuitem *AddItem(const char *name, const char *cmd, int access);
const char *GetTextString(int player, page_t page, int &keys);
bool Display(int player, page_t page);
int PagekeyToItem(page_t page, item_t key);
int GetMenuMenuid();
private:
CVector<menuitem * > m_Items;
String m_Title;
String m_Text;
int menuId;
int thisId;
};
/*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;
extern AMX_NATIVE_INFO g_NewMenuNatives[];
#endif //_INCLUDE_NEWMENUS_H

View File

@ -6,6 +6,7 @@
* This file may be freely used. No warranties of any kind. * This file may be freely used. No warranties of any kind.
*/ */
#include <stdlib.h>
// this file does not include amxmodx.h, so we have to include the memory manager here // this file does not include amxmodx.h, so we have to include the memory manager here
#ifdef MEMORY_TEST #ifdef MEMORY_TEST
#include "mmgr/mmgr.h" #include "mmgr/mmgr.h"

View File

@ -20,6 +20,13 @@
#define stricmp(a,b) strcasecmp(a,b) #define stricmp(a,b) strcasecmp(a,b)
#define strnicmp(a,b,c) strncasecmp(a,b,c) #define strnicmp(a,b,c) strncasecmp(a,b,c)
#if defined __linux__ && !defined _snprintf
#define _snprintf snprintf
#endif
#if defined __linux__ && !defined _vsnprintf
//#define _vsnprintf vsnprintf
#endif
/* /*
* WinWorld wants '\'. Unices do not. * WinWorld wants '\'. Unices do not.
*/ */

View File

@ -45,8 +45,6 @@
enginefuncs_t g_engfuncs; enginefuncs_t g_engfuncs;
globalvars_t *gpGlobals; globalvars_t *gpGlobals;
DLL_FUNCTIONS *g_pFunctionTable; DLL_FUNCTIONS *g_pFunctionTable;
DLL_FUNCTIONS *g_pFunctionTable_Post; DLL_FUNCTIONS *g_pFunctionTable_Post;
enginefuncs_t *g_pengfuncsTable; enginefuncs_t *g_pengfuncsTable;
@ -54,7 +52,6 @@ enginefuncs_t *g_pengfuncsTable_Post;
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable; NEW_DLL_FUNCTIONS *g_pNewFunctionsTable;
NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post; NEW_DLL_FUNCTIONS *g_pNewFunctionsTable_Post;
// GetEntityAPI2 functions // GetEntityAPI2 functions
static DLL_FUNCTIONS g_EntityAPI_Table = static DLL_FUNCTIONS g_EntityAPI_Table =
{ {
@ -2421,9 +2418,6 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
/************* AMXX Stuff *************/ /************* AMXX Stuff *************/
// *** Types ***
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
// *** Globals *** // *** Globals ***
// Module info // Module info
static amxx_module_info_s g_ModuleInfo = static amxx_module_info_s g_ModuleInfo =
@ -2432,15 +2426,17 @@ static amxx_module_info_s g_ModuleInfo =
MODULE_AUTHOR, MODULE_AUTHOR,
MODULE_VERSION, MODULE_VERSION,
#ifdef MODULE_RELOAD_ON_MAPCHANGE #ifdef MODULE_RELOAD_ON_MAPCHANGE
1 1,
#else // MODULE_RELOAD_ON_MAPCHANGE #else // MODULE_RELOAD_ON_MAPCHANGE
0 0,
#endif // MODULE_RELOAD_ON_MAPCHANGE #endif // MODULE_RELOAD_ON_MAPCHANGE
MODULE_LOGTAG
}; };
// Storage for the requested functions // Storage for the requested functions
PFN_ADD_NATIVES g_fn_AddNatives; PFN_ADD_NATIVES g_fn_AddNatives;
PFN_BUILD_PATHNAME g_fn_BuildPathname; PFN_BUILD_PATHNAME g_fn_BuildPathname;
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
PFN_GET_AMXADDR g_fn_GetAmxAddr; PFN_GET_AMXADDR g_fn_GetAmxAddr;
PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole; PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
PFN_GET_MODNAME g_fn_GetModname; PFN_GET_MODNAME g_fn_GetModname;
@ -2482,9 +2478,11 @@ PFN_IS_PLAYER_CONNECTING g_fn_IsPlayerConnecting;
PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV; PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor; PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth; PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
#ifdef MEMORY_TEST
PFN_ALLOCATOR g_fn_Allocator; PFN_ALLOCATOR g_fn_Allocator;
PFN_REALLOCATOR g_fn_Reallocator; PFN_REALLOCATOR g_fn_Reallocator;
PFN_DEALLOCATOR g_fn_Deallocator; PFN_DEALLOCATOR g_fn_Deallocator;
#endif
PFN_AMX_EXEC g_fn_AmxExec; PFN_AMX_EXEC g_fn_AmxExec;
PFN_AMX_EXECV g_fn_AmxExecv; PFN_AMX_EXECV g_fn_AmxExecv;
PFN_AMX_ALLOT g_fn_AmxAllot; PFN_AMX_ALLOT g_fn_AmxAllot;
@ -2501,6 +2499,9 @@ PFN_AMX_FINDNATIVE g_fn_AmxFindNative;
PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags; PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict; PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
PFN_FORMAT g_fn_Format; PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction;
PFN_AMX_PUSH g_fn_AmxPush;
// *** Exports *** // *** Exports ***
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo) C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
@ -2538,15 +2539,19 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
if (!reqFnptrFunc) if (!reqFnptrFunc)
return AMXX_PARAM; return AMXX_PARAM;
g_fn_RequestFunction = reqFnptrFunc;
// Req all known functions // Req all known functions
// Misc // Misc
REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME); REQFUNC("BuildPathname", g_fn_BuildPathname, PFN_BUILD_PATHNAME);
REQFUNC("BuildPathnameR", g_fn_BuildPathnameR, PFN_BUILD_PATHNAME_R);
REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE); REQFUNC("PrintSrvConsole", g_fn_PrintSrvConsole, PFN_PRINT_SRVCONSOLE);
REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME); REQFUNC("GetModname", g_fn_GetModname, PFN_GET_MODNAME);
REQFUNC("Log", g_fn_Log, PFN_LOG); REQFUNC("Log", g_fn_Log, PFN_LOG);
REQFUNC("LogError", g_fn_LogErrorFunc, PFN_LOG_ERROR); REQFUNC("LogError", g_fn_LogErrorFunc, PFN_LOG_ERROR);
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE); REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
REQFUNC("Format", g_fn_Format, PFN_FORMAT); REQFUNC("Format", g_fn_Format, PFN_FORMAT);
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
// Amx scripts // Amx scripts
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT); REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
@ -2605,11 +2610,14 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH); REQFUNC("GetPlayerHealth", g_fn_GetPlayerHealth, PFN_GET_PLAYER_HEALTH);
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS); REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT); REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
#ifdef MEMORY_TEST
// Memory // Memory
REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR); REQFUNC_OPT("Allocator", g_fn_Allocator, PFN_ALLOCATOR);
REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR); REQFUNC_OPT("Reallocator", g_fn_Reallocator, PFN_REALLOCATOR);
REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR); REQFUNC_OPT("Deallocator", g_fn_Deallocator, PFN_DEALLOCATOR);
#endif
REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL); REQFUNC("CellToReal", g_fn_CellToReal, PFN_CELL_TO_REAL);
REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL); REQFUNC("RealToCell", g_fn_RealToCell, PFN_REAL_TO_CELL);
@ -2670,6 +2678,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...)
void ValidateMacros_DontCallThis_Smiley() void ValidateMacros_DontCallThis_Smiley()
{ {
MF_BuildPathname("str", "str", 0); MF_BuildPathname("str", "str", 0);
MF_BuildPathnameR(NULL, 0, "%d", 0);
MF_FormatAmxString(NULL, 0, 0, NULL); MF_FormatAmxString(NULL, 0, 0, NULL);
MF_GetAmxAddr(NULL, 0); MF_GetAmxAddr(NULL, 0);
MF_PrintSrvConsole("str", "str", 0); MF_PrintSrvConsole("str", "str", 0);
@ -2711,7 +2720,7 @@ void ValidateMacros_DontCallThis_Smiley()
MF_IsPlayerHLTV(0); MF_IsPlayerHLTV(0);
MF_GetPlayerArmor(0); MF_GetPlayerArmor(0);
MF_GetPlayerHealth(0); MF_GetPlayerHealth(0);
MF_AmxExec(0, 0, 0, 0); MF_AmxExec(0, 0, 0);
MF_AmxExecv(0, 0, 0, 0, 0); MF_AmxExecv(0, 0, 0, 0, 0);
MF_AmxFindPublic(0, 0, 0); MF_AmxFindPublic(0, 0, 0);
MF_AmxAllot(0, 0, 0, 0); MF_AmxAllot(0, 0, 0, 0);
@ -2723,9 +2732,12 @@ void ValidateMacros_DontCallThis_Smiley()
MF_GetPlayerFrags(0); MF_GetPlayerFrags(0);
MF_GetPlayerEdict(0); MF_GetPlayerEdict(0);
MF_Format("", 4, "str"); MF_Format("", 4, "str");
MF_RegisterFunction(NULL, "");
} }
#endif #endif
#ifdef MEMORY_TEST
/************* MEMORY *************/ /************* MEMORY *************/
// undef all defined macros // undef all defined macros
#undef new #undef new
@ -2897,6 +2909,30 @@ void operator delete[](void *reportedAddress)
Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress); Mem_Deallocator(g_Mem_CurrentFilename, g_Mem_CurrentLine, g_Mem_CurrentFunc, m_alloc_delete_array, reportedAddress);
} }
#else
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
void * ::operator new(size_t size) {
return(calloc(1, size));
}
void * ::operator new[](size_t size) {
return(calloc(1, size));
}
void ::operator delete(void * ptr) {
if(ptr)
free(ptr);
}
void ::operator delete[](void * ptr) {
if(ptr)
free(ptr);
}
#endif
#endif //MEMORY_TEST
/************* stuff from dlls/util.cpp *************/ /************* stuff from dlls/util.cpp *************/
// must come here because cbase.h declares it's own operator new // must come here because cbase.h declares it's own operator new

View File

@ -31,8 +31,10 @@
// ***** AMXX stuff ***** // ***** AMXX stuff *****
// module interface version is 1 // module interface version was 1
#define AMXX_INTERFACE_VERSION 1 // 2 - added logtag to struct (amxx1.1-rc1)
// 3 - added new tagAMX structure (amxx1.5)
#define AMXX_INTERFACE_VERSION 3
// amxx module info // amxx module info
struct amxx_module_info_s struct amxx_module_info_s
@ -41,10 +43,9 @@ struct amxx_module_info_s
const char *author; const char *author;
const char *version; const char *version;
int reload; // reload on mapchange when nonzero int reload; // reload on mapchange when nonzero
const char *logtag; // added in version 2
}; };
// return values from functions called by amxx // return values from functions called by amxx
#define AMXX_OK 0 /* no error */ #define AMXX_OK 0 /* no error */
#define AMXX_IFVERS 1 /* interface version */ #define AMXX_IFVERS 1 /* interface version */
@ -53,15 +54,26 @@ struct amxx_module_info_s
// *** Small stuff *** // *** Small stuff ***
// The next section is copied from the amx.h file // The next section is copied from the amx.h file
// Copyright (c) ITB CompuPhase, 1997-2004 // Copyright (c) ITB CompuPhase, 1997-2005
#if defined __LCC__ || defined __DMC__ || defined __linux__ || defined __GNUC__ #if defined HAVE_STDINT_H
#include <stdint.h> #include <stdint.h>
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L #else
#if defined __LCC__ || defined __DMC__ || defined LINUX
#if defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got /* The ISO C99 defines the int16_t and int_32t types. If the compiler got
* here, these types are probably undefined. * here, these types are probably undefined.
*/ */
#if defined __FreeBSD__ #if defined __MACH__
#include <ppc/types.h>
typedef unsigned short int uint16_t;
typedef unsigned long int uint32_t;
#elif defined __FreeBSD__
#include <inttypes.h> #include <inttypes.h>
#else #else
typedef short int int16_t; typedef short int int16_t;
@ -83,8 +95,14 @@ struct amxx_module_info_s
#define HAVE_I64 #define HAVE_I64
#endif #endif
#endif #endif
#endif
#define HAVE_STDINT_H
#endif
#if defined _LP64 || defined WIN64 || defined _WIN64
#if !defined __64BIT__
#define __64BIT__
#endif
#endif #endif
/* calling convention for native functions */ /* calling convention for native functions */
#if !defined AMX_NATIVE_CALL #if !defined AMX_NATIVE_CALL
@ -104,24 +122,26 @@ struct amxx_module_info_s
#define AMXEXPORT #define AMXEXPORT
#endif #endif
#if !defined PAWN_CELL_SIZE
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
#if !defined SMALL_CELL_SIZE
#define SMALL_CELL_SIZE 32 /* by default, use 32-bit cells */
#endif #endif
#if SMALL_CELL_SIZE==32 #if PAWN_CELL_SIZE==16
typedef uint16_t ucell;
typedef int16_t cell;
#elif PAWN_CELL_SIZE==32
typedef uint32_t ucell; typedef uint32_t ucell;
typedef int32_t cell; typedef int32_t cell;
typedef float REAL; #define REAL float
#elif SMALL_CELL_SIZE==64 #elif PAWN_CELL_SIZE==64
typedef uint64_t ucell; typedef uint64_t ucell;
typedef int64_t cell; typedef int64_t cell;
typedef double REAL; #define REAL double
#else #else
#error Unsupported cell size (SMALL_CELL_SIZE) #error Unsupported cell size (PAWN_CELL_SIZE)
#endif #endif
#define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1) #define UNPACKEDMAX ((1 << (sizeof(cell)-1)*8) - 1)
#define UNLIMITED (~1u >> 1)
struct tagAMX; struct tagAMX;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params); typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
@ -139,21 +159,24 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
#endif #endif
#if defined SN_TARGET_PS2 || defined __GNUC__ /* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
#define AMX_NO_ALIGN #define AMX_NO_ALIGN
#endif #endif
#if defined __GNUC__ #if defined __GNUC__
#define PACKED __attribute__((packed)) #define PACKED __attribute__((packed))
#else #else
#define PACKED #define PACKED
#endif #endif
#if !defined AMX_NO_ALIGN #if !defined AMX_NO_ALIGN
#if defined __linux__ #if defined LINUX || defined __FreeBSD__
#pragma pack(1) /* structures must be packed (byte-aligned) */ #pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else #else
#pragma pack(push) #pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */ #pragma pack(1) /* structures must be packed (byte-aligned) */
@ -174,7 +197,7 @@ typedef struct {
* fields are valid at all times; many fields are cached in local variables. * fields are valid at all times; many fields are cached in local variables.
*/ */
typedef struct tagAMX { typedef struct tagAMX {
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */ unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */ unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
AMX_CALLBACK callback PACKED; AMX_CALLBACK callback PACKED;
AMX_DEBUG debug PACKED; /* debug callback */ AMX_DEBUG debug PACKED; /* debug callback */
@ -186,18 +209,15 @@ typedef struct tagAMX {
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */ cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */ cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
int flags PACKED; /* current status, see amx_Flags() */ int flags PACKED; /* current status, see amx_Flags() */
/* for assertions and debug hook */
cell curline PACKED;
cell curfile PACKED;
int dbgcode PACKED;
cell dbgaddr PACKED;
cell dbgparam PACKED;
char _FAR *dbgname PACKED;
/* user data */ /* user data */
long usertags[AMX_USERNUM] PACKED; long 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
void _FAR *userdata[AMX_USERNUM] PACKED; void _FAR *userdata[AMX_USERNUM] PACKED;
/* native functions can raise an error */ /* native functions can raise an error */
int error PACKED; int error PACKED;
/* passing parameters requires a "count" field */
int paramcount;
/* the sleep opcode needs to store the full AMX status */ /* the sleep opcode needs to store the full AMX status */
cell pri PACKED; cell pri PACKED;
cell alt PACKED; cell alt PACKED;
@ -207,7 +227,7 @@ typedef struct tagAMX {
/* support variables for the JIT */ /* support variables for the JIT */
int reloc_size PACKED; /* required temporary buffer for relocations */ int reloc_size PACKED; /* required temporary buffer for relocations */
long code_size PACKED; /* estimated memory footprint of the native code */ long code_size PACKED; /* estimated memory footprint of the native code */
} AMX; } PACKED AMX;
enum { enum {
AMX_ERR_NONE, AMX_ERR_NONE,
@ -224,6 +244,7 @@ enum {
AMX_ERR_NATIVE, /* native function failed */ AMX_ERR_NATIVE, /* native function failed */
AMX_ERR_DIVIDE, /* divide by zero */ AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */ AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_INVSTATE, /* invalid state for this access */
AMX_ERR_MEMORY = 16, /* out of memory */ AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */ AMX_ERR_FORMAT, /* invalid file format */
@ -1883,6 +1904,9 @@ void FN_AMXX_DETACH(void);
void FN_AMXX_PLUGINSLOADED(void); void FN_AMXX_PLUGINSLOADED(void);
#endif // FN_AMXX_PLUGINSLOADED #endif // FN_AMXX_PLUGINSLOADED
// *** Types ***
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
// ***** Module funcs stuff ***** // ***** Module funcs stuff *****
enum ForwardExecType enum ForwardExecType
{ {
@ -1906,6 +1930,7 @@ enum ForwardParam
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/); typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...); typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/); typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...); typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...);
typedef const char * (*PFN_GET_MODNAME) (void); typedef const char * (*PFN_GET_MODNAME) (void);
@ -1954,13 +1979,15 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/); typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
#endif #endif
#ifdef MEMORY_TEST
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/); const unsigned int /*type*/, const size_t /*size*/);
typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, typedef void * (*PFN_REALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ ); const unsigned int /*type*/, const size_t /*size*/, void* /*addr*/ );
typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/, typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
const unsigned int /*type*/, const void* /*addr*/ ); const unsigned int /*type*/, const void* /*addr*/ );
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, ... /*params*/); #endif
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/); typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/); typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/); typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
@ -1974,9 +2001,12 @@ typedef int (*PFN_REGISTER_SPFORWARD_BYNAME) (AMX * /*amx*/, const char * /*f
typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/); typedef void (*PFN_UNREGISTER_SPFORWARD) (int /*id*/);
typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/); typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/); 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*/);
extern PFN_ADD_NATIVES g_fn_AddNatives; extern PFN_ADD_NATIVES g_fn_AddNatives;
extern PFN_BUILD_PATHNAME g_fn_BuildPathname; extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
extern PFN_GET_AMXADDR g_fn_GetAmxAddr; extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole; extern PFN_PRINT_SRVCONSOLE g_fn_PrintSrvConsole;
extern PFN_GET_MODNAME g_fn_GetModname; extern PFN_GET_MODNAME g_fn_GetModname;
@ -2018,7 +2048,6 @@ extern PFN_IS_PLAYER_HLTV g_fn_IsPlayerHLTV;
extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor; extern PFN_GET_PLAYER_ARMOR g_fn_GetPlayerArmor;
extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth; extern PFN_GET_PLAYER_HEALTH g_fn_GetPlayerHealth;
extern PFN_AMX_EXEC g_fn_AmxExec; extern PFN_AMX_EXEC g_fn_AmxExec;
extern PFN_AMX_EXECV g_fn_AmxExecv;
extern PFN_AMX_ALLOT g_fn_AmxAllot; extern PFN_AMX_ALLOT g_fn_AmxAllot;
extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic; extern PFN_AMX_FINDPUBLIC g_fn_AmxFindPublic;
extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript; extern PFN_LOAD_AMXSCRIPT g_fn_LoadAmxScript;
@ -2034,12 +2063,16 @@ extern PFN_GETPLAYERFLAGS g_fn_GetPlayerFlags;
extern PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict; extern PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
extern PFN_FORMAT g_fn_Format; extern PFN_FORMAT g_fn_Format;
extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam; 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;
#ifdef MAY_NEVER_BE_DEFINED #ifdef MAY_NEVER_BE_DEFINED
// Function prototypes for intellisense and similar systems // Function prototypes for intellisense and similar systems
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED // They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
int MF_AddNatives (const AMX_NATIVE_INFO *list) { } int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
char * MF_BuildPathname (const char * format, ...) { } char * MF_BuildPathname (const char * format, ...) { }
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
cell * MF_GetAmxAddr (AMX * amx, cell offset) { } cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
void MF_PrintSrvConsole (char * format, ...) { } void MF_PrintSrvConsole (char * format, ...) { }
const char * MF_GetModname (void) { } const char * MF_GetModname (void) { }
@ -2089,10 +2122,15 @@ void MF_UnregisterSPForward (int id) { }
int MF_GetPlayerFlags (int id) { } int MF_GetPlayerFlags (int id) { }
edict_t* MF_GetPlayerEdict (int id) { } edict_t* MF_GetPlayerEdict (int id) { }
const char * MF_Format (const char *fmt, ...) { } const char * MF_Format (const char *fmt, ...) { }
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) { }
#endif // MAY_NEVER_BE_DEFINED #endif // MAY_NEVER_BE_DEFINED
#define MF_AddNatives g_fn_AddNatives #define MF_AddNatives g_fn_AddNatives
#define MF_BuildPathname g_fn_BuildPathname #define MF_BuildPathname g_fn_BuildPathname
#define MF_BuildPathnameR g_fn_BuildPathnameR
#define MF_FormatAmxString g_fn_FormatAmxString #define MF_FormatAmxString g_fn_FormatAmxString
#define MF_GetAmxAddr g_fn_GetAmxAddr #define MF_GetAmxAddr g_fn_GetAmxAddr
#define MF_PrintSrvConsole g_fn_PrintSrvConsole #define MF_PrintSrvConsole g_fn_PrintSrvConsole
@ -2150,7 +2188,11 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_GetPlayerFlags g_fn_GetPlayerFlags #define MF_GetPlayerFlags g_fn_GetPlayerFlags
#define MF_GetPlayerEdict g_fn_GetPlayerEdict #define MF_GetPlayerEdict g_fn_GetPlayerEdict
#define MF_Format g_fn_Format #define MF_Format g_fn_Format
#define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction;
#define MF_AmxPush g_fn_AmxPush
#ifdef MEMORY_TEST
/*** Memory ***/ /*** Memory ***/
void *operator new(size_t reportedSize); void *operator new(size_t reportedSize);
void *operator new[](size_t reportedSize); void *operator new[](size_t reportedSize);
@ -2194,4 +2236,6 @@ void Mem_Deallocator(const char *sourceFile, const unsigned int sourceLine, cons
#define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr) #define realloc(ptr,sz) Mem_Reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
#define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr) #define free(ptr) Mem_Deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
#endif //MEMORY_TEST
#endif // #ifndef __AMXXMODULE_H__ #endif // #ifndef __AMXXMODULE_H__

View File

@ -21,13 +21,23 @@
// metamod plugin? // metamod plugin?
// #define USE_METAMOD // #define USE_METAMOD
// use memory manager/tester?
// note that if you use this, you cannot construct/allocate
// anything before the module attached (OnAmxxAttach).
// be careful of default constructors using new/malloc!
// #define MEMORY_TEST
// Unless you use STL or exceptions, keep this commented.
// It allows you to compile without libstdc++.so as a dependency
// #define NO_ALLOC_OVERRIDES
// - AMXX Init functions // - AMXX Init functions
// Also consider using FN_META_* // Also consider using FN_META_*
// AMXX query // AMXX query
//#define FN_AMXX_QUERY OnAmxxQuery //#define FN_AMXX_QUERY OnAmxxQuery
// AMXX attach // AMXX attach
// Do native functions init here (MF_AddNatives) // Do native functions init here (MF_AddNatives)
// #define FN_AMXX_ATTACH OnAmxxAttach //#define FN_AMXX_ATTACH OnAmxxAttach
// AMXX detach // AMXX detach
//#define FN_AMXX_DETACH OnAmxxDetach //#define FN_AMXX_DETACH OnAmxxDetach
// All plugins loaded // All plugins loaded

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,1,0 FILEVERSION 1,6,0,0
PRODUCTVERSION 1,0,1,0 PRODUCTVERSION 1,6,0,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -45,12 +45,12 @@ BEGIN
BEGIN BEGIN
VALUE "Comments", "AMX Mod X" VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X" VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", "1.01" VALUE "FileVersion", "1.60"
VALUE "InternalName", "amxmodx" VALUE "InternalName", "amxmodx"
VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team" VALUE "LegalCopyright", "Copyright (c) 2004-2005, AMX Mod X Dev Team"
VALUE "OriginalFilename", "amxmodx_mm.dll" VALUE "OriginalFilename", "amxmodx_mm.dll"
VALUE "ProductName", "AMX Mod X" VALUE "ProductName", "AMX Mod X"
VALUE "ProductVersion", "1.01" VALUE "ProductVersion", "1.60"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.1, November 17th, 2003 version 1.2.3, July 18th, 2005
Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -37,8 +37,8 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.2.1" #define ZLIB_VERSION "1.2.3"
#define ZLIB_VERNUM 0x1210 #define ZLIB_VERNUM 0x1230
/* /*
The 'zlib' compression library provides in-memory compression and The 'zlib' compression library provides in-memory compression and
@ -53,24 +53,22 @@ extern "C" {
application must provide more input and/or consume the output application must provide more input and/or consume the output
(providing more output space) before each call. (providing more output space) before each call.
The compressed data format used by the in-memory functions is the zlib The compressed data format used by default by the in-memory functions is
format, which is a zlib wrapper documented in RFC 1950, wrapped around a the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
deflate stream, which is itself documented in RFC 1951. around a deflate stream, which is itself documented in RFC 1951.
The library also supports reading and writing files in gzip (.gz) format The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio using the functions that start with an interface similar to that of stdio using the functions that start
with "gz". The gzip format is different from the zlib format. gzip is a with "gz". The gzip format is different from the zlib format. gzip is a
gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
This library can optionally read and write gzip streams in memory as well.
The zlib format was designed to be compact and fast for use in memory The zlib format was designed to be compact and fast for use in memory
and on communications channels. The gzip format was designed for single- and on communications channels. The gzip format was designed for single-
file compression on file systems, has a larger header than zlib to maintain file compression on file systems, has a larger header than zlib to maintain
directory information, and uses a different, slower check method than zlib. directory information, and uses a different, slower check method than zlib.
This library does not provide any functions to write gzip files in memory.
However such functions could be easily written using zlib's deflate function,
the documentation in the gzip RFC, and the examples in gzio.c.
The library does not install any signal handler. The decoder checks The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never the consistency of the compressed data, so the library should never
crash even in case of corrupted input. crash even in case of corrupted input.
@ -97,13 +95,36 @@ typedef struct z_stream_s {
free_func zfree; /* used to free the internal state */ free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */ voidpf opaque; /* private data object passed to zalloc and zfree */
int data_type; /* best guess about the data type: ascii or binary */ int data_type; /* best guess about the data type: binary or text */
uLong adler; /* adler32 value of the uncompressed data */ uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */ uLong reserved; /* reserved for future use */
} z_stream; } z_stream;
typedef z_stream FAR *z_streamp; typedef z_stream FAR *z_streamp;
/*
gzip header information passed to and from zlib routines. See RFC 1952
for more details on the meanings of these fields.
*/
typedef struct gz_header_s {
int text; /* true if compressed data believed to be text */
uLong time; /* modification time */
int xflags; /* extra flags (not used when writing a gzip file) */
int os; /* operating system */
Bytef *extra; /* pointer to extra field or Z_NULL if none */
uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
uInt extra_max; /* space at extra (only when reading header) */
Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
uInt name_max; /* space at name (only when reading header) */
Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
uInt comm_max; /* space at comment (only when reading header) */
int hcrc; /* true if there was or will be a header crc */
int done; /* true when done reading gzip header (not used
when writing a gzip file) */
} gz_header;
typedef gz_header FAR *gz_headerp;
/* /*
The application must update next_in and avail_in when avail_in has The application must update next_in and avail_in when avail_in has
dropped to zero. It must update next_out and avail_out when avail_out dropped to zero. It must update next_out and avail_out when avail_out
@ -168,11 +189,13 @@ typedef z_stream FAR *z_streamp;
#define Z_FILTERED 1 #define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2 #define Z_HUFFMAN_ONLY 2
#define Z_RLE 3 #define Z_RLE 3
#define Z_FIXED 4
#define Z_DEFAULT_STRATEGY 0 #define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */ /* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0 #define Z_BINARY 0
#define Z_ASCII 1 #define Z_TEXT 1
#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
#define Z_UNKNOWN 2 #define Z_UNKNOWN 2
/* Possible values of the data_type field (though see inflate()) */ /* Possible values of the data_type field (though see inflate()) */
@ -246,6 +269,10 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
and with zero avail_out, it must be called again after making room in the and with zero avail_out, it must be called again after making room in the
output buffer because there might be more output pending. output buffer because there might be more output pending.
Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
decide how much data to accumualte before producing output, in order to
maximize compression.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so flushed to the output buffer and the output is aligned on a byte boundary, so
that the decompressor can get all input data available so far. (In particular that the decompressor can get all input data available so far. (In particular
@ -257,7 +284,7 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_SYNC_FLUSH, and the compression state is reset so that decompression can Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if restart from this point if previous compressed data has been damaged or if
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
the compression. compression.
If deflate returns with avail_out == 0, this function must be called again If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated with the same value of the flush parameter and more output space (updated
@ -282,8 +309,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
deflate() sets strm->adler to the adler32 checksum of all input read deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes). so far (that is, total_in bytes).
deflate() may update data_type if it can make a good guess about deflate() may update strm->data_type if it can make a good guess about
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
binary. This field is only for information purposes and does not affect binary. This field is only for information purposes and does not affect
the compression algorithm in any manner. the compression algorithm in any manner.
@ -365,11 +392,11 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
output as possible to the output buffer. Z_BLOCK requests that inflate() stop output as possible to the output buffer. Z_BLOCK requests that inflate() stop
if and when it get to the next deflate block boundary. When decoding the zlib if and when it gets to the next deflate block boundary. When decoding the
or gzip format, this will cause inflate() to return immediately after the zlib or gzip format, this will cause inflate() to return immediately after
header and before the first block. When doing a raw inflate, inflate() will the header and before the first block. When doing a raw inflate, inflate()
go ahead and process the first block, and will return when it gets to the end will go ahead and process the first block, and will return when it gets to
of that block, or when it runs out of data. the end of that block, or when it runs out of data.
The Z_BLOCK option assists in appending to or combining deflate streams. The Z_BLOCK option assists in appending to or combining deflate streams.
Also to assist in this, on return inflate() will set strm->data_type to the Also to assist in this, on return inflate() will set strm->data_type to the
@ -401,7 +428,7 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
because Z_BLOCK is used. because Z_BLOCK is used.
If a preset dictionary is needed after this call (see inflateSetDictionary If a preset dictionary is needed after this call (see inflateSetDictionary
below), inflate sets strm-adler to the adler32 checksum of the dictionary below), inflate sets strm->adler to the adler32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is, strm->adler to the adler32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
@ -478,7 +505,8 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
16 to windowBits to write a simple gzip header and trailer around the 16 to windowBits to write a simple gzip header and trailer around the
compressed data instead of a zlib wrapper. The gzip header will have no compressed data instead of a zlib wrapper. The gzip header will have no
file name, no extra data, no comment, no modification time (set to zero), file name, no extra data, no comment, no modification time (set to zero),
no header crc, and the operating system will be set to 255 (unknown). no header crc, and the operating system will be set to 255 (unknown). If a
gzip stream is being written, strm->adler is a crc32 instead of an adler32.
The memLevel parameter specifies how much memory should be allocated The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but for the internal compression state. memLevel=1 uses minimum memory but
@ -497,7 +525,9 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
parameter only affects the compression ratio but not the correctness of the parameter only affects the compression ratio but not the correctness of the
compressed output even if it is not set appropriately. compressed output even if it is not set appropriately. Z_FIXED prevents the
use of dynamic Huffman codes, allowing for a simpler decoder for special
applications.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
@ -526,7 +556,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateInit or deflateInit2, a part of the dictionary may in effect be deflateInit or deflateInit2, a part of the dictionary may in effect be
discarded, for example if the dictionary is larger than the window size in discarded, for example if the dictionary is larger than the window size in
deflate or deflate2. Thus the strings most likely to be useful should be deflate or deflate2. Thus the strings most likely to be useful should be
put at the end of the dictionary, not at the front. put at the end of the dictionary, not at the front. In addition, the
current implementation of deflate will use at most the window size minus
262 bytes of the provided dictionary.
Upon return of this function, strm->adler is set to the adler32 value Upon return of this function, strm->adler is set to the adler32 value
of the dictionary; the decompressor may later use this value to determine of the dictionary; the decompressor may later use this value to determine
@ -592,6 +624,23 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
if strm->avail_out was zero. if strm->avail_out was zero.
*/ */
ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
int good_length,
int max_lazy,
int nice_length,
int max_chain));
/*
Fine tune deflate's internal compression parameters. This should only be
used by someone who understands the algorithm used by zlib's deflate for
searching for the best matching string, and even then only by the most
fanatic optimizer trying to squeeze out the last compressed bit for their
specific input data. Read the deflate.c source code for the meaning of the
max_lazy, good_length, nice_length, and max_chain parameters.
deflateTune() can be called after deflateInit() or deflateInit2(), and
returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
*/
ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
uLong sourceLen)); uLong sourceLen));
/* /*
@ -617,6 +666,30 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
stream state was inconsistent. stream state was inconsistent.
*/ */
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
gz_headerp head));
/*
deflateSetHeader() provides gzip header information for when a gzip
stream is requested by deflateInit2(). deflateSetHeader() may be called
after deflateInit2() or deflateReset() and before the first call of
deflate(). The text, time, os, extra field, name, and comment information
in the provided gz_header structure are written to the gzip header (xflag is
ignored -- the extra flags are set according to the compression level). The
caller must assure that, if not Z_NULL, name and comment are terminated with
a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
available there. If hcrc is true, a gzip header crc is included. Note that
the current versions of the command-line version of gzip (up through version
1.3.x) do not support header crc's, and will report that it is a "multi-part
gzip file" and give up.
If deflateSetHeader is not used, the default gzip header has text false,
the time set to zero, and os set to 255, with no extra, name, or comment
fields. The gzip header is returned to the default state by deflateReset().
deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/* /*
ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
int windowBits)); int windowBits));
@ -649,14 +722,15 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
windowBits can also be greater than 15 for optional gzip decoding. Add windowBits can also be greater than 15 for optional gzip decoding. Add
32 to windowBits to enable zlib and gzip decoding with automatic header 32 to windowBits to enable zlib and gzip decoding with automatic header
detection, or add 16 to decode only the gzip format (the zlib format will detection, or add 16 to decode only the gzip format (the zlib format will
return a Z_DATA_ERROR). return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
a crc32 instead of an adler32.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
memLevel). msg is set to null if there is no error message. inflateInit2 is set to null if there is no error message. inflateInit2 does not perform
does not perform any decompression apart from reading the zlib header if any decompression apart from reading the zlib header if present: this will
present: this will be done by inflate(). (So next_in and avail_in may be be done by inflate(). (So next_in and avail_in may be modified, but next_out
modified, but next_out and avail_out are unchanged.) and avail_out are unchanged.)
*/ */
ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
@ -664,11 +738,14 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
uInt dictLength)); uInt dictLength));
/* /*
Initializes the decompression dictionary from the given uncompressed byte Initializes the decompression dictionary from the given uncompressed byte
sequence. This function must be called immediately after a call of inflate sequence. This function must be called immediately after a call of inflate,
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the adler32 value returned by this call of can be determined from the adler32 value returned by that call of inflate.
inflate. The compressor and decompressor must use exactly the same The compressor and decompressor must use exactly the same dictionary (see
dictionary (see deflateSetDictionary). deflateSetDictionary). For raw inflate, this function can be called
immediately after inflateInit2() or inflateReset() and before any call of
inflate() to set the dictionary. The application must insure that the
dictionary that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is parameter is invalid (such as NULL dictionary) or the stream state is
@ -719,8 +796,64 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
stream state was inconsistent (such as zalloc or state being NULL). stream state was inconsistent (such as zalloc or state being NULL).
*/ */
ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
int bits,
int value));
/* /*
ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, This function inserts bits in the inflate input stream. The intent is
that this function is used to start inflating at a bit position in the
middle of a byte. The provided bits will be used before any bytes are used
from next_in. This function should only be used with raw inflate, and
should be used before the first inflate() call after inflateInit2() or
inflateReset(). bits must be less than or equal to 16, and that many of the
least significant bits of value will be inserted in the input.
inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
gz_headerp head));
/*
inflateGetHeader() requests that gzip header information be stored in the
provided gz_header structure. inflateGetHeader() may be called after
inflateInit2() or inflateReset(), and before the first call of inflate().
As inflate() processes the gzip stream, head->done is zero until the header
is completed, at which time head->done is set to one. If a zlib stream is
being decoded, then head->done is set to -1 to indicate that there will be
no gzip header information forthcoming. Note that Z_BLOCK can be used to
force inflate() to return immediately after header processing is complete
and before any actual data is decompressed.
The text, time, xflags, and os fields are filled in with the gzip header
contents. hcrc is set to true if there is a header CRC. (The header CRC
was valid if done is set to one.) If extra is not Z_NULL, then extra_max
contains the maximum number of bytes to write to extra. Once done is true,
extra_len contains the actual extra field length, and extra contains the
extra field, or that field truncated if extra_max is less than extra_len.
If name is not Z_NULL, then up to name_max characters are written there,
terminated with a zero unless the length is greater than name_max. If
comment is not Z_NULL, then up to comm_max characters are written there,
terminated with a zero unless the length is greater than comm_max. When
any of extra, name, or comment are not Z_NULL and the respective field is
not present in the header, then that field is set to Z_NULL to signal its
absence. This allows the use of deflateSetHeader() with the returned
structure to duplicate the header. However if those fields are set to
allocated memory, then the application will need to save those pointers
elsewhere so that they can be eventually freed.
If inflateGetHeader is not used, then the header information is simply
discarded. The header is always checked for validity, including the header
CRC if present. inflateReset() will reset the process to discard the header
information. The application would need to call inflateGetHeader() again to
retrieve the header from the next gzip stream.
inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
/*
ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
unsigned char FAR *window)); unsigned char FAR *window));
Initialize the internal stream state for decompression using inflateBack() Initialize the internal stream state for decompression using inflateBack()
@ -744,7 +877,7 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
in_func in, void FAR *in_desc, in_func in, void FAR *in_desc,
out_func out, void FAR *out_desc)); out_func out, void FAR *out_desc));
/* /*
@ -813,7 +946,7 @@ ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
that inflateBack() cannot return Z_OK. that inflateBack() cannot return Z_OK.
*/ */
ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
/* /*
All memory allocated by inflateBackInit() is freed. All memory allocated by inflateBackInit() is freed.
@ -1087,6 +1220,12 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
input stream, otherwise zero. input stream, otherwise zero.
*/ */
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
Returns 1 if file is being read directly without decompression, otherwise
zero.
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file)); ZEXTERN int ZEXPORT gzclose OF((gzFile file));
/* /*
Flushes all pending output if necessary, closes the compressed file Flushes all pending output if necessary, closes the compressed file
@ -1119,7 +1258,6 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
*/ */
ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/* /*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns return the updated checksum. If buf is NULL, this function returns
@ -1135,12 +1273,21 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
if (adler != original_adler) error(); if (adler != original_adler) error();
*/ */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
z_off_t len2));
/*
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/* /*
Update a running crc with the bytes buf[0..len-1] and return the updated Update a running CRC-32 with the bytes buf[0..len-1] and return the
crc. If buf is NULL, this function returns the required initial value updated CRC-32. If buf is NULL, this function returns the required initial
for the crc. Pre- and post-conditioning (one's complement) is performed value for the for the crc. Pre- and post-conditioning (one's complement) is
within this function so it shouldn't be done by the application. performed within this function so it shouldn't be done by the application.
Usage example: Usage example:
uLong crc = crc32(0L, Z_NULL, 0); uLong crc = crc32(0L, Z_NULL, 0);
@ -1151,6 +1298,16 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
if (crc != original_crc) error(); if (crc != original_crc) error();
*/ */
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
/*
Combine two CRC-32 check values into one. For two sequences of bytes,
seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
len2.
*/
/* various hacks, don't look :) */ /* various hacks, don't look :) */
@ -1167,7 +1324,7 @@ ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int stream_size)); int stream_size));
ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size)); const char *version, int stream_size));
ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
unsigned char FAR *window, unsigned char FAR *window,
const char *version, const char *version,
int stream_size)); int stream_size));
@ -1189,7 +1346,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
struct internal_state {int dummy;}; /* hack for buggy compilers */ struct internal_state {int dummy;}; /* hack for buggy compilers */
#endif #endif
ZEXTERN const char * ZEXPORT zError OF((int err)); ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));

Binary file not shown.

143
compiler/amxxpc/Binary.cpp Executable file
View File

@ -0,0 +1,143 @@
#include "Binary.h"
BinaryWriter::BinaryWriter(FILE *fp)
{
m_Fp = fp;
}
bool BinaryWriter::WriteAddr(void *buffer, size_t size)
{
if (fwrite(buffer, size, 1, m_Fp) != 1)
return false;
return true;
}
void BinaryWriter::WriteUInt32(uint32_t num)
{
if ( !WriteAddr(&num, sizeof(uint32_t)) )
throw -1;
}
void BinaryWriter::WriteInt32(int32_t num)
{
if ( !WriteAddr(&num, sizeof(int32_t)) )
throw -1;
}
void BinaryWriter::WriteUInt16(uint16_t num)
{
if ( !WriteAddr(&num, sizeof(uint16_t)) )
throw -1;
}
void BinaryWriter::WriteInt16(int16_t num)
{
if ( !WriteAddr(&num, sizeof(int16_t)) )
throw -1;
}
void BinaryWriter::WriteUInt8(uint8_t num)
{
if ( !WriteAddr(&num, sizeof(uint8_t)) )
throw -1;
}
void BinaryWriter::WriteInt8(int8_t num)
{
if ( !WriteAddr(&num, sizeof(int8_t)) )
throw -1;
}
void BinaryWriter::WriteChars(const char buffer[], size_t chars)
{
if (!chars)
return;
if (fwrite(buffer, sizeof(char), chars, m_Fp) != chars)
throw -1;
}
BinaryReader::BinaryReader(FILE *fp)
{
m_Fp = fp;
}
bool BinaryReader::ReadAddr(void *buffer, size_t size)
{
if (fread(buffer, size, 1, m_Fp) != 1)
return false;
return true;
}
uint32_t BinaryReader::ReadUInt32()
{
uint32_t num;
if ( !ReadAddr(&num, sizeof(uint32_t)) )
throw -1;
return num;
}
int32_t BinaryReader::ReadInt32()
{
int32_t num;
if ( !ReadAddr(&num, sizeof(int32_t)) )
throw -1;
return num;
}
uint16_t BinaryReader::ReadUInt16()
{
uint16_t num;
if ( !ReadAddr(&num, sizeof(uint16_t)) )
throw -1;
return num;
}
int16_t BinaryReader::ReadInt16()
{
int16_t num;
if ( !ReadAddr(&num, sizeof(int16_t)) )
throw -1;
return num;
}
uint8_t BinaryReader::ReadUInt8()
{
uint8_t num;
if ( !ReadAddr(&num, sizeof(uint8_t)) )
throw -1;
return num;
}
int8_t BinaryReader::ReadInt8()
{
int8_t num;
if ( !ReadAddr(&num, sizeof(int8_t)) )
throw -1;
return num;
}
char *BinaryReader::ReadChars(char buffer[], size_t chars)
{
if (!chars)
return buffer;
if (fread(buffer, sizeof(char), chars, m_Fp) != chars)
throw -1;
return buffer;
}

54
compiler/amxxpc/Binary.h Executable file
View File

@ -0,0 +1,54 @@
#ifndef _INCLUDE_BINARY_H
#define _INCLUDE_BINARY_H
#include <stdio.h>
#include "amx.h"
#ifdef WIN32
typedef __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef __int16 int16_t;
typedef unsigned __int16 uint16_t;
#else
#include <stdint.h>
#endif
class BinaryReader
{
public:
BinaryReader(FILE *fp);
//~BinaryReader();
public:
uint32_t ReadUInt32();
int32_t ReadInt32();
uint16_t ReadUInt16();
int16_t ReadInt16();
uint8_t ReadUInt8();
int8_t ReadInt8();
char *ReadChars(char buffer[], size_t chars);
private:
bool ReadAddr(void *buffer, size_t size);
private:
FILE *m_Fp;
};
class BinaryWriter
{
public:
BinaryWriter(FILE *fp);
public:
void WriteUInt32(uint32_t num);
void WriteInt32(int32_t num);
void WriteUInt16(uint16_t num);
void WriteInt16(int16_t num);
void WriteUInt8(uint8_t num);
void WriteInt8(int8_t num);
void WriteChars(const char buffer[], size_t chars);
private:
bool WriteAddr(void *buffer, size_t size);
private:
FILE *m_Fp;
};
#endif //_INCLUDE_BINARY_H

46
compiler/amxxpc/Makefile Executable file
View File

@ -0,0 +1,46 @@
#(C)2004-2005 AMX Mod X Development Team
# Makefile written by David "BAILOPAN" Anderson
### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3
CPP = gcc
BINARY = amxxpc
OBJECTS = amx.cpp amxxpc.cpp Binary.cpp
LINK = -lz /lib/libstdc++.a
INCLUDE = -I. -L.
ifeq "$(DEBUG)" "true"
BIN_DIR = Debug
CFLAGS = $(DEBUG_FLAGS)
else
BIN_DIR = Release
CFLAGS = $(OPT_FLAGS)
endif
CFLAGS += -DLINUX -DNDEBUG -Wno-deprecated -fexceptions -DHAVE_STDINT_H -DAMX_ANSIONLY -fno-rtti -static-libgcc
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
$(BIN_DIR)/%.o: %.cpp
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
all:
mkdir -p $(BIN_DIR)
$(MAKE) amxxpc
amxxpc: $(OBJ_LINUX)
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -ldl -lm -o$(BIN_DIR)/$(BINARY)
default: all
clean:
rm -rf Release/*.o
rm -rf Release/$(BINARY)
rm -rf Debug/*.o
rm -rf Debug/$(BINARY)

3984
compiler/amxxpc/amx.cpp Executable file

File diff suppressed because it is too large Load Diff

432
compiler/amxxpc/amx.h Executable file
View File

@ -0,0 +1,432 @@
/* Pawn Abstract Machine (for the Pawn language)
*
* Copyright (c) ITB CompuPhase, 1997-2005
*
* This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Version: $Id$
*/
#if defined FREEBSD && !defined __FreeBSD__
#define __FreeBSD__
#endif
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
#include <sclinux.h>
#endif
#ifndef AMX_H_INCLUDED
#define AMX_H_INCLUDED
#if defined HAVE_STDINT_H
#include <stdint.h>
#else
#if defined __LCC__ || defined __DMC__ || defined LINUX
#if defined HAVE_INTTYPES_H
#include <inttypes.h>
#else
#include <stdint.h>
#endif
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
* here, these types are probably undefined.
*/
#if defined __MACH__
#include <ppc/types.h>
typedef unsigned short int uint16_t;
typedef unsigned long int uint32_t;
#elif defined __FreeBSD__
#include <inttypes.h>
#else
typedef short int int16_t;
typedef unsigned short int uint16_t;
#if defined SN_TARGET_PS2
typedef int int32_t;
typedef unsigned int uint32_t;
#else
typedef long int int32_t;
typedef unsigned long int uint32_t;
#endif
#if defined __WIN32__ || defined _WIN32 || defined WIN32
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#define HAVE_I64
#elif defined __GNUC__
typedef long long int64_t;
typedef unsigned long long uint64_t;
#define HAVE_I64
#endif
#endif
#endif
#define HAVE_STDINT_H
#endif
#if defined _LP64 || defined WIN64 || defined _WIN64
#if !defined __64BIT__
#define __64BIT__
#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
#ifdef __cplusplus
extern "C" {
#endif
#if defined PAWN_DLL
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL __stdcall
#endif
#if !defined AMXAPI
#define AMXAPI __stdcall
#endif
#endif
/* calling convention for native functions */
#if !defined AMX_NATIVE_CALL
#define AMX_NATIVE_CALL
#endif
/* calling convention for all interface functions and callback functions */
#if !defined AMXAPI
#if defined STDECL
#define AMXAPI __stdcall
#elif defined CDECL
#define AMXAPI __cdecl
#elif defined GCC_HASCLASSVISIBILITY
#define AMXAPI __attribute__ ((visibility("default")))
#else
#define AMXAPI
#endif
#endif
#if !defined AMXEXPORT
#define AMXEXPORT
#endif
/* File format version Required AMX version
* 0 (original version) 0
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
* 2 (compressed files) 2
* 3 (public variables) 2
* 4 (opcodes SWAP.pri/alt and PUSHADDR) 4
* 5 (tagnames table) 4
* 6 (reformatted header) 6
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
* 8 (opcode STMT, renewed debug interface) 8
*/
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
#if !defined PAWN_CELL_SIZE
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
#endif
#if PAWN_CELL_SIZE==16
typedef uint16_t ucell;
typedef int16_t cell;
#elif PAWN_CELL_SIZE==32
typedef uint32_t ucell;
typedef int32_t cell;
#elif PAWN_CELL_SIZE==64
typedef uint64_t ucell;
typedef int64_t cell;
#else
#error Unsupported cell size (PAWN_CELL_SIZE)
#endif
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
#define UNLIMITED (~1u >> 1)
struct tagAMX;
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
cell *result, cell *params);
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
#if !defined _FAR
#define _FAR
#endif
#if defined _MSC_VER
#pragma warning(disable:4103) /* disable warning message 4103 that complains
* about pragma pack in a header file */
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
#define AMX_NO_ALIGN
#endif
#if defined __GNUC__
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#if defined __TURBOC__
#pragma option -a- /* "pack" pragma for older Borland compilers */
#endif
#endif
#endif
typedef struct tagAMX_NATIVE_INFO {
const char _FAR *name PACKED;
AMX_NATIVE func PACKED;
} PACKED AMX_NATIVE_INFO;
#define AMX_USERNUM 4
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
#define sNAMEMAX 31 /* maximum name length of symbol name */
typedef struct tagAMX_FUNCSTUB {
ucell address PACKED;
char name[sEXPMAX+1] PACKED;
} PACKED AMX_FUNCSTUB;
typedef struct tagFUNCSTUBNT {
ucell address PACKED;
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
} PACKED AMX_FUNCSTUBNT;
/* The AMX structure is the internal structure for many functions. Not all
* fields are valid at all times; many fields are cached in local variables.
*/
typedef struct tagAMX {
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
AMX_CALLBACK callback PACKED;
AMX_DEBUG debug PACKED; /* debug callback */
/* for external functions a few registers must be accessible from the outside */
cell cip PACKED; /* instruction pointer: relative to base + amxhdr->cod */
cell frm PACKED; /* stack frame base: relative to base + amxhdr->dat */
cell hea PACKED; /* top of the heap: relative to base + amxhdr->dat */
cell hlw PACKED; /* bottom of the heap: relative to base + amxhdr->dat */
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
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 *userdata[AMX_USERNUM] PACKED;
/* native functions can raise an error */
int error PACKED;
/* passing parameters requires a "count" field */
int paramcount;
/* the sleep opcode needs to store the full AMX status */
cell pri PACKED;
cell alt PACKED;
cell reset_stk PACKED;
cell reset_hea PACKED;
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
/* support variables for the JIT */
int reloc_size PACKED; /* required temporary buffer for relocations */
long code_size PACKED; /* estimated memory footprint of the native code */
} PACKED AMX;
/* The AMX_HEADER structure is both the memory format as the file format. The
* structure is used internaly.
*/
typedef struct tagAMX_HEADER {
int32_t size PACKED; /* size of the "file" */
uint16_t magic PACKED; /* signature */
char file_version PACKED; /* file format version */
char amx_version PACKED; /* required version of the AMX */
int16_t flags PACKED;
int16_t defsize PACKED; /* size of a definition record */
int32_t cod PACKED; /* initial value of COD - code block */
int32_t dat PACKED; /* initial value of DAT - data block */
int32_t hea PACKED; /* initial value of HEA - start of the heap */
int32_t stp PACKED; /* initial value of STP - stack top */
int32_t cip PACKED; /* initial value of CIP - the instruction pointer */
int32_t publics PACKED; /* offset to the "public functions" table */
int32_t natives PACKED; /* offset to the "native functions" table */
int32_t libraries PACKED; /* offset to the table of libraries */
int32_t pubvars PACKED; /* the "public variables" table */
int32_t tags PACKED; /* the "public tagnames" table */
int32_t nametable PACKED; /* name table */
} PACKED AMX_HEADER;
//This is always the same for us
#define AMX_MAGIC 0xf1e0
enum {
AMX_ERR_NONE,
/* reserve the first 15 error codes for exit codes of the abstract machine */
AMX_ERR_EXIT, /* forced exit */
AMX_ERR_ASSERT, /* assertion failed */
AMX_ERR_STACKERR, /* stack/heap collision */
AMX_ERR_BOUNDS, /* index out of bounds */
AMX_ERR_MEMACCESS, /* invalid memory access */
AMX_ERR_INVINSTR, /* invalid instruction */
AMX_ERR_STACKLOW, /* stack underflow */
AMX_ERR_HEAPLOW, /* heap underflow */
AMX_ERR_CALLBACK, /* no callback, or invalid callback */
AMX_ERR_NATIVE, /* native function failed */
AMX_ERR_DIVIDE, /* divide by zero */
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
AMX_ERR_INVSTATE, /* invalid state for this access */
AMX_ERR_MEMORY = 16, /* out of memory */
AMX_ERR_FORMAT, /* invalid file format */
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
AMX_ERR_NOTFOUND, /* function not found */
AMX_ERR_INDEX, /* invalid index parameter (bad entry point) */
AMX_ERR_DEBUG, /* debugger cannot run */
AMX_ERR_INIT, /* AMX not initialized (or doubly initialized) */
AMX_ERR_USERDATA, /* unable to set user data field (table full) */
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
AMX_ERR_PARAMS, /* parameter error */
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
};
/* AMX_FLAG_CHAR16 0x01 no longer used */
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
#define AMX_EXEC_MAIN -1 /* start at program entry point */
#define AMX_EXEC_CONT -2 /* continue from last address */
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
#if !defined AMX_COMPACTMARGIN
#define AMX_COMPACTMARGIN 64
#endif
/* for native functions that use floating point parameters, the following
* two macros are convenient for casting a "cell" into a "float" type _without_
* changing the bit pattern
*/
#if PAWN_CELL_SIZE==32
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
#elif PAWN_CELL_SIZE==64
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
#else
#error Unsupported cell size
#endif
#define amx_StrParam(amx,param,result) \
do { \
cell *amx_cstr_; int amx_length_; \
amx_GetAddr((amx), (param), &amx_cstr_); \
amx_StrLen(amx_cstr_, &amx_length_); \
if (amx_length_ > 0 && \
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
else (result) = NULL; \
} while (0)
uint16_t * AMXAPI amx_Align16(uint16_t *v);
uint32_t * AMXAPI amx_Align32(uint32_t *v);
#if defined _I64_MAX || defined HAVE_I64
uint64_t * AMXAPI amx_Align64(uint64_t *v);
#endif
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
int AMXAPI amx_Cleanup(AMX *amx);
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
int AMXAPI amx_Init(AMX *amx, void *program);
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
int AMXAPI amx_NameLength(AMX *amx, int *length);
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
int AMXAPI amx_NumNatives(AMX *amx, int *number);
int AMXAPI amx_NumPublics(AMX *amx, int *number);
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
int AMXAPI amx_NumTags(AMX *amx, int *number);
int AMXAPI amx_Push(AMX *amx, cell value);
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
int AMXAPI amx_RaiseError(AMX *amx, int error);
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
int AMXAPI amx_StrLen(const cell *cstring, int *length);
int AMXAPI amx_UTF8Check(const char *string, int *length);
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
#if PAWN_CELL_SIZE==16
#define amx_AlignCell(v) amx_Align16(v)
#elif PAWN_CELL_SIZE==32
#define amx_AlignCell(v) amx_Align32(v)
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
#define amx_AlignCell(v) amx_Align64(v)
#else
#error Unsupported cell size
#endif
#define amx_RegisterFunc(amx, name, func) \
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack() /* reset default packing */
#elif defined MACOS && defined __MWERKS__
#pragma options align=reset
#else
#pragma pack(pop) /* reset previous packing */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* AMX_H_INCLUDED */

172
compiler/amxxpc/amxdbg.h Executable file
View File

@ -0,0 +1,172 @@
/* Abstract Machine for the Pawn compiler, debugger support
*
* This file contains extra definitions that are convenient for debugger
* support.
*
* Copyright (c) ITB CompuPhase, 2005
*
* This software is provided "as-is", without any express or implied warranty.
* In no event will the authors be held liable for any damages arising from
* the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*
* Version: $Id$
*/
#ifndef AMXDBG_H_INCLUDED
#define AMXDBG_H_INCLUDED
#ifndef AMX_H_INCLUDED
#include "amx.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Some compilers do not support the #pragma align, which should be fine. Some
* compilers give a warning on unknown #pragmas, which is not so fine...
*/
#if defined SN_TARGET_PS2 || defined __GNUC__
#define AMX_NO_ALIGN
#endif
#if defined __GNUC__
#define PACKED __attribute__((packed))
#else
#define PACKED
#endif
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack(1) /* structures must be packed (byte-aligned) */
#elif defined MACOS && defined __MWERKS__
#pragma options align=mac68k
#else
#pragma pack(push)
#pragma pack(1) /* structures must be packed (byte-aligned) */
#if defined __TURBOC__
#pragma option -a- /* "pack" pragma for older Borland compilers */
#endif
#endif
#endif
typedef struct tagAMX_DBG_HDR {
int32_t size PACKED; /* size of the debug information chunk */
uint16_t magic PACKED; /* signature, must be 0xf1ef */
char file_version PACKED; /* file format version */
char amx_version PACKED; /* required version of the AMX */
int16_t flags PACKED; /* currently unused */
int16_t files PACKED; /* number of entries in the "file" table */
int16_t lines PACKED; /* number of entries in the "line" table */
int16_t symbols PACKED; /* number of entries in the "symbol" table */
int16_t tags PACKED; /* number of entries in the "tag" table */
int16_t automatons PACKED; /* number of entries in the "automaton" table */
int16_t states PACKED; /* number of entries in the "state" table */
} AMX_DBG_HDR PACKED;
#define AMX_DBG_MAGIC 0xf1ef
typedef struct tagAMX_DBG_FILE {
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_FILE PACKED;
typedef struct tagAMX_DBG_LINE {
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
int32_t line PACKED; /* line number */
} AMX_DBG_LINE PACKED;
typedef struct tagAMX_DBG_SYMBOL {
ucell address PACKED; /* address in the data segment or relative to the frame */
int16_t tag PACKED; /* tag for the symbol */
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
char ident PACKED; /* kind of symbol (function/variable) */
char vclass PACKED; /* class of symbol (global/local) */
int16_t dim PACKED; /* number of dimensions */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_SYMBOL PACKED;
typedef struct tagAMX_DBG_SYMDIM {
int16_t tag PACKED; /* tag for the array dimension */
ucell size PACKED; /* size of the array dimension */
} AMX_DBG_SYMDIM PACKED;
typedef struct tagAMX_DBG_TAG {
int16_t tag PACKED; /* tag id */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_TAG PACKED;
typedef struct tagAMX_DBG_MACHINE {
int16_t automaton PACKED; /* automaton id */
ucell address PACKED; /* address of state variable */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_MACHINE PACKED;
typedef struct tagAMX_DBG_STATE {
int16_t state PACKED; /* state id */
int16_t automaton PACKED; /* automaton id */
const char name[1] PACKED; /* ASCII string, zero-terminated */
} AMX_DBG_STATE PACKED;
typedef struct tagAMX_DBG {
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
AMX_DBG_FILE _FAR **filetbl PACKED;
AMX_DBG_LINE _FAR *linetbl PACKED;
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
AMX_DBG_TAG _FAR **tagtbl PACKED;
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
AMX_DBG_STATE _FAR **statetbl PACKED;
} AMX_DBG PACKED;
#if !defined iVARIABLE
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
#define iARRAY 3
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
#define iFUNCTN 9
#endif
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, FILE *fp);
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
#if !defined AMX_NO_ALIGN
#if defined LINUX || defined __FreeBSD__
#pragma pack() /* reset default packing */
#elif defined MACOS && defined __MWERKS__
#pragma options align=reset
#else
#pragma pack(pop) /* reset previous packing */
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif /* AMXDBG_H_INCLUDED */

395
compiler/amxxpc/amxxpc.cpp Executable file
View File

@ -0,0 +1,395 @@
#include <stdio.h>
#ifdef __linux__
#include <unistd.h>
#else
#include <fcntl.h>
#include <io.h>
#endif
#include <stdlib.h>
#include "zlib.h"
#include "amx.h"
#include "amxdbg.h"
#include "amxxpc.h"
#include "Binary.h"
static PRINTF pc_printf = NULL;
void ReadFileIntoPl(abl *pl, FILE *fp);
bool CompressPl(abl *pl);
void Pl2Bh(abl *pl, BinPlugin *bh);
void WriteBh(BinaryWriter *bw, BinPlugin *bh);
int main(int argc, char **argv)
{
struct abl pl32;
struct abl pl64;
#ifdef _DEBUG
printf("debug clamp\n");
getchar();
#endif
#ifdef __linux__
HINSTANCE lib = NULL;
if (FileExists("./amxxpc32.so"))
lib = dlmount("./amxxpc32.so");
else
lib = dlmount("amxxpc32.so");
#else
HINSTANCE lib = dlmount("amxxpc32.dll");
#endif
if (!lib)
{
#ifdef __linux__
printf("32bit compiler failed to instantiate: %s\n", dlerror());
#else
printf("32bit compiler failed to instantiate: %d\n", GetLastError());
#endif
exit(0);
}
COMPILER sc32 = (COMPILER)dlsym(lib, "Compile32");
pc_printf = (PRINTF)dlsym(lib, "pc_printf");
if (!sc32 || !pc_printf)
{
#ifdef __linux__
printf("32bit compiler failed to link: %p.\n",sc32);
#else
printf("32bit compiler failed to link: %d.\n", GetLastError());
#endif
exit(0);
}
pc_printf("Welcome to the AMX Mod X %s Compiler.\n", VERSION_STRING);
pc_printf("Copyright (c) 1997-2005 ITB CompuPhase, AMX Mod X Team\n\n");
if (argc < 2)
{
pc_printf("Usage: <file.sma> [options]\n");
pc_printf("Use -? or --help to see full options\n\n");
getchar();
exit(0);
}
if (!strcmp(argv[1], "-?") || !strcmp(argv[1], "--help"))
{
show_help();
pc_printf("Press any key to continue.\n");
getchar();
exit(0);
}
sc32(argc, argv);
char *file = FindFileName(argc, argv);
if (file == NULL)
{
pc_printf("Could not locate the output file.\n");
exit(0);
} else if (strstr(file, ".asm")) {
pc_printf("Assembler output succeeded.\n");
exit(0);
} else {
FILE *fp = fopen(file, "rb");
if (fp == NULL)
{
pc_printf("Could not locate output file %s (compile failed).\n", file);
exit(0);
}
ReadFileIntoPl(&pl32, fp);
pl32.cellsize = 4;
fclose(fp);
}
unlink(file);
HINSTANCE lib64 = NULL;
#ifdef __linux__
if (FileExists("./amxxpc64.so"))
lib64 = dlmount("./amxxpc64.so");
else
lib64 = dlmount("amxxpc64.so");
#else
lib64 = dlmount("amxxpc64.dll");
#endif
if (!lib64)
{
pc_printf("64bit compiler failed to instantiate.\n");
exit(0);
}
COMPILER sc64 = (COMPILER)dlsym(lib64, "Compile64");
if (!sc64)
{
#ifdef __linux__
pc_printf("64bit compiler failed to link: %s.\n", dlerror());
#else
pc_printf("64bit compiler failed to link: %d.\n", GetLastError());
#endif
exit(0);
}
sc64(argc, argv);
dlclose(lib64);
if (file == NULL)
{
pc_printf("Could not locate the output file on second pass.\n");
exit(0);
} else {
FILE *fp = fopen(file, "rb");
if (fp == NULL)
{
pc_printf("Could not locate output file on second pass (compile failed).\n");
exit(0);
}
ReadFileIntoPl(&pl64, fp);
pl64.cellsize = 8;
fclose(fp);
}
/////////////
// COMPRSSION
/////////////
CompressPl(&pl32);
CompressPl(&pl64);
char *newfile = new char[strlen(file)+3];
strcpy(newfile, file);
if (!strstr(file, ".amxx") && !strstr(file, ".AMXX"))
strcat(newfile, "x");
FILE *fp = fopen(newfile, "wb");
if (!fp)
{
pc_printf("Error trying to write file %s.\n", newfile);
exit(0);
}
BinPlugin bh32, bh64;
Pl2Bh(&pl32, &bh32);
Pl2Bh(&pl64, &bh64);
try
{
BinaryWriter bw(fp);
bw.WriteUInt32(MAGIC_HEADER2);
bw.WriteUInt16(MAGIC_VERSION);
bw.WriteUInt8(2);
//base header
int baseaddr = sizeof(int32_t) + sizeof(int16_t) + sizeof(int8_t);
//entry is 4 ints and a byte
int entrysize = (sizeof(int32_t) * 4) + sizeof(int8_t);
//extend this by the two entries we have
baseaddr += entrysize * 2;
bh32.offs = baseaddr;
bh64.offs = bh32.offs + bh32.disksize;
WriteBh(&bw, &bh32);
WriteBh(&bw, &bh64);
bw.WriteChars(pl32.cmp, pl32.cmpsize);
bw.WriteChars(pl64.cmp, pl64.cmpsize);
} catch (...) {
fclose(fp);
unlink(file);
pc_printf("Error, failed to write binary\n");
dlclose(lib);
exit(0);
}
fclose(fp);
unlink(file);
pc_printf("Done.\n");
dlclose(lib);
exit(0);
}
void WriteBh(BinaryWriter *bw, BinPlugin *bh)
{
bw->WriteUInt8(bh->cellsize);
bw->WriteUInt32(bh->disksize);
bw->WriteUInt32(bh->imagesize);
bw->WriteUInt32(bh->memsize);
bw->WriteUInt32(bh->offs);
}
void Pl2Bh(abl *pl, BinPlugin *bh)
{
bh->cellsize = pl->cellsize;
bh->disksize = pl->cmpsize;
bh->imagesize = pl->size;
bh->memsize = pl->stp;
}
bool CompressPl(abl *pl)
{
pl->cmpsize = compressBound(pl->size);
pl->cmp = new char[pl->cmpsize];
int err = compress((Bytef *)(pl->cmp), (uLongf *)&(pl->cmpsize), (const Bytef *)(pl->data), pl->size);
delete [] pl->data;
pl->data = NULL;
if (err != Z_OK)
{
pc_printf("internal error - compression failed on first pass: %d\n", err);
exit(0);
}
return true;
}
//As of Small 3.0, there's extra debug info in the file we need to get out.
//Sadly this is placed somewhere really inconvenient and I'm mad.
void ReadFileIntoPl(abl *pl, FILE *fp)
{
AMX_HEADER hdr;
AMX_DBG_HDR dbg;
fread(&hdr, sizeof(hdr), 1, fp);
amx_Align32((uint32_t *)&hdr.stp);
amx_Align32((uint32_t *)&hdr.size);
pl->stp = hdr.stp;
int size = hdr.size;
if (hdr.flags & AMX_FLAG_DEBUG)
{
fseek(fp, hdr.size, SEEK_SET);
fread(&dbg, sizeof(dbg), 1, fp);
size += dbg.size;
}
pl->size = size;
pl->data = new char[size];
rewind(fp);
fread(pl->data, 1, size, fp);
}
//we get the full name of the file here
//our job is to a] switch the .sma extension to .amx
// and to b] strip everything but the trailing name
char *swiext(const char *file, const char *ext, int isO)
{
int i = 0, pos = -1, j = 0;
int fileLen = strlen(file);
int extLen = strlen(ext);
int max = 0, odirFlag = -1;
for (i=fileLen-1; i>=0; i--)
{
if (file[i] == '.' && pos == -1)
{
pos = i+1;
}
if ((file[i] == '/' || file[i] == '\\') && !isO)
{
odirFlag = i+1;
//realign pos - we've just stripped fileLen-i chars
pos -= i + 1;
break;
}
}
char *newbuffer = new char[fileLen+strlen(ext)+2];
fileLen += strlen(ext);
if (odirFlag == -1)
{
strcpy(newbuffer, file);
} else {
strcpy(newbuffer, &(file[odirFlag]));
}
if (pos > -1)
{
for (i=pos; i<fileLen; i++)
{
if (j < extLen)
newbuffer[i] = ext[j++];
else
break;
}
newbuffer[i] = '\0';
} else {
strcat(newbuffer, ".");
strcat(newbuffer, ext);
}
return newbuffer;
}
char *FindFileName(int argc, char **argv)
{
int i = 0;
int save = -1;
for (i=1; i<argc; i++)
{
if (argv[i][0] == '-' && argv[i][1] == 'o')
{
if (argv[i][2] == ' ' || argv[i][2] == '\0')
{
if (i == argc-1)
return NULL;
return swiext(&argv[i+1][2], "amx", 1);
} else {
return swiext(&(argv[i][2]), "amx", 1);
}
}
if (argv[i][0] != '-')
{
save = i;
}
}
if (save>0)
{
return swiext(argv[save], "amx", 0);
}
return NULL;
}
void show_help()
{
printf("Options:\n");
printf("\t-A<num> alignment in bytes of the data segment and the stack\n");
printf("\t-a output assembler code\n");
printf("\t-C[+/-] compact encoding for output file (default=-)\n");
printf("\t-c<name> codepage name or number; e.g. 1252 for Windows Latin-1\n");
printf("\t-Dpath active directory path\n");
printf("\t-d0 no symbolic information, no run-time checks\n");
printf("\t-d1 [default] run-time checks, no symbolic information\n");
printf("\t-d2 full debug information and dynamic checking\n");
printf("\t-d3 full debug information, dynamic checking, no optimization\n");
printf("\t-e<name> set name of error file (quiet compile)\n");
printf("\t-H<hwnd> window handle to send a notification message on finish\n");
printf("\t-i<name> path for include files\n");
printf("\t-l create list file (preprocess only)\n");
printf("\t-o<name> set base name of output file\n");
printf("\t-p<name> set name of \"prefix\" file\n");
printf("\t-r[name] write cross reference report to console or to specified file\n");
}
#ifdef __linux__
bool FileExists(const char *file)
{
FILE *fp = fopen(file, "rb");
if (!fp)
return false;
fclose(fp);
return true;
}
#endif

74
compiler/amxxpc/amxxpc.h Executable file
View File

@ -0,0 +1,74 @@
#ifndef _AMXXSC_INCLUDE_H
#define _AMXXSC_INCLUDE_H
#define VERSION_STRING "1.60-300"
#define VERSION 03000
#define MAGIC_HEADER 0x414D5842
#define MAGIC_HEADER2 0x414D5858
#define MAGIC_VERSION 0x0300
#ifdef __linux__
# include <dlfcn.h>
#else
# include <windows.h>
#endif
#include <string.h>
#ifdef __linux__
# define dlmount(x) dlopen(x, RTLD_NOW|RTLD_GLOBAL)
typedef void* HINSTANCE;
#else
# define dlsym(x, s) GetProcAddress(x, s)
# define dlmount(x) LoadLibrary(x)
# define dlclose(x) FreeLibrary(x)
#endif
#include "zlib.h"
#include "Binary.h"
typedef int (*COMPILER)(int argc, char **argv);
typedef int (*PRINTF)(const char *message, ...);
char *FindFileName(int argc, char **argv);
char *swiext(const char *file, const char *ext);
void show_help();
struct ablhdr
{
int magic;
char size;
};
struct abl
{
long stp;
char cellsize;
int size;
long cmpsize;
char *data;
char *cmp;
};
struct BinHeader
{
int32_t magic;
int16_t version;
int8_t plugins;
};
struct BinPlugin
{
int8_t cellsize; //cell size
int32_t imagesize; //uncompressed image size
int32_t disksize; //compressed image size
int32_t memsize; //memory image size
int32_t offs; //file offset
};
#ifdef __linux__
bool FileExists(const char *file);
#endif
#endif //_AMXXSC_INCLUDE_H

21
compiler/amxxpc/amxxpc.sln Executable file
View File

@ -0,0 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxxpc", "amxxpc.vcproj", "{39412290-D01C-472F-A439-AB5592A04C08}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{39412290-D01C-472F-A439-AB5592A04C08}.Debug.ActiveCfg = Debug|Win32
{39412290-D01C-472F-A439-AB5592A04C08}.Debug.Build.0 = Debug|Win32
{39412290-D01C-472F-A439-AB5592A04C08}.Release.ActiveCfg = Release|Win32
{39412290-D01C-472F-A439-AB5592A04C08}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

174
compiler/amxxpc/amxxpc.vcproj Executable file
View File

@ -0,0 +1,174 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="amxxpc"
ProjectGUID="{39412290-D01C-472F-A439-AB5592A04C08}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="Debug"
IntermediateDirectory="Debug"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="zlib.lib"
OutputFile="$(OutDir)/amxxpc.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/amxxpc.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="Release"
IntermediateDirectory="Release"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="4"
StructMemberAlignment="0"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="zlib.lib"
OutputFile="$(OutDir)/amxxpc.exe"
LinkIncremental="1"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<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;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
<File
RelativePath=".\amx.cpp">
</File>
<File
RelativePath=".\amxxpc.cpp">
</File>
<File
RelativePath=".\Binary.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath=".\amx.h">
</File>
<File
RelativePath=".\amxdbg.h">
</File>
<File
RelativePath=".\amxxpc.h">
</File>
<File
RelativePath=".\Binary.h">
</File>
<File
RelativePath=".\osdefs.h">
</File>
<File
RelativePath=".\resource.h">
</File>
<File
RelativePath=".\resource1.h">
</File>
<File
RelativePath=".\sclinux.h">
</File>
<File
RelativePath=".\zconf.h">
</File>
<File
RelativePath=".\zlib.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
<File
RelativePath=".\amxxpc1.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

72
compiler/amxxpc/amxxpc1.rc Executable file
View File

@ -0,0 +1,72 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource1.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource1.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
1 ICON "favicon.ico"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

BIN
compiler/amxxpc/favicon.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

15
compiler/amxxpc/getch.h Executable file
View File

@ -0,0 +1,15 @@
/* Extremely inefficient but portable POSIX getch(), see getch.c */
#ifndef GETCH_H
#define GETCH_H
#if defined __cplusplus
extern "C" {
#endif
int getch(void);
int kbhit(void);
#if defined __cplusplus
}
#endif
#endif /* GETCH_H */

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