Compare commits
2680 Commits
amxmodx-0.
...
amxmodx-1.
Author | SHA1 | Date | |
---|---|---|---|
028da81df7 | |||
57ccee89f2 | |||
4b649469b0 | |||
f1d3274f0e | |||
0c668753fb | |||
2edbf72391 | |||
e1caa575e7 | |||
9dcdba439a | |||
d3af14c957 | |||
f08bbbc45f | |||
99a2b54530 | |||
6f20664140 | |||
06fbff7042 | |||
bb609123fb | |||
d832eb8fef | |||
fd67b07530 | |||
c0396bf140 | |||
d55542aa8d | |||
2e86f51cfe | |||
84ec8ef007 | |||
07e55f3b71 | |||
50311d14fb | |||
1088b209d9 | |||
63ec26f8c0 | |||
07b5a819bf | |||
8e03e67a8f | |||
66d04f8def | |||
bce69e7116 | |||
d4bfddc034 | |||
373d25b0ce | |||
deb1b00416 | |||
6b80e9e8d2 | |||
a19b00fd2f | |||
8f2c9e9452 | |||
5463a84c12 | |||
68e1937a5c | |||
d05c34b73c | |||
c69777d8cc | |||
b3b9e72b01 | |||
7f57e8377a | |||
036ab78828 | |||
e0f1a93d6e | |||
eba189e2b9 | |||
5748ed84a2 | |||
9eb0d50f4c | |||
24c5c10a31 | |||
c91f712363 | |||
f6c9263940 | |||
ba87258a3d | |||
011c9fa45c | |||
2c7ca33bf1 | |||
2ece53fa38 | |||
36ec7bc818 | |||
b4450bbee5 | |||
c92145ee88 | |||
3fbf65103a | |||
e7858b4cd7 | |||
ad495cef13 | |||
17fb06f7bb | |||
7d3ddf502c | |||
5940b4a6ca | |||
9edf20866b | |||
30495aa34e | |||
45b8383eb9 | |||
56e97a2b60 | |||
9857731dff | |||
915c3d244c | |||
24cdcde968 | |||
cef005317b | |||
1035c35c03 | |||
2210c54d68 | |||
e546c69041 | |||
36268f04d9 | |||
3fe24d8793 | |||
b3a91bc496 | |||
8a529b100c | |||
f1f683dca7 | |||
afb8fb0019 | |||
fb904f6e40 | |||
73858b0fcd | |||
a5bd69ac4a | |||
c6e17539ca | |||
e0b05c0b83 | |||
a44eb16360 | |||
fc429213d3 | |||
80cbaa8217 | |||
170dbcaaa9 | |||
7c1da54412 | |||
c508f17bfe | |||
1cdbfb50ad | |||
579cc83d54 | |||
be7bf671af | |||
e1b9543d10 | |||
af8dea753e | |||
d0d08800ef | |||
dafc10d878 | |||
ad0eafe66a | |||
5ffb38b5bc | |||
b363b16d61 | |||
5522778aed | |||
3a7d291513 | |||
fe603c29f0 | |||
27ba10c8a0 | |||
34f5b3257d | |||
7367f29cb4 | |||
fc5e049e4a | |||
1c2749fdf6 | |||
aa1308e32e | |||
3cde89bc74 | |||
75b6aa192d | |||
43ecf97f99 | |||
4ca564540e | |||
c8d543929a | |||
e7e87ff040 | |||
ab40f426c6 | |||
7ecdf75d0d | |||
e6064af9fb | |||
44a7b62963 | |||
ac1e3a9001 | |||
7e36a19590 | |||
6af5516005 | |||
444e2caa68 | |||
3d932c8a36 | |||
2e63e1316c | |||
b4a77512ae | |||
b40f5e6637 | |||
e0bed163ac | |||
bce3bce586 | |||
f9c9088303 | |||
9bbb0df492 | |||
eafd402ead | |||
cf9cdaa3d6 | |||
a993ba159a | |||
2d75dfe865 | |||
635b681825 | |||
ef1347cb6c | |||
c0334deae1 | |||
39a22813cb | |||
d01d6b06fa | |||
6cb6ef9c84 | |||
b953f285d0 | |||
dc785a4369 | |||
a7de50a4bb | |||
00fd007e7a | |||
b6007e8223 | |||
25a2b11198 | |||
a0923e21ed | |||
f51620c2d7 | |||
1370305fb0 | |||
f7805623b0 | |||
9a34c7931a | |||
b67e6c5269 | |||
5e4d5a2c8f | |||
567044c381 | |||
b2b001c9e4 | |||
793de6d8d2 | |||
d862f23929 | |||
f8809e2663 | |||
19f2be0c96 | |||
6995b182c1 | |||
79f86bfabd | |||
035c54350e | |||
d0a61ef581 | |||
123215a53c | |||
9b68c0678a | |||
e0fa5227d6 | |||
441ab14d3b | |||
ed6e28c1d4 | |||
77f0e526bf | |||
30ce0d9f1b | |||
8920a05bba | |||
061da07af8 | |||
da757b6c62 | |||
880b83a10b | |||
76c1c78b5b | |||
afe19411b2 | |||
b2aff10e46 | |||
4e1123730c | |||
8e3a5e6d58 | |||
beb975bdbf | |||
302b759fc8 | |||
c6e8a356ee | |||
b12025093b | |||
de1f1eef8d | |||
25d4b6aea3 | |||
f9fd83b42e | |||
1e6ba05ec9 | |||
dd7529b42c | |||
cfb36025b5 | |||
f5cabb4bea | |||
58209dfb37 | |||
a29f8d0651 | |||
f600a96657 | |||
d8c8e72745 | |||
9a34213992 | |||
67d4c5ccad | |||
6b794d4a9d | |||
ca3e8582e3 | |||
7669ab02f6 | |||
c6f8749242 | |||
6ee7930a46 | |||
f2c5a2b85b | |||
37151d361f | |||
974e8882b9 | |||
9b9f0d0e27 | |||
0a4a209f94 | |||
603be35426 | |||
92645db291 | |||
00e32aca97 | |||
dad00a2eb6 | |||
576680eaf9 | |||
7a533c7be5 | |||
4e5ada6ad1 | |||
a9f300bca9 | |||
8fec829c63 | |||
f3fe58809d | |||
c6d16eac7a | |||
d7e53d7a81 | |||
26ee3955b6 | |||
21ffd88bdd | |||
ed19c53552 | |||
133c7d6815 | |||
7cd10e4796 | |||
ecd2d913e4 | |||
53e84a13be | |||
eb55e1f4aa | |||
dc063594de | |||
f26d208c38 | |||
6cc239c66f | |||
6733ef9a79 | |||
7dc4beae63 | |||
de33bb6a1d | |||
7883710bf6 | |||
0071d73e25 | |||
0555e7aa63 | |||
ddda9c9118 | |||
d2b57d29fb | |||
d78ec24679 | |||
e5057d7191 | |||
f10ecbb239 | |||
229b149247 | |||
1f8b9a8cd9 | |||
6000fe43d1 | |||
5a2e35c1bf | |||
62c096d7d3 | |||
f6cb8ab3bb | |||
8da4987895 | |||
38cb60c60b | |||
a87966cde3 | |||
9b252fa919 | |||
760514a1fe | |||
2ca42b7b21 | |||
b65b8a1cf0 | |||
e96eaa6174 | |||
2a74d2229f | |||
3f5bae615b | |||
96854aefa7 | |||
697f63f2e9 | |||
98a1d2b3da | |||
2c541f338c | |||
9dccde4567 | |||
47408443f7 | |||
f673e641f3 | |||
1f44f5f481 | |||
94d4380f39 | |||
5adc7021e4 | |||
14db579540 | |||
3aebbd7173 | |||
1c5b8670d9 | |||
768880fa92 | |||
114a6fe19d | |||
0d3e657e1a | |||
880ec0572f | |||
eba3f39d88 | |||
58ed3067ed | |||
fce58de726 | |||
3677bc15ad | |||
27d8cde394 | |||
3ba923e4c0 | |||
07b1f0ea87 | |||
769485ce29 | |||
1d6becf3b5 | |||
761e1f6fe1 | |||
b34557b839 | |||
a265189efa | |||
4101eea5e8 | |||
b57c752b1c | |||
82a739a95e | |||
0a66780727 | |||
cb92e45712 | |||
28b04878ce | |||
a5df31570e | |||
ed1b2914be | |||
41214cc461 | |||
c371684e5e | |||
c1866f8156 | |||
0939c54048 | |||
d9e2166e97 | |||
17d5e7f0ca | |||
564a5484f7 | |||
8a732c7e14 | |||
998208ef20 | |||
a2082bac93 | |||
3dacc60073 | |||
a5dc3fe777 | |||
5c55eae9a6 | |||
63aef3bcee | |||
deeb2f3cf9 | |||
59098d703e | |||
662289eb28 | |||
392b7d9fdf | |||
db9fcc28d6 | |||
63d4d6591b | |||
9ef9e3755a | |||
b8ddd281aa | |||
363d95f68c | |||
da6b71a677 | |||
c9765e50c8 | |||
cd7f15f112 | |||
4fb001ce50 | |||
e49365755d | |||
9baab16682 | |||
dfcd83ffa3 | |||
8238741f39 | |||
a595557e2d | |||
070d8177c5 | |||
9eb3cd1793 | |||
2f6fe9fac4 | |||
3bf5fb612f | |||
62b28e7033 | |||
860a4ca50e | |||
26a0767737 | |||
4eccad2c27 | |||
3966f79324 | |||
38305fdd4f | |||
9c2f98e1eb | |||
971c5ffbb5 | |||
c1edaa83bd | |||
795e23dd09 | |||
93ff6d5c67 | |||
0dc594f5e1 | |||
fad03b546a | |||
39f4a2bc13 | |||
3cb91fec58 | |||
8276223e68 | |||
2da45cfd1c | |||
82b0128308 | |||
550c505813 | |||
d50d6b0334 | |||
f2d21c410b | |||
ec51566abe | |||
8a2d750970 | |||
46b70bdfba | |||
15e137e266 | |||
93c8bd0253 | |||
10a935790c | |||
68208d73d7 | |||
b57367dd30 | |||
9eb9839a46 | |||
deccf7816c | |||
fe971497cc | |||
8c2be55233 | |||
ab443e8254 | |||
16e53eded8 | |||
a7acf05bfc | |||
5e22cd5f0a | |||
92be7f6791 | |||
94c449936d | |||
89c58265aa | |||
3783e34a70 | |||
414ecdfffa | |||
76afa40270 | |||
17bbc37638 | |||
4b0b3c0c7c | |||
006b4bd49a | |||
5395fc1280 | |||
a293e23fe2 | |||
68e729721d | |||
4f5c16c278 | |||
c15a86b454 | |||
51c8724cff | |||
ccb3b4fbb3 | |||
83bf0d7b2a | |||
f55a8c54cc | |||
dc9350fcc5 | |||
ef5437fec3 | |||
0999db0203 | |||
d84ef62e6c | |||
b5e8bc9ec1 | |||
ccaa4434ad | |||
555ac1c7f3 | |||
b9788b7e1b | |||
c6e332a0f5 | |||
007d41b5af | |||
a1956bc83b | |||
ff61158491 | |||
2c5520cad0 | |||
4bcb0fcb13 | |||
6ef670878d | |||
89e13334ae | |||
82fe1e10d9 | |||
e067a980be | |||
e98fbc47e8 | |||
b6fa60b0bd | |||
7e97156fc4 | |||
7190d933b4 | |||
3699796bc6 | |||
e208ff0664 | |||
adc2a7d169 | |||
dc8e162e26 | |||
522511d059 | |||
d5152fedc4 | |||
d7bef2ae4b | |||
9283cbe1c2 | |||
7dae023a98 | |||
9c88ce1394 | |||
4cb8d4adc7 | |||
5c88803942 | |||
4457b0d879 | |||
58415dcfb9 | |||
76c216d07e | |||
aa3582a2f3 | |||
d80b59e639 | |||
880cb401fb | |||
2e0dcb860a | |||
a9684fb81d | |||
f2b8b82515 | |||
eb7a49f6d4 | |||
982b22ab20 | |||
38acf132c8 | |||
f25824a1aa | |||
446c5523f8 | |||
7bcdc4be44 | |||
6c6389ba65 | |||
0898418cf3 | |||
943b902e23 | |||
74cd310504 | |||
44979f2b07 | |||
a3142a520f | |||
372a01e6da | |||
3b4cd21835 | |||
2d6c06b82f | |||
a9cdb2b48e | |||
60b411757d | |||
19b5835ae4 | |||
48377168b2 | |||
d89f216682 | |||
62489d05cc | |||
84b09301e6 | |||
3c1b564956 | |||
f7d4c6fe34 | |||
d2cc14fa18 | |||
51b2cf120e | |||
dc5506efe3 | |||
628d38df7a | |||
d4c2bf154f | |||
a504caac62 | |||
2653f88b73 | |||
f853f8f8cd | |||
b2437451e3 | |||
c49bff54b1 | |||
b9ed05f38b | |||
4aaa2f8e0f | |||
85c37c6a39 | |||
ed4d8f9e26 | |||
1a03391347 | |||
0999ad32e3 | |||
f62933efd4 | |||
b968f437ca | |||
d9f9c5256a | |||
0da49cfc45 | |||
8735bf3df3 | |||
4db61f243a | |||
a43a3b0803 | |||
bf8cf574e0 | |||
4fed42b5c7 | |||
1f2d9c8a92 | |||
8502fb51b3 | |||
1d30d0831b | |||
0520c606ec | |||
6997c780d9 | |||
631e709471 | |||
1d508c0e04 | |||
28ca230a53 | |||
01b58a4635 | |||
0852dfa112 | |||
7362cd0621 | |||
635d18de92 | |||
484014e2db | |||
2ba0b079ab | |||
2843c333aa | |||
4369023394 | |||
dc97e18955 | |||
c31e2be46f | |||
7539751fc6 | |||
8a8b91998a | |||
c7fbc7f55e | |||
ea5c9f0af4 | |||
76609e2a4a | |||
1923d42c5f | |||
13360bec73 | |||
f1a4cfee61 | |||
ac5d87b2c2 | |||
bf0c1990dd | |||
a8c01e4865 | |||
472613d973 | |||
323341f67a | |||
71c023f485 | |||
48d3b6e952 | |||
2c8808aaff | |||
82693ccae6 | |||
e74ff6a5a4 | |||
eba5b1a920 | |||
a93001a68b | |||
d548457c30 | |||
be1bc6f75c | |||
76358f4289 | |||
652f8b9f74 | |||
dcaf3066bf | |||
b527efde41 | |||
a195a0af30 | |||
52aa992a2f | |||
c602308acb | |||
5a0b3b0f9f | |||
750b098e02 | |||
2a13d923fa | |||
3507155189 | |||
1e4c71e8e3 | |||
8d0a3ac9ae | |||
fb0febb50e | |||
60586fdda4 | |||
b381fc9141 | |||
33da5f3737 | |||
3dcaa5742d | |||
e59d7c2f01 | |||
9946a6892c | |||
9a5b855e2d | |||
a43f62615b | |||
459f91af24 | |||
29f46a56d9 | |||
a2bd08cf64 | |||
208a57eaf8 | |||
2879c86d79 | |||
506a6e0465 | |||
53c029471f | |||
cc32f33815 | |||
e2c1b8c178 | |||
458f2acfe7 | |||
e929dc55bd | |||
b5b42c675d | |||
278e267690 | |||
93ad26fb2a | |||
f8d0e4b90d | |||
35e8a67a48 | |||
0df187edcd | |||
2cfebb0234 | |||
8edd843f4b | |||
6324161b98 | |||
f0f8b78df9 | |||
e0d4ad0a06 | |||
815afdcd11 | |||
88d2b393d8 | |||
07affb56f2 | |||
2ad9a320de | |||
df082de817 | |||
3027b732a5 | |||
af939f4e8d | |||
2ab9fce457 | |||
63b10cfaf5 | |||
dcae78a389 | |||
ea34df433a | |||
0e3727573e | |||
f40ae48849 | |||
7070273616 | |||
923ecaa0e5 | |||
53d9274b45 | |||
4426910b9a | |||
eb010688af | |||
314392bffe | |||
28ede82f91 | |||
a5819d8cf8 | |||
2d0e12363f | |||
cb291dbdd5 | |||
44db80bc75 | |||
bc5445d255 | |||
55613eb882 | |||
04c54128af | |||
82cb94ab56 | |||
82653094fb | |||
7c7422a553 | |||
018b4645e8 | |||
6cec38a329 | |||
8cc73227c7 | |||
93ce1ac470 | |||
bd1999cdfb | |||
8d9ad2ce06 | |||
8ee50cee1b | |||
7183954b08 | |||
564dfbf329 | |||
ab5c11f876 | |||
73ba5d1644 | |||
fd7f4441fb | |||
636f1141e4 | |||
2eac69e9b4 | |||
3b79a063b6 | |||
69b6ed5f56 | |||
07b9bb9987 | |||
9578e8ac3d | |||
39fd00c5be | |||
a3572f7206 | |||
e8a4b46cc5 | |||
6a59d8cd07 | |||
a4db0d927a | |||
bec98dcddd | |||
e27c0b205f | |||
85f14422cb | |||
66c278c64b | |||
04113f8a02 | |||
86c033a922 | |||
91c082878c | |||
3d00b8c545 | |||
0c745590ec | |||
b46ee941d4 | |||
0d3055e505 | |||
4b51565e3b | |||
c9e84c563d | |||
60716cd346 | |||
531cc5f2c1 | |||
d1b290c7a4 | |||
8aaa2d859f | |||
0c6d606fea | |||
8a5806cd25 | |||
40ca5f8002 | |||
e50151343b | |||
6aaf11f2a3 | |||
9d480b05af | |||
3f36b51f6c | |||
7cc586bd0c | |||
b6d6be3c27 | |||
0b834a3f9b | |||
5d5d1e1a7c | |||
d55bffede6 | |||
806895ebd8 | |||
914b53933b | |||
402236e51e | |||
2ebf822dea | |||
389f470662 | |||
522dccef76 | |||
186728053a | |||
507a901a9e | |||
83d2e1a510 | |||
f336585d4f | |||
80fdb2cdb2 | |||
8251ffd25f | |||
5ad341edd7 | |||
2f8939967e | |||
6d84dff2b0 | |||
8112fbe161 | |||
e9db0c8c76 | |||
cbcc91cc09 | |||
7ed757dc0d | |||
8196ddd0b3 | |||
1a48ebb345 | |||
c6fc34a64d | |||
f13599177f | |||
bb292d13ad | |||
6f2121cd4d | |||
3324d65f3f | |||
5c5ca9251e | |||
30f7f6d51f | |||
922a2f6006 | |||
54f3bba89d | |||
5d8150637b | |||
3938933384 | |||
0482883a8a | |||
9e4b1661e3 | |||
4040410c97 | |||
8edf4d674f | |||
847158f400 | |||
6ca3edad0c | |||
0551b46c8b | |||
e5a798357c | |||
c051c7f5b7 | |||
322ad6fd68 | |||
a5bd8463e8 | |||
71926e6d03 | |||
803852ee0c | |||
fc6a193765 | |||
db0dd03128 | |||
429798ae35 | |||
4cc1218391 | |||
83ea8b82b9 | |||
32cd6be7f5 | |||
4d9f2ded74 | |||
6163e25d7d | |||
a3d0767b22 | |||
62e7e22a93 | |||
694d7c118c | |||
a8bb28caa4 | |||
23fb93a3cc | |||
778c2080b0 | |||
94308b208a | |||
b00d313ee8 | |||
4e497d9737 | |||
8cc10bdb3d | |||
e816c86d7a | |||
db77e12615 | |||
79c4d0ca5c | |||
34f12e76c4 | |||
2ac00713a7 | |||
c5761610b8 | |||
d09a8e1aac | |||
16f402ae49 | |||
1e5c9b5ed7 | |||
3125630b21 | |||
32fd0f9e93 | |||
4165548661 | |||
31b71760e4 | |||
18bf26efb6 | |||
d190b207b4 | |||
c4d120082b | |||
38178ea9fa | |||
0dd88dccbd | |||
78b35d80ee | |||
a66f13fc91 | |||
1cb99082e2 | |||
6ea52a9a08 | |||
efe4b674e2 | |||
8016d02319 | |||
67c0230a62 | |||
d5c75fd6a5 | |||
fc9e39a021 | |||
be1475b732 | |||
2931247559 | |||
9657430ef7 | |||
d5cfb53cf8 | |||
10a64737b5 | |||
0be7540637 | |||
3ced207dd3 | |||
d2fb486e70 | |||
c8d69c41bc | |||
3d59eabdc5 | |||
e8a6126473 | |||
62e1856229 | |||
21caa9a0de | |||
a46ec5357e | |||
ca70678155 | |||
c3450df360 | |||
76b6510a27 | |||
a75feafc4f | |||
86c2c2db02 | |||
21d13507b1 | |||
adfe7de08e | |||
116536fe36 | |||
f7dbc25461 | |||
30736ebb53 | |||
dc5e458d9e | |||
4feaa1449f | |||
25002f559a | |||
41f38424ee | |||
862ee2029a | |||
cd30fb0c1c | |||
59ad6c49e3 | |||
2d255829a6 | |||
be762580b7 | |||
ae8bf10746 | |||
324f4c58a8 | |||
a816767abb | |||
164a47bde4 | |||
545769e241 | |||
dcf39196d5 | |||
58dd553d00 | |||
f64ca6a827 | |||
ebd4974c75 | |||
4b1769f457 | |||
f58c0f4508 | |||
4d7bdcde47 | |||
c7a620424e | |||
24260137ec | |||
315e69797d | |||
dddc693369 | |||
13e654aafe | |||
f02c73f94c | |||
92f79ffe88 | |||
db33e50f92 | |||
2ad557024e | |||
ddf3b6df32 | |||
12bf140931 | |||
0d65bb64f9 | |||
c6e265b414 | |||
9ba597b5c1 | |||
b6a4514bd0 | |||
a6daebe7d4 | |||
471ba0adbf | |||
7225aa3cc0 | |||
88b833f879 | |||
6f8816c13f | |||
95ccd6078c | |||
2e5c71f771 | |||
eeb77395cd | |||
e3afe22a48 | |||
73d70aff29 | |||
120c849e4b | |||
138b732e75 | |||
760e29e531 | |||
401ee3c97f | |||
6e52ce7678 | |||
89aab62549 | |||
468d99ff70 | |||
2d787f43de | |||
f0c5e44985 | |||
76760b221d | |||
612a86dbef | |||
369ece2d56 | |||
cc37f479aa | |||
deaaf20713 | |||
e566413224 | |||
368856f122 | |||
52cc204787 | |||
52b1d67ca2 | |||
16ad8739e7 | |||
e67457440d | |||
fc955009da | |||
0dc2ba85e8 | |||
de65e65854 | |||
d95f2cba37 | |||
e2a521583a | |||
f8aac5e88d | |||
4738c92b8e | |||
7ce59966fc | |||
afa1337e62 | |||
cc34f468f0 | |||
3f9598fcbb | |||
97b5391118 | |||
227c13d12c | |||
729932476b | |||
7c21deb0f2 | |||
80048eba61 | |||
0552e5ef58 | |||
ce881a7d30 | |||
80dd7f034d | |||
5fac746feb | |||
67f012b74a | |||
5705e69abb | |||
bece1e6d0c | |||
f2527ecc86 | |||
66b95f64a5 | |||
af79fe8e20 | |||
d3e2bad4e7 | |||
6bebf37f1a | |||
2f27b7da8d | |||
824caab2c5 | |||
a105bc7402 | |||
81ab33d794 | |||
e90364c17b | |||
ac4014ff5a | |||
ad634924fa | |||
2d5f9ba181 | |||
aa0e4e121e | |||
f8227a09b4 | |||
46130a6754 | |||
58c006a9c8 | |||
ea1d72401c | |||
fdbe0e2064 | |||
e239801671 | |||
4be88a5015 | |||
ee02d0b13d | |||
2ec084ffa3 | |||
6636c20336 | |||
27c80b00f8 | |||
6bcb72952c | |||
8c17be27dd | |||
0232b0abee | |||
12fd7a9f0d | |||
71c6e70706 | |||
c5cc94ba98 | |||
8220cc4c01 | |||
57ce74c4c7 | |||
5d6c72bf42 | |||
63b2bbc67e | |||
12f628e3d7 | |||
cd8d800eb7 | |||
160ab3572b | |||
dc57ef1e0c | |||
ca1544564c | |||
462916d00f | |||
e15761b79a | |||
270d898f82 | |||
2a2d5697b8 | |||
b17f277a1b | |||
c15ed5741a | |||
9e035dc744 | |||
ac279b37e4 | |||
974fdc950e | |||
8bb01423b9 | |||
401a23a298 | |||
7ac9ed4b80 | |||
6fdcd8ffae | |||
d50a6302e0 | |||
5fd891bc32 | |||
864f7c268e | |||
4770f28a18 | |||
51a4e2bf4e | |||
c213c771d2 | |||
0176d3a2ae | |||
92653ceebc | |||
c9051ad364 | |||
94d350118d | |||
2e22dde409 | |||
4dad81af30 | |||
b271b01b13 | |||
a17b879380 | |||
ea05af9fe8 | |||
d661196429 | |||
1114443a43 | |||
d802a3c961 | |||
e2226ae809 | |||
fd8a27013b | |||
b12224eabd | |||
c30c3cf35c | |||
f828cde999 | |||
d05c381789 | |||
245054cf48 | |||
da82ce757f | |||
4d74743138 | |||
c1db39d086 | |||
d516824936 | |||
10328f5f81 | |||
d4f09aac74 | |||
8f97ed7934 | |||
1fcf7628a3 | |||
bdd740f8ab | |||
82fed37247 | |||
5b208eb9f5 | |||
9be88ffa42 | |||
f54d112bbb | |||
96c4d33da4 | |||
bad4c02647 | |||
70140ffc8f | |||
53e6bb6b50 | |||
4cb7986426 | |||
18ba13be84 | |||
dd371c4dbe | |||
7ea47c5a96 | |||
5693d2629e | |||
24d9e3266e | |||
b3b3ce4c2d | |||
5882802a3e | |||
94e19aae0c | |||
7d51404aeb | |||
1cdb12c4e4 | |||
e9993cce25 | |||
80bd845182 | |||
f986202b06 | |||
a4168a2096 | |||
3e85589930 | |||
b5a57da29c | |||
58fec512e5 | |||
a6ca045086 | |||
e401231d25 | |||
9ddc24898f | |||
f5350c0e0e | |||
fa64bef511 | |||
29bfd81b36 | |||
2d2506f1c4 | |||
f334fec0a3 | |||
03b6d3e77d | |||
661f6c9851 | |||
593e013572 | |||
b04498cddb | |||
8648bf32a3 | |||
1768ae4b23 | |||
80e6d31998 | |||
381e331dda | |||
13c65f006b | |||
4e8eff3e04 | |||
572ad38366 | |||
b2ade117ec | |||
9eb36bd2bb | |||
85b7ac740b | |||
98d3fb79d7 | |||
bf092b4f95 | |||
a4a9613f5b | |||
ad86bf636f | |||
d0b5886d7d | |||
aa75a143fc | |||
7144f5c794 | |||
befb651268 | |||
c8fdea6216 | |||
4a6a16c627 | |||
6256687272 | |||
5be9ba4a68 | |||
8f61073f43 | |||
a973adb4f2 | |||
96c9fc8bc8 | |||
d472d5d309 | |||
a819a494b8 | |||
f2c3dfa874 | |||
fe3645d809 | |||
b9ff24171f | |||
59fb0a39b2 | |||
94202eec34 | |||
ef8715892b | |||
e5ce86d61a | |||
7825364e06 | |||
5cba645e49 | |||
ef4d04a7e1 | |||
0302803f38 | |||
d57004c91f | |||
f5fe076ec1 | |||
7eaa8a1a39 | |||
de5abef49a | |||
edd9fa2879 | |||
0686da47a6 | |||
4f9f548a58 | |||
2d79c6e634 | |||
ad6c7d412a | |||
686dadc9c5 | |||
70bff9c430 | |||
cefad23b72 | |||
0447c39a97 | |||
688c12ac8b | |||
5cbcd34bec | |||
f9563b5103 | |||
38da105ac1 | |||
cc393d0e8d | |||
25cbe60bf8 | |||
6be3805841 | |||
6e3de2c53a | |||
cf274f7f50 | |||
17cca4587c | |||
3014e60bdb | |||
e5b4b5a53d | |||
bc66a93fcf | |||
8f06e36d04 | |||
e38b64ff82 | |||
4687ecd99b | |||
b1718bc334 | |||
d7063435f4 | |||
a7133501d5 | |||
5078ed9d0f | |||
424a8c17b3 | |||
90c0e32cb3 | |||
d3acbcc319 | |||
a776e832dd | |||
65bd10c47b | |||
9bdd0ba0a4 | |||
ff48a9076b | |||
3f99ce7af5 | |||
4451691aa2 | |||
bc64ae2712 | |||
7f55873bfb | |||
d94016384a | |||
eb87344a16 | |||
43c06b0e36 | |||
a35b96fb7e | |||
562633c040 | |||
71eac5c544 | |||
4fe39dd5cc | |||
7605abc929 | |||
0a4133b4d0 | |||
0086b58f39 | |||
583b67dbb1 | |||
a81f356835 | |||
b2218661f8 | |||
8234977fa9 | |||
13ed6ed2d6 | |||
a7fb4e85c9 | |||
abfca025d5 | |||
34acc54cc9 | |||
b27eaab57f | |||
dd6c169994 | |||
5751d381af | |||
28998b5c14 | |||
a939cd0e2a | |||
d9d5446e86 | |||
b91cc24d32 | |||
faae071ee8 | |||
cdbfa38391 | |||
5d92972aad | |||
ba17c8a75f | |||
389a593f9e | |||
b35e5dbd55 | |||
0591c38d45 | |||
041e73dc7e | |||
431eb72518 | |||
75b63da66f | |||
51d54a96ff | |||
df982ceb79 | |||
ee978890b8 | |||
fa46d2e1b5 | |||
559d8bc7eb | |||
0d90a958ae | |||
cb7bfbf642 | |||
6cf6edb5b6 | |||
b9ee99a3dc | |||
a86302beea | |||
f6d647f614 | |||
32a42886dd | |||
5b1d0dd2b9 | |||
166b5ca650 | |||
044fa19470 | |||
1d6b173e87 | |||
eaf102d78f | |||
31436e3ecf | |||
62cdaf5e10 | |||
0de08a9452 | |||
0de288139d | |||
94d3b31f40 | |||
6d7442fb4f | |||
68ad9c2b9a | |||
191acd8e42 | |||
ce043d0633 | |||
f18354807e | |||
6a97d73167 | |||
586d09e533 | |||
ba24020857 | |||
4b9425cf3b | |||
ef2a9a2b34 | |||
1a3a5331d1 | |||
363e7e2270 | |||
fdbee670c5 | |||
a47ccb2a2a | |||
9e46d2da47 | |||
451a6d8464 | |||
4abd7b4706 | |||
09a08fd2f6 | |||
4609cb409b | |||
955aa04b41 | |||
69a5b5f410 | |||
b94fbb519a | |||
832de07128 | |||
f6b91f9258 | |||
f9ca86cee6 | |||
0ef9b80430 | |||
057929e2f6 | |||
25d629083f | |||
c2502626e6 | |||
76505f172a | |||
79268c5316 | |||
0c36613352 | |||
37a80e6ef6 | |||
7fc97524e2 | |||
842813dcbb | |||
9e194394c3 | |||
e188bf087a | |||
c5aae0d8aa | |||
25f1870020 | |||
911e2ecefe | |||
b9131293c5 | |||
536a4f8472 | |||
29e1a5edc8 | |||
34e5872881 | |||
1d853b5fee | |||
191824d72a | |||
99f65175ff | |||
2f8e311140 | |||
21551a6ea8 | |||
c4f097bb36 | |||
ffbf9fdca6 | |||
3863bd3ccc | |||
a89e1ac536 | |||
2f64226c6b | |||
91da6f1631 | |||
e8c87f8d89 | |||
3cba7811bd | |||
70396a2fc1 | |||
1a53b7bba7 | |||
74ec2e75b8 | |||
b312da8c63 | |||
fe2d28f711 | |||
1b09be51e1 | |||
e1d1802cb9 | |||
db293cc451 | |||
116984afed | |||
a9d4e4e711 | |||
ef908ff4f5 | |||
4631311905 | |||
1106113f2b | |||
35ed810775 | |||
e1a1153018 | |||
e91cd0862e | |||
5ac71db62d | |||
d270feb15f | |||
1c8aca42eb | |||
e0dbc031cc | |||
39eba4134e | |||
9f77c8a4a2 | |||
9b6fb64aba | |||
82d6cb9de0 | |||
8ae1d4ce27 | |||
21541fcc7f | |||
e9e4ab69e6 | |||
35ecd40228 | |||
e8d30a11d7 | |||
36d19dfe04 | |||
5d90ccf088 | |||
de5eb6924a | |||
0600e3357c | |||
40f28a543e | |||
13b6c0764c | |||
950d1b4a5f | |||
85ed8468f8 | |||
756a6a2b65 | |||
e63ed1e3e0 | |||
27c2978617 | |||
b0c9b868cd | |||
101c590f32 | |||
943a75d7e1 | |||
611ad2be94 | |||
64b7c7b600 | |||
cc899d298d | |||
3f2c117039 | |||
0d21377035 | |||
48749382fb | |||
996f461157 | |||
8d898ae459 | |||
b609eead1b | |||
567ab19fe5 | |||
1cc60fc9ad | |||
959a5b9225 | |||
9b8658606b | |||
51ff0a2c49 | |||
c1552aacd6 | |||
ba245458de | |||
c32e747dc1 | |||
7ad84abb09 | |||
dd6abc5487 | |||
3642cedd2b | |||
df87bc06c2 | |||
9d200888ff | |||
ebf0945c6e | |||
7c6d869cb4 | |||
6de8178c30 | |||
1b80dd5584 | |||
7ceaa4801d | |||
15bd719cf5 | |||
acb2b27852 | |||
abbb2f2cc2 | |||
aa8beace98 | |||
d17d9103de | |||
85f5604d43 | |||
fa42dbf011 | |||
d1c27a7534 | |||
8675d6a4a8 | |||
1d770fd400 | |||
d6b704e74c | |||
eeee302722 | |||
81f4a505c1 | |||
560f50eda7 | |||
73f1e4d77e | |||
87fd5e2b4e | |||
01cc4a1bad | |||
ad732d7286 | |||
448da8bd9e | |||
a4be1ac635 | |||
5e46f64d75 | |||
f9281fe309 | |||
d3a49d1d41 | |||
8736214678 | |||
b2aa069cd4 | |||
01bacc3275 | |||
53b7516449 | |||
916325d3db | |||
054f046807 | |||
a4e57797f5 | |||
afef83ae66 | |||
730857a23b | |||
7fd9fff987 | |||
3074ca0756 | |||
7b8165fe6f | |||
3774575160 | |||
57eec2b88e | |||
b2eb9df894 | |||
00e9f2bbea | |||
adf12ab745 | |||
9d4e5b18ee | |||
8a40ed8cd6 | |||
c79909eb80 | |||
26e8b0dbb6 | |||
a2c2dc88fc | |||
99f47224ee | |||
a085cef0d6 | |||
2980fb1d82 | |||
3ed92695be | |||
9d797f8664 | |||
d7dbf60c8f | |||
06923d0f6d | |||
948be015a7 | |||
1a339b2f77 | |||
39479f2403 | |||
e4beb3828a | |||
84caa10733 | |||
a8ff2abab5 | |||
b4d2f83d6f | |||
be28d95b8d | |||
2401d1833e | |||
a189c0bda7 | |||
cc462c9ccb | |||
3d7987e8d8 | |||
1c544f55ca | |||
5c231919b6 | |||
4b48be3e93 | |||
ca07e53293 | |||
3f2a8ccfc5 | |||
e097932ac9 | |||
27e4174be6 | |||
7f47d2de56 | |||
6200ee6977 | |||
e98fb7d6e4 | |||
4e6233b898 | |||
544b74f839 | |||
4a823a0894 | |||
53188ab941 | |||
5f7dabf9b6 | |||
e343d224ce | |||
188023b5ac | |||
f18adbf9d6 | |||
9959ef52b3 | |||
8e58484fc5 | |||
a58ab24b0c | |||
a67085217f | |||
f08f16c20d | |||
ec9d4a52fe | |||
01b955d2d4 | |||
a384a78544 | |||
b4ad89e6ef | |||
2b4ed9cc27 | |||
e986848faf | |||
21ceae3c9e | |||
51b9fae4bc | |||
4e7d24f64b | |||
40640c92d4 | |||
c5b3919122 | |||
29a22bb5fd | |||
2baf9c4c20 | |||
c4727c1dc3 | |||
4901dee86d | |||
c1f2a499f8 | |||
7aa31c764d | |||
08fea0eea1 | |||
add716276b | |||
e688addd98 | |||
199131b2b8 | |||
fb29cbff16 | |||
11fa330f10 | |||
ca720c8c83 | |||
456d7b69a2 | |||
a86cb11fd7 | |||
96c65dcfc4 | |||
86451da9a9 | |||
57607f1a28 | |||
eb4fdf53fa | |||
6251521102 | |||
c940a0b621 | |||
719af5c72c | |||
128d19c69e | |||
46861ff5b4 | |||
ee464539de | |||
f69ff642df | |||
db77c245e6 | |||
d5caf3e2ac | |||
148b365e43 | |||
8c215e5d6f | |||
0513dae63e | |||
f73a8356f6 | |||
77c5198009 | |||
820fedca22 | |||
28a1182cd2 | |||
16444a713a | |||
6457fc45c7 | |||
cb94cccf22 | |||
c0ee97b437 | |||
f950d384b6 | |||
426a71e7f2 | |||
d49b2453bb | |||
74a1db4417 | |||
dc7e1e2494 | |||
5dfbcf2a23 | |||
09c1471c3a | |||
50a882cf4c | |||
850557df5a | |||
4c43eccbb5 | |||
380db7c884 | |||
1994917044 | |||
449f31d78c | |||
bc2386fe47 | |||
ec02883f6e | |||
abd372447a | |||
fef70c0386 | |||
719b32d71f | |||
4e385fec50 | |||
c9b2f2f060 | |||
d038e926fd | |||
712859eb20 | |||
826893d8d2 | |||
47d1881c29 | |||
741666b742 | |||
ee8e30417c | |||
cc4bbadfa2 | |||
8761791473 | |||
6697b7b1d3 | |||
3c9a47aae3 | |||
d1675c82b5 | |||
b40643950d | |||
ff5b1dd7cc | |||
3587483fa6 | |||
c9c26b869c | |||
8f18856e91 | |||
ddfba00791 | |||
c6eaa97391 | |||
5eb095b514 | |||
4e0bfe161e | |||
0e681d9bd4 | |||
3d1162ecd9 | |||
3414cd7ce7 | |||
66386cca59 | |||
75396c753c | |||
4edd77faee | |||
91db6c7398 | |||
46390b83ac | |||
89eda75b1f | |||
f14808e009 | |||
b569ea3c3f | |||
f595be47dc | |||
ee3404fea0 | |||
61fc7da654 | |||
14c3930b3d | |||
3efa25a5fb | |||
c29a7d34e5 | |||
daa873d8ed | |||
c09de969eb | |||
b0dd18580c | |||
32deaa261f | |||
3a8e103faf | |||
f4b1c9f78a | |||
618759f390 | |||
ced5d6ff57 | |||
db4041114f | |||
b52d77e8bf | |||
940b0be4b9 | |||
75f49e78b0 | |||
f06359e38f | |||
2733adbb49 | |||
fc4d8f183b | |||
ea70c77dd8 | |||
301a69aacb | |||
92eda7c214 | |||
4800ab292c | |||
34cfce33a1 | |||
fec17424fb | |||
264dd7a10d | |||
6cef4eab4f | |||
f4ada32ec2 | |||
bff8c3cdcf | |||
3b670333de | |||
eb36757ef1 | |||
054b1f8868 | |||
23234fad0b | |||
74dca8b6ef | |||
2a187988f6 | |||
d1ee9ee9ba | |||
380f560fa4 | |||
d9b6fa1f93 | |||
8a57648b87 | |||
80b8591295 | |||
f94aa52974 | |||
ef8ad4a894 | |||
41b6f6bd4a | |||
9e8f380121 | |||
39070081d1 | |||
00d8ffe503 | |||
4ef8530bba | |||
77aa0f4f8e | |||
766246648d | |||
7963eb1cde | |||
02d8b2c523 | |||
227fb0411e | |||
027ae6dc7e | |||
334905e16e | |||
e3fad723b8 | |||
5e52c45968 | |||
e3a2a2bc17 | |||
18b75cb07c | |||
4e1c5a3e02 | |||
5db290890f | |||
b9c83aa4a2 | |||
bb12f71137 | |||
0a3911231b | |||
846ef95c58 | |||
601bb30b7e | |||
9728b79c33 | |||
90baf98057 | |||
8ad6437dd8 | |||
02bf904467 | |||
62e4bbcfe9 | |||
fc15ac1f41 | |||
01770f0e5b | |||
87ff81a499 | |||
981f41aee0 | |||
605ca152c2 | |||
0fc8f0b489 | |||
c511d80da7 | |||
8304fc143c | |||
f3cfd31668 | |||
ef90960121 | |||
3700b8b39f | |||
b83f2f5257 | |||
06f61cf92a | |||
5a5ff6d8ea | |||
bbe2626fd1 | |||
d5646ae238 | |||
df43d897df | |||
687a0f23da | |||
aa0dc4dbaf | |||
de399c54c6 | |||
58d522e4c3 | |||
3b90cca5bd | |||
b7c9cfeea4 | |||
4fcad51d25 | |||
c2a2fc7dbe | |||
3f0d3c257a | |||
ecc07d4b45 | |||
8da965552b | |||
cfe36dea52 | |||
c16eab09ec | |||
d07cc0424d | |||
c669efd609 | |||
c3151b312a | |||
3fc3ece5b0 | |||
6887dfef16 | |||
867e7615ae | |||
5157be6e3d | |||
82ca25b231 | |||
a555f9b3f0 | |||
c1a6ce2565 | |||
8874666109 | |||
5233be593f | |||
0f38a24555 | |||
8d06f80eeb | |||
0983698d2e | |||
dde43b6e0d | |||
4382158b88 | |||
ba69d73785 | |||
be3d078d5a | |||
b8ca4586ad | |||
25750d2f05 | |||
423a467a70 | |||
d6e18a3e97 | |||
a6d5d89209 | |||
16b35006bd | |||
95b638dbcd | |||
c42fef6d48 | |||
d60d19a3d7 | |||
3f1c730863 | |||
89f5a45e1d | |||
2b2149b643 | |||
f074af039b | |||
30ec1eec60 | |||
0e279c5bc9 | |||
525dfceb1d | |||
83fa1aea27 | |||
6e3f2f9616 | |||
6a77edfa97 | |||
b24f44896c | |||
e23726ac54 | |||
fb2be2256f | |||
1ef7f8dd72 | |||
4008743091 | |||
bff11bc18e | |||
6ada631aaf | |||
9042efd195 | |||
04b88c16a9 | |||
1c6636b106 | |||
a6a03bf51e | |||
b05cf94a23 | |||
b641192e73 | |||
d14c107db1 | |||
2e24077b77 | |||
d819c76024 | |||
89b5496dfb | |||
de44b4382a | |||
c71fc25a9d | |||
5527afc91e | |||
47eb690a89 | |||
bb662770e0 | |||
4d04072672 | |||
4c00d8b95d | |||
f828e1c8a0 | |||
34abaa1d56 | |||
768ea7519f | |||
3eed3b7f07 | |||
3419aa4dc5 | |||
54a00466e8 | |||
5133915e9c | |||
895948ca45 | |||
d0c51bd637 | |||
2e028ebe20 | |||
26349730e5 | |||
c0374c5fe5 | |||
ab2794d4bd | |||
e0af113cac | |||
f9a57a83a0 | |||
b7c0c47c05 | |||
2d9ec5295d | |||
b3f01faf38 | |||
58578690ad | |||
4754ccdd1d | |||
f6facb5349 | |||
1728c02561 | |||
c90d922443 | |||
2f1de39dd3 | |||
ec5f944c03 | |||
d43807a248 | |||
1980c524d3 | |||
31604d44a8 | |||
dba30f7ee6 | |||
1aaf540be4 | |||
d3751054da | |||
0c2dbdbc47 | |||
1485014229 | |||
0ea68c81dc | |||
8fbbda13c6 | |||
a96d26d573 | |||
fb7d1c0a7d | |||
d7d8ba1398 | |||
36c78421ae | |||
083fe35188 | |||
9e4a611b7f | |||
4ed906248d | |||
44bb871f7e | |||
c1a138f370 | |||
569ef4d494 | |||
26465afbf7 | |||
e287a2f202 | |||
91decabfde | |||
9a21e3e9d3 | |||
60940512e2 | |||
d4e69d97e0 | |||
f171842cf8 | |||
3d9bf8bc93 | |||
d7325f4209 | |||
5c177aada0 | |||
5c6289e1f0 | |||
844fbf581e | |||
22bac3c8f4 | |||
35ffbf8ca6 | |||
926f995a3a | |||
8589f0bcf5 | |||
1a2ef38588 | |||
fed8228712 | |||
09d0ba039d | |||
f2dcb89609 | |||
69e7cbc722 | |||
54e88bf8a8 | |||
b0315f5d56 | |||
ec55a2ab97 | |||
1082ef31c7 | |||
ee28532c53 | |||
e4294da5bd | |||
1ba9a39b3f | |||
5453b55bdc | |||
16f51ea619 | |||
b209d92a2a | |||
0def8c9354 | |||
ac59f75523 | |||
f2faf990a0 | |||
7f6e9f5e20 | |||
c12b04d302 | |||
9922b5016f | |||
77fffb46b2 | |||
e7cd31b1d5 | |||
9006673b09 | |||
96271810d8 | |||
8377680989 | |||
00582481c6 | |||
c2255016d2 | |||
9e1c5f2808 | |||
897d93a892 | |||
04be9fb703 | |||
acf722e855 | |||
d2fe1dc043 | |||
dafc8bb678 | |||
d303a2e0b7 | |||
7c8e9509ce | |||
7334f968a8 | |||
f5a997069d | |||
c7f8b3f965 | |||
316ddad7ab | |||
4d34270ee9 | |||
2573c9c4d2 | |||
d72b8de045 | |||
49d24f6829 | |||
6f9ec854dc | |||
9a3e713a69 | |||
3ec4ccd9da | |||
5867e3398f | |||
07ed1baee9 | |||
1e1d479d76 | |||
78c191b4c9 | |||
cf65ebf647 | |||
7b626ab632 | |||
90eafe59a6 | |||
a055d3d373 | |||
267db7cc2b | |||
5043a40c51 | |||
0a74f09273 | |||
767795b91e | |||
8089d42eda | |||
6b9c8ac1ea | |||
3c037270a6 | |||
6ac682cc5b | |||
e378c45be7 | |||
66da3375ba | |||
1df654c6a1 | |||
388915e6f8 | |||
4d8a927ff7 | |||
b8721e0123 | |||
59880371e1 | |||
6c73a7d8d1 | |||
4232d68c92 | |||
17faf3af1f | |||
1c3a871831 | |||
a313c5b95b | |||
b23eba293d | |||
08682ab378 | |||
39cb15cc56 | |||
c5d7417f8e | |||
4c202dadb0 | |||
78dc3ffd39 | |||
1d3dd15e61 | |||
02446ac5f1 | |||
2601879c0b | |||
313e0603e9 | |||
1d145d6c79 | |||
213b0e65dc | |||
079a3e8bcd | |||
3010241fbd | |||
f3ea36c5d7 | |||
55dfbefb40 | |||
1aee2c6f81 | |||
226c7300be | |||
f2af6ad1e6 | |||
02d60ded5d | |||
3d0e25a8ef | |||
baef3362ed | |||
8903bc7f04 | |||
fe2e3a1468 | |||
3cbcebae56 | |||
0fe010f4f0 | |||
cd6e51271c | |||
711ad7b3dc | |||
7ed66f0b38 | |||
3c67dcd326 | |||
8d0b5360c2 | |||
44c5265757 | |||
3297cf2e9b | |||
b040f4474b | |||
5094bba5e9 | |||
e0e4f5cb34 | |||
c0d73ce572 | |||
7d3d04b13d | |||
88e199ff10 | |||
ec3ade999a | |||
57e93ef281 | |||
6122364a24 | |||
ff1be08b8a | |||
a66d04d26f | |||
d20e9527f7 | |||
5c72931b94 | |||
276886022e | |||
8df987cf95 | |||
de30d647d4 | |||
7f70805e63 | |||
1822261046 | |||
2a622424a0 | |||
37a5a38be5 | |||
580b20e720 | |||
9a4f15e4ad | |||
dd5c75888a | |||
e8ec0ad5bf | |||
961b92db2c | |||
af6349454d | |||
32b07e4c0c | |||
e73b3bbbb7 | |||
fbb7c0bb92 | |||
04c43f8589 | |||
9d733d7a6b | |||
30ddeda877 | |||
72e5e9885f | |||
5c6b34b1d8 | |||
7a627f75cf | |||
02cb4b94f5 | |||
0b5c02f678 | |||
ec5f9ec5ca | |||
551d51ea42 | |||
560cd184cc | |||
14297c8408 | |||
385fa07884 | |||
35fdb8aa6e | |||
34c6a1d4be | |||
745c595fc8 | |||
e979252742 | |||
90b7dc2b9c | |||
66bed5a1ab | |||
8575c9a637 | |||
e73acf4fe4 | |||
2f37ab7ede | |||
b1dd324354 | |||
5f00f09314 | |||
f06796c275 | |||
e15c151167 | |||
0b2eae8e0a | |||
4fff936626 | |||
e2c9dbaa62 | |||
b2f3a52884 | |||
a720b62aaa | |||
71e6ce30a3 | |||
4ee0573203 | |||
68354f8964 | |||
d0b37726d5 | |||
51e8519d96 | |||
c6d2516df8 | |||
813bc1a212 | |||
aa3c8fa377 | |||
8cb5ad18f5 | |||
b34179e997 | |||
91aacb1036 | |||
2134a7e36d | |||
6da1dc3e4a | |||
b33a53d258 | |||
bec1e418e7 | |||
5c6db6d743 | |||
ac25c5fc60 | |||
1e36d0ca39 | |||
945900605d | |||
3b6d22d3bf | |||
b254f14285 | |||
38e89f11f4 | |||
f4960433bc | |||
ebe778d0ee | |||
36ad12b6b3 | |||
0c022b1543 | |||
4e9de62da6 | |||
727c798892 | |||
d9b768e2cf | |||
c1d75857f3 | |||
6d91af30b8 | |||
a1d36ff75d | |||
9a3e53478e | |||
7703c36a90 | |||
a3d048880f | |||
53f8d12237 | |||
54fb9fbfef | |||
5a80d24780 | |||
b8bbe4ae8f | |||
da13f4797d | |||
6d35912c67 | |||
02be09dd00 | |||
93cd6dbed5 | |||
8c8ccc51c4 | |||
c7982c2bc3 | |||
4015655141 | |||
980ccfddf5 | |||
891be11032 | |||
269a0e4305 | |||
9fb04f552c | |||
19101470fd | |||
fb8a883eec | |||
8d714dd84e | |||
c6c958db2d | |||
185070a9ad | |||
a86c892af2 | |||
5464977fb7 | |||
f5fc9d026f | |||
d5cb120ab4 | |||
7cbe114cf0 | |||
84771f11a7 | |||
8b35ce2145 | |||
9d3ea5513b | |||
94219ae71a | |||
f4130105b0 | |||
e4d11b321d | |||
c53f54fe20 | |||
c95e1d8ae3 | |||
4ee81cd1ca | |||
9a98b20d1b | |||
ff9bce89f2 | |||
2d9e405b18 | |||
4a74dce0cd | |||
473699e7c8 | |||
a23712bb19 | |||
586fcbc21a | |||
91f0f8786e | |||
2e247acdad | |||
909460a58f | |||
5d8353326a | |||
a0562ce437 | |||
ed5093ae42 | |||
160f52ec39 | |||
293486ff12 | |||
d101d94209 | |||
9b5ce4c2bb | |||
628993f249 | |||
4112c78c11 | |||
ae01b71078 | |||
d966983354 | |||
c392f3cbbc | |||
9419fdecc9 | |||
b822b91c75 | |||
c003f90713 | |||
19fb29c688 | |||
e94e4ce068 | |||
141336817e | |||
6be1f51be2 | |||
db48f4c382 | |||
1cfd5a587a | |||
72a7e9d849 | |||
3818987c33 | |||
6f8c2b828a | |||
f1a6938441 | |||
9b12979b05 | |||
ff8eec09e1 | |||
a9cb464a33 | |||
3a78aff06d | |||
51caf26399 | |||
722cd23065 | |||
e9ebf6bf59 | |||
d4ad09619e | |||
11952467e1 | |||
b63ae4eed8 | |||
2f3950b548 | |||
a653808e9b | |||
a2cf062aeb | |||
67f81dec2a | |||
4bf0a0c6c3 | |||
2b87e6d585 | |||
cf6e1598d5 | |||
1d860645c2 | |||
051657714c | |||
49ee255fa4 | |||
bb9160e21f | |||
b35214cce9 | |||
dca58b7356 | |||
c4af0ff664 | |||
09b3306dc2 | |||
8d86d078c3 | |||
d9f5d9dc32 | |||
f512ff25d8 | |||
40b5e7e817 | |||
f2a2b95013 | |||
ee1144338b | |||
58422ceb29 | |||
d50ede5492 | |||
25071dce26 | |||
4f371ccb6c | |||
d19d570758 | |||
b6d142f481 | |||
16c406fe1a | |||
3af9ae8927 | |||
213694cccc | |||
008474fbe5 | |||
36aa331530 | |||
204e8b7850 | |||
ef0fb41bfd | |||
e648b19651 | |||
365d3ab538 | |||
ada99a3067 | |||
0899098cd8 | |||
2c13271b10 | |||
e6dbc065d1 | |||
c622e1b6c7 | |||
5f4d791129 | |||
bf553e6ce0 | |||
9fc68b6d94 | |||
73516f8772 | |||
f0c7c37a59 | |||
480fbd7aaa | |||
560be731f2 | |||
b5accd4d7a | |||
7799bde73d | |||
5ecd986d9b | |||
1bd7ab3a95 | |||
46adfaedd3 | |||
3bbfca6d08 | |||
76684e68c2 | |||
c032415d35 | |||
d1f082eb1b | |||
5e3acc30c4 | |||
0db3ec3460 | |||
216136c5ce | |||
7961bae20b | |||
7aa6902e36 | |||
93851f289f | |||
484bb04f1c | |||
9d15fa1ef7 | |||
8ae116b6c4 | |||
c4c1ba9a91 | |||
0181a491d8 | |||
27bb44a7fe | |||
d79dfd9884 | |||
9408fb274e | |||
b96eaf1650 | |||
ae893f79f1 | |||
310ad81849 | |||
9a0d61ac27 | |||
7035a79e56 | |||
7ccc346f31 | |||
170331b0c3 | |||
03b2afc7e4 | |||
0bb4e1bfff | |||
21b20dedbb | |||
d01ae06199 | |||
de71cfb4e8 | |||
79a7b7967c | |||
e42aef8714 | |||
9f1bb9345c | |||
f12680f179 | |||
58f13e887c | |||
1efbb0f65e | |||
7f255b2b7f | |||
060a0a565c | |||
5469f70dba | |||
eadd0a8317 | |||
955fcb8549 | |||
2a00a62bcb | |||
796a7ad4d7 | |||
3155a300c6 | |||
f4ed94a9da | |||
b41a3631aa | |||
1335de63b7 | |||
89807bc80e | |||
81b3e662cf | |||
c9a0a3f9be | |||
2a1ee3fd37 | |||
bd11b5eb90 | |||
7fad1802cf | |||
b5ef654987 | |||
3a04fa0788 | |||
c47eb57871 | |||
7acc70ee62 | |||
74d278d1c6 | |||
f90ab9d732 | |||
edfb24bcd1 | |||
85afb2a823 | |||
b14708d6f2 | |||
1dc16b835e | |||
9bed70c543 | |||
1709408ea7 | |||
175c5767f1 | |||
70a1afe05e | |||
7b111a179e | |||
023f9b43ea | |||
c7df3853d5 | |||
e61fa39515 | |||
a1e955370b | |||
a3f5ffdcda | |||
d4bcbf586a | |||
574189468b | |||
d81f4af4c9 | |||
94474b57c1 | |||
0eb04ba899 | |||
a8dab8993e | |||
80a32b6d08 | |||
fbfb43b7d2 | |||
27f5e72afe | |||
06098e3bf1 | |||
e2b83f8bf5 | |||
2c4be26756 | |||
9d3ffda996 | |||
2cd6ea9de3 | |||
7f41ac3410 | |||
5dd3fe742c | |||
3bedaa95e4 | |||
d692d8a4fb | |||
ee7a14faa2 | |||
402c51582f | |||
f88ce70892 | |||
89b4ef92b5 | |||
9276dbb086 | |||
b98478a3ee | |||
5bf3577d9c | |||
ffad9e7af4 | |||
f2bfee294e | |||
ee2c5c4f8b | |||
245932a825 | |||
525f13662e | |||
fdbcb8b9df | |||
597b6dfd32 | |||
e7444ddb97 | |||
4d1d2b5527 | |||
a073c4ae3c | |||
d88b8a28a7 | |||
321fe54d81 | |||
e4713629d9 | |||
515659c29e | |||
0be7ddcbd9 | |||
b25d3a081f | |||
403f22340f | |||
98f946c544 | |||
453d8d8f47 | |||
296208dcb9 | |||
d2576d3801 | |||
2ca6e3382e | |||
65a5e34d38 | |||
739b2b8e80 | |||
3eae9a1699 | |||
f5f2592ef4 | |||
ca3bd4d118 | |||
414b19cc7a | |||
29674d9c75 | |||
a5ca11f88f | |||
fca13d171f | |||
91618c5272 | |||
02611efe76 | |||
13effdeab7 | |||
af69e24eaf | |||
4fccdd676b | |||
ac910f9e56 | |||
c768788f4e | |||
f566d95b4b | |||
1551f500e3 | |||
c6c95f2443 | |||
4d843e0792 | |||
8e23ca757a | |||
77c887d514 | |||
adb57a102e | |||
134ac453c0 | |||
bf786ef950 | |||
2f5c5e0d50 | |||
0dee2be6be | |||
e57742e9de | |||
7a77ac7704 | |||
50877bc846 | |||
786cfd0512 | |||
705eaac795 | |||
d8b1f0b64a | |||
3e2772b698 | |||
868f6dbc57 | |||
edb6e0896f | |||
ecde670a4a | |||
25901fb737 | |||
8b49efed59 | |||
e15bbcfb50 | |||
bf79e177e3 | |||
8b60695829 | |||
9a88c0e240 | |||
5874a313e4 | |||
265ef9ab88 | |||
7bd087281a | |||
9b2a1d204c | |||
8811b56756 | |||
286a0d0d02 | |||
7801cde7f0 | |||
2fb9a5d4b5 | |||
166bbc1101 | |||
123262235e | |||
2f4c021217 | |||
4f64d4daad | |||
04781dd75d | |||
6d74c31597 | |||
d7caf3803e | |||
53332dbe76 | |||
5915a18b3c | |||
9d0481e7df | |||
db726a5ba2 | |||
0cb1aabb90 | |||
15b12e7a55 | |||
538876a82c | |||
26d5f430e2 | |||
a2edcc38b1 | |||
5e14f93868 | |||
1417434533 | |||
52b9b7f04d | |||
b409769f2b | |||
0338fe0343 | |||
3910dfce12 | |||
132c4dd9e4 | |||
65df08c363 | |||
17c00abbde | |||
5a93f4a80b | |||
3a904ed05c | |||
b70eac0461 | |||
53d860a47e | |||
30ca720920 | |||
afce6de801 | |||
2a57fa02ca | |||
221375b730 | |||
bbf8a21693 | |||
6dc00f64f8 | |||
8e8633a49a | |||
c39b5d1ec6 | |||
82d5b42356 | |||
cfbf4bf5b5 | |||
98d1644ade | |||
521d6ee7d2 | |||
9f868f27ff | |||
bcb2adf95a | |||
b7e9f34471 | |||
1a9d55a0f4 | |||
0aa11dcae7 | |||
6cd5790ea8 | |||
6236590aed | |||
138e984e66 | |||
bd93ea88a5 | |||
1c7aa62db1 | |||
1cd4dc20dc | |||
18490e545c | |||
594edabac0 | |||
0b9f3d8e8c | |||
064853d9d5 | |||
c504df473d | |||
5daf73e3d5 | |||
011d9ecc33 | |||
7b14a4bb4e | |||
0f8ec91e00 | |||
ef11026195 | |||
bcc8292730 | |||
3439fac417 | |||
287720c4e4 | |||
fa7dc91449 | |||
a6f7742e86 | |||
59bb24e791 | |||
09da646086 | |||
fd9666d068 | |||
41c7d041df | |||
8ea1c7f486 | |||
63c2c0a322 | |||
c00fffa444 | |||
78a88d90a0 | |||
aaa1e781c2 | |||
4003204ffe | |||
60c6b1703d | |||
06dd58e7a4 | |||
fc58946ffa | |||
5b7e96532d | |||
228d3a13c8 | |||
7c9be9c348 | |||
919953b661 | |||
f0f6dc88b1 | |||
4878c66032 | |||
9656eac079 | |||
8973af479c | |||
221d5b623d | |||
1d555a66f8 | |||
0dd5024408 | |||
e0f1b56363 | |||
8dceb45567 | |||
ab6909a60c | |||
dc971460ff | |||
f5eb46d234 | |||
67b13237d6 | |||
994e41d7cf | |||
7ed7d37914 | |||
28b21550d4 | |||
f413bf37a2 | |||
b5e960ed3b | |||
3c99a32272 | |||
ed7b584b49 | |||
e4a735d447 | |||
e0a9c60bf1 | |||
9ccddad1cf | |||
59b03740c9 | |||
325afaa612 | |||
017c94eae1 | |||
93f6a136fa | |||
413f02ab2a | |||
5b8f7e471f | |||
3dedf9976b | |||
ff23a74e9c | |||
7083c898f0 | |||
5ea3af0b2b | |||
b67da6965f | |||
75c5bebc41 | |||
42c187fa33 | |||
09e13f5dd9 | |||
3c22ae73a1 | |||
feda453e6d | |||
1b09d4e3fc | |||
721f86001e | |||
5b9a7451c3 | |||
3b2d711c4f | |||
667d06b126 | |||
88cc9156fe | |||
c6813d1f18 | |||
e6fc5904b5 | |||
6b89c12f73 | |||
429c295738 | |||
743767610a | |||
47dd28bd63 | |||
285a4ffed8 | |||
e8d33e1379 | |||
e1a3b158d0 | |||
6e9b836767 | |||
552e82861b | |||
4adb119f8e | |||
502d006e84 | |||
feedb222f8 | |||
67d8042df1 | |||
f520743aa2 | |||
67fbc56618 | |||
de668db307 | |||
de8e8e699b | |||
4f3be95a36 | |||
527ca0efb7 | |||
8671c25b2e | |||
cf137b54ad | |||
eeebee0e18 | |||
b5e9fe2d49 | |||
1b43105658 | |||
f69da4341b | |||
fc3b165e57 | |||
8885714465 | |||
9c24b9ae05 | |||
f4de83c31a | |||
8477d8834a | |||
d4aef1a60b | |||
8fa1a42c1b | |||
e60d1c815c | |||
9c59ece7a4 | |||
932dec9dee | |||
136873b9ea | |||
60da2d5621 | |||
9057043180 | |||
6d8f61c4e0 | |||
a9c5228c31 | |||
45a3493256 | |||
ca24deb6b9 | |||
7741f8f6a9 | |||
bf1340cf14 | |||
35c2c41a41 | |||
8e227f4f54 | |||
3d521e5d30 | |||
4ab6b083c1 | |||
0d07a13dbe | |||
d17945c087 | |||
42ff533d65 | |||
4b3d2d3133 | |||
37d144abe5 | |||
553f1872a5 | |||
ab03ce077e | |||
1af005a047 | |||
0660f872eb | |||
07ecc9f6fe | |||
8cff99c7f4 | |||
f7e0baa45e | |||
259a9d70ec | |||
d3bb65eec7 | |||
8840c03dff | |||
5cbc863f33 | |||
667b15787d | |||
577c8c5f61 | |||
5ce181a995 | |||
175e3ed1cd | |||
ce15e9a3ba | |||
c6b0c75b72 | |||
ca0a32a546 | |||
b4107e3523 | |||
9e99831fb2 | |||
e620debd1f | |||
549e9d6b55 | |||
9307994060 | |||
8c600f90c3 | |||
14e59c6967 | |||
7695d24a50 | |||
86b1021f45 | |||
642eb769b2 | |||
3d3775ec00 | |||
a6af81e359 | |||
e0a9729b47 | |||
9627b4803d | |||
55b57ca0cb | |||
9df4374195 | |||
8afd62a7c9 | |||
997a79a692 | |||
5a91f05748 | |||
6ae66d39b8 | |||
54bc9cb10e | |||
9e852deb17 | |||
5c3ce78c58 | |||
c3d50a293d | |||
c74ebdf401 | |||
23c4f0b666 | |||
f88bd58919 | |||
7853e0c3e8 | |||
af29e2fb81 | |||
8b256eb8bb | |||
86598d3582 | |||
2ee078bada | |||
a21537f644 | |||
e45e0c9634 | |||
86fb009e43 | |||
37a08f66b0 | |||
7bb4c78a33 | |||
2cf4801f6b | |||
af1242415c | |||
104514f988 | |||
ecd0c53ca1 | |||
836e6267dc | |||
58cf8a1416 | |||
1f31c6e309 | |||
e9e4b380cb | |||
7c4324b963 | |||
90f777d593 | |||
e2ff797de4 | |||
5ce096457a | |||
d7a8292419 | |||
be5276dde6 | |||
18abdd8149 | |||
c3661e8bb3 | |||
b9b2a2581e | |||
7b5b6195c2 | |||
771a16db26 | |||
e6d53c4666 | |||
863805ff6f | |||
ccf02c9484 | |||
a019ef2d52 | |||
eead209a39 | |||
16867d6f24 | |||
1b263d13aa | |||
807e3f04bf | |||
4b517fe1ad | |||
dd4bc05952 | |||
a04df29f22 | |||
de5bdad8de | |||
7aa98c9038 | |||
7c2fc26c4f | |||
97e2c3b902 | |||
8cb40e903e | |||
32efef099c | |||
0cb086eb6b | |||
2a7709d680 | |||
4e7209eeab | |||
3b0d52c8d3 | |||
4549115165 | |||
acc0439d3c | |||
6faef3b75a | |||
91eacb7464 | |||
3a3acb517b | |||
de3dbd8a1d | |||
f508690552 | |||
7921f93335 | |||
c088c4835f | |||
81e7de4a2e | |||
fc4e813d9a | |||
3120b750f4 | |||
72a0a37f74 | |||
79a87f4cc8 | |||
85b0e04ca3 | |||
72aeebfeb7 | |||
21287f4f3a | |||
607da4d4a2 | |||
81cd9b4449 | |||
8c4e8e20a5 | |||
8eae80c6e9 | |||
29e36fdee2 | |||
c2784feb71 | |||
f51ca46646 | |||
f8f553d485 | |||
992d863436 | |||
f75cf50eac | |||
8f96e95d07 | |||
4d01d5625c | |||
aaf8bd7af9 | |||
add9b1126a | |||
1d9cba3fcf | |||
2a460d8c18 | |||
8f63a1a7b9 | |||
24791ac315 | |||
8ef66cee8c | |||
205f3734cd | |||
9441505ab3 | |||
82e2cf7741 | |||
d98d6af9e3 | |||
dab5306655 | |||
284ec17eea | |||
0483e491b3 | |||
7d13e8cd01 | |||
b9c9e9d100 | |||
79e214a6ea | |||
06da72658b | |||
64bf40aaa3 | |||
1fa97936ff | |||
74d424c2a3 | |||
23bea839da | |||
1f178b916f | |||
c1291e7504 | |||
2a1e246658 | |||
70e3d68643 | |||
688e986999 | |||
35f04bd679 | |||
f25a4cc22c | |||
15123043fe | |||
3042aef82e | |||
611135de3d | |||
8e351d74d0 | |||
204fa550c3 | |||
4f4c87d9b2 | |||
b0e6ea16ce | |||
b677e5c164 | |||
b01c6a27f6 | |||
5889743b3e | |||
b300c1dfe2 | |||
32b0c93539 | |||
97bf30cb2a | |||
23200da401 | |||
9037291791 | |||
93cb272d45 | |||
b008438e6c | |||
b9530d538b | |||
773e358596 | |||
52722d7ebf | |||
75c3cd90e0 | |||
ffae6da15e | |||
1428a87edc | |||
56de4677b8 | |||
fd9cc48bad | |||
bfdd7db2a7 | |||
5866200876 | |||
eaf5384522 | |||
f499dd947b | |||
0cc0253f5c | |||
2fa8e1fa1b | |||
0612e67e2d | |||
bada4d4336 | |||
9902faa81c | |||
cdbfcdc4c4 | |||
5c1287bbfb | |||
05cf53e1b9 | |||
a3c9489360 | |||
63e1d7e43b | |||
a82b5383d7 | |||
9b551916f1 | |||
64a7afa371 | |||
c7981eb54b | |||
a6473737a2 | |||
3fc4049b0a | |||
4f6450abf0 | |||
130f274f86 | |||
98c63e8efd | |||
2b7b1a844c | |||
012507c38a | |||
a9a46e20b2 | |||
ab110d3d27 | |||
cfb45c1302 | |||
e40daf1315 | |||
5967f7d951 | |||
ca0c0bfce2 | |||
079f824a81 | |||
d850e62a02 | |||
10b887147e | |||
df2a96e2d7 | |||
63bc246264 | |||
16e3582ef5 | |||
0a582d4635 | |||
cd3f57987b | |||
ecbf698486 | |||
64a0c95bfa | |||
894d650593 | |||
8d89be8de3 | |||
b9bb70d410 | |||
8c7938d47a | |||
c78e2bcf7e | |||
0bea18ca9f | |||
7937c77eed | |||
8110271bdd | |||
f566ac2eb7 | |||
b311a9ccc3 | |||
2a7b5b714d | |||
f711baf3df | |||
5c82095e81 | |||
15904761e8 | |||
6d58afcedb | |||
1b0cc63b5b | |||
94b9bc9939 | |||
95445293a2 | |||
431bfbb4d9 | |||
e47104aa29 | |||
180fa52acb | |||
bbbe0cda78 | |||
b21bbcbf90 | |||
66a1f11387 | |||
2b366a354c | |||
cebf782a90 | |||
4ffa954055 | |||
556e9cee57 | |||
421c62c6a0 | |||
9bec921fd8 | |||
b7b2d59613 | |||
db41e1830a | |||
9061e13e11 | |||
a72b749fac | |||
cd0cd140ac | |||
7fef5aad34 | |||
38af364744 | |||
a7c4f5a147 | |||
96b79cd24f | |||
bbb5adc70f | |||
a4eccaa4bb | |||
6a10397641 | |||
398773849c | |||
41c8013adf | |||
93a4d8a0d3 | |||
bf35c8f079 | |||
1425615e20 | |||
ee947b1673 | |||
439550c2ac | |||
35fe033d53 | |||
8b81138800 | |||
308e77d3b1 | |||
e6ad1b5b65 | |||
b70fb5b525 | |||
1dfe40c135 | |||
29f31e808f | |||
f4a729e85a | |||
d3839db6f8 | |||
41a56a8fda | |||
812ee46260 | |||
5ddb726a12 | |||
5b56c27e67 | |||
faafdf9498 | |||
d9b84087d9 | |||
79b2095932 | |||
5679cb285a | |||
47a2ecaa81 | |||
1e78c58aa9 | |||
d819a55802 | |||
7d1a26e4ca | |||
d0965d38c8 | |||
6a8380fb0f | |||
cecb04944f | |||
d47ed6c48c | |||
4656bb246e | |||
fe3977ee61 | |||
486e8da7a8 | |||
d65d599b2c | |||
655c5a5db3 | |||
3598791060 | |||
b505bdb7e8 | |||
1e69aaff18 | |||
fa725d1838 | |||
be58c942c0 | |||
bed1df8237 | |||
7206639ef9 | |||
fbb6b260a6 | |||
753426440d | |||
de0cf4da9a | |||
923f3a987f | |||
145455ecfb | |||
21dbe183e3 | |||
0bdc09d3d9 | |||
31f59ea92e | |||
513a005f3d | |||
91d4d821ec | |||
acb2ebaaf9 | |||
6385e00106 | |||
666bc67f3d | |||
2d327e8d14 | |||
d1379bb671 | |||
0f4c470e67 | |||
af26dc83a5 | |||
87378017fd | |||
e25aadd7a3 | |||
a26606f799 | |||
b938e955f5 | |||
864c6d6aa4 | |||
96ab54a107 | |||
d37bdc026c | |||
10a28dcde9 | |||
57747fff55 | |||
5cb9cb1c05 | |||
db278c390d | |||
8ffcb98ce7 | |||
c2879eafab | |||
214f914547 | |||
1e880869e7 | |||
d3a58298c9 | |||
0b129c3a9f | |||
da149e4580 | |||
913b72451d |
200
amxmodx/CCmd.cpp
200
amxmodx/CCmd.cpp
@ -29,16 +29,16 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CCmd.h"
|
||||
|
||||
// *****************************************************
|
||||
// class CmdMngr
|
||||
// *****************************************************
|
||||
CmdMngr::CmdMngr() {
|
||||
memset(sortedlists,0,sizeof(sortedlists));
|
||||
|
||||
CmdMngr::CmdMngr()
|
||||
{
|
||||
memset(sortedlists, 0, sizeof(sortedlists));
|
||||
srvcmdlist = 0;
|
||||
clcmdlist = 0;
|
||||
prefixHead = 0;
|
||||
@ -51,15 +51,14 @@ CmdMngr::CmdMngr() {
|
||||
|
||||
}
|
||||
|
||||
CmdMngr::Command::Command( CPluginMngr::CPlugin* pplugin,const char* pcmd,
|
||||
const char* pinfo , int pflags , int pfunc,
|
||||
bool pviewable, CmdMngr* pparent ) : commandline(pcmd) , info(pinfo) {
|
||||
|
||||
CmdMngr::Command::Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags,
|
||||
int pfunc, bool pviewable, CmdMngr* pparent) : commandline(pcmd), info(pinfo)
|
||||
{
|
||||
char szCmd[64], szArg[64];
|
||||
*szCmd = 0; *szArg=0;
|
||||
sscanf(pcmd,"%s %s",szCmd,szArg);
|
||||
command.set(szCmd);
|
||||
argument.set(szArg);
|
||||
*szCmd = 0; *szArg = 0;
|
||||
sscanf(pcmd, "%s %s", szCmd, szArg);
|
||||
command.assign(szCmd);
|
||||
argument.assign(szArg);
|
||||
plugin = pplugin;
|
||||
flags = pflags;
|
||||
cmdtype = 0;
|
||||
@ -75,95 +74,88 @@ CmdMngr::Command::~Command()
|
||||
++uniqueid;
|
||||
}
|
||||
|
||||
CmdMngr::Command* CmdMngr::registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable )
|
||||
CmdMngr::Command* CmdMngr::registerCommand(CPluginMngr::CPlugin* plugin, int func, char* cmd, char* info, int level, bool listable)
|
||||
{
|
||||
Command* b = new Command( plugin , cmd , info , level , func , listable, this );
|
||||
if ( b == 0 ) return 0;
|
||||
setCmdLink( &sortedlists[0] , b );
|
||||
return b;
|
||||
Command* b = new Command(plugin, cmd, info, level, func, listable, this);
|
||||
if (b == 0) return 0;
|
||||
setCmdLink(&sortedlists[0], b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
CmdMngr::Command* CmdMngr::getCmd( long int id ,int type, int access )
|
||||
CmdMngr::Command* CmdMngr::getCmd(long int id, int type, int access)
|
||||
{
|
||||
//if ( id >= 1024 || id < 0 ) return (Command*)id;
|
||||
if ( id < 0 ){
|
||||
for (CmdMngr::iterator a = begin( type ); a ; ++a){
|
||||
if ( (*a).id == id )
|
||||
//if (id >= 1024 || id < 0) return (Command*)id;
|
||||
if (id < 0)
|
||||
{
|
||||
for (CmdMngr::iterator a = begin(type); a ; ++a)
|
||||
{
|
||||
if ((*a).id == id)
|
||||
return &(*a);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( (id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype) )
|
||||
if ((id < buf_cmdid) || (access != buf_cmdaccess) || (type != buf_cmdtype))
|
||||
{
|
||||
buf_cmdptr = begin( type );
|
||||
buf_cmdptr = begin(type);
|
||||
buf_cmdaccess = access;
|
||||
buf_cmdtype = type;
|
||||
buf_cmdid = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int a = id;
|
||||
id -= buf_cmdid;
|
||||
buf_cmdid = a;
|
||||
}
|
||||
|
||||
while ( buf_cmdptr )
|
||||
while (buf_cmdptr)
|
||||
{
|
||||
|
||||
if ( (*buf_cmdptr).gotAccess( access ) &&
|
||||
(*buf_cmdptr).getPlugin()->isExecutable( (*buf_cmdptr).getFunction() )
|
||||
&& (*buf_cmdptr).isViewable() )
|
||||
if ((*buf_cmdptr).gotAccess(access) && (*buf_cmdptr).getPlugin()->isExecutable((*buf_cmdptr).getFunction()) && (*buf_cmdptr).isViewable())
|
||||
{
|
||||
|
||||
if ( id-- == 0 )
|
||||
if (id-- == 0)
|
||||
return &(*buf_cmdptr);
|
||||
|
||||
}
|
||||
|
||||
++buf_cmdptr;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdMngr::getCmdNum( int type, int access )
|
||||
int CmdMngr::getCmdNum(int type, int access)
|
||||
{
|
||||
if ( (access == buf_access) && (type == buf_type) )
|
||||
return buf_num; // once calculated don't have to be done again
|
||||
if ((access == buf_access) && (type == buf_type))
|
||||
return buf_num; // once calculated don't have to be done again
|
||||
|
||||
buf_access = access;
|
||||
buf_type = type;
|
||||
buf_num = 0;
|
||||
|
||||
CmdMngr::iterator a = begin( type );
|
||||
CmdMngr::iterator a = begin(type);
|
||||
|
||||
while ( a )
|
||||
while (a)
|
||||
{
|
||||
|
||||
if ( (*a).gotAccess( access ) &&
|
||||
(*a).getPlugin()->isExecutable( (*a).getFunction() )
|
||||
&& (*a).isViewable() )
|
||||
++buf_num;
|
||||
if ((*a).gotAccess(access) && (*a).getPlugin()->isExecutable((*a).getFunction()) && (*a).isViewable())
|
||||
++buf_num;
|
||||
++a;
|
||||
}
|
||||
|
||||
return buf_num;
|
||||
}
|
||||
|
||||
void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
|
||||
void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
|
||||
{
|
||||
CmdLink* np = new CmdLink( c );
|
||||
CmdLink* np = new CmdLink(c);
|
||||
|
||||
if ( np == 0 ) return;
|
||||
if (np == 0) return;
|
||||
|
||||
if ( sorted )
|
||||
if (sorted)
|
||||
{
|
||||
while( *a )
|
||||
while (*a)
|
||||
{
|
||||
int i = strcmp(c->getCommand(),(*a)->cmd->getCommand() );
|
||||
int i = strcmp(c->getCommand(), (*a)->cmd->getCommand());
|
||||
|
||||
if ( (i<0) || (i==0) && ( strcmp( c->getArgument() , (*a)->cmd->getArgument() ) < 0 ) )
|
||||
if ((i < 0) || (i == 0) && (strcmp(c->getArgument(), (*a)->cmd->getArgument()) < 0))
|
||||
break;
|
||||
|
||||
a = &(*a)->next;
|
||||
@ -171,84 +163,101 @@ void CmdMngr::setCmdLink( CmdLink** a , Command* c, bool sorted )
|
||||
|
||||
np->next = *a;
|
||||
*a = np;
|
||||
}
|
||||
else
|
||||
{
|
||||
while ( *a ) a = &(*a)->next;
|
||||
} else {
|
||||
while (*a) a = &(*a)->next;
|
||||
*a = np;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void CmdMngr::clearCmdLink( CmdLink** phead, bool pclear )
|
||||
void CmdMngr::clearCmdLink(CmdLink** phead, bool pclear)
|
||||
{
|
||||
while( *phead ){
|
||||
while (*phead)
|
||||
{
|
||||
CmdLink* pp = (*phead)->next;
|
||||
if ( pclear ) delete (*phead)->cmd;
|
||||
|
||||
if (pclear) delete (*phead)->cmd;
|
||||
delete *phead;
|
||||
*phead = pp;
|
||||
}
|
||||
}
|
||||
|
||||
void CmdMngr::Command::setCmdType( int a )
|
||||
void CmdMngr::Command::setCmdType(int a)
|
||||
{
|
||||
switch(a){
|
||||
case CMD_ConsoleCommand: cmdtype |= 3; break;
|
||||
case CMD_ClientCommand: cmdtype |= 1; break;
|
||||
case CMD_ServerCommand: cmdtype |= 2; break;
|
||||
switch (a)
|
||||
{
|
||||
case CMD_ConsoleCommand: cmdtype |= 3; break;
|
||||
case CMD_ClientCommand: cmdtype |= 1; break;
|
||||
case CMD_ServerCommand: cmdtype |= 2; break;
|
||||
}
|
||||
if ( cmdtype & 1 ) { // ClientCommand
|
||||
parent->setCmdLink( &parent->sortedlists[1] , this );
|
||||
if ( !parent->registerCmdPrefix( this ) )
|
||||
parent->setCmdLink( &parent->clcmdlist , this , false );
|
||||
|
||||
if (cmdtype & 1) // ClientCommand
|
||||
{
|
||||
parent->setCmdLink(&parent->sortedlists[1], this);
|
||||
|
||||
if (!parent->registerCmdPrefix(this))
|
||||
parent->setCmdLink(&parent->clcmdlist, this, false);
|
||||
}
|
||||
if ( cmdtype & 2 ) { // ServerCommand
|
||||
parent->setCmdLink( &parent->sortedlists[2] , this );
|
||||
parent->setCmdLink( &parent->srvcmdlist , this , false );
|
||||
|
||||
if (cmdtype & 2) // ServerCommand
|
||||
{
|
||||
parent->setCmdLink(&parent->sortedlists[2], this);
|
||||
parent->setCmdLink(&parent->srvcmdlist, this, false);
|
||||
}
|
||||
}
|
||||
|
||||
const char* CmdMngr::Command::getCmdType() const {
|
||||
switch( cmdtype ){
|
||||
case 1: return"client";
|
||||
case 2: return "server";
|
||||
case 3: return "console";
|
||||
const char* CmdMngr::Command::getCmdType() const
|
||||
{
|
||||
switch (cmdtype)
|
||||
{
|
||||
case 1: return "client";
|
||||
case 2: return "server";
|
||||
case 3: return "console";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
bool CmdMngr::registerCmdPrefix( Command* cc )
|
||||
bool CmdMngr::registerCmdPrefix(Command* cc)
|
||||
{
|
||||
CmdPrefix** b = findPrefix( cc->getCommand() );
|
||||
if (*b){
|
||||
setCmdLink( &(*b)->list , cc , false );
|
||||
CmdPrefix** b = findPrefix(cc->getCommand());
|
||||
|
||||
if (*b)
|
||||
{
|
||||
setCmdLink(&(*b)->list, cc, false);
|
||||
cc->prefix = (*b)->name.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CmdMngr::registerPrefix( const char* nn )
|
||||
void CmdMngr::registerPrefix(const char* nn)
|
||||
{
|
||||
if ( *nn == 0 ) return;
|
||||
CmdPrefix** b = findPrefix( nn );
|
||||
if (*nn == 0) return;
|
||||
CmdPrefix** b = findPrefix(nn);
|
||||
|
||||
if (*b) return;
|
||||
*b = new CmdPrefix( nn , this );
|
||||
*b = new CmdPrefix(nn, this);
|
||||
}
|
||||
|
||||
CmdMngr::CmdPrefix** CmdMngr::findPrefix( const char* nn ){
|
||||
CmdMngr::CmdPrefix** CmdMngr::findPrefix(const char* nn)
|
||||
{
|
||||
CmdPrefix** aa = &prefixHead;
|
||||
while(*aa){
|
||||
if ( !strncmp( (*aa)->name.str(), nn, (*aa)->name.size() ) )
|
||||
|
||||
while (*aa)
|
||||
{
|
||||
if (!strncmp((*aa)->name.c_str(), nn, (*aa)->name.size()))
|
||||
break;
|
||||
aa=&(*aa)->next;
|
||||
aa = &(*aa)->next;
|
||||
}
|
||||
|
||||
return aa;
|
||||
}
|
||||
|
||||
void CmdMngr::clearPrefix(){
|
||||
while(prefixHead){
|
||||
void CmdMngr::clearPrefix()
|
||||
{
|
||||
while (prefixHead)
|
||||
{
|
||||
CmdPrefix* a = prefixHead->next;
|
||||
delete prefixHead;
|
||||
prefixHead = a;
|
||||
@ -266,7 +275,8 @@ void CmdMngr::clear()
|
||||
clearBufforedInfo();
|
||||
}
|
||||
|
||||
void CmdMngr::clearBufforedInfo() {
|
||||
void CmdMngr::clearBufforedInfo()
|
||||
{
|
||||
buf_type = -1;
|
||||
buf_access = 0;
|
||||
buf_id = -1;
|
||||
|
@ -36,7 +36,8 @@
|
||||
// class CmdMngr
|
||||
// *****************************************************
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CMD_ConsoleCommand,
|
||||
CMD_ClientCommand,
|
||||
CMD_ServerCommand
|
||||
@ -48,14 +49,17 @@ public:
|
||||
class Command;
|
||||
friend class Command;
|
||||
|
||||
class Command {
|
||||
class Command
|
||||
{
|
||||
friend class CmdMngr;
|
||||
|
||||
CPluginMngr::CPlugin* plugin;
|
||||
CmdMngr* parent;
|
||||
String command;
|
||||
String argument;
|
||||
String commandline;
|
||||
String info;
|
||||
|
||||
bool listable;
|
||||
int function;
|
||||
int flags;
|
||||
@ -63,33 +67,33 @@ public:
|
||||
int cmdtype;
|
||||
int prefix;
|
||||
static int uniqueid;
|
||||
Command( CPluginMngr::CPlugin* pplugin,const char* pcmd, const char* pinfo , int pflags , int pfunc, bool pviewable, CmdMngr* pparent );
|
||||
|
||||
Command(CPluginMngr::CPlugin* pplugin, const char* pcmd, const char* pinfo, int pflags, int pfunc, bool pviewable, CmdMngr* pparent);
|
||||
~Command();
|
||||
public:
|
||||
|
||||
inline const char* getCommand() const{ return command.str(); }
|
||||
inline const char* getArgument() const{ return argument.str(); }
|
||||
inline const char* getCmdInfo() const{ return info.str(); }
|
||||
inline const char* getCmdLine() const{ return commandline.str(); }
|
||||
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.str()+prefix, cmd+prefix ) && (argument.empty() || !stricmp(argument.str() , arg ))); }
|
||||
inline bool matchCommand(const char* cmd) { return (!strcmp(command.str(), cmd )); }
|
||||
inline const char* getCommand() { return command.c_str(); }
|
||||
inline const char* getArgument() { return argument.c_str(); }
|
||||
inline const char* getCmdInfo() { return info.c_str(); }
|
||||
inline const char* getCmdLine() { return commandline.c_str(); }
|
||||
inline bool matchCommandLine(const char* cmd, const char* arg) { return (!stricmp(command.c_str() + prefix, cmd + prefix) && (argument.empty() || !stricmp(argument.c_str(), arg))); }
|
||||
inline bool matchCommand(const char* cmd) { return (!strcmp(command.c_str(), cmd)); }
|
||||
inline int getFunction() const { return function; }
|
||||
inline bool gotAccess(int f) const { return (!flags||((flags & f)==flags)); }
|
||||
inline bool gotAccess(int f) const { return (!flags || ((flags & f) == flags)); }
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline bool isViewable() const { return listable; }
|
||||
inline int getFlags() const { return flags; }
|
||||
inline long int getId() const { return (long int)id; }
|
||||
const char* getCmdType() const;
|
||||
void setCmdType( int a );
|
||||
|
||||
const char* getCmdType() const;
|
||||
void setCmdType(int a);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
struct CmdPrefix;
|
||||
friend struct CmdPrefix;
|
||||
|
||||
struct CmdLink {
|
||||
struct CmdLink
|
||||
{
|
||||
Command* cmd;
|
||||
CmdLink* next;
|
||||
CmdLink(Command* c): cmd(c), next(0) {}
|
||||
@ -99,36 +103,40 @@ private:
|
||||
CmdLink* srvcmdlist;
|
||||
CmdLink* clcmdlist;
|
||||
|
||||
struct CmdPrefix {
|
||||
CmdMngr* parent;
|
||||
struct CmdPrefix
|
||||
{
|
||||
String name;
|
||||
CmdMngr* parent;
|
||||
CmdLink* list;
|
||||
CmdPrefix* next;
|
||||
CmdPrefix( const char* nn , CmdMngr* pp) : name(nn),parent(pp),list(0),next(0){}
|
||||
~CmdPrefix(){ parent->clearCmdLink(&list); }
|
||||
CmdPrefix(const char* nn, CmdMngr* pp): name(nn), parent(pp), list(0), next(0) {}
|
||||
~CmdPrefix() { parent->clearCmdLink(&list); }
|
||||
} *prefixHead;
|
||||
|
||||
bool registerCmdPrefix( Command* cc );
|
||||
CmdPrefix** findPrefix( const char* nn );
|
||||
bool registerCmdPrefix(Command* cc);
|
||||
CmdPrefix** findPrefix(const char* nn);
|
||||
void clearPrefix();
|
||||
|
||||
void setCmdLink( CmdLink** a , Command* c, bool sorted = true );
|
||||
void clearCmdLink( CmdLink** phead, bool pclear = false );
|
||||
void setCmdLink(CmdLink** a, Command* c, bool sorted = true);
|
||||
void clearCmdLink(CmdLink** phead, bool pclear = false);
|
||||
|
||||
public:
|
||||
CmdMngr();
|
||||
~CmdMngr() {clear();}
|
||||
~CmdMngr() { clear(); }
|
||||
|
||||
// Interface
|
||||
|
||||
void registerPrefix( const char* nn );
|
||||
Command* registerCommand( CPluginMngr::CPlugin* plugin , int func , char* cmd , char* info , int level , bool listable );
|
||||
Command* getCmd( long int id ,int type, int access);
|
||||
int getCmdNum( int type, int access );
|
||||
void registerPrefix(const char* nn);
|
||||
|
||||
Command* registerCommand(CPluginMngr::CPlugin* plugin, int func, char* cmd, char* info, int level, bool listable);
|
||||
Command* getCmd(long int id, int type, int access);
|
||||
int getCmdNum(int type, int access);
|
||||
|
||||
void clearBufforedInfo();
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
class iterator
|
||||
{
|
||||
CmdLink *a;
|
||||
public:
|
||||
iterator(CmdLink*aa = 0) : a(aa) {}
|
||||
@ -138,28 +146,30 @@ public:
|
||||
operator bool () const { return a ? true : false; }
|
||||
Command& operator*() { return *a->cmd; }
|
||||
};
|
||||
inline iterator clcmdprefixbegin(const char* nn){
|
||||
|
||||
inline iterator clcmdprefixbegin(const char* nn)
|
||||
{
|
||||
CmdPrefix* a = *findPrefix(nn);
|
||||
return iterator( a ? a->list : 0 );
|
||||
return iterator(a ? a->list : 0);
|
||||
}
|
||||
inline iterator clcmdbegin() const {return iterator(clcmdlist);}
|
||||
inline iterator srvcmdbegin() const {return iterator(srvcmdlist);}
|
||||
inline iterator begin( int type ) const { return iterator(sortedlists[type]); }
|
||||
|
||||
inline iterator clcmdbegin() const { return iterator(clcmdlist); }
|
||||
inline iterator srvcmdbegin() const { return iterator(srvcmdlist); }
|
||||
inline iterator begin(int type) const { return iterator(sortedlists[type]); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
|
||||
private:
|
||||
|
||||
int buf_cmdid;
|
||||
int buf_cmdtype;
|
||||
int buf_cmdaccess;
|
||||
|
||||
iterator buf_cmdptr;
|
||||
|
||||
int buf_id;
|
||||
int buf_type;
|
||||
int buf_access;
|
||||
int buf_num;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif //COMMANDS_H
|
||||
|
||||
|
@ -29,37 +29,92 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CEvent.h"
|
||||
|
||||
// *****************************************************
|
||||
// class ClEvent
|
||||
// *****************************************************
|
||||
|
||||
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
|
||||
{
|
||||
m_Plugin = plugin;
|
||||
m_Func = func;
|
||||
|
||||
// flags
|
||||
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||
m_FlagAlive = true;
|
||||
m_FlagDead = true;
|
||||
|
||||
m_FlagWorld = (flags & 1) ? true : false; // flag a
|
||||
m_FlagPlayer = (flags & 2) ? true : false; // flag b
|
||||
m_FlagOnce = (flags & 4) ? true : false; // flag c
|
||||
|
||||
if (flags & 24)
|
||||
{
|
||||
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||
m_FlagAlive = (flags & 16) ? true : false; // flag e
|
||||
m_FlagDead = (flags & 8) ? true : false; // flag d
|
||||
}
|
||||
|
||||
m_Stamp = 0.0f;
|
||||
m_Done = false;
|
||||
|
||||
m_Conditions = NULL;
|
||||
}
|
||||
|
||||
EventsMngr::ClEvent::~ClEvent()
|
||||
{
|
||||
cond_t *tmp1 = m_Conditions;
|
||||
cond_t *tmp2 = NULL;
|
||||
|
||||
while (tmp1)
|
||||
{
|
||||
tmp2 = tmp1->next;
|
||||
delete tmp1;
|
||||
tmp1 = tmp2;
|
||||
}
|
||||
|
||||
m_Conditions = NULL;
|
||||
}
|
||||
|
||||
void EventsMngr::NextParam()
|
||||
{
|
||||
const int INITIAL_PARSEVAULT_SIZE = 32;
|
||||
|
||||
if (m_ParsePos < m_ParseVaultSize)
|
||||
return;
|
||||
|
||||
MsgDataEntry *tmp = NULL;
|
||||
int tmpSize = 0;
|
||||
|
||||
if (m_ParseVault)
|
||||
{
|
||||
// copy to tmp
|
||||
tmp = new MsgDataEntry[m_ParseVaultSize];
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
return; // :TODO: Error report !!
|
||||
}
|
||||
|
||||
memcpy(tmp, m_ParseVault, m_ParseVaultSize * sizeof(MsgDataEntry));
|
||||
tmpSize = m_ParseVaultSize;
|
||||
delete [] m_ParseVault;
|
||||
m_ParseVault = NULL;
|
||||
}
|
||||
|
||||
if (m_ParseVaultSize > 0)
|
||||
m_ParseVaultSize *= 2;
|
||||
else
|
||||
m_ParseVaultSize = INITIAL_PARSEVAULT_SIZE;
|
||||
|
||||
m_ParseVault = new MsgDataEntry[m_ParseVaultSize];
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
memcpy(m_ParseVault, tmp, tmpSize * sizeof(MsgDataEntry));
|
||||
delete [] tmp;
|
||||
tmp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int EventsMngr::ClEvent::getFunction()
|
||||
@ -69,6 +124,9 @@ int EventsMngr::ClEvent::getFunction()
|
||||
|
||||
EventsMngr::EventsMngr()
|
||||
{
|
||||
m_ParseVault = NULL;
|
||||
m_ParseVaultSize = 0;
|
||||
m_CurrentMsgType = -1;
|
||||
clearEvents();
|
||||
}
|
||||
|
||||
@ -77,7 +135,6 @@ EventsMngr::~EventsMngr()
|
||||
clearEvents();
|
||||
}
|
||||
|
||||
|
||||
CPluginMngr::CPlugin * EventsMngr::ClEvent::getPlugin()
|
||||
{
|
||||
return m_Plugin;
|
||||
@ -106,23 +163,35 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
|
||||
if (!*value)
|
||||
return;
|
||||
|
||||
CondMapPair pair;
|
||||
cond_t *tmpCond = new cond_t;
|
||||
if (!tmpCond)
|
||||
return;
|
||||
|
||||
// type character
|
||||
pair.second.type = *value;
|
||||
tmpCond->type = *value;
|
||||
|
||||
// set a null here so param id can be recognized later
|
||||
// set a null here so param id can be recognized, and save it
|
||||
*value++ = 0;
|
||||
tmpCond->paramId = atoi(filter);
|
||||
|
||||
// rest of line
|
||||
pair.second.sValue = value;
|
||||
pair.second.fValue = atof(value);
|
||||
pair.second.iValue = atoi(value);
|
||||
tmpCond->sValue.assign(value);
|
||||
tmpCond->fValue = static_cast<float>(atof(value));
|
||||
tmpCond->iValue = atoi(value);
|
||||
|
||||
// param id
|
||||
pair.first = atoi(filter);
|
||||
tmpCond->next = NULL;
|
||||
|
||||
m_Conditions.insert(pair);
|
||||
if (m_Conditions)
|
||||
{
|
||||
cond_t *tmp = m_Conditions;
|
||||
|
||||
while (tmp->next)
|
||||
tmp = tmp->next;
|
||||
|
||||
tmp->next = tmpCond;
|
||||
}
|
||||
else
|
||||
m_Conditions = tmpCond;
|
||||
}
|
||||
|
||||
EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid)
|
||||
@ -132,10 +201,11 @@ EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int
|
||||
return NULL;
|
||||
|
||||
ClEvent *event = new ClEvent(plugin, func, flags);
|
||||
|
||||
if (!event)
|
||||
return NULL;
|
||||
|
||||
m_Events[msgid].push_back(event);
|
||||
m_Events[msgid].put(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
@ -145,58 +215,57 @@ void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int in
|
||||
if (msg_type < 0 || msg_type > MAX_AMX_REG_MSG)
|
||||
return;
|
||||
|
||||
m_CurrentMsgType = msg_type;
|
||||
|
||||
m_ParseNotDone = false;
|
||||
m_Timer = timer;
|
||||
|
||||
// don't parse if nothing to do
|
||||
if (m_Events[msg_type].empty())
|
||||
if (!m_Events[msg_type].size())
|
||||
return;
|
||||
|
||||
for(ClEventVecIter iter = m_Events[msg_type].begin(); iter != m_Events[msg_type].end(); ++iter)
|
||||
for (ClEventVecIter iter = m_Events[msg_type].begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter)->m_Done)
|
||||
if ((*iter).m_Done)
|
||||
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;
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
else if (!(*iter)->m_FlagWorld)
|
||||
else if (!(*iter).m_FlagWorld)
|
||||
{
|
||||
(*iter)->m_Done = true;
|
||||
(*iter).m_Done = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*iter)->m_FlagOnce && (*iter)->m_Stamp == (float)(*timer))
|
||||
if ((*iter).m_FlagOnce && (*iter).m_Stamp == (float)(*timer))
|
||||
{
|
||||
(*iter)->m_Done = true;
|
||||
(*iter).m_Done = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_ParseNotDone = true;
|
||||
}
|
||||
|
||||
if (m_ParseNotDone)
|
||||
{
|
||||
// we don't clear it (performance)
|
||||
if (m_ParseVault.size() < 1)
|
||||
{
|
||||
m_ParseVault.reserve(32); // 32 as default
|
||||
m_ParseVault.push_back(MsgDataVault());
|
||||
}
|
||||
m_ParsePos = 0;
|
||||
m_ParseVault[m_ParsePos].type = MSG_INTEGER;
|
||||
m_ParseVault[m_ParsePos].iValue = index;
|
||||
NextParam();
|
||||
m_ParseVault[0].type = MSG_INTEGER;
|
||||
m_ParseVault[0].iValue = index;
|
||||
}
|
||||
|
||||
m_ParseFun = &m_Events[msg_type];
|
||||
}
|
||||
|
||||
@ -207,44 +276,43 @@ void EventsMngr::parseValue(int iValue)
|
||||
return;
|
||||
|
||||
// grow if needed
|
||||
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||
{
|
||||
MsgDataVault tmp;
|
||||
m_ParseVault.push_back(tmp);
|
||||
}
|
||||
++m_ParsePos;
|
||||
NextParam();
|
||||
|
||||
m_ParseVault[m_ParsePos].type = MSG_INTEGER;
|
||||
m_ParseVault[m_ParsePos].iValue = iValue;
|
||||
|
||||
// loop through the registered funcs, and decide whether they have to be called
|
||||
bool skip;
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||
// loop through the registered funcs, and decide whether they have to be called or not
|
||||
// if they shouldnt, their m_Done is set to true
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter)->m_Done)
|
||||
continue;
|
||||
if ((*iter).m_Done)
|
||||
continue; // already skipped; don't bother with parsing
|
||||
|
||||
skip = false;
|
||||
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||
if (condIter == (*iter)->m_Conditions.end())
|
||||
continue;
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
do
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
switch(condIter->second.type)
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
case '=': if (condIter->second.iValue == iValue) skip=true; break;
|
||||
case '!': if (condIter->second.iValue != iValue) skip=true; break;
|
||||
case '&': if (iValue & condIter->second.iValue) skip=true; break;
|
||||
case '<': if (iValue < condIter->second.iValue) skip=true; break;
|
||||
case '>': if (iValue > condIter->second.iValue) skip=true; break;
|
||||
anyConditions = true;
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (condIter->iValue == iValue) execute = true; break;
|
||||
case '!': if (condIter->iValue != iValue) execute = true; break;
|
||||
case '&': if (iValue & condIter->iValue) execute = true; break;
|
||||
case '<': if (iValue < condIter->iValue) execute = true; break;
|
||||
case '>': if (iValue > condIter->iValue) execute = true; break;
|
||||
}
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
if (skip)
|
||||
break;
|
||||
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||
}
|
||||
|
||||
if (skip)
|
||||
continue;
|
||||
(*iter)->m_Done = true;
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
}
|
||||
|
||||
@ -255,43 +323,43 @@ void EventsMngr::parseValue(float fValue)
|
||||
return;
|
||||
|
||||
// grow if needed
|
||||
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||
{
|
||||
MsgDataVault tmp;
|
||||
m_ParseVault.push_back(tmp);
|
||||
}
|
||||
++m_ParsePos;
|
||||
NextParam();
|
||||
|
||||
m_ParseVault[m_ParsePos].type = MSG_FLOAT;
|
||||
m_ParseVault[m_ParsePos].fValue = fValue;
|
||||
|
||||
// loop through the registered funcs, and decide whether they have to be called
|
||||
bool skip;
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||
// loop through the registered funcs, and decide whether they have to be called or not
|
||||
// if they shouldnt, their m_Done is set to true
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter)->m_Done)
|
||||
continue;
|
||||
if ((*iter).m_Done)
|
||||
continue; // already skipped; don't bother with parsing
|
||||
|
||||
skip = false;
|
||||
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||
if (condIter == (*iter)->m_Conditions.end())
|
||||
continue;
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
do
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
switch(condIter->second.type)
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
case '=': if (condIter->second.fValue == fValue) skip=true; break;
|
||||
case '!': if (condIter->second.fValue != fValue) skip=true; break;
|
||||
case '<': if (fValue < condIter->second.fValue) skip=true; break;
|
||||
case '>': if (fValue > condIter->second.fValue) skip=true; break;
|
||||
}
|
||||
if (skip)
|
||||
break;
|
||||
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||
anyConditions = true;
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (condIter->fValue == fValue) execute = true; break;
|
||||
case '!': if (condIter->fValue != fValue) execute = true; break;
|
||||
case '<': if (fValue < condIter->fValue) execute = true; break;
|
||||
case '>': if (fValue > condIter->fValue) execute = true; break;
|
||||
}
|
||||
|
||||
if (skip)
|
||||
continue;
|
||||
(*iter)->m_Done = true;
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,138 +370,122 @@ void EventsMngr::parseValue(const char *sz)
|
||||
return;
|
||||
|
||||
// grow if needed
|
||||
if (m_ParseVault.size() <= static_cast<size_t>(++m_ParsePos))
|
||||
{
|
||||
MsgDataVault tmp;
|
||||
m_ParseVault.push_back(tmp);
|
||||
}
|
||||
++m_ParsePos;
|
||||
NextParam();
|
||||
|
||||
m_ParseVault[m_ParsePos].type = MSG_STRING;
|
||||
m_ParseVault[m_ParsePos].sValue = sz;
|
||||
|
||||
// loop through the registered funcs, and decide whether they have to be called
|
||||
bool skip;
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||
// loop through the registered funcs, and decide whether they have to be called or not
|
||||
// if they shouldnt, their m_Done is set to true
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter)->m_Done)
|
||||
continue;
|
||||
if ((*iter).m_Done)
|
||||
continue; // already skipped; don't bother with parsing
|
||||
|
||||
skip = false;
|
||||
ClEvent::CondMapIter condIter = (*iter)->m_Conditions.find(m_ParsePos);
|
||||
if (condIter == (*iter)->m_Conditions.end())
|
||||
continue;
|
||||
// loop through conditions
|
||||
bool execute = false;
|
||||
bool anyConditions = false;
|
||||
|
||||
do
|
||||
for (ClEvent::cond_t *condIter = (*iter).m_Conditions; condIter; condIter = condIter->next)
|
||||
{
|
||||
switch(condIter->second.type)
|
||||
if (condIter->paramId == m_ParsePos)
|
||||
{
|
||||
case '=': if (!strcmp(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||
case '!': if (!strstr(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||
case '&': if (strstr(sz, condIter->second.sValue.c_str())) skip=true; break;
|
||||
}
|
||||
if (skip)
|
||||
break;
|
||||
} while ( ++condIter != (*iter)->m_Conditions.end() );
|
||||
anyConditions = true;
|
||||
switch (condIter->type)
|
||||
{
|
||||
case '=': if (!strcmp(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
case '!': if (strcmp(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
case '&': if (strstr(sz, condIter->sValue.c_str())) execute = true; break;
|
||||
}
|
||||
|
||||
if (skip)
|
||||
continue;
|
||||
(*iter)->m_Done = true;
|
||||
if (execute)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyConditions && !execute)
|
||||
(*iter).m_Done = true; // don't execute
|
||||
}
|
||||
}
|
||||
|
||||
void EventsMngr::executeEvents()
|
||||
{
|
||||
int err;
|
||||
|
||||
if (!m_ParseFun)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter; ++iter)
|
||||
{
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
for (ClEventVecIter iter = m_ParseFun->begin(); iter != m_ParseFun->end(); ++iter)
|
||||
if ((*iter).m_Done)
|
||||
{
|
||||
if ( (*iter)->m_Done )
|
||||
{
|
||||
(*iter)->m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
(*iter)->m_Stamp = *m_Timer;
|
||||
|
||||
if ((err = amx_Exec((*iter)->m_Plugin->getAMX(), NULL, (*iter)->m_Func, 1, m_ParseVault.size() ? m_ParseVault[0].iValue : 0)) != AMX_ERR_NONE)
|
||||
{
|
||||
UTIL_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err,
|
||||
(*iter)->m_Plugin->getAMX()->curline, (*iter)->m_Plugin->getName());
|
||||
}
|
||||
(*iter).m_Done = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0));
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
UTIL_Log( "[AMXX] fatal error at event execution");
|
||||
}
|
||||
#endif // #ifdef ENABLEEXEPTIONS
|
||||
|
||||
m_CurrentMsgType = -1;
|
||||
m_ParseFun = NULL;
|
||||
}
|
||||
|
||||
int EventsMngr::getArgNum()
|
||||
int EventsMngr::getArgNum() const
|
||||
{
|
||||
return m_ParsePos + 1;
|
||||
}
|
||||
|
||||
const char* EventsMngr::getArgString(int a)
|
||||
const char* EventsMngr::getArgString(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return "";
|
||||
|
||||
static char var[32];
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
sprintf( var, "%d", m_ParseVault[a].iValue );
|
||||
return var;
|
||||
case MSG_STRING:
|
||||
return m_ParseVault[a].sValue;
|
||||
default:
|
||||
sprintf( var, "%g", m_ParseVault[a].fValue );
|
||||
return var;
|
||||
case MSG_INTEGER:
|
||||
sprintf(var, "%d", m_ParseVault[a].iValue);
|
||||
return var;
|
||||
case MSG_STRING:
|
||||
return m_ParseVault[a].sValue;
|
||||
default:
|
||||
sprintf(var, "%g", m_ParseVault[a].fValue);
|
||||
return var;
|
||||
}
|
||||
}
|
||||
|
||||
int EventsMngr::getArgInteger(int a)
|
||||
int EventsMngr::getArgInteger(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return 0;
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atoi(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return (int)m_ParseVault[a].fValue;
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atoi(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return (int)m_ParseVault[a].fValue;
|
||||
}
|
||||
}
|
||||
|
||||
float EventsMngr::getArgFloat(int a)
|
||||
float EventsMngr::getArgFloat(int a) const
|
||||
{
|
||||
if ( a < 0 || a > m_ParsePos )
|
||||
if (a < 0 || a > m_ParsePos)
|
||||
return 0.0f;
|
||||
|
||||
switch(m_ParseVault[a].type)
|
||||
switch (m_ParseVault[a].type)
|
||||
{
|
||||
case MSG_INTEGER:
|
||||
return m_ParseVault[a].iValue;
|
||||
case MSG_STRING:
|
||||
return atof(m_ParseVault[a].sValue);
|
||||
default:
|
||||
return m_ParseVault[a].fValue;
|
||||
case MSG_INTEGER:
|
||||
return static_cast<float>(m_ParseVault[a].iValue);
|
||||
case MSG_STRING:
|
||||
return static_cast<float>(atof(m_ParseVault[a].sValue));
|
||||
default:
|
||||
return m_ParseVault[a].fValue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -441,13 +493,16 @@ void EventsMngr::clearEvents(void)
|
||||
{
|
||||
for (int i = 0; i < MAX_AMX_REG_MSG; ++i)
|
||||
{
|
||||
for (ClEventVecIter iter = m_Events[i].begin(); iter != m_Events[i].end(); ++iter)
|
||||
{
|
||||
if (*iter)
|
||||
delete *iter;
|
||||
}
|
||||
m_Events[i].clear();
|
||||
}
|
||||
|
||||
// delete parsevault
|
||||
if (m_ParseVault)
|
||||
{
|
||||
delete [] m_ParseVault;
|
||||
m_ParseVault = NULL;
|
||||
m_ParseVaultSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int EventsMngr::getEventId(const char* msg)
|
||||
@ -459,23 +514,29 @@ int EventsMngr::getEventId(const char* msg)
|
||||
CS_EventsIds id;
|
||||
} table[] =
|
||||
{
|
||||
{ "CS_DeathMsg" , CS_DeathMsg },
|
||||
// { "CS_RoundEnd" , CS_RoundEnd },
|
||||
// { "CS_RoundStart" , CS_RoundStart },
|
||||
// { "CS_Restart" , CS_Restart },
|
||||
{ "" , CS_Null }
|
||||
{"CS_DeathMsg", CS_DeathMsg},
|
||||
// {"CS_RoundEnd", CS_RoundEnd},
|
||||
// {"CS_RoundStart", CS_RoundStart},
|
||||
// {"CS_Restart", CS_Restart},
|
||||
{"", CS_Null}
|
||||
};
|
||||
|
||||
// if msg is a number, return it
|
||||
int pos = atoi(msg);
|
||||
|
||||
if (pos != 0)
|
||||
return pos;
|
||||
|
||||
// try to find in table first
|
||||
for (pos = 0; table[ pos ].id != CS_Null; ++pos )
|
||||
if ( !strcmp( table[ pos ].name , msg ) )
|
||||
return table[ pos ].id;
|
||||
for (pos = 0; table[pos].id != CS_Null; ++pos)
|
||||
if (!strcmp(table[pos].name, msg))
|
||||
return table[pos].id;
|
||||
|
||||
// find the id of the message
|
||||
return pos = GET_USER_MSG_ID(PLID, msg , 0 );
|
||||
return pos = GET_USER_MSG_ID(PLID, msg, 0);
|
||||
}
|
||||
|
||||
int EventsMngr::getCurrentMsgType()
|
||||
{
|
||||
return m_CurrentMsgType;
|
||||
}
|
||||
|
@ -32,13 +32,10 @@
|
||||
#ifndef __CEVENTS_H__
|
||||
#define __CEVENTS_H__
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#define MAX_AMX_REG_MSG MAX_REG_MSGS + 16
|
||||
|
||||
#define MAX_AMX_REG_MSG MAX_REG_MSGS+16
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
CS_DEATHMSG = MAX_REG_MSGS,
|
||||
// CS_ROUNDEND,
|
||||
// CS_ROUNDSTART,
|
||||
@ -71,7 +68,7 @@ public:
|
||||
|
||||
class ClEvent
|
||||
{
|
||||
friend class EventsMngr; // events manager may access our private members
|
||||
friend class EventsMngr; // events manager may access our private members
|
||||
|
||||
int m_Func; // function to be executed
|
||||
CPluginMngr::CPlugin *m_Plugin; // the plugin this ClEvent class is assigned to
|
||||
@ -90,50 +87,54 @@ public:
|
||||
// conditions
|
||||
struct cond_t
|
||||
{
|
||||
std::string sValue; // value
|
||||
float fValue;
|
||||
int iValue;
|
||||
int type;
|
||||
int paramId; // the message parameter id
|
||||
|
||||
String sValue; // value (string)
|
||||
float fValue; // value (float)
|
||||
int iValue; // value (int)
|
||||
int type; // type (can be int, float, string)
|
||||
|
||||
cond_t *next;
|
||||
};
|
||||
|
||||
typedef std::pair<int, cond_t> CondMapPair;
|
||||
typedef std::map<int, cond_t> CondMap;
|
||||
typedef CondMap::iterator CondMapIter;
|
||||
cond_t *m_Conditions;
|
||||
|
||||
CondMap m_Conditions;
|
||||
|
||||
// constructors & destructors
|
||||
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||
~ClEvent();
|
||||
public:
|
||||
// constructors & destructors
|
||||
ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags);
|
||||
~ClEvent();
|
||||
|
||||
inline CPluginMngr::CPlugin* getPlugin();
|
||||
inline int getFunction();
|
||||
void registerFilter(char* filter); // add a condition
|
||||
};
|
||||
|
||||
private:
|
||||
struct MsgDataVault
|
||||
struct MsgDataEntry
|
||||
{
|
||||
float fValue;
|
||||
int iValue;
|
||||
const char* sValue;
|
||||
MsgParamType type;
|
||||
};
|
||||
typedef std::vector<MsgDataVault> MsgDataVaultVec;
|
||||
typedef MsgDataVaultVec::iterator MsgDataVaultVecIter;
|
||||
MsgDataVaultVec m_ParseVault;
|
||||
|
||||
typedef std::vector<ClEvent*> ClEventVec;
|
||||
MsgDataEntry *m_ParseVault;
|
||||
int m_ParseVaultSize;
|
||||
void NextParam(); // make sure a new parameter can be added
|
||||
|
||||
typedef CList<ClEvent> ClEventVec;
|
||||
typedef ClEventVec::iterator ClEventVecIter;
|
||||
|
||||
ClEventVec m_Events[MAX_AMX_REG_MSG];
|
||||
ClEventVec *m_ParseFun; // current Event vector
|
||||
ClEventVec *m_ParseFun; // current Event vector
|
||||
|
||||
bool m_ParseNotDone;
|
||||
int m_ParsePos; // is -1 less then args. num.
|
||||
int m_ParsePos; // is args. num. - 1
|
||||
float* m_Timer;
|
||||
|
||||
ClEvent* getValidEvent(ClEvent* a );
|
||||
ClEvent* getValidEvent(ClEvent* a);
|
||||
|
||||
int m_CurrentMsgType;
|
||||
public:
|
||||
EventsMngr();
|
||||
~EventsMngr();
|
||||
@ -141,17 +142,20 @@ public:
|
||||
// Interface
|
||||
|
||||
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
|
||||
|
||||
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
|
||||
void parseValue(int iValue);
|
||||
void parseValue(float fValue);
|
||||
void parseValue(const char *sz);
|
||||
void executeEvents();
|
||||
int getArgNum(); //{ return (parsePos+1); }
|
||||
const char* getArgString(int a);
|
||||
int getArgInteger(int a);
|
||||
float getArgFloat(int a);
|
||||
|
||||
int getArgNum() const; //{ return (parsePos + 1); }
|
||||
const char* getArgString(int a) const;
|
||||
int getArgInteger(int a) const;
|
||||
float getArgFloat(int a) const;
|
||||
void clearEvents(void);
|
||||
static int getEventId( const char* msg );
|
||||
static int getEventId(const char* msg);
|
||||
int getCurrentMsgType();
|
||||
};
|
||||
|
||||
#endif // #ifdef __CEVENTS_H__
|
||||
#endif //__CEVENTS_H__
|
||||
|
@ -29,87 +29,98 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "CFile.h"
|
||||
#include <ctype.h>
|
||||
#include "amxmodx.h"
|
||||
#include "CFile.h"
|
||||
|
||||
// *****************************************************
|
||||
// class File
|
||||
// *****************************************************
|
||||
File::File( const char* n, const char* m )
|
||||
|
||||
File::File(const char* n, const char* m)
|
||||
{
|
||||
fp = fopen( n , m );
|
||||
fp = fopen(n, m);
|
||||
}
|
||||
|
||||
File::~File( )
|
||||
File::~File()
|
||||
{
|
||||
if ( fp )
|
||||
fclose( fp );
|
||||
if (fp)
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
File::operator bool ( ) const
|
||||
File::operator bool () const
|
||||
{
|
||||
return fp && !feof(fp);
|
||||
return fp && !feof(fp);
|
||||
}
|
||||
|
||||
File& operator<<( File& f, const String& n )
|
||||
File& operator<<(File& f, const String& n)
|
||||
{
|
||||
if ( f ) fputs( n.str() , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputs(n.c_str(), f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator<<( File& f, const char* n )
|
||||
File& operator<<(File& f, const char* n)
|
||||
{
|
||||
if ( f ) fputs( n , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputs(n, f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator<<( File& f, int n )
|
||||
File& operator<<(File& f, int n)
|
||||
{
|
||||
if ( f ) fprintf( f.fp , "%d" , n ) ;
|
||||
return f;
|
||||
if (f) fprintf(f.fp, "%d", n);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
File& operator<<( File& f, const char& c )
|
||||
File& operator<<(File& f, const char& c)
|
||||
{
|
||||
if ( f ) fputc( c , f.fp ) ;
|
||||
return f;
|
||||
if (f) fputc(c, f.fp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator>>( File& f, String& n )
|
||||
File& operator>>(File& f, String& n)
|
||||
{
|
||||
if ( !f ) return f;
|
||||
char temp[1024];
|
||||
fscanf( f.fp , "%s", temp );
|
||||
n.set(temp);
|
||||
return f;
|
||||
if (!f) return f;
|
||||
char temp[1024];
|
||||
fscanf(f.fp, "%s", temp);
|
||||
n.assign(temp);
|
||||
return f;
|
||||
}
|
||||
|
||||
File& operator>>( File& f, char* n )
|
||||
File& operator>>(File& f, char* n)
|
||||
{
|
||||
if ( f ) fscanf( f.fp , "%s", n );
|
||||
return f;
|
||||
if (f) fscanf(f.fp, "%s", n);
|
||||
return f;
|
||||
}
|
||||
|
||||
int File::getline( char* buf, int sz )
|
||||
int File::getline(char* buf, int sz)
|
||||
{
|
||||
int a = sz;
|
||||
if ( *this )
|
||||
{
|
||||
int c;
|
||||
while ( sz-- && (c = getc( (*this).fp)) && c != EOF && c != '\n' )
|
||||
*buf++ = c;
|
||||
*buf = 0;
|
||||
}
|
||||
return a - sz;
|
||||
int a = sz;
|
||||
char *origBuf = buf;
|
||||
|
||||
if (*this)
|
||||
{
|
||||
int c;
|
||||
while (sz-- && (c = getc((*this).fp)) && c != EOF && c != '\n')
|
||||
*buf++ = c;
|
||||
*buf = 0;
|
||||
}
|
||||
|
||||
// trim 0x0a and 0x0d characters at the end
|
||||
while (buf != origBuf)
|
||||
{
|
||||
if (*buf == 0x0a || *buf == 0x0d)
|
||||
*buf = 0;
|
||||
--buf;
|
||||
}
|
||||
|
||||
return a - sz;
|
||||
}
|
||||
|
||||
File& File::skipWs( )
|
||||
File& File::skipWs()
|
||||
{
|
||||
if ( !*this ) return *this;
|
||||
int c;
|
||||
while( isspace( c = getc( fp ) ) ){};
|
||||
ungetc( c , fp );
|
||||
return *this;
|
||||
if (!*this) return *this;
|
||||
int c;
|
||||
while (isspace(c = getc(fp))) {};
|
||||
ungetc(c, fp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -41,18 +41,19 @@ class File
|
||||
FILE* fp;
|
||||
|
||||
public:
|
||||
File( const char* n, const char* m );
|
||||
~File( );
|
||||
operator bool ( ) const;
|
||||
friend File& operator<<( File& f, const String& n );
|
||||
friend File& operator<<( File& f, const char* n );
|
||||
friend File& operator<<( File& f, const char& c );
|
||||
friend File& operator<<( File& f, int n );
|
||||
friend File& operator>>( File& f, String& n );
|
||||
friend File& operator>>( File& f, char* n );
|
||||
int getline( char* buf, int sz );
|
||||
File& skipWs( );
|
||||
File(const char* n, const char* m);
|
||||
~File();
|
||||
|
||||
operator bool () const;
|
||||
|
||||
friend File& operator<<(File& f, const String& n);
|
||||
friend File& operator<<(File& f, const char* n);
|
||||
friend File& operator<<(File& f, const char& c);
|
||||
friend File& operator<<(File& f, int n);
|
||||
friend File& operator>>(File& f, String& n);
|
||||
friend File& operator>>(File& f, char* n);
|
||||
|
||||
int getline(char* buf, int sz);
|
||||
|
||||
File& skipWs();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -29,52 +29,650 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "CForward.h"
|
||||
#include "amxmodx.h"
|
||||
#include "debugger.h"
|
||||
#include "binlog.h"
|
||||
|
||||
void CForwardMngr::registerForward( CPluginMngr::CPlugin* p, int func , int type ){
|
||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
m_FuncName = name;
|
||||
m_ExecType = et;
|
||||
m_NumParams = numParams;
|
||||
|
||||
CForward** a = &head[ type ];
|
||||
while(*a) a = &(*a)->next;
|
||||
*a = new CForward( p , func );
|
||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||
|
||||
// find funcs
|
||||
int func;
|
||||
AMXForward *tmp = NULL;
|
||||
m_Funcs.clear();
|
||||
|
||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||
{
|
||||
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
||||
{
|
||||
AMXForward tmp;
|
||||
tmp.pPlugin = &(*iter);
|
||||
tmp.func = func;
|
||||
m_Funcs.push_back(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
m_Name.assign(name);
|
||||
}
|
||||
|
||||
void CForwardMngr::clearForwards( CForward** a ){
|
||||
while( *a ) {
|
||||
CForward* b = (*a)->next;
|
||||
delete *a;
|
||||
*a = b;
|
||||
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
{
|
||||
cell realParams[FORWARD_MAX_PARAMS];
|
||||
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||
|
||||
const int STRINGEX_MAXLENGTH = 128;
|
||||
|
||||
cell globRetVal = 0;
|
||||
|
||||
unsigned int id = 0;
|
||||
|
||||
AMXForwardList::iterator iter;
|
||||
|
||||
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
|
||||
{
|
||||
if (iter->pPlugin->isExecutable(iter->func))
|
||||
{
|
||||
// Get debug info
|
||||
AMX *amx = (*iter).pPlugin->getAMX();
|
||||
Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
|
||||
// handle strings & arrays
|
||||
int i, ax = 0;
|
||||
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
const char *str = reinterpret_cast<const char*>(params[i]);
|
||||
cell *tmp;
|
||||
if (!str)
|
||||
str = "";
|
||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, str, 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
||||
physAddrs[i] = tmp;
|
||||
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||
}
|
||||
} else {
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
|
||||
for (i = m_NumParams-1; i >= 0; i--)
|
||||
{
|
||||
amx_Push(amx, realParams[i]);
|
||||
}
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
#if defined BINLOG_ENABLED
|
||||
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
|
||||
#endif
|
||||
int err = amx_Exec(amx, &retVal, iter->func);
|
||||
|
||||
// log runtime error, if any
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pDebugger && pDebugger->ErrorExists())
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
}
|
||||
else if (err != -1)
|
||||
{
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(amx, err, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
amx->error = AMX_ERR_NONE;
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->EndExec();
|
||||
|
||||
// cleanup strings & arrays
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING)
|
||||
{
|
||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
// copy back
|
||||
if (preparedArrays[params[i]].copyBack)
|
||||
{
|
||||
cell *tmp = physAddrs[i];
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||
}
|
||||
}
|
||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// decide what to do (based on exectype and retval)
|
||||
switch (m_ExecType)
|
||||
{
|
||||
case ET_IGNORE:
|
||||
break;
|
||||
case ET_STOP:
|
||||
if (retVal > 0)
|
||||
return retVal;
|
||||
case ET_STOP2:
|
||||
if (retVal == 1)
|
||||
return 1;
|
||||
else if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
case ET_CONTINUE:
|
||||
if (retVal > globRetVal)
|
||||
globRetVal = retVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return globRetVal;
|
||||
}
|
||||
|
||||
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
char name[sNAMEMAX];
|
||||
m_Func = func;
|
||||
m_Amx = amx;
|
||||
m_NumParams = numParams;
|
||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||
m_HasFunc = true;
|
||||
isFree = false;
|
||||
name[0] = '\0';
|
||||
amx_GetPublic(amx, func, name);
|
||||
m_Name.assign(name);
|
||||
}
|
||||
|
||||
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
m_Amx = amx;
|
||||
m_NumParams = numParams;
|
||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
||||
isFree = false;
|
||||
m_Name.assign(funcName);
|
||||
}
|
||||
|
||||
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
{
|
||||
if (isFree)
|
||||
return 0;
|
||||
|
||||
const int STRINGEX_MAXLENGTH = 128;
|
||||
|
||||
cell realParams[FORWARD_MAX_PARAMS];
|
||||
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||
|
||||
if (!m_HasFunc)
|
||||
return 0;
|
||||
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
||||
if (!pPlugin->isExecutable(m_Func))
|
||||
return 0;
|
||||
|
||||
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
|
||||
// handle strings & arrays
|
||||
int i;
|
||||
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
const char *str = reinterpret_cast<const char*>(params[i]);
|
||||
if (!str)
|
||||
str = "";
|
||||
cell *tmp;
|
||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, str, 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
cell *tmp;
|
||||
amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
|
||||
physAddrs[i] = tmp;
|
||||
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||
}
|
||||
} else {
|
||||
realParams[i] = params[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = m_NumParams - 1; i >= 0; i--)
|
||||
amx_Push(m_Amx, realParams[i]);
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
#if defined BINLOG_ENABLED
|
||||
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
|
||||
#endif
|
||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
//Did something else set an error?
|
||||
if (pDebugger && pDebugger->ErrorExists())
|
||||
{
|
||||
//we don't care, something else logged the error.
|
||||
}
|
||||
else if (err != -1)
|
||||
{
|
||||
//nothing logged the error so spit it out anyway
|
||||
LogError(m_Amx, err, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (pDebugger)
|
||||
pDebugger->EndExec();
|
||||
|
||||
m_Amx->error = AMX_ERR_NONE;
|
||||
|
||||
// cleanup strings & arrays
|
||||
for (i = 0; i < m_NumParams; ++i)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING)
|
||||
{
|
||||
amx_Release(m_Amx, realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
// copy back
|
||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||
amx_Release(m_Amx, realParams[i]);
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
{
|
||||
// copy back
|
||||
if (preparedArrays[params[i]].copyBack)
|
||||
{
|
||||
cell *tmp = physAddrs[i];
|
||||
if (preparedArrays[params[i]].type == Type_Cell)
|
||||
{
|
||||
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||
} else {
|
||||
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||
|
||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||
}
|
||||
}
|
||||
amx_Release(m_Amx, realParams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
||||
{
|
||||
int retVal = m_Forwards.size() << 1;
|
||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
||||
|
||||
if (!tmp)
|
||||
return -1; // should be invalid
|
||||
|
||||
m_Forwards.push_back(tmp);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
int retVal = -1;
|
||||
CSPForward *pForward;
|
||||
|
||||
if (!m_FreeSPForwards.empty())
|
||||
{
|
||||
retVal = m_FreeSPForwards.front();
|
||||
pForward = m_SPForwards[retVal >> 1];
|
||||
pForward->Set(func, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
return -1;
|
||||
|
||||
m_FreeSPForwards.pop();
|
||||
} else {
|
||||
retVal = (m_SPForwards.size() << 1) | 1;
|
||||
pForward = new CSPForward();
|
||||
|
||||
if (!pForward)
|
||||
return -1;
|
||||
|
||||
pForward->Set(func, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
{
|
||||
return -1;
|
||||
delete pForward;
|
||||
}
|
||||
|
||||
m_SPForwards.push_back(pForward);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||
{
|
||||
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||
CSPForward *pForward;
|
||||
|
||||
if (!m_FreeSPForwards.empty())
|
||||
{
|
||||
retVal = m_FreeSPForwards.front();
|
||||
pForward = m_SPForwards[retVal>>1]; // >>1 because unregisterSPForward pushes the id which contains the sp flag
|
||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
return -1;
|
||||
|
||||
m_FreeSPForwards.pop();
|
||||
} else {
|
||||
pForward = new CSPForward();
|
||||
|
||||
if (!pForward)
|
||||
return -1;
|
||||
|
||||
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||
|
||||
if (pForward->getFuncsNum() == 0)
|
||||
{
|
||||
delete pForward;
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_SPForwards.push_back(pForward);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
bool CForwardMngr::isIdValid(int id) const
|
||||
{
|
||||
return (id >= 0) && ((id & 1) ? (static_cast<size_t>(id >> 1) < m_SPForwards.size()) : (static_cast<size_t>(id >> 1) < m_Forwards.size()));
|
||||
}
|
||||
|
||||
cell CForwardMngr::executeForwards(int id, cell *params)
|
||||
{
|
||||
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||
m_TmpArraysNum = 0;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
const char *CForwardMngr::getFuncName(int id) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
|
||||
}
|
||||
|
||||
int CForwardMngr::getParamsNum(int id) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
|
||||
}
|
||||
|
||||
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
||||
}
|
||||
|
||||
void CForwardMngr::clear()
|
||||
{
|
||||
for ( int a = 0; a < FORWARD_NUM; ++a )
|
||||
clearForwards( &head[ a ] );
|
||||
}
|
||||
|
||||
void CForwardMngr::executeForwards( int type , int num , int player ) {
|
||||
|
||||
cell ret = 0;
|
||||
int err;
|
||||
CForward* a = head[ type ];
|
||||
|
||||
while ( a )
|
||||
for (ForwardVec::iterator iter = m_Forwards.begin(); iter != m_Forwards.end(); ++iter)
|
||||
{
|
||||
if ( a->getPlugin()->isExecutable( a->getFunction() ) )
|
||||
{
|
||||
|
||||
if ((err = amx_Exec(a->getPlugin()->getAMX(), &ret, a->getFunction() , num, player)) != AMX_ERR_NONE)
|
||||
UTIL_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")", err,a->getPlugin()->getAMX()->curline,a->getPlugin()->getName());
|
||||
|
||||
if ( ret )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
a = a->next;
|
||||
delete *iter;
|
||||
}
|
||||
|
||||
SPForwardVec::iterator spIter;
|
||||
|
||||
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
||||
{
|
||||
delete (*spIter);
|
||||
}
|
||||
|
||||
m_Forwards.clear();
|
||||
m_SPForwards.clear();
|
||||
|
||||
while (!m_FreeSPForwards.empty())
|
||||
m_FreeSPForwards.pop();
|
||||
|
||||
m_TmpArraysNum = 0;
|
||||
}
|
||||
|
||||
bool CForwardMngr::isSPForward(int id) const
|
||||
{
|
||||
return ((id & 1) == 0) ? false : true;
|
||||
}
|
||||
|
||||
void CForwardMngr::unregisterSPForward(int id)
|
||||
{
|
||||
//make sure the id is valid
|
||||
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
||||
return;
|
||||
|
||||
m_SPForwards.at(id >> 1)->isFree = true;
|
||||
m_FreeSPForwards.push(id);
|
||||
}
|
||||
|
||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num)
|
||||
{
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
|
||||
for (size_t i=0; i<num; i++)
|
||||
params[i] = static_cast<ForwardParam>(list[i]);
|
||||
|
||||
return g_forwards.registerForward(funcName, et, num, params);
|
||||
}
|
||||
|
||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, et);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerForward(funcName, et, curParam, params);
|
||||
}
|
||||
|
||||
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
|
||||
{
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
|
||||
for (size_t i=0; i<num; i++)
|
||||
params[i] = static_cast<ForwardParam>(list[i]);
|
||||
|
||||
return g_forwards.registerSPForward(funcName, amx, num, params);
|
||||
}
|
||||
|
||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, funcName);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
||||
}
|
||||
|
||||
int registerSPForward(AMX *amx, int func, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, func);
|
||||
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
ForwardParam tmp;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (curParam == FORWARD_MAX_PARAMS)
|
||||
break;
|
||||
|
||||
tmp = (ForwardParam)va_arg(argptr, int);
|
||||
|
||||
if (tmp == FP_DONE)
|
||||
break;
|
||||
|
||||
params[curParam] = tmp;
|
||||
++curParam;
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.registerSPForward(func, amx, curParam, params);
|
||||
}
|
||||
|
||||
cell executeForwards(int id, ...)
|
||||
{
|
||||
if (!g_forwards.isIdValid(id))
|
||||
return -1;
|
||||
|
||||
cell params[FORWARD_MAX_PARAMS];
|
||||
|
||||
int paramsNum = g_forwards.getParamsNum(id);
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, id);
|
||||
|
||||
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
||||
{
|
||||
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
||||
{
|
||||
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
||||
params[i] = *(cell*)&tmp;
|
||||
}
|
||||
else
|
||||
params[i] = (cell)va_arg(argptr, cell);
|
||||
}
|
||||
|
||||
va_end(argptr);
|
||||
|
||||
return g_forwards.executeForwards(id, params);
|
||||
}
|
||||
|
||||
cell CForwardMngr::prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack)
|
||||
{
|
||||
if (m_TmpArraysNum >= FORWARD_MAX_PARAMS)
|
||||
{
|
||||
#ifdef MEMORY_TEST
|
||||
m_validateAllAllocUnits();
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
AMXXLOG_Log("[AMXX] Forwards with more than 32 parameters are not supported (tried to prepare array # %d).", m_TmpArraysNum + 1);
|
||||
m_TmpArraysNum = 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
m_TmpArrays[m_TmpArraysNum].ptr = ptr;
|
||||
m_TmpArrays[m_TmpArraysNum].size = size;
|
||||
m_TmpArrays[m_TmpArraysNum].type = type;
|
||||
m_TmpArrays[m_TmpArraysNum].copyBack = copyBack;
|
||||
|
||||
return m_TmpArraysNum++;
|
||||
}
|
||||
|
||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack)
|
||||
{
|
||||
return g_forwards.prepareArray((void*)ptr, size, Type_Cell, copyBack);
|
||||
}
|
||||
|
||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack)
|
||||
{
|
||||
return g_forwards.prepareArray((void*)ptr, size, Type_Char, copyBack);
|
||||
}
|
||||
|
||||
void unregisterSPForward(int id)
|
||||
{
|
||||
g_forwards.unregisterSPForward(id);
|
||||
}
|
@ -29,87 +29,214 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
/*
|
||||
CForward.h
|
||||
forwards
|
||||
1) normal forwards: called in all plugins
|
||||
2) single plugin (sp) forwards: called in one plugin
|
||||
|
||||
The SP Forwards are handled differently because they are expected to be created / deleted
|
||||
often, but the "normal" forwards are expected to be initialized at start up.
|
||||
|
||||
Note about forward ids:
|
||||
for normal forwards: <index to vector> << 1
|
||||
for sp forwards: (<index to vector> << 1) | 1
|
||||
*/
|
||||
|
||||
#ifndef FORWARD_H
|
||||
#define FORWARD_H
|
||||
|
||||
// *****************************************************
|
||||
// class CmdMngr
|
||||
// *****************************************************
|
||||
#include <stdarg.h>
|
||||
#include "sh_stack.h"
|
||||
|
||||
#define FORWARD_NUM 12
|
||||
const int FORWARD_MAX_PARAMS = 32;
|
||||
|
||||
enum {
|
||||
FF_ClientCommand,
|
||||
FF_ClientConnect,
|
||||
FF_ClientDisconnect,
|
||||
FF_ClientInfoChanged,
|
||||
FF_ClientPutInServer,
|
||||
FF_PluginInit,
|
||||
FF_PluginCfg,
|
||||
FF_PluginPrecache,
|
||||
FF_PluginLog,
|
||||
FF_PluginEnd,
|
||||
FF_InconsistentFile,
|
||||
FF_ClientAuthorized,
|
||||
enum ForwardExecType
|
||||
{
|
||||
ET_IGNORE = 0, // Ignore return vaue
|
||||
ET_STOP, // Stop on PLUGIN_HANDLED
|
||||
ET_STOP2, // Stop on PLUGIN_HANDLED, continue on other values, return biggest return value
|
||||
ET_CONTINUE, // Continue; return biggest return value
|
||||
};
|
||||
|
||||
enum ForwardParam
|
||||
{
|
||||
FP_DONE = -1, // specify this as the last argument
|
||||
// only tells the function that there are no more arguments
|
||||
FP_CELL, // normal cell
|
||||
FP_FLOAT, // float; used as normal cell though
|
||||
FP_STRING, // string
|
||||
FP_STRINGEX, // string; will be updated to the last function's value
|
||||
FP_ARRAY, // array; use the return value of prepareArray.
|
||||
};
|
||||
|
||||
// for prepareArray
|
||||
enum ForwardArrayElemType
|
||||
{
|
||||
Type_Cell = 0,
|
||||
Type_Char
|
||||
};
|
||||
|
||||
struct ForwardPreparedArray
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
ForwardArrayElemType type;
|
||||
|
||||
unsigned int size;
|
||||
bool copyBack;
|
||||
};
|
||||
|
||||
// Normal forward
|
||||
class CForward
|
||||
{
|
||||
const char *m_FuncName;
|
||||
ForwardExecType m_ExecType;
|
||||
int m_NumParams;
|
||||
String m_Name;
|
||||
|
||||
struct AMXForward
|
||||
{
|
||||
CPluginMngr::CPlugin *pPlugin;
|
||||
int func;
|
||||
};
|
||||
|
||||
typedef CVector<AMXForward> AMXForwardList;
|
||||
|
||||
AMXForwardList m_Funcs;
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
|
||||
public:
|
||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
|
||||
CForward() {} // leaves everything unitialized'
|
||||
|
||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||
|
||||
int getParamsNum() const
|
||||
{
|
||||
return m_NumParams;
|
||||
}
|
||||
|
||||
int getFuncsNum() const
|
||||
{
|
||||
return m_Funcs.size();
|
||||
}
|
||||
|
||||
const char *getFuncName() const
|
||||
{
|
||||
return m_Name.c_str();
|
||||
}
|
||||
|
||||
ForwardParam getParamType(int paramId) const
|
||||
{
|
||||
if (paramId < 0 || paramId >= m_NumParams)
|
||||
return FP_DONE;
|
||||
|
||||
return m_ParamTypes[paramId];
|
||||
}
|
||||
};
|
||||
|
||||
// Single plugin forward
|
||||
class CSPForward
|
||||
{
|
||||
const char *m_FuncName;
|
||||
int m_NumParams;
|
||||
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
AMX *m_Amx;
|
||||
|
||||
int m_Func;
|
||||
bool m_HasFunc;
|
||||
String m_Name;
|
||||
|
||||
public:
|
||||
bool isFree;
|
||||
public:
|
||||
CSPForward() { m_HasFunc = false; }
|
||||
void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
|
||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||
|
||||
int getParamsNum() const
|
||||
{
|
||||
return m_NumParams;
|
||||
}
|
||||
|
||||
int getFuncsNum() const
|
||||
{
|
||||
return (m_HasFunc) ? 1 : 0;
|
||||
}
|
||||
|
||||
const char *getFuncName() const
|
||||
{
|
||||
return m_Name.c_str();
|
||||
}
|
||||
|
||||
ForwardParam getParamType(int paramId) const
|
||||
{
|
||||
if (paramId < 0 || paramId >= m_NumParams)
|
||||
return FP_DONE;
|
||||
|
||||
return m_ParamTypes[paramId];
|
||||
}
|
||||
};
|
||||
|
||||
class CForwardMngr
|
||||
{
|
||||
typedef CVector<CForward*> ForwardVec;
|
||||
typedef CVector<CSPForward*> SPForwardVec;
|
||||
typedef CStack<int> FreeSPVec; // Free SP Forwards
|
||||
|
||||
ForwardVec m_Forwards;
|
||||
|
||||
SPForwardVec m_SPForwards;
|
||||
FreeSPVec m_FreeSPForwards; // so we don't have to free memory
|
||||
|
||||
ForwardPreparedArray m_TmpArrays[FORWARD_MAX_PARAMS]; // used by prepareArray
|
||||
int m_TmpArraysNum;
|
||||
public:
|
||||
|
||||
class iterator;
|
||||
|
||||
class CForward
|
||||
{
|
||||
|
||||
friend class iterator;
|
||||
friend class CForwardMngr;
|
||||
|
||||
CPluginMngr::CPlugin* plugin;
|
||||
int function;
|
||||
CForward* next;
|
||||
CForward( CPluginMngr::CPlugin* p, int func ) : plugin(p) , function(func) {next=0;}
|
||||
|
||||
public:
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline int getFunction() { return function; }
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
private:
|
||||
CForward *head[ FORWARD_NUM ];
|
||||
void clearForwards( CForward** a );
|
||||
|
||||
public:
|
||||
CForwardMngr() {memset( head, 0, sizeof(head));}
|
||||
~CForwardMngr() { clear(); }
|
||||
CForwardMngr()
|
||||
{ m_TmpArraysNum = 0; }
|
||||
~CForwardMngr() {}
|
||||
|
||||
// Interface
|
||||
// Register normal forward
|
||||
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
|
||||
// Register single plugin forward
|
||||
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
|
||||
void registerForward( CPluginMngr::CPlugin* p, int func , int type );
|
||||
void executeForwards( int type , int num = 0, int player = 0 );
|
||||
void clear();
|
||||
// Unregister single plugin forward
|
||||
void unregisterSPForward(int id);
|
||||
|
||||
// execute forward
|
||||
cell executeForwards(int id, cell *params);
|
||||
void clear(); // delete all forwards
|
||||
|
||||
class iterator {
|
||||
CForward *a;
|
||||
public:
|
||||
iterator(CForward*aa) : a(aa) {}
|
||||
iterator& operator++() { a = a->next; return *this; }
|
||||
bool operator==(const iterator& b) const { return a == b.a; }
|
||||
bool operator!=(const iterator& b) const { return !operator==(b); }
|
||||
operator bool () const { return a ? true : false; }
|
||||
CForward& operator*() { return *a; }
|
||||
};
|
||||
inline iterator begin( int type ) const { return iterator(head[(int)type]); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
inline bool forwardsExist( int type ) {return head[(int)type]?true:false;}
|
||||
bool isIdValid(int id) const; // check whether forward id is valid
|
||||
bool isSPForward(int id) const; // check whether forward is single plugin
|
||||
int getParamsNum(int id) const; // get num of params of a forward
|
||||
int getFuncsNum(int id) const; // get num of found functions of a forward
|
||||
const char *getFuncName(int id) const; // get the function name
|
||||
|
||||
ForwardParam getParamType(int id, int paramId) const;
|
||||
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
|
||||
};
|
||||
|
||||
// (un)register forward
|
||||
int registerForward(const char *funcName, ForwardExecType et, ...);
|
||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num);
|
||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
|
||||
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num);
|
||||
int registerSPForward(AMX *amx, int func, ...);
|
||||
void unregisterSPForward(int id);
|
||||
|
||||
#endif
|
||||
// execute forwards
|
||||
cell executeForwards(int id, ...);
|
||||
// prepare array
|
||||
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
|
||||
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
|
||||
|
||||
#endif //FORWARD_H
|
||||
|
593
amxmodx/CLang.cpp
Executable file
593
amxmodx/CLang.cpp
Executable file
@ -0,0 +1,593 @@
|
||||
/* 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 <stdarg.h>
|
||||
#include "amxmodx.h"
|
||||
#include "CLang.h"
|
||||
#include "format.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
|
||||
#define LITIDX_NONE 0
|
||||
#define LITIDX_BRACKET 1
|
||||
#define LITIDX_DEFINITION 2
|
||||
|
||||
#define INSERT_NUMBER 1
|
||||
#define INSERT_FLOAT 2
|
||||
#define INSERT_STRING 3
|
||||
#define INSERT_NEWLINE 4
|
||||
|
||||
template<>
|
||||
int Compare<String>(const String &k1, const String &k2)
|
||||
{
|
||||
return k1.compare(k2.c_str());
|
||||
}
|
||||
|
||||
template<>
|
||||
int CompareAlt<char const *, String>(char const * const &k1, String const &k2)
|
||||
{
|
||||
return strcmp(k1, k2.c_str());
|
||||
}
|
||||
|
||||
template<>
|
||||
int HashFunction<String>(const String &k)
|
||||
{
|
||||
unsigned long hash = 5381;
|
||||
register const char *str = k.c_str();
|
||||
register char c;
|
||||
while (c = *str++) hash = ((hash << 5) + hash) + c; // hash*33 + c
|
||||
return hash;
|
||||
}
|
||||
|
||||
template<>
|
||||
int HashAlt<const char *>(char const * const &k)
|
||||
{
|
||||
unsigned long hash = 5381;
|
||||
register const char *str = k;
|
||||
register char c;
|
||||
while (c = *str++) hash = ((hash << 5) + hash) + c; // hash*33 + c
|
||||
return hash;
|
||||
}
|
||||
|
||||
template<>
|
||||
int HashFunction<int>(const int &k)
|
||||
{
|
||||
return k;
|
||||
}
|
||||
|
||||
template<>
|
||||
int Compare<int>(const int &k1, const int &k2)
|
||||
{
|
||||
return (k1-k2);
|
||||
}
|
||||
|
||||
// strip the whitespaces at the beginning and the end of a string
|
||||
// also convert to lowercase if needed
|
||||
// return the number of written characters (including the terimating zero char)
|
||||
size_t CLangMngr::strip(char *str, char *newstr, bool makelower)
|
||||
{
|
||||
size_t i = 0;
|
||||
size_t pos = 0;
|
||||
int flag = 0;
|
||||
size_t strln = strlen(str);
|
||||
|
||||
for (i = strln - 1; i >= 0; i--)
|
||||
{
|
||||
if (str[i] == '\n' || str[i] == ' ' || str[i] == '\t')
|
||||
{
|
||||
str[i] = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
char *ptr = str;
|
||||
while (*ptr)
|
||||
{
|
||||
if (!flag)
|
||||
{
|
||||
if (*ptr != '\n' && *ptr != ' ' && *ptr != '\t')
|
||||
{
|
||||
flag = 1;
|
||||
newstr[pos++] = makelower ? tolower(*ptr) : *ptr;
|
||||
}
|
||||
} else {
|
||||
newstr[pos++] = makelower ? tolower(*ptr) : *ptr;
|
||||
}
|
||||
++ptr;
|
||||
}
|
||||
|
||||
newstr[pos] = 0;
|
||||
|
||||
return ptr - str + 1;
|
||||
}
|
||||
|
||||
|
||||
/******** CLangMngr::CLang *********/
|
||||
|
||||
CLangMngr::CLang::CLang()
|
||||
{
|
||||
m_LookUpTable.clear();
|
||||
m_entries = 0;
|
||||
}
|
||||
|
||||
CLangMngr::CLang::CLang(const char *lang)
|
||||
{
|
||||
m_LookUpTable.clear();
|
||||
m_entries = 0;
|
||||
strncpy(m_LanguageName, lang, 2);
|
||||
m_LanguageName[2] = 0;
|
||||
}
|
||||
|
||||
void CLangMngr::CLang::AddEntry(int key, const char *definition)
|
||||
{
|
||||
defentry &d = m_LookUpTable[key];
|
||||
|
||||
if (d.definition)
|
||||
{
|
||||
delete d.definition;
|
||||
} else {
|
||||
m_entries++;
|
||||
}
|
||||
|
||||
d.definition = new String(definition);
|
||||
}
|
||||
|
||||
CLangMngr::CLang::~CLang()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CLangMngr::CLang::Clear()
|
||||
{
|
||||
THash<int, defentry>::iterator iter;
|
||||
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
|
||||
{
|
||||
if (iter->val.definition)
|
||||
{
|
||||
delete iter->val.definition;
|
||||
iter->val.definition = NULL;
|
||||
}
|
||||
}
|
||||
m_LookUpTable.clear();
|
||||
m_entries = 0;
|
||||
}
|
||||
|
||||
void CLangMngr::CLang::MergeDefinitions(CQueue<sKeyDef> &vec)
|
||||
{
|
||||
String *pDef;
|
||||
int key = -1;
|
||||
|
||||
while (!vec.empty())
|
||||
{
|
||||
key = vec.front().key;
|
||||
pDef = vec.front().definition;
|
||||
|
||||
AddEntry(key, pDef->c_str());
|
||||
|
||||
delete vec.front().definition;
|
||||
|
||||
vec.pop();
|
||||
}
|
||||
}
|
||||
|
||||
const char * CLangMngr::CLang::GetDef(int key, int &status)
|
||||
{
|
||||
defentry &def = m_LookUpTable[key];
|
||||
|
||||
if (!def.definition)
|
||||
{
|
||||
status = ERR_BADKEY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return def.definition->c_str();
|
||||
}
|
||||
|
||||
int CLangMngr::CLang::Entries()
|
||||
{
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
/******** CLangMngr *********/
|
||||
|
||||
inline String &make_string(const char *str)
|
||||
{
|
||||
static String g_temp;
|
||||
|
||||
g_temp.assign(str);
|
||||
|
||||
return g_temp;
|
||||
}
|
||||
|
||||
CLangMngr::CLangMngr()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
const char * CLangMngr::GetKey(int key)
|
||||
{
|
||||
if (key < 0 || key >= (int)KeyList.size())
|
||||
return NULL;
|
||||
|
||||
return KeyList[key]->c_str();
|
||||
}
|
||||
|
||||
int CLangMngr::GetKeyEntry(const char *key)
|
||||
{
|
||||
keytbl_val &val = KeyTable[key];
|
||||
|
||||
return val.index;
|
||||
}
|
||||
|
||||
int CLangMngr::AddKeyEntry(String &key)
|
||||
{
|
||||
keytbl_val val;
|
||||
val.index = static_cast<int>(KeyList.size());
|
||||
|
||||
String *pString = new String(key);
|
||||
KeyList.push_back(pString);
|
||||
|
||||
KeyTable[key] = val;
|
||||
|
||||
return val.index;
|
||||
}
|
||||
|
||||
int CLangMngr::GetKeyEntry(String &key)
|
||||
{
|
||||
keytbl_val &val = KeyTable[key];
|
||||
|
||||
return val.index;
|
||||
}
|
||||
|
||||
char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
|
||||
{
|
||||
//do an initial run through all this
|
||||
static char outbuf[4096];
|
||||
cell *addr = get_amxaddr(amx, params[parm++]);
|
||||
|
||||
len = atcprintf(outbuf, sizeof(outbuf)-1, addr, amx, params, &parm);
|
||||
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec)
|
||||
{
|
||||
CLang * language = GetLang(lang);
|
||||
if (language)
|
||||
language->MergeDefinitions(tmpVec);
|
||||
}
|
||||
|
||||
//this is the file parser for dictionary text files
|
||||
// -- BAILOPAN
|
||||
int CLangMngr::MergeDefinitionFile(const char *file)
|
||||
{
|
||||
FILE *fp = fopen(file, "rt");
|
||||
if (!fp)
|
||||
{
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
for (iter = FileList.begin(); iter != FileList.end(); ++iter)
|
||||
{
|
||||
if ((*iter)->file.compare(file) == 0)
|
||||
{
|
||||
char buf[33] = {0};
|
||||
(*iter)->val.assign(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
AMXXLOG_Log("[AMXX] Failed to open dictionary file: %s", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
MD5 md5;
|
||||
md5.update(fp); // closes for us
|
||||
md5.finalize();
|
||||
char md5buffer[33];
|
||||
md5.hex_digest(md5buffer);
|
||||
bool foundFlag = false;
|
||||
|
||||
CVector<md5Pair *>::iterator iter;
|
||||
for (iter = FileList.begin(); iter != FileList.end(); ++iter)
|
||||
{
|
||||
if ((*iter)->file.compare(file) == 0)
|
||||
{
|
||||
if ((*iter)->val.compare(md5buffer) == 0)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
(*iter)->val.assign(md5buffer);
|
||||
break;
|
||||
}
|
||||
foundFlag = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFlag)
|
||||
{
|
||||
md5Pair *p = new md5Pair;
|
||||
p->file.assign(file);
|
||||
p->val.assign(md5buffer);
|
||||
FileList.push_back(p);
|
||||
}
|
||||
|
||||
fp = fopen(file, "rt");
|
||||
if (!fp)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Failed to re-open dictionary file: %s", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Allocate enough memory to store everything
|
||||
bool multiline = 0;
|
||||
int pos = 0, line = 0;
|
||||
CQueue<sKeyDef> Defq;
|
||||
String buf;
|
||||
char language[3];
|
||||
sKeyDef tmpEntry;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
line++;
|
||||
buf._fread(fp);
|
||||
buf.trim();
|
||||
if (buf[0] == 0)
|
||||
continue;
|
||||
if ((buf[0] == ';') || (buf[0] == '/' && buf[1] == '/'))
|
||||
continue;
|
||||
|
||||
if (buf[0] == '[' && buf.size() >= 3)
|
||||
{
|
||||
if (multiline)
|
||||
{
|
||||
AMXXLOG_Log("New section, multiline unterminated (file \"%s\" line %d)", file, line);
|
||||
tmpEntry.key = -1;
|
||||
tmpEntry.definition = NULL;
|
||||
}
|
||||
|
||||
if (!Defq.empty())
|
||||
{
|
||||
MergeDefinitions(language, Defq);
|
||||
}
|
||||
|
||||
language[0] = buf[1];
|
||||
language[1] = buf[2];
|
||||
language[2] = 0;
|
||||
} else {
|
||||
if (!multiline)
|
||||
{
|
||||
pos = buf.find('=');
|
||||
|
||||
if (pos > String::npos)
|
||||
{
|
||||
String key;
|
||||
key.assign(buf.substr(0, pos).c_str());
|
||||
String def;
|
||||
def.assign(buf.substr(pos + 1).c_str());
|
||||
key.trim();
|
||||
key.toLower();
|
||||
int iKey = GetKeyEntry(key);
|
||||
if (iKey == -1)
|
||||
iKey = AddKeyEntry(key);
|
||||
tmpEntry.key = iKey;
|
||||
tmpEntry.definition = new String;
|
||||
tmpEntry.definition->assign(def.c_str());
|
||||
tmpEntry.definition->trim();
|
||||
tmpEntry.definition->reparse_newlines();
|
||||
Defq.push(tmpEntry);
|
||||
tmpEntry.key = -1;
|
||||
tmpEntry.definition = NULL;
|
||||
} else {
|
||||
pos = buf.find(':');
|
||||
|
||||
if (pos > String::npos)
|
||||
{
|
||||
String key;
|
||||
key.assign(buf.substr(0, pos).c_str());;
|
||||
key.trim();
|
||||
key.toLower();
|
||||
int iKey = GetKeyEntry(key);
|
||||
if (iKey == -1)
|
||||
iKey = AddKeyEntry(key);
|
||||
tmpEntry.key = iKey;
|
||||
tmpEntry.definition = new String;
|
||||
multiline = true;
|
||||
} else {
|
||||
//user typed a line with no directives
|
||||
AMXXLOG_Log("Invalid multi-lingual line (file \"%s\" line %d)", file, line);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (buf[0] == ':')
|
||||
{
|
||||
tmpEntry.definition->reparse_newlines();
|
||||
Defq.push(tmpEntry);
|
||||
tmpEntry.key = -1;
|
||||
tmpEntry.definition = NULL;
|
||||
multiline = false;
|
||||
} else {
|
||||
if (!tmpEntry.definition)
|
||||
tmpEntry.definition = new String();
|
||||
tmpEntry.definition->append(buf);
|
||||
}
|
||||
} // if !multiline
|
||||
} //if - main
|
||||
}
|
||||
|
||||
// merge last section
|
||||
if (!Defq.empty())
|
||||
{
|
||||
MergeDefinitions(language, Defq);
|
||||
}
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Find a CLang by name, if not found, add it
|
||||
CLangMngr::CLang * CLangMngr::GetLang(const char *name)
|
||||
{
|
||||
LangVecIter iter;
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if (strcmp((*iter)->GetName(), name) == 0)
|
||||
return (*iter);
|
||||
}
|
||||
|
||||
CLang *p = new CLang(name);
|
||||
p->SetMngr(this);
|
||||
|
||||
m_Languages.push_back(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
// Find a CLang by name, if not found, return NULL
|
||||
CLangMngr::CLang * CLangMngr::GetLangR(const char *name)
|
||||
{
|
||||
LangVecIter iter;
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if (strcmp((*iter)->GetName(), name) == 0)
|
||||
return (*iter);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *CLangMngr::GetDef(const char *langName, const char *key, int &status)
|
||||
{
|
||||
CLang *lang = GetLangR(langName);
|
||||
keytbl_val &val = KeyTable.AltFindOrInsert(key); //KeyTable[make_string(key)];
|
||||
if (lang == NULL)
|
||||
{
|
||||
status = ERR_BADLANG;
|
||||
return NULL;
|
||||
} else if (val.index == -1) {
|
||||
status = ERR_BADKEY;
|
||||
return NULL;
|
||||
} else {
|
||||
return lang->GetDef(val.index, status);
|
||||
}
|
||||
}
|
||||
|
||||
void CLangMngr::InvalidateCache()
|
||||
{
|
||||
for (size_t i = 0; i < FileList.size(); i++)
|
||||
{
|
||||
if (FileList[i])
|
||||
delete FileList[i];
|
||||
}
|
||||
|
||||
FileList.clear();
|
||||
}
|
||||
|
||||
CLangMngr::~CLangMngr()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
void CLangMngr::Clear()
|
||||
{
|
||||
unsigned int i = 0;
|
||||
|
||||
KeyTable.clear();
|
||||
|
||||
for (i = 0; i < m_Languages.size(); i++)
|
||||
{
|
||||
if (m_Languages[i])
|
||||
delete m_Languages[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < FileList.size(); i++)
|
||||
{
|
||||
if (FileList[i])
|
||||
delete FileList[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < KeyList.size(); i++)
|
||||
{
|
||||
if (KeyList[i])
|
||||
delete KeyList[i];
|
||||
}
|
||||
|
||||
m_Languages.clear();
|
||||
KeyList.clear();
|
||||
FileList.clear();
|
||||
}
|
||||
|
||||
int CLangMngr::GetLangsNum()
|
||||
{
|
||||
return m_Languages.size();
|
||||
}
|
||||
|
||||
const char *CLangMngr::GetLangName(int langId)
|
||||
{
|
||||
int i = 0;
|
||||
LangVecIter iter;
|
||||
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if (i == langId)
|
||||
{
|
||||
return (*iter)->GetName();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool CLangMngr::LangExists(const char *langName)
|
||||
{
|
||||
char buf[3] = {0};
|
||||
int i = 0;
|
||||
|
||||
while (buf[i] = tolower(*langName++))
|
||||
{
|
||||
if (++i == 2)
|
||||
break;
|
||||
}
|
||||
|
||||
LangVecIter iter;
|
||||
|
||||
for (iter = m_Languages.begin(); iter != m_Languages.end(); ++iter)
|
||||
{
|
||||
if (strcmp((*iter)->GetName(), buf) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CLangMngr::SetDefLang(int id)
|
||||
{
|
||||
m_CurGlobId = id;
|
||||
}
|
188
amxmodx/CLang.h
Executable file
188
amxmodx/CLang.h
Executable file
@ -0,0 +1,188 @@
|
||||
/* 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_CLANG_H
|
||||
#define _INCLUDE_CLANG_H
|
||||
|
||||
#include "sh_tinyhash.h"
|
||||
|
||||
#define LANG_SERVER 0
|
||||
#define LANG_PLAYER -1
|
||||
|
||||
#define ERR_BADKEY 1 // Lang key not found
|
||||
#define ERR_BADLANG 2 // Invalid lang
|
||||
|
||||
struct md5Pair
|
||||
{
|
||||
String file;
|
||||
String val;
|
||||
};
|
||||
|
||||
struct sKeyDef
|
||||
{
|
||||
String *definition;
|
||||
int key;
|
||||
};
|
||||
|
||||
struct lang_err
|
||||
{
|
||||
lang_err() : last(0.0f)
|
||||
{
|
||||
};
|
||||
float last;
|
||||
};
|
||||
|
||||
class defentry
|
||||
{
|
||||
public:
|
||||
defentry() : definition(NULL)
|
||||
{
|
||||
};
|
||||
defentry(const defentry &src)
|
||||
{
|
||||
definition = src.definition;
|
||||
}
|
||||
~defentry()
|
||||
{
|
||||
}
|
||||
String *definition;
|
||||
};
|
||||
|
||||
struct keytbl_val
|
||||
{
|
||||
keytbl_val() : index(-1)
|
||||
{
|
||||
};
|
||||
int index;
|
||||
};
|
||||
|
||||
class CLangMngr
|
||||
{
|
||||
class CLang
|
||||
{
|
||||
public:
|
||||
// Construct an empty CLang object
|
||||
CLang();
|
||||
// Construct a CLang object initialized with a language name
|
||||
CLang(const char *lang);
|
||||
// Destructor
|
||||
~CLang();
|
||||
|
||||
// Get the definition
|
||||
const char *GetDef(int key, int &status);
|
||||
// Add definitions to this language
|
||||
void MergeDefinitions(CQueue <sKeyDef> & vec);
|
||||
// Reset this language
|
||||
void Clear();
|
||||
|
||||
// compare this language to a language name
|
||||
friend bool operator == (const CLang &left, const char *right)
|
||||
{
|
||||
return strcmp(left.m_LanguageName, right) == 0 ? true : false;
|
||||
}
|
||||
|
||||
// Get language name
|
||||
const char *GetName() { return m_LanguageName; }
|
||||
void SetMngr(CLangMngr *l) { m_LMan = l; }
|
||||
// Get number of entries
|
||||
int Entries();
|
||||
protected:
|
||||
typedef THash<int, defentry> LookUpVec;
|
||||
typedef LookUpVec::iterator LookUpVecIter;
|
||||
|
||||
char m_LanguageName[3];
|
||||
|
||||
// our lookup table
|
||||
LookUpVec m_LookUpTable;
|
||||
int m_entries;
|
||||
CLangMngr *m_LMan;
|
||||
public:
|
||||
void AddEntry(int key, const char *definition);
|
||||
};
|
||||
|
||||
// Merge definitions into a language
|
||||
void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
|
||||
// strip lowercase; make lower if needed
|
||||
static size_t strip(char *str, char *newstr, bool makelower = false);
|
||||
|
||||
typedef CVector<CLang*> LangVec;
|
||||
typedef CVector<CLang*>::iterator LangVecIter;
|
||||
|
||||
LangVec m_Languages;
|
||||
|
||||
CVector<md5Pair *> FileList;
|
||||
CVector<String *> KeyList;
|
||||
THash<String, keytbl_val> KeyTable;
|
||||
|
||||
// Get a lang object (construct if needed)
|
||||
CLang * GetLang(const char *name);
|
||||
|
||||
CLang * GetLangR(const char *name);
|
||||
|
||||
// Current global client-id for functions like client_print with first parameter 0
|
||||
int m_CurGlobId;
|
||||
public:
|
||||
// Merge a definitions file
|
||||
int MergeDefinitionFile(const char *file);
|
||||
// Get a definition from a lang name and a key
|
||||
const char *GetDef(const char *langName, const char *key, int &status);
|
||||
// Format a string for an AMX plugin
|
||||
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
|
||||
void InvalidateCache();
|
||||
// Get index
|
||||
int GetKeyEntry(String &key);
|
||||
int GetKeyEntry(const char *key);
|
||||
int GetKeyIndex(const char *key);
|
||||
// Get key from index
|
||||
const char *GetKey(int key);
|
||||
// Add key
|
||||
int AddKeyEntry(String &key);
|
||||
|
||||
// Get the number of languages
|
||||
int GetLangsNum();
|
||||
// Get the name of a language
|
||||
const char *GetLangName(int langId);
|
||||
// Check if a language exists
|
||||
bool LangExists(const char *langName);
|
||||
|
||||
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
|
||||
void SetDefLang(int id);
|
||||
|
||||
inline int GetDefLang() const { return m_CurGlobId; }
|
||||
|
||||
// Reset
|
||||
void Clear();
|
||||
|
||||
CLangMngr();
|
||||
~CLangMngr();
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CLANG_H
|
335
amxmodx/CList.h
335
amxmodx/CList.h
@ -36,75 +36,294 @@
|
||||
// class CList
|
||||
// *****************************************************
|
||||
|
||||
// Linked list
|
||||
template <typename T, typename F = char* >
|
||||
class CList {
|
||||
public:
|
||||
class iterator;
|
||||
class CListEle {
|
||||
friend class CList<T,F>;
|
||||
friend class iterator;
|
||||
T* obj;
|
||||
CListEle* next;
|
||||
CListEle( T* a , CListEle* nn ) : obj(a) , next(nn) {}
|
||||
public:
|
||||
T& operator* () { return *obj; }
|
||||
};
|
||||
class CList
|
||||
{
|
||||
private:
|
||||
CListEle *head;
|
||||
int cur_size;
|
||||
public:
|
||||
CList<T,F>() { head = 0; cur_size = 0; }
|
||||
~CList<T,F>() { clear(); }
|
||||
void clear() {
|
||||
iterator a = begin();
|
||||
while( a ) a.remove();
|
||||
cur_size = 0;
|
||||
}
|
||||
void put( T* a ) {
|
||||
head = new CListEle( a , head );
|
||||
++cur_size;
|
||||
}
|
||||
int size() {
|
||||
return cur_size;
|
||||
}
|
||||
class iterator {
|
||||
CListEle** a;
|
||||
// One list element
|
||||
class CElement
|
||||
{
|
||||
T *m_pObject; // pointer to the object
|
||||
CElement *m_pNext; // pointer to the next element
|
||||
CElement *m_pPrev; // pointer to the previous element
|
||||
public:
|
||||
iterator(CListEle** i=0) : a(i){}
|
||||
T& operator*() const { return *(*a)->obj;}
|
||||
inline operator bool () const { return (a && *a); }
|
||||
inline iterator& operator++() {
|
||||
a = &(*a)->next;
|
||||
// dereference operator
|
||||
T& operator* ()
|
||||
{
|
||||
return *m_pObject;
|
||||
}
|
||||
|
||||
// constructor
|
||||
CElement(T *pObj)
|
||||
{
|
||||
m_pObject = pObj;
|
||||
m_pNext = NULL;
|
||||
m_pPrev = NULL;
|
||||
}
|
||||
|
||||
// destructor
|
||||
~CElement()
|
||||
{
|
||||
delete m_pObject;
|
||||
|
||||
if (m_pNext)
|
||||
m_pNext->m_pPrev = m_pPrev;
|
||||
|
||||
if (m_pPrev)
|
||||
m_pPrev->m_pNext = m_pNext;
|
||||
}
|
||||
|
||||
// returns object pointer
|
||||
T *GetObj()
|
||||
{
|
||||
return m_pObject;
|
||||
}
|
||||
|
||||
// returns next element pointer
|
||||
CElement *GetNext()
|
||||
{
|
||||
return m_pNext;
|
||||
}
|
||||
|
||||
// sets next element
|
||||
void SetNext(CElement *newNext)
|
||||
{
|
||||
m_pNext = newNext;
|
||||
}
|
||||
|
||||
// returns previous element pointer
|
||||
CElement *GetPrev()
|
||||
{
|
||||
return m_pPrev;
|
||||
}
|
||||
|
||||
// sets previous element
|
||||
void SetPrev(CElement *newPrev)
|
||||
{
|
||||
m_pPrev = newPrev;
|
||||
}
|
||||
};
|
||||
|
||||
// CList<T, F> class
|
||||
CElement *m_pHead; // head of the linked list
|
||||
CElement *m_pTail; // tail of the linked list
|
||||
public:
|
||||
// iterator class
|
||||
class iterator
|
||||
{
|
||||
friend class CList<T, F>;
|
||||
|
||||
CList<T, F> *m_pList; // The list that created this iterator
|
||||
CElement *m_CurPos; // Current position in the list
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_pList = NULL;
|
||||
m_CurPos = NULL;
|
||||
}
|
||||
|
||||
// constructor based on list, element
|
||||
iterator(CList<T, F> *pList, CElement *startPos)
|
||||
{
|
||||
m_pList = pList;
|
||||
m_CurPos = startPos;
|
||||
}
|
||||
|
||||
// constructor based on other iterator
|
||||
iterator(const iterator &other)
|
||||
{
|
||||
m_pList = other.m_pList;
|
||||
m_CurPos = other.m_CurPos;
|
||||
}
|
||||
|
||||
// dereference operator
|
||||
T & operator* () const
|
||||
{
|
||||
return *m_CurPos->GetObj();
|
||||
}
|
||||
|
||||
T * operator-> () const
|
||||
{
|
||||
return m_CurPos->GetObj();
|
||||
}
|
||||
|
||||
// validity check operator
|
||||
inline operator bool () const
|
||||
{
|
||||
return m_pList != NULL && m_CurPos != NULL && m_CurPos->GetObj() != NULL;
|
||||
}
|
||||
|
||||
// pre increment operator
|
||||
inline iterator& operator ++ ()
|
||||
{
|
||||
m_CurPos = m_CurPos->GetNext();
|
||||
return *this;
|
||||
}
|
||||
inline iterator operator++(int) {
|
||||
iterator tmp(a);
|
||||
a = &(*a)->next;
|
||||
|
||||
// post increment operator
|
||||
inline iterator operator++(int)
|
||||
{
|
||||
iterator tmp(*this);
|
||||
m_CurPos = m_CurPos->next;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
iterator& remove(){
|
||||
CListEle* aa = (*a)->next;
|
||||
delete (*a)->obj;
|
||||
delete *a;
|
||||
*a = aa;
|
||||
return *this;
|
||||
|
||||
// returns iterator that points to next element
|
||||
iterator GetNext()
|
||||
{
|
||||
iterator tmp(*this);
|
||||
return ++tmp;
|
||||
}
|
||||
iterator& put( T* aa ){
|
||||
*a = new CListEle( aa , *a );
|
||||
return *this;
|
||||
|
||||
iterator remove()
|
||||
{
|
||||
return m_pList->remove(*this);
|
||||
}
|
||||
|
||||
iterator put(T *obj)
|
||||
{
|
||||
return m_pList->put(obj, *this);
|
||||
}
|
||||
};
|
||||
inline iterator begin() { return iterator(&head); }
|
||||
iterator find( F a ){
|
||||
iterator cc = begin();
|
||||
while(cc){
|
||||
if ( *cc == a )
|
||||
break;
|
||||
++cc;
|
||||
|
||||
CList<T, F>()
|
||||
{
|
||||
m_pHead = NULL;
|
||||
m_pTail = NULL;
|
||||
}
|
||||
|
||||
~CList<T, F>()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// removes the object referenced by where
|
||||
// sets where to the next object
|
||||
// returns an iterator pointing to the next object
|
||||
iterator remove(iterator &where)
|
||||
{
|
||||
iterator tmp(where.GetNext());
|
||||
|
||||
if (where.m_CurPos == m_pHead)
|
||||
m_pHead = where.m_CurPos->GetNext();
|
||||
|
||||
if (where.m_CurPos == m_pTail)
|
||||
m_pTail = where.m_CurPos->GetPrev();
|
||||
|
||||
delete where.m_CurPos;
|
||||
where = tmp;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// puts an element to the end of the list
|
||||
// returns an iterator pointing to it
|
||||
iterator put_back(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
} else {
|
||||
pTmp->SetNext(NULL);
|
||||
pTmp->SetPrev(m_pTail);
|
||||
m_pTail->SetNext(pTmp);
|
||||
m_pTail = pTmp;
|
||||
}
|
||||
return cc;
|
||||
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
iterator put_front(T *pObj)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (!m_pHead)
|
||||
{
|
||||
m_pHead = pTmp;
|
||||
m_pTail = pTmp;
|
||||
} else {
|
||||
pTmp->SetNext(m_pHead);
|
||||
pTmp->SetPrev(NULL);
|
||||
m_pHead->SetPrev(pTmp);
|
||||
m_pHead = pTmp;
|
||||
}
|
||||
|
||||
return iterator(this, pTmp);
|
||||
}
|
||||
|
||||
// alias for put_back
|
||||
iterator put(T *pObj)
|
||||
{
|
||||
return put_back(pObj);
|
||||
}
|
||||
|
||||
// puts an element after where
|
||||
// alters where to point to the new element
|
||||
// returns an iterator pointing to the new element
|
||||
iterator put(T *pObj, iterator &where)
|
||||
{
|
||||
CElement *pTmp = new CElement(pObj);
|
||||
|
||||
if (where.m_CurPos->GetNext())
|
||||
where.m_CurPos->GetNext()->SetPrev(pTmp);
|
||||
else // where = tail
|
||||
m_pTail = pTmp;
|
||||
|
||||
pTmp->SetPrev(where.m_CurPos);
|
||||
pTmp->SetNext(where.m_CurPos->GetNext());
|
||||
|
||||
where.m_CurPos->SetNext(pTmp);
|
||||
|
||||
return ++where;
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this, m_pHead);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
iterator iter = begin();
|
||||
while (iter) iter.remove();
|
||||
}
|
||||
|
||||
iterator find(iterator startOn, const F &desc)
|
||||
{
|
||||
iterator iter = startOn;
|
||||
while (iter)
|
||||
{
|
||||
if (*iter == desc)
|
||||
break;
|
||||
++iter;
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
iterator find(const F &desc)
|
||||
{
|
||||
return find(begin(), desc);
|
||||
}
|
||||
|
||||
int size()
|
||||
{
|
||||
iterator iter = begin();
|
||||
int i = 0;
|
||||
|
||||
while (iter)
|
||||
{
|
||||
++i;
|
||||
++iter;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif //CLIST_H
|
||||
|
@ -29,225 +29,290 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CLogEvent.h"
|
||||
|
||||
// *****************************************************
|
||||
// class LogEventsMngr
|
||||
// *****************************************************
|
||||
LogEventsMngr::LogEventsMngr() {
|
||||
logCurrent = logCounter = 0;
|
||||
logcmplist = 0;
|
||||
arelogevents = false;
|
||||
memset( logevents, 0, sizeof(logevents) );
|
||||
|
||||
LogEventsMngr::LogEventsMngr()
|
||||
{
|
||||
logCurrent = logCounter = 0;
|
||||
logcmplist = 0;
|
||||
arelogevents = false;
|
||||
memset(logevents, 0, sizeof(logevents));
|
||||
}
|
||||
|
||||
LogEventsMngr::~LogEventsMngr() {
|
||||
clearLogEvents();
|
||||
LogEventsMngr::~LogEventsMngr()
|
||||
{
|
||||
clearLogEvents();
|
||||
}
|
||||
|
||||
int LogEventsMngr::CLogCmp::compareCondition(const char* string){
|
||||
if ( logid == parent->logCounter )
|
||||
return result;
|
||||
logid = parent->logCounter;
|
||||
if ( in ) return result = strstr( string , text.str() ) ? 0 : 1;
|
||||
return result = strcmp(string,text.str());
|
||||
int LogEventsMngr::CLogCmp::compareCondition(const char* string)
|
||||
{
|
||||
if (logid == parent->logCounter)
|
||||
return result;
|
||||
|
||||
logid = parent->logCounter;
|
||||
|
||||
if (in)
|
||||
return result = strstr(string, text.c_str()) ? 0 : 1;
|
||||
|
||||
return result = strcmp(string,text.c_str());
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter){
|
||||
LogEventsMngr::CLogCmp* LogEventsMngr::registerCondition(char* filter)
|
||||
{
|
||||
char* temp = filter;
|
||||
// expand "1=message"
|
||||
while ( isdigit(*filter) )
|
||||
|
||||
while (isdigit(*filter))
|
||||
++filter;
|
||||
bool in = (*filter=='&');
|
||||
*filter++ = 0;
|
||||
int pos = atoi(temp);
|
||||
if ( pos < 0 || pos >= MAX_LOGARGS) pos = 0;
|
||||
|
||||
bool in = (*filter=='&');
|
||||
*filter++ = 0;
|
||||
int pos = atoi(temp);
|
||||
|
||||
if (pos < 0 || pos >= MAX_LOGARGS)
|
||||
pos = 0;
|
||||
|
||||
CLogCmp* c = logcmplist;
|
||||
while( c ) {
|
||||
if ( (c->pos==pos) && (c->in==in) && !strcmp(c->text.str(), filter))
|
||||
|
||||
while (c)
|
||||
{
|
||||
if ((c->pos == pos) && (c->in == in) && !strcmp(c->text.c_str(), filter))
|
||||
return c;
|
||||
c = c->next;
|
||||
}
|
||||
return logcmplist = new CLogCmp( filter , in , pos , logcmplist,this );
|
||||
|
||||
return logcmplist = new CLogCmp(filter, in, pos, logcmplist, this);
|
||||
}
|
||||
|
||||
void LogEventsMngr::CLogEvent::registerFilter( char* filter ){
|
||||
CLogCmp *cmp = parent->registerCondition( filter );
|
||||
if ( cmp == 0 ) return;
|
||||
for(LogCond* c = filters; c ; c = c->next){
|
||||
if ( c->argnum == cmp->pos ){
|
||||
c->list = new LogCondEle( cmp , c->list );
|
||||
void LogEventsMngr::CLogEvent::registerFilter(char* filter)
|
||||
{
|
||||
CLogCmp *cmp = parent->registerCondition(filter);
|
||||
if (cmp == 0) return;
|
||||
|
||||
for (LogCond* c = filters; c; c = c->next)
|
||||
{
|
||||
if (c->argnum == cmp->pos)
|
||||
{
|
||||
c->list = new LogCondEle(cmp, c->list);
|
||||
return;
|
||||
}
|
||||
}
|
||||
LogCondEle* aa = new LogCondEle( cmp , 0 );
|
||||
if ( aa == 0 ) return;
|
||||
filters = new LogCond( cmp->pos , aa , filters );
|
||||
|
||||
LogCondEle* aa = new LogCondEle(cmp, 0);
|
||||
|
||||
if (aa == 0)
|
||||
return;
|
||||
|
||||
filters = new LogCond(cmp->pos, aa, filters);
|
||||
}
|
||||
|
||||
void LogEventsMngr::setLogString( char* frmt, va_list& vaptr ) {
|
||||
void LogEventsMngr::setLogString(char* frmt, va_list& vaptr)
|
||||
{
|
||||
++logCounter;
|
||||
int len = vsnprintf (logString, 255 , frmt, vaptr );
|
||||
if ( len == - 1) {
|
||||
int len = vsnprintf(logString, 255, frmt, vaptr);
|
||||
|
||||
if (len == - 1)
|
||||
{
|
||||
len = 255;
|
||||
logString[len] = 0;
|
||||
}
|
||||
if ( len ) logString[--len] = 0;
|
||||
|
||||
if (len)
|
||||
logString[--len] = 0;
|
||||
|
||||
logArgc = 0;
|
||||
}
|
||||
|
||||
void LogEventsMngr::setLogString( char* frmt, ... ) {
|
||||
void LogEventsMngr::setLogString(char* frmt, ...)
|
||||
{
|
||||
++logCounter;
|
||||
va_list logArgPtr;
|
||||
va_start ( logArgPtr , frmt );
|
||||
int len = vsnprintf(logString, 255 , frmt, logArgPtr );
|
||||
if ( len == - 1) {
|
||||
va_start(logArgPtr, frmt);
|
||||
int len = vsnprintf(logString, 255, frmt, logArgPtr);
|
||||
|
||||
if (len == - 1)
|
||||
{
|
||||
len = 255;
|
||||
logString[len] = 0;
|
||||
}
|
||||
va_end ( logArgPtr );
|
||||
if ( len ) logString[--len] = 0;
|
||||
|
||||
va_end(logArgPtr);
|
||||
|
||||
if (len)
|
||||
logString[--len] = 0;
|
||||
|
||||
logArgc = 0;
|
||||
}
|
||||
|
||||
void LogEventsMngr::parseLogString( ) {
|
||||
register const char* b = logString;
|
||||
register int a;
|
||||
while( *b && logArgc < MAX_LOGARGS ){
|
||||
a = 0;
|
||||
if ( *b == '"' ) {
|
||||
++b;
|
||||
while ( *b && *b != '"' && a < 127 )
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
logArgs[logArgc++][a] = 0;
|
||||
if ( *b) b+=2; // thanks to double terminator
|
||||
}
|
||||
else if ( *b == '(' ) {
|
||||
++b;
|
||||
while ( *b && *b != ')' && a < 127 )
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
logArgs[logArgc++][a] = 0;
|
||||
if ( *b) b+=2;
|
||||
}
|
||||
else {
|
||||
while ( *b && *b != '(' && *b != '"' && a < 127 )
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
if ( *b ) --a;
|
||||
logArgs[logArgc++][a] = 0;
|
||||
}
|
||||
}
|
||||
void LogEventsMngr::parseLogString()
|
||||
{
|
||||
register const char* b = logString;
|
||||
register int a;
|
||||
|
||||
while (*b && logArgc < MAX_LOGARGS)
|
||||
{
|
||||
a = 0;
|
||||
|
||||
if (*b == '"')
|
||||
{
|
||||
++b;
|
||||
|
||||
while (*b && *b != '"' && a < 127)
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
|
||||
logArgs[logArgc++][a] = 0;
|
||||
if (*b) b+=2; // thanks to double terminator
|
||||
}
|
||||
else if (*b == '(')
|
||||
{
|
||||
++b;
|
||||
|
||||
while (*b && *b != ')' && a < 127)
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
|
||||
logArgs[logArgc++][a] = 0;
|
||||
if (*b) b+=2;
|
||||
} else {
|
||||
while (*b && *b != '(' && *b != '"' && a < 127)
|
||||
logArgs[logArgc][a++] = *b++;
|
||||
if (*b) --a;
|
||||
logArgs[logArgc++][a] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos )
|
||||
LogEventsMngr::CLogEvent* LogEventsMngr::registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos)
|
||||
{
|
||||
if ( pos < 1 || pos > MAX_LOGARGS)
|
||||
return 0;
|
||||
arelogevents = true;
|
||||
CLogEvent** d = &logevents[pos];
|
||||
while(*d) d = &(*d)->next;
|
||||
return *d = new CLogEvent( plugin , func, this );
|
||||
if (pos < 1 || pos > MAX_LOGARGS)
|
||||
return 0;
|
||||
|
||||
arelogevents = true;
|
||||
CLogEvent** d = &logevents[pos];
|
||||
|
||||
while (*d)
|
||||
d = &(*d)->next;
|
||||
|
||||
return *d = new CLogEvent(plugin, func, this);
|
||||
}
|
||||
|
||||
void LogEventsMngr::executeLogEvents()
|
||||
{
|
||||
int err;
|
||||
bool valid;
|
||||
for(CLogEvent* a = logevents[ logArgc ]; a ; a = a->next){
|
||||
bool valid;
|
||||
|
||||
for (CLogEvent* a = logevents[logArgc]; a; a = a->next)
|
||||
{
|
||||
valid = true;
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||
|
||||
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
|
||||
{
|
||||
valid = false;
|
||||
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||
|
||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
||||
{
|
||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!valid) break;
|
||||
|
||||
if (!valid)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
try
|
||||
if (valid)
|
||||
{
|
||||
#endif
|
||||
|
||||
if (valid){
|
||||
if ((err = amx_Exec(a->plugin->getAMX(), NULL , a->func , 0)) != AMX_ERR_NONE)
|
||||
UTIL_Log("[AMXX] Run time error %d on line %ld (plugin \"%s\")",
|
||||
err,a->plugin->getAMX()->curline,a->plugin->getName());
|
||||
}
|
||||
|
||||
#ifdef ENABLEEXEPTIONS
|
||||
executeForwards(a->func);
|
||||
}
|
||||
catch( ... )
|
||||
}
|
||||
}
|
||||
|
||||
void LogEventsMngr::clearLogEvents()
|
||||
{
|
||||
logCurrent = logCounter = 0;
|
||||
arelogevents = false;
|
||||
|
||||
for (int i = 0; i < MAX_LOGARGS + 1; ++i)
|
||||
{
|
||||
CLogEvent **a = &logevents[i];
|
||||
while (*a)
|
||||
{
|
||||
UTIL_Log( "[AMXX] fatal error at log forward function execution");
|
||||
CLogEvent* bb = (*a)->next;
|
||||
delete *a;
|
||||
*a = bb;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
clearConditions();
|
||||
}
|
||||
|
||||
void LogEventsMngr::clearLogEvents(){
|
||||
logCurrent = logCounter = 0;
|
||||
arelogevents = false;
|
||||
for(int i = 0; i < MAX_LOGARGS + 1; ++i){
|
||||
CLogEvent **a = &logevents[i];
|
||||
while(*a){
|
||||
CLogEvent* bb = (*a)->next;
|
||||
delete *a;
|
||||
*a = bb;
|
||||
}
|
||||
}
|
||||
clearConditions();
|
||||
void LogEventsMngr::clearConditions()
|
||||
{
|
||||
while (logcmplist)
|
||||
{
|
||||
CLogCmp* a = logcmplist->next;
|
||||
delete logcmplist;
|
||||
logcmplist = a;
|
||||
}
|
||||
}
|
||||
|
||||
void LogEventsMngr::clearConditions() {
|
||||
while (logcmplist){
|
||||
CLogCmp* a = logcmplist->next;
|
||||
delete logcmplist;
|
||||
logcmplist = a;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent::LogCond::~LogCond() {
|
||||
while( list ) {
|
||||
LogEventsMngr::CLogEvent::LogCond::~LogCond()
|
||||
{
|
||||
while (list)
|
||||
{
|
||||
LogCondEle* cc = list->next;
|
||||
delete list;
|
||||
list = cc;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent::~CLogEvent() {
|
||||
while( filters ) {
|
||||
LogEventsMngr::CLogEvent::~CLogEvent()
|
||||
{
|
||||
while (filters)
|
||||
{
|
||||
LogCond* cc = filters->next;
|
||||
delete filters;
|
||||
filters = cc;
|
||||
}
|
||||
}
|
||||
|
||||
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent( CLogEvent * a )
|
||||
LogEventsMngr::CLogEvent *LogEventsMngr::getValidLogEvent(CLogEvent * a)
|
||||
{
|
||||
bool valid;
|
||||
while(a){
|
||||
|
||||
while (a)
|
||||
{
|
||||
valid = true;
|
||||
for( CLogEvent::LogCond* b = a->filters; b ; b = b->next){
|
||||
|
||||
for (CLogEvent::LogCond* b = a->filters; b; b = b->next)
|
||||
{
|
||||
valid = false;
|
||||
for( CLogEvent::LogCondEle* c = b->list; c ; c = c->next) {
|
||||
if ( c->cmp->compareCondition( logArgs[b->argnum] ) == 0 ){
|
||||
|
||||
for (CLogEvent::LogCondEle* c = b->list; c; c = c->next)
|
||||
{
|
||||
if (c->cmp->compareCondition(logArgs[b->argnum]) == 0)
|
||||
{
|
||||
valid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) break;
|
||||
}
|
||||
if (!valid){
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -40,127 +40,139 @@
|
||||
// class LogEventsMngr
|
||||
// *****************************************************
|
||||
|
||||
class LogEventsMngr {
|
||||
|
||||
char logString[256];
|
||||
char logArgs[MAX_LOGARGS][128];
|
||||
int logArgc;
|
||||
int logCounter;
|
||||
int logCurrent;
|
||||
bool arelogevents;
|
||||
class LogEventsMngr
|
||||
{
|
||||
char logString[256];
|
||||
char logArgs[MAX_LOGARGS][128];
|
||||
int logArgc;
|
||||
int logCounter;
|
||||
int logCurrent;
|
||||
bool arelogevents;
|
||||
|
||||
public:
|
||||
class CLogCmp;
|
||||
class iterator;
|
||||
class CLogEvent;
|
||||
|
||||
friend class CLogEvent;
|
||||
friend class CLogCmp;
|
||||
friend class iterator;
|
||||
|
||||
class CLogCmp
|
||||
{
|
||||
friend class LogEventsMngr;
|
||||
class CLogCmp;
|
||||
class iterator;
|
||||
class CLogEvent;
|
||||
friend class CLogEvent;
|
||||
LogEventsMngr* parent;
|
||||
String text;
|
||||
int logid;
|
||||
int pos;
|
||||
int result;
|
||||
bool in;
|
||||
CLogCmp *next;
|
||||
CLogCmp( const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg ) : text(s) {
|
||||
logid = result = 0;
|
||||
pos = p;
|
||||
parent = mg;
|
||||
in = r;
|
||||
next = n;
|
||||
}
|
||||
public:
|
||||
|
||||
int compareCondition(const char* string);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CLogCmp *logcmplist;
|
||||
|
||||
public:
|
||||
|
||||
class CLogEvent {
|
||||
friend class LogEventsMngr;
|
||||
friend class CLogCmp;
|
||||
friend class iterator;
|
||||
struct LogCondEle {
|
||||
CLogCmp *cmp;
|
||||
LogCondEle *next;
|
||||
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c) , next(n) { }
|
||||
};
|
||||
struct LogCond {
|
||||
LogCondEle *list;
|
||||
int argnum;
|
||||
LogCond *next;
|
||||
LogCond( int a , LogCondEle* ee , LogCond* n ) : argnum(a) , list(ee), next(n) {}
|
||||
~LogCond();
|
||||
};
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
int func;
|
||||
LogEventsMngr* parent;
|
||||
LogCond *filters;
|
||||
CLogEvent *next;
|
||||
CLogEvent(CPluginMngr::CPlugin *p,int f, LogEventsMngr* ppp) : plugin(p),func(f), filters(0),parent(ppp) ,next(0) { }
|
||||
~CLogEvent();
|
||||
public:
|
||||
|
||||
void registerFilter( char* filter );
|
||||
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
|
||||
inline int getFunction() { return func; }
|
||||
};
|
||||
class CLogCmp
|
||||
{
|
||||
friend class LogEventsMngr;
|
||||
friend class CLogEvent;
|
||||
|
||||
LogEventsMngr* parent;
|
||||
String text;
|
||||
|
||||
int logid;
|
||||
int pos;
|
||||
int result;
|
||||
bool in;
|
||||
|
||||
CLogCmp *next;
|
||||
|
||||
CLogCmp(const char* s, bool r, int p, CLogCmp *n, LogEventsMngr* mg) : text(s)
|
||||
{
|
||||
logid = result = 0;
|
||||
pos = p;
|
||||
parent = mg;
|
||||
in = r;
|
||||
next = n;
|
||||
}
|
||||
|
||||
public:
|
||||
int compareCondition(const char* string);
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
CLogEvent *logevents[MAX_LOGARGS+1];
|
||||
CLogEvent *getValidLogEvent( CLogEvent * a );
|
||||
CLogCmp* registerCondition(char* filter);
|
||||
void clearConditions();
|
||||
|
||||
CLogCmp *logcmplist;
|
||||
public:
|
||||
|
||||
LogEventsMngr();
|
||||
~LogEventsMngr();
|
||||
class CLogEvent
|
||||
{
|
||||
friend class LogEventsMngr;
|
||||
friend class iterator;
|
||||
|
||||
struct LogCondEle
|
||||
{
|
||||
CLogCmp *cmp;
|
||||
LogCondEle *next;
|
||||
LogCondEle(CLogCmp *c, LogCondEle *n): cmp(c), next(n) {}
|
||||
};
|
||||
|
||||
struct LogCond
|
||||
{
|
||||
int argnum;
|
||||
|
||||
LogCondEle *list;
|
||||
LogCond *next;
|
||||
LogCond(int a, LogCondEle* ee, LogCond* n) : argnum(a), list(ee), next(n) {}
|
||||
~LogCond();
|
||||
};
|
||||
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
|
||||
int func;
|
||||
|
||||
LogCond *filters;
|
||||
LogEventsMngr* parent;
|
||||
|
||||
CLogEvent *next;
|
||||
CLogEvent(CPluginMngr::CPlugin *p, int f, LogEventsMngr* ppp) : plugin(p), func(f), filters(0), parent(ppp), next(0) {}
|
||||
~CLogEvent();
|
||||
public:
|
||||
inline CPluginMngr::CPlugin *getPlugin() { return plugin; }
|
||||
void registerFilter(char* filter);
|
||||
inline int getFunction() { return func; }
|
||||
};
|
||||
|
||||
private:
|
||||
CLogEvent *logevents[MAX_LOGARGS + 1];
|
||||
CLogEvent *getValidLogEvent(CLogEvent * a);
|
||||
CLogCmp* registerCondition(char* filter);
|
||||
|
||||
void clearConditions();
|
||||
public:
|
||||
LogEventsMngr();
|
||||
~LogEventsMngr();
|
||||
|
||||
// Interface
|
||||
CLogEvent* registerLogEvent(CPluginMngr::CPlugin* plugin, int func, int pos);
|
||||
inline bool logEventsExist() { return arelogevents; }
|
||||
|
||||
void setLogString(char* frmt, va_list& vaptr);
|
||||
void setLogString(char* frmt, ...);
|
||||
void parseLogString();
|
||||
void executeLogEvents();
|
||||
|
||||
CLogEvent* registerLogEvent( CPluginMngr::CPlugin* plugin, int func, int pos );
|
||||
inline bool logEventsExist() { return arelogevents; }
|
||||
void setLogString( char* frmt, va_list& vaptr );
|
||||
void setLogString( char* frmt , ... );
|
||||
void parseLogString( );
|
||||
void executeLogEvents();
|
||||
inline const char* getLogString() { return logString; }
|
||||
inline int getLogArgNum() { return logArgc; }
|
||||
inline const char* getLogArg( int i ) { return ( i < 0 || i >= logArgc ) ? "" : logArgs[ i ]; }
|
||||
void clearLogEvents();
|
||||
inline const char* getLogString() { return logString; }
|
||||
inline int getLogArgNum() { return logArgc; }
|
||||
inline const char* getLogArg(int i) { return (i < 0 || i >= logArgc) ? "" : logArgs[i]; }
|
||||
void clearLogEvents();
|
||||
|
||||
class iterator
|
||||
{
|
||||
CLogEvent* a;
|
||||
LogEventsMngr* b;
|
||||
|
||||
class iterator {
|
||||
LogEventsMngr* b;
|
||||
CLogEvent* a;
|
||||
public:
|
||||
inline iterator(CLogEvent*aa,LogEventsMngr* bb) : a(aa), b(bb) {}
|
||||
inline iterator& operator++() {
|
||||
a = b->getValidLogEvent( a->next );
|
||||
return *this;
|
||||
}
|
||||
inline bool operator==(const iterator& c) const { return a == c.a; }
|
||||
inline bool operator!=(const iterator& c) const { return !operator==(c); }
|
||||
CLogEvent& operator*() { return *a; }
|
||||
operator bool ( ) const { return a ? true : false; }
|
||||
};
|
||||
inline iterator begin() { return iterator(getValidLogEvent(logevents[ logArgc ]),this); }
|
||||
inline iterator end() { return iterator(0,this); }
|
||||
public:
|
||||
inline iterator(CLogEvent*aa, LogEventsMngr* bb) : a(aa), b(bb) {}
|
||||
|
||||
inline iterator& operator++()
|
||||
{
|
||||
a = b->getValidLogEvent(a->next);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool operator==(const iterator& c) const { return a == c.a; }
|
||||
inline bool operator!=(const iterator& c) const { return !operator == (c); }
|
||||
CLogEvent& operator*() { return *a; }
|
||||
operator bool () const { return a ? true : false; }
|
||||
};
|
||||
|
||||
inline iterator begin() { return iterator(getValidLogEvent(logevents[logArgc]), this); }
|
||||
inline iterator end() { return iterator(0, this); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //LOGEVENTS_H
|
||||
|
@ -29,15 +29,14 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CMenu.h"
|
||||
|
||||
// *****************************************************
|
||||
// class MenuMngr
|
||||
// *****************************************************
|
||||
MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f ) {
|
||||
MenuMngr::MenuCommand::MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f)
|
||||
{
|
||||
plugin = a;
|
||||
keys = k;
|
||||
menuid = mi;
|
||||
@ -48,47 +47,97 @@ MenuMngr::MenuCommand::MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int
|
||||
MenuMngr::~MenuMngr()
|
||||
{
|
||||
clear();
|
||||
MenuMngr::MenuIdEle::uniqueid = 0;
|
||||
}
|
||||
|
||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||
{
|
||||
for( MenuIdEle* b = headid; b ; b = b->next) {
|
||||
if ( (!b->amx || amx == b->amx) && strstr(name,b->name.str()) )
|
||||
return b->id;
|
||||
}
|
||||
return 0;
|
||||
for (MenuIdEle* b = headid; b; b = b->next)
|
||||
{
|
||||
if ((!amx || !b->amx || amx == b->amx) && strstr(name,b->name.c_str()))
|
||||
return b->id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MenuMngr::registerMenuId(const char* n, AMX* a )
|
||||
void MenuMngr::removeMenuId(int id)
|
||||
{
|
||||
int id = findMenuId( n, a );
|
||||
if (id) return id;
|
||||
headid = new MenuIdEle( n, a , headid );
|
||||
return headid->id;
|
||||
MenuIdEle *n = headid;
|
||||
MenuIdEle *l = NULL;
|
||||
while (n)
|
||||
{
|
||||
if (n->id == id)
|
||||
{
|
||||
if (l)
|
||||
l->next = n->next;
|
||||
else
|
||||
headid = n->next;
|
||||
delete n;
|
||||
break;
|
||||
}
|
||||
l = n;
|
||||
n = n->next;
|
||||
}
|
||||
|
||||
MenuCommand *c = headcmd;
|
||||
MenuCommand *lc = NULL;
|
||||
MenuCommand *tmp;
|
||||
while (c)
|
||||
{
|
||||
if (c->menuid == id)
|
||||
{
|
||||
if (lc)
|
||||
lc->next = c->next;
|
||||
else
|
||||
headcmd = c->next;
|
||||
tmp = c->next;
|
||||
delete c;
|
||||
c = tmp;
|
||||
} else {
|
||||
lc = c;
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MenuMngr::registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f )
|
||||
int MenuMngr::registerMenuId(const char* n, AMX* a)
|
||||
{
|
||||
int id = findMenuId(n, a);
|
||||
|
||||
if (id)
|
||||
return id;
|
||||
|
||||
headid = new MenuIdEle(n, a, headid);
|
||||
|
||||
if (!headid)
|
||||
return 0; // :TODO: Better error report
|
||||
|
||||
return headid->id;
|
||||
}
|
||||
|
||||
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f)
|
||||
{
|
||||
MenuCommand** temp = &headcmd;
|
||||
while(*temp) temp = &(*temp)->next;
|
||||
*temp = new MenuCommand(a,mi, k,f);
|
||||
while (*temp) temp = &(*temp)->next;
|
||||
*temp = new MenuCommand(a, mi, k, f);
|
||||
}
|
||||
|
||||
void MenuMngr::clear()
|
||||
{
|
||||
while (headid)
|
||||
{
|
||||
MenuIdEle* a = headid->next;
|
||||
delete headid;
|
||||
headid = a;
|
||||
}
|
||||
while (headid)
|
||||
{
|
||||
MenuIdEle* a = headid->next;
|
||||
delete headid;
|
||||
headid = a;
|
||||
}
|
||||
|
||||
while (headcmd)
|
||||
{
|
||||
MenuCommand* a = headcmd->next;
|
||||
delete headcmd;
|
||||
headcmd = a;
|
||||
}
|
||||
while (headcmd)
|
||||
{
|
||||
MenuCommand* a = headcmd->next;
|
||||
delete headcmd;
|
||||
headcmd = a;
|
||||
}
|
||||
}
|
||||
|
||||
int MenuMngr::MenuIdEle::uniqueid = 0;
|
@ -38,55 +38,57 @@
|
||||
|
||||
class MenuMngr
|
||||
{
|
||||
struct MenuIdEle
|
||||
{
|
||||
String name;
|
||||
AMX* amx;
|
||||
MenuIdEle* next;
|
||||
int id;
|
||||
static int uniqueid;
|
||||
MenuIdEle( const char* n, AMX* a, MenuIdEle* m ) : name( n ) , amx(a) , next( m ) {
|
||||
id = ++uniqueid;
|
||||
}
|
||||
~MenuIdEle() { --uniqueid; }
|
||||
} *headid;
|
||||
struct MenuIdEle
|
||||
{
|
||||
String name;
|
||||
AMX* amx;
|
||||
MenuIdEle* next;
|
||||
|
||||
int id;
|
||||
static int uniqueid;
|
||||
|
||||
MenuIdEle(const char* n, AMX* a, MenuIdEle* m) : name(n), amx(a), next(m)
|
||||
{
|
||||
id = ++uniqueid;
|
||||
}
|
||||
} *headid;
|
||||
|
||||
public:
|
||||
class iterator;
|
||||
|
||||
class iterator;
|
||||
private:
|
||||
|
||||
class MenuCommand
|
||||
{
|
||||
friend class iterator;
|
||||
friend class MenuMngr;
|
||||
class MenuCommand
|
||||
{
|
||||
friend class iterator;
|
||||
friend class MenuMngr;
|
||||
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
int menuid;
|
||||
int keys;
|
||||
int function;
|
||||
MenuCommand* next;
|
||||
MenuCommand( CPluginMngr::CPlugin *a, int mi, int k, int f );
|
||||
public:
|
||||
inline int getFunction() { return function; }
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline bool matchCommand( int m, int k ) { return ((m == menuid) && (keys & k)); }
|
||||
} *headcmd;
|
||||
CPluginMngr::CPlugin *plugin;
|
||||
int menuid;
|
||||
int keys;
|
||||
int function;
|
||||
|
||||
MenuCommand* next;
|
||||
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||
public:
|
||||
inline int getFunction() { return function; }
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
|
||||
} *headcmd;
|
||||
|
||||
public:
|
||||
|
||||
MenuMngr() { headid = 0; headcmd = 0; }
|
||||
MenuMngr() { headid = 0; headcmd = 0; }
|
||||
~MenuMngr();
|
||||
|
||||
// Interface
|
||||
|
||||
|
||||
int findMenuId(const char* name, AMX* a = 0);
|
||||
int registerMenuId(const char* n, AMX* a );
|
||||
void registerMenuCmd( CPluginMngr::CPlugin *a,int mi, int k , int f );
|
||||
int registerMenuId(const char* n, AMX* a);
|
||||
void removeMenuId(int id);
|
||||
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
class iterator
|
||||
{
|
||||
MenuCommand* a;
|
||||
public:
|
||||
iterator(MenuCommand*aa) : a(aa) {}
|
||||
@ -96,12 +98,9 @@ public:
|
||||
operator bool () const { return a ? true : false; }
|
||||
MenuCommand& operator*() { return *a; }
|
||||
};
|
||||
|
||||
inline iterator begin() const { return iterator(headcmd); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //MENUS_H
|
||||
|
@ -28,15 +28,13 @@
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "newmenus.h"
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
void CPlayer::Init( edict_t* e , int i )
|
||||
|
||||
void CPlayer::Init(edict_t* e, int i)
|
||||
{
|
||||
index = i;
|
||||
pEdict = e;
|
||||
@ -51,6 +49,8 @@ void CPlayer::Init( edict_t* e , int i )
|
||||
aiming = 0;
|
||||
menu = 0;
|
||||
keys = 0;
|
||||
menuexpire = 0.0;
|
||||
newmenu = -1;
|
||||
|
||||
death_weapon.clear();
|
||||
name.clear();
|
||||
@ -58,175 +58,268 @@ void CPlayer::Init( edict_t* e , int i )
|
||||
team.clear();
|
||||
}
|
||||
|
||||
void CPlayer::Disconnect() {
|
||||
ingame = false;
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
}
|
||||
void CPlayer::PutInServer() {
|
||||
playtime = gpGlobals->time;
|
||||
ingame = true;
|
||||
}
|
||||
bool CPlayer::Connect(const char* connectname,const char* ipaddress) {
|
||||
name.set(connectname);
|
||||
ip.set(ipaddress);
|
||||
time = gpGlobals->time;
|
||||
bot = IsBot();
|
||||
death_killer = 0;
|
||||
memset(flags,0,sizeof(flags));
|
||||
memset(weapons,0,sizeof(weapons));
|
||||
initialized = true;
|
||||
authorized = false;
|
||||
void CPlayer::Disconnect()
|
||||
{
|
||||
ingame = false;
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
|
||||
const char* authid = GETPLAYERAUTHID( pEdict );
|
||||
if (newmenu != -1)
|
||||
{
|
||||
Menu *pMenu = g_NewMenus[newmenu];
|
||||
if (pMenu)
|
||||
{
|
||||
//prevent recursion
|
||||
newmenu = -1;
|
||||
menu = 0;
|
||||
executeForwards(pMenu->func,
|
||||
static_cast<cell>(ENTINDEX(pEdict)),
|
||||
static_cast<cell>(pMenu->thisId),
|
||||
static_cast<cell>(MENU_EXIT));
|
||||
}
|
||||
}
|
||||
|
||||
if ( (authid == 0) || (*authid == 0)
|
||||
|| (strcmp( authid , "STEAM_ID_PENDING") == 0) )
|
||||
return true;
|
||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
||||
for (iter=queries.begin(); iter!=end; iter++)
|
||||
{
|
||||
unregisterSPForward((*iter)->resultFwd);
|
||||
delete [] (*iter)->params;
|
||||
delete (*iter);
|
||||
}
|
||||
queries.clear();
|
||||
|
||||
return false;
|
||||
bot = 0;
|
||||
menu = 0;
|
||||
newmenu = -1;
|
||||
}
|
||||
|
||||
void CPlayer::PutInServer()
|
||||
{
|
||||
playtime = gpGlobals->time;
|
||||
ingame = true;
|
||||
}
|
||||
|
||||
int CPlayer::NextHUDChannel()
|
||||
{
|
||||
int ilow = 1;
|
||||
|
||||
for (int i=ilow+1; i<=4; i++)
|
||||
{
|
||||
if (channels[i] < channels[ilow])
|
||||
ilow = i;
|
||||
}
|
||||
|
||||
return ilow;
|
||||
}
|
||||
|
||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
||||
{
|
||||
name.assign(connectname);
|
||||
ip.assign(ipaddress);
|
||||
time = gpGlobals->time;
|
||||
bot = IsBot();
|
||||
death_killer = 0;
|
||||
menu = 0;
|
||||
newmenu = -1;
|
||||
|
||||
memset(flags, 0, sizeof(flags));
|
||||
memset(weapons, 0, sizeof(weapons));
|
||||
|
||||
initialized = true;
|
||||
authorized = false;
|
||||
|
||||
for (int i=0; i<=4; i++)
|
||||
{
|
||||
channels[i] = 0.0f;
|
||||
hudmap[i] = 0;
|
||||
}
|
||||
|
||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
||||
for (iter=queries.begin(); iter!=end; iter++)
|
||||
{
|
||||
unregisterSPForward((*iter)->resultFwd);
|
||||
delete [] (*iter)->params;
|
||||
delete (*iter);
|
||||
}
|
||||
queries.clear();
|
||||
|
||||
const char* authid = GETPLAYERAUTHID(pEdict);
|
||||
|
||||
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class Grenades
|
||||
// *****************************************************
|
||||
void Grenades::put( edict_t* grenade, float time, int type, CPlayer* player )
|
||||
|
||||
void Grenades::put(edict_t* grenade, float time, int type, CPlayer* player)
|
||||
{
|
||||
Obj* a = new Obj;
|
||||
if ( a == 0 ) return;
|
||||
a->player = player;
|
||||
a->grenade = grenade;
|
||||
a->time = gpGlobals->time + time;
|
||||
a->type = type;
|
||||
a->next = head;
|
||||
head = a;
|
||||
Obj* a = new Obj;
|
||||
if (a == 0) return;
|
||||
a->player = player;
|
||||
a->grenade = grenade;
|
||||
a->time = gpGlobals->time + time;
|
||||
a->type = type;
|
||||
a->next = head;
|
||||
head = a;
|
||||
}
|
||||
|
||||
bool Grenades::find( edict_t* enemy, CPlayer** p, int& type )
|
||||
bool Grenades::find(edict_t* enemy, CPlayer** p, int& type)
|
||||
{
|
||||
bool found = false;
|
||||
Obj** a = &head;
|
||||
while ( *a ){
|
||||
if ( (*a)->time > gpGlobals->time ) {
|
||||
if ( (*a)->grenade == enemy ) {
|
||||
found = true;
|
||||
(*p) = (*a)->player;
|
||||
type = (*a)->type;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Obj* b = (*a)->next;
|
||||
delete *a;
|
||||
*a = b;
|
||||
continue;
|
||||
bool found = false;
|
||||
Obj** a = &head;
|
||||
|
||||
}
|
||||
a = &(*a)->next;
|
||||
}
|
||||
return found;
|
||||
while (*a)
|
||||
{
|
||||
if ((*a)->time > gpGlobals->time)
|
||||
{
|
||||
if ((*a)->grenade == enemy)
|
||||
{
|
||||
found = true;
|
||||
(*p) = (*a)->player;
|
||||
type = (*a)->type;
|
||||
}
|
||||
} else {
|
||||
Obj* b = (*a)->next;
|
||||
delete *a;
|
||||
*a = b;
|
||||
continue;
|
||||
}
|
||||
a = &(*a)->next;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
void Grenades::clear()
|
||||
{
|
||||
while(head){
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
while (head)
|
||||
{
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class XVars
|
||||
// *****************************************************
|
||||
void XVars::clear() {
|
||||
|
||||
void XVars::clear()
|
||||
{
|
||||
delete[] head;
|
||||
head = 0;
|
||||
num = 0;
|
||||
size = 0;
|
||||
}
|
||||
|
||||
int XVars::put( AMX* p, cell* v )
|
||||
int XVars::put(AMX* p, cell* v)
|
||||
{
|
||||
for(int a = 0; a < num; ++a) {
|
||||
if ( (head[a].amx == p) && (head[a].value == v) )
|
||||
return a;
|
||||
}
|
||||
for (int a = 0; a < num; ++a)
|
||||
{
|
||||
if ((head[a].amx == p) && (head[a].value == v))
|
||||
return a;
|
||||
}
|
||||
|
||||
if ( (num >= size) && realloc_array( size ? (size * 2) : 8 ) )
|
||||
return -1;
|
||||
if ((num >= size) && realloc_array(size ? (size * 2) : 8))
|
||||
return -1;
|
||||
|
||||
head[num].value = v;
|
||||
head[num].amx = p;
|
||||
return num++;
|
||||
head[num].value = v;
|
||||
head[num].amx = p;
|
||||
|
||||
return num++;
|
||||
}
|
||||
|
||||
int XVars::realloc_array( int nsize )
|
||||
int XVars::realloc_array(int nsize)
|
||||
{
|
||||
XVarEle* me = new XVarEle[nsize];
|
||||
if ( me ){
|
||||
for(int a = 0 ; a < num; ++a)
|
||||
|
||||
if (me)
|
||||
{
|
||||
for (int a = 0 ; a < num; ++a)
|
||||
me[a] = head[a];
|
||||
|
||||
delete[] head;
|
||||
head = me;
|
||||
size = nsize;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// *****************************************************
|
||||
// class TeamIds
|
||||
// *****************************************************
|
||||
|
||||
TeamIds::TeamIds() { head = 0; newTeam = 0; }
|
||||
TeamIds::~TeamIds() {
|
||||
while( head ) {
|
||||
|
||||
TeamIds::~TeamIds()
|
||||
{
|
||||
while (head)
|
||||
{
|
||||
TeamEle* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TeamIds::registerTeam( const char* n ,int s )
|
||||
void TeamIds::registerTeam(const char* n, int s)
|
||||
{
|
||||
TeamEle** a = &head;
|
||||
while( *a ){
|
||||
if ( strcmp((*a)->name.str(),n) == 0 ){
|
||||
if (s != -1){
|
||||
TeamEle** a = &head;
|
||||
|
||||
while (*a)
|
||||
{
|
||||
if (strcmp((*a)->name.c_str(),n) == 0)
|
||||
{
|
||||
if (s != -1)
|
||||
{
|
||||
(*a)->id = s;
|
||||
newTeam &= ~(1<<(*a)->tid);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
a = &(*a)->next;
|
||||
}
|
||||
*a = new TeamEle( n , s );
|
||||
if ( *a == 0 ) return;
|
||||
newTeam |= (1<<(*a)->tid);
|
||||
}
|
||||
|
||||
*a = new TeamEle(n, s);
|
||||
|
||||
if (*a == 0)
|
||||
return;
|
||||
|
||||
newTeam |= (1<<(*a)->tid);
|
||||
}
|
||||
|
||||
int TeamIds::findTeamId( const char* n )
|
||||
int TeamIds::findTeamId(const char* n)
|
||||
{
|
||||
TeamEle* a = head;
|
||||
while( a ){
|
||||
if ( !strcmpi(a->name.str(),n) )
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (!stricmp(a->name.c_str(), n))
|
||||
return a->id;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TeamIds::findTeamIdCase( const char* n)
|
||||
int TeamIds::findTeamIdCase(const char* n)
|
||||
{
|
||||
TeamEle* a = head;
|
||||
while( a ){
|
||||
if ( !strcmp(a->name.str(), n) )
|
||||
|
||||
while (a)
|
||||
{
|
||||
if (!strcmp(a->name.c_str(), n))
|
||||
return a->id;
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
char TeamIds::TeamEle::uid = 0;
|
||||
|
||||
|
225
amxmodx/CMisc.h
225
amxmodx/CMisc.h
@ -33,39 +33,47 @@
|
||||
#define CMISC_H
|
||||
|
||||
#include "CList.h"
|
||||
#include "string.h"
|
||||
#include "sh_list.h"
|
||||
|
||||
// *****************************************************
|
||||
// class CCVar
|
||||
// *****************************************************
|
||||
|
||||
class CCVar
|
||||
{
|
||||
cvar_t cvar;
|
||||
String name;
|
||||
String plugin;
|
||||
cvar_t cvar;
|
||||
String name;
|
||||
String plugin;
|
||||
|
||||
public:
|
||||
CCVar( const char* pname, const char* pplugin,
|
||||
int pflags, float pvalue ) : name(pname) , plugin(pplugin ) {
|
||||
cvar.name = (char*)name.str();
|
||||
CCVar(const char* pname, const char* pplugin, int pflags, float pvalue) : name(pname), plugin(pplugin)
|
||||
{
|
||||
cvar.name = (char*)name.c_str();
|
||||
cvar.flags = pflags;
|
||||
cvar.string = "";
|
||||
cvar.value = pvalue;
|
||||
}
|
||||
}
|
||||
|
||||
inline cvar_t* getCvar() { return &cvar; }
|
||||
inline const char* getPluginName() { return plugin.str(); }
|
||||
inline const char* getName() { return name.str(); }
|
||||
inline bool operator == ( const char* string ) const { return (strcmp(name.str(),string)==0); }
|
||||
inline const char* getPluginName() { return plugin.c_str(); }
|
||||
inline const char* getName() { return name.c_str(); }
|
||||
inline bool operator == (const char* string) { return (strcmp(name.c_str(), string) == 0); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
|
||||
struct ClientCvarQuery_Info
|
||||
{
|
||||
int resultFwd;
|
||||
int requestId;
|
||||
int paramLen;
|
||||
cell *params;
|
||||
};
|
||||
|
||||
class CPlayer
|
||||
{
|
||||
|
||||
public:
|
||||
edict_t* pEdict;
|
||||
|
||||
@ -77,11 +85,14 @@ public:
|
||||
bool ingame;
|
||||
bool bot;
|
||||
bool authorized;
|
||||
bool vgui;
|
||||
|
||||
float time;
|
||||
float playtime;
|
||||
float menuexpire;
|
||||
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
int ammo;
|
||||
int clip;
|
||||
} weapons[MAX_WEAPONS];
|
||||
@ -100,27 +111,38 @@ public:
|
||||
int death_victim;
|
||||
bool death_tk;
|
||||
String death_weapon;
|
||||
int newmenu;
|
||||
int page;
|
||||
|
||||
float channels[5];
|
||||
cell hudmap[5];
|
||||
|
||||
Vector lastTrace;
|
||||
Vector thisTrace;
|
||||
Vector lastHit;
|
||||
|
||||
void Init( edict_t* e , int i );
|
||||
List<ClientCvarQuery_Info *> queries;
|
||||
|
||||
void Init(edict_t* e, int i);
|
||||
void Disconnect();
|
||||
void PutInServer();
|
||||
bool Connect(const char* connectname,const char* ipaddress);
|
||||
|
||||
inline bool IsBot(){
|
||||
const char* auth= (*g_engfuncs.pfnGetPlayerAuthId)(pEdict);
|
||||
return ( auth && !strcmp( auth , "BOT" ) );
|
||||
bool Connect(const char* connectname, const char* ipaddress);
|
||||
|
||||
inline bool IsBot()
|
||||
{
|
||||
return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
|
||||
}
|
||||
|
||||
inline bool IsAlive(){
|
||||
return ((pEdict->v.deadflag==DEAD_NO)&&(pEdict->v.health>0));
|
||||
inline bool IsAlive()
|
||||
{
|
||||
return ((pEdict->v.deadflag == DEAD_NO) && (pEdict->v.health > 0));
|
||||
}
|
||||
|
||||
inline void Authorize() { authorized = true; }
|
||||
|
||||
int NextHUDChannel();
|
||||
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
@ -129,40 +151,44 @@ public:
|
||||
|
||||
class Grenades
|
||||
{
|
||||
struct Obj
|
||||
{
|
||||
CPlayer* player;
|
||||
edict_t* grenade;
|
||||
float time;
|
||||
int type;
|
||||
Obj* next;
|
||||
} *head;
|
||||
|
||||
struct Obj
|
||||
{
|
||||
CPlayer* player;
|
||||
edict_t* grenade;
|
||||
float time;
|
||||
int type;
|
||||
Obj* next;
|
||||
} *head;
|
||||
|
||||
public:
|
||||
Grenades() { head = 0; }
|
||||
~Grenades() { clear(); }
|
||||
void put( edict_t* grenade, float time, int type, CPlayer* player );
|
||||
bool find( edict_t* enemy, CPlayer** p, int& type );
|
||||
void clear();
|
||||
Grenades() { head = 0; }
|
||||
~Grenades() { clear(); }
|
||||
|
||||
void put(edict_t* grenade, float time, int type, CPlayer* player);
|
||||
bool find(edict_t* enemy, CPlayer** p, int& type);
|
||||
void clear();
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class ForceObject
|
||||
// *****************************************************
|
||||
class ForceObject {
|
||||
AMX* amx;
|
||||
String filename;
|
||||
FORCE_TYPE type;
|
||||
Vector mins;
|
||||
Vector maxs;
|
||||
|
||||
class ForceObject
|
||||
{
|
||||
String filename;
|
||||
FORCE_TYPE type;
|
||||
Vector mins;
|
||||
Vector maxs;
|
||||
AMX* amx;
|
||||
public:
|
||||
ForceObject(const char* n, FORCE_TYPE c,Vector& mi, Vector& ma, AMX* a) :
|
||||
filename(n) , type(c), mins(mi), maxs(ma), amx(a) {}
|
||||
inline const char* getFilename() { return filename.str(); }
|
||||
ForceObject(const char* n, FORCE_TYPE c, Vector& mi, Vector& ma, AMX* a) : filename(n), type(c), mins(mi), maxs(ma), amx(a) {}
|
||||
|
||||
inline const char* getFilename() { return filename.c_str(); }
|
||||
inline AMX* getAMX() { return amx; }
|
||||
|
||||
Vector& getMin() { return mins; }
|
||||
Vector& getMax() { return maxs; }
|
||||
|
||||
inline FORCE_TYPE getForceType() { return type; }
|
||||
};
|
||||
|
||||
@ -172,81 +198,92 @@ public:
|
||||
|
||||
class XVars
|
||||
{
|
||||
struct XVarEle {
|
||||
AMX* amx;
|
||||
cell* value;
|
||||
};
|
||||
struct XVarEle
|
||||
{
|
||||
AMX* amx;
|
||||
cell* value;
|
||||
};
|
||||
|
||||
XVarEle* head;
|
||||
int size;
|
||||
int num;
|
||||
XVarEle* head;
|
||||
|
||||
int realloc_array( int nsize );
|
||||
int size;
|
||||
int num;
|
||||
int realloc_array(int nsize);
|
||||
|
||||
public:
|
||||
XVars() { num = 0; size = 0; head = 0; }
|
||||
~XVars() { clear(); }
|
||||
void clear();
|
||||
int put( AMX* a, cell* v );
|
||||
inline cell getValue( int a ) {
|
||||
return ( a >= 0 && a < num ) ? *(head[a].value) : 0;
|
||||
}
|
||||
inline int setValue( int a, cell v ) {
|
||||
if ( a >= 0 && a < num ){
|
||||
*(head[a].value) = v;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
XVars() { num = 0; size = 0; head = 0; }
|
||||
~XVars() { clear(); }
|
||||
|
||||
void clear();
|
||||
int put(AMX* a, cell* v);
|
||||
|
||||
inline cell getValue(int a)
|
||||
{
|
||||
return (a >= 0 && a < num) ? *(head[a].value) : 0;
|
||||
}
|
||||
|
||||
inline int setValue(int a, cell v)
|
||||
{
|
||||
if (a >= 0 && a < num)
|
||||
{
|
||||
*(head[a].value) = v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class CScript
|
||||
// *****************************************************
|
||||
|
||||
class CScript
|
||||
{
|
||||
String filename;
|
||||
AMX* amx;
|
||||
void* code;
|
||||
public:
|
||||
CScript(AMX* aa, void* cc,const char* ff):filename(ff),amx(aa),code(cc){}
|
||||
CScript(AMX* aa, void* cc, const char* ff) : filename(ff), amx(aa), code(cc) {}
|
||||
|
||||
inline AMX* getAMX() { return amx; }
|
||||
inline const char* getName() { return filename.str(); }
|
||||
inline bool operator==( void* a ) { return (amx == (AMX*)a); }
|
||||
inline const char* getName() { return filename.c_str(); }
|
||||
inline bool operator==(void* a) { return (amx == (AMX*)a); }
|
||||
inline void* getCode() { return code; }
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
// class TeamIds
|
||||
// *****************************************************
|
||||
|
||||
class TeamIds
|
||||
{
|
||||
struct TeamEle {
|
||||
String name;
|
||||
int id;
|
||||
char tid;
|
||||
static char uid;
|
||||
TeamEle* next;
|
||||
TeamEle(const char* n, int& i) : name(n) , id(i) , next(0) {
|
||||
tid = uid++;
|
||||
};
|
||||
~TeamEle(){ --uid; }
|
||||
} *head;
|
||||
struct TeamEle
|
||||
{
|
||||
String name;
|
||||
int id;
|
||||
char tid;
|
||||
static char uid;
|
||||
TeamEle* next;
|
||||
|
||||
int newTeam;
|
||||
TeamEle(const char* n, int& i) : name(n), id(i), next(0)
|
||||
{
|
||||
tid = uid++;
|
||||
}
|
||||
|
||||
~TeamEle() { --uid; }
|
||||
} *head;
|
||||
|
||||
int newTeam;
|
||||
|
||||
public:
|
||||
TeamIds();
|
||||
~TeamIds();
|
||||
void registerTeam( const char* n ,int s );
|
||||
int findTeamId( const char* n);
|
||||
int findTeamIdCase( const char* n);
|
||||
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||
TeamIds();
|
||||
~TeamIds();
|
||||
|
||||
void registerTeam(const char* n, int s);
|
||||
int findTeamId(const char* n);
|
||||
int findTeamIdCase(const char* n);
|
||||
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif //CMISC_H
|
||||
|
@ -29,164 +29,378 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "libraries.h"
|
||||
|
||||
#ifndef FAR // PM: Test: FAR
|
||||
#define FAR
|
||||
#ifndef FAR
|
||||
#define FAR
|
||||
#endif
|
||||
|
||||
typedef int (FAR *QUERYMOD)(module_info_s**);
|
||||
typedef int (FAR *ATTACHMOD)(pfnamx_engine_g*,pfnmodule_engine_g*);
|
||||
typedef int (FAR *DETACHMOD)(void);
|
||||
|
||||
QUERYMOD QueryModule;
|
||||
ATTACHMOD AttachModule;
|
||||
DETACHMOD DetachModule;
|
||||
|
||||
|
||||
|
||||
pfnamx_engine_g engAmxFunc = {
|
||||
amx_Align16,
|
||||
amx_Align32,
|
||||
amx_Allot,
|
||||
amx_Callback,
|
||||
amx_Clone,
|
||||
amx_Debug,
|
||||
amx_Exec,
|
||||
amx_Execv,
|
||||
amx_FindPublic,
|
||||
amx_FindPubVar,
|
||||
amx_FindTagId,
|
||||
amx_Flags,
|
||||
amx_GetAddr,
|
||||
amx_GetPublic,
|
||||
amx_GetPubVar,
|
||||
amx_GetString,
|
||||
amx_GetTag,
|
||||
amx_GetUserData,
|
||||
amx_Init,
|
||||
amx_InitJIT,
|
||||
amx_MemInfo,
|
||||
amx_NameLength,
|
||||
amx_NativeInfo,
|
||||
amx_NumPublics,
|
||||
amx_NumPubVars,
|
||||
amx_NumTags,
|
||||
amx_RaiseError,
|
||||
amx_Register,
|
||||
amx_Release,
|
||||
amx_SetCallback,
|
||||
amx_SetDebugHook,
|
||||
amx_SetString,
|
||||
amx_SetUserData,
|
||||
amx_StrLen,
|
||||
};
|
||||
|
||||
pfnmodule_engine_g engModuleFunc = {
|
||||
add_amxnatives,
|
||||
build_pathname,
|
||||
copy_amxmemory,
|
||||
format_amxstring,
|
||||
get_amxaddr,
|
||||
get_amxscript,
|
||||
get_amxscriptname,
|
||||
get_amxstring,
|
||||
get_modname,
|
||||
load_amxscript,
|
||||
print_srvconsole,
|
||||
report_error,
|
||||
set_amxnatives,
|
||||
set_amxstring,
|
||||
amxstring_len,
|
||||
unload_amxscript,
|
||||
alloc_amxmemory,
|
||||
free_amxmemory,
|
||||
};
|
||||
// New
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||
typedef int (FAR *ATTACHMOD_NEW)(PFN_REQ_FNPTR /*reqFnptrFunc*/);
|
||||
typedef int (FAR *DETACHMOD_NEW)(void);
|
||||
typedef void (FAR *PLUGINSLOADED_NEW)(void);
|
||||
typedef void (*PLUGINSUNLOADED_NEW)(void);
|
||||
typedef void (*PLUGINSUNLOADING_NEW)(void);
|
||||
|
||||
// *****************************************************
|
||||
// class CModule
|
||||
// *****************************************************
|
||||
|
||||
CModule::CModule(const char* fname) : filename(fname)
|
||||
CModule::CModule(const char* fname)
|
||||
{
|
||||
metamod = false;
|
||||
info = 0;
|
||||
module = 0;
|
||||
status = MODULE_NONE;
|
||||
m_Filename.assign(fname);
|
||||
clear(false);
|
||||
}
|
||||
|
||||
CModule::~CModule()
|
||||
{
|
||||
if ( module ) DLFREE(module);
|
||||
natives.clear();
|
||||
// old & new
|
||||
if (m_Handle)
|
||||
DLFREE(m_Handle);
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void CModule::clear(bool clearFilename)
|
||||
{
|
||||
// old & new
|
||||
m_Metamod = false;
|
||||
m_Handle = NULL;
|
||||
m_Status = MODULE_NONE;
|
||||
|
||||
if (clearFilename)
|
||||
m_Filename.assign("unknown");
|
||||
|
||||
// new
|
||||
m_Amxx = false;
|
||||
m_InfoNew.author = "unknown";
|
||||
m_InfoNew.name = "unknown";
|
||||
m_InfoNew.version = "unknown";
|
||||
m_InfoNew.reload = 0;
|
||||
m_MissingFunc = NULL;
|
||||
|
||||
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
|
||||
{
|
||||
delete [] m_Natives[m_DestroyableIndexes[i]];
|
||||
}
|
||||
|
||||
m_DestroyableIndexes.clear();
|
||||
m_Natives.clear();
|
||||
}
|
||||
|
||||
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||
{
|
||||
void **handle;
|
||||
void *dummy = NULL;
|
||||
|
||||
if (!m_Handle)
|
||||
handle = &dummy;
|
||||
else
|
||||
handle = (void **)&m_Handle;
|
||||
|
||||
int res = LoadMetamodPlugin(mmfile, handle, now);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
m_Metamod = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//this ugly function is ultimately something like O(n^4).
|
||||
//sigh. it shouldn't be needed.
|
||||
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
|
||||
{
|
||||
AMX_NATIVE_INFO *curlist;
|
||||
for (size_t i=0; i<m_Natives.size(); i++)
|
||||
{
|
||||
curlist = m_Natives[i];
|
||||
bool changed = false;
|
||||
bool found = false;
|
||||
CVector<size_t> newlist;
|
||||
for (size_t j=0; curlist[j].func != NULL; j++)
|
||||
{
|
||||
found = false;
|
||||
for (size_t k=0; list[k].func != NULL; k++)
|
||||
{
|
||||
if (strcmp(curlist[j].name, list[k].name) == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
changed = true;
|
||||
//don't break, we have to search it all
|
||||
} else {
|
||||
newlist.push_back(j);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
//now build the new list
|
||||
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
|
||||
for (size_t j=0; j<newlist.size(); j++)
|
||||
{
|
||||
rlist[j].func = curlist[newlist[j]].func;
|
||||
rlist[j].name = curlist[newlist[j]].name;
|
||||
}
|
||||
rlist[newlist.size()].func = NULL;
|
||||
rlist[newlist.size()].name = NULL;
|
||||
m_Natives[i] = rlist;
|
||||
m_DestroyableIndexes.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CModule::attachModule()
|
||||
{
|
||||
if ( status != MODULE_QUERY )
|
||||
// old & new
|
||||
if (m_Status != MODULE_QUERY || !m_Handle)
|
||||
return false;
|
||||
AttachModule = (ATTACHMOD)DLPROC(module,"AMX_Attach");
|
||||
if ( AttachModule ) (*AttachModule)(&engAmxFunc,&engModuleFunc);
|
||||
status = MODULE_LOADED;
|
||||
return true;
|
||||
|
||||
if (m_Amxx)
|
||||
{
|
||||
// new
|
||||
ATTACHMOD_NEW AttachFunc_New = (ATTACHMOD_NEW)DLPROC(m_Handle, "AMXX_Attach");
|
||||
|
||||
if (!AttachFunc_New)
|
||||
return false;
|
||||
|
||||
g_ModuleCallReason = ModuleCall_Attach;
|
||||
g_CurrentlyCalledModule = this;
|
||||
int retVal = (*AttachFunc_New)(Module_ReqFnptr);
|
||||
g_CurrentlyCalledModule = NULL;
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
|
||||
switch (retVal)
|
||||
{
|
||||
case AMXX_OK:
|
||||
m_Status = MODULE_LOADED;
|
||||
break;
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_FUNC_NOT_PRESENT:
|
||||
m_Status = MODULE_FUNCNOTPRESENT;
|
||||
m_MissingFunc = g_LastRequestedFunc;
|
||||
return false;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
m_Status = MODULE_BADLOAD;
|
||||
}
|
||||
|
||||
if (m_Status == MODULE_LOADED)
|
||||
{
|
||||
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
|
||||
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CModule::queryModule()
|
||||
{
|
||||
if ( status != MODULE_NONE ) // don't check if already quried
|
||||
if (m_Status != MODULE_NONE) // don't check if already queried
|
||||
return false;
|
||||
module = DLLOAD( filename.str() ); // link dll
|
||||
if ( !module ){
|
||||
status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
int meta = (int)DLPROC(module,"Meta_Attach"); // check if also MM
|
||||
if ( meta ) metamod = true;
|
||||
|
||||
QueryModule = (QUERYMOD)DLPROC(module,"AMX_Query"); // check what version
|
||||
if (QueryModule == 0) {
|
||||
status = MODULE_NOQUERY;
|
||||
m_Handle = DLLOAD(m_Filename.c_str()); // load file
|
||||
if (!m_Handle)
|
||||
{
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
(*QueryModule)( &info );
|
||||
if ( info == 0 ){
|
||||
status = MODULE_NOINFO;
|
||||
|
||||
// Check whether the module uses metamod (for auto attach)
|
||||
if (DLPROC(m_Handle, "Meta_Attach"))
|
||||
m_Metamod = true;
|
||||
|
||||
// Try new interface first
|
||||
QUERYMOD_NEW queryFunc_New = (QUERYMOD_NEW)DLPROC(m_Handle, "AMXX_Query");
|
||||
|
||||
if (queryFunc_New)
|
||||
{
|
||||
m_Amxx = true;
|
||||
int ifVers = AMXX_INTERFACE_VERSION;
|
||||
g_ModuleCallReason = ModuleCall_Query;
|
||||
g_CurrentlyCalledModule = this;
|
||||
int retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||
g_CurrentlyCalledModule = NULL;
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
|
||||
switch (retVal)
|
||||
{
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
return false;
|
||||
case AMXX_IFVERS:
|
||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||
{
|
||||
//backwards compat for new defs
|
||||
if (ifVers == 3)
|
||||
{
|
||||
g_ModuleCallReason = ModuleCall_Query;
|
||||
g_CurrentlyCalledModule = this;
|
||||
retVal = (*queryFunc_New)(&ifVers, &m_InfoNew);
|
||||
g_CurrentlyCalledModule = NULL;
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
if (retVal == AMXX_OK)
|
||||
{
|
||||
m_InfoNew.library = m_InfoNew.logtag;
|
||||
if (StrCaseStr(m_InfoNew.library, "sql")
|
||||
|| StrCaseStr(m_InfoNew.library, "dbi"))
|
||||
{
|
||||
m_InfoNew.libclass = "DBI";
|
||||
} else {
|
||||
m_InfoNew.libclass = "";
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
m_Status = MODULE_OLD;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
m_Status = MODULE_NEWER;
|
||||
return false;
|
||||
}
|
||||
case AMXX_OK:
|
||||
break;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an invalid code.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for attach
|
||||
if (!DLPROC(m_Handle, "AMXX_Attach"))
|
||||
{
|
||||
m_Status = MODULE_NOATTACH;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Status = MODULE_QUERY;
|
||||
return true;
|
||||
} else {
|
||||
m_Status = MODULE_NOQUERY;
|
||||
m_Amxx = false;
|
||||
return false;
|
||||
}
|
||||
if ( info->ivers != AMX_INTERFACE_VERSION ) {
|
||||
status = MODULE_OLD;
|
||||
return false;
|
||||
}
|
||||
AttachModule = (ATTACHMOD)DLPROC(module,"AMX_Attach"); // check for attach
|
||||
if ( AttachModule == 0) {
|
||||
status = MODULE_NOATTACH;
|
||||
return false;
|
||||
}
|
||||
info->serial = (long int)this;
|
||||
status = MODULE_QUERY;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CModule::detachModule()
|
||||
{
|
||||
if ( status != MODULE_LOADED )
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return false;
|
||||
DetachModule = (DETACHMOD)DLPROC(module,"AMX_Detach");
|
||||
if (DetachModule) (*DetachModule)();
|
||||
DLFREE(module);
|
||||
module = 0;
|
||||
natives.clear();
|
||||
status = MODULE_NONE;
|
||||
|
||||
RemoveLibraries(this);
|
||||
|
||||
if (m_Amxx)
|
||||
{
|
||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||
|
||||
if (detachFunc_New)
|
||||
{
|
||||
g_ModuleCallReason = ModuleCall_Detach;
|
||||
g_CurrentlyCalledModule = this;
|
||||
(*detachFunc_New)();
|
||||
g_CurrentlyCalledModule = NULL;
|
||||
g_ModuleCallReason = ModuleCall_NotCalled;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef FAKEMETA
|
||||
if (IsMetamod())
|
||||
{
|
||||
UnloadMetamodPlugin(m_Handle);
|
||||
}
|
||||
#endif
|
||||
|
||||
DLFREE(m_Handle);
|
||||
clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
const char* CModule::getStatus() const {
|
||||
switch(status){
|
||||
case MODULE_NONE: return "error";
|
||||
case MODULE_QUERY: return "pending";
|
||||
case MODULE_BADLOAD:return "bad load";
|
||||
case MODULE_LOADED:return "running";
|
||||
case MODULE_NOINFO:return "no info";
|
||||
case MODULE_NOQUERY:return "no query";
|
||||
case MODULE_NOATTACH:return "no attach";
|
||||
case MODULE_OLD:return "old";
|
||||
|
||||
void CModule::CallPluginsUnloaded()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return;
|
||||
|
||||
if (!m_Handle)
|
||||
return;
|
||||
|
||||
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
void CModule::CallPluginsUnloading()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return;
|
||||
|
||||
if (!m_Handle)
|
||||
return;
|
||||
|
||||
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
void CModule::CallPluginsLoaded()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return;
|
||||
|
||||
if (!m_Handle)
|
||||
return;
|
||||
|
||||
PLUGINSLOADED_NEW func = (PLUGINSLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsLoaded");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
const char* CModule::getStatus() const
|
||||
{
|
||||
switch (m_Status)
|
||||
{
|
||||
case MODULE_NONE: return "error";
|
||||
case MODULE_QUERY: return "pending";
|
||||
case MODULE_BADLOAD: return "bad load";
|
||||
case MODULE_LOADED: return "running";
|
||||
case MODULE_NOINFO: return "no info";
|
||||
case MODULE_NOQUERY: return "no query";
|
||||
case MODULE_NOATTACH: return "no attach";
|
||||
case MODULE_OLD: return "old";
|
||||
case MODULE_FUNCNOTPRESENT:
|
||||
case MODULE_NEWER: return "newer";
|
||||
case MODULE_INTERROR: return "internal err";
|
||||
case MODULE_NOT64BIT: return "not 64bit";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
@ -36,49 +36,88 @@
|
||||
#ifndef CMODULE_H
|
||||
#define CMODULE_H
|
||||
|
||||
enum MODULE_STATUS {
|
||||
MODULE_NONE,
|
||||
MODULE_QUERY,
|
||||
MODULE_BADLOAD,
|
||||
MODULE_LOADED,
|
||||
MODULE_NOINFO,
|
||||
MODULE_NOQUERY,
|
||||
MODULE_NOATTACH,
|
||||
MODULE_OLD
|
||||
enum MODULE_STATUS
|
||||
{
|
||||
MODULE_NONE, // No module loaded
|
||||
MODULE_QUERY, // Query failed
|
||||
MODULE_BADLOAD, // Bad file or the module writer messed something up ;]
|
||||
MODULE_LOADED, // Loaded
|
||||
MODULE_NOINFO, // No info
|
||||
MODULE_NOQUERY, // No query function present
|
||||
MODULE_NOATTACH, // No attach function present
|
||||
MODULE_OLD, // Old interface
|
||||
MODULE_NEWER, // newer interface
|
||||
MODULE_INTERROR, // Internal error
|
||||
MODULE_FUNCNOTPRESENT, // Function not present
|
||||
MODULE_NOT64BIT // Not 64 bit compatible
|
||||
};
|
||||
|
||||
struct amxx_module_info_s
|
||||
{
|
||||
const char *name;
|
||||
const char *author;
|
||||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; //added in version 2
|
||||
const char *library; // added in version 4
|
||||
const char *libclass; // added in version 4
|
||||
};
|
||||
|
||||
#define AMXX_OK 0 /* no error */
|
||||
#define AMXX_IFVERS 1 /* interface version */
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||
|
||||
#define AMXX_INTERFACE_VERSION 4
|
||||
|
||||
class CModule
|
||||
{
|
||||
String filename;
|
||||
bool metamod;
|
||||
module_info_s* info;
|
||||
DLHANDLE module;
|
||||
MODULE_STATUS status;
|
||||
String m_Filename; // Filename
|
||||
|
||||
bool m_Metamod; // Using metamod?
|
||||
bool m_Amxx; // Using new module interface?
|
||||
|
||||
amxx_module_info_s m_InfoNew; // module info (new module interface)
|
||||
DLHANDLE m_Handle; // handle
|
||||
MODULE_STATUS m_Status; // status
|
||||
const char *m_MissingFunc; // missing function; only set on MODULE_FUNCNOTPRESENT status
|
||||
|
||||
void clear(bool clearFilename = true);
|
||||
public:
|
||||
|
||||
CModule(const char* fname);
|
||||
~CModule();
|
||||
|
||||
// Interface
|
||||
|
||||
bool attachModule();
|
||||
bool queryModule();
|
||||
bool detachModule();
|
||||
const char* getStatus() const;
|
||||
inline const char* getType() const { return metamod ? "amx&mm" : "amx"; }
|
||||
inline const char* getAuthor() const { return info ? info->author : "unknown"; }
|
||||
inline const char* getVersion() const { return info ? info->version : "unknown"; }
|
||||
inline const char* getName() const { return info ? info->name : "unknown"; }
|
||||
inline module_info_s* getInfo() const { return info; }
|
||||
inline int getStatusValue() { return status; }
|
||||
inline bool operator==( void* fname ) { return !strcmp( filename.str() , (char*)fname ); }
|
||||
inline bool isReloadable() { return ( (status==MODULE_LOADED) && (info->type==RELOAD_MODULE)); }
|
||||
CList<AMX_NATIVE_INFO*> natives;
|
||||
};
|
||||
|
||||
|
||||
void rewriteNativeLists(AMX_NATIVE_INFO *list);
|
||||
|
||||
#ifndef FAKEMETA
|
||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
||||
#endif
|
||||
|
||||
const char* getStatus() const;
|
||||
inline const char* getType() const { return m_Amxx ? "amxx" : (m_Metamod ? "amx&mm" : "amx"); }
|
||||
inline const char* getAuthor() const { return m_InfoNew.author; }
|
||||
inline const char* getVersion() const { return m_InfoNew.version; }
|
||||
inline const char* getName() const { return m_InfoNew.name; }
|
||||
inline const amxx_module_info_s* getInfoNew() const { return &m_InfoNew; } // new
|
||||
inline int getStatusValue() { return m_Status; }
|
||||
inline bool operator==(const char* fname) { return !strcmp(m_Filename.c_str(), fname); }
|
||||
inline bool isReloadable() { return ((m_Status == MODULE_LOADED) && (m_InfoNew.reload != 0)); }
|
||||
inline bool isAmxx() const { return m_Amxx; }
|
||||
inline const char *getMissingFunc() const { return m_MissingFunc; }
|
||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||
inline bool IsMetamod() { return m_Metamod; }
|
||||
|
||||
void CallPluginsLoaded();
|
||||
void CallPluginsUnloaded();
|
||||
void CallPluginsUnloading();
|
||||
|
||||
CVector<AMX_NATIVE_INFO*> m_Natives;
|
||||
CVector<size_t> m_DestroyableIndexes;
|
||||
};
|
||||
|
||||
#endif //CMODULE_H
|
||||
|
@ -29,174 +29,619 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CPlugin.h"
|
||||
#include "CForward.h"
|
||||
#include "CFile.h"
|
||||
#include "amx.h"
|
||||
#include "natives.h"
|
||||
#include "debugger.h"
|
||||
#include "libraries.h"
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error) {
|
||||
extern const char *no_function;
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::loadPlugin(const char* path, const char* name, char* error, int debug)
|
||||
{
|
||||
CPlugin** a = &head;
|
||||
while( *a ) a = &(*a)->next;
|
||||
*a = new CPlugin( pCounter++ ,path,name,error);
|
||||
return *error ? 0 : *a;
|
||||
|
||||
while (*a)
|
||||
a = &(*a)->next;
|
||||
|
||||
*a = new CPlugin(pCounter++, path, name, error, debug);
|
||||
|
||||
return (*a);
|
||||
}
|
||||
|
||||
void CPluginMngr::unloadPlugin( CPlugin** a ) {
|
||||
void CPluginMngr::unloadPlugin(CPlugin** a)
|
||||
{
|
||||
CPlugin* next = (*a)->next;
|
||||
delete *a;
|
||||
*a = next;
|
||||
--pCounter;
|
||||
}
|
||||
|
||||
int CPluginMngr::loadPluginsFromFile( const char* filename )
|
||||
void CPluginMngr::Finalize()
|
||||
{
|
||||
File fp( build_pathname("%s",filename) , "r" );
|
||||
if (m_Finalized)
|
||||
return;
|
||||
|
||||
if ( !fp )
|
||||
pNatives = BuildNativeTable();
|
||||
CPlugin *a = head;
|
||||
|
||||
while (a)
|
||||
{
|
||||
UTIL_Log( "[AMXX] Plugins list not found (file \"%s\")",filename);
|
||||
if (a->getStatusCode() == ps_running)
|
||||
{
|
||||
amx_Register(a->getAMX(), pNatives, -1);
|
||||
a->Finalize();
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
m_Finalized = true;
|
||||
}
|
||||
|
||||
int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
{
|
||||
char file[256];
|
||||
FILE *fp = fopen(build_pathname_r(file, sizeof(file) - 1, "%s", filename), "rt");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Plugins list not found (file \"%s\")", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Find now folder
|
||||
char pluginName[256], line[256], error[256];
|
||||
const char pluginsDir[] = "addons/amxx/plugins"; // hardcoded; :TODO: make it localinfo
|
||||
char pluginName[256], error[256], debug[256];
|
||||
int debugFlag = 0;
|
||||
const char *pluginsDir = get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins");
|
||||
|
||||
String line;
|
||||
|
||||
while ( fp.getline(line , 255 ) )
|
||||
while (!feof(fp))
|
||||
{
|
||||
*pluginName = 0;
|
||||
sscanf(line,"%s",pluginName);
|
||||
if (!isalnum(*pluginName)) continue;
|
||||
pluginName[0] = '\0';
|
||||
|
||||
CPlugin* plugin = loadPlugin( pluginsDir , pluginName , error );
|
||||
debug[0] = '\0';
|
||||
debugFlag = 0;
|
||||
|
||||
if ( plugin != 0 ) // load_amxscript fills it with info in case of error
|
||||
line.clear();
|
||||
line._fread(fp);
|
||||
/** quick hack */
|
||||
char *ptr = const_cast<char *>(line.c_str());
|
||||
while (*ptr)
|
||||
{
|
||||
AMX* amx = plugin->getAMX();
|
||||
int iFunc;
|
||||
|
||||
if(amx_FindPublic(amx, "client_command" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientCommand);
|
||||
if(amx_FindPublic(amx, "client_connect" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientConnect);
|
||||
if(amx_FindPublic(amx, "client_disconnect" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientDisconnect);
|
||||
if(amx_FindPublic(amx, "client_infochanged" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientInfoChanged);
|
||||
if(amx_FindPublic(amx, "client_putinserver" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientPutInServer);
|
||||
if(amx_FindPublic(amx, "plugin_init" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_PluginInit);
|
||||
if(amx_FindPublic(amx, "plugin_cfg" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_PluginCfg);
|
||||
if(amx_FindPublic(amx, "plugin_precache" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_PluginPrecache);
|
||||
if(amx_FindPublic(amx, "plugin_log" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_PluginLog);
|
||||
if(amx_FindPublic(amx, "plugin_end" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_PluginEnd);
|
||||
if(amx_FindPublic(amx, "inconsistent_file" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_InconsistentFile);
|
||||
if(amx_FindPublic(amx, "client_authorized" , &iFunc) == AMX_ERR_NONE)
|
||||
g_forwards.registerForward( plugin , iFunc , FF_ClientAuthorized);
|
||||
if (*ptr == ';')
|
||||
{
|
||||
*ptr = '\0';
|
||||
} else {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
else
|
||||
sscanf(line.c_str(), "%s %s", pluginName, debug);
|
||||
|
||||
if (!isalnum(*pluginName))
|
||||
continue;
|
||||
|
||||
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
||||
{
|
||||
UTIL_Log("[AMXX] %s (plugin \"%s\")", error, pluginName );
|
||||
debugFlag = 1;
|
||||
}
|
||||
|
||||
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
|
||||
|
||||
if (plugin->getStatusCode() == ps_bad_load)
|
||||
{
|
||||
char errorMsg[255];
|
||||
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
|
||||
plugin->setError(errorMsg);
|
||||
AMXXLOG_Log("[AMXX] %s", plugin->getError());
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
InvalidateCache();
|
||||
|
||||
return pCounter;
|
||||
}
|
||||
|
||||
void CPluginMngr::clear() {
|
||||
CPlugin**a = &head;
|
||||
while ( *a )
|
||||
unloadPlugin(a);
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||
void CPluginMngr::clear()
|
||||
{
|
||||
return (CPlugin*)(amx->userdata[3]);
|
||||
/*CPlugin*a = head;
|
||||
while ( a && &a->amx != amx )
|
||||
a=a->next;
|
||||
return a;*/
|
||||
}
|
||||
CPlugin**a = &head;
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx) {
|
||||
CPlugin*a = head;
|
||||
while ( a && &a->amx != amx )
|
||||
a=a->next;
|
||||
return a;
|
||||
}
|
||||
while (*a)
|
||||
unloadPlugin(a);
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index){
|
||||
CPlugin*a = head;
|
||||
while ( a && index--)
|
||||
a=a->next;
|
||||
return a;
|
||||
}
|
||||
m_Finalized = false;
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name) {
|
||||
if (!name) return 0;
|
||||
int len = strlen(name);
|
||||
if (!len) return 0;
|
||||
CPlugin*a = head;
|
||||
while( a && strncmp(a->name.str(), name,len) )
|
||||
a=a->next;
|
||||
return a;
|
||||
}
|
||||
|
||||
const char* CPluginMngr::CPlugin::getStatus() const {
|
||||
switch(status){
|
||||
case ps_running: return "running";
|
||||
case ps_paused: return "paused";
|
||||
case ps_bad_load: return "bad load";
|
||||
case ps_stopped: return "stopped";
|
||||
case ps_locked: return "locked";
|
||||
if (pNatives)
|
||||
{
|
||||
delete [] pNatives;
|
||||
pNatives = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
|
||||
{
|
||||
CPlugin*a = head;
|
||||
|
||||
while (a && &a->amx != amx)
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(int index)
|
||||
{
|
||||
CPlugin*a = head;
|
||||
|
||||
while (a && index--)
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
|
||||
{
|
||||
if (!name)
|
||||
return 0;
|
||||
|
||||
int len = strlen(name);
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
CPlugin*a = head;
|
||||
|
||||
while (a && strncmp(a->name.c_str(), name, len))
|
||||
a = a->next;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
const char* CPluginMngr::CPlugin::getStatus() const
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case ps_running:
|
||||
{
|
||||
if (m_Debug)
|
||||
{
|
||||
return "debug";
|
||||
} else {
|
||||
return "running";
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ps_paused: return "paused";
|
||||
case ps_bad_load: return "bad load";
|
||||
case ps_stopped: return "stopped";
|
||||
case ps_locked: return "locked";
|
||||
}
|
||||
|
||||
return "error";
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin::CPlugin(int i, const char* p,const char* n, char* e) : name(n), title(n) {
|
||||
CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int d) : name(n), title(n)
|
||||
{
|
||||
const char* unk = "unknown";
|
||||
title.set(unk);
|
||||
author.set(unk);
|
||||
version.set(unk);
|
||||
char* path = build_pathname("%s/%s",p,n);
|
||||
|
||||
title.assign(unk);
|
||||
author.assign(unk);
|
||||
version.assign(unk);
|
||||
|
||||
char file[256];
|
||||
char* path = build_pathname_r(file, sizeof(file) - 1, "%s/%s", p, n);
|
||||
code = 0;
|
||||
int err = load_amxscript(&amx,&code,path,e );
|
||||
if ( err == AMX_ERR_NONE ) status = ps_running;
|
||||
else status = ps_bad_load;
|
||||
amx.userdata[3] = this;
|
||||
memset(&amx, 0, sizeof(AMX));
|
||||
int err = load_amxscript(&amx, &code, path, e, d);
|
||||
|
||||
if (err == AMX_ERR_NONE)
|
||||
{
|
||||
status = ps_running;
|
||||
} else {
|
||||
status = ps_bad_load;
|
||||
}
|
||||
|
||||
amx.userdata[UD_FINDPLUGIN] = this;
|
||||
paused_fun = 0;
|
||||
next = 0;
|
||||
id = i;
|
||||
}
|
||||
CPluginMngr::CPlugin::~CPlugin( ){
|
||||
unload_amxscript( &amx, &code );
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::pauseFunction( int id ) {
|
||||
if (isValid()){
|
||||
paused_fun |= (1<<id);
|
||||
g_commands.clearBufforedInfo();
|
||||
if (status == ps_running)
|
||||
{
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE);
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE);
|
||||
|
||||
if (amx.flags & AMX_FLAG_DEBUG)
|
||||
{
|
||||
m_Debug = true;
|
||||
} else {
|
||||
m_Debug = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::unpauseFunction( int id ) {
|
||||
if (isValid()) {
|
||||
paused_fun &= ~(1<<id);
|
||||
g_commands.clearBufforedInfo();
|
||||
CPluginMngr::CPlugin::~CPlugin()
|
||||
{
|
||||
unload_amxscript(&amx, &code);
|
||||
}
|
||||
|
||||
int AMXAPI native_handler(AMX *amx, int index)
|
||||
{
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
char name[sNAMEMAX + 1];
|
||||
amx_GetNative(amx, index, name);
|
||||
|
||||
return pHandler->HandleNative(name, index, 0);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
||||
{
|
||||
//A script has accidentally called an invalid native! give them a
|
||||
// first chance to block the resulting error.
|
||||
|
||||
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
|
||||
|
||||
//this should never happen
|
||||
if (!pHandler)
|
||||
{
|
||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//this should never happen because this native won't be called
|
||||
// if the plugin isn't filtering.
|
||||
if (!pHandler->IsNativeFiltering())
|
||||
{
|
||||
LogError(amx, AMX_ERR_INVNATIVE, "Invalid native attempt");
|
||||
return 0;
|
||||
}
|
||||
|
||||
char name[sNAMEMAX + 1];
|
||||
int native = (int)(_INT_PTR)(amx->usertags[UT_NATIVE]);
|
||||
int err = amx_GetNative(amx, native, name);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
name[0] = '\0';
|
||||
|
||||
//1 - because we're trapping usage
|
||||
if (!pHandler->HandleNative(name, native, 1))
|
||||
{
|
||||
amx->usertags[UT_NATIVE] = (void *)native;
|
||||
LogError(amx, AMX_ERR_INVNATIVE, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Someday maybe allow native filters to write their own return value?
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::Finalize()
|
||||
{
|
||||
char buffer[128];
|
||||
int old_status = status;
|
||||
|
||||
if (CheckModules(&amx, buffer))
|
||||
{
|
||||
if (amx_Register(&amx, core_Natives, -1) != AMX_ERR_NONE)
|
||||
{
|
||||
Handler *pHandler = (Handler *)amx.userdata[UD_HANDLER];
|
||||
int res = 0;
|
||||
|
||||
if (pHandler->IsNativeFiltering())
|
||||
res = amx_CheckNatives(&amx, native_handler);
|
||||
|
||||
if (!res)
|
||||
{
|
||||
status = ps_bad_load;
|
||||
sprintf(buffer, "Plugin uses an unknown function (name \"%s\") - check your modules.ini.", no_function);
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
} else {
|
||||
amx_RegisterToAny(&amx, invalid_native);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = ps_bad_load;
|
||||
errorMsg.assign(buffer);
|
||||
amx.error = AMX_ERR_NOTFOUND;
|
||||
}
|
||||
|
||||
if (old_status != status)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Plugin \"%s\" failed to load: %s", name.c_str(), errorMsg.c_str());
|
||||
}
|
||||
}
|
||||
void CPluginMngr::CPlugin::setStatus( int a ) {
|
||||
|
||||
void CPluginMngr::CPlugin::pauseFunction(int id)
|
||||
{
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::unpauseFunction(int id)
|
||||
{
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::setStatus(int a)
|
||||
{
|
||||
status = a;
|
||||
g_commands.clearBufforedInfo(); // ugly way
|
||||
}
|
||||
|
||||
// Pause a plugin
|
||||
void CPluginMngr::CPlugin::pausePlugin()
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
// call plugin_pause if provided
|
||||
if (m_PauseFwd != -1)
|
||||
executeForwards(m_PauseFwd);
|
||||
|
||||
setStatus(ps_paused);
|
||||
}
|
||||
}
|
||||
|
||||
// Unpause a plugin
|
||||
void CPluginMngr::CPlugin::unpausePlugin()
|
||||
{
|
||||
if (isValid())
|
||||
{
|
||||
// set status first so the function will be marked executable
|
||||
setStatus(ps_running);
|
||||
|
||||
// call plugin_unpause if provided
|
||||
if (m_UnpauseFwd != -1)
|
||||
executeForwards(m_UnpauseFwd);
|
||||
}
|
||||
}
|
||||
|
||||
char *CPluginMngr::ReadIntoOrFromCache(const char *file, size_t &bufsize)
|
||||
{
|
||||
List<plcache_entry *>::iterator iter;
|
||||
plcache_entry *pl;
|
||||
|
||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||
{
|
||||
pl = (*iter);
|
||||
if (pl->path.compare(file) == 0)
|
||||
{
|
||||
bufsize = pl->bufsize;
|
||||
return pl->buffer;
|
||||
}
|
||||
}
|
||||
|
||||
pl = new plcache_entry;
|
||||
|
||||
pl->file = new CAmxxReader(file, sizeof(cell));
|
||||
pl->buffer = NULL;
|
||||
if (pl->file->GetStatus() != CAmxxReader::Err_None)
|
||||
{
|
||||
delete pl->file;
|
||||
delete pl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pl->bufsize = pl->file->GetBufferSize();
|
||||
if (pl->bufsize)
|
||||
{
|
||||
pl->buffer = new char[pl->bufsize];
|
||||
pl->file->GetSection(pl->buffer);
|
||||
}
|
||||
|
||||
if (!pl->buffer || pl->file->GetStatus() != CAmxxReader::Err_None)
|
||||
{
|
||||
delete [] pl->buffer;
|
||||
delete pl->file;
|
||||
delete pl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pl->path.assign(file);
|
||||
|
||||
bufsize = pl->bufsize;
|
||||
|
||||
m_plcache.push_back(pl);
|
||||
|
||||
return pl->buffer;
|
||||
}
|
||||
|
||||
void CPluginMngr::InvalidateCache()
|
||||
{
|
||||
List<plcache_entry *>::iterator iter;
|
||||
plcache_entry *pl;
|
||||
|
||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||
{
|
||||
pl = (*iter);
|
||||
delete [] pl->buffer;
|
||||
delete pl->file;
|
||||
delete pl;
|
||||
}
|
||||
|
||||
m_plcache.clear();
|
||||
}
|
||||
|
||||
void CPluginMngr::InvalidateFileInCache(const char *file, bool freebuf)
|
||||
{
|
||||
List<plcache_entry *>::iterator iter;
|
||||
plcache_entry *pl;
|
||||
|
||||
for (iter=m_plcache.begin(); iter!=m_plcache.end(); iter++)
|
||||
{
|
||||
pl = (*iter);
|
||||
if (pl->path.compare(file) == 0)
|
||||
{
|
||||
if (freebuf)
|
||||
delete [] pl->buffer;
|
||||
delete pl->file;
|
||||
delete pl;
|
||||
m_plcache.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CPluginMngr::CacheAndLoadModules(const char *plugin)
|
||||
{
|
||||
size_t progsize;
|
||||
char *prog = ReadIntoOrFromCache(plugin, progsize);
|
||||
|
||||
if (!prog)
|
||||
return;
|
||||
|
||||
AMX_HEADER hdr;
|
||||
memcpy(&hdr, prog, sizeof(AMX_HEADER));
|
||||
|
||||
uint16_t magic = hdr.magic;
|
||||
amx_Align16(&magic);
|
||||
|
||||
if (magic != AMX_MAGIC)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr.file_version < MIN_FILE_VERSION ||
|
||||
hdr.file_version > CUR_FILE_VERSION)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if ((hdr.defsize != sizeof(AMX_FUNCSTUB)) &&
|
||||
(hdr.defsize != sizeof(AMX_FUNCSTUBNT)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
amx_Align32((uint32_t*)&hdr.nametable);
|
||||
uint16_t *namelength=(uint16_t*)((unsigned char*)prog + (unsigned)hdr.nametable);
|
||||
amx_Align16(namelength);
|
||||
if (*namelength>sNAMEMAX)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (hdr.stp <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AMX amx;
|
||||
memset(&amx, 0, sizeof(AMX));
|
||||
amx.base = (unsigned char *)prog;
|
||||
|
||||
int num;
|
||||
char name[sNAMEMAX+1];
|
||||
|
||||
num = amx_GetLibraries(&amx);
|
||||
for (int i=0; i<num; i++)
|
||||
{
|
||||
amx_GetLibrary(&amx, i, name, sNAMEMAX);
|
||||
if (stricmp(name, "Float")==0)
|
||||
continue;
|
||||
//awful backwards compat hack
|
||||
if (stricmp(name, "socket")==0)
|
||||
strcpy(name, "sockets");
|
||||
//we don't want to report failed modules here...
|
||||
LoadModule(name, PT_ANYTIME, true, true);
|
||||
}
|
||||
|
||||
cell tag_id;
|
||||
amx_NumTags(&amx, &num);
|
||||
|
||||
CVector<LibDecoder *> expects;
|
||||
CVector<LibDecoder *> defaults;
|
||||
CStack<LibDecoder *> delstack;
|
||||
for (int i=0; i<num; i++)
|
||||
{
|
||||
amx_GetTag(&amx, i, name, &tag_id);
|
||||
if (name[0] == '?')
|
||||
{
|
||||
LibDecoder *dc = new LibDecoder;
|
||||
delstack.push(dc);
|
||||
if (DecodeLibCmdString(name, dc))
|
||||
{
|
||||
if (dc->cmd == LibCmd_ForceLib)
|
||||
{
|
||||
RunLibCommand(dc);
|
||||
} else if ( (dc->cmd == LibCmd_ExpectClass) ||
|
||||
(dc->cmd == LibCmd_ExpectLib) )
|
||||
{
|
||||
expects.push_back(dc);
|
||||
} else if (dc->cmd == LibCmd_DefaultLib) {
|
||||
defaults.push_back(dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i=0; i<expects.size(); i++)
|
||||
{
|
||||
RunLibCommand(expects[i]);
|
||||
}
|
||||
for (size_t i=0; i<defaults.size(); i++)
|
||||
{
|
||||
RunLibCommand(defaults[i]);
|
||||
}
|
||||
|
||||
expects.clear();
|
||||
defaults.clear();
|
||||
|
||||
while (!delstack.empty())
|
||||
{
|
||||
delete delstack.front();
|
||||
delstack.pop();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void CPluginMngr::CALMFromFile(const char *file)
|
||||
{
|
||||
char filename[256];
|
||||
FILE *fp = fopen(build_pathname_r(filename, sizeof(filename) - 1, "%s", file), "rt");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Find now folder
|
||||
char pluginName[256];
|
||||
char line[256];
|
||||
String rline;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
fgets(line, sizeof(line)-1, fp);
|
||||
if (line[0] == ';' || line[0] == '\n' || line[0] == '\0')
|
||||
continue;
|
||||
|
||||
/** quick hack */
|
||||
char *ptr = line;
|
||||
while (*ptr)
|
||||
{
|
||||
if (*ptr == ';')
|
||||
{
|
||||
*ptr = '\0';
|
||||
} else {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
|
||||
rline.assign(line);
|
||||
rline.trim();
|
||||
pluginName[0] = '\0';
|
||||
sscanf(rline.c_str(), "%s", pluginName);
|
||||
|
||||
if (!isalnum(*pluginName))
|
||||
continue;
|
||||
|
||||
build_pathname_r(filename, sizeof(filename)-1, "%s/%s", get_localinfo("amxx_pluginsdir", "addons/amxmodx/plugins"), pluginName);
|
||||
|
||||
CacheAndLoadModules(filename);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
@ -32,22 +32,27 @@
|
||||
#ifndef PLUGIN_H
|
||||
#define PLUGIN_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "sh_list.h"
|
||||
#include "amx.h"
|
||||
#include "amxxfile.h"
|
||||
|
||||
// *****************************************************
|
||||
// class CPluginMngr
|
||||
// *****************************************************
|
||||
|
||||
enum {
|
||||
ps_bad_load,
|
||||
ps_error,
|
||||
ps_paused,
|
||||
ps_running,
|
||||
ps_stopped,
|
||||
ps_locked
|
||||
enum
|
||||
{
|
||||
ps_bad_load, //Load failed
|
||||
ps_error, //Erroneous state
|
||||
ps_locked, //UNUSED
|
||||
ps_paused, //Plugin is temporarily paused
|
||||
ps_stopped, //Plugin is ... more temporarily paused
|
||||
ps_running, //Plugin is running
|
||||
};
|
||||
|
||||
class CPluginMngr
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
class iterator;
|
||||
@ -59,62 +64,80 @@ public:
|
||||
|
||||
AMX amx;
|
||||
void* code;
|
||||
|
||||
String name;
|
||||
String version;
|
||||
String title;
|
||||
String author;
|
||||
String errorMsg;
|
||||
|
||||
int m_PauseFwd;
|
||||
int m_UnpauseFwd;
|
||||
int paused_fun;
|
||||
int status;
|
||||
CPlugin* next;
|
||||
int id;
|
||||
CPlugin(int i , const char* p,const char* n, char* e);
|
||||
~CPlugin( );
|
||||
|
||||
CPlugin(int i, const char* p, const char* n, char* e, int d);
|
||||
~CPlugin();
|
||||
|
||||
bool m_Debug;
|
||||
public:
|
||||
|
||||
inline const char* getName() const { return name.str();}
|
||||
inline const char* getVersion() const { return version.str();}
|
||||
inline const char* getTitle() const { return title.str();}
|
||||
inline const char* getAuthor()const { return author.str();}
|
||||
inline const char* getName() { return name.c_str();}
|
||||
inline const char* getVersion() { return version.c_str();}
|
||||
inline const char* getTitle() { return title.c_str();}
|
||||
inline const char* getAuthor() { return author.c_str();}
|
||||
inline const char* getError() { return errorMsg.c_str();}
|
||||
inline int getStatusCode() { return status; }
|
||||
inline int getId() const { return id; }
|
||||
inline AMX* getAMX() { return &amx; }
|
||||
inline void setTitle( const char* n ) { title.set(n); }
|
||||
inline void setAuthor( const char* n ) { author.set(n); }
|
||||
inline void setVersion( const char* n ) { version.set(n); }
|
||||
inline bool isValid() const { return ((status != ps_bad_load) && (status != ps_locked)); }
|
||||
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() && !isFunctionPaused(id)); }
|
||||
inline void pausePlugin( ) { if ( isValid() ) setStatus(ps_paused); }
|
||||
inline void unpausePlugin( ) { if ( isValid() ) setStatus(ps_running); }
|
||||
void pauseFunction( int id );
|
||||
void unpauseFunction( int id );
|
||||
void setStatus( int a );
|
||||
inline const AMX* getAMX() const { return &amx; }
|
||||
inline void setTitle(const char* n) { title.assign(n); }
|
||||
inline void setAuthor(const char* n) { author.assign(n); }
|
||||
inline void setVersion(const char* n) { version.assign(n); }
|
||||
inline void setError(const char* n) { errorMsg.assign(n); }
|
||||
inline bool isValid() const { return (status >= ps_paused); }
|
||||
inline bool isPaused() const { return ((status == ps_paused) || (status == ps_stopped)); }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||
|
||||
void Finalize();
|
||||
void pausePlugin();
|
||||
void unpausePlugin();
|
||||
void pauseFunction(int id);
|
||||
void unpauseFunction(int id);
|
||||
void setStatus(int a);
|
||||
|
||||
const char* getStatus() const;
|
||||
inline bool isDebug() const { return m_Debug; }
|
||||
};
|
||||
|
||||
private:
|
||||
CPlugin *head;
|
||||
int pCounter;
|
||||
|
||||
|
||||
public:
|
||||
CPluginMngr() { head = 0; pCounter = 0; }
|
||||
~CPluginMngr() { clear(); }
|
||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||
~CPluginMngr() { clear(); InvalidateCache(); }
|
||||
|
||||
bool m_Finalized;
|
||||
AMX_NATIVE_INFO *pNatives;
|
||||
|
||||
// Interface
|
||||
|
||||
CPlugin* loadPlugin(const char* path, const char* name, char* error);
|
||||
void unloadPlugin( CPlugin** a );
|
||||
int loadPluginsFromFile( const char* filename );
|
||||
CPlugin* findPluginFast(AMX *amx);
|
||||
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
||||
void unloadPlugin(CPlugin** a);
|
||||
int loadPluginsFromFile(const char* filename);
|
||||
|
||||
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); }
|
||||
CPlugin* findPlugin(AMX *amx);
|
||||
CPlugin* findPlugin(int index);
|
||||
CPlugin* findPlugin(const char* name);
|
||||
|
||||
inline int getPluginsNum() const { return pCounter; }
|
||||
void Finalize();
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
class iterator
|
||||
{
|
||||
CPlugin *a;
|
||||
public:
|
||||
iterator(CPlugin*aa) : a(aa) {}
|
||||
@ -124,10 +147,24 @@ public:
|
||||
operator bool () const { return a ? true : false; }
|
||||
CPlugin& operator*() { return *a; }
|
||||
};
|
||||
|
||||
inline iterator begin() const { return iterator(head); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
public:
|
||||
struct plcache_entry
|
||||
{
|
||||
CAmxxReader *file;
|
||||
size_t bufsize;
|
||||
char *buffer;
|
||||
String path;
|
||||
};
|
||||
char *ReadIntoOrFromCache(const char *file, size_t &bufsize);
|
||||
void InvalidateCache();
|
||||
void InvalidateFileInCache(const char *file, bool freebuf);
|
||||
void CacheAndLoadModules(const char *plugin);
|
||||
void CALMFromFile(const char *file);
|
||||
private:
|
||||
List<plcache_entry *> m_plcache;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //PLUGIN_H
|
||||
|
129
amxmodx/CQueue.h
Executable file
129
amxmodx/CQueue.h
Executable file
@ -0,0 +1,129 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
#ifndef _INCLUDE_CQUEUE_H
|
||||
#define _INCLUDE_CQUEUE_H
|
||||
|
||||
template <class T>
|
||||
class CQueue
|
||||
{
|
||||
public:
|
||||
class CQueueItem
|
||||
{
|
||||
public:
|
||||
CQueueItem(const T &i, CQueueItem *n)
|
||||
{
|
||||
item = i;
|
||||
next = n;
|
||||
}
|
||||
|
||||
CQueueItem *GetNext()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
T & GetItem()
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
void SetNext(CQueueItem *n)
|
||||
{
|
||||
next = n;
|
||||
}
|
||||
private:
|
||||
T item;
|
||||
CQueueItem *next;
|
||||
};
|
||||
public:
|
||||
CQueue()
|
||||
{
|
||||
mSize = 0;
|
||||
mFirst = NULL;
|
||||
mLast = NULL;
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return ((mSize == 0) ? true : false);
|
||||
}
|
||||
|
||||
void push(const T &v)
|
||||
{
|
||||
CQueueItem *p = new CQueueItem(v, NULL);
|
||||
if (empty())
|
||||
{
|
||||
mFirst = p;
|
||||
} else {
|
||||
mLast->SetNext(p);
|
||||
}
|
||||
mLast = p;
|
||||
mSize++;
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
if (mFirst == mLast)
|
||||
{
|
||||
delete mFirst;
|
||||
mFirst = NULL;
|
||||
mLast = NULL;
|
||||
} else {
|
||||
CQueueItem *p = mFirst->GetNext();
|
||||
delete mFirst;
|
||||
mFirst = p;
|
||||
}
|
||||
mSize--;
|
||||
}
|
||||
|
||||
T & front()
|
||||
{
|
||||
return mFirst->GetItem();
|
||||
}
|
||||
|
||||
T & back()
|
||||
{
|
||||
return mLast->GetItem();
|
||||
}
|
||||
|
||||
unsigned int size()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
private:
|
||||
CQueueItem *mFirst;
|
||||
CQueueItem *mLast;
|
||||
|
||||
unsigned int mSize;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CQUEUE_H
|
@ -29,30 +29,385 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef STRING_CUSTOM_H
|
||||
#define STRING_CUSTOM_H
|
||||
#ifndef _INCLUDE_CSTRING_H
|
||||
#define _INCLUDE_CSTRING_H
|
||||
|
||||
// *****************************************************
|
||||
// class String
|
||||
// *****************************************************
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
class String
|
||||
{
|
||||
char* napis;
|
||||
short int len;
|
||||
|
||||
public:
|
||||
String();
|
||||
String( const char* n );
|
||||
~String();
|
||||
void set( const char* n );
|
||||
inline bool empty() const { return (len == 0); }
|
||||
inline const char* str() const { return napis ? napis : "(null)"; }
|
||||
inline short int size() const { return len; }
|
||||
void clear();
|
||||
String()
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
//assign("");
|
||||
}
|
||||
|
||||
~String()
|
||||
{
|
||||
if (v)
|
||||
delete [] v;
|
||||
}
|
||||
|
||||
String(const char *src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src);
|
||||
}
|
||||
|
||||
const char * _fread(FILE *fp)
|
||||
{
|
||||
Grow(512, false);
|
||||
char *ret = fgets(v, 511, fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
String(const String &src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
const char *c_str() { return v?v:""; }
|
||||
|
||||
const char *c_str() const { return v?v:""; }
|
||||
|
||||
void append(const char *t)
|
||||
{
|
||||
Grow(size() + strlen(t) + 1);
|
||||
strcat(v, t);
|
||||
}
|
||||
|
||||
void append(const char c)
|
||||
{
|
||||
size_t len = size();
|
||||
Grow(len + 2);
|
||||
v[len] = c;
|
||||
v[len + 1] = '\0';
|
||||
}
|
||||
|
||||
void append(String &d)
|
||||
{
|
||||
append(d.c_str());
|
||||
}
|
||||
|
||||
void assign(const String &src)
|
||||
{
|
||||
assign(src.c_str());
|
||||
}
|
||||
|
||||
void assign(const char *d)
|
||||
{
|
||||
if (!d)
|
||||
{
|
||||
clear();
|
||||
} else {
|
||||
size_t len = strlen(d);
|
||||
Grow(len + 1, false);
|
||||
memcpy(v, d, len);
|
||||
v[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (v)
|
||||
v[0] = '\0';
|
||||
}
|
||||
|
||||
int compare (const char *d) const
|
||||
{
|
||||
if (!v)
|
||||
return strcmp("", d);
|
||||
else
|
||||
return strcmp(v, d);
|
||||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty()
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
|
||||
if (v[0] == '\0')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
if (v)
|
||||
return strlen(v);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find(const char c, int index = 0)
|
||||
{
|
||||
int len = static_cast<int>(size());
|
||||
if (len < 1)
|
||||
return npos;
|
||||
if (index >= len || index < 0)
|
||||
return npos;
|
||||
int i = 0;
|
||||
for (i=index; i<len; i++)
|
||||
{
|
||||
if (v[i] == c)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return npos;
|
||||
}
|
||||
|
||||
bool is_space(int c)
|
||||
{
|
||||
if (c == '\f' || c == '\n' ||
|
||||
c == '\t' || c == '\r' ||
|
||||
c == '\v' || c == ' ')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void reparse_newlines()
|
||||
{
|
||||
size_t len = size();
|
||||
int offs = 0;
|
||||
char c;
|
||||
if (!len)
|
||||
return;
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
c = v[i];
|
||||
if (c == '^' && (i != len-1))
|
||||
{
|
||||
c = v[++i];
|
||||
if (c == 'n')
|
||||
c = '\n';
|
||||
else if (c == 't')
|
||||
c = '\t';
|
||||
offs++;
|
||||
}
|
||||
v[i-offs] = c;
|
||||
}
|
||||
v[len-offs] = '\0';
|
||||
}
|
||||
|
||||
void trim()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
size_t len = strlen(v);
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[i]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char c0 = v[0];
|
||||
|
||||
if (is_space(c0))
|
||||
{
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (!is_space(v[i]) || (is_space(v[i]) && ((unsigned char)i==len-1)))
|
||||
{
|
||||
erase(0, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len = strlen(v);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_space(v[len-1]))
|
||||
{
|
||||
for (i=len-1; i>=0; i--)
|
||||
{
|
||||
if (!is_space(v[i])
|
||||
|| (is_space(v[i]) && i==0))
|
||||
{
|
||||
erase(i+1, j);
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
if (is_space(v[0]))
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void erase(unsigned int start, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = size();
|
||||
//check for bounds
|
||||
if (num == npos || start+num > len-start)
|
||||
num = len - start;
|
||||
//do the erasing
|
||||
bool copyflag = false;
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (i>=start && i<start+num)
|
||||
{
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
copyflag = true;
|
||||
} else if (copyflag) {
|
||||
if (i+num < len)
|
||||
{
|
||||
v[i] = v[i+num];
|
||||
} else {
|
||||
v[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
len -= num;
|
||||
v[len] = 0;
|
||||
}
|
||||
|
||||
String substr(unsigned int index, int num = npos)
|
||||
{
|
||||
if (!v)
|
||||
{
|
||||
String b("");
|
||||
return b;
|
||||
}
|
||||
|
||||
String ns;
|
||||
|
||||
size_t len = size();
|
||||
|
||||
if (index >= len || !v)
|
||||
return ns;
|
||||
|
||||
if (num == npos)
|
||||
{
|
||||
num = len - index;
|
||||
} else if (index+num >= len) {
|
||||
num = len - index;
|
||||
}
|
||||
|
||||
unsigned int i = 0;
|
||||
unsigned int nslen = num + 2;
|
||||
|
||||
ns.Grow(nslen);
|
||||
|
||||
for (i=index; i<index+num; i++)
|
||||
ns.append(v[i]);
|
||||
|
||||
return ns;
|
||||
}
|
||||
|
||||
void toLower()
|
||||
{
|
||||
if (!v)
|
||||
return;
|
||||
unsigned int i = 0;
|
||||
size_t len = strlen(v);
|
||||
for (i=0; i<len; i++)
|
||||
{
|
||||
if (v[i] >= 65 && v[i] <= 90)
|
||||
v[i] &= ~(1<<5);
|
||||
}
|
||||
}
|
||||
|
||||
String & operator = (const String &src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & operator = (const char *src)
|
||||
{
|
||||
assign(src);
|
||||
return *this;
|
||||
|
||||
}
|
||||
|
||||
char operator [] (unsigned int index)
|
||||
{
|
||||
if (index > size() || !v)
|
||||
{
|
||||
return -1;
|
||||
} else {
|
||||
return v[index];
|
||||
}
|
||||
}
|
||||
|
||||
int at(int a)
|
||||
{
|
||||
if (a < 0 || a >= (int)size() || !v)
|
||||
return -1;
|
||||
|
||||
return v[a];
|
||||
}
|
||||
|
||||
bool at(int at, char c)
|
||||
{
|
||||
if (at < 0 || at >= (int)size() || !v)
|
||||
return false;
|
||||
|
||||
v[at] = c;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
void Grow(unsigned int d, bool copy=true)
|
||||
{
|
||||
if (d <= a_size)
|
||||
return;
|
||||
char *n = new char[d + 1];
|
||||
if (copy && v)
|
||||
strcpy(n, v);
|
||||
if (v)
|
||||
delete [] v;
|
||||
else
|
||||
strcpy(n, "");
|
||||
v = n;
|
||||
a_size = d + 1;
|
||||
}
|
||||
|
||||
char *v;
|
||||
unsigned int a_size;
|
||||
public:
|
||||
static const int npos = -1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif //_INCLUDE_CSTRING_H
|
||||
|
@ -29,164 +29,267 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
#include "CTask.h"
|
||||
|
||||
/*********************** CTask ***********************/
|
||||
|
||||
CTaskMngr::CTask::CTask( CPluginMngr::CPlugin* p, int f, int flags,
|
||||
int i, float base, float exec, int parlen ,
|
||||
const cell* par, int r){
|
||||
plugin = p;
|
||||
func = f;
|
||||
id = i;
|
||||
next = 0;
|
||||
prev = 0;
|
||||
param_len = 0;
|
||||
param = 0;
|
||||
base_time = base;
|
||||
exec_time = exec;
|
||||
repeat = (flags & 1) ? r : 0;
|
||||
loop = (flags & 2) ? true : false;
|
||||
afterstart = (flags & 4) ? true : false;
|
||||
beforeend = (flags & 8) ? true : false;
|
||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
||||
{
|
||||
clear();
|
||||
m_bFree = false;
|
||||
|
||||
if ( parlen )
|
||||
m_pPlugin = pPlugin;
|
||||
m_iFunc = iFunc;
|
||||
m_iId = iId;
|
||||
m_fBase = fBase;
|
||||
m_bInExecute = false;
|
||||
|
||||
if (iFlags & 2)
|
||||
{
|
||||
param = new cell[ parlen + 1 ];
|
||||
m_bLoop = true;
|
||||
m_iRepeat = -1;
|
||||
}
|
||||
else if (iFlags & 1)
|
||||
{
|
||||
m_bLoop = true;
|
||||
m_iRepeat = iRepeat;
|
||||
}
|
||||
|
||||
if ( param ){
|
||||
param_len = parlen + 1;
|
||||
memcpy( param , par , sizeof( cell ) * parlen );
|
||||
param[ parlen ] = 0;
|
||||
m_bAfterStart = (iFlags & 4) ? true : false;
|
||||
m_bBeforeEnd = (iFlags & 8) ? true : false;
|
||||
|
||||
m_fNextExecTime = fCurrentTime + m_fBase;
|
||||
|
||||
if (iParamsLen)
|
||||
{
|
||||
m_iParamLen = iParamsLen + 1;
|
||||
m_pParams = new cell[m_iParamLen];
|
||||
memcpy(m_pParams, pParams, sizeof(cell)*iParamsLen);
|
||||
m_pParams[iParamsLen] = 0;
|
||||
} else {
|
||||
m_iParamLen = 0;
|
||||
m_pParams = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void CTaskMngr::CTask::clear()
|
||||
{
|
||||
m_bFree = true;
|
||||
|
||||
if (m_iFunc >= 0)
|
||||
{
|
||||
unregisterSPForward(m_iFunc);
|
||||
m_iFunc = -1;
|
||||
}
|
||||
|
||||
if (m_pParams)
|
||||
{
|
||||
delete [] m_pParams;
|
||||
m_pParams = NULL;
|
||||
}
|
||||
|
||||
m_pPlugin = NULL;
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
}
|
||||
|
||||
bool CTaskMngr::CTask::isFree() const
|
||||
{
|
||||
return m_bFree;
|
||||
}
|
||||
|
||||
void CTaskMngr::CTask::changeBase(float fNewBase)
|
||||
{
|
||||
m_fBase = fNewBase;
|
||||
}
|
||||
|
||||
void CTaskMngr::CTask::resetNextExecTime(float fCurrentTime)
|
||||
{
|
||||
m_fNextExecTime = fCurrentTime + m_fBase;
|
||||
}
|
||||
|
||||
void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft)
|
||||
{
|
||||
bool execute = false;
|
||||
bool done = false;
|
||||
|
||||
if (m_bAfterStart)
|
||||
{
|
||||
if (fCurrentTime - fTimeLeft + 1.0f >= m_fBase)
|
||||
execute = true;
|
||||
}
|
||||
else if (m_bBeforeEnd)
|
||||
{
|
||||
if (fTimeLimit != 0.0f && (fTimeLeft + fTimeLimit * 60.0f) - fCurrentTime - 1.0f <= m_fBase)
|
||||
execute = true;
|
||||
}
|
||||
else if (m_fNextExecTime <= fCurrentTime)
|
||||
{
|
||||
execute = true;
|
||||
}
|
||||
|
||||
if (execute)
|
||||
{
|
||||
//only bother calling if we have something to call
|
||||
if (!(m_bLoop && !m_iRepeat))
|
||||
{
|
||||
m_bInExecute = true;
|
||||
if (m_iParamLen) // call with parameters
|
||||
{
|
||||
cell arr = prepareCellArray(m_pParams, m_iParamLen);
|
||||
executeForwards(m_iFunc, arr, m_iId);
|
||||
} else {
|
||||
executeForwards(m_iFunc, m_iId);
|
||||
}
|
||||
m_bInExecute = false;
|
||||
}
|
||||
|
||||
if (isFree())
|
||||
return;
|
||||
|
||||
// set new exec time OR remove the task if needed
|
||||
if (m_bLoop)
|
||||
{
|
||||
if (m_iRepeat != -1 && --m_iRepeat <= 0)
|
||||
done = true;
|
||||
} else {
|
||||
done = true;
|
||||
}
|
||||
|
||||
if (done)
|
||||
{
|
||||
clear();
|
||||
} else {
|
||||
m_fNextExecTime += m_fBase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CTaskMngr::CTask* CTaskMngr::getFirstValidTask(CTask* h){
|
||||
CTask* a = h;
|
||||
while( a ) {
|
||||
if ( a->isRemoved() ) {
|
||||
CTask* b = a->next;
|
||||
unlink( a );
|
||||
delete a;
|
||||
a = b;
|
||||
continue;
|
||||
}
|
||||
else if ( a->afterstart ){
|
||||
if ( *m_timer - *m_timeleft + 1 < a->base_time ) {
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( a->beforeend ){
|
||||
if ( *m_timelimit == 0 ){
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
if ( (*m_timeleft + *m_timelimit * 60.0) - *m_timer - 1 >
|
||||
a->base_time ){
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ( a->exec_time > *m_timer ) {
|
||||
a = a->next;
|
||||
continue;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
return 0;
|
||||
CTaskMngr::CTask::CTask()
|
||||
{
|
||||
m_bFree = true;
|
||||
|
||||
m_pPlugin = NULL;
|
||||
m_iFunc = -1;
|
||||
m_iId = 0;
|
||||
m_fBase = 0.0f;
|
||||
|
||||
m_iRepeat = 0;
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
m_bInExecute = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
|
||||
m_iParamLen = 0;
|
||||
m_pParams = NULL;
|
||||
}
|
||||
|
||||
CTaskMngr::CTask* CTaskMngr::getNextTask(CTask* a) {
|
||||
if ( a->isRemoved() )
|
||||
return a->next;
|
||||
if ( a->loop || a->isToReply() ){
|
||||
a->exec_time = *m_timer + a->base_time;
|
||||
return a->next;
|
||||
}
|
||||
a->setToRemove();
|
||||
return a->next;
|
||||
}
|
||||
|
||||
|
||||
CTaskMngr::CTaskMngr() {
|
||||
head = 0;
|
||||
tail = 0;
|
||||
m_timer = 0;
|
||||
m_timelimit = 0;
|
||||
m_timeleft = 0;
|
||||
}
|
||||
|
||||
CTaskMngr::~CTaskMngr() {
|
||||
CTaskMngr::CTask::~CTask()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void CTaskMngr::clear() {
|
||||
while ( head ) {
|
||||
tail = head->next;
|
||||
delete head;
|
||||
head = tail;
|
||||
}
|
||||
}
|
||||
/*********************** CTaskMngr ***********************/
|
||||
|
||||
void CTaskMngr::registerTimers( float* timer , float* timelimit, float* timeleft ) {
|
||||
m_timer = timer;
|
||||
m_timelimit = timelimit;
|
||||
m_timeleft = timeleft;
|
||||
}
|
||||
|
||||
void CTaskMngr::registerTask( CPluginMngr::CPlugin* plugin, int func,
|
||||
int flags, int i, float base, float exec,
|
||||
int parlen , const cell* par, int repeat ){
|
||||
|
||||
CTask* a = new CTask(plugin,func,flags,i,base,exec,parlen,par,repeat );
|
||||
|
||||
if ( a == 0 ) return;
|
||||
|
||||
if ( tail )
|
||||
{
|
||||
tail->next = a;
|
||||
a->prev = tail;
|
||||
tail = a;
|
||||
}
|
||||
else {
|
||||
head = a;
|
||||
tail = a;
|
||||
}
|
||||
}
|
||||
|
||||
CTaskMngr::CTask* CTaskMngr::findTask( int id , AMX* amx )
|
||||
CTaskMngr::CTaskMngr()
|
||||
{
|
||||
for (CTask* a = head; a ; a = a->next)
|
||||
{
|
||||
if ( !a->isRemoved() && (a->getTaskId() == id) && (!amx ||
|
||||
(a->getPlugin()->getAMX() == amx)) )
|
||||
return a;
|
||||
}
|
||||
|
||||
return 0;
|
||||
m_pTmr_CurrentTime = NULL;
|
||||
m_pTmr_TimeLimit = NULL;
|
||||
m_pTmr_TimeLeft = NULL;
|
||||
}
|
||||
|
||||
void CTaskMngr::unlink(CTask* a){
|
||||
if ( a->prev ) a->prev->next = a->next;
|
||||
else head = a->next;
|
||||
if ( a->next ) a->next->prev = a->prev;
|
||||
else tail = a->prev;
|
||||
}
|
||||
|
||||
int CTaskMngr::removeTasks( int id , AMX* amx )
|
||||
CTaskMngr::~CTaskMngr()
|
||||
{
|
||||
CTask* a;
|
||||
clear();
|
||||
}
|
||||
|
||||
void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft)
|
||||
{
|
||||
m_pTmr_CurrentTime = pCurrentTime;
|
||||
m_pTmr_TimeLimit = pTimeLimit;
|
||||
m_pTmr_TimeLeft = pTimeLeft;
|
||||
}
|
||||
|
||||
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
||||
{
|
||||
// first, search for free tasks
|
||||
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
||||
|
||||
if (iter)
|
||||
{
|
||||
// found: reuse it
|
||||
iter->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||
} else {
|
||||
// not found: make a new one
|
||||
CTask *pTmp = new CTask;
|
||||
|
||||
if (!pTmp)
|
||||
return;
|
||||
|
||||
pTmp->set(pPlugin, iFunc, iFlags, iId, fBase, iParamsLen, pParams, iRepeat, *m_pTmr_CurrentTime);
|
||||
m_Tasks.put(pTmp);
|
||||
}
|
||||
}
|
||||
|
||||
int CTaskMngr::removeTasks(int iId, AMX *pAmx)
|
||||
{
|
||||
CTaskDescriptor descriptor(iId, pAmx);
|
||||
TaskListIter iter = m_Tasks.find(descriptor);
|
||||
int i = 0;
|
||||
|
||||
while ( (a = findTask(id, amx )) != 0 ) {
|
||||
a->setToRemove();
|
||||
while (iter)
|
||||
{
|
||||
iter->clear();
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int CTaskMngr::changeTasks(int iId, AMX *pAmx, float fNewBase)
|
||||
{
|
||||
CTaskDescriptor descriptor(iId, pAmx);
|
||||
TaskListIter iter = m_Tasks.find(descriptor);
|
||||
int i = 0;
|
||||
|
||||
while (iter)
|
||||
{
|
||||
iter->changeBase(fNewBase);
|
||||
iter->resetNextExecTime(*m_pTmr_CurrentTime);
|
||||
++i;
|
||||
iter = m_Tasks.find(++iter, descriptor);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
bool CTaskMngr::taskExists(int iId, AMX *pAmx)
|
||||
{
|
||||
return m_Tasks.find(CTaskDescriptor(iId, pAmx));
|
||||
}
|
||||
|
||||
void CTaskMngr::startFrame()
|
||||
{
|
||||
for (TaskListIter iter = m_Tasks.begin(); iter; ++iter)
|
||||
{
|
||||
if (iter->isFree())
|
||||
continue;
|
||||
iter->executeIfRequired(*m_pTmr_CurrentTime, *m_pTmr_TimeLimit, *m_pTmr_TimeLeft);
|
||||
}
|
||||
}
|
||||
|
||||
void CTaskMngr::clear()
|
||||
{
|
||||
m_Tasks.clear();
|
||||
}
|
||||
|
142
amxmodx/CTask.h
142
amxmodx/CTask.h
@ -32,97 +32,99 @@
|
||||
#ifndef CTASK_H
|
||||
#define CTASK_H
|
||||
|
||||
// *****************************************************
|
||||
// class CTaskMngr
|
||||
// *****************************************************
|
||||
|
||||
class CTaskMngr
|
||||
{
|
||||
public:
|
||||
|
||||
class iterator;
|
||||
|
||||
private:
|
||||
/*** class CTask ***/
|
||||
class CTask
|
||||
{
|
||||
// task settings
|
||||
|
||||
friend class iterator;
|
||||
friend class CTaskMngr;
|
||||
CPluginMngr::CPlugin *m_pPlugin;
|
||||
cell m_iId;
|
||||
int m_iFunc;
|
||||
int m_iRepeat;
|
||||
|
||||
CPluginMngr::CPlugin* plugin;
|
||||
int id;
|
||||
int func;
|
||||
int repeat;
|
||||
bool loop;
|
||||
bool afterstart;
|
||||
bool beforeend;
|
||||
float base_time;
|
||||
float exec_time;
|
||||
int param_len;
|
||||
cell* param;
|
||||
CTask* next;
|
||||
CTask* prev;
|
||||
inline void setToRemove() { exec_time = -1.0f; }
|
||||
inline bool isToReply() { return (repeat-- > 0); }
|
||||
inline bool isRemoved() { return (exec_time == -1.0f); }
|
||||
CTask( CPluginMngr::CPlugin* p, int f, int flags, int i,
|
||||
float base, float exec, int parlen , const cell* par, int r );
|
||||
~CTask() { if ( param_len ) delete[] param; }
|
||||
bool m_bInExecute;
|
||||
bool m_bLoop;
|
||||
bool m_bAfterStart;
|
||||
bool m_bBeforeEnd;
|
||||
float m_fBase; // for normal tasks, stores the interval, for the others, stores the amount of time before start / after end
|
||||
int m_iParamLen;
|
||||
|
||||
cell *m_pParams;
|
||||
bool m_bFree;
|
||||
|
||||
// execution
|
||||
float m_fNextExecTime;
|
||||
public:
|
||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||
void clear();
|
||||
bool isFree() const;
|
||||
|
||||
inline int getParamLen() { return param_len; }
|
||||
inline int getTaskId() { return id; }
|
||||
inline int getFunction() { return func; }
|
||||
cell* getParam() { return param; }
|
||||
CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline CPluginMngr::CPlugin *getPlugin() const { return m_pPlugin; }
|
||||
inline AMX *getAMX() const { return m_pPlugin->getAMX(); }
|
||||
inline int getTaskId() const { return m_iId; }
|
||||
|
||||
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
||||
|
||||
void changeBase(float fNewBase);
|
||||
void resetNextExecTime(float fCurrentTime);
|
||||
inline bool inExecute() const { return m_bInExecute; }
|
||||
|
||||
bool shouldRepeat();
|
||||
|
||||
CTask();
|
||||
~CTask();
|
||||
};
|
||||
|
||||
class CTaskDescriptor
|
||||
{
|
||||
public:
|
||||
cell m_iId;
|
||||
AMX *m_pAmx;
|
||||
bool m_bFree;
|
||||
|
||||
CTaskDescriptor(int iId, AMX *pAmx, bool bFree = false)
|
||||
{
|
||||
m_iId = iId;
|
||||
m_pAmx = pAmx;
|
||||
m_bFree = bFree;
|
||||
}
|
||||
|
||||
private:
|
||||
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
|
||||
{
|
||||
if (right.m_bFree)
|
||||
return (left.isFree() && !left.inExecute());
|
||||
|
||||
friend class iterator;
|
||||
CTask *head;
|
||||
CTask *tail;
|
||||
float* m_timer;
|
||||
float* m_timelimit;
|
||||
float* m_timeleft;
|
||||
CTask* getFirstValidTask(CTask* a);
|
||||
CTask* getNextTask(CTask* a);
|
||||
CTask* findTask( int id , AMX* amx );
|
||||
void unlink(CTask* a);
|
||||
return (!left.isFree()) &&
|
||||
(right.m_pAmx ? left.getAMX() == right.m_pAmx : true) &&
|
||||
(left.getTaskId() == right.m_iId);
|
||||
}
|
||||
};
|
||||
|
||||
/*** CTaskMngr priv members ***/
|
||||
typedef CList<CTask, CTaskDescriptor> TaskList;
|
||||
typedef TaskList::iterator TaskListIter;
|
||||
|
||||
TaskList m_Tasks;
|
||||
|
||||
float *m_pTmr_CurrentTime;
|
||||
float *m_pTmr_TimeLimit;
|
||||
float *m_pTmr_TimeLeft;
|
||||
public:
|
||||
|
||||
CTaskMngr();
|
||||
~CTaskMngr();
|
||||
|
||||
// Interface
|
||||
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, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
||||
|
||||
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
|
||||
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
|
||||
bool taskExists(int iId, AMX *pAmx);
|
||||
|
||||
void registerTimers( float* timer , float* timelimit, float* timeleft );
|
||||
void registerTask( CPluginMngr::CPlugin* plugin, int func, int flags, int i, float base, float exec, int parlen , const cell* par, int repeat );
|
||||
inline int taskExists( int id ,AMX* amx) { return findTask(id,amx ) ? 1 : 0; }
|
||||
int removeTasks( int id , AMX* amx );
|
||||
void startFrame();
|
||||
void clear();
|
||||
|
||||
class iterator {
|
||||
CTaskMngr* b;
|
||||
CTask* a;
|
||||
public:
|
||||
iterator(CTask*aa,CTaskMngr* bb) : a(aa), b(bb) {}
|
||||
iterator& operator++() {
|
||||
a = b->getNextTask( a );
|
||||
a = b->getFirstValidTask( a );
|
||||
return *this;
|
||||
}
|
||||
CTask& operator*() { return *a; }
|
||||
operator bool ( ) const { return a ? true : false; }
|
||||
};
|
||||
inline iterator begin() { return iterator(getFirstValidTask(head),this); }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif //CTASK_H
|
||||
|
@ -29,55 +29,57 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "CVault.h"
|
||||
#include "CFile.h"
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "amxmodx.h"
|
||||
#include "CVault.h"
|
||||
#include "CFile.h"
|
||||
|
||||
// *****************************************************
|
||||
// class Vault
|
||||
// *****************************************************
|
||||
bool Vault::exists( const char* k )
|
||||
{
|
||||
if ( *k == 0 ) return false;
|
||||
|
||||
return *find( k ) != 0;
|
||||
bool Vault::exists(const char* k)
|
||||
{
|
||||
if (*k == 0) return false;
|
||||
|
||||
return *find(k) != 0;
|
||||
}
|
||||
|
||||
void Vault::put( const char* k, const char* v )
|
||||
void Vault::put(const char* k, const char* v)
|
||||
{
|
||||
if ( *k == 0 ) return;
|
||||
if (*k == 0) return;
|
||||
|
||||
if ( *v == 0 )
|
||||
if (*v == 0)
|
||||
{
|
||||
remove( k );
|
||||
remove(k);
|
||||
return;
|
||||
}
|
||||
|
||||
Obj** a = find( k );
|
||||
Obj** a = find(k);
|
||||
|
||||
if ( *a )
|
||||
if (*a)
|
||||
{
|
||||
(*a)->value.set(v);
|
||||
(*a)->number = atoi( v );
|
||||
(*a)->value.assign(v);
|
||||
(*a)->number = atoi(v);
|
||||
}
|
||||
else
|
||||
*a = new Obj( k , v );
|
||||
|
||||
*a = new Obj(k, v);
|
||||
}
|
||||
|
||||
Vault::Obj::Obj( const char* k, const char* v): key(k) , value(v) , next(0) {
|
||||
Vault::Obj::Obj(const char* k, const char* v): key(k), value(v), next(0)
|
||||
{
|
||||
number = atoi(v);
|
||||
}
|
||||
|
||||
Vault::Obj** Vault::find( const char* n )
|
||||
Vault::Obj** Vault::find(const char* n)
|
||||
{
|
||||
Obj** a = &head;
|
||||
|
||||
while( *a )
|
||||
while (*a)
|
||||
{
|
||||
if ( strcmp((*a)->key.str(), n) == 0 )
|
||||
if (strcmp((*a)->key.c_str(), n) == 0)
|
||||
return a;
|
||||
|
||||
a = &(*a)->next;
|
||||
@ -87,90 +89,89 @@ Vault::Obj** Vault::find( const char* n )
|
||||
}
|
||||
|
||||
|
||||
int Vault::get_number( const char* n )
|
||||
int Vault::get_number(const char* n)
|
||||
{
|
||||
if ( *n == 0 ) return 0;
|
||||
if (*n == 0) return 0;
|
||||
|
||||
Obj* b = *find( n );
|
||||
Obj* b = *find(n);
|
||||
|
||||
if ( b == 0 ) return 0;
|
||||
if (b == 0) return 0;
|
||||
|
||||
return b->number;
|
||||
}
|
||||
|
||||
const char* Vault::get( const char* n )
|
||||
const char* Vault::get(const char* n)
|
||||
{
|
||||
if ( *n == 0 ) return "";
|
||||
if (*n == 0) return "";
|
||||
|
||||
Obj* b = *find( n );
|
||||
Obj* b = *find(n);
|
||||
|
||||
if ( b == 0 ) return "";
|
||||
if (b == 0) return "";
|
||||
|
||||
return b->value.str();
|
||||
return b->value.c_str();
|
||||
}
|
||||
|
||||
void Vault::clear()
|
||||
{
|
||||
while ( head )
|
||||
while (head)
|
||||
{
|
||||
Obj* a = head->next;
|
||||
delete head;
|
||||
head = a;
|
||||
head = a;
|
||||
}
|
||||
}
|
||||
|
||||
void Vault::remove( const char* n )
|
||||
void Vault::remove(const char* n)
|
||||
{
|
||||
Obj** b = find( n );
|
||||
Obj** b = find(n);
|
||||
|
||||
if ( *b == 0 ) return;
|
||||
if (*b == 0) return;
|
||||
|
||||
Obj* a = (*b)->next;
|
||||
delete *b;
|
||||
*b = a;
|
||||
}
|
||||
|
||||
void Vault::setSource( const char* n )
|
||||
void Vault::setSource(const char* n)
|
||||
{
|
||||
path.set(n);
|
||||
path.assign(n);
|
||||
}
|
||||
|
||||
|
||||
bool Vault::loadVault( )
|
||||
bool Vault::loadVault()
|
||||
{
|
||||
if ( path.empty() ) return false;
|
||||
if (path.empty()) return false;
|
||||
|
||||
clear();
|
||||
|
||||
File a( path.str() , "r" );
|
||||
File a(path.c_str(), "r");
|
||||
|
||||
if ( !a ) return false;
|
||||
if (!a) return false;
|
||||
|
||||
const int sz = 512;
|
||||
char value[sz+1];
|
||||
char key[sz+1];
|
||||
char value[sz + 1];
|
||||
char key[sz + 1];
|
||||
|
||||
while ( a >> key && a.skipWs() && a.getline( value , sz ) )
|
||||
while (a >> key && a.skipWs() && a.getline(value, sz))
|
||||
{
|
||||
if ( isalpha ( *key ) )
|
||||
put( key, value );
|
||||
if (isalpha(*key))
|
||||
put(key, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool Vault::saveVault( )
|
||||
bool Vault::saveVault()
|
||||
{
|
||||
if ( path.empty() ) return false;
|
||||
if (path.empty()) return false;
|
||||
|
||||
File a( path.str() , "w" );
|
||||
File a(path.c_str(), "w");
|
||||
|
||||
if ( !a ) return false;
|
||||
if (!a) return false;
|
||||
|
||||
a << "; Don't modify!" << '\n';
|
||||
|
||||
for (Obj* b = head; b ;b = b->next)
|
||||
for (Obj* b = head; b; b = b->next)
|
||||
a << b->key << '\t' << b->value << '\n';
|
||||
|
||||
return true;
|
||||
|
@ -41,53 +41,55 @@
|
||||
|
||||
class Vault
|
||||
{
|
||||
struct Obj
|
||||
{
|
||||
String key;
|
||||
String value;
|
||||
int number;
|
||||
Obj *next;
|
||||
Obj( const char* k, const char* v);
|
||||
} *head;
|
||||
struct Obj
|
||||
{
|
||||
String key;
|
||||
String value;
|
||||
|
||||
String path;
|
||||
int number;
|
||||
Obj *next;
|
||||
Obj(const char* k, const char* v);
|
||||
} *head;
|
||||
|
||||
Obj** find( const char* n );
|
||||
String path;
|
||||
|
||||
Obj** find(const char* n);
|
||||
|
||||
public:
|
||||
|
||||
Vault() {head=0;}
|
||||
~Vault() { clear();}
|
||||
Vault() { head = 0; }
|
||||
~Vault() { clear(); }
|
||||
|
||||
// Interface
|
||||
|
||||
bool exists( const char* k );
|
||||
void put(const char* k, const char* v);
|
||||
void remove( const char* k );
|
||||
const char* get( const char* n );
|
||||
int get_number( const char* n );
|
||||
void setSource( const char* n );
|
||||
bool loadVault( );
|
||||
bool saveVault( );
|
||||
void clear();
|
||||
bool exists(const char* k);
|
||||
|
||||
void put(const char* k, const char* v);
|
||||
void remove(const char* k);
|
||||
|
||||
class iterator {
|
||||
Obj * a;
|
||||
public:
|
||||
iterator(Obj*aa) : a(aa) {}
|
||||
iterator& operator++() { if ( a ) a = a->next; return *this; }
|
||||
bool operator==(const iterator& b) const { return a == b.a; }
|
||||
bool operator!=(const iterator& b) const { return !operator==(b); }
|
||||
String& key() const { return a->key; }
|
||||
String& value() const { return a->value; }
|
||||
};
|
||||
const char* get(const char* n);
|
||||
int get_number(const char* n);
|
||||
void setSource(const char* n);
|
||||
|
||||
inline iterator begin() const { return iterator(head); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
bool loadVault();
|
||||
bool saveVault();
|
||||
|
||||
void clear();
|
||||
|
||||
class iterator
|
||||
{
|
||||
Obj * a;
|
||||
public:
|
||||
iterator(Obj* aa) : a(aa) {}
|
||||
iterator& operator++() { if (a) a = a->next; return *this; }
|
||||
bool operator==(const iterator& b) const { return a == b.a; }
|
||||
bool operator!=(const iterator& b) const { return !operator==(b); }
|
||||
String& key() const { return a->key; }
|
||||
String& value() const { return a->value; }
|
||||
};
|
||||
|
||||
inline iterator begin() const { return iterator(head); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif //VAULT_CUSTOM_H
|
||||
|
491
amxmodx/CVector.h
Executable file
491
amxmodx/CVector.h
Executable file
@ -0,0 +1,491 @@
|
||||
/* 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 __CVECTOR_H__
|
||||
#define __CVECTOR_H__
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// Vector
|
||||
template <class T> class CVector
|
||||
{
|
||||
bool Grow()
|
||||
{
|
||||
// automatic grow
|
||||
size_t newSize = m_Size * 2;
|
||||
if (newSize == 0)
|
||||
newSize = 8; // a good init value
|
||||
T *newData = new T[newSize];
|
||||
if (!newData)
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
for (size_t i=0; i<m_CurrentUsedSize; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
m_Size = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrowIfNeeded()
|
||||
{
|
||||
if (m_CurrentUsedSize >= m_Size)
|
||||
return Grow();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChangeSize(size_t size)
|
||||
{
|
||||
// change size
|
||||
if (size == m_Size)
|
||||
return true;
|
||||
|
||||
if (!size)
|
||||
{
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
m_Size = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
T *newData = new T[size];
|
||||
if (!newData)
|
||||
return false;
|
||||
if (m_Data)
|
||||
{
|
||||
size_t end = (m_CurrentUsedSize < size) ? (m_CurrentUsedSize) : size;
|
||||
for (size_t i=0; i<end; i++)
|
||||
newData[i] = m_Data[i];
|
||||
delete [] m_Data;
|
||||
}
|
||||
m_Data = newData;
|
||||
m_Size = size;
|
||||
if (m_CurrentUsedSize > m_Size)
|
||||
m_CurrentUsedSize = m_Size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FreeMemIfPossible()
|
||||
{
|
||||
if (!m_Data)
|
||||
return;
|
||||
|
||||
if (!m_CurrentUsedSize)
|
||||
{
|
||||
ChangeSize(0);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t newSize = m_Size;
|
||||
while (m_CurrentUsedSize <= newSize / 2)
|
||||
newSize /= 2;
|
||||
|
||||
if (newSize != m_Size)
|
||||
ChangeSize(newSize);
|
||||
}
|
||||
protected:
|
||||
T *m_Data;
|
||||
size_t m_Size;
|
||||
size_t m_CurrentUsedSize;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
protected:
|
||||
T *m_Ptr;
|
||||
public:
|
||||
// constructors / destructors
|
||||
iterator()
|
||||
{
|
||||
m_Ptr = NULL;
|
||||
}
|
||||
|
||||
iterator(T * ptr)
|
||||
{
|
||||
m_Ptr = ptr;
|
||||
}
|
||||
|
||||
// member functions
|
||||
T * base()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
const T * base() const
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
// operators
|
||||
T & operator*()
|
||||
{
|
||||
return *m_Ptr;
|
||||
}
|
||||
|
||||
T * operator->()
|
||||
{
|
||||
return m_Ptr;
|
||||
}
|
||||
|
||||
iterator & operator++() // preincrement
|
||||
{
|
||||
++m_Ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator++(int) // postincrement
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++m_Ptr;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator & operator--() // predecrement
|
||||
{
|
||||
--m_Ptr;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator--(int) // postdecrememnt
|
||||
{
|
||||
iterator tmp = *this;
|
||||
--m_Ptr;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(T * right) const
|
||||
{
|
||||
return (m_Ptr == right);
|
||||
}
|
||||
|
||||
bool operator==(const iterator & right) const
|
||||
{
|
||||
return (m_Ptr == right.m_Ptr);
|
||||
}
|
||||
|
||||
bool operator!=(T * right) const
|
||||
{
|
||||
return (m_Ptr != right);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator & right) const
|
||||
{
|
||||
return (m_Ptr != right.m_Ptr);
|
||||
}
|
||||
|
||||
iterator & operator+=(size_t offset)
|
||||
{
|
||||
m_Ptr += offset;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator & operator-=(size_t offset)
|
||||
{
|
||||
m_Ptr -= offset;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator+(size_t offset) const
|
||||
{
|
||||
iterator tmp(*this);
|
||||
tmp.m_Ptr += offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator operator-(size_t offset) const
|
||||
{
|
||||
iterator tmp(*this);
|
||||
tmp.m_Ptr -= offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
T & operator[](size_t offset)
|
||||
{
|
||||
return (*(*this + offset));
|
||||
}
|
||||
|
||||
const T & operator[](size_t offset) const
|
||||
{
|
||||
return (*(*this + offset));
|
||||
}
|
||||
|
||||
bool operator<(const iterator & right) const
|
||||
{
|
||||
return m_Ptr < right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator>(const iterator & right) const
|
||||
{
|
||||
return m_Ptr > right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator<=(const iterator & right) const
|
||||
{
|
||||
return m_Ptr <= right.m_Ptr;
|
||||
}
|
||||
|
||||
bool operator>=(const iterator & right) const
|
||||
{
|
||||
return m_Ptr >= right.m_Ptr;
|
||||
}
|
||||
|
||||
size_t operator-(const iterator & right) const
|
||||
{
|
||||
return m_Ptr - right.m_Ptr;
|
||||
}
|
||||
};
|
||||
|
||||
// constructors / destructors
|
||||
CVector<T>()
|
||||
{
|
||||
m_Size = 0;
|
||||
m_CurrentUsedSize = 0;
|
||||
m_Data = NULL;
|
||||
}
|
||||
|
||||
CVector<T>(const CVector<T> & other)
|
||||
{
|
||||
// copy data
|
||||
m_Data = new T [other.m_CurrentUsedSize];
|
||||
m_Size = other.m_CurrentUsedSize;
|
||||
m_CurrentUsedSize = other.m_CurrentUsedSize;
|
||||
for (size_t i=0; i<other.m_CurrentUsedSize; i++)
|
||||
m_Data[i] = other.m_Data[i];
|
||||
}
|
||||
|
||||
~CVector<T>()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
// interface
|
||||
size_t size() const
|
||||
{
|
||||
return m_CurrentUsedSize;
|
||||
}
|
||||
|
||||
size_t capacity() const
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Data);
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Data + m_CurrentUsedSize);
|
||||
}
|
||||
|
||||
iterator iterAt(size_t pos)
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
assert(0);
|
||||
return iterator(m_Data + pos);
|
||||
}
|
||||
|
||||
bool reserve(size_t newSize)
|
||||
{
|
||||
if (newSize > m_Size)
|
||||
return ChangeSize(newSize);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool push_back(const T & elem)
|
||||
{
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data[m_CurrentUsedSize - 1] = elem;
|
||||
return true;
|
||||
}
|
||||
|
||||
void pop_back()
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
if (m_CurrentUsedSize < 0)
|
||||
m_CurrentUsedSize = 0;
|
||||
|
||||
FreeMemIfPossible();
|
||||
}
|
||||
|
||||
bool resize(size_t newSize)
|
||||
{
|
||||
if (!ChangeSize(newSize))
|
||||
return false;
|
||||
m_CurrentUsedSize = newSize;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return (m_CurrentUsedSize == 0);
|
||||
}
|
||||
|
||||
T & at(size_t pos)
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[pos];
|
||||
}
|
||||
|
||||
const T & at(size_t pos) const
|
||||
{
|
||||
if (pos > m_CurrentUsedSize)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[pos];
|
||||
}
|
||||
|
||||
T & operator[](size_t pos)
|
||||
{
|
||||
return at(pos);
|
||||
}
|
||||
|
||||
const T & operator[](size_t pos) const
|
||||
{
|
||||
return at(pos);
|
||||
}
|
||||
|
||||
T & front()
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[0];
|
||||
}
|
||||
|
||||
const T & front() const
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[0];
|
||||
}
|
||||
|
||||
T & back()
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[m_CurrentUsedSize - 1];
|
||||
}
|
||||
|
||||
const T & back() const
|
||||
{
|
||||
if (m_CurrentUsedSize < 1)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
return m_Data[m_CurrentUsedSize - 1];
|
||||
}
|
||||
|
||||
iterator insert(iterator where, const T & value)
|
||||
{
|
||||
// validate iter
|
||||
if (where < m_Data || where > (m_Data + m_CurrentUsedSize))
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
where = begin() + ofs;
|
||||
|
||||
// Move subsequent entries
|
||||
for (T *ptr = m_Data + m_CurrentUsedSize - 2; ptr >= where.base(); --ptr)
|
||||
*(ptr + 1) = *ptr;
|
||||
|
||||
*where.base() = value;
|
||||
|
||||
return where;
|
||||
}
|
||||
|
||||
iterator erase(iterator where)
|
||||
{
|
||||
// validate iter
|
||||
if (where < m_Data || where >= (m_Data + m_CurrentUsedSize))
|
||||
return iterator(0);
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
if (m_CurrentUsedSize > 1)
|
||||
{
|
||||
// move
|
||||
T *theend = m_Data + m_CurrentUsedSize;
|
||||
for (T *ptr = where.base() + 1; ptr < theend; ++ptr)
|
||||
*(ptr - 1) = *ptr;
|
||||
}
|
||||
|
||||
--m_CurrentUsedSize;
|
||||
|
||||
FreeMemIfPossible();
|
||||
|
||||
return begin() + ofs;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
m_Size = 0;
|
||||
m_CurrentUsedSize = 0;
|
||||
if (m_Data)
|
||||
{
|
||||
delete [] m_Data;
|
||||
m_Data = NULL;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __CVECTOR_H__
|
||||
|
BIN
amxmodx/JIT/amxexecn.o
Executable file
BIN
amxmodx/JIT/amxexecn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxexecn.obj
Executable file
BIN
amxmodx/JIT/amxexecn.obj
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.o
Executable file
BIN
amxmodx/JIT/amxjitsn.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
BIN
amxmodx/JIT/amxjitsn.obj
Executable file
Binary file not shown.
BIN
amxmodx/JIT/helpers-x86.o
Normal file
BIN
amxmodx/JIT/helpers-x86.o
Normal file
Binary file not shown.
BIN
amxmodx/JIT/helpers-x86.obj
Normal file
BIN
amxmodx/JIT/helpers-x86.obj
Normal file
Binary file not shown.
BIN
amxmodx/JIT/natives-amd64.o
Executable file
BIN
amxmodx/JIT/natives-amd64.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/natives-x86.o
Executable file
BIN
amxmodx/JIT/natives-x86.o
Executable file
Binary file not shown.
BIN
amxmodx/JIT/natives-x86.obj
Executable file
BIN
amxmodx/JIT/natives-x86.obj
Executable file
Binary file not shown.
171
amxmodx/Makefile
171
amxmodx/Makefile
@ -1,116 +1,111 @@
|
||||
MODNAME = amx_mm
|
||||
SRCFILES = meta_api.cpp CFile.cpp CString.cpp CVault.cpp vault.cpp\
|
||||
float.cpp file.cpp modules.cpp CMisc.cpp CTask.cpp string.cpp\
|
||||
amxmod.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp srvcmd.cpp strptime.cpp\
|
||||
CForward.cpp CPlugin.cpp CModule.cpp CMenu.cpp emsg.cpp util.cpp
|
||||
CSRCFILES = amx.c amxcore.c amxtime.c power.c
|
||||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
EXTRA_LIBS_LINUX =
|
||||
EXTRA_LIBS_WIN32 =
|
||||
EXTRA_LIBDIRS_LINUX = -Lextra/lib_linux
|
||||
EXTRA_LIBDIRS_WIN32 = -Lextra/lib_win32
|
||||
HLSDK = ../hlsdk/SourceCode
|
||||
MM_ROOT = ../metamod/metamod
|
||||
|
||||
EXTRA_INCLUDEDIRS = -Iextra/include
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
|
||||
EXTRA_FLAGS = -Dstrcmpi=strcasecmp
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -fomit-frame-pointer -pipe
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = amxmodx
|
||||
|
||||
SDKTOP=../hlsdk
|
||||
METADIR=../metamodx
|
||||
BIN_SUFFIX_32 = mm_i386.so
|
||||
BIN_SUFFIX_64 = mm_amd64.so
|
||||
|
||||
OBJECTS = meta_api.cpp CFile.cpp CVault.cpp vault.cpp float.cpp file.cpp modules.cpp \
|
||||
CMisc.cpp CTask.cpp string.cpp amxmodx.cpp CEvent.cpp CCmd.cpp CLogEvent.cpp \
|
||||
srvcmd.cpp strptime.cpp amxcore.cpp amxtime.cpp power.cpp amxxlog.cpp fakemeta.cpp \
|
||||
amxxfile.cpp CLang.cpp md5.cpp emsg.cpp CForward.cpp CPlugin.cpp CModule.cpp \
|
||||
CMenu.cpp util.cpp amx.cpp amxdbg.cpp natives.cpp newmenus.cpp debugger.cpp \
|
||||
optimizer.cpp format.cpp messages.cpp libraries.cpp vector.cpp
|
||||
|
||||
SDKSRC=$(SDKTOP)/SourceCode
|
||||
OBJDIR_LINUX=obj.linux
|
||||
OBJDIR_WIN32=obj.win32
|
||||
SRCDIR=.
|
||||
LINK = /lib/libstdc++.a
|
||||
|
||||
ifdef windir
|
||||
OS=WIN32
|
||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared -I$(HLSDK)/game_shared \
|
||||
-I$(MM_ROOT) -Lzlib -I$(HLSDK)/common
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
else
|
||||
OS=LINUX
|
||||
BIN_DIR = Release
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CC_LINUX=gcc
|
||||
ifeq "$(OS)" "WIN32"
|
||||
CC_WIN32=gcc
|
||||
LD_WINDLL=dllwrap
|
||||
DEFAULT=win32
|
||||
CLEAN=clean_win32
|
||||
else
|
||||
CC_WIN32=/usr/local/cross-tools/i386-mingw32msvc/bin/gcc
|
||||
LD_WINDLL=/usr/local/cross-tools/bin/i386-mingw32msvc-dllwrap
|
||||
DEFAULT=linux win32
|
||||
CLEAN=clean_both
|
||||
ifeq "$(BINLOG)" "true"
|
||||
NAME := $(NAME)_bl
|
||||
BIN_DIR := $(BIN_DIR)BinLog
|
||||
OBJECTS += binlog.cpp
|
||||
CFLAGS += -DBINLOG_ENABLED
|
||||
endif
|
||||
|
||||
CFLAGS += -DLINUX -DNDEBUG -fPIC -Wno-deprecated -DHAVE_STDINT_H -static-libgcc -fno-rtti -fno-exceptions
|
||||
|
||||
|
||||
LIBFILE_LINUX = $(MODNAME)_i386.so
|
||||
LIBFILE_WIN32 = $(MODNAME).dll
|
||||
TARGET_LINUX = $(OBJDIR_LINUX)/$(LIBFILE_LINUX)
|
||||
TARGET_WIN32 = $(OBJDIR_WIN32)/$(LIBFILE_WIN32)
|
||||
|
||||
FILES_ALL = *.cpp *.h [A-Z]* *.rc
|
||||
ifeq "$(OS)" "LINUX"
|
||||
ASRCFILES := $(shell ls -t $(SRCFILES))
|
||||
ifeq "$(AMD64)" "true"
|
||||
BINARY = $(NAME)_$(BIN_SUFFIX_64)
|
||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -DAMD64 -m64
|
||||
LINK += -lz64
|
||||
OBJECTS += JIT/natives-amd64.o
|
||||
else
|
||||
ASRCFILES := $(shell dir /b)
|
||||
BINARY = $(NAME)_$(BIN_SUFFIX_32)
|
||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
||||
OBJECTS += JIT/helpers-x86.o
|
||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||
LINK += -lz
|
||||
OPT_FLAGS += -march=i586
|
||||
endif
|
||||
OBJ_LINUX := $(SRCFILES:%.cpp=$(OBJDIR_LINUX)/%.o)
|
||||
OBJC_LINUX := $(CSRCFILES:%.c=$(OBJDIR_LINUX)/%.o)
|
||||
OBJ_WIN32 := $(SRCFILES:%.cpp=$(OBJDIR_WIN32)/%.o)
|
||||
OBJC_WIN32 := $(CSRCFILES:%.c=$(OBJDIR_WIN32)/%.o)
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
CCOPT = -march=i586 -O6 -ffast-math -funroll-loops \
|
||||
-fomit-frame-pointer -fexpensive-optimizations -malign-loops=2 \
|
||||
-malign-jumps=2 -malign-functions=2 -s -DNDEBUG
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
||||
|
||||
INCLUDEDIRS=-I../curl/include -I$(SRCDIR) -I$(METADIR) -I$(SDKSRC)/engine -I$(SDKSRC)/common -I$(SDKSRC)/pm_shared -I$(SDKSRC)/dlls -I$(SDKSRC) $(EXTRA_INCLUDEDIRS)
|
||||
CFLAGS=-Wall -Wno-unknown-pragmas
|
||||
ODEF = -DOPT_TYPE=\"optimized\"
|
||||
CFLAGS:=$(CCOPT) $(CFLAGS) $(ODEF) $(EXTRA_FLAGS)
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(MAKE) amxmodx
|
||||
|
||||
DO_CC_LINUX=$(CC_LINUX) $(CFLAGS) -fPIC $(INCLUDEDIRS) -o $@ -c $<
|
||||
DO_CC_WIN32=$(CC_WIN32) $(CFLAGS) $(INCLUDEDIRS) -o $@ -c $<
|
||||
LINK_LINUX=$(CC_LINUX) $(CFLAGS) -lstdc++ -shared -ldl -lm $(OBJ_LINUX) $(OBJC_LINUX) $(EXTRA_LIBDIRS_LINUX) $(EXTRA_LIBS_LINUX) -o $@
|
||||
LINK_WIN32=$(LD_WINDLL) -mwindows --def $(MODNAME).def --add-stdcall-alias $(OBJ_WIN32) $(OBJC_WIN32) $(EXTRA_LIBDIRS_WIN32) $(EXTRA_LIBS_WIN32) -o $@
|
||||
amd64:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true
|
||||
|
||||
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.c
|
||||
$(DO_CC_LINUX)
|
||||
amd64_debug:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true DEBUG=true
|
||||
|
||||
$(OBJDIR_LINUX)/%.o: $(SRCDIR)/%.cpp
|
||||
$(DO_CC_LINUX)
|
||||
amd64_binlog:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true BINLOG=true
|
||||
|
||||
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.c
|
||||
$(DO_CC_WIN32)
|
||||
amd64_binlog_debug:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true BINLOG=true DEBUG=true
|
||||
|
||||
$(OBJDIR_WIN32)/%.o: $(SRCDIR)/%.cpp
|
||||
$(DO_CC_WIN32)
|
||||
binlog:
|
||||
$(MAKE) all BINLOG=true
|
||||
|
||||
default: $(DEFAULT)
|
||||
binlog_debug:
|
||||
$(MAKE) all BINLOG=true DEBUG=true
|
||||
|
||||
$(TARGET_LINUX): $(OBJDIR_LINUX) $(OBJ_LINUX) $(OBJC_LINUX)
|
||||
$(LINK_LINUX)
|
||||
amxmodx: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
|
||||
$(TARGET_WIN32): $(OBJDIR_WIN32) $(OBJ_WIN32) $(OBJC_WIN32)
|
||||
$(LINK_WIN32)
|
||||
debug:
|
||||
$(MAKE) all DEBUG=true
|
||||
|
||||
$(OBJDIR_LINUX):
|
||||
mkdir $@
|
||||
|
||||
$(OBJDIR_WIN32):
|
||||
mkdir $@
|
||||
|
||||
win32: $(TARGET_WIN32)
|
||||
|
||||
linux: $(TARGET_LINUX)
|
||||
|
||||
clean: $(CLEAN)
|
||||
|
||||
clean_both:
|
||||
-rm -f $(OBJDIR_LINUX)/*
|
||||
-rm -f $(OBJDIR_WIN32)/*
|
||||
|
||||
clean_win32:
|
||||
del /q $(OBJDIR_WIN32)
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX_32)
|
||||
rm -rf Release/$(NAME)_$(BIN_SUFFIX_64)
|
||||
rm -rf ReleaseBinLog/*.o
|
||||
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
|
||||
rm -rf ReleaseBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_32)
|
||||
rm -rf Debug/$(NAME)_$(BIN_SUFFIX_64)
|
||||
rm -rf DebugBinLog/*.o
|
||||
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_32)
|
||||
rm -rf DebugBinLog/$(NAME)_bl_$(BIN_SUFFIX_64)
|
||||
|
4182
amxmodx/amx.cpp
Executable file
4182
amxmodx/amx.cpp
Executable file
File diff suppressed because it is too large
Load Diff
362
amxmodx/amx.h
362
amxmodx/amx.h
@ -1,6 +1,6 @@
|
||||
/* Abstract Machine for the Small compiler
|
||||
/* Pawn Abstract Machine (for the Pawn language)
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2003
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
@ -10,40 +10,92 @@
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* PM: Whole file changed
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#define LINUX
|
||||
#if defined LINUX
|
||||
|
||||
#if defined FREEBSD && !defined __FreeBSD__
|
||||
#define __FreeBSD__
|
||||
#endif
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#include <sclinux.h>
|
||||
#endif
|
||||
#ifndef __AMX_H
|
||||
#define __AMX_H
|
||||
#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __LCC__ || defined LINUX
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
#if defined SN_TARGET_PS2
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#define AMX_H_INCLUDED
|
||||
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
|
||||
/* The ISO C99 defines the int16_t and int_32t types. If the compiler got
|
||||
* here, these types are probably undefined.
|
||||
*/
|
||||
#if defined __MACH__
|
||||
#include <ppc/types.h>
|
||||
typedef unsigned short int uint16_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#elif defined __FreeBSD__
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
typedef short int int16_t;
|
||||
typedef unsigned short int uint16_t;
|
||||
#if defined SN_TARGET_PS2
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
#else
|
||||
typedef long int int32_t;
|
||||
typedef unsigned long int uint32_t;
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#define HAVE_I64
|
||||
#elif defined __GNUC__
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
#define HAVE_I64
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#define HAVE_STDINT_H
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined __MSDOS__
|
||||
#if !defined alloca
|
||||
#define alloca(n) _alloca(n)
|
||||
#if defined _LP64 || defined WIN64 || defined _WIN64
|
||||
#if !defined __64BIT__
|
||||
#define __64BIT__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined arraysize
|
||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined PAWN_DLL
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL __stdcall
|
||||
#endif
|
||||
#if !defined AMXAPI
|
||||
#define AMXAPI __stdcall
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* calling convention for native functions */
|
||||
#if !defined AMX_NATIVE_CALL
|
||||
#define AMX_NATIVE_CALL
|
||||
@ -54,6 +106,8 @@ extern "C" {
|
||||
#define AMXAPI __stdcall
|
||||
#elif defined CDECL
|
||||
#define AMXAPI __cdecl
|
||||
#elif defined GCC_HASCLASSVISIBILITY
|
||||
#define AMXAPI __attribute__ ((visibility("default")))
|
||||
#else
|
||||
#define AMXAPI
|
||||
#endif
|
||||
@ -61,6 +115,7 @@ extern "C" {
|
||||
#if !defined AMXEXPORT
|
||||
#define AMXEXPORT
|
||||
#endif
|
||||
|
||||
/* File format version Required AMX version
|
||||
* 0 (original version) 0
|
||||
* 1 (opcodes JUMP.pri, SWITCH and CASETBL) 1
|
||||
@ -70,47 +125,75 @@ extern "C" {
|
||||
* 5 (tagnames table) 4
|
||||
* 6 (reformatted header) 6
|
||||
* 7 (name table, opcodes SYMTAG & SYSREQ.D) 7
|
||||
* 8 (opcode STMT, renewed debug interface) 8
|
||||
*/
|
||||
#define CUR_FILE_VERSION 7 /* current file version; also the current AMX version */
|
||||
#define CUR_FILE_VERSION 8 /* current file version; also the current AMX version */
|
||||
#define MIN_FILE_VERSION 6 /* lowest supported file format version for the current AMX version */
|
||||
#define MIN_AMX_VERSION 7 /* minimum AMX version needed to support the current file format */
|
||||
#if !defined CELL_TYPE
|
||||
#define CELL_TYPE
|
||||
#if defined(BIT16)
|
||||
typedef uint16_t ucell; /* only for type casting */
|
||||
typedef int16_t cell;
|
||||
#else
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
#endif
|
||||
#define MIN_AMX_VERSION 8 /* minimum AMX version needed to support the current file format */
|
||||
|
||||
#if !defined PAWN_CELL_SIZE
|
||||
#define PAWN_CELL_SIZE 32 /* by default, use 32-bit cells */
|
||||
#endif
|
||||
#if PAWN_CELL_SIZE==16
|
||||
typedef uint16_t ucell;
|
||||
typedef int16_t cell;
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
typedef uint32_t ucell;
|
||||
typedef int32_t cell;
|
||||
#define REAL float
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
typedef uint64_t ucell;
|
||||
typedef int64_t cell;
|
||||
#define REAL double
|
||||
#else
|
||||
#error Unsupported cell size (PAWN_CELL_SIZE)
|
||||
#endif
|
||||
|
||||
#define UNPACKEDMAX ((1L << (sizeof(cell)-1)*8) - 1)
|
||||
#define UNLIMITED (~1u >> 1)
|
||||
|
||||
struct tagAMX;
|
||||
typedef cell (AMX_NATIVE_CALL *AMX_NATIVE)(struct tagAMX *amx, cell *params);
|
||||
typedef int (AMXAPI *AMX_CALLBACK)(struct tagAMX *amx, cell index,
|
||||
cell *result, cell *params);
|
||||
typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
||||
#if !defined _FAR
|
||||
#define _FAR
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||
* about pragma pack in a header file */
|
||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
// MSVC8 - Replace POSIX stricmp with ISO C++ conformant one as it is deprecated
|
||||
#define stricmp _stricmp
|
||||
|
||||
// Need this because of some stupid bug
|
||||
#pragma warning (disable : 4996)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#if (defined SN_TARGET_PS2 || defined __GNUC__) && !defined AMX_NO_ALIGN
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
@ -119,22 +202,31 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
typedef struct {
|
||||
char _FAR *name PACKED;
|
||||
|
||||
typedef struct tagAMX_NATIVE_INFO {
|
||||
const char _FAR *name PACKED;
|
||||
AMX_NATIVE func PACKED;
|
||||
} AMX_NATIVE_INFO PACKED;
|
||||
} PACKED AMX_NATIVE_INFO;
|
||||
|
||||
#define AMX_USERNUM 4
|
||||
#define sEXPMAX 19 /* maximum name length for file version <= 6 */
|
||||
#define sNAMEMAX 31 /* maximum name length of symbol name */
|
||||
|
||||
typedef struct tagAMX_FUNCSTUB {
|
||||
uint32_t address PACKED;
|
||||
ucell address PACKED;
|
||||
char name[sEXPMAX+1] PACKED;
|
||||
} AMX_FUNCSTUB PACKED;
|
||||
} PACKED AMX_FUNCSTUB;
|
||||
|
||||
typedef struct tagFUNCSTUBNT {
|
||||
ucell address PACKED;
|
||||
ucell nameofs PACKED; //we need this for amxx to be backwards comaptible
|
||||
} PACKED AMX_FUNCSTUBNT;
|
||||
|
||||
/* The AMX structure is the internal structure for many functions. Not all
|
||||
* fields are valid at all times; many fields are cached in local variables.
|
||||
*/
|
||||
typedef struct tagAMX {
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header ("amxhdr") plus the code, optionally also the data */
|
||||
unsigned char _FAR *base PACKED; /* points to the AMX header plus the code, optionally also the data */
|
||||
unsigned char _FAR *data PACKED; /* points to separate data+stack+heap, may be NULL */
|
||||
AMX_CALLBACK callback PACKED;
|
||||
AMX_DEBUG debug PACKED; /* debug callback */
|
||||
@ -146,30 +238,27 @@ typedef struct tagAMX {
|
||||
cell stk PACKED; /* stack pointer: relative to base + amxhdr->dat */
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* for assertions and debug hook */
|
||||
cell curline PACKED;
|
||||
cell curfile PACKED;
|
||||
int dbgcode PACKED;
|
||||
cell dbgaddr PACKED;
|
||||
cell dbgparam PACKED;
|
||||
char _FAR *dbgname PACKED;
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
void _FAR *usertags[AMX_USERNUM] PACKED;
|
||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||
//we're also gonna set userdata[2] to a special debug structure
|
||||
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
|
||||
void _FAR *userdata[AMX_USERNUM] PACKED;
|
||||
/* native functions can raise an error */
|
||||
int error PACKED;
|
||||
/* passing parameters requires a "count" field */
|
||||
int paramcount;
|
||||
/* the sleep opcode needs to store the full AMX status */
|
||||
cell pri PACKED;
|
||||
cell alt PACKED;
|
||||
cell reset_stk PACKED;
|
||||
cell reset_hea PACKED;
|
||||
cell _FAR *syscall_d PACKED; /* relocated value/address for the SYSCALL.D opcode */
|
||||
#if defined JIT
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
#endif
|
||||
} AMX PACKED;
|
||||
cell sysreq_d PACKED; /* relocated address/value for the SYSREQ.D opcode */
|
||||
/* support variables for the JIT */
|
||||
int reloc_size PACKED; /* required temporary buffer for relocations */
|
||||
long code_size PACKED; /* estimated memory footprint of the native code */
|
||||
} PACKED AMX;
|
||||
|
||||
/* The AMX_HEADER structure is both the memory format as the file format. The
|
||||
* structure is used internaly.
|
||||
*/
|
||||
@ -190,9 +279,12 @@ typedef struct tagAMX_HEADER {
|
||||
int32_t libraries PACKED; /* offset to the table of libraries */
|
||||
int32_t pubvars PACKED; /* the "public variables" table */
|
||||
int32_t tags PACKED; /* the "public tagnames" table */
|
||||
int32_t nametable PACKED; /* name table, file version 7 only */
|
||||
} AMX_HEADER PACKED;
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
int32_t nametable PACKED; /* name table */
|
||||
} PACKED AMX_HEADER;
|
||||
|
||||
//This is always the same for us
|
||||
#define AMX_MAGIC 0xf1e0
|
||||
|
||||
enum {
|
||||
AMX_ERR_NONE,
|
||||
/* reserve the first 15 error codes for exit codes of the abstract machine */
|
||||
@ -208,6 +300,9 @@ enum {
|
||||
AMX_ERR_NATIVE, /* native function failed */
|
||||
AMX_ERR_DIVIDE, /* divide by zero */
|
||||
AMX_ERR_SLEEP, /* go into sleepmode - code can be restarted */
|
||||
AMX_ERR_INVSTATE, /* invalid state for this access */
|
||||
AMX_ERR_INVNATIVE, /* invalid native was used */
|
||||
|
||||
AMX_ERR_MEMORY = 16, /* out of memory */
|
||||
AMX_ERR_FORMAT, /* invalid file format */
|
||||
AMX_ERR_VERSION, /* file is for a newer version of the AMX */
|
||||
@ -219,92 +314,153 @@ enum {
|
||||
AMX_ERR_INIT_JIT, /* cannot initialize the JIT */
|
||||
AMX_ERR_PARAMS, /* parameter error */
|
||||
AMX_ERR_DOMAIN, /* domain error, expression result does not fit in range */
|
||||
AMX_ERR_GENERAL, /* general error (unknown or unspecific error) */
|
||||
};
|
||||
enum {
|
||||
DBG_INIT, /* query/initialize */
|
||||
DBG_FILE, /* file number in curfile, filename in name */
|
||||
DBG_LINE, /* line number in curline, file number in curfile */
|
||||
DBG_SYMBOL, /* address in dbgaddr, class/type in dbgparam */
|
||||
DBG_CLRSYM, /* stack address below which locals should be removed. stack address in stk */
|
||||
DBG_CALL, /* function call, address jumped to in dbgaddr */
|
||||
DBG_RETURN, /* function returns */
|
||||
DBG_TERMINATE, /* program ends, code address in dbgaddr, reason in dbgparam */
|
||||
DBG_SRANGE, /* symbol size and dimensions (arrays); level in dbgaddr (!); length in dbgparam */
|
||||
DBG_SYMTAG, /* tag of the most recent symbol (if non-zero), tag in dbgparam */
|
||||
};
|
||||
#define AMX_FLAG_CHAR16 0x01 /* characters are 16-bit */
|
||||
|
||||
/* AMX_FLAG_CHAR16 0x01 no longer used */
|
||||
#define AMX_FLAG_DEBUG 0x02 /* symbolic info. available */
|
||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||
#define AMX_FLAG_BIGENDIAN 0x08 /* big endian encoding */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* browsing/relocating or executing */
|
||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||
#define AMX_FLAG_PRENIT 0x100 /* pre-initialized, do not check natives */
|
||||
#define AMX_FLAG_NTVREG 0x1000 /* all native functions are registered */
|
||||
#define AMX_FLAG_JITC 0x2000 /* abstract machine is JIT compiled */
|
||||
#define AMX_FLAG_BROWSE 0x4000 /* busy browsing */
|
||||
#define AMX_FLAG_RELOC 0x8000 /* jump/call addresses relocated */
|
||||
|
||||
#define AMX_EXEC_MAIN -1 /* start at program entry point */
|
||||
#define AMX_EXEC_CONT -2 /* continue from last address */
|
||||
|
||||
#define AMX_USERTAG(a,b,c,d) ((a) | ((b)<<8) | ((long)(c)<<16) | ((long)(d)<<24))
|
||||
#define AMX_EXPANDMARGIN 64
|
||||
|
||||
#if !defined AMX_COMPACTMARGIN
|
||||
#define AMX_COMPACTMARGIN 64
|
||||
#endif
|
||||
|
||||
#define UD_FINDPLUGIN 3
|
||||
#define UD_DEBUGGER 2
|
||||
#define UD_OPCODELIST 1
|
||||
#define UD_HANDLER 0
|
||||
#define UT_NATIVE 3
|
||||
#define UT_OPTIMIZER 2
|
||||
#define UT_BROWSEHOOK 1
|
||||
#define UT_BINLOGS 0
|
||||
|
||||
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
* changing the bit pattern
|
||||
*/
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||
#define amx_StrParam(amx,param,result) { \
|
||||
cell *amx_cstr_; int amx_length_; \
|
||||
amx_GetAddr((amx), (param), &amx_cstr_); \
|
||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||
if (amx_length_ > 0 && \
|
||||
((result) = (char*)alloca(amx_length_ + 1)) != NULL) \
|
||||
amx_GetString((result), amx_cstr_); \
|
||||
else (result) = NULL; \
|
||||
}
|
||||
#if PAWN_CELL_SIZE==32
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((float*)&c) ) /* cell to float */
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
#define amx_ftoc(f) ( * ((cell*)&f) ) /* float to cell */
|
||||
#define amx_ctof(c) ( * ((double*)&c) ) /* cell to float */
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_StrParam(amx,param,result) \
|
||||
do { \
|
||||
cell *amx_cstr_; int amx_length_; \
|
||||
amx_GetAddr((amx), (param), &amx_cstr_); \
|
||||
amx_StrLen(amx_cstr_, &amx_length_); \
|
||||
if (amx_length_ > 0 && \
|
||||
((result) = (void*)alloca((amx_length_ + 1) * sizeof(*(result)))) != NULL) \
|
||||
amx_GetString((char*)(result), amx_cstr_, sizeof(*(result))>1, amx_length_); \
|
||||
else (result) = NULL; \
|
||||
} while (0)
|
||||
|
||||
uint16_t * AMXAPI amx_Align16(uint16_t *v);
|
||||
uint32_t * AMXAPI amx_Align32(uint32_t *v);
|
||||
#if defined _I64_MAX || defined HAVE_I64
|
||||
uint64_t * AMXAPI amx_Align64(uint64_t *v);
|
||||
#endif
|
||||
int AMXAPI amx_Allot(AMX *amx, int cells, cell *amx_addr, cell **phys_addr);
|
||||
int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params);
|
||||
int AMXAPI amx_CheckNatives(AMX *amx, AMX_NATIVE_FILTER nf);
|
||||
int AMXAPI amx_Cleanup(AMX *amx);
|
||||
int AMXAPI amx_Clone(AMX *amxClone, AMX *amxSource, void *data);
|
||||
int AMXAPI amx_Debug(AMX *amx); /* default debug procedure, does nothing */
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index, int numparams, ...);
|
||||
int AMXAPI amx_Execv(AMX *amx, cell *retval, int index, int numparams, cell params[]);
|
||||
int AMXAPI amx_FindNative(AMX *amx, char *name, int *index);
|
||||
int AMXAPI amx_FindPublic(AMX *amx, char *funcname, int *index);
|
||||
int AMXAPI amx_FindPubVar(AMX *amx, char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_Exec(AMX *amx, cell *retval, int index);
|
||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index);
|
||||
int AMXAPI amx_FindPublic(AMX *amx, const char *funcname, int *index);
|
||||
int AMXAPI amx_FindPubVar(AMX *amx, const char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname);
|
||||
int AMXAPI amx_Flags(AMX *amx,uint16_t *flags);
|
||||
int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr);
|
||||
int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPublic(AMX *amx, int index, char *funcname);
|
||||
int AMXAPI amx_GetPubVar(AMX *amx, int index, char *varname, cell *amx_addr);
|
||||
int AMXAPI amx_GetString(char *dest,cell *source);
|
||||
int AMXAPI amx_GetString(char *dest,const cell *source, int use_wchar, size_t size);
|
||||
int AMXAPI amx_GetTag(AMX *amx, int index, char *tagname, cell *tag_id);
|
||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr);
|
||||
int AMXAPI amx_Init(AMX *amx, void *program);
|
||||
int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code);
|
||||
int AMXAPI amx_MemInfo(AMX *amx, long *codesize, long *datasize, long *stackheap);
|
||||
int AMXAPI amx_NameLength(AMX *amx, int *length);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(char *name,AMX_NATIVE func);
|
||||
AMX_NATIVE_INFO * AMXAPI amx_NativeInfo(const char *name, AMX_NATIVE func);
|
||||
int AMXAPI amx_NumNatives(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPublics(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumPubVars(AMX *amx, int *number);
|
||||
int AMXAPI amx_NumTags(AMX *amx, int *number);
|
||||
int AMXAPI amx_Push(AMX *amx, cell value);
|
||||
int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell array[], int numcells);
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
|
||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||
int AMXAPI amx_SetDebugHook(AMX *amx, AMX_DEBUG debug);
|
||||
int AMXAPI amx_SetString(cell *dest, char *source, int pack);
|
||||
int AMXAPI amx_SetString(cell *dest, const char *source, int pack, int use_wchar, size_t size);
|
||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr);
|
||||
char * AMXAPI amx_StrError(int errnum);
|
||||
int AMXAPI amx_StrLen(cell *cstring, int *length);
|
||||
int AMXAPI amx_StrLen(const cell *cstring, int *length);
|
||||
int AMXAPI amx_UTF8Check(const char *string, int *length);
|
||||
int AMXAPI amx_UTF8Get(const char *string, const char **endptr, cell *value);
|
||||
int AMXAPI amx_UTF8Len(const cell *cstr, int *length);
|
||||
int AMXAPI amx_UTF8Put(char *string, char **endptr, int maxchars, cell value);
|
||||
int AMXAPI amx_GetLibraries(AMX *amx);
|
||||
const char *AMXAPI amx_GetLibrary(AMX *amx, int index, char *buffer, int len);
|
||||
int AMXAPI amx_SetStringOld(cell *dest,const char *source,int pack,int use_wchar);
|
||||
int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
||||
|
||||
#if PAWN_CELL_SIZE==16
|
||||
#define amx_AlignCell(v) amx_Align16(v)
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
#define amx_AlignCell(v) amx_Align32(v)
|
||||
#elif PAWN_CELL_SIZE==64 && (defined _I64_MAX || defined HAVE_I64)
|
||||
#define amx_AlignCell(v) amx_Align64(v)
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
|
||||
#define amx_RegisterFunc(amx, name, func) \
|
||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
typedef struct tagBINLOG
|
||||
{
|
||||
void (*pfnLogNative)(AMX *amx, int native, int params);
|
||||
void (*pfnLogReturn)(AMX *amx, cell retval);
|
||||
void (*pfnLogParams)(AMX *amx, cell *params);
|
||||
} binlogfuncs_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __AMX_H */
|
||||
|
||||
#endif /* AMX_H_INCLUDED */
|
||||
|
@ -1,36 +1,74 @@
|
||||
/* Core module for the Small AMX
|
||||
/* Core module for the Pawn AMX
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 1997-2002
|
||||
* This file may be freely used. No warranties of any kind.
|
||||
* Copyright (c) ITB CompuPhase, 1997-2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#if defined _UNICODE || defined __UNICODE__ || defined UNICODE
|
||||
# if !defined UNICODE /* for Windows */
|
||||
# define UNICODE
|
||||
# endif
|
||||
# if !defined _UNICODE /* for C library */
|
||||
# define _UNICODE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include "amx.h"
|
||||
|
||||
#define NOPROPLIST
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 || defined _Windows
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
/* A few compilers do not provide the ANSI C standard "time" functions */
|
||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if defined _UNICODE
|
||||
# include <tchar.h>
|
||||
#elif !defined __T
|
||||
typedef char TCHAR;
|
||||
# define __T(string) string
|
||||
# define _tcschr strchr
|
||||
# define _tcscpy strcpy
|
||||
# define _tcsdup strdup
|
||||
# define _tcslen strlen
|
||||
#endif
|
||||
|
||||
|
||||
#define CHARBITS (8*sizeof(char))
|
||||
typedef unsigned char uchar;
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
typedef struct _property_list {
|
||||
struct _property_list *next;
|
||||
cell id;
|
||||
char *name;
|
||||
cell value;
|
||||
//??? safe AMX (owner of the property)
|
||||
} proplist;
|
||||
|
||||
static proplist proproot = { NULL };
|
||||
static proplist proproot = { NULL, 0, NULL, 0 };
|
||||
|
||||
static proplist *list_additem(proplist *root)
|
||||
{
|
||||
@ -96,17 +134,15 @@ static proplist *list_finditem(proplist *root,cell id,char *name,cell value,
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL numargs(AMX *amx, cell *params)
|
||||
{
|
||||
AMX_HEADER *hdr;
|
||||
uchar *data;
|
||||
cell bytes;
|
||||
|
||||
(void)params;
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
data=amx->base+(int)hdr->dat;
|
||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||
/* the number of bytes is on the stack, at "frm + 2*cell" */
|
||||
bytes= * (cell *)(data+(int)amx->frm+2*sizeof(cell));
|
||||
/* the number of arguments is the number of bytes divided
|
||||
@ -121,7 +157,7 @@ static cell AMX_NATIVE_CALL getarg(AMX *amx, cell *params)
|
||||
cell value;
|
||||
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
data=amx->base+(int)hdr->dat;
|
||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||
/* get the base value */
|
||||
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
|
||||
/* adjust the address in "value" in case of an array access */
|
||||
@ -138,7 +174,7 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
||||
cell value;
|
||||
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
data=amx->base+(int)hdr->dat;
|
||||
data=amx->data ? amx->data : amx->base+(int)hdr->dat;
|
||||
/* get the base value */
|
||||
value= * (cell *)(data+(int)amx->frm+((int)params[1]+3)*sizeof(cell));
|
||||
/* adjust the address in "value" in case of an array access */
|
||||
@ -151,11 +187,9 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL heapspace(AMX *amx,cell *params)
|
||||
{
|
||||
(void)params;
|
||||
return amx->stk - amx->hea;
|
||||
}
|
||||
|
||||
@ -174,191 +208,95 @@ static cell AMX_NATIVE_CALL funcidx(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
|
||||
amx_GetString(name,cstr);
|
||||
amx_GetString(name,cstr,0,UNLIMITED);
|
||||
err=amx_FindPublic(amx,name,&index);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
index=-1; /* this is not considered a fatal error */
|
||||
return index;
|
||||
}
|
||||
|
||||
int amx_StrPack(cell *dest,cell *source)
|
||||
{
|
||||
int len;
|
||||
|
||||
amx_StrLen(source,&len);
|
||||
if ((ucell)*source>UCHAR_MAX) {
|
||||
/* source string is already packed */
|
||||
while (len >= 0) {
|
||||
*dest++ = *source++;
|
||||
len-=sizeof(cell);
|
||||
} /* while */
|
||||
} else {
|
||||
/* pack string, from bottom up */
|
||||
cell c;
|
||||
int i;
|
||||
for (c=0,i=0; i<len; i++) {
|
||||
assert((*source & ~0xffL)==0);
|
||||
c=(c<<CHARBITS) | *source++;
|
||||
if (i%sizeof(cell) == sizeof(cell)-1) {
|
||||
*dest++=c;
|
||||
c=0;
|
||||
} /* if */
|
||||
} /* for */
|
||||
if (i%sizeof(cell) != 0) /* store remaining packed characters */
|
||||
*dest=c << (sizeof(cell)-i%sizeof(cell))*CHARBITS;
|
||||
else
|
||||
*dest=0; /* store full cell of zeros */
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int amx_StrUnpack(cell *dest,cell *source)
|
||||
{
|
||||
if ((ucell)*source>UCHAR_MAX) {
|
||||
/* unpack string, from top down (so string can be unpacked in place) */
|
||||
cell c;
|
||||
int i,len;
|
||||
amx_StrLen(source,&len);
|
||||
dest[len]=0;
|
||||
for (i=len-1; i>=0; i--) {
|
||||
c=source[i/sizeof(cell)] >> (sizeof(cell)-i%sizeof(cell)-1)*CHARBITS;
|
||||
dest[i]=c & UCHAR_MAX;
|
||||
} /* for */
|
||||
} else {
|
||||
/* source string is already unpacked */
|
||||
while ((*dest++ = *source++) != 0)
|
||||
/* nothing */;
|
||||
} /* if */
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL core_strlen(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cptr;
|
||||
int len = 0;
|
||||
|
||||
if (amx_GetAddr(amx,params[1],&cptr)==AMX_ERR_NONE)
|
||||
amx_StrLen(cptr,&len);
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,needed,lastaddr,err;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
needed=(len+sizeof(cell))/sizeof(cell); /* # of cells needed */
|
||||
assert(needed>0);
|
||||
lastaddr=params[1]+sizeof(cell)*needed-1;
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrPack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL strunpack(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cdest,*csrc;
|
||||
int len,err,lastaddr;
|
||||
|
||||
/* calculate number of cells needed for (packed) destination */
|
||||
amx_GetAddr(amx,params[2],&csrc);
|
||||
amx_StrLen(csrc,&len);
|
||||
assert(len>=0);
|
||||
lastaddr=params[1]+sizeof(cell)*(len+1)-1;
|
||||
if (verify_addr(amx,(cell)lastaddr)!=AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
amx_GetAddr(amx,params[1],&cdest);
|
||||
err=amx_StrUnpack(cdest,csrc);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
return amx_RaiseError(amx,err);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL swapchars(AMX *amx,cell *params)
|
||||
{
|
||||
union {
|
||||
cell c;
|
||||
#if defined BIT16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
uchar b[2];
|
||||
#else
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
uchar b[4];
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
uchar b[8];
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
} value;
|
||||
uchar t;
|
||||
|
||||
(void)amx;
|
||||
assert((size_t)params[0]==sizeof(cell));
|
||||
value.c = params[1];
|
||||
#if defined BIT16
|
||||
#if PAWN_CELL_SIZE==16
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[1];
|
||||
value.b[1] = t;
|
||||
#else
|
||||
#elif PAWN_CELL_SIZE==32
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[3];
|
||||
value.b[3] = t;
|
||||
t = value.b[1];
|
||||
value.b[1] = value.b[2];
|
||||
value.b[2] = t;
|
||||
#elif PAWN_CELL_SIZE==64
|
||||
t = value.b[0];
|
||||
value.b[0] = value.b[7];
|
||||
value.b[7] = t;
|
||||
t = value.b[1];
|
||||
value.b[1] = value.b[6];
|
||||
value.b[6] = t;
|
||||
t = value.b[2];
|
||||
value.b[2] = value.b[5];
|
||||
value.b[5] = t;
|
||||
t = value.b[3];
|
||||
value.b[3] = value.b[4];
|
||||
value.b[4] = t;
|
||||
#else
|
||||
#error Unsupported cell size
|
||||
#endif
|
||||
return value.c;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_tolower(AMX *amx,cell *params)
|
||||
{
|
||||
assert((size_t)params[0]==sizeof(cell));
|
||||
return tolower((int)params[1]);
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharLower((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
return (cell)AnsiLower((LPSTR)params[1]);
|
||||
#else
|
||||
return tolower((int)params[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_toupper(AMX *amx,cell *params)
|
||||
{
|
||||
assert((size_t)params[0]==sizeof(cell));
|
||||
return toupper((int)params[1]);
|
||||
(void)amx;
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32
|
||||
return (cell)CharUpper((LPTSTR)params[1]);
|
||||
#elif defined _Windows
|
||||
return (cell)AnsiUpper((LPSTR)params[1]);
|
||||
#else
|
||||
return toupper((int)params[1]);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_min(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] <= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
static cell AMX_NATIVE_CALL core_max(AMX *amx,cell *params)
|
||||
{
|
||||
(void)amx;
|
||||
return params[1] >= params[2] ? params[1] : params[2];
|
||||
}
|
||||
|
||||
@ -374,7 +312,7 @@ static cell AMX_NATIVE_CALL core_clamp(AMX *amx,cell *params)
|
||||
return value;
|
||||
}
|
||||
|
||||
#if !defined NOPROPLIST
|
||||
#if !defined AMX_NOPROPLIST
|
||||
static char *MakePackedString(cell *cptr)
|
||||
{
|
||||
int len;
|
||||
@ -382,10 +320,21 @@ static char *MakePackedString(cell *cptr)
|
||||
|
||||
amx_StrLen(cptr,&len);
|
||||
dest=(char *)malloc(len+sizeof(cell));
|
||||
amx_GetString(dest,cptr);
|
||||
amx_GetString(dest,cptr,0,UNLIMITED);
|
||||
return dest;
|
||||
}
|
||||
|
||||
static int verify_addr(AMX *amx,cell addr)
|
||||
{
|
||||
int err;
|
||||
cell *cdest;
|
||||
|
||||
err=amx_GetAddr(amx,addr,&cdest);
|
||||
if (err!=AMX_ERR_NONE)
|
||||
amx_RaiseError(amx,err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
{
|
||||
cell *cstr;
|
||||
@ -403,7 +352,7 @@ static cell AMX_NATIVE_CALL getproperty(AMX *amx,cell *params)
|
||||
return 0;
|
||||
} /* if */
|
||||
amx_GetAddr(amx,params[4],&cstr);
|
||||
amx_SetString(cstr,item->name,1);
|
||||
amx_SetString(cstr,item->name,1,0,UNLIMITED);
|
||||
} /* if */
|
||||
free(name);
|
||||
return (item!=NULL) ? item->value : 0;
|
||||
@ -468,12 +417,14 @@ static cell AMX_NATIVE_CALL existproperty(AMX *amx,cell *params)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NORANDOM
|
||||
/* This routine comes from the book "Inner Loops" by Rick Booth, Addison-Wesley
|
||||
* (ISBN 0-201-47960-5). This is a "multiplicative congruential random number
|
||||
* generator" that has been extended to 31-bits (the standard C version returns
|
||||
* only 15-bits).
|
||||
*/
|
||||
static unsigned long IL_StandardRandom_seed = 0L;
|
||||
#define INITIAL_SEED 0xcaa938dbL
|
||||
static unsigned long IL_StandardRandom_seed = INITIAL_SEED; /* always use a non-zero seed */
|
||||
#define IL_RMULT 1103515245L
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
@ -485,7 +436,7 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
|
||||
/* one-time initialization (or, mostly one-time) */
|
||||
#if !defined SN_TARGET_PS2 && !defined _WIN32_WCE
|
||||
if (IL_StandardRandom_seed == 0L)
|
||||
if (IL_StandardRandom_seed == INITIAL_SEED)
|
||||
IL_StandardRandom_seed=(unsigned long)time(NULL);
|
||||
#endif
|
||||
|
||||
@ -502,47 +453,37 @@ static cell AMX_NATIVE_CALL core_random(AMX *amx,cell *params)
|
||||
result %= params[1];
|
||||
return (cell)result;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
void core_Init(void)
|
||||
{
|
||||
/* reduced to a do-nothing routine */
|
||||
}
|
||||
|
||||
void core_Exit(void)
|
||||
{
|
||||
#if !defined NOPROPLIST
|
||||
while (proproot.next!=NULL)
|
||||
list_delete(&proproot,proproot.next);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
AMX_NATIVE_INFO core_Natives[] = {
|
||||
{ "numargs", numargs },
|
||||
{ "getarg", getarg },
|
||||
{ "setarg", setarg },
|
||||
{ "heapspace", heapspace },
|
||||
{ "funcidx", funcidx },
|
||||
{ "strlen", core_strlen },
|
||||
{ "strpack", strpack },
|
||||
{ "strunpack", strunpack },
|
||||
{ "swapchars", swapchars },
|
||||
{ "tolower", core_tolower },
|
||||
{ "toupper", core_toupper },
|
||||
{ "random", core_random },
|
||||
{ "min", core_min },
|
||||
{ "max", core_max },
|
||||
{ "clamp", core_clamp },
|
||||
#if !defined NOPROPLIST
|
||||
{ "getproperty", getproperty },
|
||||
{ "setproperty", setproperty },
|
||||
{ "deleteproperty",delproperty },
|
||||
{ "existproperty", existproperty },
|
||||
#endif
|
||||
{ "random", core_random },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
int AMXEXPORT amx_CoreInit(AMX *amx)
|
||||
{
|
||||
return amx_Register(amx, core_Natives, -1);
|
||||
}
|
||||
|
||||
int AMXEXPORT amx_CoreCleanup(AMX *amx)
|
||||
{
|
||||
(void)amx;
|
||||
#if !defined AMX_NOPROPLIST
|
||||
//??? delete only the properties owned by the AMX
|
||||
while (proproot.next!=NULL)
|
||||
list_delete(&proproot,proproot.next);
|
||||
#endif
|
||||
return AMX_ERR_NONE;
|
||||
}
|
498
amxmodx/amxdbg.cpp
Executable file
498
amxmodx/amxdbg.cpp
Executable file
@ -0,0 +1,498 @@
|
||||
/* Pawn debugger interface
|
||||
*
|
||||
* Support functions for debugger applications
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "osdefs.h" /* for _MAX_PATH */
|
||||
#include "amx.h"
|
||||
#include "amxdbg.h"
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg)
|
||||
{
|
||||
assert(amxdbg != NULL);
|
||||
if (amxdbg->hdr != NULL)
|
||||
free(amxdbg->hdr);
|
||||
if (amxdbg->filetbl != NULL)
|
||||
free(amxdbg->filetbl);
|
||||
if (amxdbg->symboltbl != NULL)
|
||||
free(amxdbg->symboltbl);
|
||||
if (amxdbg->tagtbl != NULL)
|
||||
free(amxdbg->tagtbl);
|
||||
if (amxdbg->automatontbl != NULL)
|
||||
free(amxdbg->automatontbl);
|
||||
if (amxdbg->statetbl != NULL)
|
||||
free(amxdbg->statetbl);
|
||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
void memread(void *dest, char **src, size_t size)
|
||||
{
|
||||
void *ptr = *src;
|
||||
memcpy(dest, ptr, size);
|
||||
*src += size;
|
||||
}
|
||||
|
||||
const char *ClipFileName(const char *inp)
|
||||
{
|
||||
static char buffer[256];
|
||||
size_t len = strlen(inp);
|
||||
const char *ptr = inp;
|
||||
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
if ((inp[i] == '\\' || inp[i] == '/') && (i != len-1))
|
||||
ptr = inp + i + 1;
|
||||
}
|
||||
strcpy(buffer, ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
//Note - I changed this function to read from memory instead.
|
||||
// -- BAILOPAN
|
||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr)
|
||||
{
|
||||
AMX_DBG_HDR dbghdr;
|
||||
unsigned char *ptr;
|
||||
int index, dim;
|
||||
AMX_DBG_SYMDIM *symdim;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
|
||||
char *addr = (char *)(dbg_addr);
|
||||
|
||||
memset(&dbghdr, 0, sizeof(AMX_DBG_HDR));
|
||||
memread(&dbghdr, &addr, sizeof(AMX_DBG_HDR));
|
||||
|
||||
//brabbby graa gragghty graaahhhh
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align32((uint32_t*)&dbghdr.size);
|
||||
amx_Align16(&dbghdr.magic);
|
||||
amx_Align16(&dbghdr.flags);
|
||||
amx_Align16(&dbghdr.files);
|
||||
amx_Align16(&dbghdr.lines);
|
||||
amx_Align16(&dbghdr.symbols);
|
||||
amx_Align16(&dbghdr.tags);
|
||||
amx_Align16(&dbghdr.automatons);
|
||||
amx_Align16(&dbghdr.states);
|
||||
#endif
|
||||
|
||||
if (dbghdr.magic != AMX_DBG_MAGIC)
|
||||
return AMX_ERR_FORMAT;
|
||||
|
||||
/* allocate all memory */
|
||||
memset(amxdbg, 0, sizeof(AMX_DBG));
|
||||
amxdbg->hdr = (AMX_DBG_HDR *)malloc((size_t)dbghdr.size);
|
||||
if (dbghdr.files > 0)
|
||||
amxdbg->filetbl = (AMX_DBG_FILE **)malloc(dbghdr.files * sizeof(AMX_DBG_FILE *));
|
||||
if (dbghdr.symbols > 0)
|
||||
amxdbg->symboltbl = (AMX_DBG_SYMBOL **)malloc(dbghdr.symbols * sizeof(AMX_DBG_SYMBOL *));
|
||||
if (dbghdr.tags > 0)
|
||||
amxdbg->tagtbl = (AMX_DBG_TAG **)malloc(dbghdr.tags * sizeof(AMX_DBG_TAG *));
|
||||
if (dbghdr.automatons > 0)
|
||||
amxdbg->automatontbl = (AMX_DBG_MACHINE **)malloc(dbghdr.automatons * sizeof(AMX_DBG_MACHINE *));
|
||||
if (dbghdr.states > 0)
|
||||
amxdbg->statetbl = (AMX_DBG_STATE **)malloc(dbghdr.states * sizeof(AMX_DBG_STATE *));
|
||||
if (amxdbg->hdr == NULL
|
||||
|| (dbghdr.files > 0 && amxdbg->filetbl == NULL)
|
||||
|| (dbghdr.symbols > 0 && amxdbg->symboltbl == NULL)
|
||||
|| (dbghdr.tags > 0 && amxdbg->tagtbl == NULL)
|
||||
|| (dbghdr.states > 0 && amxdbg->statetbl == NULL)
|
||||
|| (dbghdr.automatons > 0 && amxdbg->automatontbl == NULL))
|
||||
{
|
||||
dbg_FreeInfo(amxdbg);
|
||||
return AMX_ERR_MEMORY;
|
||||
} /* if */
|
||||
|
||||
/* load the entire symbolic information block into memory */
|
||||
memcpy(amxdbg->hdr, &dbghdr, sizeof dbghdr);
|
||||
ptr = (unsigned char *)(amxdbg->hdr + 1);
|
||||
memread(ptr, &addr, (size_t)(dbghdr.size-sizeof(dbghdr)));
|
||||
|
||||
/* file table */
|
||||
for (index = 0; index < dbghdr.files; index++) {
|
||||
assert(amxdbg->filetbl != NULL);
|
||||
amxdbg->filetbl[index] = (AMX_DBG_FILE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_AlignCell(&amxdbg->filetbl[index]->address);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_FILE); *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
//debug("Files: %d\n", amxdbg->hdr->files);
|
||||
for (index=0;index<amxdbg->hdr->files; index++)
|
||||
{
|
||||
strcpy((char *)amxdbg->filetbl[index]->name, ClipFileName(amxdbg->filetbl[index]->name));
|
||||
//debug(" [%d] %s\n", index, amxdbg->filetbl[index]->name);
|
||||
}
|
||||
|
||||
/* line table */
|
||||
amxdbg->linetbl = (AMX_DBG_LINE*)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
for (index = 0; index < dbghdr.lines; index++) {
|
||||
amx_AlignCell(&amxdbg->linetbl[index].address);
|
||||
amx_Align32((uint32_t*)&amxdbg->linetbl[index].line);
|
||||
} /* for */
|
||||
#endif
|
||||
ptr += dbghdr.lines * sizeof(AMX_DBG_LINE);
|
||||
|
||||
/* symbol table (plus index tags) */
|
||||
for (index = 0; index < dbghdr.symbols; index++) {
|
||||
assert(amxdbg->symboltbl != NULL);
|
||||
amxdbg->symboltbl[index] = (AMX_DBG_SYMBOL *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->address);
|
||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->tag);
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->codestart);
|
||||
amx_AlignCell(&amxdbg->symboltbl[index]->codeend);
|
||||
amx_Align16((uint16_t*)&amxdbg->symboltbl[index]->dim);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_SYMBOL); *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
for (dim = 0; dim < amxdbg->symboltbl[index]->dim; dim++) {
|
||||
symdim = (AMX_DBG_SYMDIM *)ptr;
|
||||
amx_Align16((uint16_t*)&symdim->tag);
|
||||
amx_AlignCell(&symdim->size);
|
||||
ptr += sizeof(AMX_DBG_SYMDIM);
|
||||
} /* for */
|
||||
} /* for */
|
||||
|
||||
/* tag name table */
|
||||
for (index = 0; index < dbghdr.tags; index++) {
|
||||
assert(amxdbg->tagtbl != NULL);
|
||||
amxdbg->tagtbl[index] = (AMX_DBG_TAG *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->tagtbl[index]->tag);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_TAG) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
/* automaton name table */
|
||||
for (index = 0; index < dbghdr.automatons; index++) {
|
||||
assert(amxdbg->automatontbl != NULL);
|
||||
amxdbg->automatontbl[index] = (AMX_DBG_MACHINE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
||||
amx_AlignCell(&amxdbg->automatontbl[index]->address);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_MACHINE) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
/* state name table */
|
||||
for (index = 0; index < dbghdr.states; index++) {
|
||||
assert(amxdbg->statetbl != NULL);
|
||||
amxdbg->statetbl[index] = (AMX_DBG_STATE *)ptr;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align16(&amxdbg->statetbl[index]->state);
|
||||
amx_Align16(&amxdbg->automatontbl[index]->automaton);
|
||||
#endif
|
||||
for (ptr = ptr + sizeof(AMX_DBG_STATE) - 1; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
ptr++; /* skip '\0' too */
|
||||
} /* for */
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(filename != NULL);
|
||||
*filename = NULL;
|
||||
/* this is a simple linear look-up; a binary search would be possible too */
|
||||
for (index = 0; index < amxdbg->hdr->files && amxdbg->filetbl[index]->address <= address; index++)
|
||||
/* nothing */;
|
||||
/* reset for overrun */
|
||||
if (--index < 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*filename = amxdbg->filetbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(line != NULL);
|
||||
*line = 0;
|
||||
/* this is a simple linear look-up; a binary search would be possible too */
|
||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address <= address; index++)
|
||||
/* nothing */;
|
||||
/* reset for overrun */
|
||||
if (--index < 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*line = (long)amxdbg->linetbl[index].line;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname)
|
||||
{
|
||||
/* dbg_LookupFunction() finds the function a code address is in. It can be
|
||||
* used for stack walking, and for stepping through a function while stepping
|
||||
* over sub-functions
|
||||
*/
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(funcname != NULL);
|
||||
*funcname = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->symbols; index++) {
|
||||
if (amxdbg->symboltbl[index]->ident == iFUNCTN
|
||||
&& amxdbg->symboltbl[index]->codestart <= address
|
||||
&& amxdbg->symboltbl[index]->codeend > address)
|
||||
break;
|
||||
} /* for */
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*funcname = amxdbg->symboltbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->tags && amxdbg->tagtbl[index]->tag != tag; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->tags)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->tagtbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->automatons && amxdbg->automatontbl[index]->automaton != automaton; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->automatons)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->automatontbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(name != NULL);
|
||||
*name = NULL;
|
||||
for (index = 0; index < amxdbg->hdr->states && amxdbg->statetbl[index]->state != state; index++)
|
||||
/* nothing */;
|
||||
if (index >= amxdbg->hdr->states)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
*name = amxdbg->statetbl[index]->name;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address)
|
||||
{
|
||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
||||
* the specified file). The address is moved up to the next "breakable" line
|
||||
* if no "breakpoint" is available on the specified line. You can use function
|
||||
* dbg_LookupLine() to find out at which precise line the breakpoint was set.
|
||||
*
|
||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
||||
* structure.
|
||||
*/
|
||||
int file, index;
|
||||
ucell bottomaddr,topaddr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(filename != NULL);
|
||||
assert(address != NULL);
|
||||
*address = 0;
|
||||
|
||||
index = 0;
|
||||
for (file = 0; file < amxdbg->hdr->files; file++) {
|
||||
/* find the (next) mathing instance of the file */
|
||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
||||
continue;
|
||||
/* get address range for the current file */
|
||||
bottomaddr = amxdbg->filetbl[file]->address;
|
||||
topaddr = (file + 1 < amxdbg->hdr->files) ? amxdbg->filetbl[file+1]->address : (ucell)(cell)-1;
|
||||
/* go to the starting address in the line table */
|
||||
while (index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < bottomaddr)
|
||||
index++;
|
||||
/* browse until the line is found or until the top address is exceeded */
|
||||
while (index < amxdbg->hdr->lines
|
||||
&& amxdbg->linetbl[index].line < line
|
||||
&& amxdbg->linetbl[index].address < topaddr)
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->lines)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
if (amxdbg->linetbl[index].line >= line)
|
||||
break;
|
||||
/* if not found (and the line table is not yet exceeded) try the next
|
||||
* instance of the same file (a file may appear twice in the file table)
|
||||
*/
|
||||
} /* for */
|
||||
|
||||
if (strcmp(amxdbg->filetbl[file]->name, filename) != 0)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
|
||||
assert(index < amxdbg->hdr->lines);
|
||||
*address = amxdbg->linetbl[index].address;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address)
|
||||
{
|
||||
/* Find a suitable "breakpoint address" close to the indicated line (and in
|
||||
* the specified file). The address is moved up to the first "breakable" line
|
||||
* in the function. You can use function dbg_LookupLine() to find out at which
|
||||
* precise line the breakpoint was set.
|
||||
*
|
||||
* The filename comparison is strict (case sensitive and path sensitive); the
|
||||
* "filename" parameter should point into the "filetbl" of the AMX_DBG
|
||||
* structure. The function name comparison is case sensitive too.
|
||||
*/
|
||||
int index, err;
|
||||
const char *tgtfile;
|
||||
ucell funcaddr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(funcname != NULL);
|
||||
assert(filename != NULL);
|
||||
assert(address != NULL);
|
||||
*address = 0;
|
||||
|
||||
index = 0;
|
||||
for ( ;; ) {
|
||||
/* find (next) matching function */
|
||||
while (index < amxdbg->hdr->symbols
|
||||
&& (amxdbg->symboltbl[index]->ident != iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, funcname) != 0))
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
/* verify that this line falls in the appropriate file */
|
||||
err = dbg_LookupFile(amxdbg, amxdbg->symboltbl[index]->address, &tgtfile);
|
||||
if (err == AMX_ERR_NONE || strcmp(filename, tgtfile) == 0)
|
||||
break;
|
||||
index++; /* line is the wrong file, search further */
|
||||
} /* for */
|
||||
|
||||
/* now find the first line in the function where we can "break" on */
|
||||
assert(index < amxdbg->hdr->symbols);
|
||||
funcaddr = amxdbg->symboltbl[index]->address;
|
||||
for (index = 0; index < amxdbg->hdr->lines && amxdbg->linetbl[index].address < funcaddr; index++)
|
||||
/* nothing */;
|
||||
|
||||
if (index >= amxdbg->hdr->lines)
|
||||
return AMX_ERR_NOTFOUND;
|
||||
*address = amxdbg->linetbl[index].address;
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym)
|
||||
{
|
||||
ucell codestart,codeend;
|
||||
int index;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(symname != NULL);
|
||||
assert(sym != NULL);
|
||||
*sym = NULL;
|
||||
|
||||
codestart = codeend = 0;
|
||||
index = 0;
|
||||
for ( ;; ) {
|
||||
/* find (next) matching variable */
|
||||
while (index < amxdbg->hdr->symbols
|
||||
&& (amxdbg->symboltbl[index]->ident == iFUNCTN || strcmp(amxdbg->symboltbl[index]->name, symname) != 0)
|
||||
&& (amxdbg->symboltbl[index]->codestart > scopeaddr || amxdbg->symboltbl[index]->codeend < scopeaddr))
|
||||
index++;
|
||||
if (index >= amxdbg->hdr->symbols)
|
||||
break;
|
||||
/* check the range, keep a pointer to the symbol with the smallest range */
|
||||
if (strcmp(amxdbg->symboltbl[index]->name, symname) == 0
|
||||
&& (codestart == 0 && codeend == 0
|
||||
|| amxdbg->symboltbl[index]->codestart >= codestart && amxdbg->symboltbl[index]->codeend <= codeend))
|
||||
{
|
||||
*sym = amxdbg->symboltbl[index];
|
||||
codestart = amxdbg->symboltbl[index]->codestart;
|
||||
codeend = amxdbg->symboltbl[index]->codeend;
|
||||
} /* if */
|
||||
index++;
|
||||
} /* for */
|
||||
|
||||
return (*sym == NULL) ? AMX_ERR_NOTFOUND : AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim)
|
||||
{
|
||||
/* retrieves a pointer to the array dimensions structures of an array symbol */
|
||||
const char *ptr;
|
||||
|
||||
assert(amxdbg != NULL);
|
||||
assert(sym != NULL);
|
||||
assert(symdim != NULL);
|
||||
*symdim = NULL;
|
||||
|
||||
if (sym->ident != iARRAY && sym->ident != iREFARRAY)
|
||||
return AMX_ERR_PARAMS;
|
||||
assert(sym->dim > 0); /* array must have at least one dimension */
|
||||
|
||||
/* find the end of the symbol name */
|
||||
for (ptr = sym->name; *ptr != '\0'; ptr++)
|
||||
/* nothing */;
|
||||
*symdim = (AMX_DBG_SYMDIM *)(ptr + 1);/* skip '\0' too */
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
172
amxmodx/amxdbg.h
Executable file
172
amxmodx/amxdbg.h
Executable file
@ -0,0 +1,172 @@
|
||||
/* Abstract Machine for the Pawn compiler, debugger support
|
||||
*
|
||||
* This file contains extra definitions that are convenient for debugger
|
||||
* support.
|
||||
*
|
||||
* Copyright (c) ITB CompuPhase, 2005
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty.
|
||||
* In no event will the authors be held liable for any damages arising from
|
||||
* the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software in
|
||||
* a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
*/
|
||||
|
||||
#ifndef AMXDBG_H_INCLUDED
|
||||
#define AMXDBG_H_INCLUDED
|
||||
|
||||
#ifndef AMX_H_INCLUDED
|
||||
#include "amx.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Some compilers do not support the #pragma align, which should be fine. Some
|
||||
* compilers give a warning on unknown #pragmas, which is not so fine...
|
||||
*/
|
||||
#if defined SN_TARGET_PS2 || defined __GNUC__
|
||||
#define AMX_NO_ALIGN
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
#else
|
||||
#pragma pack(push)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct tagAMX_DBG_HDR {
|
||||
int32_t size PACKED; /* size of the debug information chunk */
|
||||
uint16_t magic PACKED; /* signature, must be 0xf1ef */
|
||||
char file_version PACKED; /* file format version */
|
||||
char amx_version PACKED; /* required version of the AMX */
|
||||
int16_t flags PACKED; /* currently unused */
|
||||
int16_t files PACKED; /* number of entries in the "file" table */
|
||||
int16_t lines PACKED; /* number of entries in the "line" table */
|
||||
int16_t symbols PACKED; /* number of entries in the "symbol" table */
|
||||
int16_t tags PACKED; /* number of entries in the "tag" table */
|
||||
int16_t automatons PACKED; /* number of entries in the "automaton" table */
|
||||
int16_t states PACKED; /* number of entries in the "state" table */
|
||||
} AMX_DBG_HDR PACKED;
|
||||
#define AMX_DBG_MAGIC 0xf1ef
|
||||
|
||||
typedef struct tagAMX_DBG_FILE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this file) starts */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_FILE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_LINE {
|
||||
ucell address PACKED; /* address in the code segment where generated code (for this line) starts */
|
||||
int32_t line PACKED; /* line number */
|
||||
} AMX_DBG_LINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMBOL {
|
||||
ucell address PACKED; /* address in the data segment or relative to the frame */
|
||||
int16_t tag PACKED; /* tag for the symbol */
|
||||
ucell codestart PACKED; /* address in the code segment from which this symbol is valid (in scope) */
|
||||
ucell codeend PACKED; /* address in the code segment until which this symbol is valid (in scope) */
|
||||
char ident PACKED; /* kind of symbol (function/variable) */
|
||||
char vclass PACKED; /* class of symbol (global/local) */
|
||||
int16_t dim PACKED; /* number of dimensions */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_SYMBOL PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_SYMDIM {
|
||||
int16_t tag PACKED; /* tag for the array dimension */
|
||||
ucell size PACKED; /* size of the array dimension */
|
||||
} AMX_DBG_SYMDIM PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_TAG {
|
||||
int16_t tag PACKED; /* tag id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_TAG PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_MACHINE {
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
ucell address PACKED; /* address of state variable */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_MACHINE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG_STATE {
|
||||
int16_t state PACKED; /* state id */
|
||||
int16_t automaton PACKED; /* automaton id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_STATE PACKED;
|
||||
|
||||
typedef struct tagAMX_DBG {
|
||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
||||
AMX_DBG_FILE _FAR **filetbl PACKED;
|
||||
AMX_DBG_LINE _FAR *linetbl PACKED;
|
||||
AMX_DBG_SYMBOL _FAR **symboltbl PACKED;
|
||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
||||
} AMX_DBG PACKED;
|
||||
|
||||
#if !defined iVARIABLE
|
||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||
#define iREFERENCE 2 /* iVARIABLE, but must be dereferenced */
|
||||
#define iARRAY 3
|
||||
#define iREFARRAY 4 /* an array passed by reference (i.e. a pointer) */
|
||||
#define iFUNCTN 9
|
||||
#endif
|
||||
|
||||
|
||||
int AMXAPI dbg_FreeInfo(AMX_DBG *amxdbg);
|
||||
int AMXAPI dbg_LoadInfo(AMX_DBG *amxdbg, void *dbg_addr);
|
||||
|
||||
int AMXAPI dbg_LookupFile(AMX_DBG *amxdbg, ucell address, const char **filename);
|
||||
int AMXAPI dbg_LookupFunction(AMX_DBG *amxdbg, ucell address, const char **funcname);
|
||||
int AMXAPI dbg_LookupLine(AMX_DBG *amxdbg, ucell address, long *line);
|
||||
|
||||
int AMXAPI dbg_GetFunctionAddress(AMX_DBG *amxdbg, const char *funcname, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetLineAddress(AMX_DBG *amxdbg, long line, const char *filename, ucell *address);
|
||||
int AMXAPI dbg_GetAutomatonName(AMX_DBG *amxdbg, int automaton, const char **name);
|
||||
int AMXAPI dbg_GetStateName(AMX_DBG *amxdbg, int state, const char **name);
|
||||
int AMXAPI dbg_GetTagName(AMX_DBG *amxdbg, int tag, const char **name);
|
||||
int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr, const AMX_DBG_SYMBOL **sym);
|
||||
int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX_DBG_SYMDIM **symdim);
|
||||
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AMXDBG_H_INCLUDED */
|
86
amxmodx/amxdefn.asm
Executable file
86
amxmodx/amxdefn.asm
Executable file
@ -0,0 +1,86 @@
|
||||
; Definition of the AMX structure for assembler syntax (NASM)
|
||||
|
||||
struc amx_s
|
||||
_base: resd 1
|
||||
_dataseg: resd 1
|
||||
_callback: resd 1
|
||||
_debug: resd 1
|
||||
_cip: resd 1
|
||||
_frm: resd 1
|
||||
_hea: resd 1
|
||||
_hlw: resd 1
|
||||
_stk: resd 1
|
||||
_stp: resd 1
|
||||
_flags: resd 1
|
||||
_usertags: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_userdata: resd 4 ; 4 = AMX_USERNUM (#define'd in amx.h)
|
||||
_error: resd 1
|
||||
_paramcount: resd 1
|
||||
_pri: resd 1
|
||||
_alt: resd 1
|
||||
_reset_stk: resd 1
|
||||
_reset_hea: resd 1
|
||||
_syscall_d: resd 1
|
||||
%ifdef JIT
|
||||
; the two fields below are for the JIT; they do not exist in
|
||||
; the non-JIT version of the abstract machine
|
||||
_reloc_size: resd 1 ; memory block for relocations
|
||||
_code_size: resd 1 ; memory size of the native code
|
||||
%endif
|
||||
endstruc
|
||||
|
||||
struc amxhead_s
|
||||
_size: resd 1 ; size of the "file"
|
||||
_magic: resw 1 ; signature
|
||||
_file_version: resb 1; file format version
|
||||
_amx_version: resb 1 ; required version of the AMX
|
||||
_h_flags: resw 1
|
||||
_defsize: resw 1 ; size of one public/native function entry
|
||||
_cod: resd 1 ; initial value of COD - code block
|
||||
_dat: resd 1 ; initial value of DAT - data block
|
||||
_h_hea: resd 1 ; initial value of HEA - start of the heap
|
||||
_h_stp: resd 1 ; initial value of STP - stack top
|
||||
_h_cip: resd 1 ; initial value of CIP - the instruction pointer
|
||||
_publics: resd 1 ; offset to the "public functions" table
|
||||
_natives: resd 1 ; offset to the "native functions" table
|
||||
_libraries: resd 1 ; offset to the "library" table
|
||||
_pubvars: resd 1 ; offset to the "public variables" table
|
||||
_tags: resd 1 ; offset to the "public tagnames" table
|
||||
_nametable: resd 1 ; offset to the name table, file version 7 only
|
||||
endstruc
|
||||
|
||||
|
||||
AMX_ERR_NONE EQU 0
|
||||
AMX_ERR_EXIT EQU 1
|
||||
AMX_ERR_ASSERT EQU 2
|
||||
AMX_ERR_STACKERR EQU 3
|
||||
AMX_ERR_BOUNDS EQU 4
|
||||
AMX_ERR_MEMACCESS EQU 5
|
||||
AMX_ERR_INVINSTR EQU 6
|
||||
AMX_ERR_STACKLOW EQU 7
|
||||
AMX_ERR_HEAPLOW EQU 8
|
||||
AMX_ERR_CALLBACK EQU 9
|
||||
AMX_ERR_NATIVE EQU 10
|
||||
AMX_ERR_DIVIDE EQU 11 ; for catching divide errors
|
||||
AMX_ERR_SLEEP EQU 12
|
||||
|
||||
AMX_ERR_MEMORY EQU 16
|
||||
AMX_ERR_FORMAT EQU 17
|
||||
AMX_ERR_VERSION EQU 18
|
||||
AMX_ERR_NOTFOUND EQU 19
|
||||
AMX_ERR_INDEX EQU 20
|
||||
AMX_ERR_DEBUG EQU 21
|
||||
AMX_ERR_INIT EQU 22
|
||||
AMX_ERR_USERDATA EQU 23
|
||||
AMX_ERR_INIT_JIT EQU 24
|
||||
AMX_ERR_PARAMS EQU 25
|
||||
AMX_ERR_DOMAIN EQU 26
|
||||
AMX_ERR_GENERAL EQU 27
|
||||
|
||||
AMX_FLAG_DEBUG EQU 0002h ; symbolic info. available
|
||||
AMX_FLAG_COMPACT EQU 0004h
|
||||
AMX_FLAG_BYTEOPC EQU 0008h
|
||||
AMX_FLAG_NOCHECKS EQU 0010h
|
||||
AMX_FLAG_BROWSE EQU 4000h
|
||||
AMX_FLAG_RELOC EQU 8000h ; jump/call addresses relocated
|
||||
|
1763
amxmodx/amxexecn.asm
Executable file
1763
amxmodx/amxexecn.asm
Executable file
File diff suppressed because it is too large
Load Diff
2592
amxmodx/amxjitsn.asm
Executable file
2592
amxmodx/amxjitsn.asm
Executable file
File diff suppressed because it is too large
Load Diff
2445
amxmodx/amxmod.cpp
2445
amxmodx/amxmod.cpp
File diff suppressed because it is too large
Load Diff
4155
amxmodx/amxmodx.cpp
Executable file
4155
amxmodx/amxmodx.cpp
Executable file
File diff suppressed because it is too large
Load Diff
@ -29,12 +29,34 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef AMXMOD_H
|
||||
#define AMXMOD_H
|
||||
#ifndef AMXMODX_H
|
||||
#define AMXMODX_H
|
||||
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "sclinux.h"
|
||||
#endif
|
||||
#include <ctype.h> //tolower, etc
|
||||
#include "string.h"
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated
|
||||
#if _MSC_VER >= 1400
|
||||
#define unlink _unlink
|
||||
#define mkdir _mkdir
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
#include "CVector.h"
|
||||
#include "CList.h"
|
||||
#include "CQueue.h"
|
||||
#include "modules.h"
|
||||
#include "CString.h"
|
||||
#include "CList.h"
|
||||
#include "CPlugin.h"
|
||||
#include "CMisc.h"
|
||||
#include "CVault.h"
|
||||
@ -45,39 +67,51 @@
|
||||
#include "CCmd.h"
|
||||
#include "CMenu.h"
|
||||
#include "CEvent.h"
|
||||
#include "CLang.h"
|
||||
#include "fakemeta.h"
|
||||
#include "amxxlog.h"
|
||||
|
||||
#define AMX_VERSION "0.1"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
extern AMX_NATIVE_INFO power_Natives[];
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
extern AMX_NATIVE_INFO amxmod_Natives[];
|
||||
extern AMX_NATIVE_INFO file_Natives[];
|
||||
extern AMX_NATIVE_INFO float_Natives[];
|
||||
extern AMX_NATIVE_INFO string_Natives[];
|
||||
extern AMX_NATIVE_INFO vault_Natives[];
|
||||
#define AMXXLOG_Log g_log.Log
|
||||
#define AMXXLOG_Error g_log.LogError
|
||||
#define AMX_VERSION "1.75a"
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
extern AMX_NATIVE_INFO power_Natives[];
|
||||
extern AMX_NATIVE_INFO amxmodx_Natives[];
|
||||
extern AMX_NATIVE_INFO file_Natives[];
|
||||
extern AMX_NATIVE_INFO float_Natives[];
|
||||
extern AMX_NATIVE_INFO string_Natives[];
|
||||
extern AMX_NATIVE_INFO vault_Natives[];
|
||||
extern AMX_NATIVE_INFO msg_Natives[];
|
||||
extern AMX_NATIVE_INFO vector_Natives[];
|
||||
|
||||
#ifndef __linux__
|
||||
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path);
|
||||
#define DLPROC(m,func) GetProcAddress(m,func);
|
||||
#define DLFREE(m) FreeLibrary(m);
|
||||
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
|
||||
#define DLPROC(m, func) GetProcAddress(m, func)
|
||||
#define DLFREE(m) FreeLibrary(m)
|
||||
#else
|
||||
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW);
|
||||
#define DLPROC(m,func) dlsym(m,func);
|
||||
#define DLFREE(m) dlclose(m);
|
||||
#define DLLOAD(path) (DLHANDLE)dlopen(path, RTLD_NOW)
|
||||
#define DLPROC(m, func) dlsym(m, func)
|
||||
#define DLFREE(m) dlclose(m)
|
||||
#endif
|
||||
|
||||
#if defined __GNUC__
|
||||
#include <stdint.h>
|
||||
typedef intptr_t _INT_PTR;
|
||||
#else
|
||||
#if defined AMD64
|
||||
typedef __int64 _INT_PTR;
|
||||
#else
|
||||
typedef __int32 _INT_PTR;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __linux__
|
||||
typedef HINSTANCE DLHANDLE;
|
||||
typedef HINSTANCE DLHANDLE;
|
||||
#else
|
||||
typedef void* DLHANDLE;
|
||||
typedef void* DLHANDLE;
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#ifndef GETPLAYERAUTHID
|
||||
@ -93,35 +127,38 @@ typedef void* DLHANDLE;
|
||||
|
||||
char* UTIL_SplitHudMessage(register const char *src);
|
||||
int UTIL_ReadFlags(const char* c);
|
||||
void UTIL_ClientPrint( edict_t *pEntity, int msg_dest, char *msg );
|
||||
|
||||
void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg);
|
||||
void UTIL_FakeClientCommand(edict_t *pEdict, const char *cmd, const char *arg1 = NULL, const char *arg2 = NULL);
|
||||
void UTIL_GetFlags(char* flags,int flag);
|
||||
void UTIL_GetFlags(char* flags, int flag);
|
||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
|
||||
void UTIL_IntToString(int value, char *output);
|
||||
void UTIL_ShowMOTD( edict_t *client , char *motd, int mlen, const char *name);
|
||||
void UTIL_ShowMenu( edict_t* pEntity, int slots, int time, char *menu, int mlen );
|
||||
void UTIL_MakeNewLogFile();
|
||||
void UTIL_Log(const char *fmt, ...);
|
||||
void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name);
|
||||
void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen);
|
||||
|
||||
char *UTIL_VarArgs(const char *fmt, ...);
|
||||
|
||||
|
||||
#define GET_PLAYER_POINTER(e) (&g_players[ENTINDEX(e)])
|
||||
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t ))])
|
||||
//#define GET_PLAYER_POINTER(e) (&g_players[(((int)e-g_edict_point)/sizeof(edict_t))])
|
||||
#define GET_PLAYER_POINTER_I(i) (&g_players[i])
|
||||
|
||||
struct WeaponsVault {
|
||||
String fullName;
|
||||
short int iId;
|
||||
short int ammoSlot;
|
||||
struct WeaponsVault
|
||||
{
|
||||
String fullName;
|
||||
short int iId;
|
||||
short int ammoSlot;
|
||||
};
|
||||
|
||||
struct fakecmd_t {
|
||||
char args[256];
|
||||
const char *argv[3];
|
||||
//char argv[3][128];
|
||||
int argc;
|
||||
bool fake;
|
||||
struct fakecmd_t
|
||||
{
|
||||
char args[256];
|
||||
const char *argv[3];
|
||||
int argc;
|
||||
bool fake;
|
||||
};
|
||||
|
||||
|
||||
extern CLog g_log;
|
||||
extern CPluginMngr g_plugins;
|
||||
extern CTaskMngr g_tasksMngr;
|
||||
extern CPlayer g_players[33];
|
||||
@ -131,25 +168,25 @@ extern CList<CCVar> g_cvars;
|
||||
extern CList<ForceObject> g_forcemodels;
|
||||
extern CList<ForceObject> g_forcesounds;
|
||||
extern CList<ForceObject> g_forcegeneric;
|
||||
extern CList<CModule> g_modules;
|
||||
extern CList<CModule, const char *> g_modules;
|
||||
extern CList<CScript, AMX*> g_loadedscripts;
|
||||
extern CList<CPlayer*> g_auth;
|
||||
extern EventsMngr g_events;
|
||||
extern Grenades g_grenades;
|
||||
extern LogEventsMngr g_logevents;
|
||||
extern MenuMngr g_menucmds;
|
||||
extern CLangMngr g_langMngr;
|
||||
extern String g_log_dir;
|
||||
extern String g_mod_name;
|
||||
extern TeamIds g_teamsIds;
|
||||
extern Vault g_vault;
|
||||
extern CForwardMngr g_forwards;
|
||||
extern CForwardMngr g_forwards;
|
||||
extern WeaponsVault g_weaponsData[MAX_WEAPONS];
|
||||
extern XVars g_xvars;
|
||||
extern bool g_bmod_cstrike;
|
||||
extern bool g_bmod_dod;
|
||||
extern bool g_dontprecache;
|
||||
extern bool g_initialized;
|
||||
extern int g_srvindex;
|
||||
extern cvar_t* amx_version;
|
||||
extern cvar_t* amxmodx_version;
|
||||
extern cvar_t* hostname;
|
||||
extern cvar_t* mp_timelimit;
|
||||
@ -158,6 +195,7 @@ extern float g_game_restarting;
|
||||
extern float g_game_timeleft;
|
||||
extern float g_task_time;
|
||||
extern float g_auth_time;
|
||||
extern bool g_NewDLL_Available;
|
||||
extern hudtextparms_t g_hudset;
|
||||
//extern int g_edict_point;
|
||||
extern int g_players_num;
|
||||
@ -206,35 +244,100 @@ void Client_DeathMsg(void*);
|
||||
void amx_command();
|
||||
void plugin_srvcmd();
|
||||
|
||||
const char* stristr(const char* a,const char* b);
|
||||
const char* stristr(const char* a, const char* b);
|
||||
char *strptime(const char *buf, const char *fmt, struct tm *tm, short addthem);
|
||||
|
||||
int loadModules(const char* filename);
|
||||
void dettachModules();
|
||||
void dettachReloadModules();
|
||||
void attachModules();
|
||||
void attachMetaModModules( const char* filename );
|
||||
void dettachMetaModModules( const char* filename );
|
||||
int loadModules(const char* filename, PLUG_LOADTIME now);
|
||||
void detachModules();
|
||||
void detachReloadModules();
|
||||
|
||||
int add_amxnatives(module_info_s* info,AMX_NATIVE_INFO*natives);
|
||||
cell* get_amxaddr(AMX *amx,cell amx_addr);
|
||||
char* build_pathname(char *fmt, ... );
|
||||
char* format_amxstring(AMX *amx, cell *params, int parm,int& len);
|
||||
AMX* get_amxscript(int, void**,const char**);
|
||||
#ifdef FAKEMETA
|
||||
void attachModules();
|
||||
#endif
|
||||
|
||||
// Count modules
|
||||
enum CountModulesMode
|
||||
{
|
||||
CountModules_Running = 0,
|
||||
CountModules_All,
|
||||
CountModules_Stopped
|
||||
};
|
||||
|
||||
int countModules(CountModulesMode mode);
|
||||
void modules_callPluginsLoaded();
|
||||
void modules_callPluginsUnloaded();
|
||||
void modules_callPluginsUnloading();
|
||||
|
||||
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
||||
char* build_pathname(char *fmt, ...);
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||
char* format_amxstring(AMX *amx, cell *params, int parm, int& len);
|
||||
AMX* get_amxscript(int, void**, const char**);
|
||||
const char* get_amxscriptname(AMX* amx);
|
||||
char* get_amxstring(AMX *amx,cell amx_addr,int id,int& len);
|
||||
char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len);
|
||||
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
|
||||
|
||||
int amxstring_len(cell* cstr);
|
||||
int load_amxscript(AMX* amx, void** program, const char* path, char error[64]);
|
||||
int set_amxnatives(AMX* amx,char error[64]);
|
||||
int set_amxstring(AMX *amx,cell amx_addr,const char *source,int max);
|
||||
int unload_amxscript(AMX* amx,void** program);
|
||||
void copy_amxmemory(cell* dest,cell* src,int len);
|
||||
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
|
||||
int set_amxnatives(AMX* amx, char error[64]);
|
||||
int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max);
|
||||
int unload_amxscript(AMX* amx, void** program);
|
||||
|
||||
void copy_amxmemory(cell* dest, cell* src, int len);
|
||||
void get_modname(char*);
|
||||
void print_srvconsole( char *fmt, ... );
|
||||
void report_error( int code, char* fmt, ... );
|
||||
void print_srvconsole(char *fmt, ...);
|
||||
void report_error(int code, char* fmt, ...);
|
||||
void* alloc_amxmemory(void**, int size);
|
||||
void free_amxmemory(void **ptr);
|
||||
// get_localinfo
|
||||
const char* get_localinfo(const char* name, const char* def);
|
||||
cell AMX_NATIVE_CALL require_module(AMX *amx, cell *params);
|
||||
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
|
||||
enum ModuleCallReason
|
||||
{
|
||||
ModuleCall_NotCalled = 0, // nothing
|
||||
ModuleCall_Query, // in Query func
|
||||
ModuleCall_Attach, // in Attach func
|
||||
ModuleCall_Detach, // in Detach func
|
||||
};
|
||||
|
||||
#endif // AMXMOD_H
|
||||
extern ModuleCallReason g_ModuleCallReason; // modules.cpp
|
||||
extern CModule *g_CurrentlyCalledModule; // modules.cpp
|
||||
extern const char *g_LastRequestedFunc; // modules.cpp
|
||||
|
||||
void Module_CacheFunctions();
|
||||
void Module_UncacheFunctions();
|
||||
|
||||
void *Module_ReqFnptr(const char *funcName); // modules.cpp
|
||||
|
||||
// standard forwards
|
||||
// defined in meta_api.cpp
|
||||
extern int FF_ClientCommand;
|
||||
extern int FF_ClientConnect;
|
||||
extern int FF_ClientDisconnect;
|
||||
extern int FF_ClientInfoChanged;
|
||||
extern int FF_ClientPutInServer;
|
||||
extern int FF_PluginInit;
|
||||
extern int FF_PluginCfg;
|
||||
extern int FF_PluginPrecache;
|
||||
extern int FF_PluginLog;
|
||||
extern int FF_PluginEnd;
|
||||
extern int FF_InconsistentFile;
|
||||
extern int FF_ClientAuthorized;
|
||||
extern int FF_ChangeLevel;
|
||||
extern bool g_coloredmenus;
|
||||
|
||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
||||
|
||||
#define MM_CVAR2_VERS 13
|
||||
|
||||
struct func_s
|
||||
{
|
||||
void *pfn;
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
extern enginefuncs_t *g_pEngTable;
|
||||
|
||||
#endif // AMXMODX_H
|
@ -11,6 +11,20 @@
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# ifndef CLK_TCK
|
||||
# define CLK_TCK CLOCKS_PER_SEC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
@ -40,7 +54,7 @@ static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
|
||||
/* the time() function returns the number of seconds since January 1 1970
|
||||
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
|
||||
*/
|
||||
return sec1970;
|
||||
return (cell)sec1970;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
374
amxmodx/amxxfile.cpp
Executable file
374
amxmodx/amxxfile.cpp
Executable file
@ -0,0 +1,374 @@
|
||||
/* 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 "amxxfile.h"
|
||||
#include "zlib/zlib.h"
|
||||
|
||||
/**********************
|
||||
****** AMXXFILE ******
|
||||
**********************/
|
||||
|
||||
#if defined __GNUC__
|
||||
#define PACKED __attribute__((packed))
|
||||
#else
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if defined __linux__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#else
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#if defined __TURBOC__
|
||||
#pragma option -a- /* "pack" pragma for older Borland compilers */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct TableEntry
|
||||
{
|
||||
mint8_t cellSize PACKED;
|
||||
mint32_t origSize PACKED; // contains AMX_HEADER->stp
|
||||
mint32_t offset PACKED;
|
||||
};
|
||||
|
||||
#define DATAREAD(addr, itemsize, itemcount) \
|
||||
if (fread((addr), (itemsize), (itemcount), (m_pFile)) != (itemcount)) \
|
||||
{ \
|
||||
if (feof(m_pFile)) \
|
||||
m_Status = Err_FileInvalid; \
|
||||
else \
|
||||
m_Status = Err_FileRead; \
|
||||
fclose(m_pFile); \
|
||||
m_pFile = NULL; \
|
||||
return; \
|
||||
}
|
||||
|
||||
CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
{
|
||||
m_Bh.plugins = NULL;
|
||||
m_AmxxFile = false;
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
m_Status = Err_InvalidParam;
|
||||
return;
|
||||
}
|
||||
|
||||
m_Status = Err_None;
|
||||
m_CellSize = cellsize;
|
||||
m_pFile = fopen(filename, "rb");
|
||||
|
||||
if (!m_pFile)
|
||||
{
|
||||
m_Status = Err_FileOpen;
|
||||
return;
|
||||
}
|
||||
|
||||
mint32_t magic;
|
||||
DATAREAD(&magic, sizeof(magic), 1);
|
||||
|
||||
m_OldFile = false;
|
||||
|
||||
if (magic == 0x524C4542)
|
||||
{
|
||||
//we have an invalid, old, RLEB file
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
else if (magic == MAGIC_HEADER2)
|
||||
{
|
||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
||||
|
||||
if (m_Bh.version > MAGIC_VERSION)
|
||||
{
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_AmxxFile = true;
|
||||
DATAREAD(&m_Bh.numPlugins, sizeof(mint8_t), 1);
|
||||
m_Bh.plugins = new PluginEntry[m_Bh.numPlugins];
|
||||
PluginEntry *pe;
|
||||
m_SectionHdrOffset = 0;
|
||||
m_Entry = -1;
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
||||
DATAREAD(&pe->disksize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->imagesize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->memsize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->offs, sizeof(int32_t), 1);
|
||||
}
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
|
||||
if (pe->cellsize == m_CellSize)
|
||||
{
|
||||
m_Entry = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Entry == -1)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pe = &(m_Bh.plugins[m_Entry]);
|
||||
m_SectionLength = pe->disksize;
|
||||
}
|
||||
else if (magic == MAGIC_HEADER)
|
||||
{
|
||||
// try to find the section
|
||||
mint8_t numOfPlugins;
|
||||
DATAREAD(&numOfPlugins, sizeof(numOfPlugins), 1);
|
||||
|
||||
TableEntry entry;
|
||||
|
||||
m_SectionHdrOffset = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < static_cast<int>(numOfPlugins); ++i)
|
||||
{
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
if (entry.cellSize == m_CellSize)
|
||||
{
|
||||
m_SectionHdrOffset = ftell(m_pFile) - sizeof(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_SectionHdrOffset)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// compute section length
|
||||
if ((i + 1) < static_cast<int>(numOfPlugins))
|
||||
{
|
||||
// there is a next section
|
||||
TableEntry nextEntry;
|
||||
DATAREAD(&nextEntry, sizeof(nextEntry), 1);
|
||||
m_SectionLength = nextEntry.offset - entry.offset;
|
||||
} else {
|
||||
fseek(m_pFile, 0, SEEK_END);
|
||||
m_SectionLength = ftell(m_pFile) - (long)entry.offset;
|
||||
}
|
||||
} else {
|
||||
// check for old file
|
||||
AMX_HEADER hdr;
|
||||
rewind(m_pFile);
|
||||
fread(&hdr, sizeof(hdr), 1, m_pFile);
|
||||
amx_Align16(&hdr.magic);
|
||||
|
||||
if (hdr.magic == AMX_MAGIC)
|
||||
{
|
||||
if (cellsize != 4)
|
||||
{
|
||||
m_Status = Err_SectionNotFound;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_OldFile = true;
|
||||
|
||||
return;
|
||||
} else {
|
||||
// no known file format
|
||||
m_Status = Err_FileInvalid;
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CAmxxReader::~CAmxxReader()
|
||||
{
|
||||
if (m_pFile)
|
||||
{
|
||||
fclose(m_pFile);
|
||||
m_pFile = NULL;
|
||||
}
|
||||
|
||||
if (m_Bh.plugins)
|
||||
{
|
||||
delete [] m_Bh.plugins;
|
||||
m_Bh.plugins = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CAmxxReader::Error CAmxxReader::GetStatus()
|
||||
{
|
||||
return m_Status;
|
||||
}
|
||||
|
||||
#undef DATAREAD
|
||||
#define DATAREAD(addr, itemsize, itemcount) \
|
||||
if (fread(addr, itemsize, itemcount, m_pFile) != itemcount) \
|
||||
{ \
|
||||
if (feof(m_pFile)) \
|
||||
m_Status = Err_FileInvalid; \
|
||||
else \
|
||||
m_Status = Err_FileRead; \
|
||||
fclose(m_pFile); \
|
||||
m_pFile = NULL; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
size_t CAmxxReader::GetBufferSize()
|
||||
{
|
||||
if (!m_pFile)
|
||||
return 0;
|
||||
|
||||
long save = ftell(m_pFile);
|
||||
|
||||
if (m_OldFile)
|
||||
{
|
||||
rewind(m_pFile);
|
||||
AMX_HEADER hdr;
|
||||
DATAREAD(&hdr, sizeof(hdr), 1);
|
||||
fseek(m_pFile, save, SEEK_SET);
|
||||
|
||||
return hdr.stp;
|
||||
}
|
||||
else if (m_AmxxFile)
|
||||
{
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
|
||||
if (pe->imagesize > pe->memsize)
|
||||
return pe->imagesize + 1;
|
||||
|
||||
return pe->memsize + 1;
|
||||
}
|
||||
|
||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||
|
||||
TableEntry entry;
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
fseek(m_pFile, save, SEEK_SET);
|
||||
|
||||
return entry.origSize + 1; // +1 : safe
|
||||
}
|
||||
|
||||
#undef DATAREAD
|
||||
#define DATAREAD(addr, itemsize, itemcount) \
|
||||
if (fread(addr, itemsize, itemcount, m_pFile) != itemcount) \
|
||||
{ \
|
||||
if (feof(m_pFile)) \
|
||||
m_Status = Err_FileInvalid; \
|
||||
else \
|
||||
m_Status = Err_FileRead; \
|
||||
fclose(m_pFile); \
|
||||
m_pFile = NULL; \
|
||||
return m_Status; \
|
||||
}
|
||||
|
||||
CAmxxReader::Error CAmxxReader::GetSection(void *buffer)
|
||||
{
|
||||
if (!m_pFile)
|
||||
return m_Status;
|
||||
|
||||
if (m_OldFile)
|
||||
{
|
||||
// get file size
|
||||
fseek(m_pFile, 0, SEEK_END);
|
||||
long filesize = ftell(m_pFile);
|
||||
rewind(m_pFile);
|
||||
DATAREAD(buffer, 1, filesize);
|
||||
m_Status = Err_None;
|
||||
|
||||
return m_Status;
|
||||
}
|
||||
else if (m_AmxxFile)
|
||||
{
|
||||
PluginEntry *pe = &(m_Bh.plugins[m_Entry]);
|
||||
char *tempBuffer = new char[m_SectionLength + 1];
|
||||
fseek(m_pFile, pe->offs, SEEK_SET);
|
||||
DATAREAD((void *)tempBuffer, 1, m_SectionLength);
|
||||
uLongf destLen = GetBufferSize();
|
||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
return Err_Decompress;
|
||||
}
|
||||
|
||||
return Err_None;
|
||||
} else {
|
||||
// new file type: go to the section table entry
|
||||
fseek(m_pFile, m_SectionHdrOffset, SEEK_SET);
|
||||
// go to the offset
|
||||
TableEntry entry;
|
||||
DATAREAD(&entry, sizeof(entry), 1);
|
||||
fseek(m_pFile, entry.offset, SEEK_SET);
|
||||
uLongf destLen = GetBufferSize();
|
||||
// read the data to a temporary buffer
|
||||
char *tempBuffer = new char[m_SectionLength + 1];
|
||||
//fread(tempBuffer, sizeof(char), m_SectionLength, m_pFile);
|
||||
DATAREAD((void*)tempBuffer, 1, m_SectionLength);
|
||||
// decompress
|
||||
int result = uncompress((Bytef *)buffer, &destLen, (Bytef *)tempBuffer, m_SectionLength);
|
||||
delete [] tempBuffer;
|
||||
|
||||
if (result != Z_OK)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Zlib error encountered: %d(%d)", result, m_SectionLength);
|
||||
m_Status = Err_Decompress;
|
||||
|
||||
return Err_Decompress;
|
||||
}
|
||||
|
||||
return Err_None;
|
||||
}
|
||||
}
|
97
amxmodx/amxxfile.h
Executable file
97
amxmodx/amxxfile.h
Executable file
@ -0,0 +1,97 @@
|
||||
/* 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 __AMXXFILE_H__
|
||||
#define __AMXXFILE_H__
|
||||
|
||||
#define MAGIC_HEADER 0x414D5842
|
||||
#define MAGIC_HEADER2 0x414D5858
|
||||
#define MAGIC_VERSION 0x0300
|
||||
|
||||
typedef char mint8_t;
|
||||
typedef int16_t mint16_t;
|
||||
typedef int32_t mint32_t;
|
||||
|
||||
struct PluginEntry
|
||||
{
|
||||
mint8_t cellsize; //cell size
|
||||
int32_t imagesize; //uncompressed image size
|
||||
int32_t disksize; //compressed image size
|
||||
int32_t memsize; //memory image size
|
||||
int32_t offs; //file offset
|
||||
};
|
||||
|
||||
struct BinHeader
|
||||
{
|
||||
int32_t magic;
|
||||
mint16_t version;
|
||||
mint8_t numPlugins;
|
||||
PluginEntry *plugins;
|
||||
};
|
||||
|
||||
class CAmxxReader
|
||||
{
|
||||
public:
|
||||
enum Error
|
||||
{
|
||||
Err_None=0,
|
||||
Err_InvalidParam,
|
||||
Err_FileOpen,
|
||||
Err_FileRead,
|
||||
Err_FileInvalid,
|
||||
Err_SectionNotFound,
|
||||
Err_DecompressorInit,
|
||||
Err_Decompress,
|
||||
Err_OldFile,
|
||||
};
|
||||
|
||||
private:
|
||||
Error m_Status;
|
||||
FILE *m_pFile;
|
||||
|
||||
bool m_OldFile; // old .amx file
|
||||
bool m_AmxxFile; // new 'AMXX' header format
|
||||
BinHeader m_Bh; // binary header
|
||||
int m_Entry; // entry #
|
||||
|
||||
int m_CellSize;
|
||||
int m_SectionHdrOffset; // offset to the table in the header that describes the required section
|
||||
int m_SectionLength;
|
||||
public:
|
||||
CAmxxReader(const char *filename, int cellsize);
|
||||
~CAmxxReader();
|
||||
|
||||
Error GetStatus(); // Get the current status
|
||||
size_t GetBufferSize(); // Get the size for the buffer
|
||||
Error GetSection(void *buffer); // Copy the currently selected section to the buffer
|
||||
};
|
||||
|
||||
#endif // __AMXXFILE_H__
|
271
amxmodx/amxxlog.cpp
Executable file
271
amxmodx/amxxlog.cpp
Executable file
@ -0,0 +1,271 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// amxx_logging localinfo:
|
||||
// 0 = no logging
|
||||
// 1 = one logfile / day
|
||||
// 2 = one logfile / map
|
||||
// 3 = HL Logs
|
||||
|
||||
#include <time.h>
|
||||
#ifndef __linux__
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifndef __linux__
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
CLog::CLog()
|
||||
{
|
||||
m_LogType = 0;
|
||||
m_LogFile.clear();
|
||||
m_FoundError = false;
|
||||
}
|
||||
|
||||
CLog::~CLog()
|
||||
{
|
||||
CloseFile();
|
||||
}
|
||||
|
||||
void CLog::CloseFile()
|
||||
{
|
||||
// log "log file closed" to old file, if any
|
||||
if (!m_LogFile.empty())
|
||||
{
|
||||
FILE *fp = fopen(m_LogFile.c_str(), "r");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fclose(fp);
|
||||
fp = fopen(m_LogFile.c_str(), "a+");
|
||||
|
||||
// get time
|
||||
time_t td;
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
char date[32];
|
||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
||||
|
||||
fprintf(fp, "L %s: %s\n", date, "Log file closed.");
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
m_LogFile.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::CreateNewFile()
|
||||
{
|
||||
CloseFile();
|
||||
|
||||
// build filename
|
||||
time_t td;
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
char file[256];
|
||||
int i = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
|
||||
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
|
||||
|
||||
if (!pTmpFile)
|
||||
break;
|
||||
|
||||
fclose(pTmpFile);
|
||||
++i;
|
||||
}
|
||||
m_LogFile.assign(file);
|
||||
|
||||
// Log logfile start
|
||||
FILE *fp = fopen(m_LogFile.c_str(), "w");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error. AMXX Logging disabled.\n");
|
||||
SET_LOCALINFO("amxx_logging", "0");
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::UseFile(const String &fileName)
|
||||
{
|
||||
static char file[256];
|
||||
m_LogFile.assign(build_pathname_r(file, sizeof(file)-1, "%s/%s", g_log_dir.c_str(), fileName.c_str()));
|
||||
}
|
||||
|
||||
void CLog::MapChange()
|
||||
{
|
||||
// create dir if not existing
|
||||
char file[256];
|
||||
#ifdef __linux
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()), 0700);
|
||||
#else
|
||||
mkdir(build_pathname_r(file, sizeof(file)-1, "%s", g_log_dir.c_str()));
|
||||
#endif
|
||||
|
||||
m_LogType = atoi(get_localinfo("amxx_logging", "1"));
|
||||
|
||||
if (m_LogType < 0 || m_LogType > 3)
|
||||
{
|
||||
SET_LOCALINFO("amxx_logging", "1");
|
||||
m_LogType = 1;
|
||||
print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1...");
|
||||
}
|
||||
|
||||
if (m_LogType == 2)
|
||||
{
|
||||
// create new logfile
|
||||
CreateNewFile();
|
||||
}
|
||||
else if (m_LogType == 1)
|
||||
{
|
||||
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
void CLog::Log(const char *fmt, ...)
|
||||
{
|
||||
static char file[256];
|
||||
|
||||
if (m_LogType == 1 || m_LogType == 2)
|
||||
{
|
||||
// get time
|
||||
time_t td;
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
char date[32];
|
||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
||||
|
||||
// msg
|
||||
static char msg[3072];
|
||||
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsnprintf(msg, 3071, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
FILE *pF = NULL;
|
||||
if (m_LogType == 2)
|
||||
{
|
||||
pF = fopen(m_LogFile.c_str(), "a+");
|
||||
if (!pF)
|
||||
{
|
||||
CreateNewFile();
|
||||
pF = fopen(m_LogFile.c_str(), "a+");
|
||||
|
||||
if (!pF)
|
||||
{
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", m_LogFile.c_str());
|
||||
m_LogType = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
|
||||
pF = fopen(file, "a+");
|
||||
}
|
||||
|
||||
if (pF)
|
||||
{
|
||||
fprintf(pF, "L %s: %s\n", date, msg);
|
||||
fclose(pF);
|
||||
} else {
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Logging disabled for this map.\n", file);
|
||||
m_LogType = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// print on server console
|
||||
print_srvconsole("L %s: %s\n", date, msg);
|
||||
}
|
||||
else if (m_LogType == 3)
|
||||
{
|
||||
// build message
|
||||
static char msg_[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsnprintf(msg_, 3071, fmt, arglst);
|
||||
va_end(arglst);
|
||||
ALERT(at_logged, "%s\n", msg_);
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::LogError(const char *fmt, ...)
|
||||
{
|
||||
static char file[256];
|
||||
|
||||
if (m_FoundError)
|
||||
return;
|
||||
|
||||
// get time
|
||||
time_t td;
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
char date[32];
|
||||
strftime(date, 31, "%m/%d/%Y - %H:%M:%S", curTime);
|
||||
|
||||
// msg
|
||||
static char msg[3072];
|
||||
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsnprintf(msg, 3071, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
FILE *pF = NULL;
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/error_%02d%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, curTime->tm_year - 100);
|
||||
pF = fopen(file, "a+");
|
||||
|
||||
if (pF)
|
||||
{
|
||||
fprintf(pF, "L %s: %s\n", date, msg);
|
||||
fclose(pF);
|
||||
} else {
|
||||
ALERT(at_logged, "[AMXX] Unexpected fatal logging error (couldn't open %s for a+). AMXX Error Logging disabled for this map.\n", file);
|
||||
m_FoundError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// print on server console
|
||||
print_srvconsole("L %s: %s\n", date, msg);
|
||||
}
|
||||
|
54
amxmodx/amxxlog.h
Executable file
54
amxmodx/amxxlog.h
Executable file
@ -0,0 +1,54 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
*
|
||||
* 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 __AMXXLOG_H__
|
||||
#define __AMXXLOG_H__
|
||||
|
||||
class CLog
|
||||
{
|
||||
private:
|
||||
String m_LogFile;
|
||||
int m_LogType;
|
||||
bool m_FoundError;
|
||||
|
||||
void GetLastFile(int &outMonth, int &outDay, String &outFilename);
|
||||
void UseFile(const String &fileName);
|
||||
public:
|
||||
CLog();
|
||||
~CLog();
|
||||
|
||||
void CreateNewFile();
|
||||
void CloseFile();
|
||||
void MapChange();
|
||||
void Log(const char *fmt, ...);
|
||||
void LogError(const char *fmt, ...);
|
||||
};
|
||||
|
||||
#endif // __AMXXLOG_H__
|
271
amxmodx/binlog.cpp
Normal file
271
amxmodx/binlog.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
#if defined BINLOG_ENABLED
|
||||
|
||||
#include <time.h>
|
||||
#include "amxmodx.h"
|
||||
#include "binlog.h"
|
||||
|
||||
BinLog g_BinLog;
|
||||
int g_binlog_level = 0;
|
||||
int g_binlog_maxsize = 0;
|
||||
|
||||
bool BinLog::Open()
|
||||
{
|
||||
const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
|
||||
char path[255];
|
||||
build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);
|
||||
|
||||
if (!DirExists(path))
|
||||
{
|
||||
mkdir(path
|
||||
#if defined __linux__
|
||||
, 0755
|
||||
#endif
|
||||
);
|
||||
if (!DirExists(path))
|
||||
return false;
|
||||
}
|
||||
|
||||
char file[255];
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);
|
||||
|
||||
unsigned int lastcntr = 0;
|
||||
FILE *lastlog = fopen(file, "rb");
|
||||
if (lastlog)
|
||||
{
|
||||
if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
|
||||
lastcntr = 0;
|
||||
fclose(lastlog);
|
||||
}
|
||||
lastlog = fopen(file, "wb");
|
||||
if (lastlog)
|
||||
{
|
||||
lastcntr++;
|
||||
fwrite(&lastcntr, sizeof(int), 1, lastlog);
|
||||
fclose(lastlog);
|
||||
}
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
|
||||
m_logfile.assign(file);
|
||||
|
||||
/**
|
||||
* it's now safe to create the binary log
|
||||
*/
|
||||
FILE *fp = fopen(m_logfile.c_str(), "wb");
|
||||
if (!fp)
|
||||
return false;
|
||||
|
||||
int magic = BINLOG_MAGIC;
|
||||
short vers = BINLOG_VERSION;
|
||||
char c = sizeof(time_t);
|
||||
fwrite(&magic, sizeof(int), 1, fp);
|
||||
fwrite(&vers, sizeof(short), 1, fp);
|
||||
fwrite(&c, sizeof(char), 1, fp);
|
||||
|
||||
WritePluginDB(fp);
|
||||
fclose(fp);
|
||||
|
||||
m_state = true;
|
||||
|
||||
WriteOp(BinLog_Start, -1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BinLog::Close()
|
||||
{
|
||||
WriteOp(BinLog_End, -1);
|
||||
m_state = false;
|
||||
}
|
||||
|
||||
void BinLog::WriteOp(BinLogOp op, int plug, ...)
|
||||
{
|
||||
if (!m_state)
|
||||
return;
|
||||
|
||||
FILE *fp = fopen(m_logfile.c_str(), "ab");
|
||||
if (!fp)
|
||||
return;
|
||||
|
||||
if (g_binlog_maxsize && op != BinLog_End)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
if (ftell(fp) > (g_binlog_maxsize * (1024 * 1024)))
|
||||
{
|
||||
fclose(fp);
|
||||
Close();
|
||||
Open();
|
||||
fp = fopen(m_logfile.c_str(), "ab");
|
||||
if (!fp)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char c = static_cast<char>(op);
|
||||
time_t t = time(NULL);
|
||||
float gt = gpGlobals->time;
|
||||
fwrite(&c, sizeof(char), 1, fp);
|
||||
fwrite(&t, sizeof(time_t), 1, fp);
|
||||
fwrite(>, sizeof(float), 1, fp);
|
||||
fwrite(&plug, sizeof(int), 1, fp);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, plug);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case BinLog_Registered:
|
||||
{
|
||||
const char *title = va_arg(ap, const char *);
|
||||
const char *vers = va_arg(ap, const char *);
|
||||
c = (char)strlen(title);
|
||||
fwrite(&c, sizeof(char), 1, fp);
|
||||
fwrite(title, sizeof(char), c+1, fp);
|
||||
c = (char)strlen(vers);
|
||||
fwrite(&c, sizeof(char), 1 ,fp);
|
||||
fwrite(vers, sizeof(char), c+1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_NativeCall:
|
||||
{
|
||||
int native = va_arg(ap, int);
|
||||
int params = va_arg(ap, int);
|
||||
fwrite(&native, sizeof(int), 1, fp);
|
||||
fwrite(¶ms, sizeof(int), 1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_NativeRet:
|
||||
{
|
||||
cell retval = va_arg(ap, cell);
|
||||
fwrite(&retval, sizeof(cell), 1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_NativeError:
|
||||
{
|
||||
int err = va_arg(ap, int);
|
||||
const char *msg = va_arg(ap, const char *);
|
||||
short len = (short)strlen(msg);
|
||||
fwrite(&err, sizeof(int), 1, fp);
|
||||
fwrite(&len, sizeof(short), 1, fp);
|
||||
fwrite(msg, sizeof(char), len+1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_CallPubFunc:
|
||||
{
|
||||
int num = va_arg(ap, int);
|
||||
fwrite(&num, sizeof(int), 1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_SetLine:
|
||||
{
|
||||
int line = va_arg(ap, int);
|
||||
fwrite(&line, sizeof(int), 1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_FormatString:
|
||||
{
|
||||
int param = va_arg(ap, int);
|
||||
int maxlen = va_arg(ap, int);
|
||||
const char *str = va_arg(ap, const char *);
|
||||
short len = (short)strlen(str);
|
||||
fwrite(¶m, sizeof(int), 1, fp);
|
||||
fwrite(&maxlen, sizeof(int), 1, fp);
|
||||
fwrite(&len, sizeof(short), 1, fp);
|
||||
fwrite(str, sizeof(char), len+1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_NativeParams:
|
||||
{
|
||||
cell *params = va_arg(ap, cell *);
|
||||
cell num = params[0] / sizeof(cell);
|
||||
fwrite(&num, sizeof(cell), 1, fp);
|
||||
for (cell i=1; i<=num; i++)
|
||||
fwrite(&(params[i]), sizeof(cell), 1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_GetString:
|
||||
{
|
||||
cell addr = va_arg(ap, cell);
|
||||
const char *str = va_arg(ap, const char *);
|
||||
short len = (short)strlen(str);
|
||||
fwrite(&addr, sizeof(cell), 1, fp);
|
||||
fwrite(&len, sizeof(short), 1, fp);
|
||||
fwrite(str, sizeof(char), len+1, fp);
|
||||
break;
|
||||
}
|
||||
case BinLog_SetString:
|
||||
{
|
||||
cell addr = va_arg(ap, cell);
|
||||
int maxlen = va_arg(ap, int);
|
||||
const char *str = va_arg(ap, const char *);
|
||||
short len = (short)strlen(str);
|
||||
fwrite(&addr, sizeof(cell), 1, fp);
|
||||
fwrite(&maxlen, sizeof(int), 1, fp);
|
||||
fwrite(&len, sizeof(short), 1, fp);
|
||||
fwrite(str, sizeof(char), len+1, fp);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
va_end(ap);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void BinLog::WritePluginDB(FILE *fp)
|
||||
{
|
||||
int num = g_plugins.getPluginsNum();
|
||||
fwrite(&num, sizeof(int), 1, fp);
|
||||
|
||||
CPluginMngr::CPlugin *pl;
|
||||
char c;
|
||||
unsigned char len;
|
||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||
{
|
||||
pl = &(*iter);
|
||||
if (pl->isValid())
|
||||
c = 1;
|
||||
else
|
||||
c = 0;
|
||||
if (c && pl->isDebug())
|
||||
c = 2;
|
||||
fwrite(&c, sizeof(char), 1, fp);
|
||||
if (c)
|
||||
{
|
||||
len = (char)strlen(pl->getName());
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
len++;
|
||||
fwrite(pl->getName(), sizeof(char), len, fp);
|
||||
int natives, publics;
|
||||
AMX *amx = pl->getAMX();
|
||||
amx_NumNatives(amx, &natives);
|
||||
amx_NumPublics(amx, &publics);
|
||||
fwrite(&natives, sizeof(int), 1, fp);
|
||||
fwrite(&publics, sizeof(int), 1, fp);
|
||||
char name[34];
|
||||
for (int i=0; i<natives; i++)
|
||||
{
|
||||
amx_GetNative(amx, i, name);
|
||||
len = (char)strlen(name);
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
len++;
|
||||
fwrite(name, sizeof(char), len, fp);
|
||||
}
|
||||
for (int i=0; i<publics; i++)
|
||||
{
|
||||
amx_GetPublic(amx, i, name);
|
||||
len = (char)strlen(name);
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
len++;
|
||||
fwrite(name, sizeof(char), len, fp);
|
||||
}
|
||||
} else {
|
||||
char empty[] = " ";
|
||||
len = 1;
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
fwrite(empty, sizeof(char), len, fp);
|
||||
int no = 0;
|
||||
fwrite(&no, sizeof(int), 1, fp);
|
||||
fwrite(&no, sizeof(int), 1, fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //BINLOG_ENABLED
|
77
amxmodx/binlog.h
Normal file
77
amxmodx/binlog.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef _INCLUDE_BINLOG_H
|
||||
#define _INCLUDE_BINLOG_H
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#define BINLOG_MAGIC 0x414D424C
|
||||
#define BINLOG_VERSION 0x0200
|
||||
|
||||
/**
|
||||
* Format of binlog:
|
||||
* uint32 magic
|
||||
* uint16 version
|
||||
* uint8 sizeof(time_t)
|
||||
* uint32 num plugins
|
||||
* [
|
||||
* uint8 status codes
|
||||
* str[int8] filename
|
||||
* uint32 num natives
|
||||
* uint32 num publics
|
||||
* [
|
||||
* str[uint8] native name
|
||||
* ]
|
||||
* [
|
||||
* str[uint8] public name
|
||||
* ]
|
||||
* ]
|
||||
* [
|
||||
* uint8 operation code
|
||||
* time_t realtime
|
||||
* float gametime
|
||||
* int32 plugin id
|
||||
* <extra info>
|
||||
* ]
|
||||
*/
|
||||
|
||||
enum BinLogOp
|
||||
{
|
||||
BinLog_Start=1,
|
||||
BinLog_End,
|
||||
BinLog_NativeCall, //<int32 native id> <int32_t num_params>
|
||||
BinLog_NativeError, //<int32 errornum> <str[int16] string>
|
||||
BinLog_NativeRet, //<cell value>
|
||||
BinLog_CallPubFunc, //<int32 public id>
|
||||
BinLog_SetLine, //<int32 line no#>
|
||||
BinLog_Registered, //<string title> <string version>
|
||||
BinLog_FormatString, //<int32 param#> <int32 maxlen> <str[int16] string>
|
||||
BinLog_NativeParams, //<int32 num> <cell ...>
|
||||
BinLog_GetString, //<cell addr> <string[int16]>
|
||||
BinLog_SetString, //<cell addr> <int maxlen> <string[int16]>
|
||||
};
|
||||
|
||||
class BinLog
|
||||
{
|
||||
public:
|
||||
BinLog() : m_state(false)
|
||||
{
|
||||
};
|
||||
public:
|
||||
bool Open();
|
||||
void Close();
|
||||
void WriteOp(BinLogOp op, int plug, ...);
|
||||
private:
|
||||
void WritePluginDB(FILE *fp);
|
||||
private:
|
||||
String m_logfile;
|
||||
bool m_state;
|
||||
};
|
||||
|
||||
extern BinLog g_BinLog;
|
||||
extern int g_binlog_level;
|
||||
extern int g_binlog_maxsize;
|
||||
|
||||
#endif //BINLOG_ENABLED
|
||||
|
||||
#endif //_INCLUDE_BINLOG_H
|
1010
amxmodx/debugger.cpp
Executable file
1010
amxmodx/debugger.cpp
Executable file
File diff suppressed because it is too large
Load Diff
201
amxmodx/debugger.h
Executable file
201
amxmodx/debugger.h
Executable file
@ -0,0 +1,201 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_DEBUGGER_H_
|
||||
#define _INCLUDE_DEBUGGER_H_
|
||||
|
||||
#include "CVector.h"
|
||||
#include "amxdbg.h"
|
||||
|
||||
/**
|
||||
* Third revision of the AMX Mod X Plugin Debugger.
|
||||
* This final, object oriented version is safe for multiple calls and lets you
|
||||
* fine-tune error handling.
|
||||
* -BAILOPAN
|
||||
*/
|
||||
class Debugger
|
||||
{
|
||||
public:
|
||||
class Tracer
|
||||
{
|
||||
public:
|
||||
|
||||
struct trace_info
|
||||
{
|
||||
trace_info() : cip(0), frm(0), used(false), next(NULL), prev(NULL) {};
|
||||
|
||||
cell cip;
|
||||
cell frm;
|
||||
|
||||
trace_info *next;
|
||||
trace_info *prev;
|
||||
|
||||
bool used;
|
||||
};
|
||||
|
||||
public:
|
||||
Tracer() : m_Error(0), m_pStart(NULL), m_pEnd(NULL), m_Reset(true) {};
|
||||
~Tracer();
|
||||
public:
|
||||
void StepI(cell frm, cell cip);
|
||||
void Reset();
|
||||
void Clear();
|
||||
|
||||
Debugger::Tracer::trace_info *GetStart() const;
|
||||
Debugger::Tracer::trace_info *GetEnd() const;
|
||||
public:
|
||||
int m_Error;
|
||||
private:
|
||||
trace_info *m_pStart;
|
||||
trace_info *m_pEnd;
|
||||
|
||||
bool m_Reset;
|
||||
};
|
||||
|
||||
public:
|
||||
Debugger(AMX *pAmx, AMX_DBG *pAmxDbg) : m_pAmx(pAmx), m_pAmxDbg(pAmxDbg), m_Top(-1)
|
||||
{
|
||||
_CacheAmxOpcodeList();
|
||||
};
|
||||
~Debugger();
|
||||
public:
|
||||
//Begin a trace for a function
|
||||
void BeginExec();
|
||||
|
||||
//Step through one instruction
|
||||
void StepI();
|
||||
|
||||
//Get/set the last traced error
|
||||
int GetTracedError();
|
||||
void SetTracedError(int error);
|
||||
|
||||
//Get the first trace info of the call stack
|
||||
Debugger::Tracer::trace_info *GetTraceStart() const;
|
||||
|
||||
//Get extra info about the call stack
|
||||
bool GetTraceInfo(Debugger::Tracer::trace_info *pTraceInfo, long &line, const char *&function, const char *&file);
|
||||
|
||||
//Get the next trace in the call stack, NULL if none
|
||||
Debugger::Tracer::trace_info *GetNextTrace(Debugger::Tracer::trace_info *pTraceInfo);
|
||||
|
||||
//Returns true if an error exists
|
||||
bool ErrorExists();
|
||||
|
||||
//Formats the error message into a buffer.
|
||||
//returns length of data copied, or -1 if there is no error.
|
||||
int FormatError(char *buffer, size_t maxLength);
|
||||
|
||||
//End a trace
|
||||
void EndExec();
|
||||
|
||||
//Reset the internal states as if the debugger was inactive
|
||||
void Reset();
|
||||
|
||||
//Destroy internal states for shutdown
|
||||
void Clear();
|
||||
|
||||
void DisplayTrace(const char *message);
|
||||
|
||||
AMX *GetAMX() const { return m_pAmx; }
|
||||
public:
|
||||
//generic static opcode breaker
|
||||
static int AMXAPI DebugHook(AMX *amx);
|
||||
|
||||
static void FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength);
|
||||
static void GenericMessage(AMX *amx, int error);
|
||||
private:
|
||||
void _CacheAmxOpcodeList();
|
||||
|
||||
int _GetOpcodeFromCip(cell cip, cell *&addr);
|
||||
cell _CipAsVa(cell cip);
|
||||
|
||||
const char *_GetFilename();
|
||||
public:
|
||||
AMX *m_pAmx;
|
||||
AMX_DBG *m_pAmxDbg;
|
||||
|
||||
int m_Top;
|
||||
cell *m_pOpcodeList;
|
||||
String m_FileName;
|
||||
|
||||
CVector<Tracer *> m_pCalls;
|
||||
};
|
||||
|
||||
typedef Debugger::Tracer::trace_info trace_info_t;
|
||||
|
||||
/**
|
||||
* Error handler for plugins
|
||||
*/
|
||||
|
||||
class Handler
|
||||
{
|
||||
public:
|
||||
Handler(AMX *pAmx) : m_pAmx(pAmx), m_iErrFunc(-1), m_iModFunc(-1), m_iNatFunc(-1), m_Handling(false), m_InNativeFilter(false) {};
|
||||
~Handler() {};
|
||||
public:
|
||||
int SetErrorHandler(const char *function);
|
||||
int SetNativeFilter(const char *function);
|
||||
int SetModuleFilter(const char *function);
|
||||
public:
|
||||
int HandleError(const char *msg);
|
||||
int HandleNative(const char *native, int index, int trap);
|
||||
int HandleModule(const char *module, bool isClass=false);
|
||||
public:
|
||||
bool IsHandling() const { return m_Handling; }
|
||||
void SetErrorMsg(const char *msg);
|
||||
|
||||
const char *GetLastMsg();
|
||||
trace_info_t *GetTrace() const { return m_pTrace; }
|
||||
const char *GetFmtCache() { return m_FmtCache.c_str(); }
|
||||
|
||||
bool IsNativeFiltering() { return (m_iNatFunc > 0); }
|
||||
bool InNativeFilter() { return m_InNativeFilter; }
|
||||
private:
|
||||
AMX *m_pAmx;
|
||||
|
||||
int m_iErrFunc;
|
||||
int m_iModFunc;
|
||||
int m_iNatFunc;
|
||||
|
||||
bool m_Handling;
|
||||
|
||||
//in the future, make this a stack!
|
||||
bool m_InNativeFilter;
|
||||
|
||||
String m_MsgCache;
|
||||
String m_FmtCache;
|
||||
|
||||
trace_info_t *m_pTrace;
|
||||
};
|
||||
|
||||
extern AMX_NATIVE_INFO g_DebugNatives[];
|
||||
|
||||
#endif //_INCLUDE_DEBUGGER_H_
|
388
amxmodx/emsg.cpp
388
amxmodx/emsg.cpp
@ -29,9 +29,7 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#include "amxmodx.h"
|
||||
|
||||
int gmsgAmmoPickup;
|
||||
int gmsgAmmoX;
|
||||
@ -59,208 +57,233 @@ WeaponsVault g_weaponsData[MAX_WEAPONS];
|
||||
|
||||
void Client_VGUIMenu(void* mValue)
|
||||
{
|
||||
if (!mPlayer) return;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
mPlayer->menu = -(*(int*)mValue);
|
||||
break;
|
||||
case 1:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
}
|
||||
if (!mPlayer) return;
|
||||
|
||||
mPlayer->vgui = true;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
mPlayer->menu = -(*(int*)mValue);
|
||||
mPlayer->newmenu = -1;
|
||||
break;
|
||||
case 1:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
}
|
||||
}
|
||||
|
||||
void Client_ShowMenu(void* mValue)
|
||||
{
|
||||
if (!mPlayer) return;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
break;
|
||||
case 3:
|
||||
mPlayer->menu = g_menucmds.findMenuId( (char*)mValue );
|
||||
}
|
||||
if (!mPlayer) return;
|
||||
|
||||
mPlayer->vgui = true;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
|
||||
mPlayer->newmenu = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client_TeamInfo(void* mValue)
|
||||
{
|
||||
if (mPlayer) return;
|
||||
static int index;
|
||||
switch (mState++) {
|
||||
case 0:
|
||||
index = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if ( index < 1 || index > gpGlobals->maxClients ) break;
|
||||
char* msg = (char*)mValue;
|
||||
g_players[ index ].team.set( msg );
|
||||
g_teamsIds.registerTeam( msg , -1 );
|
||||
}
|
||||
if (mPlayer) return;
|
||||
static int index;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
index = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (index < 1 || index > gpGlobals->maxClients) break;
|
||||
char* msg = (char*)mValue;
|
||||
g_players[index].team.assign(msg);
|
||||
g_teamsIds.registerTeam(msg, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void Client_TextMsg(void* mValue)
|
||||
{
|
||||
if ( mPlayer ) return;
|
||||
switch (mState++) {
|
||||
case 1:{
|
||||
char * msg = (char*)mValue;
|
||||
if (!msg) break;
|
||||
if ( !strncmp("#Game_C", msg , 7) ) {
|
||||
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
|
||||
// g_endround_time = gpGlobals->time;
|
||||
// g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
|
||||
}
|
||||
else if (!strncmp("#Game_w", msg , 7) ) {
|
||||
g_game_timeleft = -2;
|
||||
}
|
||||
else if ( !strncmp("#game_clan_s", msg , 12) ){
|
||||
g_game_timeleft = -3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
char * msg = (char*)mValue;
|
||||
if (!msg) break;
|
||||
if (g_game_timeleft == -2 ){
|
||||
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi( msg );
|
||||
// g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
|
||||
}
|
||||
else if ( g_game_timeleft == -3 )
|
||||
g_game_restarting = atoi( msg ) * 60;
|
||||
break;
|
||||
}
|
||||
case 3:{
|
||||
char * msg = (char*)mValue;
|
||||
if (!msg) break;
|
||||
if ( g_game_timeleft != -3 ) break;
|
||||
g_game_restarting += atoi( msg );
|
||||
g_game_timeleft = g_game_restarting = gpGlobals->time + g_game_restarting;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mPlayer) return;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
char * msg = (char*)mValue;
|
||||
if (!msg) break;
|
||||
|
||||
if (!strncmp("#Game_C", msg, 7))
|
||||
{
|
||||
g_game_timeleft = g_game_restarting = gpGlobals->time + 3;
|
||||
//g_endround_time = gpGlobals->time;
|
||||
//g_newround_time = gpGlobals->time + CVAR_GET_FLOAT("mp_freezetime") + 3;
|
||||
}
|
||||
else if (!strncmp("#Game_w", msg, 7))
|
||||
{
|
||||
g_game_timeleft = -2;
|
||||
}
|
||||
else if (!strncmp("#game_clan_s", msg, 12))
|
||||
{
|
||||
g_game_timeleft = -3;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
char * msg = (char*)mValue;
|
||||
if (!msg) break;
|
||||
|
||||
if (g_game_timeleft == -2)
|
||||
{
|
||||
g_game_timeleft = g_game_restarting = gpGlobals->time + atoi(msg);
|
||||
//g_newround_time = g_game_timeleft + CVAR_GET_FLOAT("mp_freezetime");
|
||||
}
|
||||
else if (g_game_timeleft == -3)
|
||||
g_game_restarting = atoi(msg) * 60.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)
|
||||
{
|
||||
static int wpnList = 0;
|
||||
//static int wpnList2;
|
||||
static int iSlot;
|
||||
static const char* wpnName;
|
||||
switch (mState++) {
|
||||
case 0:
|
||||
wpnName = (char*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
iSlot = *(int*)mValue;
|
||||
break;
|
||||
case 7:
|
||||
int iId = *(int*)mValue;
|
||||
/*int* blocker;
|
||||
static int wpnList = 0;
|
||||
//static int wpnList2;
|
||||
static int iSlot;
|
||||
static const char* wpnName;
|
||||
|
||||
int iwpn = iId;
|
||||
|
||||
if (iId > 31) {
|
||||
iwpn -= 31;
|
||||
blocker = &wpnList2;
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
wpnName = (char*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
iSlot = *(int*)mValue;
|
||||
break;
|
||||
case 7:
|
||||
int iId = *(int*)mValue;
|
||||
if ((iId < 0 || iId >= MAX_WEAPONS) || (wpnList & (1<<iId)))
|
||||
break;
|
||||
wpnList |= (1<<iId);
|
||||
g_weaponsData[iId].iId = iId;
|
||||
g_weaponsData[iId].ammoSlot = iSlot;
|
||||
g_weaponsData[iId].fullName.assign(wpnName);
|
||||
}
|
||||
else
|
||||
blocker = &wpnList;*/
|
||||
|
||||
if ( (iId < 0 || iId >= MAX_WEAPONS ) || (wpnList & (1<<iId)) )
|
||||
break;
|
||||
wpnList |= (1<<iId);
|
||||
g_weaponsData[iId].iId = iId;
|
||||
g_weaponsData[iId].ammoSlot = iSlot;
|
||||
g_weaponsData[iId].fullName.set(wpnName);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Client_CurWeapon(void* mValue)
|
||||
{
|
||||
static int iState;
|
||||
static int iId;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
iState = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!iState) break;
|
||||
iId = *(int*)mValue;
|
||||
break;
|
||||
case 2:
|
||||
if (!mPlayer) return;
|
||||
if (!iState || (iId < 1 || iId >= MAX_WEAPONS ) ) break;
|
||||
mPlayer->weapons[iId].clip = *(int*)mValue;
|
||||
mPlayer->current = iId;
|
||||
mPlayer->lastHit = mPlayer->lastTrace;
|
||||
}
|
||||
static int iState;
|
||||
static int iId;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
iState = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!iState) break;
|
||||
iId = *(int*)mValue;
|
||||
break;
|
||||
case 2:
|
||||
if (!mPlayer) return;
|
||||
if (!iState || (iId < 1 || iId >= MAX_WEAPONS)) break;
|
||||
mPlayer->weapons[iId].clip = *(int*)mValue;
|
||||
mPlayer->current = iId;
|
||||
mPlayer->lastHit = mPlayer->lastTrace;
|
||||
}
|
||||
}
|
||||
|
||||
void Client_AmmoX(void* mValue)
|
||||
{
|
||||
static int iAmmo;
|
||||
|
||||
static int iAmmo;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
iAmmo = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!mPlayer) return;
|
||||
for(int i=1;i<MAX_WEAPONS;++i)
|
||||
if (iAmmo == g_weaponsData[i].ammoSlot)
|
||||
mPlayer->weapons[i].ammo = *(int*)mValue;
|
||||
}
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
iAmmo = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!mPlayer) return;
|
||||
for (int i = 1; i < MAX_WEAPONS; ++i)
|
||||
if (iAmmo == g_weaponsData[i].ammoSlot)
|
||||
mPlayer->weapons[i].ammo = *(int*)mValue;
|
||||
}
|
||||
}
|
||||
|
||||
void Client_AmmoPickup(void* mValue)
|
||||
{
|
||||
static int iSlot;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
iSlot = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!mPlayer) return;
|
||||
for(int i=1;i<MAX_WEAPONS;++i)
|
||||
if (g_weaponsData[i].ammoSlot==iSlot)
|
||||
mPlayer->weapons[i].ammo += *(int*)mValue;
|
||||
}
|
||||
static int iSlot;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
iSlot = *(int*)mValue;
|
||||
break;
|
||||
case 1:
|
||||
if (!mPlayer) return;
|
||||
for (int i = 1; i < MAX_WEAPONS; ++i)
|
||||
if (g_weaponsData[i].ammoSlot==iSlot)
|
||||
mPlayer->weapons[i].ammo += *(int*)mValue;
|
||||
}
|
||||
}
|
||||
|
||||
void Client_ScoreInfo(void* mValue)
|
||||
{
|
||||
static int index;
|
||||
static int deaths;
|
||||
switch (mState++){
|
||||
case 0:
|
||||
index = *(int*)mValue;
|
||||
break;
|
||||
case 2:
|
||||
deaths = *(int*)mValue;
|
||||
break;
|
||||
case 4:
|
||||
if ( index < 1 || index > gpGlobals->maxClients ) break;
|
||||
CPlayer*pPlayer = GET_PLAYER_POINTER_I( index );
|
||||
pPlayer->deaths = deaths;
|
||||
pPlayer->teamId = *(int*)mValue;
|
||||
if ( g_teamsIds.isNewTeam() )
|
||||
g_teamsIds.registerTeam( pPlayer->team.str() , pPlayer->teamId );
|
||||
}
|
||||
static int index;
|
||||
static int deaths;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
index = *(int*)mValue;
|
||||
break;
|
||||
case 2:
|
||||
deaths = *(int*)mValue;
|
||||
break;
|
||||
case 4:
|
||||
if (index < 1 || index > gpGlobals->maxClients) break;
|
||||
CPlayer*pPlayer = GET_PLAYER_POINTER_I(index);
|
||||
pPlayer->deaths = deaths;
|
||||
pPlayer->teamId = *(int*)mValue;
|
||||
if (g_teamsIds.isNewTeam())
|
||||
g_teamsIds.registerTeam(pPlayer->team.c_str(), pPlayer->teamId);
|
||||
}
|
||||
}
|
||||
|
||||
void Client_DamageEnd(void* mValue)
|
||||
{
|
||||
CPlayer* dead = mPlayer;
|
||||
|
||||
if ( dead && dead->death_killer )
|
||||
if (dead && dead->death_killer)
|
||||
{
|
||||
g_events.parserInit( CS_DEATHMSG , &gpGlobals->time , mPlayer = 0, mPlayerIndex = 0 );
|
||||
g_events.parseValue( dead->death_killer );
|
||||
g_events.parseValue( dead->index );
|
||||
g_events.parseValue( dead->death_headshot );
|
||||
g_events.parseValue( dead->death_weapon.str() );
|
||||
g_events.parseValue( dead->death_tk ? 1 : 0 );
|
||||
g_events.parserInit(CS_DEATHMSG, &gpGlobals->time, mPlayer = 0, mPlayerIndex = 0);
|
||||
g_events.parseValue(dead->death_killer);
|
||||
g_events.parseValue(dead->index);
|
||||
g_events.parseValue(dead->death_headshot);
|
||||
g_events.parseValue(dead->death_weapon.c_str());
|
||||
g_events.parseValue(dead->death_tk ? 1 : 0);
|
||||
g_events.executeEvents();
|
||||
dead->death_killer = 0;
|
||||
}
|
||||
@ -274,28 +297,25 @@ void Client_DeathMsg(void* mValue)
|
||||
static int victim_id;
|
||||
static int hs;
|
||||
|
||||
switch (mState++){
|
||||
case 0:
|
||||
killer_id = *(int*)mValue;
|
||||
killer = (killer_id > 0 && killer_id < 33) ?
|
||||
GET_PLAYER_POINTER_I(killer_id) : 0;
|
||||
break;
|
||||
case 1:
|
||||
victim_id = *(int*)mValue;
|
||||
victim = (victim_id > 0 && victim_id < 33) ?
|
||||
GET_PLAYER_POINTER_I(victim_id) : 0;
|
||||
break;
|
||||
case 2:
|
||||
hs = *(int*)mValue;
|
||||
break;
|
||||
case 3:
|
||||
|
||||
if ( !killer || !victim ) break;
|
||||
|
||||
victim->death_killer = killer_id;
|
||||
victim->death_weapon.set((char*)mValue);
|
||||
victim->death_headshot = hs;
|
||||
victim->death_tk = (killer->teamId == victim->teamId);
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
killer_id = *(int*)mValue;
|
||||
killer = (killer_id > 0 && killer_id < 33) ? GET_PLAYER_POINTER_I(killer_id) : 0;
|
||||
break;
|
||||
case 1:
|
||||
victim_id = *(int*)mValue;
|
||||
victim = (victim_id > 0 && victim_id < 33) ? GET_PLAYER_POINTER_I(victim_id) : 0;
|
||||
break;
|
||||
case 2:
|
||||
hs = *(int*)mValue;
|
||||
break;
|
||||
case 3:
|
||||
if (!killer || !victim) break;
|
||||
victim->death_killer = killer_id;
|
||||
victim->death_weapon.assign((char*)mValue);
|
||||
victim->death_headshot = hs;
|
||||
victim->death_tk = (killer->teamId == victim->teamId);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* 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
|
||||
@ -29,41 +28,27 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "CString.h"
|
||||
#include "string.h"
|
||||
#include "CFile.h"
|
||||
#include "amxmodx.h"
|
||||
#include "fakemeta.h"
|
||||
|
||||
String::String()
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now)
|
||||
{
|
||||
len = 0;
|
||||
napis = 0;
|
||||
}
|
||||
|
||||
String::String( const char* n )
|
||||
{
|
||||
napis = 0;
|
||||
set(n);
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void String::set( const char* n )
|
||||
{
|
||||
clear();
|
||||
if ( n != 0 ){
|
||||
len = strlen( n );
|
||||
napis = new char[ len + 1 ];
|
||||
if ( napis ) strcpy( napis , n );
|
||||
else len = 0;
|
||||
int err = 0;
|
||||
if ( (err = LOAD_PLUGIN(PLID, path, now, handle)) || !*handle)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "Can't Attach Module \"%s\".", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void String::clear() {
|
||||
delete[] napis;
|
||||
napis = 0;
|
||||
len = 0;
|
||||
}
|
||||
int UnloadMetamodPlugin(void *handle)
|
||||
{
|
||||
if (UNLOAD_PLUGIN_BY_HANDLE(PLID, (void *)handle, PT_ANYTIME, PNL_PLUGIN))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
37
amxmodx/fakemeta.h
Executable file
37
amxmodx/fakemeta.h
Executable file
@ -0,0 +1,37 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
*
|
||||
*
|
||||
* 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 __FAKEMETA_H__
|
||||
#define __FAKEMETA_H__
|
||||
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
|
||||
#endif // #ifndef __FAKEMETA_H__
|
894
amxmodx/file.cpp
894
amxmodx/file.cpp
@ -35,25 +35,44 @@
|
||||
#define _INTPTR_T_DEFINED
|
||||
#endif
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmod.h"
|
||||
#ifdef __GNUC__
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
// header file for unlink()
|
||||
#ifdef __linux__
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include "amxmodx.h"
|
||||
|
||||
//#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
CVector<FILE *> FileList;
|
||||
|
||||
#endif
|
||||
class AutoFilePtr
|
||||
{
|
||||
FILE *m_FP;
|
||||
public:
|
||||
AutoFilePtr(FILE *fp) : m_FP(fp)
|
||||
{}
|
||||
|
||||
~AutoFilePtr()
|
||||
{
|
||||
if (m_FP)
|
||||
fclose(m_FP);
|
||||
}
|
||||
|
||||
operator FILE* ()
|
||||
{
|
||||
return m_FP;
|
||||
}
|
||||
};
|
||||
|
||||
static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
{
|
||||
@ -61,20 +80,26 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
int a;
|
||||
struct dirent *ep;
|
||||
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];
|
||||
if ( (dp = opendir (dirname)) == NULL )
|
||||
|
||||
if ((dp = opendir (dirname)) == NULL)
|
||||
return 0;
|
||||
seekdir( dp , a );
|
||||
if ( (ep = readdir (dp)) != NULL ) {
|
||||
cell *length = get_amxaddr(amx,params[5]);
|
||||
*length = set_amxstring(amx,params[3], ep->d_name ,params[4]);
|
||||
a = telldir( dp );
|
||||
}
|
||||
else
|
||||
|
||||
seekdir(dp, a);
|
||||
|
||||
if ((ep = readdir (dp)) != NULL)
|
||||
{
|
||||
cell *length = get_amxaddr(amx, params[5]);
|
||||
*length = set_amxstring(amx, params[3], ep->d_name, params[4]);
|
||||
a = telldir(dp);
|
||||
} else
|
||||
a = 0;
|
||||
|
||||
closedir (dp);
|
||||
|
||||
return a;
|
||||
|
||||
#else
|
||||
int tmp;
|
||||
char *dirname = build_pathname("%s/*", get_amxstring(amx, params[1], 0, tmp));
|
||||
@ -82,10 +107,12 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
|
||||
_finddata_t fd;
|
||||
intptr_t handle = _findfirst(dirname, &fd);
|
||||
|
||||
if (handle < 0)
|
||||
return 0;
|
||||
|
||||
++tmp;
|
||||
|
||||
for (int i = 0; i < tmp; ++i)
|
||||
{
|
||||
if (_findnext(handle, &fd) < 0)
|
||||
@ -94,8 +121,9 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
_findclose(handle);
|
||||
|
||||
@ -105,171 +133,719 @@ static cell AMX_NATIVE_CALL read_dir(AMX *amx, cell *params)
|
||||
|
||||
static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
|
||||
{
|
||||
int iLen;
|
||||
char* szFile = get_amxstring(amx,params[1],0,iLen);
|
||||
FILE*fp;
|
||||
if ( (fp =fopen(build_pathname("%s",szFile),"r")) == NULL) {
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
char buffor[1024];
|
||||
int i = 0, iLine = params[2];
|
||||
while((i <= iLine) && fgets(buffor,1023,fp) )
|
||||
i++;
|
||||
fclose(fp);
|
||||
if (i > iLine){
|
||||
int len = strlen(buffor);
|
||||
if (buffor[len-1]=='\n')
|
||||
buffor[--len]=0;
|
||||
if (buffor[len-1]=='\r')
|
||||
buffor[--len]=0;
|
||||
cell *length = get_amxaddr(amx,params[5]);
|
||||
*length = set_amxstring(amx,params[3],buffor,params[4]);
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
int iLen;
|
||||
char* szFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
FILE *fp;
|
||||
|
||||
if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't read file \"%s\"", szFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char buffor[1024];
|
||||
int i = 0, iLine = params[2];
|
||||
|
||||
while ((i <= iLine) && fgets(buffor, 1023, fp))
|
||||
i++;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (i > iLine)
|
||||
{
|
||||
int len = strlen(buffor);
|
||||
|
||||
if (buffor[len - 1] == '\n')
|
||||
buffor[--len] = 0;
|
||||
|
||||
if (buffor[len - 1] == '\r')
|
||||
buffor[--len] = 0;
|
||||
|
||||
cell *length = get_amxaddr(amx, params[5]);
|
||||
*length = set_amxstring(amx, params[3], buffor, params[4]);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
{
|
||||
int i;
|
||||
char* sFile = build_pathname("%s", get_amxstring(amx,params[1],0,i) );
|
||||
char* sText = get_amxstring(amx,params[2],0,i);
|
||||
FILE* pFile;
|
||||
int iLine = params[3];
|
||||
int i;
|
||||
char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, i));
|
||||
char* sText = get_amxstring(amx, params[2], 0, i);
|
||||
FILE* pFile;
|
||||
int iLine = params[3];
|
||||
|
||||
// apending to the end
|
||||
if (iLine < 0) {
|
||||
if ( (pFile = fopen( sFile ,"a")) == NULL ){
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
fputs( sText , pFile );
|
||||
fputc( '\n', pFile );
|
||||
fclose( pFile );
|
||||
return 1;
|
||||
}
|
||||
// apending to the end
|
||||
if (iLine < 0)
|
||||
{
|
||||
if ((pFile = fopen(sFile, "a")) == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// creating a new file with a line in a middle
|
||||
if ( (pFile = fopen(sFile,"r")) == NULL ) {
|
||||
if ( (pFile = fopen(sFile,"w")) == NULL ){
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
for(i=0;i < iLine;++i)
|
||||
fputc('\n',pFile);
|
||||
fputs( sText , pFile );
|
||||
fputc( '\n', pFile );
|
||||
fclose(pFile);
|
||||
return 1;
|
||||
}
|
||||
fputs(sText, pFile);
|
||||
fputc('\n', pFile);
|
||||
fclose(pFile);
|
||||
|
||||
// adding a new line in a middle of already existing file
|
||||
FILE* pTemp;
|
||||
char buffor[1024];
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ( (pTemp = tmpfile()) == NULL ){
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
// creating a new file with a line in a middle
|
||||
if ((pFile = fopen(sFile, "r")) == NULL)
|
||||
{
|
||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i=0;;++i){
|
||||
if ( i == iLine ){
|
||||
fgets(buffor,1023,pFile);
|
||||
fputs( sText , pTemp );
|
||||
fputc( '\n', pTemp );
|
||||
}
|
||||
else if ( fgets(buffor,1023,pFile) ){
|
||||
fputs(buffor , pTemp );
|
||||
}
|
||||
else if ( i < iLine ) {
|
||||
fputc( '\n', pTemp );
|
||||
}
|
||||
else break;
|
||||
}
|
||||
for (i = 0; i < iLine; ++i)
|
||||
fputc('\n', pFile);
|
||||
|
||||
fclose(pFile);
|
||||
rewind(pTemp);
|
||||
fputs(sText, pFile);
|
||||
fputc('\n', pFile);
|
||||
fclose(pFile);
|
||||
|
||||
// now rewrite because file can be now smaller...
|
||||
if ( (pFile = fopen(sFile,"w")) == NULL ){
|
||||
amx_RaiseError(amx,AMX_ERR_NATIVE);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
while(fgets(buffor,1023,pTemp))
|
||||
fputs(buffor,pFile );
|
||||
// adding a new line in a middle of already existing file
|
||||
FILE* pTemp;
|
||||
char buffor[2048];
|
||||
|
||||
fclose(pTemp);
|
||||
fclose(pFile);
|
||||
return 1;
|
||||
if ((pTemp = tmpfile()) == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't create temp file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
if (i == iLine)
|
||||
{
|
||||
fgets(buffor, 2047, pFile);
|
||||
fputs(sText, pTemp);
|
||||
fputc('\n', pTemp);
|
||||
}
|
||||
else if (fgets(buffor, 2047, pFile))
|
||||
{
|
||||
fputs(buffor, pTemp);
|
||||
}
|
||||
else if (i < iLine)
|
||||
{
|
||||
fputc('\n', pTemp);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(pFile);
|
||||
rewind(pTemp);
|
||||
|
||||
// now rewrite because file can be now smaller...
|
||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (fgets(buffor, 2047, pTemp))
|
||||
fputs(buffor, pFile);
|
||||
|
||||
fclose(pTemp);
|
||||
fclose(pFile);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL delete_file(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
return (unlink( build_pathname("%s",sFile) )?0:1);
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
|
||||
return (unlink(build_pathname("%s", sFile)) ? 0 : 1);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL file_exists(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||
if ( fp != NULL) {
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
int iLen;
|
||||
char *sFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
char *file = build_pathname("%s", sFile);
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
DWORD attr = GetFileAttributes(file);
|
||||
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
return 0;
|
||||
|
||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#else
|
||||
struct stat s;
|
||||
|
||||
if (stat(file, &s) != 0)
|
||||
return 0;
|
||||
|
||||
if (S_ISDIR(s.st_mode))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char *sFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
char *file = build_pathname("%s", sFile);
|
||||
|
||||
return DirExists(file) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx,params[1],0,iLen);
|
||||
FILE* fp = fopen(build_pathname("%s",sFile),"r");
|
||||
if ( fp != NULL) {
|
||||
if ( params[0] < 2 || params[2] == 0 ){
|
||||
fseek(fp,0,SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fclose(fp);
|
||||
return size;
|
||||
}
|
||||
else if ( params[2] == 1 ){
|
||||
int a = 0,lines = 0;
|
||||
while( a != EOF ){
|
||||
++lines;
|
||||
while ( (a = fgetc(fp)) != '\n' && a != EOF )
|
||||
;
|
||||
}
|
||||
//int a, b = '\n';
|
||||
//while( (a = fgetc(fp)) != EOF ){
|
||||
// if ( a == '\n')
|
||||
// ++lines;
|
||||
// b = a;
|
||||
//}
|
||||
//if ( b != '\n' )
|
||||
// ++lines;
|
||||
return lines;
|
||||
}
|
||||
else if ( params[2] == 2 ){
|
||||
fseek(fp,-1,SEEK_END);
|
||||
if ( fgetc(fp) == '\n' )
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
int iLen;
|
||||
char* sFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
AutoFilePtr fp(fopen(build_pathname("%s", sFile), "r"));
|
||||
|
||||
if (fp != NULL)
|
||||
{
|
||||
if (params[0] < 2 || params[2] == 0)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
|
||||
return size;
|
||||
}
|
||||
else if (params[2] == 1)
|
||||
{
|
||||
int a = 0,lines = 0;
|
||||
|
||||
while (a != EOF)
|
||||
{
|
||||
++lines;
|
||||
while ((a = fgetc(fp)) != '\n' && a != EOF);
|
||||
}
|
||||
//int a, b = '\n';
|
||||
//while( (a = fgetc(fp)) != EOF ){
|
||||
// if ( a == '\n')
|
||||
// ++lines;
|
||||
// b = a;
|
||||
//}
|
||||
//if ( b != '\n' )
|
||||
// ++lines;
|
||||
return lines;
|
||||
}
|
||||
else if (params[2] == 2)
|
||||
{
|
||||
fseek(fp, -1, SEEK_END);
|
||||
|
||||
if (fgetc(fp) == '\n')
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO file_Natives[] = {
|
||||
{ "delete_file", delete_file },
|
||||
{ "file_exists", file_exists },
|
||||
{ "file_size", file_size },
|
||||
{ "read_dir", read_dir },
|
||||
{ "read_file", read_file },
|
||||
{ "write_file", write_file },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
||||
{
|
||||
int len, j = -1;
|
||||
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
|
||||
char *flags = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
FILE *fp = fopen(file, flags);
|
||||
|
||||
return (cell)fp;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite_blocks(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
size_t blocks = params[3];
|
||||
size_t btmp = blocks;
|
||||
cell mode = params[4];
|
||||
switch (mode)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
char *a = new char[blocks];
|
||||
char *ptr = a;
|
||||
while (btmp--)
|
||||
*a++ = static_cast<char>(*addr++);
|
||||
size_t res = fwrite(a, sizeof(char), blocks, fp);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
short *a = new short[blocks];
|
||||
short *ptr = a;
|
||||
while (btmp--)
|
||||
*a++ = static_cast<short>(*addr++);
|
||||
size_t res = fwrite(a, sizeof(short), blocks, fp);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
int *a = new int[blocks];
|
||||
int *ptr = a;
|
||||
while (btmp--)
|
||||
*a++ = static_cast<int>(*addr++);
|
||||
size_t res = fwrite(a, sizeof(int), blocks, fp);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
size_t mode = params[3];
|
||||
switch (mode)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
char a = static_cast<char>(params[2]);
|
||||
return fwrite(&a, sizeof(char), 1, fp);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
short b = static_cast<short>(params[2]);
|
||||
return fwrite(&b, sizeof(short), 1, fp);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
int c = static_cast<int>(params[2]);
|
||||
return fwrite(&c, sizeof(short), 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite_raw(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
return fwrite(addr, params[3], params[4], fp);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread_raw(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
size_t size = static_cast<cell>(params[3]);
|
||||
size_t blocks = static_cast<cell>(params[4]);
|
||||
|
||||
return fread(addr, size, blocks, fp);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
switch (params[3])
|
||||
{
|
||||
case 1: //char
|
||||
{
|
||||
char a;
|
||||
size_t res = fread(&a, sizeof(char), 1, fp);
|
||||
*addr = static_cast<cell>(a);
|
||||
return res;
|
||||
}
|
||||
case 2: //short
|
||||
{
|
||||
short a;
|
||||
size_t res = fread(&a, sizeof(short), 1, fp);
|
||||
*addr = static_cast<cell>(a);
|
||||
return res;
|
||||
}
|
||||
case 4: //int
|
||||
default:
|
||||
{
|
||||
int a;
|
||||
size_t res = fread(&a, sizeof(int), 1, fp);
|
||||
*addr = static_cast<cell>(a);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread_blocks(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
size_t blocks = params[3];
|
||||
switch (params[3])
|
||||
{
|
||||
case 1: //char
|
||||
{
|
||||
char *a = new char[blocks];
|
||||
char *ptr = a;
|
||||
size_t res = fread(a, sizeof(char), blocks, fp);
|
||||
while (blocks--)
|
||||
*addr++ = static_cast<cell>(*ptr++);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
case 2: //short
|
||||
{
|
||||
short *a = new short[blocks];
|
||||
short *ptr = a;
|
||||
size_t res = fread(a, sizeof(short), blocks, fp);
|
||||
while (blocks--)
|
||||
*addr++ = static_cast<cell>(*ptr++);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
case 4: //int
|
||||
default:
|
||||
{
|
||||
int *a = new int[blocks];
|
||||
int *ptr = a;
|
||||
size_t res = fread(a, sizeof(int), blocks, fp);
|
||||
while (blocks--)
|
||||
*addr++ = static_cast<cell>(*ptr++);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[2], 0, len);
|
||||
return fputs(str, fp);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
static char buffer[4096];
|
||||
buffer[0] = '\0';
|
||||
fgets(buffer, sizeof(buffer)-1, fp);
|
||||
return set_amxstring(amx, params[2], buffer, params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fseek(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return fseek(fp, params[2], params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return ftell(fp);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fprintf(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *str = format_amxstring(amx, params, 2, len);
|
||||
return fprintf(fp, "%s", str);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 1;
|
||||
|
||||
return feof(fp);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 1;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *file = build_pathname("%s", format_amxstring(amx, params, 1, len));
|
||||
long size;
|
||||
|
||||
AutoFilePtr fp(fopen(file, "rb"));
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *szPath = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
return set_amxstring(amx, params[2], build_pathname("%s", szPath), params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *path = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
char *dirname = build_pathname("%s\\*", path);
|
||||
|
||||
WIN32_FIND_DATA fd;
|
||||
HANDLE hFile = FindFirstFile(dirname, &fd);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return 0;
|
||||
|
||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
||||
|
||||
return (DWORD)hFile;
|
||||
#else
|
||||
char *dirname = build_pathname("%s", path);
|
||||
DIR *dp = opendir(dirname);
|
||||
|
||||
if (!dp)
|
||||
return NULL;
|
||||
struct dirent *ep = readdir(dp);
|
||||
|
||||
if (!ep)
|
||||
{
|
||||
closedir(dp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
set_amxstring(amx, params[2], ep->d_name, params[3]);
|
||||
|
||||
return (cell)dp;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_close_dir(AMX *amx, cell *params)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
||||
return 0;
|
||||
|
||||
FindClose(hFile);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
DIR *dp = (DIR *)params[1];
|
||||
|
||||
if (!dp)
|
||||
return 0;
|
||||
|
||||
closedir(dp);
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
|
||||
{
|
||||
#if defined WIN32 || defined _WIN32
|
||||
HANDLE hFile = (HANDLE)((DWORD)params[1]);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE || hFile == NULL)
|
||||
return 0;
|
||||
|
||||
WIN32_FIND_DATA fd;
|
||||
|
||||
if (!FindNextFile(hFile, &fd))
|
||||
return 0;
|
||||
|
||||
set_amxstring(amx, params[2], fd.cFileName, params[3]);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
DIR *dp = (DIR *)params[1];
|
||||
|
||||
if (!dp)
|
||||
return 0;
|
||||
struct dirent *ep = readdir(dp);
|
||||
|
||||
if (!ep)
|
||||
return 0;
|
||||
|
||||
set_amxstring(amx, params[2], ep->d_name, params[3]);
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
//native fgetc( file );
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return fgetc(fp);
|
||||
}
|
||||
|
||||
//native fputc( file, data );
|
||||
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return fputc(static_cast<int>(params[2]), fp);
|
||||
}
|
||||
|
||||
//native ungetc( file, data );
|
||||
static cell AMX_NATIVE_CALL amx_ungetc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return ungetc(static_cast<int>(params[2]), fp);
|
||||
}
|
||||
|
||||
#if defined __linux__
|
||||
#define _rmdir rmdir
|
||||
#endif
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_rmdir(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, len));
|
||||
|
||||
if (_rmdir(sFile) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_rename(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *fold = get_amxstring(amx, params[1], 0, len);
|
||||
char *fnew = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
#if defined __linux__
|
||||
return (rename(fold, fnew) == 0);
|
||||
#elif defined WIN32
|
||||
return MoveFileA(fold, fnew);
|
||||
#endif
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO file_Natives[] =
|
||||
{
|
||||
{"delete_file", delete_file},
|
||||
{"file_exists", file_exists},
|
||||
{"file_size", file_size},
|
||||
{"read_dir", read_dir},
|
||||
{"read_file", read_file},
|
||||
{"write_file", write_file},
|
||||
//new, sane file natives
|
||||
{"fopen", amx_fopen},
|
||||
{"fclose", amx_fclose},
|
||||
{"fread", amx_fread},
|
||||
{"fread_blocks", amx_fread_blocks},
|
||||
{"fread_raw", amx_fread_raw},
|
||||
{"fwrite", amx_fwrite},
|
||||
{"fwrite_blocks", amx_fwrite_blocks},
|
||||
{"fwrite_raw", amx_fwrite_raw},
|
||||
{"feof", amx_feof},
|
||||
{"fprintf", amx_fprintf},
|
||||
{"fgets", amx_fgets},
|
||||
{"fseek", amx_fseek},
|
||||
{"ftell", amx_ftell},
|
||||
{"filesize", amx_filesize},
|
||||
{"unlink", delete_file},
|
||||
{"build_pathname", amx_build_pathname},
|
||||
{"dir_exists", dir_exists},
|
||||
{"open_dir", amx_open_dir},
|
||||
{"close_dir", amx_close_dir},
|
||||
{"next_file", amx_get_dir},
|
||||
{"fgetc", amx_fgetc},
|
||||
{"fputc", amx_fputc},
|
||||
{"fungetc", amx_ungetc},
|
||||
{"rmdir", amx_rmdir},
|
||||
{"fputs", amx_fputs},
|
||||
{"rename_file", amx_rename},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -14,11 +14,19 @@
|
||||
* 2003-11-24: A few more native functions (geometry), plus minor modifications,
|
||||
* mostly to be compatible with dynamically loadable extension
|
||||
* modules, by Thiadmer Riemersma
|
||||
* 2004-01-09: Adaptions for 64-bit cells (using "double precision"), by
|
||||
* Thiadmer Riemersma
|
||||
*/
|
||||
#include <stdlib.h> /* for atof() */
|
||||
#include <stdio.h> /* for NULL */
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
/*
|
||||
@ -29,6 +37,19 @@
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
static REAL FromRadians(REAL angle, int radix)
|
||||
{
|
||||
switch (radix)
|
||||
{
|
||||
case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
|
||||
return (REAL)(angle / PI * 180.0);
|
||||
case 2: /* grades, centesimal system */
|
||||
return (REAL)(angle / PI * 200.0);
|
||||
default: /* assume already radian */
|
||||
return angle;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
@ -39,10 +60,10 @@ static cell AMX_NATIVE_CALL n_float(AMX *amx,cell *params)
|
||||
* params[0] = number of bytes
|
||||
* params[1] = long value to convert to a float
|
||||
*/
|
||||
float fValue;
|
||||
REAL fValue;
|
||||
|
||||
/* Convert to a float. Calls the compilers long to float conversion. */
|
||||
fValue = (float) params[1];
|
||||
fValue = (REAL) params[1];
|
||||
|
||||
/* Return the cell. */
|
||||
return amx_ftoc(fValue);
|
||||
@ -60,7 +81,7 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
||||
*/
|
||||
char szSource[60];
|
||||
cell *pString;
|
||||
float fNum;
|
||||
REAL fNum;
|
||||
int nLen;
|
||||
|
||||
/* They should have sent us 1 cell. */
|
||||
@ -71,14 +92,14 @@ static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
|
||||
|
||||
/* Find out how long the string is in characters. */
|
||||
amx_StrLen(pString, &nLen);
|
||||
if (nLen == 0 || nLen >= sizeof szSource)
|
||||
if (nLen == 0 || (unsigned int)nLen >= sizeof szSource)
|
||||
return 0;
|
||||
|
||||
/* Now convert the Small String into a C type null terminated string */
|
||||
amx_GetString(szSource, pString);
|
||||
amx_GetStringOld(szSource, pString, 0);
|
||||
|
||||
/* Now convert this to a float. */
|
||||
fNum = (float)atof(szSource);
|
||||
fNum = (REAL)atof(szSource);
|
||||
|
||||
return amx_ftoc(fNum);
|
||||
}
|
||||
@ -94,7 +115,7 @@ static cell AMX_NATIVE_CALL n_floatmul(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1
|
||||
* params[2] = float operand 2
|
||||
*/
|
||||
float fRes = amx_ctof(params[1]) * amx_ctof(params[2]);
|
||||
REAL fRes = amx_ctof(params[1]) * amx_ctof(params[2]);
|
||||
return amx_ftoc(fRes);
|
||||
}
|
||||
|
||||
@ -109,7 +130,7 @@ static cell AMX_NATIVE_CALL n_floatdiv(AMX *amx,cell *params)
|
||||
* params[1] = float dividend (top)
|
||||
* params[2] = float divisor (bottom)
|
||||
*/
|
||||
float fRes = amx_ctof(params[1]) / amx_ctof(params[2]);
|
||||
REAL fRes = amx_ctof(params[1]) / amx_ctof(params[2]);
|
||||
return amx_ftoc(fRes);
|
||||
}
|
||||
|
||||
@ -124,7 +145,7 @@ static cell AMX_NATIVE_CALL n_floatadd(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1
|
||||
* params[2] = float operand 2
|
||||
*/
|
||||
float fRes = amx_ctof(params[1]) + amx_ctof(params[2]);
|
||||
REAL fRes = amx_ctof(params[1]) + amx_ctof(params[2]);
|
||||
return amx_ftoc(fRes);
|
||||
}
|
||||
|
||||
@ -139,7 +160,7 @@ static cell AMX_NATIVE_CALL n_floatsub(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1
|
||||
* params[2] = float operand 2
|
||||
*/
|
||||
float fRes = amx_ctof(params[1]) - amx_ctof(params[2]);
|
||||
REAL fRes = amx_ctof(params[1]) - amx_ctof(params[2]);
|
||||
return amx_ftoc(fRes);
|
||||
}
|
||||
|
||||
@ -154,8 +175,8 @@ static cell AMX_NATIVE_CALL n_floatfract(AMX *amx,cell *params)
|
||||
* params[0] = number of bytes
|
||||
* params[1] = float operand
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
fA = fA - (float)(floor((double)fA));
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = fA - (REAL)(floor((double)fA));
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
@ -171,24 +192,24 @@ static cell AMX_NATIVE_CALL n_floatround(AMX *amx,cell *params)
|
||||
* params[1] = float operand
|
||||
* params[2] = Type of rounding (long)
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case 1: /* round downwards (truncate) */
|
||||
fA = (float)(floor((double)fA));
|
||||
fA = (REAL)(floor((double)fA));
|
||||
break;
|
||||
case 2: /* round upwards */
|
||||
fA = (float)(ceil((double)fA));
|
||||
fA = (REAL)(ceil((double)fA));
|
||||
break;
|
||||
case 3: /* round towards zero */
|
||||
if ( fA>=0.0 )
|
||||
fA = (float)(floor((double)fA));
|
||||
fA = (REAL)(floor((double)fA));
|
||||
else
|
||||
fA = (float)(ceil((double)fA));
|
||||
fA = (REAL)(ceil((double)fA));
|
||||
break;
|
||||
default: /* standard, round to nearest */
|
||||
fA = (float)(floor((double)fA+.5));
|
||||
fA = (REAL)(floor((double)fA+.5));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -206,7 +227,7 @@ static cell AMX_NATIVE_CALL n_floatcmp(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1
|
||||
* params[2] = float operand 2
|
||||
*/
|
||||
float fA, fB;
|
||||
REAL fA, fB;
|
||||
|
||||
fA = amx_ctof(params[1]);
|
||||
fB = amx_ctof(params[2]);
|
||||
@ -226,8 +247,8 @@ static cell AMX_NATIVE_CALL n_floatsqroot(AMX *amx,cell *params)
|
||||
* params[0] = number of bytes
|
||||
* params[1] = float operand
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
fA = (float)sqrt(fA);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = (REAL)sqrt(fA);
|
||||
if (fA < 0)
|
||||
return amx_RaiseError(amx, AMX_ERR_DOMAIN);
|
||||
return amx_ftoc(fA);
|
||||
@ -244,9 +265,9 @@ static cell AMX_NATIVE_CALL n_floatpower(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1 (base)
|
||||
* params[2] = float operand 2 (exponent)
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
float fB = amx_ctof(params[2]);
|
||||
fA = (float)pow(fA, fB);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
REAL fB = amx_ctof(params[2]);
|
||||
fA = (REAL)pow(fA, fB);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
@ -261,25 +282,25 @@ static cell AMX_NATIVE_CALL n_floatlog(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1 (value)
|
||||
* params[2] = float operand 2 (base)
|
||||
*/
|
||||
float fValue = amx_ctof(params[1]);
|
||||
float fBase = amx_ctof(params[2]);
|
||||
REAL fValue = amx_ctof(params[1]);
|
||||
REAL fBase = amx_ctof(params[2]);
|
||||
if (fValue <= 0.0 || fBase <= 0)
|
||||
return amx_RaiseError(amx, AMX_ERR_DOMAIN);
|
||||
if (fBase == 10.0) // ??? epsilon
|
||||
fValue = (float)log10(fValue);
|
||||
fValue = (REAL)log10(fValue);
|
||||
else
|
||||
fValue = (float)(log(fValue) / log(fBase));
|
||||
fValue = (REAL)(log(fValue) / log(fBase));
|
||||
return amx_ftoc(fValue);
|
||||
}
|
||||
|
||||
static float ToRadians(float angle, int radix)
|
||||
static REAL ToRadians(REAL angle, int radix)
|
||||
{
|
||||
switch (radix)
|
||||
{
|
||||
case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
|
||||
return (float)(angle * PI / 180.0);
|
||||
return (REAL)(angle * PI / 180.0);
|
||||
case 2: /* grades, centesimal system */
|
||||
return (float)(angle * PI / 200.0);
|
||||
return (REAL)(angle * PI / 200.0);
|
||||
default: /* assume already radian */
|
||||
return angle;
|
||||
} /* switch */
|
||||
@ -296,9 +317,9 @@ static cell AMX_NATIVE_CALL n_floatsin(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1 (angle)
|
||||
* params[2] = float operand 2 (radix)
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = sinf(fA); // PM: using the float version of sin
|
||||
fA = sin(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
@ -313,9 +334,9 @@ static cell AMX_NATIVE_CALL n_floatcos(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1 (angle)
|
||||
* params[2] = float operand 2 (radix)
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = cosf(fA); // PM: using the float version of cos
|
||||
fA = cos(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
@ -330,19 +351,87 @@ static cell AMX_NATIVE_CALL n_floattan(AMX *amx,cell *params)
|
||||
* params[1] = float operand 1 (angle)
|
||||
* params[2] = float operand 2 (radix)
|
||||
*/
|
||||
float fA = amx_ctof(params[1]);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = tanf(fA); // PM: using the float version of tan
|
||||
fA = tan(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by BAILOPAN */
|
||||
static cell AMX_NATIVE_CALL n_floatatan(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = atan(fA);
|
||||
fA = FromRadians(fA, params[2]);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by BAILOPAN */
|
||||
static cell AMX_NATIVE_CALL n_floatacos(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = acos(fA);
|
||||
fA = FromRadians(fA, params[2]);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by BAILOPAN */
|
||||
static cell AMX_NATIVE_CALL n_floatasin(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = asin(fA);
|
||||
fA = FromRadians(fA, params[2]);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by BAILOPAN */
|
||||
static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = x
|
||||
* params[2] = y
|
||||
* params[3] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
REAL fB = amx_ctof(params[2]);
|
||||
REAL fC;
|
||||
fC = atan2(fA, fB);
|
||||
fC = FromRadians(fC, params[3]);
|
||||
return amx_ftoc(fC);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/******************************************************************/
|
||||
static cell AMX_NATIVE_CALL n_floatabs(AMX *amx,cell *params)
|
||||
{
|
||||
float fA = amx_ctof(params[1]);
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = (fA >= 0) ? fA : -fA;
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
@ -364,6 +453,10 @@ AMX_NATIVE_INFO float_Natives[] = {
|
||||
{ "floatcos", n_floatcos },
|
||||
{ "floattan", n_floattan },
|
||||
{ "floatabs", n_floatabs },
|
||||
{ "floatasin", n_floatasin },
|
||||
{ "floatacos", n_floatacos },
|
||||
{ "floatatan", n_floatatan },
|
||||
{ "floatatan2", n_floatatan2 },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
|
434
amxmodx/format.cpp
Normal file
434
amxmodx/format.cpp
Normal file
@ -0,0 +1,434 @@
|
||||
#include "amxmodx.h"
|
||||
#include "format.h"
|
||||
|
||||
//Adapted from Quake3's vsprintf
|
||||
// thanks to cybermind for linking me to this :)
|
||||
//I made the following changes:
|
||||
// - Fixed spacing to be AMX Mod X standard
|
||||
// - Added 'n' support, no buffer overflows
|
||||
// - Templatized input/output buffers
|
||||
|
||||
#define ALT 0x00000001 /* alternate form */
|
||||
#define HEXPREFIX 0x00000002 /* add 0x or 0X prefix */
|
||||
#define LADJUST 0x00000004 /* left adjustment */
|
||||
#define LONGDBL 0x00000008 /* long double */
|
||||
#define LONGINT 0x00000010 /* long integer */
|
||||
#define QUADINT 0x00000020 /* quad integer */
|
||||
#define SHORTINT 0x00000040 /* short integer */
|
||||
#define ZEROPAD 0x00000080 /* zero (as opposed to blank) pad */
|
||||
#define FPT 0x00000100 /* floating point number */
|
||||
#define to_digit(c) ((c) - '0')
|
||||
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
|
||||
#define to_char(n) ((n) + '0')
|
||||
#define CHECK_ARGS(n) \
|
||||
if ((arg+n) > args) { \
|
||||
LogError(amx, AMX_ERR_PARAMS, "String formatted incorrectly - parameter %d (total %d)", arg, args); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
THash<String, lang_err> BadLang_Table;
|
||||
|
||||
static cvar_t *amx_mldebug = NULL;
|
||||
static cvar_t *amx_cl_langs = NULL;
|
||||
|
||||
const char *translate(AMX *amx, cell amxaddr, const char *key)
|
||||
{
|
||||
const char *pLangName = NULL;
|
||||
const char *def = NULL;
|
||||
int status;
|
||||
cell *addr = get_amxaddr(amx, amxaddr);
|
||||
char name[4];
|
||||
if (addr[0] == LANG_PLAYER)
|
||||
{
|
||||
if (!amx_cl_langs)
|
||||
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
|
||||
if ( (int)amx_cl_langs->value == 0 )
|
||||
{
|
||||
pLangName = g_vault.get("server_language");
|
||||
} else {
|
||||
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(g_langMngr.GetDefLang())->pEdict, "lang");
|
||||
}
|
||||
} else if (addr[0] == LANG_SERVER) {
|
||||
pLangName = g_vault.get("server_language");
|
||||
} else if (addr[0] >= 1 && addr[0] <= gpGlobals->maxClients) {
|
||||
if (!amx_cl_langs)
|
||||
amx_cl_langs = CVAR_GET_POINTER("amx_client_languages");
|
||||
if ( (int)amx_cl_langs->value == 0 )
|
||||
{
|
||||
pLangName = g_vault.get("server_language");
|
||||
} else {
|
||||
pLangName = ENTITY_KEYVALUE(GET_PLAYER_POINTER_I(addr[0])->pEdict, "lang");
|
||||
}
|
||||
} else {
|
||||
get_amxstring_r(amx, amxaddr, name, 3);
|
||||
pLangName = name;
|
||||
}
|
||||
if (!pLangName || !isalpha(pLangName[0]))
|
||||
pLangName = "en";
|
||||
//next parameter!
|
||||
def = g_langMngr.GetDef(pLangName, key, status);
|
||||
|
||||
if (!amx_mldebug)
|
||||
amx_mldebug = CVAR_GET_POINTER("amx_mldebug");
|
||||
|
||||
bool debug = (amx_mldebug && amx_mldebug->string && (amx_mldebug->string[0] != '\0'));
|
||||
|
||||
if (debug)
|
||||
{
|
||||
int debug_status;
|
||||
bool validlang = true;
|
||||
const char *testlang = amx_mldebug->string;
|
||||
if (!g_langMngr.LangExists(testlang))
|
||||
{
|
||||
AMXXLOG_Error("[AMXX] \"%s\" is an invalid debug language", testlang);
|
||||
validlang = false;
|
||||
}
|
||||
|
||||
g_langMngr.GetDef(testlang, key, debug_status);
|
||||
|
||||
if (validlang && debug_status == ERR_BADKEY)
|
||||
AMXXLOG_Error("[AMXX] Language key \"%s\" not found for language \"%s\", check \"%s\"", key, testlang, GetFileName(amx));
|
||||
}
|
||||
|
||||
if (def == NULL)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
if (status == ERR_BADLANG && (BadLang_Table.AltFindOrInsert(pLangName).last + 120.0f < gpGlobals->time))
|
||||
{
|
||||
AMXXLOG_Error("[AMXX] Language \"%s\" not found", pLangName);
|
||||
BadLang_Table.AltFindOrInsert(pLangName).last = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
|
||||
if (addr[0] != LANG_SERVER)
|
||||
def = g_langMngr.GetDef(g_vault.get("server_language"), key, status);
|
||||
|
||||
if (!def && (strcmp(pLangName, "en") != 0 && strcmp(g_vault.get("server_language"), "en") != 0))
|
||||
def = g_langMngr.GetDef("en", key, status);
|
||||
}
|
||||
|
||||
return def;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void AddString(U **buf_p, size_t &maxlen, const cell *string, int width, int prec)
|
||||
{
|
||||
int size = 0;
|
||||
U *buf;
|
||||
static cell nlstr[] = {'(','n','u','l','l',')','\0'};
|
||||
|
||||
buf = *buf_p;
|
||||
|
||||
if (string == NULL)
|
||||
{
|
||||
string = nlstr;
|
||||
prec = -1;
|
||||
}
|
||||
|
||||
if (prec >= 0)
|
||||
{
|
||||
for (size = 0; size < prec; size++)
|
||||
{
|
||||
if (string[size] == '\0')
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
while (string[size++]) ;
|
||||
size--;
|
||||
}
|
||||
|
||||
if (size > (int)maxlen)
|
||||
size = maxlen;
|
||||
|
||||
maxlen -= size;
|
||||
width -= size;
|
||||
|
||||
while (size--)
|
||||
*buf++ = static_cast<U>(*string++);
|
||||
|
||||
while (width-- > 0 && maxlen)
|
||||
{
|
||||
*buf++ = ' ';
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
*buf_p = buf;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void AddFloat(U **buf_p, size_t &maxlen, double fval, int width, int prec)
|
||||
{
|
||||
U text[32];
|
||||
int digits;
|
||||
double signedVal;
|
||||
U *buf;
|
||||
int val;
|
||||
|
||||
// get the sign
|
||||
signedVal = fval;
|
||||
if (fval < 0)
|
||||
fval = -fval;
|
||||
|
||||
// write the float number
|
||||
digits = 0;
|
||||
val = (int)fval;
|
||||
do {
|
||||
text[digits++] = '0' + val % 10;
|
||||
val /= 10;
|
||||
} while (val);
|
||||
|
||||
if (signedVal < 0)
|
||||
text[digits++] = '-';
|
||||
|
||||
buf = *buf_p;
|
||||
|
||||
while (digits < width && maxlen)
|
||||
{
|
||||
*buf++ = ' ';
|
||||
width--;
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
while (digits-- && maxlen)
|
||||
{
|
||||
*buf++ = text[digits];
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
*buf_p = buf;
|
||||
|
||||
if (prec < 0)
|
||||
prec = 6;
|
||||
// write the fraction
|
||||
digits = 0;
|
||||
while (digits < prec)
|
||||
{
|
||||
fval -= (int) fval;
|
||||
fval *= 10.0;
|
||||
val = (int) fval;
|
||||
text[digits++] = '0' + val % 10;
|
||||
}
|
||||
|
||||
if (digits > 0 && maxlen)
|
||||
{
|
||||
buf = *buf_p;
|
||||
*buf++ = '.';
|
||||
maxlen--;
|
||||
for (prec = 0; maxlen && prec < digits; prec++)
|
||||
{
|
||||
*buf++ = text[prec];
|
||||
maxlen--;
|
||||
}
|
||||
*buf_p = buf;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void AddInt(U **buf_p, size_t &maxlen, int val, int width, int flags)
|
||||
{
|
||||
U text[32];
|
||||
int digits;
|
||||
int signedVal;
|
||||
U *buf;
|
||||
|
||||
digits = 0;
|
||||
signedVal = val;
|
||||
if (val < 0)
|
||||
val = -val;
|
||||
do {
|
||||
text[digits++] = '0' + val % 10;
|
||||
val /= 10;
|
||||
} while (val);
|
||||
|
||||
if (signedVal < 0)
|
||||
text[digits++] = '-';
|
||||
|
||||
buf = *buf_p;
|
||||
|
||||
if( !(flags & LADJUST) )
|
||||
{
|
||||
while (digits < width && maxlen)
|
||||
{
|
||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||
width--;
|
||||
maxlen--;
|
||||
}
|
||||
}
|
||||
|
||||
while (digits-- && maxlen)
|
||||
{
|
||||
*buf++ = text[digits];
|
||||
width--;
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
if (flags & LADJUST)
|
||||
{
|
||||
while (width-- && maxlen)
|
||||
{
|
||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||
maxlen--;
|
||||
}
|
||||
}
|
||||
|
||||
*buf_p = buf;
|
||||
}
|
||||
|
||||
template <typename D, typename S>
|
||||
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param)
|
||||
{
|
||||
int arg;
|
||||
int args = params[0] / sizeof(cell);
|
||||
D *buf_p;
|
||||
D ch;
|
||||
int flags;
|
||||
int width;
|
||||
int prec;
|
||||
int n;
|
||||
char sign;
|
||||
const S *fmt;
|
||||
size_t llen = maxlen;
|
||||
|
||||
buf_p = buffer;
|
||||
arg = *param;
|
||||
fmt = format;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// run through the format string until we hit a '%' or '\0'
|
||||
for (ch = static_cast<D>(*fmt);
|
||||
llen && ((ch = static_cast<D>(*fmt)) != '\0' && ch != '%');
|
||||
fmt++)
|
||||
{
|
||||
*buf_p++ = static_cast<D>(ch);
|
||||
llen--;
|
||||
}
|
||||
if (ch == '\0' || llen <= 0)
|
||||
goto done;
|
||||
|
||||
// skip over the '%'
|
||||
fmt++;
|
||||
|
||||
// reset formatting state
|
||||
flags = 0;
|
||||
width = 0;
|
||||
prec = -1;
|
||||
sign = '\0';
|
||||
|
||||
rflag:
|
||||
ch = static_cast<D>(*fmt++);
|
||||
reswitch:
|
||||
switch(ch)
|
||||
{
|
||||
case '-':
|
||||
flags |= LADJUST;
|
||||
goto rflag;
|
||||
case '.':
|
||||
n = 0;
|
||||
while( is_digit( ( ch = static_cast<D>(*fmt++)) ) )
|
||||
n = 10 * n + ( ch - '0' );
|
||||
prec = n < 0 ? -1 : n;
|
||||
goto reswitch;
|
||||
case '0':
|
||||
flags |= ZEROPAD;
|
||||
goto rflag;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
n = 0;
|
||||
do {
|
||||
n = 10 * n + ( ch - '0' );
|
||||
ch = static_cast<D>(*fmt++);
|
||||
} while( is_digit( ch ) );
|
||||
width = n;
|
||||
goto reswitch;
|
||||
case 'c':
|
||||
CHECK_ARGS(0);
|
||||
*buf_p++ = static_cast<D>(*get_amxaddr(amx, params[arg]));
|
||||
arg++;
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
CHECK_ARGS(0);
|
||||
AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
|
||||
arg++;
|
||||
break;
|
||||
case 'f':
|
||||
CHECK_ARGS(0);
|
||||
AddFloat(&buf_p, llen, amx_ctof(*get_amxaddr(amx, params[arg])), width, prec);
|
||||
arg++;
|
||||
break;
|
||||
case 's':
|
||||
CHECK_ARGS(0);
|
||||
AddString(&buf_p, llen, get_amxaddr(amx, params[arg]), width, prec);
|
||||
arg++;
|
||||
break;
|
||||
case 'L':
|
||||
{
|
||||
CHECK_ARGS(1);
|
||||
cell addr = params[arg++];
|
||||
int len;
|
||||
const char *key = get_amxstring(amx, params[arg++], 3, len);
|
||||
const char *def = translate(amx, addr, key);
|
||||
if (!def)
|
||||
{
|
||||
static char buf[255];
|
||||
snprintf(buf, sizeof(buf)-1, "ML_NOTFOUND: %s", key);
|
||||
def = buf;
|
||||
}
|
||||
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
|
||||
buf_p += written;
|
||||
llen -= written;
|
||||
break;
|
||||
}
|
||||
case '%':
|
||||
*buf_p++ = static_cast<D>(ch);
|
||||
if (!llen)
|
||||
goto done;
|
||||
llen--;
|
||||
break;
|
||||
case '\0':
|
||||
*buf_p++ = static_cast<D>('%');
|
||||
if (!llen)
|
||||
goto done;
|
||||
llen--;
|
||||
goto done;
|
||||
break;
|
||||
default:
|
||||
*buf_p++ = static_cast<D>(ch);
|
||||
if (!llen)
|
||||
goto done;
|
||||
llen--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
*buf_p = static_cast<D>(0);
|
||||
*param = arg;
|
||||
return maxlen-llen;
|
||||
}
|
||||
|
||||
/**
|
||||
* HACKHACK: The compiler will generate code for each case we need.
|
||||
* Don't remove this, otherwise files that use certain code generations
|
||||
* will have extern problems. For each case you need, add dummy code
|
||||
* here.
|
||||
*/
|
||||
void __WHOA_DONT_CALL_ME_PLZ_K_lol_o_O()
|
||||
{
|
||||
//acsprintf
|
||||
atcprintf((cell *)NULL, 0, (const char *)NULL, NULL, NULL, NULL);
|
||||
//accprintf
|
||||
atcprintf((cell *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
|
||||
//ascprintf
|
||||
atcprintf((char *)NULL, 0, (cell *)NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
8
amxmodx/format.h
Normal file
8
amxmodx/format.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _INCLUDE_FORMATTING_H
|
||||
#define _INCLUDE_FORMATTING_H
|
||||
|
||||
//Amx Templatized Cell Printf
|
||||
template <typename D, typename S>
|
||||
size_t atcprintf(D *buffer, size_t maxlen, const S *format, AMX *amx, cell *params, int *param);
|
||||
|
||||
#endif //_INCLUDE_FORMATTING_H
|
51
amxmodx/helpers-x86.asm
Normal file
51
amxmodx/helpers-x86.asm
Normal file
@ -0,0 +1,51 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (C)2006 by David "BAILOPAN" Anderson ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;Licensed under the GNU General Public License, version 2
|
||||
;;This is a portion of AMX Mod X
|
||||
;; and is maintained by the AMX Mod X development team.
|
||||
|
||||
section .text
|
||||
|
||||
global amxx_CpuSupport, _amxx_CpuSupport
|
||||
|
||||
amxx_CpuSupport:
|
||||
_amxx_CpuSupport:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push ebx
|
||||
|
||||
mov eax, 0
|
||||
cpuid
|
||||
cmp eax, 1
|
||||
jl .fail
|
||||
|
||||
mov eax, 1
|
||||
cpuid
|
||||
;check if family == 5 or 4
|
||||
and eax, 0780h ;family mask
|
||||
shr eax, 7 ;family shift
|
||||
cmp eax, 5
|
||||
je .fail
|
||||
cmp eax, 4
|
||||
je .fail
|
||||
;check if CMOV exists
|
||||
shr edx, 15
|
||||
and edx, 1
|
||||
cmp edx, 0
|
||||
je .fail
|
||||
|
||||
mov eax, 1
|
||||
jmp .end
|
||||
|
||||
.fail:
|
||||
xor eax, eax
|
||||
|
||||
.end
|
||||
|
||||
pop ebx
|
||||
|
||||
pop ebp
|
||||
ret
|
243
amxmodx/libraries.cpp
Normal file
243
amxmodx/libraries.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
#include "libraries.h"
|
||||
#include "sh_list.h"
|
||||
|
||||
List<Library *> g_libraries;
|
||||
|
||||
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent)
|
||||
{
|
||||
if (FindLibrary(name, type))
|
||||
return false;
|
||||
|
||||
Library *lib = new Library;
|
||||
|
||||
lib->name.assign(name);
|
||||
lib->type = type;
|
||||
lib->src = src;
|
||||
lib->parent = parent;
|
||||
|
||||
g_libraries.push_back(lib);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DecodeLibCmdString(const char *str, LibDecoder *dec)
|
||||
{
|
||||
if (dec->buffer)
|
||||
{
|
||||
free(dec->buffer);
|
||||
dec->buffer = NULL;
|
||||
}
|
||||
if (str[0] != '?')
|
||||
{
|
||||
return false;
|
||||
} else {
|
||||
str++;
|
||||
if (*str == 'r')
|
||||
{
|
||||
str++;
|
||||
if (*str == 'c')
|
||||
dec->cmd = LibCmd_ReqClass;
|
||||
else if (*str == 'l')
|
||||
dec->cmd = LibCmd_ReqLib;
|
||||
else
|
||||
return false;
|
||||
str++;
|
||||
} else if (*str == 'f') {
|
||||
str++;
|
||||
dec->cmd = LibCmd_ForceLib;
|
||||
} else if (*str == 'e') {
|
||||
str++;
|
||||
if (*str == 'c')
|
||||
dec->cmd = LibCmd_ExpectClass;
|
||||
else if (*str == 'l')
|
||||
dec->cmd = LibCmd_ExpectLib;
|
||||
else
|
||||
return false;
|
||||
str++;
|
||||
} else if (*str == 'd') {
|
||||
str++;
|
||||
dec->cmd = LibCmd_DefaultLib;
|
||||
}
|
||||
if (*str != '_')
|
||||
return false;
|
||||
str++;
|
||||
if (dec->cmd < LibCmd_ExpectLib)
|
||||
{
|
||||
dec->buffer = strdup(str);
|
||||
dec->param1 = dec->buffer;
|
||||
dec->param2 = NULL;
|
||||
} else {
|
||||
dec->buffer = strdup(str);
|
||||
char *p = strchr(dec->buffer, '_');
|
||||
while (p && (*(p+1) == '_'))
|
||||
p = strchr(p+2, '_');
|
||||
if (!p || !*(p+1))
|
||||
return false;
|
||||
*p = '\0';
|
||||
dec->param1 = dec->buffer;
|
||||
dec->param2 = p+1;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent)
|
||||
{
|
||||
char buffer[255];
|
||||
char *ptr, *p, s;
|
||||
size_t count = 0;
|
||||
|
||||
snprintf(buffer, sizeof(buffer)-1, "%s", name);
|
||||
|
||||
ptr = buffer;
|
||||
p = buffer;
|
||||
while (*p)
|
||||
{
|
||||
while (*p && (*p != ','))
|
||||
p++;
|
||||
s = *p;
|
||||
*p = '\0';
|
||||
if (AddLibrary(ptr, type, src, parent))
|
||||
count++;
|
||||
if (!s)
|
||||
break;
|
||||
p++;
|
||||
while (*p && (*p == ','))
|
||||
p++;
|
||||
ptr = p;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t ClearLibraries(LibSource src)
|
||||
{
|
||||
List<Library *>::iterator iter;
|
||||
size_t count = 0;
|
||||
|
||||
iter = g_libraries.begin();
|
||||
while (iter != g_libraries.end())
|
||||
{
|
||||
if ( (*iter)->src == src )
|
||||
{
|
||||
delete (*iter);
|
||||
iter = g_libraries.erase(iter);
|
||||
count++;
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t RemoveLibraries(void *parent)
|
||||
{
|
||||
List<Library *>::iterator iter;
|
||||
Library *lib;
|
||||
size_t count = 0;
|
||||
|
||||
iter = g_libraries.begin();
|
||||
while (iter != g_libraries.end())
|
||||
{
|
||||
lib = (*iter);
|
||||
if (lib->parent == parent)
|
||||
{
|
||||
delete (*iter);
|
||||
iter = g_libraries.erase(iter);
|
||||
count++;
|
||||
} else {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool FindLibrary(const char *name, LibType type)
|
||||
{
|
||||
List<Library *>::iterator iter;
|
||||
Library *lib;
|
||||
|
||||
for (iter = g_libraries.begin(); iter != g_libraries.end(); iter++)
|
||||
{
|
||||
lib = (*iter);
|
||||
if (lib->type != type)
|
||||
continue;
|
||||
if (strcasecmp(lib->name.c_str(), name) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LibError RunLibCommand(const LibDecoder *enc)
|
||||
{
|
||||
List<Library *>::iterator iter,end;
|
||||
Library *lib;
|
||||
|
||||
iter = g_libraries.begin();
|
||||
end = g_libraries.end();
|
||||
|
||||
if ( (enc->cmd == LibCmd_ReqLib) || (enc->cmd == LibCmd_ReqClass) )
|
||||
{
|
||||
LibType expect;
|
||||
|
||||
if (enc->cmd == LibCmd_ReqLib)
|
||||
expect = LibType_Library;
|
||||
else if (enc->cmd == LibCmd_ReqClass)
|
||||
expect = LibType_Class;
|
||||
|
||||
/** see if it exists */
|
||||
for (; iter != end; iter++)
|
||||
{
|
||||
lib = (*iter);
|
||||
if (lib->type != expect)
|
||||
continue;
|
||||
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
|
||||
return LibErr_None;
|
||||
}
|
||||
if (expect == LibType_Library)
|
||||
return LibErr_NoLibrary;
|
||||
else if (expect = LibType_Class)
|
||||
return LibErr_NoClass;
|
||||
|
||||
return LibErr_NoLibrary;
|
||||
} else if (enc->cmd == LibCmd_ForceLib) {
|
||||
if (!LoadModule(enc->param1, PT_ANYTIME, true, true))
|
||||
{
|
||||
return LibErr_NoLibrary;
|
||||
}
|
||||
} else if ( (enc->cmd == LibCmd_DefaultLib) ||
|
||||
((enc->cmd == LibCmd_ExpectLib) || (enc->cmd == LibCmd_ExpectClass)) )
|
||||
{
|
||||
LibType expect;
|
||||
|
||||
if (enc->cmd == LibCmd_ExpectLib)
|
||||
expect = LibType_Library;
|
||||
else
|
||||
expect = LibType_Class;
|
||||
|
||||
/** see if it exists */
|
||||
for (; iter != end; iter++)
|
||||
{
|
||||
lib = (*iter);
|
||||
if (lib->type != expect)
|
||||
continue;
|
||||
if (strcasecmp(lib->name.c_str(), enc->param1) == 0)
|
||||
return LibErr_None;
|
||||
}
|
||||
|
||||
if (!LoadModule(enc->param2, PT_ANYTIME, true, true))
|
||||
{
|
||||
return LibErr_NoLibrary;
|
||||
}
|
||||
|
||||
return LibErr_None;
|
||||
}
|
||||
|
||||
return LibErr_None;
|
||||
}
|
73
amxmodx/libraries.h
Normal file
73
amxmodx/libraries.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef _INCLUDE_LIBRARIES_H
|
||||
#define _INCLUDE_LIBRARIES_H
|
||||
|
||||
#include <string.h>
|
||||
#include "amxmodx.h"
|
||||
#include "CString.h"
|
||||
|
||||
enum LibSource
|
||||
{
|
||||
LibSource_Plugin,
|
||||
LibSource_Module
|
||||
};
|
||||
|
||||
enum LibType
|
||||
{
|
||||
LibType_Library,
|
||||
LibType_Class
|
||||
};
|
||||
|
||||
struct Library
|
||||
{
|
||||
String name;
|
||||
LibSource src;
|
||||
LibType type;
|
||||
void *parent;
|
||||
};
|
||||
|
||||
enum LibCmd
|
||||
{
|
||||
LibCmd_ReqLib,
|
||||
LibCmd_ReqClass,
|
||||
LibCmd_ForceLib,
|
||||
LibCmd_ExpectLib,
|
||||
LibCmd_ExpectClass,
|
||||
LibCmd_DefaultLib,
|
||||
};
|
||||
|
||||
enum LibError
|
||||
{
|
||||
LibErr_None = 0,
|
||||
LibErr_NoLibrary,
|
||||
LibErr_NoClass,
|
||||
};
|
||||
|
||||
class LibDecoder
|
||||
{
|
||||
public:
|
||||
LibDecoder() : buffer(NULL)
|
||||
{
|
||||
}
|
||||
~LibDecoder()
|
||||
{
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
param1 = NULL;
|
||||
param2 = NULL;
|
||||
}
|
||||
char *buffer;
|
||||
char *param1;
|
||||
char *param2;
|
||||
LibCmd cmd;
|
||||
};
|
||||
|
||||
bool AddLibrary(const char *name, LibType type, LibSource src, void *parent=NULL);
|
||||
bool DecodeLibCmdString(const char *str, LibDecoder *cmd);
|
||||
size_t AddLibrariesFromString(const char *name, LibType type, LibSource src, void *parent=NULL);
|
||||
size_t ClearLibraries(LibSource src);
|
||||
LibError RunLibCommand(const LibDecoder *enc);
|
||||
size_t RemoveLibraries(void *parent);
|
||||
bool FindLibrary(const char *name, LibType type);
|
||||
|
||||
|
||||
#endif //_INCLUDE_LIBRARIES_H
|
474
amxmodx/md5.cpp
Executable file
474
amxmodx/md5.cpp
Executable file
@ -0,0 +1,474 @@
|
||||
// MD5.CC - source code for the C++/object oriented translation and
|
||||
// modification of MD5.
|
||||
|
||||
// Translation and modification (c) 1995 by Mordechai T. Abzug
|
||||
|
||||
// This translation/ modification is provided "as is," without express or
|
||||
// implied warranty of any kind.
|
||||
|
||||
// The translator/ modifier does not claim (1) that MD5 will do what you think
|
||||
// it does; (2) that this translation/ modification is accurate; or (3) that
|
||||
// this software is "merchantible." (Language for this disclaimer partially
|
||||
// copied from the disclaimer below).
|
||||
|
||||
/* based on:
|
||||
|
||||
MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||
MDDRIVER.C - test driver for MD2, MD4 and MD5
|
||||
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
// MD5 simple initialization method
|
||||
|
||||
MD5::MD5(){
|
||||
|
||||
init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MD5 block update operation. Continues an MD5 message-digest
|
||||
// operation, processing another message block, and updating the
|
||||
// context.
|
||||
|
||||
void MD5::update (uint1 *input, uint4 input_length) {
|
||||
|
||||
uint4 input_index, buffer_index;
|
||||
uint4 buffer_space; // how much space is left in buffer
|
||||
|
||||
if (finalized){ // so we can't update!
|
||||
/*cerr << "MD5::update: Can't update a finalized digest!" << endl;*/
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute number of bytes mod 64
|
||||
buffer_index = (unsigned int)((count[0] >> 3) & 0x3F);
|
||||
|
||||
// Update number of bits
|
||||
if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) )
|
||||
count[1]++;
|
||||
|
||||
count[1] += ((uint4)input_length >> 29);
|
||||
|
||||
|
||||
buffer_space = 64 - buffer_index; // how much space is left in buffer
|
||||
|
||||
// Transform as many times as possible.
|
||||
if (input_length >= buffer_space) { // ie. we have enough to fill the buffer
|
||||
// fill the rest of the buffer and transform
|
||||
memcpy (buffer + buffer_index, input, buffer_space);
|
||||
transform (buffer);
|
||||
|
||||
// now, transform each 64-byte piece of the input, bypassing the buffer
|
||||
for (input_index = buffer_space; input_index + 63 < input_length;
|
||||
input_index += 64)
|
||||
transform (input+input_index);
|
||||
|
||||
buffer_index = 0; // so we can buffer remaining
|
||||
}
|
||||
else
|
||||
input_index=0; // so we can buffer the whole input
|
||||
|
||||
|
||||
// and here we do the buffering:
|
||||
memcpy(buffer+buffer_index, input+input_index, input_length-input_index);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MD5 update for files.
|
||||
// Like above, except that it works on files (and uses above as a primitive.)
|
||||
|
||||
void MD5::update(FILE *file){
|
||||
|
||||
unsigned char buffer[1024];
|
||||
int len;
|
||||
|
||||
while (len=fread(buffer, 1, 1024, file))
|
||||
update(buffer, len);
|
||||
|
||||
fclose (file);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
// the message digest and zeroizing the context.
|
||||
|
||||
|
||||
void MD5::finalize (){
|
||||
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
static uint1 PADDING[64]={
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
if (finalized){
|
||||
/* cerr << "MD5::finalize: Already finalized this digest!" << endl;*/
|
||||
return;
|
||||
}
|
||||
|
||||
// Save number of bits
|
||||
encode (bits, count, 8);
|
||||
|
||||
// Pad out to 56 mod 64.
|
||||
index = (uint4) ((count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
update (PADDING, padLen);
|
||||
|
||||
// Append length (before padding)
|
||||
update (bits, 8);
|
||||
|
||||
// Store state in digest
|
||||
encode (digest, state, 16);
|
||||
|
||||
// Zeroize sensitive information
|
||||
memset (buffer, 0, sizeof(*buffer));
|
||||
|
||||
finalized=1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
MD5::MD5(FILE *file){
|
||||
|
||||
init(); // must be called be all constructors
|
||||
update(file);
|
||||
finalize ();
|
||||
}
|
||||
|
||||
unsigned char *MD5::raw_digest(){
|
||||
|
||||
uint1 *s = new uint1[16];
|
||||
|
||||
if (!finalized){
|
||||
/* cerr << "MD5::raw_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return ( (unsigned char*) "");
|
||||
}
|
||||
|
||||
memcpy(s, digest, 16);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *MD5::hex_digest(){
|
||||
|
||||
int i;
|
||||
char *s= new char[33];
|
||||
|
||||
if (!finalized){
|
||||
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(s+i*2, "%02x", digest[i]);
|
||||
|
||||
s[32]='\0';
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
char *MD5::hex_digest(char buffer[33]){
|
||||
|
||||
int i;
|
||||
|
||||
if (!finalized)
|
||||
{
|
||||
/* cerr << "MD5::hex_digest: Can't get digest if you haven't "<<
|
||||
"finalized the digest!" <<endl;*/
|
||||
return "";
|
||||
}
|
||||
|
||||
for (i=0; i<16; i++)
|
||||
sprintf(buffer+i*2, "%02x", digest[i]);
|
||||
|
||||
buffer[32]='\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
// PRIVATE METHODS:
|
||||
|
||||
|
||||
|
||||
void MD5::init(){
|
||||
finalized=0; // we just started!
|
||||
|
||||
// Nothing counted, so count=0
|
||||
count[0] = 0;
|
||||
count[1] = 0;
|
||||
|
||||
// Load magic initialization constants.
|
||||
state[0] = 0x67452301;
|
||||
state[1] = 0xefcdab89;
|
||||
state[2] = 0x98badcfe;
|
||||
state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Constants for MD5Transform routine.
|
||||
// Although we could use C++ style constants, defines are actually better,
|
||||
// since they let us easily evade scope clashes.
|
||||
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
|
||||
|
||||
|
||||
// MD5 basic transformation. Transforms state based on block.
|
||||
void MD5::transform (uint1 block[64]){
|
||||
|
||||
uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
decode (x, block, 64);
|
||||
|
||||
assert(!finalized); // not just a user error, since the method is private
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
// Zeroize sensitive information.
|
||||
memset ( (uint1 *) x, 0, sizeof(x));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Encodes input (UINT4) into output (unsigned char). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::encode (uint1 *output, uint4 *input, uint4 len) {
|
||||
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (uint1) (input[i] & 0xff);
|
||||
output[j+1] = (uint1) ((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (uint1) ((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (uint1) ((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Decodes input (unsigned char) into output (UINT4). Assumes len is
|
||||
// a multiple of 4.
|
||||
void MD5::decode (uint4 *output, uint1 *input, uint4 len){
|
||||
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) |
|
||||
(((uint4)input[j+2]) << 16) | (((uint4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Note: Replace "for loop" with standard memcpy if possible.
|
||||
void MD5::memcpy (uint1 *output, uint1 *input, uint4 len){
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output[i] = input[i];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Note: Replace "for loop" with standard memset if possible.
|
||||
void MD5::memset (uint1 *output, uint1 value, uint4 len){
|
||||
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
output[i] = value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ROTATE_LEFT rotates x left n bits.
|
||||
|
||||
inline unsigned int MD5::rotate_left (uint4 x, uint4 n){
|
||||
return (x << n) | (x >> (32-n)) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// F, G, H and I are basic MD5 functions.
|
||||
|
||||
inline unsigned int MD5::F (uint4 x, uint4 y, uint4 z){
|
||||
return (x & y) | (~x & z);
|
||||
}
|
||||
|
||||
inline unsigned int MD5::G (uint4 x, uint4 y, uint4 z){
|
||||
return (x & z) | (y & ~z);
|
||||
}
|
||||
|
||||
inline unsigned int MD5::H (uint4 x, uint4 y, uint4 z){
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
|
||||
inline unsigned int MD5::I (uint4 x, uint4 y, uint4 z){
|
||||
return y ^ (x | ~z);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
// Rotation is separate from addition to prevent recomputation.
|
||||
|
||||
|
||||
inline void MD5::FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += F(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += G(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += H(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
||||
|
||||
inline void MD5::II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac){
|
||||
a += I(b, c, d) + x + ac;
|
||||
a = rotate_left (a, s) +b;
|
||||
}
|
105
amxmodx/md5.h
Executable file
105
amxmodx/md5.h
Executable file
@ -0,0 +1,105 @@
|
||||
// MD5.CC - source code for the C++/object oriented translation and
|
||||
// modification of MD5.
|
||||
|
||||
// Translation and modification (c) 1995 by Mordechai T. Abzug
|
||||
|
||||
// This translation/ modification is provided "as is," without express or
|
||||
// implied warranty of any kind.
|
||||
|
||||
// The translator/ modifier does not claim (1) that MD5 will do what you think
|
||||
// it does; (2) that this translation/ modification is accurate; or (3) that
|
||||
// this software is "merchantible." (Language for this disclaimer partially
|
||||
// copied from the disclaimer below).
|
||||
|
||||
/* based on:
|
||||
|
||||
MD5.H - header file for MD5C.C
|
||||
MDDRIVER.C - test driver for MD2, MD4 and MD5
|
||||
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
//#include <fstream.h>
|
||||
//#include <iostream.h>
|
||||
|
||||
class MD5 {
|
||||
|
||||
public:
|
||||
// methods for controlled operation:
|
||||
MD5 (); // simple initializer
|
||||
void update (unsigned char *input, unsigned int input_length);
|
||||
void update (FILE *file);
|
||||
void finalize ();
|
||||
|
||||
// constructors for special circumstances. All these constructors finalize
|
||||
// the MD5 context.
|
||||
MD5 (unsigned char *string); // digest string, finalize
|
||||
MD5 (FILE *file); // digest file, close, finalize
|
||||
|
||||
// methods to acquire finalized result
|
||||
unsigned char *raw_digest (); // digest as a 16-byte binary array
|
||||
char * hex_digest (); // digest as a 33-byte ascii-hex string
|
||||
char * hex_digest (char buffer[33]); //same as above, passing buffer
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
// first, some types:
|
||||
typedef unsigned int uint4; // assumes integer is 4 words long
|
||||
typedef unsigned short int uint2; // assumes short integer is 2 words long
|
||||
typedef unsigned char uint1; // assumes char is 1 word long
|
||||
|
||||
// next, the private data:
|
||||
uint4 state[4];
|
||||
uint4 count[2]; // number of *bits*, mod 2^64
|
||||
uint1 buffer[64]; // input buffer
|
||||
uint1 digest[16];
|
||||
uint1 finalized;
|
||||
|
||||
// last, the private methods, mostly static:
|
||||
void init (); // called by all constructors
|
||||
void transform (uint1 *buffer); // does the real update work. Note
|
||||
// that length is implied to be 64.
|
||||
|
||||
static void encode (uint1 *dest, uint4 *src, uint4 length);
|
||||
static void decode (uint4 *dest, uint1 *src, uint4 length);
|
||||
static void memcpy (uint1 *dest, uint1 *src, uint4 length);
|
||||
static void memset (uint1 *start, uint1 val, uint4 length);
|
||||
|
||||
static inline uint4 rotate_left (uint4 x, uint4 n);
|
||||
static inline uint4 F (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 G (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 H (uint4 x, uint4 y, uint4 z);
|
||||
static inline uint4 I (uint4 x, uint4 y, uint4 z);
|
||||
static inline void FF (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void GG (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void HH (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
static inline void II (uint4& a, uint4 b, uint4 c, uint4 d, uint4 x,
|
||||
uint4 s, uint4 ac);
|
||||
|
||||
};
|
805
amxmodx/messages.cpp
Executable file
805
amxmodx/messages.cpp
Executable file
@ -0,0 +1,805 @@
|
||||
#include "amxmodx.h"
|
||||
#include "messages.h"
|
||||
|
||||
Message Msg;
|
||||
CVector<int> msgHooks[256];
|
||||
int msgBlocks[256] = {BLOCK_NOT};
|
||||
int msgDest;
|
||||
int msgType;
|
||||
float *msgOrigin;
|
||||
edict_t *msgpEntity;
|
||||
bool inhook = false;
|
||||
bool inblock = false;
|
||||
enginefuncs_t *g_pEngTable = NULL;
|
||||
|
||||
void ClearMessages()
|
||||
{
|
||||
for (size_t i=0; i<MAX_MESSAGES; i++)
|
||||
{
|
||||
msgHooks[i].clear();
|
||||
msgBlocks[i] = BLOCK_NOT;
|
||||
}
|
||||
}
|
||||
|
||||
Message::Message()
|
||||
{
|
||||
m_CurParam = 0;
|
||||
}
|
||||
|
||||
bool Message::Ready()
|
||||
{
|
||||
if (!m_Params.size())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Message::Init()
|
||||
{
|
||||
if (!Ready())
|
||||
{
|
||||
msgparam *p = new msgparam;
|
||||
m_Params.push_back(p);
|
||||
}
|
||||
m_CurParam = 0;
|
||||
}
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
for (size_t i=0; i<m_Params.size(); i++)
|
||||
delete m_Params[i];
|
||||
|
||||
m_Params.clear();
|
||||
}
|
||||
|
||||
msgparam *Message::AdvPtr()
|
||||
{
|
||||
msgparam *pParam = NULL;
|
||||
|
||||
if (++m_CurParam >= m_Params.size())
|
||||
{
|
||||
pParam = new msgparam;
|
||||
m_Params.push_back(pParam);
|
||||
} else {
|
||||
pParam = m_Params[m_CurParam];
|
||||
}
|
||||
|
||||
return pParam;
|
||||
}
|
||||
|
||||
void Message::AddParam(const char *data, msgtype type)
|
||||
{
|
||||
msgparam *pParam = AdvPtr();
|
||||
|
||||
pParam->szData.assign(data);
|
||||
pParam->type = type;
|
||||
}
|
||||
|
||||
void Message::AddParam(int data, msgtype type)
|
||||
{
|
||||
msgparam *pParam = AdvPtr();
|
||||
|
||||
pParam->v.iData = data;
|
||||
pParam->type = type;
|
||||
}
|
||||
|
||||
void Message::AddParam(float data, msgtype type)
|
||||
{
|
||||
msgparam *pParam = AdvPtr();
|
||||
|
||||
pParam->v.fData = data;
|
||||
pParam->type = type;
|
||||
}
|
||||
|
||||
msgtype Message::GetParamType(size_t index)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return static_cast<msgtype>(0);
|
||||
|
||||
return m_Params[index]->type;
|
||||
}
|
||||
|
||||
float Message::GetParamFloat(size_t index)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return 0;
|
||||
|
||||
return m_Params[index]->v.fData;
|
||||
}
|
||||
|
||||
const char *Message::GetParamString(size_t index)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return 0;
|
||||
|
||||
return m_Params[index]->szData.c_str();
|
||||
}
|
||||
|
||||
int Message::GetParamInt(size_t index)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return 0;
|
||||
|
||||
return m_Params[index]->v.iData;
|
||||
}
|
||||
|
||||
void Message::SetParam(size_t index, float data)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return;
|
||||
|
||||
m_Params[index]->v.fData = data;
|
||||
}
|
||||
|
||||
void Message::SetParam(size_t index, int data)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return;
|
||||
|
||||
m_Params[index]->v.iData = data;
|
||||
}
|
||||
|
||||
void Message::SetParam(size_t index, const char *data)
|
||||
{
|
||||
if (index < 1 || index > m_CurParam)
|
||||
return;
|
||||
|
||||
m_Params[index]->szData.assign(data);
|
||||
}
|
||||
|
||||
void Message::Reset()
|
||||
{
|
||||
m_CurParam = 0;
|
||||
}
|
||||
|
||||
size_t Message::Params()
|
||||
{
|
||||
return m_CurParam;
|
||||
}
|
||||
|
||||
void Message::Send()
|
||||
{
|
||||
msgparam *pParam = NULL;
|
||||
|
||||
for (size_t i=1; i<=m_CurParam; i++)
|
||||
{
|
||||
pParam = m_Params[i];
|
||||
switch (pParam->type)
|
||||
{
|
||||
case arg_byte:
|
||||
WRITE_BYTE(pParam->v.iData);
|
||||
break;
|
||||
case arg_char:
|
||||
WRITE_CHAR(pParam->v.iData);
|
||||
break;
|
||||
case arg_short:
|
||||
WRITE_SHORT(pParam->v.iData);
|
||||
break;
|
||||
case arg_long:
|
||||
WRITE_LONG(pParam->v.iData);
|
||||
break;
|
||||
case arg_angle:
|
||||
WRITE_ANGLE(pParam->v.fData);
|
||||
break;
|
||||
case arg_coord:
|
||||
WRITE_COORD(pParam->v.fData);
|
||||
break;
|
||||
case arg_string:
|
||||
WRITE_STRING(pParam->szData.c_str());
|
||||
break;
|
||||
case arg_entity:
|
||||
WRITE_ENTITY(pParam->v.iData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed)
|
||||
{
|
||||
if (msgBlocks[msg_type])
|
||||
{
|
||||
inblock = true;
|
||||
msgType = msg_type;
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (msgHooks[msg_type].size()) {
|
||||
inhook = true;
|
||||
msgDest = msg_dest;
|
||||
msgType = msg_type;
|
||||
msgOrigin = (float *)pOrigin;
|
||||
msgpEntity = ed;
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteByte(int iValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(iValue, arg_byte);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteChar(int iValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(iValue, arg_char);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteShort(int iValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(iValue, arg_short);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteLong(int iValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(iValue, arg_long);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteAngle(float flValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(flValue, arg_angle);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteCoord(float flValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(flValue, arg_coord);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteString(const char *sz)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(sz, arg_string);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_WriteEntity(int iValue)
|
||||
{
|
||||
if (inblock)
|
||||
{
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
Msg.AddParam(iValue, arg_entity);
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
void C_MessageEnd(void)
|
||||
{
|
||||
int mres = 0, mresB = 0;
|
||||
unsigned int i = 0;
|
||||
if (inblock)
|
||||
{
|
||||
inblock = false;
|
||||
if (msgBlocks[msgType] == BLOCK_ONCE)
|
||||
{
|
||||
msgBlocks[msgType] = BLOCK_NOT;
|
||||
}
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
for (i=0; i<msgHooks[msgType].size(); i++)
|
||||
{
|
||||
mresB = executeForwards(msgHooks[msgType].at(i), (cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
||||
if (mresB > mres)
|
||||
mres = mresB;
|
||||
}
|
||||
inhook = false;
|
||||
if (mres & 1)
|
||||
{
|
||||
Msg.Reset();
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
/* send the real message */
|
||||
MESSAGE_BEGIN(msgDest, msgType, msgOrigin, msgpEntity);
|
||||
Msg.Send();
|
||||
MESSAGE_END();
|
||||
|
||||
/* reset */
|
||||
Msg.Reset();
|
||||
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL message_begin(AMX *amx, cell *params) /* 4 param */
|
||||
{
|
||||
int numparam = *params / sizeof(cell);
|
||||
float vecOrigin[3];
|
||||
cell *cpOrigin;
|
||||
|
||||
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
|
||||
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[1])
|
||||
{
|
||||
case MSG_BROADCAST:
|
||||
case MSG_ALL:
|
||||
case MSG_SPEC:
|
||||
MESSAGE_BEGIN(params[1], params[2], NULL);
|
||||
break;
|
||||
case MSG_PVS: case MSG_PAS:
|
||||
case MSG_PVS_R: case MSG_PAS_R:
|
||||
if (numparam < 3)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpOrigin = get_amxaddr(amx, params[3]);
|
||||
|
||||
vecOrigin[0] = static_cast<float>(*cpOrigin);
|
||||
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
|
||||
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
|
||||
|
||||
MESSAGE_BEGIN(params[1], params[2], vecOrigin);
|
||||
|
||||
break;
|
||||
case MSG_ONE_UNRELIABLE:
|
||||
case MSG_ONE:
|
||||
if (numparam < 4)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
MESSAGE_BEGIN(params[1], params[2], NULL, INDEXENT(params[4]));
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL message_end(AMX *amx, cell *params)
|
||||
{
|
||||
MESSAGE_END();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_byte(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_BYTE(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_char(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_CHAR(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_short(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_SHORT(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_long(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_LONG(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_entity(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_ENTITY(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_angle(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_ANGLE(static_cast<float>(params[1]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_coord(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
WRITE_COORD(static_cast<float>(params[1]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL write_string(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int a;
|
||||
WRITE_STRING(get_amxstring(amx, params[1], 3, a));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL register_message(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *name = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
if (!Msg.Ready())
|
||||
Msg.Init();
|
||||
|
||||
if (params[1]>0 && params[1] < 256)
|
||||
{
|
||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (id != -1)
|
||||
{
|
||||
msgHooks[params[1]].push_back(id);
|
||||
return id;
|
||||
} else {
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_msg_block(AMX *amx, cell *params)
|
||||
{
|
||||
int msgid = params[1];
|
||||
int block = params[2];
|
||||
|
||||
if (msgid < 1 || msgid > 255)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
|
||||
return 0;
|
||||
}
|
||||
|
||||
msgBlocks[msgid] = block;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_block(AMX *amx, cell *params)
|
||||
{
|
||||
int msgid = params[1];
|
||||
|
||||
if (msgid < 1 || msgid > 255)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message id");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return msgBlocks[msgid];
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_args(AMX *amx, cell *params)
|
||||
{
|
||||
return Msg.Params();
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_argtype(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Msg.GetParamType(argn);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_arg_int(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Msg.GetParamInt(argn);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_msg_arg_int(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Msg.SetParam(argn, (int)params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_arg_float(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL f = (REAL)Msg.GetParamFloat(argn);
|
||||
return amx_ftoc(f);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_msg_arg_float(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
REAL fVal = amx_ctof(params[3]);
|
||||
|
||||
Msg.SetParam(argn, (float)fVal);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_arg_string(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *szVal = Msg.GetParamString(argn);
|
||||
|
||||
return set_amxstring(amx, params[2], szVal, params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL set_msg_arg_string(AMX *amx, cell *params)
|
||||
{
|
||||
size_t argn = static_cast<size_t>(params[1]);
|
||||
int iLen;
|
||||
|
||||
if (!inhook || argn > Msg.Params())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid message argument %d", argn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *szVal = get_amxstring(amx, params[2], 0, iLen);
|
||||
|
||||
Msg.SetParam(argn, szVal);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL get_msg_origin(AMX *amx, cell *params)
|
||||
{
|
||||
if (!inhook)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not in a message hook");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell *cAddr = get_amxaddr(amx, params[1]);
|
||||
|
||||
if (msgDest >= MSG_PVS && msgDest <= MSG_PAS_R)
|
||||
{
|
||||
vec3_t vRet = (Vector)msgOrigin;
|
||||
cAddr[0] = FloatToCell(vRet.x);
|
||||
cAddr[1] = FloatToCell(vRet.y);
|
||||
cAddr[2] = FloatToCell(vRet.z);
|
||||
} else {
|
||||
cAddr[0] = 0;
|
||||
cAddr[1] = 0;
|
||||
cAddr[2] = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL emessage_begin(AMX *amx, cell *params) /* 4 param */
|
||||
{
|
||||
int numparam = *params / sizeof(cell);
|
||||
float vecOrigin[3];
|
||||
cell *cpOrigin;
|
||||
|
||||
if (params[2] < 1 || ((params[2] > 63) // maximal number of engine messages
|
||||
&& !GET_USER_MSG_NAME(PLID, params[2], NULL)))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Plugin called message_begin with an invalid message id (%d).", params[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[1])
|
||||
{
|
||||
case MSG_BROADCAST:
|
||||
case MSG_ALL:
|
||||
case MSG_SPEC:
|
||||
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, NULL);
|
||||
break;
|
||||
case MSG_PVS: case MSG_PAS:
|
||||
case MSG_PVS_R: case MSG_PAS_R:
|
||||
if (numparam < 3)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpOrigin = get_amxaddr(amx, params[3]);
|
||||
|
||||
vecOrigin[0] = static_cast<float>(*cpOrigin);
|
||||
vecOrigin[1] = static_cast<float>(*(cpOrigin + 1));
|
||||
vecOrigin[2] = static_cast<float>(*(cpOrigin + 2));
|
||||
|
||||
g_pEngTable->pfnMessageBegin(params[1], params[2], vecOrigin, NULL);
|
||||
|
||||
break;
|
||||
case MSG_ONE_UNRELIABLE:
|
||||
case MSG_ONE:
|
||||
if (numparam < 4)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid number of parameters passed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_pEngTable->pfnMessageBegin(params[1], params[2], NULL, INDEXENT(params[4]));
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL emessage_end(AMX *amx, cell *params)
|
||||
{
|
||||
g_pEngTable->pfnMessageEnd();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_byte(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteByte(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_char(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteChar(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_short(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteShort(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_long(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteLong(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_entity(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteEntity(params[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_angle(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteAngle(static_cast<float>(params[1]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_coord(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
g_pEngTable->pfnWriteCoord(static_cast<float>(params[1]));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL ewrite_string(AMX *amx, cell *params) /* 1 param */
|
||||
{
|
||||
int a;
|
||||
g_pEngTable->pfnWriteString(get_amxstring(amx, params[1], 3, a));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO msg_Natives[] =
|
||||
{
|
||||
{"message_begin", message_begin},
|
||||
{"message_end", message_end},
|
||||
|
||||
{"write_angle", write_angle},
|
||||
{"write_byte", write_byte},
|
||||
{"write_char", write_char},
|
||||
{"write_coord", write_coord},
|
||||
{"write_entity", write_entity},
|
||||
{"write_long", write_long},
|
||||
{"write_short", write_short},
|
||||
{"write_string", write_string},
|
||||
|
||||
{"register_message", register_message},
|
||||
|
||||
{"set_msg_block", set_msg_block},
|
||||
{"get_msg_block", get_msg_block},
|
||||
|
||||
{"get_msg_args", get_msg_args},
|
||||
{"get_msg_argtype", get_msg_argtype},
|
||||
{"get_msg_arg_int", get_msg_arg_int},
|
||||
{"set_msg_arg_int", set_msg_arg_int},
|
||||
{"get_msg_arg_float", get_msg_arg_float},
|
||||
{"set_msg_arg_float", set_msg_arg_float},
|
||||
{"get_msg_arg_string", get_msg_arg_string},
|
||||
{"set_msg_arg_string", set_msg_arg_string},
|
||||
{"get_msg_origin", get_msg_origin},
|
||||
|
||||
{"emessage_begin", emessage_begin},
|
||||
{"emessage_end", emessage_end},
|
||||
|
||||
{"ewrite_angle", ewrite_angle},
|
||||
{"ewrite_byte", ewrite_byte},
|
||||
{"ewrite_char", ewrite_char},
|
||||
{"ewrite_coord", ewrite_coord},
|
||||
{"ewrite_entity", ewrite_entity},
|
||||
{"ewrite_long", ewrite_long},
|
||||
{"ewrite_short", ewrite_short},
|
||||
{"ewrite_string", ewrite_string},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
83
amxmodx/messages.h
Executable file
83
amxmodx/messages.h
Executable file
@ -0,0 +1,83 @@
|
||||
#ifndef _MSGS_INCLUDE_H
|
||||
#define _MSGS_INCLUDE_H
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amx.h"
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
|
||||
#define MAX_MESSAGES 255
|
||||
|
||||
#define BLOCK_NOT 0
|
||||
#define BLOCK_ONCE 1
|
||||
#define BLOCK_SET 2
|
||||
|
||||
enum msgtype
|
||||
{
|
||||
arg_byte = 1,
|
||||
arg_char,
|
||||
arg_short,
|
||||
arg_long,
|
||||
arg_angle,
|
||||
arg_coord,
|
||||
arg_string,
|
||||
arg_entity,
|
||||
};
|
||||
|
||||
struct msgparam
|
||||
{
|
||||
msgtype type;
|
||||
union
|
||||
{
|
||||
REAL fData;
|
||||
int iData;
|
||||
} v;
|
||||
String szData;
|
||||
};
|
||||
|
||||
class Message
|
||||
{
|
||||
public:
|
||||
Message();
|
||||
~Message();
|
||||
void AddParam(float data, msgtype type);
|
||||
void AddParam(int data, msgtype type);
|
||||
void AddParam(const char *data, msgtype type);
|
||||
void SetParam(size_t index, float data);
|
||||
void SetParam(size_t index, int data);
|
||||
void SetParam(size_t index, const char *data);
|
||||
const char *GetParamString(size_t index);
|
||||
float GetParamFloat(size_t index);
|
||||
bool Ready();
|
||||
void Init();
|
||||
int GetParamInt(size_t index);
|
||||
msgtype GetParamType(size_t index);
|
||||
void Reset();
|
||||
void Send();
|
||||
size_t Params();
|
||||
private:
|
||||
msgparam *AdvPtr();
|
||||
private:
|
||||
CVector<msgparam *> m_Params;
|
||||
size_t m_CurParam;
|
||||
};
|
||||
|
||||
void C_MessageBegin(int msg_dest, int msg_type, const float *pOrigin, edict_t *ed);
|
||||
void C_WriteByte(int iValue);
|
||||
void C_WriteChar(int iValue);
|
||||
void C_WriteShort(int iValue);
|
||||
void C_WriteLong(int iValue);
|
||||
void C_WriteAngle(float flValue);
|
||||
void C_WriteCoord(float flValue);
|
||||
void C_WriteString(const char *sz);
|
||||
void C_WriteEntity(int iValue);
|
||||
void C_MessageEnd(void);
|
||||
|
||||
extern CVector<int> msgHooks[256];
|
||||
extern int msgBlocks[256];
|
||||
|
||||
void ClearMessages();
|
||||
|
||||
#endif //_MSGS_INCLUDE_H
|
||||
|
2328
amxmodx/meta_api.cpp
2328
amxmodx/meta_api.cpp
File diff suppressed because it is too large
Load Diff
1622
amxmodx/mmgr/mmgr.cpp
Executable file
1622
amxmodx/mmgr/mmgr.cpp
Executable file
File diff suppressed because it is too large
Load Diff
146
amxmodx/mmgr/mmgr.h
Executable file
146
amxmodx/mmgr/mmgr.h
Executable file
@ -0,0 +1,146 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Copyright 2000, Paul Nettle. All rights reserved.
|
||||
//
|
||||
// You are free to use this source code in any commercial or non-commercial product.
|
||||
//
|
||||
// mmgr.h - Memory manager & tracking software
|
||||
//
|
||||
// The most recent version of this software can be found at: ftp://ftp.GraphicsPapers.com/pub/ProgrammingTools/MemoryManagers/
|
||||
//
|
||||
// [NOTE: Best when viewed with 8-character tabs]
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef _H_MMGR
|
||||
#define _H_MMGR
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// For systems that don't have the __FUNCTION__ variable, we can just define it here
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#define __FUNCTION__ "??"
|
||||
#endif // #ifndef __FUNCTION__
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Types
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef struct tag_au
|
||||
{
|
||||
size_t actualSize;
|
||||
size_t reportedSize;
|
||||
void *actualAddress;
|
||||
void *reportedAddress;
|
||||
char sourceFile[40];
|
||||
char sourceFunc[40];
|
||||
unsigned int sourceLine;
|
||||
unsigned int allocationType;
|
||||
bool breakOnDealloc;
|
||||
bool breakOnRealloc;
|
||||
unsigned int allocationNumber;
|
||||
struct tag_au *next;
|
||||
struct tag_au *prev;
|
||||
} sAllocUnit;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int totalReportedMemory;
|
||||
unsigned int totalActualMemory;
|
||||
unsigned int peakReportedMemory;
|
||||
unsigned int peakActualMemory;
|
||||
unsigned int accumulatedReportedMemory;
|
||||
unsigned int accumulatedActualMemory;
|
||||
unsigned int accumulatedAllocUnitCount;
|
||||
unsigned int totalAllocUnitCount;
|
||||
unsigned int peakAllocUnitCount;
|
||||
} sMStats;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// External constants
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
extern const unsigned int m_alloc_unknown;
|
||||
extern const unsigned int m_alloc_new;
|
||||
extern const unsigned int m_alloc_new_array;
|
||||
extern const unsigned int m_alloc_malloc;
|
||||
extern const unsigned int m_alloc_calloc;
|
||||
extern const unsigned int m_alloc_realloc;
|
||||
extern const unsigned int m_alloc_delete;
|
||||
extern const unsigned int m_alloc_delete_array;
|
||||
extern const unsigned int m_alloc_free;
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Used by the macros
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void m_setOwner(const char *file, const unsigned int line, const char *func);
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Allocation breakpoints
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool &m_breakOnRealloc(void *reportedAddress);
|
||||
bool &m_breakOnDealloc(void *reportedAddress);
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// The meat of the memory tracking software
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void *m_allocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc,
|
||||
const unsigned int allocationType, const size_t reportedSize);
|
||||
void *m_reallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc,
|
||||
const unsigned int reallocationType, const size_t reportedSize, void *reportedAddress);
|
||||
void m_deallocator(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc,
|
||||
const unsigned int deallocationType, const void *reportedAddress);
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Utilitarian functions
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
bool m_validateAddress(const void *reportedAddress);
|
||||
bool m_validateAllocUnit(const sAllocUnit *allocUnit);
|
||||
bool m_validateAllAllocUnits();
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Unused RAM calculations
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
unsigned int m_calcUnused(const sAllocUnit *allocUnit);
|
||||
unsigned int m_calcAllUnused();
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Logging and reporting
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void m_dumpAllocUnit(const sAllocUnit *allocUnit, const char *prefix = "");
|
||||
void m_dumpMemoryReport(const char *filename = "memreport.log", const bool overwrite = true);
|
||||
sMStats m_getMemoryStatistics();
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Variations of global operators new & delete
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void *operator new(size_t reportedSize);
|
||||
void *operator new[](size_t reportedSize);
|
||||
void *operator new(size_t reportedSize, const char *sourceFile, int sourceLine);
|
||||
void *operator new[](size_t reportedSize, const char *sourceFile, int sourceLine);
|
||||
void operator delete(void *reportedAddress);
|
||||
void operator delete[](void *reportedAddress);
|
||||
|
||||
#endif // _H_MMGR
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Macros -- "Kids, please don't try this at home. We're trained professionals here." :)
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "nommgr.h"
|
||||
#define new (m_setOwner (__FILE__,__LINE__,__FUNCTION__),false) ? NULL : new
|
||||
#define delete (m_setOwner (__FILE__,__LINE__,__FUNCTION__),false) ? m_setOwner("",0,"") : delete
|
||||
#define malloc(sz) m_allocator (__FILE__,__LINE__,__FUNCTION__,m_alloc_malloc,sz)
|
||||
#define calloc(sz) m_allocator (__FILE__,__LINE__,__FUNCTION__,m_alloc_calloc,sz)
|
||||
#define realloc(ptr,sz) m_reallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_realloc,sz,ptr)
|
||||
#define free(ptr) m_deallocator(__FILE__,__LINE__,__FUNCTION__,m_alloc_free,ptr)
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// mmgr.h - End of file
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
39
amxmodx/mmgr/nommgr.h
Executable file
39
amxmodx/mmgr/nommgr.h
Executable file
@ -0,0 +1,39 @@
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// Copyright 2000, Paul Nettle. All rights reserved.
|
||||
//
|
||||
// You are free to use this source code in any commercial or non-commercial product.
|
||||
//
|
||||
// nommgr.h - Memory manager & tracking software
|
||||
//
|
||||
// The most recent version of this software can be found at: ftp://ftp.GraphicsPapers.com/pub/ProgrammingTools/MemoryManagers/
|
||||
//
|
||||
// [NOTE: Best when viewed with 8-character tabs]
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifdef new
|
||||
#undef new
|
||||
#endif
|
||||
|
||||
#ifdef delete
|
||||
#undef delete
|
||||
#endif
|
||||
|
||||
#ifdef malloc
|
||||
#undef malloc
|
||||
#endif
|
||||
|
||||
#ifdef calloc
|
||||
#undef calloc
|
||||
#endif
|
||||
|
||||
#ifdef realloc
|
||||
#undef realloc
|
||||
#endif
|
||||
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
||||
// nommgr.h - End of file
|
||||
// ---------------------------------------------------------------------------------------------------------------------------------
|
2042
amxmodx/modules.cpp
2042
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -36,144 +36,56 @@
|
||||
|
||||
#undef DLLEXPORT
|
||||
#ifndef __linux__
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#define WINAPI
|
||||
#define DLLEXPORT
|
||||
#define WINAPI
|
||||
#endif
|
||||
|
||||
#undef C_DLLEXPORT
|
||||
#define C_DLLEXPORT extern "C" DLLEXPORT
|
||||
|
||||
#define AMX_INTERFACE_VERSION 6
|
||||
|
||||
#define RELOAD_MODULE 0
|
||||
#define STATIC_MODULE 1
|
||||
|
||||
struct module_info_s {
|
||||
const char* name;
|
||||
const char* author;
|
||||
const char* version;
|
||||
int ivers;
|
||||
int type;
|
||||
long int serial;
|
||||
};
|
||||
typedef enum
|
||||
{
|
||||
Player_Name, //String
|
||||
Player_Ip, //String
|
||||
Player_Team, //String
|
||||
Player_Ingame, //bool
|
||||
Player_Authorized, //bool
|
||||
Player_Vgui, //bool
|
||||
Player_Time, //float
|
||||
Player_Playtime, //float
|
||||
Player_MenuExpire, //float
|
||||
Player_Weapons, //struct{int,int}[32]
|
||||
Player_CurrentWeapon, //int
|
||||
Player_TeamID, //int
|
||||
Player_Deaths, //int
|
||||
Player_Aiming, //int
|
||||
Player_Menu, //int
|
||||
Player_Keys, //int
|
||||
Player_Flags, //int[32]
|
||||
Player_Newmenu, //int
|
||||
Player_NewmenuPage, //int
|
||||
} PlayerProp;
|
||||
|
||||
// Small scripting language
|
||||
struct pfnamx_engine_g {
|
||||
uint16_t* (*pfnamx_Align16)(uint16_t *); // value
|
||||
uint32_t* (*pfnamx_Align32)(uint32_t *); // value
|
||||
int (*pfnamx_Allot)(AMX*, int, cell*, cell**); // amx, length, amx_addr, phys_addr
|
||||
int (*pfnamx_Callback)(AMX*, cell , cell*, cell*); // amx, index,result,params
|
||||
int (*pfnamx_Clone)(AMX*, AMX*, void*); // amxClone, amxSrc, data
|
||||
int (*pfnamx_Debug)(AMX*); // default debug procedure, does nothing // amx
|
||||
int (*pfnamx_Exec)(AMX*, cell*, int , int , ...); // amx, return val, index, num_params, ...
|
||||
int (*pfnamx_Execv)(AMX*, cell*, int , int, cell[]); // amx, return val, index, num_params, param[]
|
||||
int (*pfnamx_FindPublic)(AMX*, char*, int*); // amx, func name, index
|
||||
int (*pfnamx_FindPubVar)(AMX*, char*, cell*); // anx, var name, amx_addr
|
||||
int (*pfnamx_FindTagId)(AMX*, cell , char*); // amx. tag_id, tagname
|
||||
int (*pfnamx_Flags)(AMX*,uint16_t *); // amx, flags
|
||||
int (*pfnamx_GetAddr)(AMX*,cell ,cell**); // amx, amx_addr, phys_addr
|
||||
int (*pfnamx_GetPublic)(AMX*, int , char*); // amx, index, funcname
|
||||
int (*pfnamx_GetPubVar)(AMX*, int , char*, cell*); // amx, index, varname, amx_addr
|
||||
int (*pfnamx_GetString)(char*dest,cell*); // dest, source
|
||||
int (*pfnamx_GetTag)(AMX*, int , char*, cell*); // amx, index, tagname, tag_id
|
||||
int (*pfnamx_GetUserData)(AMX*, long , void **); // amx, tag, ptr
|
||||
int (*pfnamx_Init)(AMX*, void *); // amx, program
|
||||
int (*pfnamx_InitJIT)(AMX*, void *, void *); // amx, reloc_table, native_code
|
||||
int (*pfnamx_MemInfo)(AMX*, long*, long*, long*); // amx, codesize, datasize, stackheap
|
||||
int (*pfnamx_NameLength)(AMX*, int*); // amx, length
|
||||
AMX_NATIVE_INFO * (*pfnamx_NativeInfo)(char*,AMX_NATIVE ); // name, func
|
||||
int (*pfnamx_NumPublics)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumPubVars)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_NumTags)(AMX*, int*); // amx, number
|
||||
int (*pfnamx_RaiseError)(AMX*, int ); // amx, error
|
||||
int (*pfnamx_Register)(AMX*, AMX_NATIVE_INFO*, int ); // amx, nativelist, number
|
||||
int (*pfnamx_Release)(AMX*, cell ); // amx, amx_addr
|
||||
int (*pfnamx_SetCallback)(AMX*, AMX_CALLBACK ); // amx, callback
|
||||
int (*pfnamx_SetDebugHook)(AMX*, AMX_DEBUG ); // amx, debug
|
||||
int (*pfnamx_SetString)(cell*, char*, int ); // dest, source, pack
|
||||
int (*pfnamx_SetUserData)(AMX*, long , void*); // amx, tag, prt
|
||||
int (*pfnamx_StrLen)(cell*, int*); // amx, cstring, length
|
||||
};
|
||||
extern pfnamx_engine_g* g_engAmxFunc;
|
||||
int CheckModules(AMX *amx, char error[128]);
|
||||
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
|
||||
const char *StrCaseStr(const char *as, const char *bs);
|
||||
|
||||
#define AMX_ALIGN16 (*g_engAmxFunc->pfnamx_Align16)
|
||||
#define AMX_ALIGN32 (*g_engAmxFunc->pfnamx_Align32)
|
||||
#define AMX_ALLOT (*g_engAmxFunc->pfnamx_Allot)
|
||||
#define AMX_CALLBACK (*g_engAmxFunc->pfnamx_Callback)
|
||||
#define AMX_CLONE (*g_engAmxFunc->pfnamx_Clone)
|
||||
#define AMX_DEBUG (*g_engAmxFunc->pfnamx_Debug)
|
||||
#define AMX_EXEC (*g_engAmxFunc->pfnamx_Exec)
|
||||
#define AMX_EXECV (*g_engAmxFunc->pfnamx_Execv)
|
||||
#define AMX_FINDPUBLIC (*g_engAmxFunc->pfnamx_FindPublic)
|
||||
#define AMX_FINDPUBVAR (*g_engAmxFunc->pfnamx_FindPubVar)
|
||||
#define AMX_FINDTAGID (*g_engAmxFunc->pfnamx_FindTagId)
|
||||
#define AMX_FLAGS (*g_engAmxFunc->pfnamx_Flags)
|
||||
#define AMX_GETADDR (*g_engAmxFunc->pfnamx_GetAddr)
|
||||
#define AMX_GETPUBLIC (*g_engAmxFunc->pfnamx_GetPublic)
|
||||
#define AMX_GETPUBVAR (*g_engAmxFunc->pfnamx_GetPubVar)
|
||||
#define AMX_GETSTRING (*g_engAmxFunc->pfnamx_GetString)
|
||||
#define AMX_GETTAG (*g_engAmxFunc->pfnamx_GetTag)
|
||||
#define AMX_GETUSERDATA (*g_engAmxFunc->pfnamx_GetUserData)
|
||||
#define AMX_INIT (*g_engAmxFunc->pfnamx_Init)
|
||||
#define AMX_INITJIT (*g_engAmxFunc->pfnamx_InitJIT)
|
||||
#define AMX_MEMINFO (*g_engAmxFunc->pfnamx_MemInfo)
|
||||
#define AMX_NAMELENGTH (*g_engAmxFunc->pfnamx_NameLength)
|
||||
#define AMX_NATIVEINFO (*g_engAmxFunc->pfnamx_NativeInfo)
|
||||
#define AMX_NUMPUBLICS (*g_engAmxFunc->pfnamx_NumPublics)
|
||||
#define AMX_NUMPUBVARS (*g_engAmxFunc->pfnamx_NumPubVars)
|
||||
#define AMX_NUMTAGS (*g_engAmxFunc->pfnamx_NumTags)
|
||||
#define AMX_RAISEERROR (*g_engAmxFunc->pfnamx_RaiseError)
|
||||
#define AMX_REGISTER (*g_engAmxFunc->pfnamx_Register)
|
||||
#define AMX_RELEASE (*g_engAmxFunc->pfnamx_Release)
|
||||
#define AMX_SETCALLBACK (*g_engAmxFunc->pfnamx_SetCallback)
|
||||
#define AMX_SETDEBUGHOOK (*g_engAmxFunc->pfnamx_SetDebugHook)
|
||||
#define AMX_SETSTRING (*g_engAmxFunc->pfnamx_SetString)
|
||||
#define AMX_SETUSERDATA (*g_engAmxFunc->pfnamx_SetUserData)
|
||||
#define AMX_STRLEN (*g_engAmxFunc->pfnamx_StrLen)
|
||||
class Debugger;
|
||||
Debugger *DisableDebugHandler(AMX *amx);
|
||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
||||
|
||||
// Modules API
|
||||
struct pfnmodule_engine_g {
|
||||
int (*pfnadd_amxnatives)(module_info_s*,AMX_NATIVE_INFO*); // list
|
||||
char* (*pfnbuild_pathname)(char*, ...); // format, ....
|
||||
void (*pfncopy_amxmemory)(cell*,cell*,int); // dest, src, len
|
||||
char* (*pfnformat_amxstring)(AMX*, cell*, int ,int& ); // amx, format, start pos, len
|
||||
cell* (*pfnget_amxaddr)(AMX*,cell ); // amx, cell
|
||||
AMX* (*pfnget_amxscript)(int, void**,const char**); // id, code, name
|
||||
const char* (*pfnget_amxscriptname)(AMX* amx); // amx
|
||||
char* (*pfnget_amxstring)(AMX*,cell,int, int&); // amx, src, buffer (0-3), len
|
||||
void (*pfnget_modname)(char*); // modname
|
||||
int (*pfnload_amxscript)(AMX*, void**, const char*, char[64]); // amx, code, path, error info
|
||||
void (*pfnprint_console)(char*, ...); // format, ....
|
||||
void (*pfnreport_error)(int code, char*, ... );
|
||||
int (*pfnset_amxnatives)(AMX*,char[64]); // amx, error info
|
||||
int (*pfnset_amxstring)(AMX*,cell ,const char*,int); // amx, dest, string, maxlen
|
||||
int (*pfnamxstring_length)(cell*); // src
|
||||
int (*pfnunload_amxscript)(AMX* amx,void**); // amx, code
|
||||
void* (*pfnalloc_amxmemory)(void**,int size);
|
||||
void (*pfnfree_amxmemory)(void**);
|
||||
};
|
||||
extern pfnmodule_engine_g* g_engModuleFunc;
|
||||
|
||||
#define ADD_AMXNATIVES (*g_engModuleFunc->pfnadd_amxnatives)
|
||||
#define AMXSTRING_LENGTH (*g_engModuleFunc->pfnamxstring_length)
|
||||
#define BUILD_PATHNAME (*g_engModuleFunc->pfnbuild_pathname)
|
||||
#define COPY_AMXMEMORY (*g_engModuleFunc->pfncopy_amxmemory)
|
||||
#define FORMAT_AMXSTRING (*g_engModuleFunc->pfnformat_amxstring)
|
||||
#define GET_AMXADDR (*g_engModuleFunc->pfnget_amxaddr)
|
||||
#define GET_AMXSCRIPT (*g_engModuleFunc->pfnget_amxscript)
|
||||
#define GET_AMXSCRIPTNAME (*g_engModuleFunc->pfnget_amxscriptname)
|
||||
#define GET_AMXSTRING (*g_engModuleFunc->pfnget_amxstring)
|
||||
#define GET_MODNAME (*g_engModuleFunc->pfnget_modname)
|
||||
#define LOAD_AMXSCRIPT (*g_engModuleFunc->pfnload_amxscript)
|
||||
#define PRINT_CONSOLE (*g_engModuleFunc->pfnprint_console)
|
||||
#define REPORT_ERROR (*g_engModuleFunc->pfnreport_error)
|
||||
#define SET_AMXNATIVES (*g_engModuleFunc->pfnset_amxnatives)
|
||||
#define SET_AMXSTRING (*g_engModuleFunc->pfnset_amxstring)
|
||||
#define UNLOAD_AMXSCRIPT (*g_engModuleFunc->pfnunload_amxscript)
|
||||
#define ALLOC_AMXMEMORY (*g_engModuleFunc->pfnalloc_amxmemory)
|
||||
#define FREE_AMXMEMORY (*g_engModuleFunc->pfnfree_amxmemory)
|
||||
bool DirExists(const char *dir);
|
||||
const char* GetFileName(AMX *amx);
|
||||
|
||||
inline cell FloatToCell(float input)
|
||||
{
|
||||
REAL output = input;
|
||||
return *(cell *)&output;
|
||||
}
|
||||
|
||||
#endif // __MODULES_H__
|
||||
|
12
amxmodx/msvc/.cvsignore
Executable file
12
amxmodx/msvc/.cvsignore
Executable file
@ -0,0 +1,12 @@
|
||||
amxmodx.sln
|
||||
amxmodx.suo
|
||||
amxmodx.aps
|
||||
amxmodx.ncb
|
||||
Debug
|
||||
JITDebug
|
||||
JITMemtestRelease
|
||||
JITRelease
|
||||
MaximalSpeed
|
||||
MemtestDebug
|
||||
MemtestRelease
|
||||
Release
|
@ -1,6 +0,0 @@
|
||||
LIBRARY amx_mm
|
||||
EXPORTS
|
||||
GiveFnptrsToDll @1
|
||||
|
||||
SECTIONS
|
||||
.data READ WRITE
|
@ -1,24 +1,24 @@
|
||||
# Microsoft Developer Studio Project File - Name="amxmod_mm" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Project File - Name="amxmodx_mm" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=amxmod_mm - Win32 Debug
|
||||
CFG=amxmodx_mm - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "amxmod_mm.mak".
|
||||
!MESSAGE NMAKE /f "amxmodx_mm.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "amxmod_mm.mak" CFG="amxmod_mm - Win32 Debug"
|
||||
!MESSAGE NMAKE /f "amxmodx_mm.mak" CFG="amxmodx_mm - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "amxmod_mm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "amxmod_mm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "amxmodx_mm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "amxmodx_mm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
@ -29,7 +29,7 @@ CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "amxmod_mm - Win32 Release"
|
||||
!IF "$(CFG)" == "amxmodx_mm - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
@ -42,8 +42,8 @@ RSC=rc.exe
|
||||
# PROP Intermediate_Dir "release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\metamod\metamod" /I "..\..\hlsdk\sourcecode\common" /I "..\..\hlsdk\sourcecode\engine" /I "..\..\hlsdk\sourcecode\dlls" /I "..\..\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /c
|
||||
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\metamod\metamod" /I "..\..\hlsdk\sourcecode\common" /I "..\..\hlsdk\sourcecode\engine" /I "..\..\hlsdk\sourcecode\dlls" /I "..\..\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
@ -53,11 +53,11 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:".\amxmod_mm.def" /out:"release/amx_mm.dll" /libpath:"..\extra\lib_win32"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /def:".\amxmodx_mm.def" /out:"release/amxx_mm.dll" /libpath:"..\extra\lib_win32"
|
||||
# Begin Custom Build
|
||||
TargetPath=.\release\amx_mm.dll
|
||||
TargetName=amx_mm
|
||||
InputPath=.\release\amx_mm.dll
|
||||
TargetPath=.\release\amxx_mm.dll
|
||||
TargetName=amxx_mm
|
||||
InputPath=.\release\amxx_mm.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
@ -65,7 +65,7 @@ SOURCE="$(InputPath)"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "amxmod_mm - Win32 Debug"
|
||||
!ELSEIF "$(CFG)" == "amxmodx_mm - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
@ -78,8 +78,8 @@ SOURCE="$(InputPath)"
|
||||
# PROP Intermediate_Dir "debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Zp4 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\metamod\metamod" /I "..\...\hlsdk\sourcecode\common" /I "..\...\hlsdk\sourcecode\engine" /I "..\...\hlsdk\sourcecode\dlls" /I "..\...\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmod_mm_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /Zp4 /MTd /W3 /Gm /GX /ZI /Od /I "..\..\metamod\metamod" /I "..\...\hlsdk\sourcecode\common" /I "..\...\hlsdk\sourcecode\engine" /I "..\...\hlsdk\sourcecode\dlls" /I "..\...\hlsdk\sourcecode\pm_shared" /I "..\extra\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amxmodx_mm_EXPORTS" /YX /FD /GZ /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
@ -89,12 +89,12 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\amxmod_mm.def" /out:"debug/amx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /def:".\amxmodx_mm.def" /out:"debug/amxx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
|
||||
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetPath=.\debug\amx_mm.dll
|
||||
TargetName=amx_mm
|
||||
InputPath=.\debug\amx_mm.dll
|
||||
TargetPath=.\debug\amxx_mm.dll
|
||||
TargetName=amxx_mm
|
||||
InputPath=.\debug\amxx_mm.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
@ -106,8 +106,8 @@ SOURCE="$(InputPath)"
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "amxmod_mm - Win32 Release"
|
||||
# Name "amxmod_mm - Win32 Debug"
|
||||
# Name "amxmodx_mm - Win32 Release"
|
||||
# Name "amxmodx_mm - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
@ -121,7 +121,7 @@ SOURCE=..\amxcore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxmod.cpp
|
||||
SOURCE=..\amxmodx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -129,6 +129,10 @@ SOURCE=..\amxtime.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxxlog.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CCmd.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
@ -225,7 +229,7 @@ SOURCE=..\vault.cpp
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxmod.h
|
||||
SOURCE=..\amxmodx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
29
amxmodx/msvc/amxmodx_mm.dsw
Executable file
29
amxmodx/msvc/amxmodx_mm.dsw
Executable file
@ -0,0 +1,29 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "amxmodx_mm"=.\amxmodx_mm.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
27
amxmodx/msvc/amxmodx_mm.sln
Executable file
27
amxmodx/msvc/amxmodx_mm.sln
Executable file
@ -0,0 +1,27 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
JITDebug = JITDebug
|
||||
JITDebugBinLog = JITDebugBinLog
|
||||
JITRelease = JITRelease
|
||||
JITReleaseBinLog = JITReleaseBinLog
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
673
amxmodx/msvc/amxmodx_mm.vcproj
Executable file
673
amxmodx/msvc/amxmodx_mm.vcproj
Executable file
@ -0,0 +1,673 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="amxmodx"
|
||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
RootNamespace="amxmodx"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="JITDebug|Win32"
|
||||
OutputDirectory="JITDebug"
|
||||
IntermediateDirectory="JITDebug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitdebug/"
|
||||
ObjectFile=".\jitdebug/"
|
||||
ProgramDataBaseFileName=".\jitdebug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitdebug/amxmodx_mm.pdb"
|
||||
ImportLibrary=".\jitdebug/amxmodx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITRelease|Win32"
|
||||
OutputDirectory="JITRelease"
|
||||
IntermediateDirectory="JITRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="0"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||
IgnoreStandardIncludePath="FALSE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitrelease/"
|
||||
ObjectFile=".\jitrelease/"
|
||||
ProgramDataBaseFileName=".\jitrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
ImportLibrary=".\jitrelease/amxmodx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITDebugBinLog|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitdebugbinlog/"
|
||||
ObjectFile=".\jitdebugbinlog/"
|
||||
ProgramDataBaseFileName=".\jitdebugbinlog/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
|
||||
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="TRUE"
|
||||
OptimizeForProcessor="0"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED"
|
||||
IgnoreStandardIncludePath="FALSE"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitreleasebinlog/"
|
||||
ObjectFile=".\jitreleasebinlog/"
|
||||
ProgramDataBaseFileName=".\jitreleasebinlog/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="..\amx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxcore.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxtime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\binlog.cpp">
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\emsg.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\float.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\format.cpp">
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libraries.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\messages.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meta_api.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\optimizer.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\power.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\srvcmd.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string.cpp">
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="2"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="2"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\strptime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\util.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vault.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vector.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\amx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\binlog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CQueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CString.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVector.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\format.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libraries.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\messages.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\optimizer.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_list.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_stack.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_tinyhash.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zconf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zlib.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc">
|
||||
<File
|
||||
RelativePath="..\version.rc">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Assembly"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\amxdefn.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxexecn.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxjitsn.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\helpers-x86.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives-amd64.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives-x86.asm">
|
||||
</File>
|
||||
<Filter
|
||||
Name="Builds"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\Jit\helpers-x86.obj">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SDK"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\sdk\amxxmodule.cpp">
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITDebugBinLog|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\amxxmodule.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\moduleconfig.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
Binary file not shown.
26
amxmodx/msvc8/amxmodx_mm.sln
Normal file
26
amxmodx/msvc8/amxmodx_mm.sln
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
JITDebug|Win32 = JITDebug|Win32
|
||||
JITDebugBinLog|Win32 = JITDebugBinLog|Win32
|
||||
JITRelease|Win32 = JITRelease|Win32
|
||||
JITReleaseBinLog|Win32 = JITReleaseBinLog|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.ActiveCfg = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.Build.0 = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.ActiveCfg = JITDebugBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog|Win32.Build.0 = JITDebugBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.ActiveCfg = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.Build.0 = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.ActiveCfg = JITReleaseBinLog|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog|Win32.Build.0 = JITReleaseBinLog|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
914
amxmodx/msvc8/amxmodx_mm.vcproj
Normal file
914
amxmodx/msvc8/amxmodx_mm.vcproj
Normal file
@ -0,0 +1,914 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="amxmodx_mm"
|
||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
RootNamespace="amxmodx"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="JITDebug|Win32"
|
||||
OutputDirectory="JITDebug"
|
||||
IntermediateDirectory="JITDebug"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
StructMemberAlignment="3"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitdebug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitdebug/"
|
||||
ObjectFile=".\jitdebug/"
|
||||
ProgramDataBaseFileName=".\jitdebug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitdebug/amxmodx_mm.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITRelease|Win32"
|
||||
OutputDirectory="JITRelease"
|
||||
IntermediateDirectory="JITRelease"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE"
|
||||
IgnoreStandardIncludePath="false"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitrelease/"
|
||||
ObjectFile=".\jitrelease/"
|
||||
ProgramDataBaseFileName=".\jitrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
ShowIncludes="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\jitrelease/amxmodx_mm.pdb"
|
||||
GenerateMapFile="true"
|
||||
ImportLibrary=".\jitrelease/amxmodx_mm.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITDebugBinLog|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
StructMemberAlignment="3"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitdebugbinlog/"
|
||||
ObjectFile=".\jitdebugbinlog/"
|
||||
ProgramDataBaseFileName=".\jitdebugbinlog/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitdebugbinlog/amxmodx_bl_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\jitdebugbinlog/amxmodx_bl_mm.pdb"
|
||||
ImportLibrary=".\jitdebugbinlog/amxmodx_bl_mm.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="true"
|
||||
SuppressStartupBanner="true"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE"
|
||||
IgnoreStandardIncludePath="false"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
TreatWChar_tAsBuiltInType="true"
|
||||
RuntimeTypeInfo="false"
|
||||
UsePrecompiledHeader="0"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitreleasebinlog/"
|
||||
ObjectFile=".\jitreleasebinlog/"
|
||||
ProgramDataBaseFileName=".\jitreleasebinlog/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitreleasebinlog/amxmodx_bl_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT;LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_bl_mm.pdb"
|
||||
GenerateMapFile="true"
|
||||
ImportLibrary=".\jitreleasebinlog/amxmodx_bl_mm.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\amx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxcore.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxtime.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\binlog.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\emsg.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\float.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\format.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="4"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libraries.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\messages.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meta_api.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\optimizer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\power.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\srvcmd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="2"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AssemblerOutput="2"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\strptime.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\util.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vault.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vector.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\amx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\binlog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CList.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CQueue.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CString.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CTask.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVault.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CVector.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\debugger.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\fakemeta.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\format.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\libraries.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\messages.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\optimizer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_list.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_stack.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sh_tinyhash.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zconf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zlib.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\version.rc"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Assembly"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\amxdefn.asm"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxexecn.asm"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxjitsn.asm"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\helpers-x86.asm"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives-amd64.asm"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives-x86.asm"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Builds"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\Jit\helpers-x86.obj"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="SDK"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\sdk\amxxmodule.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITDebugBinLog|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITReleaseBinLog|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\amxxmodule.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sdk\moduleconfig.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
91
amxmodx/natives-amd64.asm
Executable file
91
amxmodx/natives-amd64.asm
Executable file
@ -0,0 +1,91 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
||||
; register_native functions for amd64 ;;;;;;
|
||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
||||
; Thanks to T(+)rget for pushing me to implement this ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;Licensed under the GNU General Public License, version 2
|
||||
;;This is a portion of AMX Mod X
|
||||
;; and is maintained by the AMX Mod X development team.
|
||||
|
||||
;;Initializes the global variable
|
||||
|
||||
BITS 64
|
||||
|
||||
section .text
|
||||
|
||||
global amxx_DynaInit, _amxx_DynaInit
|
||||
;void amxx_DynaInit(void *ptr);
|
||||
amxx_DynaInit:
|
||||
_amxx_DynaInit:
|
||||
mov [GLOBAL_GATE wrt rip], rdi
|
||||
ret
|
||||
|
||||
;;Assembles the gateway function
|
||||
global amxx_DynaMake, _amxx_DynaMake
|
||||
;int amxx_DynaMake(char *buffer, int id);
|
||||
amxx_DynaMake:
|
||||
_amxx_DynaMake:
|
||||
;we're not damaging the stack I think so we should be safe with no prologue
|
||||
|
||||
;save these two we're about to destroy them
|
||||
push rsi ;push id
|
||||
push rdi ;push buffer
|
||||
|
||||
mov rsi, _amxx_DynaFuncStart
|
||||
mov rcx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
cld ;clear direction flag (just in case)
|
||||
rep movsb
|
||||
|
||||
pop rdi ;get buffer as destination
|
||||
pop rax ;get id
|
||||
;align us to mov rsi, 1234... - on x86-64 this is 2 bytes after the differential
|
||||
add rdi, (_amxx_DynaFuncStart.move-_amxx_DynaFuncStart) + 2
|
||||
mov [rdi], qword rax
|
||||
;align rdi to the call
|
||||
add rdi, (_amxx_DynaFuncStart.call-_amxx_DynaFuncStart.move)
|
||||
mov rax, qword [GLOBAL_GATE wrt rip]
|
||||
;copy the real address
|
||||
mov [rdi], rax
|
||||
|
||||
ret
|
||||
|
||||
;;The gateway function we will re-assemble
|
||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
||||
;; and NASM > GAS :')
|
||||
global amxx_DynaFunc, _amxx_DynaFunc
|
||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
amxx_DynaFunc:
|
||||
_amxx_DynaFunc:
|
||||
_amxx_DynaFuncStart:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
;we're given an amx and params... we're also hardcoded for this though:
|
||||
mov rdx, rsi ;move 2nd param to 3rd
|
||||
mov rsi, rdi ;move 1st param to 2nd
|
||||
;this old trick, we'll move in the real pointer in a bit.
|
||||
.move:
|
||||
mov rdi, qword 1234567812345678h
|
||||
.call:
|
||||
mov rcx, qword 1234567812345678h
|
||||
call rcx
|
||||
|
||||
pop rbp
|
||||
ret
|
||||
_amxx_DynaFuncEnd:
|
||||
|
||||
;;Just returns the buffer size required
|
||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
||||
;int amxx_DynaCodesize()
|
||||
amxx_DynaCodesize:
|
||||
_amxx_DynaCodesize:
|
||||
; on x86-64 this is 34 bytes
|
||||
mov rax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
ret
|
||||
|
||||
section .data
|
||||
|
||||
GLOBAL_GATE DQ 0
|
||||
|
100
amxmodx/natives-x86.asm
Executable file
100
amxmodx/natives-x86.asm
Executable file
@ -0,0 +1,100 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; (C)2005 by David "BAILOPAN" Anderson ;
|
||||
; register_native functions for x86 ;;;;;;
|
||||
; Based on the concept by Julien "dJeyL" Laurent ;
|
||||
; Thanks to T(+)rget for pushing me to implement this ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;Licensed under the GNU General Public License, version 2
|
||||
;;This is a portion of AMX Mod X
|
||||
;; and is maintained by the AMX Mod X development team.
|
||||
|
||||
;;Initializes the global variable
|
||||
|
||||
section .text
|
||||
|
||||
global amxx_DynaInit, _amxx_DynaInit
|
||||
;void amxx_DynaInit(void *ptr);
|
||||
amxx_DynaInit:
|
||||
_amxx_DynaInit:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
mov eax, [ebp+8] ;get pointer
|
||||
mov [GLOBAL_GATE], eax ;store
|
||||
|
||||
mov eax, 1
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;Assembles the gateway function
|
||||
global amxx_DynaMake, _amxx_DynaMake
|
||||
;int amxx_DynaMake(char *buffer, int id);
|
||||
amxx_DynaMake:
|
||||
_amxx_DynaMake:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
push edi
|
||||
push esi
|
||||
|
||||
mov edi, [ebp+8] ;buffer
|
||||
mov esi, _amxx_DynaFuncStart
|
||||
mov ecx, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
cld ;clear direction flag (just in case)
|
||||
rep movsb
|
||||
|
||||
mov edi, [ebp+8] ;get buffer again
|
||||
;align us to mov eax, 1234 - on x86 this is 4 bytes
|
||||
add edi, (_amxx_DynaMoveOffset-_amxx_DynaFuncStart) + 1
|
||||
mov eax, [ebp+12]
|
||||
mov [edi], eax
|
||||
|
||||
pop esi
|
||||
pop edi
|
||||
|
||||
mov eax, 1
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
;;The gateway function we will re-assemble
|
||||
;; This is similar to dJeyL's but a tad more elegant, as it's written in pure assembly
|
||||
;; and NASM > GAS :')
|
||||
global amxx_DynaFunc, _amxx_DynaFunc
|
||||
;int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
amxx_DynaFunc:
|
||||
_amxx_DynaFunc:
|
||||
_amxx_DynaFuncStart:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
;we're given an amx and params... we're also hardcoded for this though:
|
||||
_amxx_DynaMoveOffset:
|
||||
mov eax, 12345678h ;this old trick, we'll move in the real pointer in a bit.
|
||||
push dword [ebp+12] ;push params
|
||||
push dword [ebp+8] ;push amx
|
||||
push eax ;push the id
|
||||
call [GLOBAL_GATE] ;pass through teh global gateway.
|
||||
add esp, 12 ;reset stack oops
|
||||
|
||||
pop ebp
|
||||
ret
|
||||
_amxx_DynaFuncEnd:
|
||||
|
||||
;;Just returns the buffer size required
|
||||
global _amxx_DynaCodesize, amxx_DynaCodesize
|
||||
;int amxx_DynaCodesize()
|
||||
amxx_DynaCodesize:
|
||||
_amxx_DynaCodesize:
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
|
||||
; on x86 is this 17 bytes
|
||||
mov eax, _amxx_DynaFuncEnd - _amxx_DynaFuncStart
|
||||
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
section .data
|
||||
|
||||
GLOBAL_GATE DD 0
|
450
amxmodx/natives.cpp
Executable file
450
amxmodx/natives.cpp
Executable file
@ -0,0 +1,450 @@
|
||||
/* 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 "sh_stack.h"
|
||||
#include "natives.h"
|
||||
#include "debugger.h"
|
||||
#include "libraries.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include "sclinux.h"
|
||||
#endif
|
||||
|
||||
//Written by David "BAILOPAN" Anderson
|
||||
//With the exception for param_convert, which was written by
|
||||
// Julien "dJeyL" Laurent
|
||||
|
||||
CStack<int> g_ErrorStk;
|
||||
CVector<regnative *> g_RegNatives;
|
||||
CStack<regnative *> g_NativeStack;
|
||||
static char g_errorStr[512] = {0};
|
||||
bool g_Initialized = false;
|
||||
|
||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||
{
|
||||
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid dynamic native called");
|
||||
return 0;
|
||||
}
|
||||
|
||||
regnative *pNative = g_RegNatives[idx];
|
||||
int numParams = params[0] / sizeof(cell);
|
||||
|
||||
if (numParams > CALLFUNC_MAXPARAMS)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative with too many parameters (%d)", CALLFUNC_MAXPARAMS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
|
||||
|
||||
if (!pNativePlugin->isExecutable(pNative->func))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
|
||||
pPlugin->setStatus(ps_paused);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pNative->caller)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Bug caught! Please contact the AMX Mod X Dev Team.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
//parameter stack
|
||||
//NOTE: it is possible that recursive register native calling
|
||||
// could potentially be somehow damaged here.
|
||||
//so, a :TODO: - make the stack unique, rather than a known ptr
|
||||
pNative->caller = amx;
|
||||
|
||||
int err = 0;
|
||||
cell ret = 0;
|
||||
g_ErrorStk.push(0);
|
||||
g_NativeStack.push(pNative);
|
||||
if (pNative->style == 0)
|
||||
{
|
||||
amx_Push(pNative->amx, numParams);
|
||||
amx_Push(pNative->amx, pPlugin->getId());
|
||||
for (int i=numParams; i>=1; i--)
|
||||
pNative->params[i] = params[i];
|
||||
} else if (pNative->style == 1) {
|
||||
//use dJeyL's system .. very clever!
|
||||
for (int i=numParams; i>=1; i--)
|
||||
amx_Push(pNative->amx, params[i]);
|
||||
}
|
||||
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
if (pDebugger && pDebugger->ErrorExists())
|
||||
{
|
||||
//don't care
|
||||
} else if (err != -1) {
|
||||
//nothing logged the error
|
||||
LogError(pNative->amx, err, NULL);
|
||||
}
|
||||
pNative->amx->error = AMX_ERR_NONE;
|
||||
//furthermore, log an error in the parent plugin.
|
||||
LogError(amx, AMX_ERR_NATIVE, "Unhandled dynamic native error");
|
||||
} else if (g_ErrorStk.front()) {
|
||||
LogError(amx, g_ErrorStk.front(), g_errorStr);
|
||||
}
|
||||
if (pDebugger)
|
||||
pDebugger->EndExec();
|
||||
g_NativeStack.pop();
|
||||
g_ErrorStk.pop();
|
||||
|
||||
pNative->caller = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO *BuildNativeTable()
|
||||
{
|
||||
if (g_RegNatives.size() < 1)
|
||||
return NULL;
|
||||
|
||||
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
||||
|
||||
AMX_NATIVE_INFO info;
|
||||
regnative *pNative;
|
||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||
{
|
||||
pNative = g_RegNatives[i];
|
||||
info.name = pNative->name.c_str();
|
||||
info.func = (AMX_NATIVE)((void *)(pNative->pfn));
|
||||
pNatives[i] = info;
|
||||
}
|
||||
pNatives[g_RegNatives.size()].name = NULL;
|
||||
pNatives[g_RegNatives.size()].func = NULL;
|
||||
|
||||
//this needs to be deleted
|
||||
return pNatives;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *err = format_amxstring(amx, params, 2, len);
|
||||
|
||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
||||
g_ErrorStk.pop();
|
||||
g_ErrorStk.push(params[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//get_string(param, dest[], len)
|
||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
|
||||
return set_amxstring(amx, params[2], str, params[3]);
|
||||
}
|
||||
|
||||
//set_string(param, source[], maxlen)
|
||||
static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
|
||||
}
|
||||
|
||||
//get a byvalue parameter
|
||||
//get_param(num)
|
||||
static cell AMX_NATIVE_CALL get_param(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
return pNative->params[p];
|
||||
}
|
||||
|
||||
//get_param_byref(num)
|
||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
|
||||
return addr[0];
|
||||
}
|
||||
|
||||
//set_param_byref(num, val)
|
||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *addr = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
|
||||
addr[0] = params[2];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//get_array(param, dest[], size)
|
||||
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *source = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
cell *dest = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
|
||||
memcpy(dest, source, size * sizeof(cell));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//set_array(param, source[], size)
|
||||
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
cell *dest = get_amxaddr(pNative->caller, pNative->params[p]);
|
||||
cell *source = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
|
||||
memcpy(dest, source, size * sizeof(cell));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//This is basically right from dJeyL's lib_convert function
|
||||
//This awesome hack modifies the stack frame to have an address offset
|
||||
// that will align to the other plugin's memory.
|
||||
//I've no idea how he thought of this, but it's great. No idea how well it works.
|
||||
static cell AMX_NATIVE_CALL param_convert(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.front();
|
||||
if (pNative->style != 1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
cell p = params[1];
|
||||
|
||||
AMX *caller = pNative->caller;
|
||||
|
||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
||||
|
||||
* (cell *)(data+(int)amx->frm+(p+2)*sizeof(cell)) -= (cell)data-(cell)realdata;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//register_native(const name[], const handler[])
|
||||
static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_Initialized)
|
||||
amxx_DynaInit((void *)(amxx_DynaCallback));
|
||||
|
||||
g_Initialized = true;
|
||||
|
||||
int len;
|
||||
char *name = get_amxstring(amx, params[1], 0, len);
|
||||
char *func = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int idx, err;
|
||||
if ( (err=amx_FindPublic(amx, func, &idx)) != AMX_ERR_NONE)
|
||||
{
|
||||
LogError(amx, err, "Function \"%s\" was not found", func);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regnative *pNative = new regnative;
|
||||
pNative->amx = amx;
|
||||
pNative->func = idx;
|
||||
pNative->caller = NULL;
|
||||
|
||||
//we'll apply a safety buffer too
|
||||
//make our function
|
||||
int size = amxx_DynaCodesize();
|
||||
#ifndef __linux__
|
||||
DWORD temp;
|
||||
pNative->pfn = new char[size + 10];
|
||||
VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
|
||||
#else
|
||||
pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
|
||||
mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
|
||||
int id = (int)g_RegNatives.size();
|
||||
|
||||
amxx_DynaMake(pNative->pfn, id);
|
||||
pNative->func = idx;
|
||||
pNative->style = params[3];
|
||||
|
||||
g_RegNatives.push_back(pNative);
|
||||
|
||||
pNative->name.assign(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ClearPluginLibraries()
|
||||
{
|
||||
ClearLibraries(LibSource_Plugin);
|
||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||
{
|
||||
delete [] g_RegNatives[i]->pfn;
|
||||
delete g_RegNatives[i];
|
||||
}
|
||||
g_RegNatives.clear();
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_NativeNatives[] = {
|
||||
{"register_native", register_native},
|
||||
{"log_error", log_error},
|
||||
{"register_library",register_library},
|
||||
{"get_string", get_string},
|
||||
{"set_string", set_string},
|
||||
{"get_param", get_param},
|
||||
{"get_param_byref", get_param_byref},
|
||||
{"set_param_byref", set_param_byref},
|
||||
{"get_array", get_array},
|
||||
{"set_array", set_array},
|
||||
//these are dummy functions for floats ;p
|
||||
{"get_param_f", get_param},
|
||||
{"get_float_byref", get_param_byref},
|
||||
{"set_float_byref", set_param_byref},
|
||||
{"get_array_f", get_array},
|
||||
{"set_array_f", set_array},
|
||||
{"param_convert", param_convert},
|
||||
//////////////////////////
|
||||
{NULL, NULL},
|
||||
};
|
69
amxmodx/natives.h
Executable file
69
amxmodx/natives.h
Executable file
@ -0,0 +1,69 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NATIVES_H
|
||||
#define _INCLUDE_NATIVES_H
|
||||
|
||||
//only 16 for now sorry
|
||||
#if !defined CALLFUNC_MAXPARAMS
|
||||
#define CALLFUNC_MAXPARAMS 16
|
||||
#endif
|
||||
|
||||
#define CALLFUNC_FLAG_BYREF 1
|
||||
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
||||
|
||||
#define N_CELL 1
|
||||
#define N_ARRAY 2
|
||||
#define N_BYREF 3
|
||||
#define N_VARARG 4
|
||||
|
||||
struct regnative
|
||||
{
|
||||
AMX *amx;
|
||||
String name;
|
||||
char *pfn;
|
||||
int func;
|
||||
AMX *caller;
|
||||
int style;
|
||||
cell params[CALLFUNC_MAXPARAMS];
|
||||
};
|
||||
|
||||
extern "C" void amxx_DynaInit(void *ptr);
|
||||
extern "C" void amxx_DynaMake(char *buffer, int id);
|
||||
extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
extern "C" int amxx_DynaCodesize();
|
||||
|
||||
AMX_NATIVE_INFO *BuildNativeTable();
|
||||
void ClearPluginLibraries();
|
||||
|
||||
//I couldn't resist :)
|
||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
||||
|
||||
#endif //_INCLUDE_NATIVES_H
|
871
amxmodx/newmenus.cpp
Executable file
871
amxmodx/newmenus.cpp
Executable file
@ -0,0 +1,871 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "newmenus.h"
|
||||
|
||||
CVector<Menu *> g_NewMenus;
|
||||
CStack<int> g_MenuFreeStack;
|
||||
|
||||
void ClearMenus()
|
||||
{
|
||||
for (size_t i = 0; i < g_NewMenus.size(); i++)
|
||||
delete g_NewMenus[i];
|
||||
|
||||
g_NewMenus.clear();
|
||||
while (!g_MenuFreeStack.empty())
|
||||
g_MenuFreeStack.pop();
|
||||
}
|
||||
|
||||
void validate_menu_text(char *str)
|
||||
{
|
||||
if (!g_coloredmenus)
|
||||
{
|
||||
size_t offs = 0;
|
||||
while (*str)
|
||||
{
|
||||
if (*str == '\\')
|
||||
{
|
||||
str++;
|
||||
char c = tolower(*str);
|
||||
if (c == 'r' || c == 'w'
|
||||
|| c== 'w' || c == 'd')
|
||||
{
|
||||
str++;
|
||||
offs += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (offs)
|
||||
*(str-offs) = *str;
|
||||
str++;
|
||||
}
|
||||
if (offs)
|
||||
*(str-offs) = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
Menu::Menu(const char *title, int mid, int tid)
|
||||
{
|
||||
m_Title.assign(title);
|
||||
menuId = mid;
|
||||
thisId = tid;
|
||||
|
||||
m_OptNames[abs(MENU_BACK)].assign("Back");
|
||||
m_OptNames[abs(MENU_MORE)].assign("More");
|
||||
m_OptNames[abs(MENU_EXIT)].assign("Exit");
|
||||
|
||||
m_OptOrders[0] = MENU_BACK;
|
||||
m_OptOrders[1] = MENU_MORE;
|
||||
m_OptOrders[2] = MENU_EXIT;
|
||||
|
||||
m_AlwaysExit = false;
|
||||
m_NeverExit = false;
|
||||
m_AutoColors = g_coloredmenus;
|
||||
|
||||
items_per_page = 7;
|
||||
func = 0;
|
||||
padding = 0;
|
||||
isDestroying = false;
|
||||
}
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
for (size_t i = 0; i < m_Items.size(); i++)
|
||||
delete m_Items[i];
|
||||
|
||||
unregisterSPForward(this->func);
|
||||
|
||||
m_Items.clear();
|
||||
}
|
||||
|
||||
menuitem *Menu::AddItem(const char *name, const char *cmd, int access)
|
||||
{
|
||||
menuitem *pItem = new menuitem;
|
||||
|
||||
pItem->name.assign(name);
|
||||
pItem->cmd.assign(cmd);
|
||||
pItem->access = access;
|
||||
pItem->id = m_Items.size();
|
||||
pItem->handler = -1;
|
||||
pItem->pfn = NULL;
|
||||
|
||||
m_Items.push_back(pItem);
|
||||
|
||||
return pItem;
|
||||
}
|
||||
|
||||
menuitem *Menu::GetMenuItem(item_t item)
|
||||
{
|
||||
if (item >= m_Items.size())
|
||||
return NULL;
|
||||
|
||||
return m_Items[item];
|
||||
}
|
||||
|
||||
size_t Menu::GetItemCount()
|
||||
{
|
||||
return m_Items.size();
|
||||
}
|
||||
|
||||
size_t Menu::GetPageCount()
|
||||
{
|
||||
size_t items = GetItemCount();
|
||||
if (items_per_page == 0)
|
||||
return 1;
|
||||
|
||||
return ((items/items_per_page) + ((items % items_per_page) ? 1 : 0));
|
||||
}
|
||||
|
||||
int Menu::PagekeyToItem(page_t page, item_t key)
|
||||
{
|
||||
size_t start = page * items_per_page;
|
||||
size_t num_pages = GetPageCount();
|
||||
|
||||
if (num_pages == 1 || !items_per_page)
|
||||
{
|
||||
if (key > m_Items.size())
|
||||
return MENU_EXIT;
|
||||
else
|
||||
return key-1;
|
||||
} else {
|
||||
//first page
|
||||
if (page == 0)
|
||||
{
|
||||
if (key == items_per_page + 1)
|
||||
return MENU_MORE;
|
||||
else if (key == items_per_page + 2)
|
||||
return MENU_EXIT;
|
||||
else
|
||||
return (start + key - 1);
|
||||
} else if (page == num_pages - 1) {
|
||||
//last page
|
||||
size_t remaining = m_Items.size() - start;
|
||||
if (key == remaining + 1)
|
||||
{
|
||||
return MENU_BACK;
|
||||
} else if (key == remaining + 2) {
|
||||
return MENU_EXIT;
|
||||
} else {
|
||||
return (start + key - 1);
|
||||
}
|
||||
} else {
|
||||
if (key > items_per_page && (key-items_per_page<=3))
|
||||
{
|
||||
return m_OptOrders[key-items_per_page-1];
|
||||
} else {
|
||||
return (start + key - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Menu::Display(int player, page_t page)
|
||||
{
|
||||
int keys = 0;
|
||||
const char *str = GetTextString(player, page, keys);
|
||||
|
||||
if (!str)
|
||||
return false;
|
||||
|
||||
static char buffer[2048];
|
||||
int len = _snprintf(buffer, sizeof(buffer)-1, "%s", str);
|
||||
|
||||
CPlayer *pPlayer = GET_PLAYER_POINTER_I(player);
|
||||
|
||||
pPlayer->keys = keys;
|
||||
pPlayer->menu = menuId;
|
||||
pPlayer->newmenu = thisId;
|
||||
pPlayer->page = (int)page;
|
||||
|
||||
UTIL_ShowMenu(pPlayer->pEdict, keys, -1, buffer, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
{
|
||||
page_t pages = GetPageCount();
|
||||
item_t numItems = GetItemCount();
|
||||
|
||||
if (page >= pages)
|
||||
return NULL;
|
||||
|
||||
m_Text.clear();
|
||||
|
||||
char buffer[255];
|
||||
if (items_per_page && (pages != 1))
|
||||
{
|
||||
if (m_AutoColors)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
||||
} else {
|
||||
if (m_AutoColors)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
|
||||
}
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
enum
|
||||
{
|
||||
Display_Back = (1<<0),
|
||||
Display_Next = (1<<1),
|
||||
Display_Exit = (1<<2),
|
||||
};
|
||||
|
||||
int flags = Display_Back|Display_Next;
|
||||
item_t start = page * items_per_page;
|
||||
item_t end = 0;
|
||||
if (items_per_page)
|
||||
{
|
||||
if (start + items_per_page >= numItems)
|
||||
{
|
||||
end = numItems - 1;
|
||||
flags &= ~Display_Next;
|
||||
} else {
|
||||
end = start + items_per_page - 1;
|
||||
}
|
||||
if (!m_NeverExit && (m_AlwaysExit || (page == 0 || page == pages-1)))
|
||||
flags |= Display_Exit;
|
||||
} else {
|
||||
end = numItems - 1;
|
||||
if (end > 10)
|
||||
end = 10;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
if (page == 0)
|
||||
flags &= ~Display_Back;
|
||||
|
||||
menuitem *pItem = NULL;
|
||||
|
||||
int option = 0;
|
||||
keys = 0;
|
||||
bool enabled = true;
|
||||
int ret = 0;
|
||||
int slots = 0;
|
||||
|
||||
for (item_t i = start; i <= end; i++)
|
||||
{
|
||||
pItem = m_Items[i];
|
||||
|
||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
||||
enabled = false;
|
||||
|
||||
if (pItem->handler != -1)
|
||||
{
|
||||
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i));
|
||||
if (ret == ITEM_ENABLED)
|
||||
enabled = true;
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (pItem->pfn)
|
||||
{
|
||||
ret = (pItem->pfn)(player, thisId, i);
|
||||
if (ret == ITEM_ENABLED)
|
||||
enabled = true;
|
||||
else if (ret == ITEM_DISABLED)
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
keys |= (1<<option);
|
||||
if (m_AutoColors)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\r%d.\\w %s\n", ++option, pItem->name.c_str());
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
|
||||
} else {
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
||||
option++;
|
||||
}
|
||||
}
|
||||
slots++;
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
//attach blanks
|
||||
if (pItem->blanks.size())
|
||||
{
|
||||
for (size_t j=0; j<pItem->blanks.size(); j++)
|
||||
{
|
||||
if (pItem->blanks[j] == 1)
|
||||
option++;
|
||||
m_Text.append("\n");
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (padding == 1 && items_per_page)
|
||||
{
|
||||
int pad = items_per_page;
|
||||
if (flags & Display_Back)
|
||||
pad--;
|
||||
if (flags & Display_Next)
|
||||
pad--;
|
||||
if (flags & Display_Exit)
|
||||
pad--;
|
||||
for (int i=slots+1; i<=pad; i++)
|
||||
{
|
||||
m_Text.append("\n");
|
||||
option++;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<3; i++)
|
||||
{
|
||||
switch (m_OptOrders[i])
|
||||
{
|
||||
case MENU_BACK:
|
||||
{
|
||||
if (flags & Display_Back)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
||||
option,
|
||||
m_OptNames[abs(MENU_BACK)].c_str()
|
||||
);
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_MORE:
|
||||
{
|
||||
if (flags & Display_Next)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
||||
option,
|
||||
m_OptNames[abs(MENU_MORE)].c_str()
|
||||
);
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MENU_EXIT:
|
||||
{
|
||||
if (flags & Display_Exit)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
m_AutoColors ? "\\r%d. \\w%s\n" : "%d. %s\n",
|
||||
option,
|
||||
m_OptNames[abs(MENU_EXIT)].c_str()
|
||||
);
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_Text.c_str();
|
||||
}
|
||||
|
||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
||||
return 0; } \
|
||||
Menu *pMenu = g_NewMenus[p];
|
||||
|
||||
//Makes a new menu handle (-1 for failure)
|
||||
//native csdm_makemenu(title[]);
|
||||
static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *title = get_amxstring(amx, params[1], 0, len);
|
||||
validate_menu_text(title);
|
||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
|
||||
if (func == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function \"%s\"", handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id = g_menucmds.registerMenuId(title, amx);
|
||||
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
|
||||
|
||||
Menu *pMenu = new Menu(title, id, 0);
|
||||
|
||||
pMenu->func = func;
|
||||
|
||||
if (g_MenuFreeStack.empty())
|
||||
{
|
||||
g_NewMenus.push_back(pMenu);
|
||||
pMenu->thisId = (int)g_NewMenus.size() - 1;
|
||||
return (int)g_NewMenus.size() - 1;
|
||||
} else {
|
||||
int pos = g_MenuFreeStack.front();
|
||||
g_MenuFreeStack.pop();
|
||||
g_NewMenus[pos] = pMenu;
|
||||
pMenu->thisId = pos;
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_addblank(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
if (params[2] && (!pMenu->items_per_page && pMenu->GetItemCount() >= 10))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pMenu->m_Items.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Blanks can only be added after items.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
menuitem *item = pMenu->m_Items[pMenu->m_Items.size() - 1];
|
||||
item->blanks.push_back(params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Adds an item to the menu (returns current item count - 1)
|
||||
//native menu_additem(menu, const name[], const command[]="", access=0);
|
||||
static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *name, *cmd;
|
||||
int access;
|
||||
|
||||
GETMENU(params[1]);
|
||||
|
||||
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = get_amxstring(amx, params[2], 0, len);
|
||||
validate_menu_text(name);
|
||||
cmd = get_amxstring(amx, params[3], 1, len);
|
||||
access = params[4];
|
||||
|
||||
menuitem *pItem = pMenu->AddItem(name, cmd, access);
|
||||
|
||||
pItem->handler = params[5];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Returns the number of pages in a menu
|
||||
//native csdm_menu_pages(menu);
|
||||
static cell AMX_NATIVE_CALL menu_pages(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
return pMenu->GetPageCount();
|
||||
}
|
||||
|
||||
//Returns the number of items in a menu
|
||||
//native csdm_menu_items(menu);
|
||||
static cell AMX_NATIVE_CALL menu_items(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
return pMenu->GetItemCount();
|
||||
}
|
||||
|
||||
//Builds the menu string for a specific page (set title to 0 to not include title)
|
||||
//page indices start at 0!
|
||||
static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[2]);
|
||||
|
||||
int player = params[1];
|
||||
int page = params[3];
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(player);
|
||||
|
||||
// This will set the expire time of the menu to infinite
|
||||
pPlayer->menuexpire = INFINITE;
|
||||
|
||||
return pMenu->Display(player, page);
|
||||
}
|
||||
|
||||
//Finds the id of a menu item for a specific page and key value.
|
||||
//Note that key should be from 0-6, as it only displays 7 per page.
|
||||
//page indices start at 0
|
||||
//native menu_keyid(menu, page, key);
|
||||
static cell AMX_NATIVE_CALL menu_find_id(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
page_t page = static_cast<page_t>(params[2]);
|
||||
item_t key = static_cast<item_t>(params[3]);
|
||||
|
||||
return pMenu->PagekeyToItem(page, key);
|
||||
}
|
||||
|
||||
//Gets info about a menu option
|
||||
//native menu_item_getinfo(menu, item, &access, command[], cmdlen, name[]="", namelen=0, &callback);
|
||||
static cell AMX_NATIVE_CALL menu_item_getinfo(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
cell *addr = get_amxaddr(amx, params[3]);
|
||||
addr[0] = pItem->access;
|
||||
|
||||
set_amxstring(amx, params[4], pItem->cmd.c_str(), params[5]);
|
||||
set_amxstring(amx, params[6], pItem->name.c_str(), params[7]);
|
||||
|
||||
if (params[8])
|
||||
{
|
||||
addr = get_amxaddr(amx, params[8]);
|
||||
if (addr)
|
||||
addr[0] = pItem->handler;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_makecallback(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *name = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
int id = registerSPForwardByName(amx, name, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid function %s", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setname(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *name;
|
||||
|
||||
name = get_amxstring(amx, params[3], 0, len);
|
||||
|
||||
pItem->name.assign(name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setcmd(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
int len;
|
||||
char *cmd;
|
||||
|
||||
cmd = get_amxstring(amx, params[3], 0, len);
|
||||
|
||||
pItem->cmd.assign(cmd);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
menuitem *pItem = pMenu->GetMenuItem(static_cast<item_t>(params[2]));
|
||||
|
||||
if (!pItem)
|
||||
return 0;
|
||||
|
||||
pItem->handler = params[3];
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
int len = params[0] / sizeof(cell);
|
||||
if (len < 3)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Expected 3 parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case MPROP_PERPAGE:
|
||||
{
|
||||
cell count = *get_amxaddr(amx, params[3]);
|
||||
if (count < 0 || count > 7)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Cannot set %d items per page", count);
|
||||
return 0;
|
||||
}
|
||||
pMenu->items_per_page = count;
|
||||
break;
|
||||
}
|
||||
case MPROP_BACKNAME:
|
||||
{
|
||||
char *str = get_amxstring(amx, params[3], 0, len);
|
||||
validate_menu_text(str);
|
||||
pMenu->m_OptNames[abs(MENU_BACK)].assign(str);
|
||||
break;
|
||||
}
|
||||
case MPROP_NEXTNAME:
|
||||
{
|
||||
char *str = get_amxstring(amx, params[3], 0, len);
|
||||
validate_menu_text(str);
|
||||
pMenu->m_OptNames[abs(MENU_MORE)].assign(str);
|
||||
break;
|
||||
}
|
||||
case MPROP_EXITNAME:
|
||||
{
|
||||
char *str = get_amxstring(amx, params[3], 0, len);
|
||||
validate_menu_text(str);
|
||||
pMenu->m_OptNames[abs(MENU_EXIT)].assign(str);
|
||||
break;
|
||||
}
|
||||
case MPROP_TITLE:
|
||||
{
|
||||
char *str = get_amxstring(amx, params[3], 0, len);
|
||||
int old = pMenu->menuId;
|
||||
g_menucmds.removeMenuId(old);
|
||||
pMenu->m_Title.assign(str);
|
||||
pMenu->menuId = g_menucmds.registerMenuId(str, amx);
|
||||
g_menucmds.registerMenuCmd(
|
||||
g_plugins.findPluginFast(amx),
|
||||
pMenu->menuId,
|
||||
1023,
|
||||
pMenu->func);
|
||||
CPlayer *pl;
|
||||
/**
|
||||
* NOTE - this is actually bogus
|
||||
* the client's screen won't actually match the cmd here
|
||||
* I think, this scenario needs to be tested.
|
||||
*/
|
||||
for (int i=1; i<=gpGlobals->maxClients; i++)
|
||||
{
|
||||
pl = GET_PLAYER_POINTER_I(i);
|
||||
if (pl->menu == old)
|
||||
pl->menu = pMenu->menuId;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPROP_EXITALL:
|
||||
{
|
||||
cell ans = *get_amxaddr(amx, params[3]);
|
||||
if (ans == 1)
|
||||
{
|
||||
pMenu->m_AlwaysExit = true;
|
||||
pMenu->m_NeverExit = false;
|
||||
} else if (ans == 0) {
|
||||
pMenu->m_AlwaysExit = false;
|
||||
pMenu->m_NeverExit = false;
|
||||
} else if (ans == -1) {
|
||||
pMenu->m_NeverExit = true;
|
||||
pMenu->m_AlwaysExit = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPROP_ORDER:
|
||||
{
|
||||
cell *addr = get_amxaddr(amx, params[3]);
|
||||
pMenu->m_OptOrders[0] = addr[0];
|
||||
pMenu->m_OptOrders[1] = addr[1];
|
||||
pMenu->m_OptOrders[2] = addr[2];
|
||||
break;
|
||||
}
|
||||
case MPROP_NOCOLORS:
|
||||
{
|
||||
pMenu->m_AutoColors = *get_amxaddr(amx, params[3]) ? true : false;
|
||||
break;
|
||||
}
|
||||
case MPROP_PADMENU:
|
||||
{
|
||||
pMenu->padding = *get_amxaddr(amx, params[3]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu setting: %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define GETMENU_R(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p]) { \
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
||||
return 0; } \
|
||||
Menu *pMenu = g_NewMenus[p];
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
|
||||
{
|
||||
int index = params[1];
|
||||
|
||||
if (index < 1 || index > gpGlobals->maxClients)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not valid", index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPlayer *player = GET_PLAYER_POINTER_I(index);
|
||||
if (!player->ingame)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int menu = player->newmenu;
|
||||
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
|
||||
return 0;
|
||||
|
||||
Menu *pMenu = g_NewMenus[menu];
|
||||
|
||||
player->newmenu = -1;
|
||||
player->menu = 0;
|
||||
executeForwards(pMenu->func,
|
||||
static_cast<cell>(index),
|
||||
static_cast<cell>(pMenu->thisId),
|
||||
static_cast<cell>(MENU_EXIT));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU_R(params[1]);
|
||||
|
||||
if (pMenu->isDestroying)
|
||||
return 0; //prevent infinite recursion
|
||||
|
||||
pMenu->isDestroying = true;
|
||||
g_menucmds.removeMenuId(pMenu->menuId);
|
||||
CPlayer *player;
|
||||
for (int i=1; i<=gpGlobals->maxClients; i++)
|
||||
{
|
||||
player = GET_PLAYER_POINTER_I(i);
|
||||
if (player->newmenu == pMenu->thisId)
|
||||
{
|
||||
player->newmenu = -1;
|
||||
player->menu = 0;
|
||||
executeForwards(pMenu->func,
|
||||
static_cast<cell>(i),
|
||||
static_cast<cell>(pMenu->thisId),
|
||||
static_cast<cell>(MENU_EXIT));
|
||||
}
|
||||
}
|
||||
g_NewMenus[params[1]] = NULL;
|
||||
delete pMenu;
|
||||
g_MenuFreeStack.push(params[1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL player_menu_info(AMX *amx, cell *params)
|
||||
{
|
||||
if (params[1] < 1 || params[1] > gpGlobals->maxClients)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CPlayer *player = GET_PLAYER_POINTER_I(params[1]);
|
||||
if (!player->ingame)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Player %d is not ingame", params[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell *m = get_amxaddr(amx, params[2]);
|
||||
cell *n = get_amxaddr(amx, params[3]);
|
||||
|
||||
*m = player->menu;
|
||||
*n = player->newmenu;
|
||||
|
||||
if ( (*m != 0 && *m != -1) || (*n != -1))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_NewMenuNatives[] =
|
||||
{
|
||||
{"menu_create", menu_create},
|
||||
{"menu_additem", menu_additem},
|
||||
{"menu_addblank", menu_addblank},
|
||||
{"menu_pages", menu_pages},
|
||||
{"menu_items", menu_items},
|
||||
{"menu_display", menu_display},
|
||||
{"menu_find_id", menu_find_id},
|
||||
{"menu_item_getinfo", menu_item_getinfo},
|
||||
{"menu_makecallback", menu_makecallback},
|
||||
{"menu_item_setcall", menu_item_setcall},
|
||||
{"menu_item_setcmd", menu_item_setcmd},
|
||||
{"menu_item_setname", menu_item_setname},
|
||||
{"menu_destroy", menu_destroy},
|
||||
{"menu_setprop", menu_setprop},
|
||||
{"menu_cancel", menu_cancel},
|
||||
{"player_menu_info", player_menu_info},
|
||||
{NULL, NULL},
|
||||
};
|
115
amxmodx/newmenus.h
Executable file
115
amxmodx/newmenus.h
Executable file
@ -0,0 +1,115 @@
|
||||
/* AMX Mod X
|
||||
*
|
||||
* by the AMX Mod X Development Team
|
||||
* originally developed by OLO
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_NEWMENUS_H
|
||||
#define _INCLUDE_NEWMENUS_H
|
||||
|
||||
#define MENU_EXIT -3
|
||||
#define MENU_BACK -2
|
||||
#define MENU_MORE -1
|
||||
#define ITEM_IGNORE 0
|
||||
#define ITEM_ENABLED 1
|
||||
#define ITEM_DISABLED 2
|
||||
|
||||
|
||||
#define MPROP_PERPAGE 1
|
||||
#define MPROP_BACKNAME 2
|
||||
#define MPROP_NEXTNAME 3
|
||||
#define MPROP_EXITNAME 4
|
||||
#define MPROP_TITLE 5
|
||||
#define MPROP_EXITALL 6
|
||||
#define MPROP_ORDER 7
|
||||
#define MPROP_NOCOLORS 8
|
||||
#define MPROP_PADMENU 9
|
||||
|
||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
||||
|
||||
struct menuitem
|
||||
{
|
||||
String name;
|
||||
String cmd;
|
||||
|
||||
int access;
|
||||
int handler;
|
||||
|
||||
MENUITEM_CALLBACK pfn;
|
||||
size_t id;
|
||||
|
||||
CVector<int> blanks;
|
||||
};
|
||||
|
||||
typedef unsigned int menu_t;
|
||||
typedef unsigned int item_t;
|
||||
typedef unsigned int page_t;
|
||||
|
||||
class Menu
|
||||
{
|
||||
public:
|
||||
Menu(const char *title, int menuId, int thisId);
|
||||
~Menu();
|
||||
|
||||
menuitem *GetMenuItem(item_t item);
|
||||
size_t GetPageCount();
|
||||
size_t GetItemCount();
|
||||
menuitem *AddItem(const char *name, const char *cmd, int access);
|
||||
|
||||
const char *GetTextString(int player, page_t page, int &keys);
|
||||
bool Display(int player, page_t page);
|
||||
|
||||
int PagekeyToItem(page_t page, item_t key);
|
||||
int GetMenuMenuid();
|
||||
public:
|
||||
CVector<menuitem * > m_Items;
|
||||
String m_Title;
|
||||
String m_Text;
|
||||
|
||||
String m_OptNames[4];
|
||||
int m_OptOrders[3];
|
||||
|
||||
bool m_AlwaysExit;
|
||||
bool m_NeverExit;
|
||||
bool m_AutoColors;
|
||||
|
||||
int menuId;
|
||||
int thisId;
|
||||
int func;
|
||||
int padding;
|
||||
bool isDestroying;
|
||||
public:
|
||||
unsigned int items_per_page;
|
||||
};
|
||||
|
||||
void ClearMenus();
|
||||
|
||||
extern CVector<Menu *> g_NewMenus;
|
||||
extern AMX_NATIVE_INFO g_NewMenuNatives[];
|
||||
|
||||
#endif //_INCLUDE_NEWMENUS_H
|
123
amxmodx/optimizer.cpp
Normal file
123
amxmodx/optimizer.cpp
Normal file
@ -0,0 +1,123 @@
|
||||
#include <string.h>
|
||||
#include "optimizer.h"
|
||||
|
||||
int g_opt_level = 0;
|
||||
|
||||
#define OP_SYSREQ_C 123
|
||||
#define OP_NOP 134
|
||||
#define OP_FLOAT_MUL 138
|
||||
#define OP_FLOAT_DIV 139
|
||||
#define OP_FLOAT_ADD 140
|
||||
#define OP_FLOAT_SUB 141
|
||||
#define OP_FLOAT_TO 142
|
||||
#define OP_FLOAT_ROUND 143
|
||||
#define OP_FLOAT_CMP 144
|
||||
|
||||
cell op_trans_table[N_Total_FloatOps] =
|
||||
{
|
||||
OP_FLOAT_MUL,
|
||||
OP_FLOAT_DIV,
|
||||
OP_FLOAT_ADD,
|
||||
OP_FLOAT_SUB,
|
||||
OP_FLOAT_TO,
|
||||
OP_FLOAT_ROUND,
|
||||
OP_FLOAT_CMP
|
||||
};
|
||||
|
||||
void OnBrowseRelocate(AMX *amx, cell *oplist, cell *cip)
|
||||
{
|
||||
char *codeptr = (char *)amx->base + (long)(((AMX_HEADER *)amx->base)->cod);
|
||||
|
||||
//jump to the parameter;
|
||||
codeptr += *cip;
|
||||
|
||||
int native = -1;
|
||||
cell n_offs = *(cell *)codeptr;
|
||||
optimizer_s *opt = (optimizer_s *)amx->usertags[UT_OPTIMIZER];
|
||||
for (int i=0; i<N_Total_FloatOps; i++)
|
||||
{
|
||||
if (opt->natives[i] == n_offs)
|
||||
{
|
||||
native = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (native != -1)
|
||||
{
|
||||
//we're patching this:
|
||||
// 0x7B 0x?? SYSREQ.C float???
|
||||
//with:
|
||||
// 0x8A FLOAT.MUL
|
||||
// 0x86 NOP
|
||||
cell new_opcodes[2];
|
||||
new_opcodes[0] = op_trans_table[native];
|
||||
new_opcodes[1] = OP_NOP;
|
||||
codeptr -= sizeof(cell);
|
||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
||||
*(cell *)codeptr = oplist[new_opcodes[0]];
|
||||
*(cell *)(codeptr + sizeof(cell)) = oplist[new_opcodes[1]];
|
||||
#else
|
||||
*(cell *)codeptr = new_opcodes[0];
|
||||
*(cell *)(codeptr + sizeof(cell)) = new_opcodes[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
*cip += sizeof(cell);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#define FIND_NATIVE(name, bind) \
|
||||
if (amx_FindNative(amx, name, &index) != AMX_ERR_NOTFOUND) \
|
||||
opt->natives[bind] = index;
|
||||
|
||||
void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip)
|
||||
{
|
||||
int index;
|
||||
|
||||
amx->usertags[UT_BROWSEHOOK] = (void *)OnBrowseRelocate;
|
||||
|
||||
optimizer_s *opt = new optimizer_s;
|
||||
|
||||
for (int i=0; i<N_Total_FloatOps; i++)
|
||||
opt->natives[i] = -1;
|
||||
|
||||
amx->usertags[UT_OPTIMIZER] = (void *)opt;
|
||||
|
||||
if (g_opt_level & 1)
|
||||
{
|
||||
FIND_NATIVE("floatmul", N_Float_Mul);
|
||||
FIND_NATIVE("floatdiv", N_Float_Div);
|
||||
FIND_NATIVE("floatadd", N_Float_Add);
|
||||
FIND_NATIVE("floatsub", N_Float_Sub);
|
||||
}
|
||||
if (g_opt_level & 4)
|
||||
{
|
||||
FIND_NATIVE("float", N_Float_To);
|
||||
FIND_NATIVE("floatround", N_Float_Round);
|
||||
}
|
||||
if (g_opt_level & 2)
|
||||
{
|
||||
#if !defined AMD64
|
||||
if (amxx_CpuSupport())
|
||||
{
|
||||
#endif
|
||||
FIND_NATIVE("floatcmp", N_Float_Cmp);
|
||||
#if !defined AMD64
|
||||
} else {
|
||||
g_opt_level &= ~(2);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
//we don't do these yet because of radix stuff >:\
|
||||
//FIND_NATIVE("floatsin", N_Float_Sin);
|
||||
//FIND_NATIVE("floatcos", N_Float_Cos);
|
||||
//FIND_NATIVE("floattan", N_Float_Tan);
|
||||
}
|
||||
|
||||
void SetupOptimizer(AMX *amx)
|
||||
{
|
||||
amx->usertags[UT_BROWSEHOOK] = (void *)_Setup_Optimizer_Stage2;
|
||||
}
|
||||
|
29
amxmodx/optimizer.h
Normal file
29
amxmodx/optimizer.h
Normal file
@ -0,0 +1,29 @@
|
||||
#ifndef _INCLUDE_AMXMODX_OPTIMIZER_H
|
||||
#define _INCLUDE_AMXMODX_OPTIMIZER_H
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
enum
|
||||
{
|
||||
N_Float_Mul=0,
|
||||
N_Float_Div,
|
||||
N_Float_Add,
|
||||
N_Float_Sub,
|
||||
N_Float_To,
|
||||
N_Float_Round,
|
||||
N_Float_Cmp,
|
||||
/* ------------ */
|
||||
N_Total_FloatOps,
|
||||
};
|
||||
|
||||
struct optimizer_s
|
||||
{
|
||||
int natives[N_Total_FloatOps];
|
||||
};
|
||||
|
||||
void SetupOptimizer(AMX *amx);
|
||||
extern "C" int amxx_CpuSupport();
|
||||
|
||||
extern int g_opt_level;
|
||||
|
||||
#endif //_INCLUDE_AMXMODX_OPTIMIZER_H
|
@ -5,6 +5,13 @@
|
||||
* Copyright (c) ITB CompuPhase, 1998, 1999
|
||||
* This file may be freely used. No warranties of any kind.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
// this file does not include amxmodx.h, so we have to include the memory manager here
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#endif // MEMORY_TEST
|
||||
|
||||
#include "amx.h"
|
||||
|
||||
static cell power(AMX *amx, cell *params)
|
@ -20,6 +20,13 @@
|
||||
#define stricmp(a,b) strcasecmp(a,b)
|
||||
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
||||
|
||||
#if defined __linux__ && !defined _snprintf
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
#if defined __linux__ && !defined _vsnprintf
|
||||
//#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
/*
|
||||
* WinWorld wants '\'. Unices do not.
|
||||
*/
|
||||
|
3125
amxmodx/sdk/amxxmodule.cpp
Executable file
3125
amxmodx/sdk/amxxmodule.cpp
Executable file
File diff suppressed because it is too large
Load Diff
2454
amxmodx/sdk/amxxmodule.h
Executable file
2454
amxmodx/sdk/amxxmodule.h
Executable file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user