235 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
383 changed files with 51108 additions and 14066 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
} }
@ -403,11 +418,12 @@ void EventsMngr::executeEvents()
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); executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
} }
@ -423,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;
@ -459,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;
} }
@ -479,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)
{ {
@ -497,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,19 +30,21 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h"
void AMXAPI amxx_InvalidateTrace(AMX *amx);
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)
@ -74,67 +76,73 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{ {
// Get debug info // Get debug info
AMX *amx = (*iter).pPlugin->getAMX(); AMX *amx = (*iter).pPlugin->getAMX();
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(amx->userdata[2]); Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
if (pInfo)
pInfo->error = AMX_ERR_NONE; if (pDebugger)
pDebugger->BeginExec();
// handle strings & arrays // handle strings & arrays
int i, ax=0; 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,
&realParams[i], &tmp);
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0); amx_SetStringOld(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(amx, 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! //Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
for (i=m_NumParams-1; i>=0; i--) for (i = m_NumParams-1; i >= 0; i--)
{ {
amx_Push(amx, realParams[i]); amx_Push(amx, realParams[i]);
} }
// exec // exec
cell retVal; cell retVal;
int err = amx_Exec(amx, &retVal, iter->func); 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)
{ {
//Did something else set an error? //Did something else set an error?
if (pInfo && pInfo->error != AMX_ERR_NONE) if (pDebugger && pDebugger->ErrorExists())
{ {
//we don't care, something else logged the error. //we don't care, something else logged the error.
} else { }
else if (err != -1)
{
//nothing logged the error so spit it out anyway //nothing logged the error so spit it out anyway
LogError(amx, err, ""); LogError(amx, err, NULL);
} }
} }
amxx_InvalidateTrace(amx);
amx->error = AMX_ERR_NONE; 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)
{ {
@ -157,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);
} }
@ -190,6 +197,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
} }
} }
} }
return globRetVal; return globRetVal;
} }
@ -229,62 +237,66 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
if (!pPlugin->isExecutable(m_Func)) if (!pPlugin->isExecutable(m_Func))
return 0; return 0;
AMX_DBGINFO *pInfo = (AMX_DBGINFO *)(m_Amx->userdata[2]); Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
if (pInfo) if (pDebugger)
pInfo->error = AMX_ERR_NONE; 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,
&realParams[i], &tmp);
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0); amx_SetStringOld(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--)
for (i = m_NumParams - 1; i >= 0; i--)
amx_Push(m_Amx, realParams[i]); amx_Push(m_Amx, realParams[i]);
// exec // exec
cell retVal; cell retVal;
int err = amx_Exec(m_Amx, &retVal, m_Func); int err = amx_Exec(m_Amx, &retVal, m_Func);
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)
{ {
//Did something else set an error? //Did something else set an error?
if (pInfo && pInfo->error != AMX_ERR_NONE) if (pDebugger && pDebugger->ErrorExists())
{ {
//we don't care, something else logged the error. //we don't care, something else logged the error.
} else { }
else if (err != -1)
{
//nothing logged the error so spit it out anyway //nothing logged the error so spit it out anyway
LogError(m_Amx, err, ""); LogError(m_Amx, err, NULL);
} }
} }
amxx_InvalidateTrace(m_Amx);
if (pDebugger)
pDebugger->EndExec();
m_Amx->error = AMX_ERR_NONE; m_Amx->error = AMX_ERR_NONE;
// cleanup strings & arrays // cleanup strings & arrays
@ -309,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);
} }
@ -328,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;
} }
@ -338,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;
@ -362,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;
} }
@ -369,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()
@ -427,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);
@ -435,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;
} }
@ -448,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);
} }
@ -525,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)
@ -538,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);
} }
@ -546,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

@ -157,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')
{ {
@ -184,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;
} }
@ -279,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)
@ -300,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();
} }
@ -312,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)
{ {
@ -332,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())
@ -348,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();
} }
@ -357,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;
@ -381,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);
@ -403,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();
@ -423,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;
} }
@ -461,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;
@ -490,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)
{ {
@ -521,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;
@ -531,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)
@ -546,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");
@ -559,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 == '%')
@ -592,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':
{ {
@ -613,8 +630,7 @@ 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;
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
ZEROTERM(outbuf); ZEROTERM(outbuf);
@ -639,17 +655,19 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
} }
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':
@ -670,37 +688,36 @@ 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;
_snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString); _snprintf(outptr, sizeof(outbuf)-(outptr-outbuf)-1, format, tmpString);
ZEROTERM(outbuf); ZEROTERM(outbuf);
@ -723,28 +740,29 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
} }
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;
} }
@ -754,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;
} }
@ -782,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"))
@ -796,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");
@ -809,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 == '%')
@ -839,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);
@ -847,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);
@ -862,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':
@ -887,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);
@ -924,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);
@ -957,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);
@ -969,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();
@ -977,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 {
@ -1022,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)
@ -1031,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;
@ -1042,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);
@ -1062,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;
@ -1092,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())
{ {
@ -1105,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);
} }
@ -1122,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);
} }
@ -1136,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)";
} }
@ -1166,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);
@ -1179,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);
@ -1192,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);
} }
@ -1200,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);
@ -1211,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);
} }
@ -1236,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);
@ -1264,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);
@ -1311,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;
@ -1324,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);
@ -1332,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);
@ -1347,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);
@ -1358,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);
@ -1383,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];
@ -1415,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)
{ {
@ -1423,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)
@ -1437,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,135 +35,192 @@
// ***************************************************** // *****************************************************
// 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()
{ {
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;
} }
@ -175,64 +232,87 @@ void LogEventsMngr::executeLogEvents()
} }
} }
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 ( (!amx || !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,8 +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 ( !stricmp(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];
@ -106,17 +117,22 @@ public:
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; }
@ -138,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; }
}; };
@ -172,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;
} }
}; };
@ -203,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;
@ -238,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,7 +32,7 @@
#include "amxmodx.h" #include "amxmodx.h"
#ifndef FAR #ifndef FAR
#define FAR #define FAR
#endif #endif
// New // New
@ -55,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();
@ -67,6 +67,7 @@ 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");
@ -114,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);
@ -163,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;
@ -172,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:
@ -201,9 +205,7 @@ bool CModule::queryModule()
m_Status = MODULE_QUERY; m_Status = MODULE_QUERY;
return true; return true;
} } else {
else
{
m_Status = MODULE_NOQUERY; m_Status = MODULE_NOQUERY;
m_Amxx = false; m_Amxx = false;
return false; return false;
@ -218,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;
@ -227,14 +230,17 @@ bool CModule::detachModule()
g_ModuleCallReason = ModuleCall_NotCalled; g_ModuleCallReason = ModuleCall_NotCalled;
} }
} }
#ifndef FAKEMETA #ifndef FAKEMETA
if (IsMetamod()) if (IsMetamod())
{ {
UnloadMetamodPlugin(m_Handle); UnloadMetamodPlugin(m_Handle);
} }
#endif #endif
DLFREE(m_Handle); DLFREE(m_Handle);
clear(); clear();
return true; return true;
} }
@ -247,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";
@ -270,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 ;]
@ -60,7 +61,6 @@ struct amxx_module_info_s
const char *logtag; //added in version 2 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 */
@ -71,8 +71,10 @@ struct amxx_module_info_s
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?
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,12 +86,15 @@ public:
~CModule(); ~CModule();
// Interface // Interface
bool attachModule(); bool attachModule();
bool queryModule(); bool queryModule();
bool detachModule(); bool detachModule();
#ifndef FAKEMETA #ifndef FAKEMETA
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now); bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
#endif #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_InfoNew.author; } inline const char* getAuthor() const { return m_InfoNew.author; }
@ -97,18 +102,16 @@ public:
inline const char* getName() const { return m_InfoNew.name; } inline const char* getName() const { return m_InfoNew.name; }
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_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); } 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; } 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 #endif //CMODULE_H

View File

@ -35,17 +35,24 @@
#include "CFile.h" #include "CFile.h"
#include "amx.h" #include "amx.h"
#include "natives.h" #include "natives.h"
#include "debugger.h"
extern const char *no_function; extern const char *no_function;
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug) { CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
{
CPlugin** a = &head; 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;
@ -56,9 +63,10 @@ void CPluginMngr::Finalize()
{ {
if (m_Finalized) if (m_Finalized)
return; return;
pNatives = BuildNativeTable();
pNatives = BuildNativeTable();
CPlugin *a = head; CPlugin *a = head;
while (a) while (a)
{ {
if (a->getStatusCode() == ps_running) if (a->getStatusCode() == ps_running)
@ -66,19 +74,20 @@ void CPluginMngr::Finalize()
amx_Register(a->getAMX(), pNatives, -1); amx_Register(a->getAMX(), pNatives, -1);
a->Finalize(); a->Finalize();
} }
a=a->next; a = a->next;
} }
m_Finalized = true; m_Finalized = true;
} }
int CPluginMngr::loadPluginsFromFile( const char* filename ) int CPluginMngr::loadPluginsFromFile(const char* filename)
{ {
char file[256]; char file[256];
FILE *fp = fopen(build_pathname_r(file, sizeof(file)-1, "%s",filename) , "rt"); FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
if ( !fp ) if (!fp)
{ {
AMXXLOG_Log( "[AMXX] Plugins list not found (file \"%s\")",filename); AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
return 1; return 1;
} }
@ -89,22 +98,26 @@ int CPluginMngr::loadPluginsFromFile( const char* filename )
String line; String line;
while ( !feof(fp) ) while (!feof(fp))
{ {
pluginName[0] = '\0'; pluginName[0] = '\0';
debug[0] = '\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)
{ {
@ -120,11 +133,15 @@ 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; m_Finalized = false;
if (pNatives) if (pNatives)
{ {
delete [] pNatives; delete [] pNatives;
@ -134,35 +151,51 @@ void CPluginMngr::clear() {
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 (m_Debug) if (m_Debug)
@ -178,33 +211,41 @@ 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 file[256]; char file[256];
char* path = build_pathname_r(file, sizeof(file)-1, "%s/%s",p,n); char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
code = 0; code = 0;
memset(&amx, 0, sizeof(AMX)); memset(&amx, 0, sizeof(AMX));
int err = load_amxscript(&amx,&code,path,e, d); int err = load_amxscript(&amx, &code, path, e, d);
if ( err == AMX_ERR_NONE )
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;
if (status == ps_running) if (status == ps_running)
{ {
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause"); m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause"); m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
if (amx.flags & AMX_FLAG_DEBUG) if (amx.flags & AMX_FLAG_DEBUG)
{ {
m_Debug = true; m_Debug = true;
@ -214,51 +255,108 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e, int d
} }
} }
CPluginMngr::CPlugin::~CPlugin( ) CPluginMngr::CPlugin::~CPlugin()
{ {
unload_amxscript( &amx, &code ); unload_amxscript(&amx, &code);
}
int AMXAPI native_handler(AMX *amx, int index)
{
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
char name[sNAMEMAX + 1];
amx_GetNative(amx, index, name);
return pHandler->HandleNative(name, index, 0);
}
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
{
//A script has accidentally called an invalid native! give them a
// first chance to block the resulting error.
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
//this should never happen
if (!pHandler)
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
//this should never happen because this native won't be called
// if the plugin isn't filtering.
if (!pHandler->IsNativeFiltering())
{
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
return 0;
}
char name[sNAMEMAX + 1];
int native = 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() void CPluginMngr::CPlugin::Finalize()
{ {
char buffer[128]; char buffer[128];
int old_status = status; int old_status = status;
if (CheckModules(&amx, buffer)) if (CheckModules(&amx, buffer))
{ {
if ( amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE ) if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
{
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
int res = 0;
if (pHandler->IsNativeFiltering())
res = amx_CheckNatives(&amx, native_handler);
if (!res)
{ {
status = ps_bad_load; status = ps_bad_load;
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function); sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
errorMsg.assign(buffer); errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND; amx.error = AMX_ERR_NOTFOUND;
} else {
amx_RegisterToAny(&amx, invalid_native);
}
} }
} else { } else {
status = ps_bad_load; status = ps_bad_load;
errorMsg.assign(buffer); errorMsg.assign(buffer);
amx.error = AMX_ERR_NOTFOUND; amx.error = AMX_ERR_NOTFOUND;
} }
if (old_status != status) if (old_status != status)
{ {
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str()); AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
} }
} }
void CPluginMngr::CPlugin::pauseFunction( int id ) { void CPluginMngr::CPlugin::pauseFunction(int id)
if (isValid()){ {
paused_fun |= (1<<id);
g_commands.clearBufforedInfo();
}
} }
void CPluginMngr::CPlugin::unpauseFunction( int id ) { void CPluginMngr::CPlugin::unpauseFunction(int id)
if (isValid()) { {
paused_fun &= ~(1<<id);
g_commands.clearBufforedInfo();
}
} }
void CPluginMngr::CPlugin::setStatus( int a ) { void CPluginMngr::CPlugin::setStatus(int a)
{
status = a; status = a;
g_commands.clearBufforedInfo(); // ugly way g_commands.clearBufforedInfo(); // ugly way
} }
@ -282,8 +380,8 @@ 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
if (m_UnpauseFwd != -1) if (m_UnpauseFwd != -1)
executeForwards(m_UnpauseFwd); executeForwards(m_UnpauseFwd);

View File

@ -36,18 +36,18 @@
// class CPluginMngr // class CPluginMngr
// ***************************************************** // *****************************************************
enum { enum
{
ps_bad_load, ps_bad_load,
ps_error, ps_error,
ps_paused,
ps_running,
ps_stopped,
ps_locked, ps_locked,
ps_paused,
ps_stopped,
ps_running,
}; };
class CPluginMngr class CPluginMngr
{ {
public: public:
class iterator; class iterator;
@ -59,23 +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_PauseFwd;
int m_UnpauseFwd; 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; 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();}
@ -85,20 +87,21 @@ 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_running) && (status != ps_locked)); } inline bool isValid() const { return (status >= ps_paused); }
inline bool isPaused() const { return ( (status == ps_paused) ); } 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()); }
void Finalize(); 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; } inline bool isDebug() const { return m_Debug; }
}; };
@ -106,8 +109,6 @@ public:
private: private:
CPlugin *head; CPlugin *head;
int pCounter; int pCounter;
public: public:
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;} CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
~CPluginMngr() { clear(); } ~CPluginMngr() { clear(); }
@ -118,17 +119,20 @@ public:
// 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 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) {}
@ -138,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

View File

@ -43,27 +43,32 @@ public:
T item; T item;
CStackItem *prev; CStackItem *prev;
}; };
public: public:
CStack() CStack()
{ {
mSize = 0; mSize = 0;
mStack = NULL; mStack = NULL;
} }
~CStack() ~CStack()
{ {
CStackItem *p, *t; CStackItem *p, *t;
p = mStack; p = mStack;
while (p) while (p)
{ {
t = p->prev; t = p->prev;
delete p; delete p;
p = t; p = t;
} }
mStack = NULL; mStack = NULL;
} }
bool empty() bool empty()
{ {
return (mSize==0); return (mSize == 0);
} }
void push(const T & v) void push(const T & v)
@ -98,4 +103,3 @@ private:
}; };
#endif //_INCLUDE_CQUEUE_H #endif //_INCLUDE_CQUEUE_H

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;
@ -53,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;
@ -117,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)
@ -129,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
{ {
@ -140,18 +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)
{ {
clear(); // hamster clear();
} else {
m_fNextExecTime += m_fBase;
} }
} }
} }
@ -182,6 +206,7 @@ CTaskMngr::CTask::~CTask()
} }
/*********************** CTaskMngr ***********************/ /*********************** CTaskMngr ***********************/
CTaskMngr::CTaskMngr() CTaskMngr::CTaskMngr()
{ {
m_pTmr_CurrentTime = NULL; m_pTmr_CurrentTime = NULL;
@ -205,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);
} }
@ -225,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;
} }
@ -239,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);
@ -247,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,16 +94,16 @@ 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;
@ -110,13 +113,13 @@ public:
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

@ -70,32 +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)
{ {
size_t end = (m_Size < size) ? (m_Size) : size; size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
for (size_t i=0; i<end; i++) for (size_t i=0; i<end; i++)
newData[i] = m_Data[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
{ {
@ -189,7 +215,7 @@ public:
iterator & operator-=(size_t offset) iterator & operator-=(size_t offset)
{ {
m_Ptr += offset; m_Ptr -= offset;
return (*this); return (*this);
} }
@ -203,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;
} }
@ -277,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);
} }
@ -296,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)
@ -317,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;
} }
@ -397,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())
@ -414,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__

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe OPT_FLAGS = -O2 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc CPP = gcc
NAME = amxmodx_mm NAME = amxmodx_mm
@ -15,7 +15,7 @@ OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \ 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 \ 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 \ amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp \ CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp
LINK = -lz LINK = -lz
@ -31,16 +31,16 @@ else
endif endif
ifeq "$(MMGR)" "true" ifeq "$(MMGR)" "true"
OBJECTS += MMGR/MMGR.CPP OBJECTS += mmgr/mmgr.cpp
CFLAGS += -DMEMORY_TEST
endif endif
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
OBJECTS += JIT/natives-amd64.o OBJECTS += JIT/natives-amd64.o
LINK += -lstdc++
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o

View File

@ -10,7 +10,7 @@
* including commercial applications, and to alter it and redistribute it * including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions: * freely, subject to the following restrictions:
* *
* 1. The origin of this software must not be misrepresented; you must not * 1. The origin of this software must not be misreprfesented; you must not
* claim that you wrote the original software. If you use this software in * claim that you wrote the original software. If you use this software in
* a product, an acknowledgment in the product documentation would be * a product, an acknowledgment in the product documentation would be
* appreciated but is not required. * appreciated but is not required.
@ -425,10 +425,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
AMX_FUNCSTUB *func; AMX_FUNCSTUB *func;
AMX_NATIVE f; AMX_NATIVE f;
assert(amx!=NULL);
hdr=(AMX_HEADER *)amx->base; hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries); assert(hdr->natives<=hdr->libraries);
#if defined AMX_NATIVETABLE #if defined AMX_NATIVETABLE
if (index<NULL) { if (index<NULL) {
@ -444,34 +441,10 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
#endif #endif
assert(f!=NULL); assert(f!=NULL);
/* Now that we have found the function, patch the program so that any /* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
* subsequent call will call the function directly (bypassing this * Otherwise, we'd have no way of knowing the last native to be used.
* callback).
* This trick cannot work in the JIT, because the program would need to
* be re-JIT-compiled after patching a P-code instruction.
*/ */
#if defined JIT && !defined NDEBUG amx->usertags[UT_NATIVE] = (long)index;
if ((amx->flags & AMX_FLAG_JITC)!=0)
assert(amx->sysreq_d==0);
#endif
if (amx->sysreq_d!=0) {
/* at the point of the call, the CIP pseudo-register points directly
* behind the SYSREQ instruction and its parameter.
*/
unsigned char *code=amx->base+(int)hdr->cod+(int)amx->cip-4;
assert(amx->cip >= 4 && amx->cip < (hdr->dat - hdr->cod));
assert(sizeof(f)<=sizeof(cell)); /* function pointer must fit in a cell */
#if defined __GNUC__ || defined ASM32
if (*(cell*)code==index) {
#else
if (*(cell*)code!=OP_SYSREQ_PRI) {
assert(*(cell*)(code-sizeof(cell))==OP_SYSREQ_C);
assert(*(cell*)code==index);
#endif
*(cell*)(code-sizeof(cell))=amx->sysreq_d;
*(cell*)code=(cell)f;
} /* if */
} /* if */
/* Note: /* Note:
* params[0] == number of bytes for the additional parameters passed to the native function * params[0] == number of bytes for the additional parameters passed to the native function
@ -480,7 +453,9 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
*/ */
amx->error=AMX_ERR_NONE; amx->error=AMX_ERR_NONE;
*result = f(amx,params); *result = f(amx,params);
return amx->error; return amx->error;
} }
#endif /* defined AMX_INIT */ #endif /* defined AMX_INIT */
@ -547,6 +522,7 @@ static int amx_BrowseRelocate(AMX *amx)
*/ */
if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell)) if ((amx->flags & AMX_FLAG_JITC)==0 && sizeof(AMX_NATIVE)<=sizeof(cell))
amx->sysreq_d=opcode_list[OP_SYSREQ_D]; amx->sysreq_d=opcode_list[OP_SYSREQ_D];
amx->userdata[UD_OPCODELIST] = (void *)opcode_list;
#else #else
/* ANSI C /* ANSI C
* to use direct system requests, a function pointer must fit in a cell; * to use direct system requests, a function pointer must fit in a cell;
@ -554,6 +530,7 @@ static int amx_BrowseRelocate(AMX *amx)
*/ */
if (sizeof(AMX_NATIVE)<=sizeof(cell)) if (sizeof(AMX_NATIVE)<=sizeof(cell))
amx->sysreq_d=OP_SYSREQ_D; amx->sysreq_d=OP_SYSREQ_D;
amx->userdata[UD_OPCODELIST] = (long)NULL;
#endif #endif
/* start browsing code */ /* start browsing code */
@ -1081,7 +1058,9 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
/* JIT rulz! (TM) */ /* JIT rulz! (TM) */
/* MP: added check for correct compilation */ /* MP: added check for correct compilation */
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) != 0) { //Fixed bug (thanks T(+)rget)
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0)
{
/* update the required memory size (the previous value was a /* update the required memory size (the previous value was a
* conservative estimate, now we know the exact size) * conservative estimate, now we know the exact size)
*/ */
@ -1561,6 +1540,61 @@ static AMX_NATIVE findfunction(const char *name, const AMX_NATIVE_INFO *list, in
} }
const char *no_function; const char *no_function;
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,res=0;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address==0) {
/* this function is not yet located */
res=nf(amx,i);
if (!res)
{
no_function = GETENTRYNAME(hdr,func);
return 0;
}
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
return 1;
}
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f)
{
AMX_FUNCSTUB *func;
AMX_HEADER *hdr;
int i,numnatives,err;
hdr=(AMX_HEADER *)amx->base;
assert(hdr!=NULL);
assert(hdr->magic==AMX_MAGIC);
assert(hdr->natives<=hdr->libraries);
numnatives=NUMENTRIES(hdr,natives,libraries);
err=AMX_ERR_NONE;
func=GETENTRY(hdr,natives,0);
for (i=0; i<numnatives; i++) {
if (func->address==0) {
/* this function is not yet located */
func->address=(ucell)f;
} /* if */
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
} /* for */
if (err==AMX_ERR_NONE)
amx->flags|=AMX_FLAG_NTVREG;
return err;
}
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number) int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
{ {
AMX_FUNCSTUB *func; AMX_FUNCSTUB *func;
@ -1674,7 +1708,13 @@ int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char
#define SKIPPARAM(n) ( cip=(cell *)cip+(n) ) #define SKIPPARAM(n) ( cip=(cell *)cip+(n) )
#define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v ) #define PUSH(v) ( stk-=sizeof(cell), *(cell *)(data+(int)stk)=v )
#define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) ) #define POP(v) ( v=*(cell *)(data+(int)stk), stk+=sizeof(cell) )
#define ABORT(amx,v) { (amx)->stk=reset_stk; (amx)->hea=reset_hea; return v; } #define ABORT(amx,v) { (amx)->stk=reset_stk; \
(amx)->hea=reset_hea; \
(amx)->cip=(cell)cip; \
(amx)->pri=pri; \
(amx)->alt=alt; \
return v; \
}
#define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR #define CHKMARGIN() if (hea+STKMARGIN>stk) return AMX_ERR_STACKERR
#define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW #define CHKSTACK() if (stk>amx->stp) return AMX_ERR_STACKLOW
@ -2469,6 +2509,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) { if (num==AMX_ERR_SLEEP) {
@ -2488,6 +2530,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) { if (num==AMX_ERR_SLEEP) {
@ -2507,6 +2551,8 @@ static const void * const amx_opcodelist[] = {
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
if (amx->error!=AMX_ERR_NONE) { if (amx->error!=AMX_ERR_NONE) {
if (amx->error==AMX_ERR_SLEEP) { if (amx->error==AMX_ERR_SLEEP) {
@ -2576,6 +2622,8 @@ static const void * const amx_opcodelist[] = {
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->hea=hea; amx->hea=hea;
amx->pri=pri;
amx->alt=alt;
amx->cip=(cell)((unsigned char*)cip-code); amx->cip=(cell)((unsigned char*)cip-code);
num=amx->debug(amx); num=amx->debug(amx);
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {
@ -3443,6 +3491,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk)); num=amx->callback(amx,pri,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) { if (num==AMX_ERR_SLEEP) {
@ -3462,6 +3512,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk)); num=amx->callback(amx,offs,&pri,(cell *)(data+(int)stk));
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {
if (num==AMX_ERR_SLEEP) { if (num==AMX_ERR_SLEEP) {
@ -3481,6 +3533,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->hea=hea; amx->hea=hea;
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->pri=pri;
amx->alt=alt;
pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk)); pri=((AMX_NATIVE)offs)(amx,(cell *)(data+(int)stk));
if (amx->error!=AMX_ERR_NONE) { if (amx->error!=AMX_ERR_NONE) {
if (amx->error==AMX_ERR_SLEEP) { if (amx->error==AMX_ERR_SLEEP) {
@ -3544,6 +3598,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
amx->frm=frm; amx->frm=frm;
amx->stk=stk; amx->stk=stk;
amx->hea=hea; amx->hea=hea;
amx->pri=pri;
amx->alt=alt;
amx->cip=(cell)((unsigned char*)cip-code); amx->cip=(cell)((unsigned char*)cip-code);
num=amx->debug(amx); num=amx->debug(amx);
if (num!=AMX_ERR_NONE) { if (num!=AMX_ERR_NONE) {

View File

@ -166,6 +166,7 @@ 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_NATIVE_FILTER)(struct tagAMX *amx, int index);
#if !defined _FAR #if !defined _FAR
#define _FAR #define _FAR
#endif #endif
@ -242,6 +243,7 @@ typedef struct tagAMX {
long usertags[AMX_USERNUM] PACKED; long usertags[AMX_USERNUM] PACKED;
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer //okay userdata[3] in AMX Mod X is for the CPlugin * pointer
//we're also gonna set userdata[2] to a special debug structure //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;
@ -300,6 +302,7 @@ enum {
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_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 */
@ -335,23 +338,11 @@ enum {
#define AMX_COMPACTMARGIN 64 #define AMX_COMPACTMARGIN 64
#endif #endif
struct amx_trace #define UD_FINDPLUGIN 3
{ #define UD_DEBUGGER 2
cell frm; #define UD_OPCODELIST 1
amx_trace *prev; #define UD_HANDLER 0
amx_trace *next; #define UT_NATIVE 3
bool used;
};
struct AMX_DBGINFO
{
void *pDebug; //Pointer to debug data
int error; //non-amx_Exec() error setting
amx_trace *pTrace; //Pointer to stack trace
amx_trace *pTraceFrm;
amx_trace *pTraceEnd;
cell frm;
};
/* 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_
@ -385,6 +376,7 @@ uint32_t * AMXAPI amx_Align32(uint32_t *v);
#endif #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_Exec(AMX *amx, cell *retval, int index); int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
@ -414,6 +406,7 @@ int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar); int AMXAPI amx_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, const 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);

View File

@ -129,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]
@ -1196,8 +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
mov eax,ebx ; return the parameter of the HALT opcode _ABORT ebx
jmp _return
OP_BOUNDS: OP_BOUNDS:
@ -1221,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
@ -1251,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
@ -1293,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
@ -1416,7 +1437,7 @@ OP_BREAK:
mov [ebp+_error],eax ; save EAX (error code) before restoring all regs mov [ebp+_error],eax ; save EAX (error code) before restoring all regs
_RESTOREREGS ; abort run, but restore stack first _RESTOREREGS ; abort run, but restore stack first
mov eax,[ebp+_error] ; get error code in EAX back again mov eax,[ebp+_error] ; get error code in EAX back again
jmp _return ; return error code _FASTABORT
break_noabort: break_noabort:
_RESTOREREGS _RESTOREREGS
mov eax,[ebp+_pri] ; restore PRI and ALT mov eax,[ebp+_pri] ; restore PRI and ALT
@ -1425,43 +1446,34 @@ OP_BREAK:
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 parameters, 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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,6 @@
#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>
@ -45,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"
@ -69,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.50" #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
@ -110,30 +108,33 @@ 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, ...); 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;
}; };
@ -150,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;
@ -176,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;
@ -224,14 +227,15 @@ 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, PLUG_LOADTIME now); int loadModules(const char* filename, PLUG_LOADTIME now);
void detachModules(); void detachModules();
void detachReloadModules(); void detachReloadModules();
#ifdef FAKEMETA #ifdef FAKEMETA
void attachModules(); void attachModules();
#endif #endif
// Count modules // Count modules
@ -245,26 +249,28 @@ enum CountModulesMode
int countModules(CountModulesMode mode); int countModules(CountModulesMode mode);
void modules_callPluginsLoaded(); void modules_callPluginsLoaded();
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* 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, ...);
@ -279,6 +285,7 @@ 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
void Module_CacheFunctions(); void Module_CacheFunctions();
void Module_UncacheFunctions(); void Module_UncacheFunctions();
@ -301,7 +308,7 @@ extern int FF_ClientAuthorized;
extern bool g_coloredmenus; extern bool g_coloredmenus;
#ifdef FAKEMETA #ifdef FAKEMETA
extern CFakeMeta g_FakeMeta; extern CFakeMeta g_FakeMeta;
#endif #endif
struct func_s struct func_s
@ -311,4 +318,3 @@ struct func_s
}; };
#endif // AMXMODX_H #endif // AMXMODX_H

View File

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

@ -95,4 +95,3 @@ public:
}; };
#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,29 +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)
{ {
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);
} }
@ -123,12 +129,13 @@ void CLog::MapChange()
// create dir if not existing // create dir if not existing
char file[256]; char file[256];
#ifdef __linux #ifdef __linux
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str()), 0700); mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
#else #else
mkdir(build_pathname_r(file, sizeof(file)-1,"%s", g_log_dir.c_str())); mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
#endif #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");
@ -143,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;
@ -152,6 +159,7 @@ void CLog::MapChange()
void CLog::Log(const char *fmt, ...) void CLog::Log(const char *fmt, ...)
{ {
static char file[256]; static char file[256];
if (m_LogType == 1 || m_LogType == 2) if (m_LogType == 1 || m_LogType == 2)
{ {
// get time // get time
@ -178,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());
@ -185,19 +194,16 @@ void CLog::Log(const char *fmt, ...)
return; return;
} }
} }
} } else {
else
{
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday); 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+"); pF = fopen(file, "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", file);
m_LogType = 0; m_LogType = 0;
return; return;

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

@ -32,8 +32,8 @@
#define __FAKEMETA_H__ #define __FAKEMETA_H__
#ifndef FAKEMETA #ifndef FAKEMETA
int UnloadMetamodPlugin(void *handle); int UnloadMetamodPlugin(void *handle);
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now); int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
#else #else
// Fake metamod api for modules // Fake metamod api for modules
@ -42,7 +42,8 @@ int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
// 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),
@ -55,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:
@ -100,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
@ -232,4 +231,3 @@ extern CFakeMeta g_FakeMeta;
#endif //FAKEMETA #endif //FAKEMETA
#endif // #ifndef __FAKEMETA_H__ #endif // #ifndef __FAKEMETA_H__

View File

@ -5,7 +5,7 @@
* *
* *
* 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<EFBFBD> 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
* your option) any later version. * your option) any later version.
* *
@ -62,12 +62,14 @@ class AutoFilePtr
FILE *m_FP; FILE *m_FP;
public: public:
AutoFilePtr(FILE *fp) : m_FP(fp) AutoFilePtr(FILE *fp) : m_FP(fp)
{ } {}
~AutoFilePtr() ~AutoFilePtr()
{ {
if (m_FP) if (m_FP)
fclose(m_FP); fclose(m_FP);
} }
operator FILE* () operator FILE* ()
{ {
return m_FP; return m_FP;
@ -80,20 +82,26 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
int a; int a;
struct dirent *ep; struct dirent *ep;
DIR *dp; DIR *dp;
char* dirname = build_pathname("%s",get_amxstring(amx,params[1],0,a) ); char* dirname = build_pathname("%s", get_amxstring(amx, params[1], 0, a));
a = params[2]; a = params[2];
if ( (dp = opendir (dirname)) == NULL )
if ((dp = opendir (dirname)) == NULL)
return 0; return 0;
seekdir( dp , a );
if ( (ep = readdir (dp)) != NULL ) { seekdir(dp, a);
cell *length = get_amxaddr(amx,params[5]);
*length = set_amxstring(amx,params[3], ep->d_name ,params[4]); if ((ep = readdir (dp)) != NULL)
a = telldir( dp ); {
} cell *length = get_amxaddr(amx, params[5]);
else *length = set_amxstring(amx, params[3], ep->d_name, params[4]);
a = telldir(dp);
} else
a = 0; a = 0;
closedir (dp); closedir (dp);
return a; return a;
#else #else
int tmp; int tmp;
char *dirname = build_pathname("%s/*", get_amxstring(amx, params[1], 0, tmp)); char *dirname = build_pathname("%s/*", get_amxstring(amx, params[1], 0, tmp));
@ -101,10 +109,12 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
_finddata_t fd; _finddata_t fd;
intptr_t handle = _findfirst(dirname, &fd); intptr_t handle = _findfirst(dirname, &fd);
if (handle < 0) if (handle < 0)
return 0; return 0;
++tmp; ++tmp;
for (int i = 0; i < tmp; ++i) for (int i = 0; i < tmp; ++i)
{ {
if (_findnext(handle, &fd) < 0) if (_findnext(handle, &fd) < 0)
@ -113,8 +123,9 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
break; break;
} }
} }
// current data in fd // current data in fd
cell *length = get_amxaddr(amx,params[5]); // pointer to the outLen parameter cell *length = get_amxaddr(amx, params[5]); // pointer to the outLen parameter
*length = set_amxstring(amx, params[3], fd.name, params[4]); // set output and outLen parameters *length = set_amxstring(amx, params[3], fd.name, params[4]); // set output and outLen parameters
_findclose(handle); _findclose(handle);
@ -125,61 +136,82 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */ static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
{ {
int iLen; int iLen;
char* szFile = get_amxstring(amx,params[1],0,iLen); char* szFile = get_amxstring(amx, params[1], 0, iLen);
FILE*fp; FILE *fp;
if ( (fp =fopen(build_pathname("%s",szFile),"r")) == NULL) {
amx_RaiseError(amx,AMX_ERR_NATIVE); if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL)
{
amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
char buffor[1024]; char buffor[1024];
int i = 0, iLine = params[2]; int i = 0, iLine = params[2];
while((i <= iLine) && fgets(buffor,1023,fp) )
while ((i <= iLine) && fgets(buffor, 1023, fp))
i++; i++;
fclose(fp); fclose(fp);
if (i > iLine){
if (i > iLine)
{
int len = strlen(buffor); int len = strlen(buffor);
if (buffor[len-1]=='\n')
buffor[--len]=0; if (buffor[len - 1] == '\n')
if (buffor[len-1]=='\r') buffor[--len] = 0;
buffor[--len]=0;
cell *length = get_amxaddr(amx,params[5]); if (buffor[len - 1] == '\r')
*length = set_amxstring(amx,params[3],buffor,params[4]); buffor[--len] = 0;
cell *length = get_amxaddr(amx, params[5]);
*length = set_amxstring(amx, params[3], buffor, params[4]);
return i; return i;
} }
return 0; return 0;
} }
static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
{ {
int i; int i;
char* sFile = build_pathname("%s", get_amxstring(amx,params[1],0,i) ); char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, i));
char* sText = get_amxstring(amx,params[2],0,i); char* sText = get_amxstring(amx, params[2], 0, i);
FILE* pFile; FILE* pFile;
int iLine = params[3]; int iLine = params[3];
// apending to the end // apending to the end
if (iLine < 0) { if (iLine < 0)
if ( (pFile = fopen( sFile ,"a")) == NULL ){ {
amx_RaiseError(amx,AMX_ERR_NATIVE); if ((pFile = fopen(sFile, "a")) == NULL)
{
amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
fputs( sText , pFile );
fputc( '\n', pFile ); fputs(sText, pFile);
fclose( pFile ); fputc('\n', pFile);
fclose(pFile);
return 1; return 1;
} }
// creating a new file with a line in a middle // creating a new file with a line in a middle
if ( (pFile = fopen(sFile,"r")) == NULL ) { if ((pFile = fopen(sFile, "r")) == NULL)
if ( (pFile = fopen(sFile,"w")) == NULL ){ {
amx_RaiseError(amx,AMX_ERR_NATIVE); if ((pFile = fopen(sFile, "w")) == NULL)
{
amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
for(i=0;i < iLine;++i)
fputc('\n',pFile); for (i = 0; i < iLine; ++i)
fputs( sText , pFile ); fputc('\n', pFile);
fputc( '\n', pFile );
fputs(sText, pFile);
fputc('\n', pFile);
fclose(pFile); fclose(pFile);
return 1; return 1;
} }
@ -187,68 +219,84 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
FILE* pTemp; FILE* pTemp;
char buffor[2048]; char buffor[2048];
if ( (pTemp = tmpfile()) == NULL ){ if ((pTemp = tmpfile()) == NULL)
amx_RaiseError(amx,AMX_ERR_NATIVE); {
amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
for(i=0;;++i){ for (i = 0; ; ++i)
if ( i == iLine ){ {
fgets(buffor,2047,pFile); if (i == iLine)
fputs( sText , pTemp ); {
fputc( '\n', pTemp ); fgets(buffor, 2047, pFile);
fputs(sText, pTemp);
fputc('\n', pTemp);
} }
else if ( fgets(buffor,2047,pFile) ){ else if (fgets(buffor, 2047, pFile))
fputs(buffor , pTemp ); {
fputs(buffor, pTemp);
} }
else if ( i < iLine ) { else if (i < iLine)
fputc( '\n', pTemp ); {
fputc('\n', pTemp);
} }
else break; else
break;
} }
fclose(pFile); fclose(pFile);
rewind(pTemp); rewind(pTemp);
// now rewrite because file can be now smaller... // now rewrite because file can be now smaller...
if ( (pFile = fopen(sFile,"w")) == NULL ){ if ((pFile = fopen(sFile, "w")) == NULL)
amx_RaiseError(amx,AMX_ERR_NATIVE); {
amx_RaiseError(amx, AMX_ERR_NATIVE);
return 0; return 0;
} }
while(fgets(buffor,2047,pTemp)) while (fgets(buffor, 2047, pTemp))
fputs(buffor,pFile ); fputs(buffor, pFile);
fclose(pTemp); fclose(pTemp);
fclose(pFile); fclose(pFile);
return 1; return 1;
} }
static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */
{ {
int iLen; int iLen;
char* sFile = get_amxstring(amx,params[1],0,iLen); char* sFile = get_amxstring(amx, params[1], 0, iLen);
return (unlink( build_pathname("%s",sFile) )?0:1);
return (unlink(build_pathname("%s", sFile)) ? 0 : 1);
} }
static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
{ {
int iLen; int iLen;
char *sFile = get_amxstring(amx,params[1],0,iLen); char *sFile = get_amxstring(amx, params[1], 0, iLen);
char *file = build_pathname("%s",sFile); char *file = build_pathname("%s", sFile);
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(file); DWORD attr = GetFileAttributes(file);
if (attr == INVALID_FILE_ATTRIBUTES) if (attr == INVALID_FILE_ATTRIBUTES)
return 0; return 0;
if (attr == FILE_ATTRIBUTE_DIRECTORY) if (attr == FILE_ATTRIBUTE_DIRECTORY)
return 0; return 0;
return 1; return 1;
#else #else
struct stat s; struct stat s;
if (stat(file, &s) != 0) if (stat(file, &s) != 0)
return 0; return 0;
if (S_ISDIR(s.st_mode)) if (S_ISDIR(s.st_mode))
return 0; return 0;
return 1; return 1;
#endif #endif
} }
@ -256,21 +304,28 @@ static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
{ {
int iLen; int iLen;
char *sFile = get_amxstring(amx,params[1],0,iLen); char *sFile = get_amxstring(amx, params[1], 0, iLen);
char *file = build_pathname("%s",sFile); char *file = build_pathname("%s", sFile);
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(file); DWORD attr = GetFileAttributes(file);
if (attr == INVALID_FILE_ATTRIBUTES) if (attr == INVALID_FILE_ATTRIBUTES)
return 0; return 0;
if (attr == FILE_ATTRIBUTE_DIRECTORY) if (attr == FILE_ATTRIBUTE_DIRECTORY)
return 1; return 1;
return 0; return 0;
#else #else
struct stat s; struct stat s;
if (stat(file, &s) != 0) if (stat(file, &s) != 0)
return 0; return 0;
if (S_ISDIR(s.st_mode)) if (S_ISDIR(s.st_mode))
return 1; return 1;
return 0; return 0;
#endif #endif
} }
@ -278,24 +333,26 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
{ {
int iLen; int iLen;
char* sFile = get_amxstring(amx,params[1],0,iLen); char* sFile = get_amxstring(amx, params[1], 0, iLen);
AutoFilePtr fp(fopen(build_pathname("%s",sFile),"r")); AutoFilePtr fp(fopen(build_pathname("%s", sFile), "r"));
if ( fp != NULL)
if (fp != NULL)
{ {
if ( params[0] < 2 || params[2] == 0 ) if (params[0] < 2 || params[2] == 0)
{ {
fseek(fp,0,SEEK_END); fseek(fp, 0, SEEK_END);
int size = ftell(fp); int size = ftell(fp);
return size; return size;
} }
else if ( params[2] == 1 ) else if (params[2] == 1)
{ {
int a = 0,lines = 0; int a = 0,lines = 0;
while( a != EOF )
while (a != EOF)
{ {
++lines; ++lines;
while ( (a = fgetc(fp)) != '\n' && a != EOF ) while ((a = fgetc(fp)) != '\n' && a != EOF);
;
} }
//int a, b = '\n'; //int a, b = '\n';
//while( (a = fgetc(fp)) != EOF ){ //while( (a = fgetc(fp)) != EOF ){
@ -307,13 +364,17 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
// ++lines; // ++lines;
return lines; return lines;
} }
else if ( params[2] == 2 ){ else if (params[2] == 2)
fseek(fp,-1,SEEK_END); {
if ( fgetc(fp) == '\n' ) fseek(fp, -1, SEEK_END);
if (fgetc(fp) == '\n')
return 1; return 1;
return 0; return 0;
} }
} }
return -1; return -1;
} }
@ -322,17 +383,19 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
{ {
unsigned int i; unsigned int i;
int len, j=-1; int len, j = -1;
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len)); char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
char *flags = get_amxstring(amx, params[2], 0, len); char *flags = get_amxstring(amx, params[2], 0, len);
FILE *fp = fopen(file, flags); FILE *fp = fopen(file, flags);
if (fp == NULL) {
if (fp == NULL)
{
// Failed // Failed
return 0; return 0;
} }
for (i=0; i<FileList.size(); i++) for (i = 0; i < FileList.size(); i++)
{ {
if (FileList.at(i) == NULL) if (FileList.at(i) == NULL)
{ {
@ -340,7 +403,8 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
break; break;
} }
} }
if (j==-1)
if (j == -1)
{ {
FileList.push_back(fp); FileList.push_back(fp);
j = FileList.size() - 1; j = FileList.size() - 1;
@ -348,16 +412,20 @@ static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
FileList.at(j) = fp; FileList.at(j) = fp;
} }
return j+1; return j + 1;
} }
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) {
if (fp)
{
return fclose(fp); return fclose(fp);
} else { } else {
return -1; return -1;
@ -367,17 +435,24 @@ static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
char *buffer; char *buffer;
if (fp) {
if (fp)
{
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?) buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
fread(buffer, sizeof(char), params[3], fp); fread(buffer, sizeof(char), params[3], fp);
set_amxstring(amx, params[2], buffer, params[3]); set_amxstring(amx, params[2], buffer, params[3]);
delete [] buffer; delete [] buffer;
return 1; return 1;
} }
return -1; return -1;
} }
@ -385,10 +460,14 @@ static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) {
if (fp)
{
return fgetc(fp); return fgetc(fp);
} else { } else {
return -1; return -1;
@ -398,97 +477,128 @@ static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
char *buf; char *buf;
int len; int len;
if (fp) {
if (fp)
{
buf = format_amxstring(amx, params, 2, len); buf = format_amxstring(amx, params, 2, len);
return fwrite(buf, sizeof(char), strlen(buf), fp); return fwrite(buf, sizeof(char), strlen(buf), fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) {
if (feof(fp)) { if (fp)
{
if (feof(fp))
{
return 1; return 1;
} }
return 0; return 0;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) { if (fp)
{
return fseek(fp, (long)params[2], params[3]); return fseek(fp, (long)params[2], params[3]);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) { if (fp)
{
return fputc(params[2], fp); return fputc(params[2], fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) { if (fp)
{
rewind(fp); rewind(fp);
return 1; return 1;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) { if (fp)
{
return fflush(fp); return fflush(fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
char *buf; char *buf;
int len; int len;
buf = format_amxstring(amx, params, 2, len); buf = format_amxstring(amx, params, 2, len);
if (fp) {
if (fp)
{
return fscanf(fp, "%s", buf); return fscanf(fp, "%s", buf);
} }
@ -498,13 +608,17 @@ static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
if (fp) { if (fp)
{
return ftell(fp); return ftell(fp);
} }
return -1; return -1;
} }
#endif //UNUSED #endif //UNUSED
@ -514,12 +628,17 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
int len; int len;
char *file = build_pathname("%s", format_amxstring(amx, params, 1, len)); char *file = build_pathname("%s", format_amxstring(amx, params, 1, len));
long size; long size;
AutoFilePtr fp(fopen(file, "rb")); AutoFilePtr fp(fopen(file, "rb"));
if (fp) {
if (fp)
{
fseek(fp, 0, SEEK_END); fseek(fp, 0, SEEK_END);
size = ftell(fp); size = ftell(fp);
return size; return size;
} }
return -1; return -1;
} }
@ -527,116 +646,156 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
long t; long t;
if (fp) {
if (fp)
{
fread(&t, sizeof(long), 1, fp); fread(&t, sizeof(long), 1, fp);
return t; return t;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
int t; int t;
if (fp) {
if (fp)
{
fread(&t, sizeof(int), 1, fp); fread(&t, sizeof(int), 1, fp);
return t; return t;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
short t; short t;
if (fp) {
if (fp)
{
fread(&t, sizeof(short), 1, fp); fread(&t, sizeof(short), 1, fp);
return t; return t;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
short size = params[2]; short size = params[2];
if (fp) {
if (fp)
{
return fwrite(&size, sizeof(short), 1, fp); return fwrite(&size, sizeof(short), 1, fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
long size = params[2]; long size = params[2];
if (fp) {
if (fp)
{
return fwrite(&size, sizeof(long), 1, fp); return fwrite(&size, sizeof(long), 1, fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
int size = params[2]; int size = params[2];
if (fp) {
if (fp)
{
return fwrite(&size, sizeof(int), 1, fp); return fwrite(&size, sizeof(int), 1, fp);
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
float t; float t;
if (fp) {
if (fp)
{
fread(&t, sizeof(float), 1, fp); fread(&t, sizeof(float), 1, fp);
return *(cell*)&t; return *(cell*)&t;
} }
return -1; return -1;
} }
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params) static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
{ {
unsigned int id = params[1] - 1; unsigned int id = params[1] - 1;
if (id >= FileList.size() || FileList.at(id) == NULL) if (id >= FileList.size() || FileList.at(id) == NULL)
return 0; return 0;
FILE *fp = FileList.at(id); FILE *fp = FileList.at(id);
float size = *(float *)((void *)&params[2]); float size = *(float *)((void *)&params[2]);
if (fp) {
if (fp)
{
return fwrite(&size, sizeof(float), 1, fp); return fwrite(&size, sizeof(float), 1, fp);
} }
return -1; return -1;
} }
#endif //UNUSED #endif //UNUSED
@ -645,6 +804,7 @@ static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
{ {
int len; int len;
char *szPath = get_amxstring(amx, params[1], 0, len); char *szPath = get_amxstring(amx, params[1], 0, len);
return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]); return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]);
} }
@ -655,24 +815,32 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
char *dirname = build_pathname("%s\\*", path); char *dirname = build_pathname("%s\\*", path);
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
HANDLE hFile = FindFirstFile(dirname, &fd); HANDLE hFile = FindFirstFile(dirname, &fd);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
return 0; return 0;
set_amxstring(amx, params[2], fd.cFileName, params[3]); set_amxstring(amx, params[2], fd.cFileName, params[3]);
return (DWORD)hFile; return (DWORD)hFile;
#else #else
char *dirname = build_pathname("%s", path); char *dirname = build_pathname("%s", path);
DIR *dp = opendir(dirname); DIR *dp = opendir(dirname);
if (!dp) if (!dp)
return NULL; return NULL;
struct dirent *ep = readdir(dp); struct dirent *ep = readdir(dp);
if (!ep) if (!ep)
{ {
closedir(dp); closedir(dp);
return NULL; return NULL;
} }
set_amxstring(amx,params[2], ep->d_name,params[3]);
set_amxstring(amx, params[2], ep->d_name, params[3]);
return (cell)dp; return (cell)dp;
#endif #endif
} }
@ -681,14 +849,19 @@ static cell AMX_NATIVE_CALL amx_close_dir(AMX *amx, cell *params)
{ {
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
HANDLE hFile = (HANDLE)((DWORD)params[1]); HANDLE hFile = (HANDLE)((DWORD)params[1]);
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
return 0; return 0;
FindClose(hFile); FindClose(hFile);
return 1; return 1;
#else #else
DIR *dp = (DIR *)params[1]; DIR *dp = (DIR *)params[1];
if (!dp) if (!dp)
return 0; return 0;
closedir(dp); closedir(dp);
return 1; return 1;
#endif #endif
@ -698,64 +871,71 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
{ {
#if defined WIN32 || defined _WIN32 #if defined WIN32 || defined _WIN32
HANDLE hFile = (HANDLE)((DWORD)params[1]); HANDLE hFile = (HANDLE)((DWORD)params[1]);
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL) if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
return 0; return 0;
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
if (!FindNextFile(hFile, &fd)) if (!FindNextFile(hFile, &fd))
return 0; return 0;
set_amxstring(amx, params[2], fd.cFileName, params[3]); set_amxstring(amx, params[2], fd.cFileName, params[3]);
return 1; return 1;
#else #else
DIR *dp = (DIR *)params[1]; DIR *dp = (DIR *)params[1];
if (!dp) if (!dp)
return 0; return 0;
struct dirent *ep = readdir(dp); struct dirent *ep = readdir(dp);
if (!ep) if (!ep)
return 0; return 0;
set_amxstring(amx,params[2], ep->d_name,params[3]);
set_amxstring(amx, params[2], ep->d_name, params[3]);
return 1; return 1;
#endif #endif
} }
AMX_NATIVE_INFO file_Natives[] = { AMX_NATIVE_INFO file_Natives[] =
{ "delete_file", delete_file }, {
{ "file_exists", file_exists }, {"delete_file", delete_file},
{ "file_size", file_size }, {"file_exists", file_exists},
{ "read_dir", read_dir }, {"file_size", file_size},
{ "read_file", read_file }, {"read_dir", read_dir},
{ "write_file", write_file }, {"read_file", read_file},
{"write_file", write_file},
//Sanji's File Natives //Sanji's File Natives
{ "fopen", amx_fopen }, {"fopen", amx_fopen},
{ "fclose", amx_fclose }, {"fclose", amx_fclose},
{ "fread", amx_fread }, {"fread", amx_fread},
{ "filesize", amx_filesize }, {"filesize", amx_filesize},
#ifdef UNUSED #ifdef UNUSED
{ "fgetc", amx_fgetc }, {"fgetc", amx_fgetc},
{ "fwrite", amx_fwrite }, {"fwrite", amx_fwrite},
{ "feof", amx_feof }, {"feof", amx_feof},
{ "fseek", amx_fseek }, {"fseek", amx_fseek},
{ "fputc", amx_fputc }, {"fputc", amx_fputc},
{ "rewind", amx_rewind }, {"rewind", amx_rewind},
{ "fflush", amx_fflush }, {"fflush", amx_fflush},
{ "fscanf", amx_fscanf }, {"fscanf", amx_fscanf},
{ "ftell", amx_ftell }, {"ftell", amx_ftell},
{ "fgetl", amx_fgetl }, {"fgetl", amx_fgetl},
{ "fgeti", amx_fgeti }, {"fgeti", amx_fgeti},
{ "fgets", amx_fgets }, {"fgets", amx_fgets},
{ "fputs", amx_fputs }, {"fputs", amx_fputs},
{ "fputl", amx_fputl }, {"fputl", amx_fputl},
{ "fputi", amx_fputi }, {"fputi", amx_fputi},
{ "fgetf", amx_fgetf }, {"fgetf", amx_fgetf},
{ "fputf", amx_fputf }, {"fputf", amx_fputf},
#endif #endif
{ "unlink", delete_file }, {"unlink", delete_file},
{ "build_pathname", amx_build_pathname}, {"build_pathname", amx_build_pathname},
{ "dir_exists", dir_exists }, {"dir_exists", dir_exists},
{ "open_dir", amx_open_dir }, {"open_dir", amx_open_dir},
{ "close_dir", amx_close_dir }, {"close_dir", amx_close_dir},
{ "next_file", amx_get_dir }, {"next_file", amx_get_dir},
{NULL, NULL}
{ NULL, NULL }
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -49,5 +49,6 @@
#define STATIC_MODULE 1 #define STATIC_MODULE 1
int CheckModules(AMX *amx, char error[128]); int CheckModules(AMX *amx, char error[128]);
const char *StrCaseStr(const char *as, const char *bs);
#endif // __MODULES_H__ #endif // __MODULES_H__

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,11 +252,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="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" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb" ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
@ -371,6 +375,7 @@
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;ASM32;PAWN_CELL_SIZE=32" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
IgnoreStandardIncludePath="FALSE" IgnoreStandardIncludePath="FALSE"
@ -462,11 +467,12 @@
<Tool <Tool
Name="VCLinkerTool" Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386" AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj" 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" GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb" ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
@ -634,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>
@ -792,6 +801,9 @@
<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>
@ -837,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>

View File

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

View File

@ -29,13 +29,14 @@
*/ */
#include "amxmodx.h" #include "amxmodx.h"
#include <malloc.h>
#include <stdlib.h>
#include "CStack.h" #include "CStack.h"
#include "natives.h" #include "natives.h"
#ifdef __linux__ #ifdef __linux__
#include <malloc.h>
#include <stdlib.h>
#include <sys/mman.h> #include <sys/mman.h>
#include "sclinux.h"
#endif #endif
//Written by David "BAILOPAN" Anderson //Written by David "BAILOPAN" Anderson
@ -265,8 +266,7 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
int size = params[3]; int size = params[3];
while (size-->0) memcpy(dest, source, size * sizeof(cell));
*dest = *source;
return 1; return 1;
} }
@ -292,8 +292,7 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
int size = params[3]; int size = params[3];
while (size-->0) memcpy(dest, source, size * sizeof(cell));
*dest = *source;
return 1; return 1;
} }
@ -408,7 +407,7 @@ void ClearPluginLibraries()
for (size_t i=0; i<g_RegNatives.size(); i++) for (size_t i=0; i<g_RegNatives.size(); i++)
{ {
delete g_RegNatives[i]->pfn; delete [] g_RegNatives[i]->pfn;
delete g_RegNatives[i]; delete g_RegNatives[i];
} }
g_RegNatives.clear(); g_RegNatives.clear();
@ -423,7 +422,7 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
{"get_param", get_param}, {"get_param", get_param},
{"get_param_byref", get_param_byref}, {"get_param_byref", get_param_byref},
{"set_param_byref", set_param_byref}, {"set_param_byref", set_param_byref},
{"get_array", set_array}, {"get_array", get_array},
{"set_array", set_array}, {"set_array", set_array},
//these are dummy functions for floats ;p //these are dummy functions for floats ;p
{"get_param_f", get_param}, {"get_param_f", get_param},

View File

@ -1,3 +1,33 @@
/* 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 "amxmodx.h"
#include "newmenus.h" #include "newmenus.h"
@ -5,8 +35,9 @@ CVector<Menu *> g_NewMenus;
void ClearMenus() void ClearMenus()
{ {
for (size_t i=0; i<g_NewMenus.size(); i++) for (size_t i = 0; i < g_NewMenus.size(); i++)
delete g_NewMenus[i]; delete g_NewMenus[i];
g_NewMenus.clear(); g_NewMenus.clear();
} }
@ -19,8 +50,9 @@ Menu::Menu(const char *title, int mid, int tid)
Menu::~Menu() Menu::~Menu()
{ {
for (size_t i=0; i<m_Items.size(); i++) for (size_t i = 0; i < m_Items.size(); i++)
delete m_Items[i]; delete m_Items[i];
m_Items.clear(); m_Items.clear();
} }
@ -80,16 +112,21 @@ int Menu::PagekeyToItem(page_t page, item_t key)
if (page == 0) if (page == 0)
{ {
item_t rem = numItems >= 7 ? 7 : numItems; item_t rem = numItems >= 7 ? 7 : numItems;
if (key == rem) if (key == rem)
{ {
if (pages > 1) if (pages > 1)
return MENU_MORE; return MENU_MORE;
else else
return MENU_EXIT; return MENU_EXIT;
} else if (key == rem+1) { }
else if (key == rem + 1)
{
return MENU_EXIT; return MENU_EXIT;
} }
} else if (page == pages - 1) { }
else if (page == pages - 1)
{
//find number of remaining items //find number of remaining items
//for example, 11 items on page 1... means start=7, 11-7=4 //for example, 11 items on page 1... means start=7, 11-7=4
item_t rem = numItems - start; item_t rem = numItems - start;
@ -97,14 +134,18 @@ int Menu::PagekeyToItem(page_t page, item_t key)
if (key == rem) if (key == rem)
{ {
return MENU_EXIT; return MENU_EXIT;
} else if (key == rem+1) { }
else if (key == rem + 1)
{
return MENU_BACK; return MENU_BACK;
} }
} else { } else {
if (key == 7) if (key == 7)
{ {
return MENU_MORE; return MENU_MORE;
} else if (key == 8) { }
else if (key == 8)
{
return MENU_BACK; return MENU_BACK;
} }
} }
@ -147,9 +188,10 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
char buffer[255]; char buffer[255];
if (g_coloredmenus) if (g_coloredmenus)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page+1, pages); _snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
else else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page+1, pages); _snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
m_Text.append(buffer); m_Text.append(buffer);
item_t start = page * 7; item_t start = page * 7;
@ -162,15 +204,19 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
} }
menuitem *pItem = NULL; menuitem *pItem = NULL;
int option = 0; int option = 0;
keys = 0; keys = 0;
bool enabled = true; bool enabled = true;
int ret = 0; int ret = 0;
for (item_t i=start; i<end; i++)
for (item_t i = start; i < end; i++)
{ {
pItem = m_Items[i]; pItem = m_Items[i];
if (pItem->access && !(pItem->access & g_players[player].flags[0])) if (pItem->access && !(pItem->access & g_players[player].flags[0]))
enabled = false; enabled = false;
if (pItem->handler != -1) if (pItem->handler != -1)
{ {
ret = executeForwards(pItem->handler, player, thisId, i); ret = executeForwards(pItem->handler, player, thisId, i);
@ -179,6 +225,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
else if (ret == ITEM_DISABLED) else if (ret == ITEM_DISABLED)
enabled = false; enabled = false;
} }
if (pItem->pfn) if (pItem->pfn)
{ {
ret = (pItem->pfn)(player, thisId, i); ret = (pItem->pfn)(player, thisId, i);
@ -187,6 +234,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
else if (ret == ITEM_DISABLED) else if (ret == ITEM_DISABLED)
enabled = false; enabled = false;
} }
if (enabled) if (enabled)
{ {
keys |= (1<<option); keys |= (1<<option);
@ -202,6 +250,7 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
} }
m_Text.append(buffer); m_Text.append(buffer);
} }
//now for a weird part >:o //now for a weird part >:o
//this will either be MORE or BACK.. //this will either be MORE or BACK..
keys |= (1<<option++); keys |= (1<<option++);
@ -211,7 +260,9 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
} else { } else {
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit"); _snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
} }
m_Text.append(buffer); m_Text.append(buffer);
if (pages > 1) if (pages > 1)
{ {
keys |= (1<<option++); keys |= (1<<option++);
@ -241,6 +292,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
char *handler = get_amxstring(amx, params[2], 1, len); char *handler = get_amxstring(amx, params[2], 1, len);
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE); int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
if (func == -1) if (func == -1)
{ {
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler); LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
@ -248,7 +300,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
} }
int id = g_menucmds.registerMenuId(title, amx); int id = g_menucmds.registerMenuId(title, amx);
g_menucmds.registerMenuCmd( g_plugins.findPluginFast(amx), id, 1023, func ); g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size()); Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
g_NewMenus.push_back(pMenu); g_NewMenus.push_back(pMenu);
@ -363,6 +415,58 @@ static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
return id; 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[] = AMX_NATIVE_INFO g_NewMenuNatives[] =
{ {
{"menu_create", menu_create}, {"menu_create", menu_create},
@ -373,5 +477,8 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{"menu_find_id", menu_find_id}, {"menu_find_id", menu_find_id},
{"menu_item_getinfo", menu_item_getinfo}, {"menu_item_getinfo", menu_item_getinfo},
{"menu_makecallback", menu_makecallback}, {"menu_makecallback", menu_makecallback},
{"menu_item_setcall", menu_item_setcall},
{"menu_item_setcmd", menu_item_setcmd},
{"menu_item_setname", menu_item_setname},
{NULL, NULL}, {NULL, NULL},
}; };

View File

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

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 =
{ {
@ -2481,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;
@ -2613,10 +2612,12 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
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); 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);
@ -2735,6 +2736,8 @@ void ValidateMacros_DontCallThis_Smiley()
} }
#endif #endif
#ifdef MEMORY_TEST
/************* MEMORY *************/ /************* MEMORY *************/
// undef all defined macros // undef all defined macros
#undef new #undef new
@ -2906,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

@ -46,8 +46,6 @@ struct amxx_module_info_s
const char *logtag; // added in version 2 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 */
@ -1981,12 +1979,14 @@ 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*/ );
#endif
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/); 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*/);
@ -2048,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;
@ -2193,6 +2192,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_RequestFunction g_fn_RequestFunction; #define MF_RequestFunction g_fn_RequestFunction;
#define MF_AmxPush g_fn_AmxPush #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);
@ -2236,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 #if defined JIT && !defined ASM32
print_srvconsole( "Core mode: JIT Only\n"); print_srvconsole("Core mode: JIT Only\n");
#elif !defined JIT && defined ASM32 #elif !defined JIT && defined ASM32
print_srvconsole( "Core mode: ASM32 Only\n"); print_srvconsole("Core mode: ASM32 Only\n");
#elif defined JIT && defined ASM32 #elif defined JIT && defined ASM32
print_srvconsole( "Core mode: JIT+ASM32\n"); print_srvconsole("Core mode: JIT+ASM32\n");
#else #else
print_srvconsole( "Core mode: Normal\n"); print_srvconsole("Core mode: Normal\n");
#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,11 +240,9 @@ 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;
@ -269,13 +250,12 @@ void plugin_srvcmd()
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()); cell ret = executeForwards((*a).getFunction(), g_srvindex, (*a).getFlags(), (*a).getId());
if ( ret ) break; if (ret) break;
} }
++a; ++a;
} }

File diff suppressed because it is too large Load Diff

View File

@ -30,11 +30,10 @@
*/ */
#include <time.h> #include <time.h>
#include "amxmodx.h" #include "amxmodx.h"
#ifdef __linux__ #ifdef __linux__
#define _vsnprintf vsnprintf #define _vsnprintf vsnprintf
#endif #endif
char *UTIL_VarArgs(const char *fmt, ...) char *UTIL_VarArgs(const char *fmt, ...)
@ -52,21 +51,26 @@ char *UTIL_VarArgs(const char *fmt, ...)
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;
@ -75,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;
@ -93,14 +99,14 @@ void UTIL_ShowMenu( edict_t* pEdict, int slots, int time, char *menu, int mlen )
} }
/* warning - don't pass here const string */ /* 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();
} }
@ -109,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;
@ -125,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)
@ -168,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;
@ -219,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);
@ -237,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;
} }
@ -304,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,5,0,1 FILEVERSION 1,6,0,0
PRODUCTVERSION 1,5,0,1 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.50" 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.50-RC1" VALUE "ProductVersion", "1.60"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -200,6 +200,104 @@
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration
Name="Debug32|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=32;NO_MAIN"
MinimalRebuild="TRUE"
BasicRuntimeChecks="1"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/amxxpc32.dll"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/libpc300.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/libpc300.lib"
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="Debug64|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBPC300_EXPORTS;PAWNC_DLL;PAWN_CELL_SIZE=64;NO_MAIN"
MinimalRebuild="TRUE"
BasicRuntimeChecks="1"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="FALSE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/amxxpc64.dll"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/libpc300.pdb"
SubSystem="2"
ImportLibrary="$(OutDir)/libpc300.lib"
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> </Configurations>
<References> <References>
</References> </References>

View File

@ -63,6 +63,12 @@
#define PREPROC_TERM '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */ #define PREPROC_TERM '\x7f'/* termination character for preprocessor expressions (the "DEL" code) */
#define sDEF_PREFIX "default.inc" /* default prefix filename */ #define sDEF_PREFIX "default.inc" /* default prefix filename */
#if defined WIN32
#define INVISIBLE
#else
#define INVISIBLE __attribute__((visibility("protected")))
#endif
typedef union { typedef union {
void *pv; /* e.g. a name */ void *pv; /* e.g. a name */
int i; int i;
@ -435,12 +441,16 @@ int pc_enablewarning(int number,int enable);
*/ */
/* general console output */ /* general console output */
#if PAWN_CELL_SIZE==32
#if defined __WIN32__ || defined _WIN32 || defined WIN32 #if defined __WIN32__ || defined _WIN32 || defined WIN32
__declspec (dllexport) __declspec (dllexport)
int pc_printf(const char *message,...); int pc_printf(const char *message,...);
#else #else
extern int pc_printf(const char *message,...); extern int pc_printf(const char *message,...);
#endif #endif
#else
int pc_printf(const char *message, ...) INVISIBLE;
#endif
/* error report function */ /* error report function */
int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr); int pc_error(int number,char *message,char *filename,int firstline,int lastline,va_list argptr);
@ -629,11 +639,7 @@ SC_FUNC void jmp_eq0(int number);
SC_FUNC void outval(cell val,int newline); SC_FUNC void outval(cell val,int newline);
/* function prototypes in SC5.C */ /* function prototypes in SC5.C */
#ifdef __linux__ SC_FUNC int error(int number,...) INVISIBLE;
SC_FUNC int error(int number,...) __attribute__((visibility("internal")));
#else
SC_FUNC int error(int number,...)
#endif
SC_FUNC void errorset(int code); SC_FUNC void errorset(int code);
/* function prototypes in SC6.C */ /* function prototypes in SC6.C */

View File

@ -654,7 +654,6 @@ cleanup:
int flag_exceed=0; int flag_exceed=0;
if (sc_amxlimit > 0 && (long)(hdrsize+code_idx+glb_declared*sizeof(cell)+sc_stksize*sizeof(cell)) >= sc_amxlimit) if (sc_amxlimit > 0 && (long)(hdrsize+code_idx+glb_declared*sizeof(cell)+sc_stksize*sizeof(cell)) >= sc_amxlimit)
flag_exceed=1; flag_exceed=1;
#if PAWN_CELL_SIZE==32
if ((sc_debug & sSYMBOLIC)!=0 || verbosity>=2 || stacksize+32>=(long)sc_stksize || flag_exceed) { if ((sc_debug & sSYMBOLIC)!=0 || verbosity>=2 || stacksize+32>=(long)sc_stksize || flag_exceed) {
pc_printf("Header size: %8ld bytes\n", (long)hdrsize); pc_printf("Header size: %8ld bytes\n", (long)hdrsize);
pc_printf("Code size: %8ld bytes\n", (long)code_idx); pc_printf("Code size: %8ld bytes\n", (long)code_idx);
@ -666,7 +665,6 @@ cleanup:
pc_printf("estimated max. usage=%ld cells (%ld bytes)\n",stacksize,stacksize*sizeof(cell)); pc_printf("estimated max. usage=%ld cells (%ld bytes)\n",stacksize,stacksize*sizeof(cell));
pc_printf("Total requirements:%8ld bytes\n", (long)hdrsize+(long)code_idx+(long)glb_declared*sizeof(cell)+(long)sc_stksize*sizeof(cell)); pc_printf("Total requirements:%8ld bytes\n", (long)hdrsize+(long)code_idx+(long)glb_declared*sizeof(cell)+(long)sc_stksize*sizeof(cell));
} /* if */ } /* if */
#endif
if (flag_exceed) if (flag_exceed)
error(106,sc_amxlimit); /* this causes a jump back to label "cleanup" */ error(106,sc_amxlimit); /* this causes a jump back to label "cleanup" */
} /* if */ } /* if */
@ -1920,9 +1918,11 @@ static int declloc(int fstatic)
/* Although valid, a local variable whose name is equal to that /* Although valid, a local variable whose name is equal to that
* of a global variable or to that of a local variable at a lower * of a global variable or to that of a local variable at a lower
* level might indicate a bug. * level might indicate a bug.
* NOTE - don't bother with the error if there's no valid function!
*/ */
if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name)!=NULL); if ((sym=findloc(name))!=NULL && sym->compound!=nestlevel || findglb(name)!=NULL)
//error(219,name); /* variable shadows another symbol */ if (curfunc!=NULL && (curfunc->usage & uNATIVE))
error(219,name); /* variable shadows another symbol */
while (matchtoken('[')){ while (matchtoken('[')){
ident=iARRAY; ident=iARRAY;
if (numdim == sDIMEN_MAX) { if (numdim == sDIMEN_MAX) {
@ -3180,7 +3180,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) { if ((sym->usage & (uPROTOTYPED | uREAD))==uREAD && sym->tag!=0) {
int curstatus=sc_status; int curstatus=sc_status;
sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */ sc_status=statWRITE; /* temporarily set status to WRITE, so the warning isn't blocked */
error(208); //error(208); //this is silly, it should be caught the first pass
sc_status=curstatus; sc_status=curstatus;
sc_reparse=TRUE; /* must add another pass to "initial scan" phase */ sc_reparse=TRUE; /* must add another pass to "initial scan" phase */
} /* if */ } /* if */
@ -3645,8 +3645,8 @@ static void doarg(char *name,int ident,int offset,int tags[],int numtags,
if (argsym!=NULL) { if (argsym!=NULL) {
error(21,name); /* symbol already defined */ error(21,name); /* symbol already defined */
} else { } else {
if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN) ; if ((argsym=findglb(name))!=NULL && argsym->ident!=iFUNCTN && curfunc!=NULL)
//error(219,name); /* variable shadows another symbol */ error(219,name); /* variable shadows another symbol */
/* add details of type and address */ /* add details of type and address */
assert(numtags>0); assert(numtags>0);
argsym=addvariable(name,offset,ident,sLOCAL,tags[0], argsym=addvariable(name,offset,ident,sLOCAL,tags[0],

View File

@ -715,18 +715,6 @@ static int ftoi(cell *val,const unsigned char *curptr)
#endif #endif
#elif PAWN_CELL_SIZE==64 #elif PAWN_CELL_SIZE==64
*val=*((cell *)&fnum); *val=*((cell *)&fnum);
#if !defined NDEBUG
/* I assume that the C/C++ compiler stores "double" values in IEEE 754
* format (as mandated in the ANSI standard).
*/
{ float test1 = 0.0, test2 = 50.0, test3 = -50.0;
uint64_t bit = 1;
/* test 0.0 == all bits 0 */
assert(*(uint64_t*)&test1==0x00000000L);
/* test sign & magnitude format */
assert(((*(uint64_t*)&test2) ^ (*(uint64_t*)&test3)) == (bit << (PAWN_CELL_SIZE-1)));
}
#endif
#else #else
#error Unsupported cell size #error Unsupported cell size
#endif #endif
@ -1419,7 +1407,7 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
int prefixlen; int prefixlen;
const unsigned char *p,*s,*e; const unsigned char *p,*s,*e;
unsigned char *args[10]; unsigned char *args[10];
int match,arg,len; int match,arg,len,argsnum=0;
memset(args,0,sizeof args); memset(args,0,sizeof args);
@ -1459,6 +1447,8 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
/* store the parameter (overrule any earlier) */ /* store the parameter (overrule any earlier) */
if (args[arg]!=NULL) if (args[arg]!=NULL)
free(args[arg]); free(args[arg]);
else
argsnum++;
len=(int)(e-s); len=(int)(e-s);
args[arg]=(unsigned char*)malloc(len+1); args[arg]=(unsigned char*)malloc(len+1);
if (args[arg]==NULL) if (args[arg]==NULL)
@ -1515,14 +1505,17 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
if (match) { if (match) {
/* calculate the length of the substituted string */ /* calculate the length of the substituted string */
for (e=(unsigned char*)substitution,len=0; *e!='\0'; e++) { for (e=(unsigned char*)substitution,len=0; *e!='\0'; e++) {
if (*e=='%' && isdigit(*(e+1))) { if (*e=='%' && isdigit(*(e+1)) && argsnum) {
arg=*(e+1)-'0'; arg=*(e+1)-'0';
assert(arg>=0 && arg<=9); assert(arg>=0 && arg<=9);
if (args[arg]!=NULL) if (args[arg]!=NULL) {
len+=strlen((char*)args[arg]); len+=strlen((char*)args[arg]);
e++; /* skip %, digit is skipped later */ e++; /* skip %, digit is skipped later */
} else { } else {
len++; len++;
}
} else {
len++;
} /* if */ } /* if */
} /* for */ } /* for */
/* check length of the string after substitution */ /* check length of the string after substitution */
@ -1538,12 +1531,25 @@ static int substpattern(unsigned char *line,size_t buffersize,char *pattern,char
if (args[arg]!=NULL) { if (args[arg]!=NULL) {
strins((char*)s,(char*)args[arg],strlen((char*)args[arg])); strins((char*)s,(char*)args[arg],strlen((char*)args[arg]));
s+=strlen((char*)args[arg]); s+=strlen((char*)args[arg]);
} /* if */
e++; /* skip %, digit is skipped later */ e++; /* skip %, digit is skipped later */
} else { } else {
strins((char*)s,(char*)e,1); strins((char*)s,(char*)e,1);
s++; s++;
} /* if */ } /* if */
} else if (*e=='"') {
p=e;
if (is_startstring(e)) { /* skip strings */
e=skipstring(e);
strins((char*)s,(char*)p,(e-p+1));
s+=(e-p+1);
} else {
strins((char*)s,(char*)e,1);
s++;
}
} else {
strins((char*)s,(char*)e,1);
s++;
} /* if */
} /* for */ } /* for */
} /* if */ } /* if */
} /* if */ } /* if */
@ -1578,7 +1584,7 @@ static void substallpatterns(unsigned char *line,int buffersize)
if (*start=='\0') if (*start=='\0')
break; /* abort loop on error */ break; /* abort loop on error */
/* if matching the operator "defined", skip it plus the symbol behind it */ /* if matching the operator "defined", skip it plus the symbol behind it */
if (strncmp((char*)start,"defined",7)==0 && *(start+7)<=' ') { if (strncmp((char*)start,"defined",7)==0 && !isalpha((char)*(start+7))) {
start+=7; /* skip "defined" */ start+=7; /* skip "defined" */
/* skip white space & parantheses */ /* skip white space & parantheses */
while (*start<=' ' && *start!='\0' || *start=='(') while (*start<=' ' && *start!='\0' || *start=='(')
@ -2451,7 +2457,7 @@ static symbol *find_symbol(const symbol *root,const char *name,int fnumber,int i
while (ptr!=NULL) { while (ptr!=NULL) {
if (hash==ptr->hash && strcmp(name,ptr->name)==0 if (hash==ptr->hash && strcmp(name,ptr->name)==0
&& (ptr->parent==NULL || includechildren) && (ptr->parent==NULL || includechildren)
&& (ptr->fnumber<0 || ptr->fnumber==fnumber)) && (fnumber<0 || (ptr->fnumber<0 || ptr->fnumber==fnumber)))
return ptr; return ptr;
ptr=ptr->next; ptr=ptr->next;
} /* while */ } /* while */

View File

@ -964,8 +964,12 @@ static int hier14(value *lval1)
check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag); check_userop(NULL,lval2.tag,lval3.tag,2,&lval3,&lval2.tag);
store(&lval3); /* now, store the expression result */ store(&lval3); /* now, store the expression result */
} /* if */ } /* if */
if (!oper && !matchtag(lval3.tag,lval2.tag,TRUE)) if (!oper) { /* tagname mismatch (if "oper", warning already given in plunge2()) */
error(213); /* tagname mismatch (if "oper", warning already given in plunge2()) */ if (lval3.sym && !matchtag(lval3.sym->tag, lval2.tag, TRUE))
error(213);
else if (!lval3.sym && !matchtag(lval3.tag, lval2.tag, TRUE))
error(213);
}
if (lval3.sym) if (lval3.sym)
markusage(lval3.sym,uWRITTEN); markusage(lval3.sym,uWRITTEN);
sideeffect=TRUE; sideeffect=TRUE;
@ -2202,7 +2206,8 @@ static int nesting=0;
if ((sym->usage & uNATIVE)==0) if ((sym->usage & uNATIVE)==0)
totalsize++; /* add "call" opcode */ totalsize++; /* add "call" opcode */
totalsize+=nest_stkusage; totalsize+=nest_stkusage;
assert(curfunc!=NULL); if (!curfunc) /* if we got here, the function is invalid! */
return;
if (curfunc->x.stacksize<totalsize) if (curfunc->x.stacksize<totalsize)
curfunc->x.stacksize=totalsize; curfunc->x.stacksize=totalsize;
nest_stkusage-=nargs+heapalloc+1; /* stack/heap space, +1 for argcount param */ nest_stkusage-=nargs+heapalloc+1; /* stack/heap space, +1 for argcount param */

View File

@ -581,6 +581,8 @@ SC_FUNC int assemble(FILE *fout,FILE *fin)
constvalue *constptr; constvalue *constptr;
cell mainaddr; cell mainaddr;
fcurrent = -1;
/* if compression failed, restart the assembly with compaction switched off */ /* if compression failed, restart the assembly with compaction switched off */
if (setjmp(compact_err)!=0) { if (setjmp(compact_err)!=0) {
assert(sc_compress); /* cannot arrive here if compact encoding was disabled */ assert(sc_compress); /* cannot arrive here if compact encoding was disabled */

View File

@ -450,9 +450,14 @@ SC_FUNC stringlist *insert_dbgsymbol(symbol *sym)
#endif #endif
if (sym->ident==iARRAY || sym->ident==iREFARRAY) { if (sym->ident==iARRAY || sym->ident==iREFARRAY) {
symbol *sub; symbol *sub;
#if !defined NDEBUG
count = sym->dim.array.level;
#endif
strcat(string," [ "); strcat(string," [ ");
for (sub=sym; sub!=NULL; sub=finddepend(sub)) { for (sub=sym; sub!=NULL; sub=finddepend(sub)) {
assert(sub->dim.array.level==count++); #if !defined NDEBUG
assert(sub->dim.array.level==count--);
#endif
sprintf(string+strlen(string),"%x:%x ",sub->x.idxtag,sub->dim.array.length); sprintf(string+strlen(string),"%x:%x ",sub->x.idxtag,sub->dim.array.length);
} /* for */ } /* for */
strcat(string,"]"); strcat(string,"]");

View File

@ -35,7 +35,7 @@ statscfg.amxx ; allows to manage stats plugins via menu and commands
; Counter-Strike ; Counter-Strike
;restmenu.amxx ; restrict weapons menu ;restmenu.amxx ; restrict weapons menu
;statsx.amxx ; stats on death or round end (CSX Module required!) statsx.amxx ; stats on death or round end (CSX Module required!)
;miscstats.amxx ; bunch of events announcement for Counter-Strike ;miscstats.amxx ; bunch of events announcement for Counter-Strike
;stats_logging.amxx ; weapons stats logging (CSX Module required!) ;stats_logging.amxx ; weapons stats logging (CSX Module required!)

View File

@ -12,16 +12,16 @@ fun_amxx_amd64.so
; ---------------------------------------------------- ; ----------------------------------------------------
; Engine - provides engine functions core to Half-Life ; Engine - provides engine functions core to Half-Life
; ---------------------------------------------------- ; ----------------------------------------------------
;engine_amxx_i386.so engine_amxx_i386.so
;engine_amxx.dll engine_amxx.dll
;engine_amxx_amd64.so engine_amxx_amd64.so
; ---------------------------------------------------------- ; ----------------------------------------------------------
; Fakemeta - provides a massive interface into the HL engine ; Fakemeta - provides a massive interface into the HL engine
; ---------------------------------------------------------- ; ----------------------------------------------------------
;fakemeta_amxx_i386.so fakemeta_amxx_i386.so
;fakemeta_amxx.dll fakemeta_amxx.dll
;fakemeta_amxx_amd64.so fakemeta_amxx_amd64.so
; ------------------------------------------- ; -------------------------------------------
; Database Access - only enable one of these ; Database Access - only enable one of these
@ -67,10 +67,3 @@ fun_amxx_amd64.so
;nvault_amxx_i386.so ;nvault_amxx_i386.so
;nvault_amxx.dll ;nvault_amxx.dll
;nvault_amxx_amd64.so ;nvault_amxx_amd64.so
; --------------------------------------------
; Adds ESF miscellanious and hacking functions
; --------------------------------------------
esfmod_amxx_i386.so
esfmod_amxx.dll
esfmod_amxx_amd64.so

39
configs/esf/plugins.ini Executable file
View File

@ -0,0 +1,39 @@
; AMX Mod X plugins
; Admin Base - Always one has to be activated
admin.amxx ; admin base (required for any admin-related)
;admin_sql.amxx ; admin base - SQL version (comment admin.amxx)
; Basic
admincmd.amxx ; basic admin console commands
adminhelp.amxx ; help command for admin console commands
adminslots.amxx ; slot reservation
multilingual.amxx ; Multi-Lingual management
; Menus
menufront.amxx ; front-end for admin menus
cmdmenu.amxx ; command menu (speech, settings)
plmenu.amxx ; players menu (kick, ban, client cmds.)
;telemenu.amxx ; teleport menu (Fun Module required!)
mapsmenu.amxx ; maps menu (vote, changelevel)
; Chat / Messages
adminchat.amxx ; console chat commands
antiflood.amxx ; prevent clients from chat-flooding the server
scrollmsg.amxx ; displays a scrolling message
imessage.amxx ; displays information messages
adminvote.amxx ; vote commands
; Map related
nextmap.amxx ; displays next map in mapcycle
mapchooser.amxx ; allows to vote for next map
timeleft.amxx ; displays time left on map
; Configuration
pausecfg.amxx ; allows to pause and unpause some plugins
statscfg.amxx ; allows to manage stats plugins via menu and commands
; Custom - Add 3rd party plugins here
EvolutionX.Core.amxx ; Adds extra plugin functions for Earth's Special Forces
; (made by the Corona Bytes team of EVM)

View File

@ -6,7 +6,7 @@ MM_ROOT = ../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe OPT_FLAGS = -O2 -funroll-loops -s -pipe -fomit-frame-pointer
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc CPP = gcc
NAME = cstrike_amxx NAME = cstrike_amxx
@ -26,12 +26,11 @@ else
CFLAGS = $(OPT_FLAGS) CFLAGS = $(OPT_FLAGS)
endif endif
CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -fno-rtti -static-libgcc
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LINK += -lstdc++
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32

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 =
{ {
@ -2481,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;
@ -2502,6 +2501,7 @@ PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
PFN_FORMAT g_fn_Format; PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction; PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction; 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)
@ -2610,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);
@ -2717,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);
@ -2733,6 +2736,8 @@ void ValidateMacros_DontCallThis_Smiley()
} }
#endif #endif
#ifdef MEMORY_TEST
/************* MEMORY *************/ /************* MEMORY *************/
// undef all defined macros // undef all defined macros
#undef new #undef new
@ -2904,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

@ -46,8 +46,6 @@ struct amxx_module_info_s
const char *logtag; // added in version 2 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 */
@ -1981,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*/);
@ -2002,6 +2002,7 @@ 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 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;
@ -2047,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;
@ -2065,6 +2065,7 @@ 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_REGISTERFUNCTION g_fn_RegisterFunction;
extern PFN_REQ_FNPTR g_fn_RequestFunction; 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
@ -2123,6 +2124,8 @@ 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_RegisterFunction (void *pfn, const char *description) { }
void * MF_RequestFunction (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
@ -2187,7 +2190,9 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_Format g_fn_Format #define MF_Format g_fn_Format
#define MF_RegisterFunction g_fn_RegisterFunction #define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction; #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);
@ -2231,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

@ -175,7 +175,7 @@ static cell AMX_NATIVE_CALL cs_get_weapon_silenced(AMX *amx, cell *params) // cs
// Make into edict pointer // Make into edict pointer
edict_t *pWeapon = INDEXENT(params[1]); edict_t *pWeapon = INDEXENT(params[1]);
int weapontype = (int)*((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE); int weapontype = *((int *)pWeapon->pvPrivateData + OFFSET_WEAPONTYPE);
int *silencemode = ((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE); int *silencemode = ((int *)pWeapon->pvPrivateData + OFFSET_SILENCER_FIREMODE);
switch (weapontype) { switch (weapontype) {
case CSW_M4A1: case CSW_M4A1:
@ -357,10 +357,12 @@ static cell AMX_NATIVE_CALL cs_get_user_armor(AMX *amx, cell *params) // cs_get_
// Make into edict pointer // Make into edict pointer
edict_t *pPlayer = MF_GetPlayerEdict(params[1]); edict_t *pPlayer = MF_GetPlayerEdict(params[1]);
#if 0
cell *armorTypeByRef = MF_GetAmxAddr(amx, params[2]); cell *armorTypeByRef = MF_GetAmxAddr(amx, params[2]);
*armorTypeByRef = *((int *)pPlayer->pvPrivateData + OFFSET_ARMORTYPE); *armorTypeByRef = *((int *)pPlayer->pvPrivateData + OFFSET_ARMORTYPE);
#endif
return pPlayer->v.armorvalue; return (cell)pPlayer->v.armorvalue;
} }
static cell AMX_NATIVE_CALL cs_set_user_armor(AMX *amx, cell *params) // cs_set_user_armor(index, armorvalue, CsArmorType:armortype); = 3 params static cell AMX_NATIVE_CALL cs_set_user_armor(AMX *amx, cell *params) // cs_set_user_armor(index, armorvalue, CsArmorType:armortype); = 3 params
@ -1232,6 +1234,118 @@ static cell AMX_NATIVE_CALL cs_user_spawn(AMX *amx, cell *params)
return 1; return 1;
} }
static cell AMX_NATIVE_CALL cs_get_armoury_type(AMX *amx, cell *params)
{
// Return CSW_* constants of specified armoury_entity.
// params[1] = entity
// Valid entity should be within range.
CHECK_NONPLAYER(params[1]);
// Make into edict pointer.
edict_t *pArmoury = INDEXENT(params[1]);
// Make sure this is an armoury_entity.
if (strcmp(STRING(pArmoury->v.classname), "armoury_entity")) {
// Error out here.
MF_LogError(amx, AMX_ERR_NATIVE, "Not an armoury_entity! (%d)", params[1]);
return 0;
}
#if PAWN_CELL_SIZE == 32
int weapontype = *((int *)pArmoury->pvPrivateData + OFFSET_ARMOURY_TYPE);
// We do a switch instead of a mapped array because this way we can nicely catch unexpected values, and we don't get array out of bounds thingies.
int weapontype_out;
switch (weapontype) {
case CSA_MP5NAVY: weapontype_out = CSW_MP5NAVY; break;
case CSA_TMP: weapontype_out = CSW_TMP; break;
case CSA_P90: weapontype_out = CSW_P90; break;
case CSA_MAC10: weapontype_out = CSW_MAC10; break;
case CSA_AK47: weapontype_out = CSW_AK47; break;
case CSA_SG552: weapontype_out = CSW_SG552; break;
case CSA_M4A1: weapontype_out = CSW_M4A1; break;
case CSA_AUG: weapontype_out = CSW_AUG; break;
case CSA_SCOUT: weapontype_out = CSW_SCOUT; break;
case CSA_G3SG1: weapontype_out = CSW_G3SG1; break;
case CSA_AWP: weapontype_out = CSW_AWP; break;
case CSA_M3: weapontype_out = CSW_M3; break;
case CSA_XM1014: weapontype_out = CSW_XM1014; break;
case CSA_M249: weapontype_out = CSW_M249; break;
case CSA_FLASHBANG: weapontype_out = CSW_FLASHBANG; break;
case CSA_HEGRENADE: weapontype_out = CSW_HEGRENADE; break;
case CSA_VEST: weapontype_out = CSW_VEST; break;
case CSA_VESTHELM: weapontype_out = CSW_VESTHELM; break;
case CSA_SMOKEGRENADE: weapontype_out = CSW_SMOKEGRENADE; break;
default:
MF_LogError(amx, AMX_ERR_NATIVE, "Unexpected weapon type of %d!", params[1]);
return 0;
}
return weapontype_out;
#else
MF_LogError(amx, AMX_ERR_NATIVE, "This function not implemented on AMD64.");
return 0;
#endif
}
static cell AMX_NATIVE_CALL cs_set_armoury_type(AMX *amx, cell *params)
{
// Set CSW->CSA mapped weapon type to entity.
// params[1] = entity
// params[2] = CSW_* constant
// Valid entity should be within range.
CHECK_NONPLAYER(params[1]);
// Make into edict pointer.
edict_t *pArmoury = INDEXENT(params[1]);
// Make sure this is an armoury_entity.
if (strcmp(STRING(pArmoury->v.classname), "armoury_entity")) {
// Error out here.
MF_LogError(amx, AMX_ERR_NATIVE, "Not an armoury_entity! (%d)", params[1]);
return 0;
}
#if PAWN_CELL_SIZE == 32
// We do a switch instead of a mapped array because this way we can nicely catch unexpected values, and we don't get array out of bounds thingies.
int weapontype;
switch (params[2]) {
case CSW_MP5NAVY: weapontype = CSA_MP5NAVY; break;
case CSW_TMP: weapontype = CSA_TMP; break;
case CSW_P90: weapontype = CSA_P90; break;
case CSW_MAC10: weapontype = CSA_MAC10; break;
case CSW_AK47: weapontype = CSA_AK47; break;
case CSW_SG552: weapontype = CSA_SG552; break;
case CSW_M4A1: weapontype = CSA_M4A1; break;
case CSW_AUG: weapontype = CSA_AUG; break;
case CSW_SCOUT: weapontype = CSA_SCOUT; break;
case CSW_G3SG1: weapontype = CSA_G3SG1; break;
case CSW_AWP: weapontype = CSA_AWP; break;
case CSW_M3: weapontype = CSA_M3; break;
case CSW_XM1014: weapontype = CSA_XM1014; break;
case CSW_M249: weapontype = CSA_M249; break;
case CSW_FLASHBANG: weapontype = CSA_FLASHBANG; break;
case CSW_HEGRENADE: weapontype = CSA_HEGRENADE; break;
case CSW_VEST: weapontype = CSA_VEST; break;
case CSW_VESTHELM: weapontype = CSA_VESTHELM; break;
case CSW_SMOKEGRENADE: weapontype = CSA_SMOKEGRENADE; break;
default:
MF_LogError(amx, AMX_ERR_NATIVE, "Unsupported weapon type! (%d)", params[2]);
return 0;
}
*((int *)pArmoury->pvPrivateData + OFFSET_ARMOURY_TYPE) = weapontype;
return 1;
#else
MF_LogError(amx, AMX_ERR_NATIVE, "This function not implemented on AMD64.");
return 0;
#endif
}
AMX_NATIVE_INFO cstrike_Exports[] = { AMX_NATIVE_INFO cstrike_Exports[] = {
{"cs_set_user_money", cs_set_user_money}, {"cs_set_user_money", cs_set_user_money},
{"cs_get_user_money", cs_get_user_money}, {"cs_get_user_money", cs_get_user_money},
@ -1274,6 +1388,8 @@ AMX_NATIVE_INFO cstrike_Exports[] = {
{"cs_set_user_armor", cs_set_user_armor}, {"cs_set_user_armor", cs_set_user_armor},
{"cs_get_user_shield", cs_get_user_shield}, {"cs_get_user_shield", cs_get_user_shield},
{"cs_user_spawn", cs_user_spawn}, {"cs_user_spawn", cs_user_spawn},
{"cs_get_armoury_type", cs_get_armoury_type},
{"cs_set_armoury_type", cs_set_armoury_type},
//------------------- <-- max 19 characters! //------------------- <-- max 19 characters!
{NULL, NULL} {NULL, NULL}
}; };

View File

@ -102,6 +102,8 @@
// "hostage_entity" entities // "hostage_entity" entities
#define OFFSET_HOSTAGEFOLLOW 86 + EXTRAOFFSET #define OFFSET_HOSTAGEFOLLOW 86 + EXTRAOFFSET
#define OFFSET_HOSTAGEID 487 + EXTRAOFFSET #define OFFSET_HOSTAGEID 487 + EXTRAOFFSET
// "armoury_entity"
#define OFFSET_ARMOURY_TYPE 34 + EXTRAOFFSET
#else #else
// Amd64 offsets here // Amd64 offsets here
#define OFFSET_ARMORTYPE 137 + EXTRAOFFSET #define OFFSET_ARMORTYPE 137 + EXTRAOFFSET
@ -174,6 +176,29 @@
#define CSW_AK47 28 #define CSW_AK47 28
//#define CSW_KNIFE 29 //#define CSW_KNIFE 29
#define CSW_P90 30 #define CSW_P90 30
#define CSW_VEST 31 // Brand new invention!
#define CSW_VESTHELM 32 // Brand new invention!
// These are used with armoury_entity:s.
#define CSA_MP5NAVY 0
#define CSA_TMP 1
#define CSA_P90 2
#define CSA_MAC10 3
#define CSA_AK47 4
#define CSA_SG552 5
#define CSA_M4A1 6
#define CSA_AUG 7
#define CSA_SCOUT 8
#define CSA_G3SG1 9
#define CSA_AWP 10
#define CSA_M3 11
#define CSA_XM1014 12
#define CSA_M249 13
#define CSA_FLASHBANG 14
#define CSA_HEGRENADE 15
#define CSA_VEST 16
#define CSA_VESTHELM 17
#define CSA_SMOKEGRENADE 18
#define M4A1_SILENCED (1<<2) #define M4A1_SILENCED (1<<2)
#define M4A1_ATTACHSILENCEANIM 6 #define M4A1_ATTACHSILENCEANIM 6
@ -276,3 +301,4 @@ bool g_noknives = false;
#define GETEDICT(n) \ #define GETEDICT(n) \
((n >= 1 && n <= gpGlobals->maxClients) ? MF_GetPlayerEdict(n) : INDEXENT(n)) ((n >= 1 && n <= gpGlobals->maxClients) ? MF_GetPlayerEdict(n) : INDEXENT(n))

View File

@ -5,7 +5,7 @@
// Module info // Module info
#define MODULE_NAME "CStrike" #define MODULE_NAME "CStrike"
#define MODULE_VERSION "1.50" #define MODULE_VERSION "1.60"
#define MODULE_AUTHOR "AMX Mod X Dev Team" #define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org" #define MODULE_URL "http://www.amxmodx.org"
#define MODULE_LOGTAG "CSTRIKE" #define MODULE_LOGTAG "CSTRIKE"
@ -460,3 +460,4 @@
#endif // USE_METAMOD #endif // USE_METAMOD
#endif // __MODULECONFIG_H__ #endif // __MODULECONFIG_H__

View File

@ -308,3 +308,4 @@ void RankSystem::saveRank( const char* filename )
fclose(bfp); fclose(bfp);
} }

View File

@ -120,3 +120,4 @@ public:
#endif #endif

View File

@ -6,7 +6,7 @@ MM_ROOT = ../../../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe OPT_FLAGS = -O3 -funroll-loops -s -pipe -fomit-frame-pointer
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc CPP = gcc
NAME = csx_amxx NAME = csx_amxx
@ -26,12 +26,11 @@ else
CFLAGS = $(OPT_FLAGS) CFLAGS = $(OPT_FLAGS)
endif endif
CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LINK += -lstdc++
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32

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 =
{ {
@ -2481,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;
@ -2613,10 +2612,12 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
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); 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);
@ -2735,6 +2736,8 @@ void ValidateMacros_DontCallThis_Smiley()
} }
#endif #endif
#ifdef MEMORY_TEST
/************* MEMORY *************/ /************* MEMORY *************/
// undef all defined macros // undef all defined macros
#undef new #undef new
@ -2906,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

@ -46,8 +46,6 @@ struct amxx_module_info_s
const char *logtag; // added in version 2 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 */
@ -1981,12 +1979,14 @@ 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*/ );
#endif
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/); 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*/);
@ -2048,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;
@ -2193,6 +2192,7 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_RequestFunction g_fn_RequestFunction; #define MF_RequestFunction g_fn_RequestFunction;
#define MF_AmxPush g_fn_AmxPush #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);
@ -2236,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

@ -5,7 +5,7 @@
// Module info // Module info
#define MODULE_NAME "CSX" #define MODULE_NAME "CSX"
#define MODULE_VERSION "1.50" #define MODULE_VERSION "1.60"
#define MODULE_AUTHOR "AMX Mod X Dev Team" #define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org/" #define MODULE_URL "http://www.amxmodx.org/"
#define MODULE_LOGTAG "CSX" #define MODULE_LOGTAG "CSX"
@ -460,3 +460,4 @@
#endif // USE_METAMOD #endif // USE_METAMOD
#endif // __MODULECONFIG_H__ #endif // __MODULECONFIG_H__

View File

@ -26,9 +26,9 @@
AdditionalIncludeDirectories="..\..\metamod,..\..\sdk\common,..\..\sdk\engine,..\..\sdk\dlls" AdditionalIncludeDirectories="..\..\metamod,..\..\sdk\common,..\..\sdk\engine,..\..\sdk\dlls"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;JIT" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;csx_EXPORTS;JIT"
StringPooling="TRUE" StringPooling="TRUE"
RuntimeLibrary="0" RuntimeLibrary="4"
StructMemberAlignment="3" StructMemberAlignment="0"
EnableFunctionLevelLinking="TRUE" EnableFunctionLevelLinking="FALSE"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\release/csx.pch" PrecompiledHeaderFile=".\release/csx.pch"
AssemblerListingLocation=".\release/" AssemblerListingLocation=".\release/"
@ -91,7 +91,7 @@
AdditionalIncludeDirectories="..\..\metamod,..\..\sdk\common,..\..\sdk\engine,..\..\sdk\dlls,..\..\hlsdk\sourcecode\pm_shared" AdditionalIncludeDirectories="..\..\metamod,..\..\sdk\common,..\..\sdk\engine,..\..\sdk\dlls,..\..\hlsdk\sourcecode\pm_shared"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;csx_EXPORTS" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;csx_EXPORTS"
BasicRuntimeChecks="3" BasicRuntimeChecks="3"
RuntimeLibrary="1" RuntimeLibrary="5"
UsePrecompiledHeader="2" UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\debug/csx.pch" PrecompiledHeaderFile=".\debug/csx.pch"
AssemblerListingLocation=".\debug/" AssemblerListingLocation=".\debug/"

View File

@ -6,7 +6,7 @@ MM_ROOT = ../../../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc CPP = gcc
NAME = dodfun_amxx NAME = dodfun_amxx
@ -26,12 +26,11 @@ else
CFLAGS = $(OPT_FLAGS) CFLAGS = $(OPT_FLAGS)
endif endif
CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LINK += -lstdc++
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32

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 =
{ {
@ -2481,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;
@ -2502,6 +2501,7 @@ PFN_GET_PLAYER_EDICT g_fn_GetPlayerEdict;
PFN_FORMAT g_fn_Format; PFN_FORMAT g_fn_Format;
PFN_REGISTERFUNCTION g_fn_RegisterFunction; PFN_REGISTERFUNCTION g_fn_RegisterFunction;
PFN_REQ_FNPTR g_fn_RequestFunction; 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)
@ -2610,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);
@ -2717,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);
@ -2733,6 +2736,8 @@ void ValidateMacros_DontCallThis_Smiley()
} }
#endif #endif
#ifdef MEMORY_TEST
/************* MEMORY *************/ /************* MEMORY *************/
// undef all defined macros // undef all defined macros
#undef new #undef new
@ -2904,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

@ -46,8 +46,6 @@ struct amxx_module_info_s
const char *logtag; // added in version 2 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 */
@ -1981,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*/);
@ -2002,6 +2002,7 @@ 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 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;
@ -2047,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;
@ -2065,6 +2065,7 @@ 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_REGISTERFUNCTION g_fn_RegisterFunction;
extern PFN_REQ_FNPTR g_fn_RequestFunction; 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
@ -2123,6 +2124,8 @@ 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_RegisterFunction (void *pfn, const char *description) { }
void * MF_RequestFunction (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
@ -2187,7 +2190,9 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
#define MF_Format g_fn_Format #define MF_Format g_fn_Format
#define MF_RegisterFunction g_fn_RegisterFunction #define MF_RegisterFunction g_fn_RegisterFunction
#define MF_RequestFunction g_fn_RequestFunction; #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);
@ -2231,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

@ -5,7 +5,7 @@
// Module info // Module info
#define MODULE_NAME "DoD Fun" #define MODULE_NAME "DoD Fun"
#define MODULE_VERSION "1.50" #define MODULE_VERSION "1.60"
#define MODULE_AUTHOR "AMX Mod X Dev Team" #define MODULE_AUTHOR "AMX Mod X Dev Team"
#define MODULE_URL "http://www.amxmodx.org" #define MODULE_URL "http://www.amxmodx.org"
#define MODULE_LOGTAG "DODFUN" #define MODULE_LOGTAG "DODFUN"

View File

@ -6,7 +6,7 @@ MM_ROOT = ../../../metamod/metamod
### EDIT BELOW FOR OTHER PROJECTS ### ### EDIT BELOW FOR OTHER PROJECTS ###
OPT_FLAGS = -O3 -fno-rtti -funroll-loops -s -pipe OPT_FLAGS = -O3 -funroll-loops -s -pipe
DEBUG_FLAGS = -g -ggdb3 DEBUG_FLAGS = -g -ggdb3
CPP = gcc CPP = gcc
NAME = dodx_amxx NAME = dodx_amxx
@ -26,12 +26,11 @@ else
CFLAGS = $(OPT_FLAGS) CFLAGS = $(OPT_FLAGS)
endif endif
CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H CFLAGS += -DNDEBUG -fPIC -Wno-deprecated -fno-exceptions -DHAVE_STDINT_H -static-libgcc -fno-rtti
ifeq "$(AMD64)" "true" ifeq "$(AMD64)" "true"
BINARY = $(NAME)_amd64.so BINARY = $(NAME)_amd64.so
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64 CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
LINK += -lstdc++
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32

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