Compare commits
1502 Commits
amxmodx-1.
...
amxmodx-1.
Author | SHA1 | Date | |
---|---|---|---|
3db718799f | |||
146d77f819 | |||
06a9241bcf | |||
ce4b23b41a | |||
3184d1466e | |||
8793d8f8d5 | |||
a26a98cb98 | |||
5e69db511c | |||
468aaba79e | |||
a3aa086375 | |||
82ad133d91 | |||
250cb89479 | |||
121dc75451 | |||
69c06545ce | |||
9e5b5683af | |||
f01357aa7a | |||
7f13ae3e4f | |||
e5b990b8e0 | |||
99411af951 | |||
b318509687 | |||
37f7975416 | |||
40c1fee55a | |||
b0fe6c83e2 | |||
59fc122986 | |||
3ec6bbc2ce | |||
a431cb420b | |||
5a6c4ea408 | |||
7d9376a64b | |||
6e4f09366e | |||
6c22cb171d | |||
77e900585a | |||
86bfeec554 | |||
45343e6e27 | |||
944f608f09 | |||
ad960a64e2 | |||
e2a687d96d | |||
53e43b8f31 | |||
da2eb8ea66 | |||
088f109a64 | |||
9d65198786 | |||
49e3b748c3 | |||
5324c7c620 | |||
26d2a4f877 | |||
76d407b45a | |||
e783c4bfcb | |||
afc663a51a | |||
cb500636cc | |||
e6f4dfbfe2 | |||
1bfdda7e71 | |||
330fd1c2ae | |||
56b676eafb | |||
73e3e52057 | |||
56b53584d1 | |||
f43fcd6670 | |||
5984f0d442 | |||
1b75b0ba92 | |||
52f5723f4e | |||
eb6ab857fc | |||
24bfff9cf1 | |||
1d3f91be43 | |||
824d9953d9 | |||
b706108ed6 | |||
adab9c93a0 | |||
0f8c61c1e1 | |||
0b4f28fecf | |||
d97ab913cf | |||
2249f1e70c | |||
0f4ee9d91d | |||
5cc5ea4006 | |||
2145823971 | |||
cdf3807955 | |||
10ff8c11fd | |||
81af863496 | |||
3e8c921b9f | |||
f201592ddb | |||
72bebf9af8 | |||
73ea754640 | |||
ce9728af93 | |||
6486c56a15 | |||
1d95fb3dcd | |||
c07d8f3d93 | |||
adaf207b58 | |||
0dc6a4a5dd | |||
626bfe5240 | |||
e4a3647b88 | |||
f942a857d0 | |||
633a81f864 | |||
1b5dc0d567 | |||
21b8f905ae | |||
36a15919ca | |||
24ff7c3a01 | |||
7beef260f2 | |||
36db059672 | |||
01f3d729de | |||
0a38ef831f | |||
55d18da46c | |||
a7d6352a22 | |||
240c92e20f | |||
f410ea743d | |||
9100ec753c | |||
1d7cbd4203 | |||
4049a0c3be | |||
86ea50dfdd | |||
6a4318f4d1 | |||
6d03b29963 | |||
44e078c7c0 | |||
e1dd514f15 | |||
c52943b03c | |||
b33d2f559b | |||
53ed817183 | |||
683f453b6f | |||
145ff45876 | |||
e3e64233ec | |||
313044fe89 | |||
074fd60f3c | |||
b608305c79 | |||
bbf7593e43 | |||
e373ee1165 | |||
375d6aa0da | |||
4c4fde8bf3 | |||
5e9e119c76 | |||
2a383feef6 | |||
a726b796db | |||
9348f9931e | |||
4c79232f17 | |||
16720a2f70 | |||
69a8a86ff6 | |||
b0286c9c4d | |||
660e97c764 | |||
df522ebe6f | |||
be35cc9912 | |||
9801c4166f | |||
80db0ed0b3 | |||
b9d98ede39 | |||
e6c8afa5de | |||
60b3f30ab3 | |||
cfd2011e80 | |||
5ed4c27732 | |||
afd1072583 | |||
64ad54aa51 | |||
3df060cad6 | |||
1497d58e41 | |||
fd028ca1e7 | |||
a1d812398b | |||
df96a81a75 | |||
656d30be83 | |||
6e8a164e67 | |||
521288dae0 | |||
4c464390ac | |||
408e69c41c | |||
cc99d6d1fb | |||
3030302952 | |||
f281a24274 | |||
efbba0a909 | |||
3750788893 | |||
993b6e6c74 | |||
7f51048438 | |||
212697b950 | |||
6a567f3c77 | |||
36241e2905 | |||
b630ffe28f | |||
f6276db4d0 | |||
a2e3f8682f | |||
dbf6143747 | |||
4aafcc50a0 | |||
a86b1c5097 | |||
2d737970d0 | |||
b7f8503655 | |||
ca3d15c27e | |||
468e6fb9dd | |||
50bbefa3ba | |||
c635638fd1 | |||
b2b2c1d961 | |||
748d000c02 | |||
c1791361da | |||
6a483cfcae | |||
fcdd17480c | |||
21ad8ba71b | |||
dd55716f15 | |||
bd3b7fc70c | |||
26f1c8dec7 | |||
a749aad1b4 | |||
58c7239b48 | |||
e616bd523e | |||
d163ead2ac | |||
00838065ae | |||
8298158f08 | |||
824ed30872 | |||
2b15c30ad1 | |||
643ddc18be | |||
639db5846e | |||
0bb430b3eb | |||
550dbae0c7 | |||
f0ee52f892 | |||
84b146d74a | |||
3f1226e504 | |||
186519dc92 | |||
51ce96ac3c | |||
16f6048d74 | |||
e2c1bad224 | |||
e6663991a7 | |||
62c41fbd03 | |||
0b581b1506 | |||
76a7cafe50 | |||
12ab387be5 | |||
cfc9c1dd02 | |||
544d2dedef | |||
1721383237 | |||
68961a91e2 | |||
435766b2ef | |||
750247e8a6 | |||
a81d6f3271 | |||
cb62613501 | |||
2efc82ea59 | |||
a95658bd2d | |||
5f10cc1ebc | |||
226d188d19 | |||
9e0f3f01a7 | |||
06b461acd7 | |||
ffb8fc683b | |||
aa2cac0f0c | |||
2bc6d965f6 | |||
c5e36a4e3c | |||
bbc6af247b | |||
164780363b | |||
807e6a0f9a | |||
605bef0482 | |||
2e3c652996 | |||
a8652dd91b | |||
2379aa3108 | |||
ed3f5dfd4b | |||
747d326ed5 | |||
b4ff754e29 | |||
67ac030c56 | |||
15b62648c9 | |||
b09bf4c532 | |||
e045e2fdb6 | |||
36dc8da47c | |||
25d95f1115 | |||
e254ef6b15 | |||
7038305812 | |||
c77176a4ce | |||
c604eefde0 | |||
48022d3c5c | |||
cf36abf7e6 | |||
ed84900ab6 | |||
83c82387e3 | |||
9ce9b142e7 | |||
ced56c79b6 | |||
d836aeb716 | |||
7c642fbf6e | |||
a28a80e45f | |||
2cbf7fca08 | |||
4b02ffa920 | |||
8316318c31 | |||
7b6d4ce699 | |||
6f590c85f6 | |||
f86dad801f | |||
ee5dccfc0f | |||
16c17cff63 | |||
ce526ac432 | |||
a3342213b5 | |||
ef41393bc3 | |||
a45d98efea | |||
e23f3747ba | |||
3f268e5f2e | |||
b3e61b1d75 | |||
6865b984e0 | |||
7c4dccac8c | |||
6c0300801f | |||
069c293aba | |||
7690f1a099 | |||
add02dc55e | |||
961114c260 | |||
ff3def3d00 | |||
39f759368f | |||
4cdd43b29b | |||
0c82e09df1 | |||
1129f09660 | |||
079606c143 | |||
66feed1d2b | |||
65748001f0 | |||
4504875df9 | |||
cd023c30d9 | |||
7bb562182f | |||
77ca104a8d | |||
b660df8df6 | |||
b1a086ee93 | |||
504ddb4c2f | |||
d38d2f56e1 | |||
9b0ed67c9c | |||
1081e84981 | |||
ee64440fef | |||
0c56e2803e | |||
5fc89085d6 | |||
f747acdc7c | |||
4e2493759e | |||
1f1ecfa590 | |||
bd2ad31f5e | |||
fb5e7dbfdb | |||
0ac5ce46a7 | |||
1073a42409 | |||
66d7d39bee | |||
46bd9127fb | |||
5309189602 | |||
006396bc92 | |||
dc4c9f0258 | |||
3b737ab87b | |||
6170cbc95a | |||
78f18de61a | |||
e34120803d | |||
fdb094045e | |||
8c45216cfd | |||
897ed0cb10 | |||
fd8489d088 | |||
710cd548a9 | |||
525eb65e1c | |||
580e52bd2c | |||
2f6bfca68e | |||
0377715cdc | |||
e3240214a3 | |||
fc2b220c38 | |||
74c6290dc0 | |||
a93ef02efa | |||
68d2b03e48 | |||
d682375d7d | |||
3b80342a02 | |||
8f49cddd7d | |||
d679885985 | |||
82c3807bd5 | |||
58ad23186b | |||
c957a9db0f | |||
359b7e25dd | |||
5d6d0282b0 | |||
33e01af955 | |||
0d5531a090 | |||
2659c906fb | |||
d563ecb060 | |||
bfe1ff6e15 | |||
adfc2ab451 | |||
ea912f794c | |||
8e1f54465d | |||
2c2259ea15 | |||
be4fdb1776 | |||
76158b031d | |||
599029b68e | |||
201d65749e | |||
17d8197e72 | |||
1ed1d0005c | |||
51f8d7f84e | |||
1ec4d9cc7d | |||
b90bc3a3e4 | |||
de530e2ca3 | |||
5d4669d52e | |||
8dc310f1bb | |||
9cca961024 | |||
7b4283bf4a | |||
1f423dc39f | |||
ab6fea5767 | |||
3328b570d4 | |||
63427b2ad0 | |||
61052c41a1 | |||
5c68df7ac7 | |||
8872d98dd6 | |||
03bae80ed2 | |||
1161b5ee7e | |||
b49bf1b13c | |||
81994ecf58 | |||
4682cec1cb | |||
b9a0ffacc4 | |||
ae46e3f6ab | |||
68beb4b1a3 | |||
118b002ee8 | |||
a004e906dd | |||
eaa4122c5a | |||
e326ab1593 | |||
5252e06c2a | |||
e61809496d | |||
edaf960407 | |||
e3217964c4 | |||
397479cd77 | |||
d151ee0b58 | |||
ce88004900 | |||
1e8d0e10e6 | |||
bb641688ee | |||
ab53914351 | |||
54186736c8 | |||
b66fea0fbc | |||
bf2c9620f3 | |||
af96229d5d | |||
be323039d1 | |||
c71be87a3a | |||
e4b01bc066 | |||
3ac076e098 | |||
e6120fdcd6 | |||
4dc4616933 | |||
46a3929365 | |||
4597868d30 | |||
cf716c4049 | |||
cc6b9d3d81 | |||
a34279b971 | |||
5cac87c99f | |||
309bc2dcaa | |||
7124f8bd2c | |||
c9b19c76a5 | |||
8939c3076a | |||
71065a65dd | |||
7adc49c541 | |||
baba221dd9 | |||
829485ef2a | |||
b793b80360 | |||
ea34c2c78a | |||
722e97fef2 | |||
bd412d7204 | |||
39e6d958bf | |||
bb54b37399 | |||
88dd3b021e | |||
ef4d19378d | |||
7f1ea1490d | |||
041fb4e37f | |||
193e59df90 | |||
d4703f045d | |||
109b1e45b5 | |||
1f1edef98d | |||
83631e95aa | |||
6eb1242600 | |||
77e7ea161b | |||
09f271e5d0 | |||
e35a8326d5 | |||
09d46aa025 | |||
615e097c68 | |||
ade56b62e9 | |||
b3d7f04b5e | |||
4f81c50a3e | |||
d45c3aeb96 | |||
fff603635a | |||
06f01ea7dc | |||
2395abcf7e | |||
d33f9ba2d4 | |||
aec28542ac | |||
73219c45dd | |||
39d6cb7840 | |||
bfd4e345dd | |||
aded0f9c1c | |||
811265e28b | |||
0caffa2b82 | |||
4dfb01bb1d | |||
862ed243be | |||
39f1fa6045 | |||
f26939e2cc | |||
9d53451933 | |||
4ae54eeb2a | |||
d62ae07b75 | |||
0f22a7fa06 | |||
7f3c2d00ac | |||
b324e8ed9d | |||
8420823713 | |||
1d1b50ce0c | |||
35fcca8a66 | |||
7a01503478 | |||
dd8f138892 | |||
8341e41f04 | |||
a682ec6b7a | |||
451b648c7f | |||
2d1c43c937 | |||
17adb214f2 | |||
3a2839c6c9 | |||
f96f95c4ff | |||
609fdae508 | |||
580305ce92 | |||
cbfd12e0f1 | |||
c5ccf7d2c8 | |||
d1c42751cd | |||
68f1ce7a52 | |||
e5b0ed3af1 | |||
49e70063fa | |||
7aa4cf70be | |||
b661873426 | |||
8e290cdf31 | |||
42f23a832a | |||
13e619bf97 | |||
4332d6c271 | |||
627b3f0f98 | |||
b7b55d060a | |||
b110021f4f | |||
96c49f4ff9 | |||
f53c877670 | |||
b237317e50 | |||
73b2ceb855 | |||
b64fb4678d | |||
d6ed1a8d8a | |||
b762174c30 | |||
86838bead1 | |||
e6c15d9f05 | |||
266ed797c5 | |||
93cb2060dd | |||
0cd1782d01 | |||
75a5dadd4d | |||
f03449acbd | |||
34f127b9aa | |||
0c345ceebc | |||
c5dc780635 | |||
fe0e461c76 | |||
935da9f0de | |||
36e9f29d55 | |||
c66c076a03 | |||
4eaea443e1 | |||
299f1b5f62 | |||
4e7bf7e348 | |||
d048996b50 | |||
a34c8daf34 | |||
6cd5a51c8e | |||
5cabf748ca | |||
1905ea7295 | |||
89158f9342 | |||
db7dc509e0 | |||
c15a23a2a7 | |||
3e0866e57a | |||
551e5298cc | |||
dfea3e8a13 | |||
e8a30e7187 | |||
8a93673276 | |||
ece4db4f43 | |||
8b8cc3dd6b | |||
b33e76d9c4 | |||
6fb6d7d399 | |||
5649a17502 | |||
5cfc2df359 | |||
1ac390b54c | |||
102c2b219f | |||
4e1d420495 | |||
e93e75fa39 | |||
90c213bc6d | |||
6c3e7e7ee0 | |||
8a2528108d | |||
a65d65bee4 | |||
483403aa3a | |||
2a1dbf5247 | |||
7aa687eb69 | |||
699cb2a6d6 | |||
7b82bc7b76 | |||
ed43b8a5ac | |||
d2ebca38a1 | |||
d542015214 | |||
d84c3a3798 | |||
405d9ff48e | |||
a63c728471 | |||
a60e9d205b | |||
553a950b98 | |||
955e827b19 | |||
00380cfe4c | |||
12ecf026db | |||
3fa6cd3227 | |||
fe1ebfe7bb | |||
f3057efd7d | |||
39d5ea94fb | |||
90f11b52bc | |||
9740f6469d | |||
461e7de151 | |||
c2695a8cd8 | |||
5ded9eef2a | |||
44617778c7 | |||
647d226764 | |||
f086273d2b | |||
afde57b27e | |||
c4453a9593 | |||
020b3a5963 | |||
3720810b61 | |||
98e20e0fc7 | |||
e72aff5c14 | |||
63bc8885c9 | |||
ff8fd747c5 | |||
98278b7bb5 | |||
09df281556 | |||
4cc460cfbe | |||
947cb5f79d | |||
73386b12c5 | |||
57160763af | |||
1f0778b14e | |||
3c923170a9 | |||
09beb4b81e | |||
f48aea7a72 | |||
63ad5727ef | |||
61525e9638 | |||
918e1c3195 | |||
6e56aed778 | |||
87c3e1dc82 | |||
d925dc6e41 | |||
651c5d9f01 | |||
4f8917ec44 | |||
1c265733e1 | |||
14a068532f | |||
3c379469d5 | |||
2df8b4269e | |||
3d74b7cf09 | |||
47e2214f09 | |||
4413e54058 | |||
14aff9b19b | |||
38cb94050e | |||
c294b91ca4 | |||
d95f794844 | |||
3754604686 | |||
4bd356079c | |||
c67e19a62f | |||
96c29d5376 | |||
65eb0279b2 | |||
c287985a66 | |||
1b9ef4d268 | |||
02fb807a0b | |||
f880fc6ee9 | |||
f6f6bcc356 | |||
4f95899d2e | |||
adf12bf348 | |||
c7febb4447 | |||
77e4d85002 | |||
418efa4088 | |||
4599b59834 | |||
751e8e6299 | |||
4eb8c4e295 | |||
5a4b1d2f03 | |||
b5498818a3 | |||
5286672268 | |||
8df33abd70 | |||
38e7b9ff58 | |||
621c120b71 | |||
c9c2943c05 | |||
ed5395a54a | |||
557958b408 | |||
2905217607 | |||
78956f3d89 | |||
95537e4840 | |||
35a96176fa | |||
6a28bc602a | |||
72f59422d5 | |||
cba554d193 | |||
76a4d84dbb | |||
ec83efbdf3 | |||
9bd22661ff | |||
baf406cb6a | |||
388711e969 | |||
cb01ff1dc3 | |||
5c23cf416e | |||
b8b3107210 | |||
2cd1449f88 | |||
3691e98814 | |||
709b3705ab | |||
22bef17660 | |||
b4767cb99e | |||
30235e05e5 | |||
28c4ea4fec | |||
58e1254876 | |||
81ac41037b | |||
6786b0e356 | |||
af5a7f5434 | |||
cd6f3dfd71 | |||
a7fcf76244 | |||
3878c7492a | |||
4981f46c41 | |||
ee4f064073 | |||
a42a5f1a0e | |||
bab5bb5a72 | |||
58abc3a655 | |||
0cb316c764 | |||
74d3d23f13 | |||
5b47da7cee | |||
45b67b6e2c | |||
44a17fe646 | |||
d21a352167 | |||
4fc2c9cebb | |||
4692335abb | |||
4e639d09de | |||
deefc504e1 | |||
ea262171db | |||
e49af85119 | |||
dec169562b | |||
0acaf1b476 | |||
2cf396be3e | |||
df7ee94b83 | |||
afe7df87d2 | |||
c80b7fd422 | |||
adad1384ff | |||
fb0d728720 | |||
a1e8701236 | |||
df5c6ccb95 | |||
8a58dd8806 | |||
67f53505ce | |||
e7cc87a610 | |||
b572cdff2f | |||
446d4b8a5d | |||
db5c9c114e | |||
408f61c6d6 | |||
042b9f7f4b | |||
a8b4ebbe70 | |||
ed0312567d | |||
e80679afd0 | |||
9093a178f1 | |||
4fe8c71d62 | |||
f5414ff8de | |||
f3a833dd1b | |||
e2932fb61a | |||
43bd5fc732 | |||
377c01eac7 | |||
7af82f0d4f | |||
010ef526c5 | |||
659448ce29 | |||
d7d0d72ceb | |||
79f8525c4a | |||
2869c8f4f6 | |||
b7076fc572 | |||
f7691a51c6 | |||
5524d5dca1 | |||
e015df58c8 | |||
db175082ad | |||
8b055fd1d0 | |||
6295813723 | |||
a03cd1385d | |||
1b065c6f36 | |||
e0115ba2dc | |||
4306c4f5b6 | |||
3b62b91fb7 | |||
32b1149716 | |||
f92017516f | |||
8837c52d81 | |||
6ab3c50813 | |||
0c06cdca36 | |||
ce59ee0362 | |||
c2d2e8aef5 | |||
9780a6c36f | |||
1a6f4e08b2 | |||
49f46a5f4c | |||
51ee2e4846 | |||
928091864f | |||
fab4a43915 | |||
b44951295d | |||
db3beb9b98 | |||
2dc3f2bec9 | |||
6ac889f6e2 | |||
87ac42cd98 | |||
f64d2366e9 | |||
34d71eb4dc | |||
fb2e0c5f6c | |||
65513c6037 | |||
b859001feb | |||
895039308f | |||
43b8ea4657 | |||
0eca298c2a | |||
8d4f28ac62 | |||
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 |
24
.hgignore
Normal file
24
.hgignore
Normal file
@ -0,0 +1,24 @@
|
||||
# Binaries
|
||||
\.dll$
|
||||
\.exe$
|
||||
\.so$
|
||||
|
||||
# Files generated by Visual Studio
|
||||
\.aps$
|
||||
\.ncb$
|
||||
\.sdf$
|
||||
\.suo$
|
||||
\.user$
|
||||
|
||||
# Build directories
|
||||
/Debug.*
|
||||
/Release.*
|
||||
/JITDebug.*
|
||||
/JITRelease.*
|
||||
|
||||
# Files generated by Mac OS X Finder
|
||||
(^|/)\.DS_Store$
|
||||
|
||||
# Files generated by Windows Explorer
|
||||
(^|/)Desktop\.ini$
|
||||
(^|/)Thumbs\.db$
|
@ -124,8 +124,6 @@ CmdMngr::Command* CmdMngr::getCmd(long int id, 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
|
||||
|
||||
buf_access = access;
|
||||
buf_type = type;
|
||||
@ -155,7 +153,7 @@ void CmdMngr::setCmdLink(CmdLink** a, Command* c, bool sorted)
|
||||
{
|
||||
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;
|
||||
|
@ -78,7 +78,7 @@ public:
|
||||
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) != 0)); }
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline bool isViewable() const { return listable; }
|
||||
inline int getFlags() const { return flags; }
|
||||
|
@ -425,7 +425,7 @@ void EventsMngr::executeEvents()
|
||||
}
|
||||
|
||||
(*iter).m_Stamp = (float)*m_Timer;
|
||||
executeForwards((*iter).m_Func, m_ParseVault ? m_ParseVault[0].iValue : 0);
|
||||
executeForwards((*iter).m_Func, static_cast<cell>(m_ParseVault ? m_ParseVault[0].iValue : 0));
|
||||
}
|
||||
|
||||
m_CurrentMsgType = -1;
|
||||
|
418
amxmodx/CFlagManager.cpp
Normal file
418
amxmodx/CFlagManager.cpp
Normal file
@ -0,0 +1,418 @@
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "sh_list.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
#include "CFlagManager.h"
|
||||
|
||||
void CFlagManager::SetFile(const char *Filename)
|
||||
{
|
||||
|
||||
m_strConfigFile.assign(g_mod_name.c_str());
|
||||
m_strConfigFile.append("/");
|
||||
m_strConfigFile.append(get_localinfo("amxx_configsdir","addons/amxmodx/configs"));
|
||||
m_strConfigFile.append("/");
|
||||
m_strConfigFile.append(Filename);
|
||||
|
||||
|
||||
CreateIfNotExist();
|
||||
}
|
||||
|
||||
const int CFlagManager::LoadFile(const int force)
|
||||
{
|
||||
CheckIfDisabled();
|
||||
// If we're disabled get the hell out. now.
|
||||
if (m_iDisabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// if we're not forcing this, and NeedToLoad says we dont have to
|
||||
// then just stop
|
||||
if (!force && !NeedToLoad())
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
this->Clear();
|
||||
|
||||
|
||||
// We need to load the file
|
||||
|
||||
FILE *File;
|
||||
|
||||
File=fopen(m_strConfigFile.c_str(),"r");
|
||||
|
||||
if (!File)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] FlagManager: Cannot open file \"%s\" (FILE pointer null!)",m_strConfigFile.c_str());
|
||||
return -1;
|
||||
};
|
||||
|
||||
// Trying to copy this almost exactly as other configs are read...
|
||||
String Line;
|
||||
|
||||
char Command[256];
|
||||
char Flags[256];
|
||||
|
||||
String TempLine;
|
||||
while (!feof(File))
|
||||
{
|
||||
|
||||
Line._fread(File);
|
||||
|
||||
char *nonconst=const_cast<char *>(Line.c_str());
|
||||
|
||||
|
||||
// Strip out comments
|
||||
while (*nonconst)
|
||||
{
|
||||
if (*nonconst==';') // End the line at comments
|
||||
{
|
||||
*nonconst='\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
nonconst++;
|
||||
}
|
||||
};
|
||||
|
||||
Command[0]='\0';
|
||||
Flags[0]='\0';
|
||||
|
||||
// Extract the command
|
||||
TempLine.assign(Line.c_str());
|
||||
|
||||
nonconst=const_cast<char *>(TempLine.c_str());
|
||||
|
||||
char *start=NULL;
|
||||
char *end=NULL;
|
||||
|
||||
// move up line until the first ", mark this down as the start
|
||||
// then find the second " and mark it down as the end
|
||||
while (*nonconst!='\0')
|
||||
{
|
||||
if (*nonconst=='"')
|
||||
{
|
||||
if (start==NULL)
|
||||
{
|
||||
start=nonconst+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
end=nonconst;
|
||||
goto done_with_command;
|
||||
}
|
||||
}
|
||||
nonconst++;
|
||||
}
|
||||
done_with_command:
|
||||
|
||||
// invalid line?
|
||||
if (start==NULL || end==NULL)
|
||||
{
|
||||
// TODO: maybe warn for an invalid non-commented line?
|
||||
continue;
|
||||
}
|
||||
|
||||
*end='\0';
|
||||
|
||||
strncpy(Command,start,sizeof(Command)-1);
|
||||
|
||||
|
||||
// Now do the same thing for the flags
|
||||
nonconst=++end;
|
||||
|
||||
start=NULL;
|
||||
end=NULL;
|
||||
|
||||
// move up line until the first ", mark this down as the start
|
||||
// then find the second " and mark it down as the end
|
||||
while (*nonconst!='\0')
|
||||
{
|
||||
if (*nonconst=='"')
|
||||
{
|
||||
if (start==NULL)
|
||||
{
|
||||
start=nonconst+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
end=nonconst;
|
||||
goto done_with_flags;
|
||||
}
|
||||
}
|
||||
nonconst++;
|
||||
}
|
||||
done_with_flags:
|
||||
// invalid line?
|
||||
if (start==NULL || end==NULL)
|
||||
{
|
||||
// TODO: maybe warn for an invalid non-commented line?
|
||||
continue;
|
||||
}
|
||||
|
||||
*end='\0';
|
||||
|
||||
strncpy(Flags,start,sizeof(Flags)-1);
|
||||
|
||||
|
||||
|
||||
//if (!isalnum(*Command))
|
||||
if (*Command == '"' ||
|
||||
*Command == '\0')
|
||||
{
|
||||
continue;
|
||||
};
|
||||
|
||||
// Done sucking the command and flags out of the line
|
||||
// now insert this command into the linked list
|
||||
|
||||
AddFromFile(const_cast<const char*>(&Command[0]),&Flags[0]);
|
||||
|
||||
nonconst=const_cast<char *>(Line.c_str());
|
||||
*nonconst='\0';
|
||||
};
|
||||
|
||||
|
||||
fclose(File);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* This gets called from LoadFile
|
||||
* Do NOT flag the entries as NeedToWrite
|
||||
* No comment is passed from the file because
|
||||
* this should never get written
|
||||
*/
|
||||
void CFlagManager::AddFromFile(const char *Command, const char *Flags)
|
||||
{
|
||||
|
||||
CFlagEntry *Entry=new CFlagEntry;
|
||||
|
||||
Entry->SetName(Command);
|
||||
Entry->SetFlags(Flags);
|
||||
|
||||
// Link it
|
||||
m_FlagList.push_back(Entry);
|
||||
|
||||
};
|
||||
|
||||
|
||||
void CFlagManager::LookupOrAdd(const char *Command, int &Flags, AMX *Plugin)
|
||||
{
|
||||
if (m_iDisabled) // if disabled in core.ini stop
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
int TempFlags=Flags;
|
||||
if (TempFlags==-1)
|
||||
{
|
||||
TempFlags=0;
|
||||
}
|
||||
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if (strcmp((*iter)->GetName()->c_str(),Command)==0)
|
||||
{
|
||||
CFlagEntry *Entry=(*iter);
|
||||
|
||||
if (Entry->IsHidden()) // "!" flag, exclude this function
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Found, byref the new flags
|
||||
Flags=Entry->Flags();
|
||||
|
||||
// Move it to the back of the list for faster lookup for the rest
|
||||
m_FlagList.erase(iter);
|
||||
|
||||
m_FlagList.push_back(Entry);
|
||||
return;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
// was not found, add it
|
||||
|
||||
CFlagEntry *Entry=new CFlagEntry;
|
||||
|
||||
Entry->SetName(Command);
|
||||
Entry->SetFlags(TempFlags);
|
||||
|
||||
if (Plugin)
|
||||
{
|
||||
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(Plugin);
|
||||
|
||||
if (a)
|
||||
{
|
||||
Entry->SetComment(a->getName());
|
||||
}
|
||||
}
|
||||
|
||||
// This entry was added from a register_* native
|
||||
// it needs to be written during map change
|
||||
Entry->SetNeedWritten(1);
|
||||
|
||||
// Link it
|
||||
m_FlagList.push_back(Entry);
|
||||
|
||||
}
|
||||
void CFlagManager::WriteCommands(void)
|
||||
{
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
FILE *File;
|
||||
int NeedToRead=0;
|
||||
|
||||
// First off check the modified time of this file
|
||||
// if it matches the stored modified time, then update
|
||||
// after we write so we do not re-read next map
|
||||
struct stat TempStat;
|
||||
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
|
||||
|
||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
||||
{
|
||||
NeedToRead=1;
|
||||
};
|
||||
|
||||
|
||||
File=fopen(m_strConfigFile.c_str(),"a");
|
||||
|
||||
if (!File)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
if ((*iter)->NeedWritten())
|
||||
{
|
||||
if ((*iter)->GetComment()->size())
|
||||
{
|
||||
fprintf(File,"\"%s\" \t\"%s\" ; %s\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str(),(*iter)->GetComment()->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(File,"\"%s\" \t\"%s\"\n",(*iter)->GetName()->c_str(),(*iter)->GetFlags()->c_str());
|
||||
}
|
||||
(*iter)->SetNeedWritten(0);
|
||||
}
|
||||
++iter;
|
||||
};
|
||||
|
||||
fclose(File);
|
||||
|
||||
|
||||
// If NeedToRead was 0, then update the timestamp
|
||||
// that was saved so we do not re-read this file
|
||||
// next map
|
||||
if (!NeedToRead)
|
||||
{
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
m_Stat.st_mtime=TempStat.st_mtime;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int CFlagManager::ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const
|
||||
{
|
||||
|
||||
// If flagmanager is disabled then ignore this
|
||||
if (m_iDisabled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// If 5th param exists it was compiled after this change was made
|
||||
// if it does not exist, try our logic at the end of this function
|
||||
// 5th param being > 0 means explicit yes
|
||||
// < 0 means auto detect (default is -1), treat it like there was no 5th param
|
||||
// 0 means explicit no
|
||||
|
||||
if ((params[0] / sizeof(cell)) >= 5)
|
||||
{
|
||||
if (params[5]>0) // This command was explicitly told to be included
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (params[5]==0) // this command was explicitly told to NOT be used
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// auto detect if we should use this command
|
||||
|
||||
// if command access is -1 (default, not set to ADMIN_ALL or any other access), then no
|
||||
if (params[3]==-1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// if command is (or starts with) "say", then no
|
||||
if (strncmp(cmdname,"say",3)==0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// else use it
|
||||
return 1;
|
||||
};
|
||||
|
||||
|
||||
void CFlagManager::Clear(void)
|
||||
{
|
||||
List<CFlagEntry *>::iterator iter;
|
||||
List<CFlagEntry *>::iterator end;
|
||||
|
||||
iter=m_FlagList.begin();
|
||||
end=m_FlagList.end();
|
||||
|
||||
while (iter!=end)
|
||||
{
|
||||
delete (*iter);
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
m_FlagList.clear();
|
||||
};
|
||||
|
||||
void CFlagManager::CheckIfDisabled(void)
|
||||
{
|
||||
if (atoi(get_localinfo("disableflagman","0"))==0)
|
||||
{
|
||||
m_iDisabled=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iDisabled=1;
|
||||
}
|
||||
};
|
218
amxmodx/CFlagManager.h
Normal file
218
amxmodx/CFlagManager.h
Normal file
@ -0,0 +1,218 @@
|
||||
#ifndef CFLAGMANAGER_H
|
||||
#define CFLAGMANAGER_H
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "sh_list.h"
|
||||
#include "CString.h"
|
||||
|
||||
#include "amxmodx.h"
|
||||
|
||||
class CFlagEntry
|
||||
{
|
||||
private:
|
||||
String m_strName; // command name ("amx_slap")
|
||||
String m_strFlags; // string flags ("a","b")
|
||||
String m_strComment; // comment to write ("; admincmd.amxx")
|
||||
int m_iFlags; // bitmask flags
|
||||
int m_iNeedWritten; // write this command on map change?
|
||||
int m_iHidden; // set to 1 when the command is set to "!" access in
|
||||
// the .ini file: this means do not process this command
|
||||
|
||||
public:
|
||||
|
||||
CFlagEntry()
|
||||
{
|
||||
m_iNeedWritten=0;
|
||||
m_iFlags=0;
|
||||
m_iHidden=0;
|
||||
};
|
||||
const int NeedWritten(void) const
|
||||
{
|
||||
return m_iNeedWritten;
|
||||
};
|
||||
|
||||
void SetNeedWritten(const int i=1)
|
||||
{
|
||||
m_iNeedWritten=i;
|
||||
};
|
||||
|
||||
const String *GetName(void) const
|
||||
{
|
||||
return &m_strName;
|
||||
};
|
||||
|
||||
const String *GetFlags(void) const
|
||||
{
|
||||
return &m_strFlags;
|
||||
};
|
||||
const String *GetComment(void) const
|
||||
{
|
||||
return &m_strComment;
|
||||
};
|
||||
|
||||
const int Flags(void) const
|
||||
{
|
||||
return m_iFlags;
|
||||
};
|
||||
|
||||
void SetName(const char *data)
|
||||
{
|
||||
m_strName.assign(data);
|
||||
};
|
||||
void SetFlags(const char *flags)
|
||||
{
|
||||
// If this is a "!" entry then stop
|
||||
if (flags && flags[0]=='!')
|
||||
{
|
||||
SetHidden(1);
|
||||
return;
|
||||
}
|
||||
|
||||
m_strFlags.assign(flags);
|
||||
m_iFlags=UTIL_ReadFlags(flags);
|
||||
};
|
||||
void SetFlags(const int flags)
|
||||
{
|
||||
m_iFlags=flags;
|
||||
|
||||
char FlagsString[32];
|
||||
UTIL_GetFlags(FlagsString, flags);
|
||||
|
||||
m_strFlags.assign(FlagsString);
|
||||
};
|
||||
void SetComment(const char *comment)
|
||||
{
|
||||
m_strComment.assign(comment);
|
||||
};
|
||||
void SetHidden(int i=1)
|
||||
{
|
||||
m_iHidden=i;
|
||||
};
|
||||
int IsHidden(void) const
|
||||
{
|
||||
return m_iHidden;
|
||||
};
|
||||
};
|
||||
class CFlagManager
|
||||
{
|
||||
private:
|
||||
List<CFlagEntry *> m_FlagList;
|
||||
String m_strConfigFile;
|
||||
struct stat m_Stat;
|
||||
int m_iForceRead;
|
||||
int m_iDisabled;
|
||||
|
||||
|
||||
void CreateIfNotExist(void) const
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp=fopen(m_strConfigFile.c_str(),"r");
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
// File does not exist, create the header
|
||||
fp=fopen(m_strConfigFile.c_str(),"a");
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fprintf(fp,"; This file will store the commands used by plugins, and their access level\n");
|
||||
fprintf(fp,"; To change the access of a command, edit the flags beside it and then\n");
|
||||
fprintf(fp,"; change the server's map.\n;\n");
|
||||
fprintf(fp,"; Example: If I wanted to change the amx_slap access to require\n");
|
||||
fprintf(fp,"; RCON access (flag \"l\") I would change this:\n");
|
||||
fprintf(fp,"; \"amx_slap\" \"e\" ; admincmd.amxx\n");
|
||||
fprintf(fp,"; To this:\n");
|
||||
fprintf(fp,"; \"amx_slap\" \"l\" ; admincmd.amxx\n;\n");
|
||||
fprintf(fp,"; To disable a specific command from being used with the command manager\n");
|
||||
fprintf(fp,"; and to only use the plugin-specified access set the flag to \"!\"\n;\n");
|
||||
fprintf(fp,"; NOTE: The plugin name at the end is just for reference to what plugin\n");
|
||||
fprintf(fp,"; uses what commands. It is ignored.\n\n");
|
||||
fclose(fp);
|
||||
};
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns 1 if the timestamp for the file is different than the one we have loaded
|
||||
* 0 otherwise
|
||||
*/
|
||||
inline int NeedToLoad(void)
|
||||
{
|
||||
struct stat TempStat;
|
||||
|
||||
stat(m_strConfigFile.c_str(),&TempStat);
|
||||
|
||||
// If the modified timestamp does not match the stored
|
||||
// timestamp than we need to re-read this file.
|
||||
// Otherwise, ignore the file.
|
||||
if (TempStat.st_mtime != m_Stat.st_mtime)
|
||||
{
|
||||
// Save down the modified timestamp
|
||||
m_Stat.st_mtime=TempStat.st_mtime;
|
||||
return 1;
|
||||
};
|
||||
|
||||
return 0;
|
||||
|
||||
};
|
||||
public:
|
||||
|
||||
CFlagManager()
|
||||
{
|
||||
memset(&m_Stat,0x0,sizeof(struct stat));
|
||||
m_iDisabled=0;
|
||||
m_iForceRead=0;
|
||||
};
|
||||
~CFlagManager()
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the filename in relation to amxmodx/configs
|
||||
*/
|
||||
void SetFile(const char *Filename="cmdaccess.ini");
|
||||
|
||||
const char *GetFile(void) const { return m_strConfigFile.c_str(); };
|
||||
|
||||
/**
|
||||
* Parse the file, and load all entries
|
||||
* Returns 1 on success, 0 on refusal (no need to), and -1 on error
|
||||
*/
|
||||
const int LoadFile(const int force=0);
|
||||
|
||||
/**
|
||||
* Checks if the command exists in the list
|
||||
* If it does, it byrefs the flags for it
|
||||
* If it does not, it adds it to the list
|
||||
* These are added from register_*cmd calls
|
||||
*/
|
||||
void LookupOrAdd(const char *Command, int &Flags, AMX *Plugin);
|
||||
|
||||
|
||||
/**
|
||||
* Write the commands back to the file
|
||||
*/
|
||||
void WriteCommands(void);
|
||||
|
||||
/**
|
||||
* Add this straight from the cmdaccess.ini file
|
||||
*/
|
||||
void AddFromFile(const char *Command, const char *Flags);
|
||||
|
||||
/**
|
||||
* Checks if this command should be added to flagman or not
|
||||
* This is only checked when adding commands from the register_* natives
|
||||
* If an admin manually adds a command to cmdaccess.ini it will be used
|
||||
* regardless of whatever this function would say should be done with it
|
||||
*/
|
||||
int ShouldIAddThisCommand(const AMX *amx, const cell *params, const char *cmdname) const;
|
||||
|
||||
void Clear(void);
|
||||
|
||||
void CheckIfDisabled(void);
|
||||
};
|
||||
|
||||
#endif // CFLAGMANAGER_H
|
@ -31,8 +31,9 @@
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "debugger.h"
|
||||
#include "binlog.h"
|
||||
|
||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
|
||||
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type)
|
||||
{
|
||||
m_FuncName = name;
|
||||
m_ExecType = et;
|
||||
@ -42,11 +43,17 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
|
||||
|
||||
// find funcs
|
||||
int func;
|
||||
AMXForward *tmp = NULL;
|
||||
m_Funcs.clear();
|
||||
|
||||
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
|
||||
{
|
||||
if ((fwd_type != FORWARD_ALL) &&
|
||||
((fwd_type == FORWARD_ONLY_NEW && ((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
|
||||
|| (fwd_type == FORWARD_ONLY_OLD && !((*iter).getAMX()->flags & AMX_FLAG_OLDFILE))
|
||||
))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((*iter).isValid() && amx_FindPublic((*iter).getAMX(), name, &func) == AMX_ERR_NONE)
|
||||
{
|
||||
AMXForward tmp;
|
||||
@ -55,6 +62,8 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
|
||||
m_Funcs.push_back(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
m_Name.assign(name);
|
||||
}
|
||||
|
||||
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
@ -66,8 +75,6 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
|
||||
cell globRetVal = 0;
|
||||
|
||||
unsigned int id = 0;
|
||||
|
||||
AMXForwardList::iterator iter;
|
||||
|
||||
for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
|
||||
@ -82,15 +89,18 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
pDebugger->BeginExec();
|
||||
|
||||
// handle strings & arrays
|
||||
int i, ax = 0;
|
||||
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]);
|
||||
cell *tmp;
|
||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
if (!str)
|
||||
str = "";
|
||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, str, 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -120,7 +130,10 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
}
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
cell retVal = 0;
|
||||
#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
|
||||
@ -203,12 +216,18 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
|
||||
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);
|
||||
m_ToDelete = false;
|
||||
m_InExec = false;
|
||||
}
|
||||
|
||||
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||
@ -218,6 +237,9 @@ void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const Forwar
|
||||
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
||||
isFree = false;
|
||||
m_Name.assign(funcName);
|
||||
m_ToDelete = false;
|
||||
m_InExec = false;
|
||||
}
|
||||
|
||||
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
@ -230,13 +252,15 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
cell realParams[FORWARD_MAX_PARAMS];
|
||||
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||
|
||||
if (!m_HasFunc)
|
||||
if (!m_HasFunc || m_ToDelete)
|
||||
return 0;
|
||||
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
||||
if (!pPlugin->isExecutable(m_Func))
|
||||
return 0;
|
||||
|
||||
m_InExec = true;
|
||||
|
||||
Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
|
||||
if (pDebugger)
|
||||
pDebugger->BeginExec();
|
||||
@ -248,9 +272,12 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
{
|
||||
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||
{
|
||||
const char *str = reinterpret_cast<const char*>(params[i]);
|
||||
if (!str)
|
||||
str = "";
|
||||
cell *tmp;
|
||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i])) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, (const char *)(params[i]), 0, 0);
|
||||
amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||
amx_SetStringOld(tmp, str, 0, 0);
|
||||
physAddrs[i] = tmp;
|
||||
}
|
||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||
@ -278,6 +305,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
|
||||
// exec
|
||||
cell retVal;
|
||||
#if defined BINLOG_ENABLED
|
||||
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
|
||||
#endif
|
||||
int err = amx_Exec(m_Amx, &retVal, m_Func);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
@ -332,16 +362,20 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||
}
|
||||
}
|
||||
|
||||
m_InExec = false;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type)
|
||||
{
|
||||
int retVal = m_Forwards.size() << 1;
|
||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes);
|
||||
CForward *tmp = new CForward(funcName, et, numParams, paramTypes, fwd_type);
|
||||
|
||||
if (!tmp)
|
||||
{
|
||||
return -1; // should be invalid
|
||||
}
|
||||
|
||||
m_Forwards.push_back(tmp);
|
||||
|
||||
@ -426,12 +460,43 @@ bool CForwardMngr::isIdValid(int id) const
|
||||
|
||||
cell CForwardMngr::executeForwards(int id, cell *params)
|
||||
{
|
||||
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) : m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||
int retVal;
|
||||
if (id & 1)
|
||||
{
|
||||
CSPForward *fwd = m_SPForwards[id >> 1];
|
||||
retVal = fwd->execute(params, m_TmpArrays);
|
||||
if (fwd->m_ToDelete)
|
||||
{
|
||||
fwd->m_ToDelete = false;
|
||||
unregisterSPForward(id);
|
||||
}
|
||||
} else {
|
||||
retVal = m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||
}
|
||||
|
||||
m_TmpArraysNum = 0;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
const char *CForwardMngr::getFuncName(int id) const
|
||||
{
|
||||
if (!isIdValid(id))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getFuncName() : m_Forwards[id >> 1]->getFuncName();
|
||||
}
|
||||
|
||||
int CForwardMngr::getFuncsNum(int id) const
|
||||
{
|
||||
if (!isIdValid(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getFuncsNum() : m_Forwards[id >> 1]->getFuncsNum();
|
||||
}
|
||||
|
||||
int CForwardMngr::getParamsNum(int id) const
|
||||
{
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() : m_Forwards[id >> 1]->getParamsNum();
|
||||
@ -439,6 +504,10 @@ int CForwardMngr::getParamsNum(int id) const
|
||||
|
||||
ForwardParam CForwardMngr::getParamType(int id, int paramNum) const
|
||||
{
|
||||
if (!isIdValid(id))
|
||||
{
|
||||
return FP_DONE;
|
||||
}
|
||||
return (id & 1) ? m_SPForwards[id >> 1]->getParamType(paramNum) : m_Forwards[id >> 1]->getParamType(paramNum);
|
||||
}
|
||||
|
||||
@ -474,10 +543,63 @@ 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);
|
||||
CSPForward *fwd = m_SPForwards.at(id >> 1);
|
||||
|
||||
if (fwd->m_InExec)
|
||||
{
|
||||
fwd->m_ToDelete = true;
|
||||
} else {
|
||||
fwd->isFree = true;
|
||||
m_FreeSPForwards.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
int CForwardMngr::duplicateSPForward(int id)
|
||||
{
|
||||
if (!isIdValid(id) || m_SPForwards.at(id >> 1)->isFree)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSPForward *fwd = m_SPForwards.at(id >> 1);
|
||||
|
||||
return registerSPForward(fwd->m_Func, fwd->m_Amx, fwd->m_NumParams, fwd->m_ParamTypes);
|
||||
}
|
||||
|
||||
int CForwardMngr::isSameSPForward(int id1, int id2)
|
||||
{
|
||||
if (!isIdValid(id1) || !isIdValid(id2))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CSPForward *fwd1 = m_SPForwards.at(id1 >> 1);
|
||||
CSPForward *fwd2 = m_SPForwards.at(id2 >> 1);
|
||||
|
||||
if (fwd1->isFree || fwd2->isFree)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((fwd1->m_Amx == fwd2->m_Amx)
|
||||
&& (fwd1->m_Func == fwd2->m_Func)
|
||||
&& (fwd1->m_NumParams == fwd2->m_NumParams));
|
||||
}
|
||||
|
||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type)
|
||||
{
|
||||
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, fwd_type);
|
||||
}
|
||||
|
||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||
@ -509,6 +631,16 @@ int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||
return g_forwards.registerForward(funcName, et, curParam, params);
|
||||
}
|
||||
|
||||
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num)
|
||||
{
|
||||
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||
|
||||
for (size_t i=0; i<num; i++)
|
||||
params[i] = static_cast<ForwardParam>(list[i]);
|
||||
|
||||
return g_forwards.registerSPForward(funcName, amx, num, params);
|
||||
}
|
||||
|
||||
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
||||
{
|
||||
int curParam = 0;
|
||||
|
@ -46,8 +46,15 @@
|
||||
#ifndef FORWARD_H
|
||||
#define FORWARD_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "sh_stack.h"
|
||||
|
||||
const int FORWARD_MAX_PARAMS = 32;
|
||||
|
||||
#define FORWARD_ONLY_OLD 1
|
||||
#define FORWARD_ONLY_NEW 2
|
||||
#define FORWARD_ALL 3
|
||||
|
||||
enum ForwardExecType
|
||||
{
|
||||
ET_IGNORE = 0, // Ignore return vaue
|
||||
@ -90,6 +97,7 @@ class CForward
|
||||
const char *m_FuncName;
|
||||
ForwardExecType m_ExecType;
|
||||
int m_NumParams;
|
||||
String m_Name;
|
||||
|
||||
struct AMXForward
|
||||
{
|
||||
@ -103,7 +111,7 @@ class CForward
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
|
||||
public:
|
||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
|
||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes, int fwd_type=FORWARD_ALL);
|
||||
CForward() {} // leaves everything unitialized'
|
||||
|
||||
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||
@ -118,6 +126,11 @@ public:
|
||||
return m_Funcs.size();
|
||||
}
|
||||
|
||||
const char *getFuncName() const
|
||||
{
|
||||
return m_Name.c_str();
|
||||
}
|
||||
|
||||
ForwardParam getParamType(int paramId) const
|
||||
{
|
||||
if (paramId < 0 || paramId >= m_NumParams)
|
||||
@ -130,7 +143,7 @@ public:
|
||||
// Single plugin forward
|
||||
class CSPForward
|
||||
{
|
||||
const char *m_FuncName;
|
||||
friend class CForwardMngr;
|
||||
int m_NumParams;
|
||||
|
||||
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||
@ -138,6 +151,9 @@ class CSPForward
|
||||
|
||||
int m_Func;
|
||||
bool m_HasFunc;
|
||||
String m_Name;
|
||||
bool m_InExec;
|
||||
bool m_ToDelete;
|
||||
|
||||
public:
|
||||
bool isFree;
|
||||
@ -158,6 +174,11 @@ public:
|
||||
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)
|
||||
@ -171,7 +192,7 @@ class CForwardMngr
|
||||
{
|
||||
typedef CVector<CForward*> ForwardVec;
|
||||
typedef CVector<CSPForward*> SPForwardVec;
|
||||
typedef CQueue<int> FreeSPVec; // Free SP Forwards
|
||||
typedef CStack<int> FreeSPVec; // Free SP Forwards
|
||||
|
||||
ForwardVec m_Forwards;
|
||||
|
||||
@ -188,13 +209,15 @@ public:
|
||||
|
||||
// Interface
|
||||
// Register normal forward
|
||||
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
|
||||
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes, int fwd_type=FORWARD_ALL);
|
||||
// Register single plugin forward
|
||||
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||
|
||||
// Unregister single plugin forward
|
||||
void unregisterSPForward(int id);
|
||||
int duplicateSPForward(int id);
|
||||
int isSameSPForward(int id1, int id2);
|
||||
|
||||
// execute forward
|
||||
cell executeForwards(int id, cell *params);
|
||||
@ -204,6 +227,7 @@ public:
|
||||
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
|
||||
@ -211,7 +235,9 @@ public:
|
||||
|
||||
// (un)register forward
|
||||
int registerForward(const char *funcName, ForwardExecType et, ...);
|
||||
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num, int fwd_type=FORWARD_ALL);
|
||||
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);
|
||||
|
||||
|
1195
amxmodx/CLang.cpp
1195
amxmodx/CLang.cpp
File diff suppressed because it is too large
Load Diff
136
amxmodx/CLang.h
136
amxmodx/CLang.h
@ -32,28 +32,56 @@
|
||||
#ifndef _INCLUDE_CLANG_H
|
||||
#define _INCLUDE_CLANG_H
|
||||
|
||||
#include "sh_tinyhash.h"
|
||||
|
||||
#define LANG_SERVER 0
|
||||
#define LANG_PLAYER -1
|
||||
|
||||
#define ERR_BADKEY 1 // Lang key not found
|
||||
#define ERR_BADLANG 2 // Invalid lang
|
||||
|
||||
struct md5Pair
|
||||
{
|
||||
String file;
|
||||
String val;
|
||||
};
|
||||
|
||||
struct keyEntry
|
||||
{
|
||||
String key;
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
struct sKeyDef
|
||||
{
|
||||
sKeyDef() { key = -1; def = 0; }
|
||||
~sKeyDef() { if (def) delete def; }
|
||||
|
||||
String *definition;
|
||||
int key;
|
||||
String *def;
|
||||
};
|
||||
|
||||
struct lang_err
|
||||
{
|
||||
lang_err() : last(0.0f)
|
||||
{
|
||||
};
|
||||
float last;
|
||||
};
|
||||
|
||||
class defentry
|
||||
{
|
||||
public:
|
||||
defentry() : definition(NULL)
|
||||
{
|
||||
};
|
||||
defentry(const defentry &src)
|
||||
{
|
||||
definition = src.definition;
|
||||
}
|
||||
~defentry()
|
||||
{
|
||||
}
|
||||
String *definition;
|
||||
};
|
||||
|
||||
struct keytbl_val
|
||||
{
|
||||
keytbl_val() : index(-1)
|
||||
{
|
||||
};
|
||||
int index;
|
||||
};
|
||||
|
||||
class CLangMngr
|
||||
@ -69,9 +97,9 @@ class CLangMngr
|
||||
~CLang();
|
||||
|
||||
// Get the definition
|
||||
const char *GetDef(const char *key);
|
||||
const char *GetDef(int key, int &status);
|
||||
// Add definitions to this language
|
||||
void MergeDefinitions(CQueue <sKeyDef*> & vec);
|
||||
void MergeDefinitions(CQueue <sKeyDef> & vec);
|
||||
// Reset this language
|
||||
void Clear();
|
||||
|
||||
@ -83,69 +111,27 @@ class CLangMngr
|
||||
|
||||
// Get language name
|
||||
const char *GetName() { return m_LanguageName; }
|
||||
// Save to file
|
||||
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
|
||||
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
|
||||
// Load
|
||||
bool Load(FILE *fp);
|
||||
void SetMngr(CLangMngr *l) { m_LMan = l; }
|
||||
// Get number of entries
|
||||
int Entries() { return m_LookUpTable.size(); }
|
||||
// Make a hash from a string; convert to lowercase first if needed
|
||||
static uint32_t MakeHash(const char *src, bool makeLower = false);
|
||||
|
||||
int Entries();
|
||||
protected:
|
||||
// An entry in the language
|
||||
class LangEntry
|
||||
{
|
||||
// the definition hash
|
||||
uint32_t m_DefHash;
|
||||
// index into the lookup table?
|
||||
int key;
|
||||
// the definition
|
||||
String m_pDef;
|
||||
// is this from the cache or not?
|
||||
bool m_isCache;
|
||||
public:
|
||||
// Set
|
||||
void SetKey(int key);
|
||||
void SetDef(const char *pDef);
|
||||
void SetCache(bool c);
|
||||
// Get
|
||||
uint32_t GetDefHash();
|
||||
int GetKey();
|
||||
const char *GetDef();
|
||||
int GetDefLength();
|
||||
bool GetCache();
|
||||
|
||||
// Constructors / destructors
|
||||
LangEntry();
|
||||
LangEntry(int key);
|
||||
LangEntry(int key, const char *pDef);
|
||||
LangEntry(const LangEntry &other);
|
||||
LangEntry(int pKey, uint32_t defHash, const char *pDef);
|
||||
|
||||
// Reset
|
||||
void Clear();
|
||||
};
|
||||
|
||||
// Get (construct if needed) an entry
|
||||
LangEntry * GetEntry(int key);
|
||||
|
||||
typedef CVector<LangEntry*> LookUpVec;
|
||||
typedef LookUpVec::iterator LookUpVecIter;
|
||||
typedef THash<int, defentry> LookUpVec;
|
||||
typedef LookUpVec::iterator LookUpVecIter;
|
||||
|
||||
char m_LanguageName[3];
|
||||
|
||||
// our lookup table
|
||||
LookUpVec m_LookUpTable;
|
||||
int m_entries;
|
||||
CLangMngr *m_LMan;
|
||||
public:
|
||||
LangEntry *AddEntry(int pKey, uint32_t defHash, const char *def, bool cache);
|
||||
void AddEntry(int key, const char *definition);
|
||||
};
|
||||
|
||||
public:
|
||||
// Merge definitions into a language
|
||||
void MergeDefinitions(const char *lang, CQueue <sKeyDef*> &tmpVec);
|
||||
void MergeDefinitions(const char *lang, CQueue <sKeyDef> &tmpVec);
|
||||
|
||||
private:
|
||||
// strip lowercase; make lower if needed
|
||||
static size_t strip(char *str, char *newstr, bool makelower = false);
|
||||
|
||||
@ -155,7 +141,8 @@ class CLangMngr
|
||||
LangVec m_Languages;
|
||||
|
||||
CVector<md5Pair *> FileList;
|
||||
CVector<keyEntry*> KeyList;
|
||||
CVector<String *> KeyList;
|
||||
THash<String, keytbl_val> KeyTable;
|
||||
|
||||
// Get a lang object (construct if needed)
|
||||
CLang * GetLang(const char *name);
|
||||
@ -167,30 +154,19 @@ class CLangMngr
|
||||
public:
|
||||
// Merge a definitions file
|
||||
int MergeDefinitionFile(const char *file);
|
||||
// Get a definition from a lang name and a kyer
|
||||
const char *GetDef(const char *langName, const char *key);
|
||||
// Format a string
|
||||
const char *Format(const char *src, ...);
|
||||
// Get a definition from a lang name and a key
|
||||
const char *GetDef(const char *langName, const char *key, int &status);
|
||||
// Format a string for an AMX plugin
|
||||
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
|
||||
char *FormatString(const char *fmt, va_list &ap);
|
||||
// Save
|
||||
bool Save(const char *filename);
|
||||
// Load
|
||||
bool Load(const char *filename);
|
||||
// Cache
|
||||
bool LoadCache(const char *filename);
|
||||
bool SaveCache(const char *filename);
|
||||
void InvalidateCache();
|
||||
// Get index
|
||||
int GetKeyEntry(String &key);
|
||||
int GetKeyEntry(const char *key);
|
||||
int GetKeyHash(int key);
|
||||
// Get key from index
|
||||
const char *GetKey(int key);
|
||||
// Add key
|
||||
int AddKeyEntry(String &key);
|
||||
// Make a hash from a string; convert to lowercase first if needed
|
||||
uint32_t MakeHash(const char *src, bool makeLower);
|
||||
int AddKeyEntry(const char *key);
|
||||
|
||||
// Get the number of languages
|
||||
int GetLangsNum();
|
||||
@ -202,6 +178,8 @@ public:
|
||||
// When a language id in a format string in FormatAmxString is LANG_PLAYER, the glob id decides which language to take.
|
||||
void SetDefLang(int id);
|
||||
|
||||
inline int GetDefLang() const { return m_CurGlobId; }
|
||||
|
||||
// Reset
|
||||
void Clear();
|
||||
|
||||
|
@ -111,7 +111,7 @@ void LogEventsMngr::CLogEvent::registerFilter(char* filter)
|
||||
filters = new LogCond(cmp->pos, aa, filters);
|
||||
}
|
||||
|
||||
void LogEventsMngr::setLogString(char* frmt, va_list& vaptr)
|
||||
void LogEventsMngr::setLogString(const char* frmt, va_list& vaptr)
|
||||
{
|
||||
++logCounter;
|
||||
int len = vsnprintf(logString, 255, frmt, vaptr);
|
||||
@ -128,7 +128,7 @@ void LogEventsMngr::setLogString(char* frmt, va_list& vaptr)
|
||||
logArgc = 0;
|
||||
}
|
||||
|
||||
void LogEventsMngr::setLogString(char* frmt, ...)
|
||||
void LogEventsMngr::setLogString(const char* frmt, ...)
|
||||
{
|
||||
++logCounter;
|
||||
va_list logArgPtr;
|
||||
|
@ -141,8 +141,8 @@ public:
|
||||
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 setLogString(const char* frmt, va_list& vaptr);
|
||||
void setLogString(const char* frmt, ...);
|
||||
void parseLogString();
|
||||
void executeLogEvents();
|
||||
|
||||
|
@ -35,18 +35,21 @@
|
||||
// *****************************************************
|
||||
// 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, bool new_menu)
|
||||
{
|
||||
plugin = a;
|
||||
keys = k;
|
||||
menuid = mi;
|
||||
function = f;
|
||||
next = 0;
|
||||
is_new_menu = new_menu;
|
||||
|
||||
function = f;
|
||||
}
|
||||
|
||||
MenuMngr::~MenuMngr()
|
||||
{
|
||||
clear();
|
||||
MenuMngr::MenuIdEle::uniqueid = 0;
|
||||
}
|
||||
|
||||
int MenuMngr::findMenuId(const char* name, AMX* amx)
|
||||
@ -65,21 +68,42 @@ int MenuMngr::registerMenuId(const char* n, AMX* a)
|
||||
int id = findMenuId(n, a);
|
||||
|
||||
if (id)
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
headid = new MenuIdEle(n, a, headid);
|
||||
|
||||
if (!headid)
|
||||
return 0; // :TODO: Better error report
|
||||
|
||||
return headid->id;
|
||||
}
|
||||
|
||||
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f)
|
||||
void MenuMngr::registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu)
|
||||
{
|
||||
MenuCommand** temp = &headcmd;
|
||||
while (*temp) temp = &(*temp)->next;
|
||||
*temp = new MenuCommand(a, mi, k, f);
|
||||
MenuCommand **temp = &headcmd;
|
||||
if (from_new_menu)
|
||||
{
|
||||
MenuCommand *ptr;
|
||||
while (*temp)
|
||||
{
|
||||
ptr = *temp;
|
||||
if (ptr->is_new_menu
|
||||
&& ptr->plugin == a
|
||||
&& ptr->menuid == mi)
|
||||
{
|
||||
if (g_forwards.isSameSPForward(ptr->function, f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
temp = &(*temp)->next;
|
||||
}
|
||||
} else {
|
||||
while (*temp)
|
||||
{
|
||||
temp = &(*temp)->next;
|
||||
}
|
||||
}
|
||||
*temp = new MenuCommand(a, mi, k, f, from_new_menu);
|
||||
}
|
||||
|
||||
void MenuMngr::clear()
|
||||
@ -99,4 +123,13 @@ void MenuMngr::clear()
|
||||
}
|
||||
}
|
||||
|
||||
MenuMngr::iterator MenuMngr::SetWatchIter(MenuMngr::iterator iter)
|
||||
{
|
||||
MenuMngr::iterator old = m_watch_iter;
|
||||
|
||||
m_watch_iter = iter;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
||||
int MenuMngr::MenuIdEle::uniqueid = 0;
|
||||
|
@ -51,8 +51,6 @@ class MenuMngr
|
||||
{
|
||||
id = ++uniqueid;
|
||||
}
|
||||
|
||||
~MenuIdEle() { --uniqueid; }
|
||||
} *headid;
|
||||
|
||||
public:
|
||||
@ -68,28 +66,34 @@ private:
|
||||
int menuid;
|
||||
int keys;
|
||||
int function;
|
||||
int is_new_menu;
|
||||
|
||||
MenuCommand* next;
|
||||
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f);
|
||||
MenuCommand(CPluginMngr::CPlugin *a, int mi, int k, int f, bool new_menu=false);
|
||||
public:
|
||||
inline int getFunction() { return function; }
|
||||
inline CPluginMngr::CPlugin* getPlugin() { return plugin; }
|
||||
inline bool matchCommand(int m, int k) { return ((m == menuid) && (keys & k)); }
|
||||
inline bool matchCommand(int m, int k)
|
||||
{
|
||||
return ((m == menuid) && (keys & k));
|
||||
}
|
||||
} *headcmd;
|
||||
|
||||
public:
|
||||
MenuMngr() { headid = 0; headcmd = 0; }
|
||||
MenuMngr() : m_watch_iter(end())
|
||||
{ headid = NULL; headcmd = NULL; }
|
||||
~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);
|
||||
void registerMenuCmd(CPluginMngr::CPlugin *a, int mi, int k, int f, bool from_new_menu=false);
|
||||
void clear();
|
||||
|
||||
class iterator
|
||||
{
|
||||
friend class MenuMngr;
|
||||
MenuCommand* a;
|
||||
public:
|
||||
iterator(MenuCommand*aa) : a(aa) {}
|
||||
@ -102,6 +106,13 @@ public:
|
||||
|
||||
inline iterator begin() const { return iterator(headcmd); }
|
||||
inline iterator end() const { return iterator(0); }
|
||||
|
||||
MenuMngr::iterator SetWatchIter(MenuMngr::iterator iter);
|
||||
inline MenuMngr::iterator GetWatchIter() { return m_watch_iter; }
|
||||
private:
|
||||
MenuMngr::iterator m_watch_iter;
|
||||
};
|
||||
|
||||
extern MenuMngr g_menucmds;
|
||||
|
||||
#endif //MENUS_H
|
||||
|
@ -29,6 +29,7 @@
|
||||
* version.
|
||||
*/
|
||||
#include "amxmodx.h"
|
||||
#include "newmenus.h"
|
||||
// *****************************************************
|
||||
// class CPlayer
|
||||
// *****************************************************
|
||||
@ -39,7 +40,6 @@ void CPlayer::Init(edict_t* e, int i)
|
||||
pEdict = e;
|
||||
initialized = false;
|
||||
ingame = false;
|
||||
bot = false;
|
||||
authorized = false;
|
||||
|
||||
current = 0;
|
||||
@ -48,6 +48,8 @@ void CPlayer::Init(edict_t* e, int i)
|
||||
aiming = 0;
|
||||
menu = 0;
|
||||
keys = 0;
|
||||
menuexpire = 0.0;
|
||||
newmenu = -1;
|
||||
|
||||
death_weapon.clear();
|
||||
name.clear();
|
||||
@ -61,19 +63,32 @@ void CPlayer::Disconnect()
|
||||
initialized = false;
|
||||
authorized = false;
|
||||
|
||||
while (!cvarQueryQueue.empty())
|
||||
if (newmenu != -1)
|
||||
{
|
||||
ClientCvarQuery_Info *pQuery = cvarQueryQueue.front();
|
||||
unregisterSPForward(pQuery->resultFwd);
|
||||
|
||||
if (pQuery->params)
|
||||
delete [] pQuery->params;
|
||||
|
||||
delete pQuery;
|
||||
cvarQueryQueue.pop();
|
||||
Menu *pMenu = g_NewMenus[newmenu];
|
||||
if (pMenu)
|
||||
{
|
||||
//prevent recursion
|
||||
newmenu = -1;
|
||||
menu = 0;
|
||||
executeForwards(pMenu->func,
|
||||
static_cast<cell>(ENTINDEX(pEdict)),
|
||||
static_cast<cell>(pMenu->thisId),
|
||||
static_cast<cell>(MENU_EXIT));
|
||||
}
|
||||
}
|
||||
|
||||
bot = 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();
|
||||
|
||||
menu = 0;
|
||||
newmenu = -1;
|
||||
}
|
||||
|
||||
void CPlayer::PutInServer()
|
||||
@ -82,13 +97,27 @@ void CPlayer::PutInServer()
|
||||
ingame = true;
|
||||
}
|
||||
|
||||
int CPlayer::NextHUDChannel()
|
||||
{
|
||||
int ilow = 1;
|
||||
|
||||
for (int i=ilow+1; i<=4; i++)
|
||||
{
|
||||
if (channels[i] < channels[ilow])
|
||||
ilow = i;
|
||||
}
|
||||
|
||||
return ilow;
|
||||
}
|
||||
|
||||
bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
||||
{
|
||||
name.assign(connectname);
|
||||
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));
|
||||
@ -96,6 +125,21 @@ bool CPlayer::Connect(const char* connectname, const char* ipaddress)
|
||||
initialized = true;
|
||||
authorized = false;
|
||||
|
||||
for (int i=0; i<=4; i++)
|
||||
{
|
||||
channels[i] = 0.0f;
|
||||
hudmap[i] = 0;
|
||||
}
|
||||
|
||||
List<ClientCvarQuery_Info *>::iterator iter, end=queries.end();
|
||||
for (iter=queries.begin(); iter!=end; iter++)
|
||||
{
|
||||
unregisterSPForward((*iter)->resultFwd);
|
||||
delete [] (*iter)->params;
|
||||
delete (*iter);
|
||||
}
|
||||
queries.clear();
|
||||
|
||||
const char* authid = GETPLAYERAUTHID(pEdict);
|
||||
|
||||
if ((authid == 0) || (*authid == 0) || (strcmp(authid, "STEAM_ID_PENDING") == 0))
|
||||
|
113
amxmodx/CMisc.h
113
amxmodx/CMisc.h
@ -33,6 +33,7 @@
|
||||
#define CMISC_H
|
||||
|
||||
#include "CList.h"
|
||||
#include "sh_list.h"
|
||||
|
||||
// *****************************************************
|
||||
// class CCVar
|
||||
@ -57,6 +58,7 @@ public:
|
||||
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); }
|
||||
int plugin_id;
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
@ -65,10 +67,8 @@ public:
|
||||
|
||||
struct ClientCvarQuery_Info
|
||||
{
|
||||
bool querying; // Are we actually waiting for a response at the moment?
|
||||
String cvarName;
|
||||
int resultFwd;
|
||||
|
||||
int requestId;
|
||||
int paramLen;
|
||||
cell *params;
|
||||
};
|
||||
@ -84,11 +84,12 @@ public:
|
||||
|
||||
bool initialized;
|
||||
bool ingame;
|
||||
bool bot;
|
||||
bool authorized;
|
||||
bool vgui;
|
||||
|
||||
float time;
|
||||
float playtime;
|
||||
float menuexpire;
|
||||
|
||||
struct
|
||||
{
|
||||
@ -113,11 +114,13 @@ public:
|
||||
int newmenu;
|
||||
int page;
|
||||
|
||||
float channels[5];
|
||||
cell hudmap[5];
|
||||
|
||||
Vector lastTrace;
|
||||
Vector thisTrace;
|
||||
Vector lastHit;
|
||||
|
||||
CQueue<ClientCvarQuery_Info*> cvarQueryQueue;
|
||||
List<ClientCvarQuery_Info *> queries;
|
||||
|
||||
void Init(edict_t* e, int i);
|
||||
void Disconnect();
|
||||
@ -127,7 +130,18 @@ public:
|
||||
|
||||
inline bool IsBot()
|
||||
{
|
||||
return ((pEdict->v.flags & FL_FAKECLIENT) ? true : false);
|
||||
if ((pEdict->v.flags & FL_FAKECLIENT) == FL_FAKECLIENT)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const char *auth = GETPLAYERAUTHID(pEdict);
|
||||
if (auth && (strcmp(auth, "BOT") == 0))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool IsAlive()
|
||||
@ -137,6 +151,8 @@ public:
|
||||
|
||||
inline void Authorize() { authorized = true; }
|
||||
|
||||
int NextHUDChannel();
|
||||
|
||||
};
|
||||
|
||||
// *****************************************************
|
||||
@ -280,4 +296,87 @@ public:
|
||||
inline bool isNewTeam() { return newTeam ? true : false; }
|
||||
};
|
||||
|
||||
class CAdminData
|
||||
{
|
||||
private:
|
||||
cell m_AuthData[44];
|
||||
cell m_Password[32];
|
||||
cell m_Flags;
|
||||
cell m_Access;
|
||||
public:
|
||||
|
||||
CAdminData()
|
||||
{
|
||||
m_AuthData[0]=0;
|
||||
m_Password[0]=0;
|
||||
m_Flags=0;
|
||||
m_Access=0;
|
||||
};
|
||||
|
||||
void SetAccess(cell Access)
|
||||
{
|
||||
m_Access=Access;
|
||||
};
|
||||
cell GetAccess(void) const
|
||||
{
|
||||
return m_Access;
|
||||
};
|
||||
|
||||
void SetFlags(cell Flags)
|
||||
{
|
||||
m_Flags=Flags;
|
||||
};
|
||||
cell GetFlags(void) const
|
||||
{
|
||||
return m_Flags;
|
||||
};
|
||||
|
||||
void SetAuthID(const cell *Input)
|
||||
{
|
||||
unsigned int i=0;
|
||||
while (i<sizeof(m_AuthData)-1)
|
||||
{
|
||||
if ((m_AuthData[i++]=*Input++)==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_AuthData[arraysize(m_AuthData)-1]=0;
|
||||
|
||||
};
|
||||
const cell *GetAuthID(void) const
|
||||
{
|
||||
return &m_AuthData[0];
|
||||
};
|
||||
|
||||
void SetPass(const cell *Input)
|
||||
{
|
||||
unsigned int i=0;
|
||||
while (i<sizeof(m_Password)-1)
|
||||
{
|
||||
if ((m_Password[i++]=*Input++)==0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_Password[arraysize(m_Password)-1]=0;
|
||||
|
||||
};
|
||||
const cell *GetPass(void) const
|
||||
{
|
||||
return &m_Password[0];
|
||||
};
|
||||
|
||||
CAdminData & operator = (const CAdminData &src)
|
||||
{
|
||||
this->SetAccess(src.GetAccess());
|
||||
this->SetFlags(src.GetFlags());
|
||||
this->SetAuthID(src.GetAuthID());
|
||||
this->SetPass(src.GetPass());
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
#endif //CMISC_H
|
||||
|
@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "libraries.h"
|
||||
|
||||
#ifndef FAR
|
||||
#define FAR
|
||||
@ -38,9 +39,12 @@
|
||||
// New
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
typedef int (FAR *QUERYMOD_NEW)(int * /*ifvers*/, amxx_module_info_s * /*modInfo*/);
|
||||
typedef int (FAR *CHECKGAME_NEW)(const char *);
|
||||
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
|
||||
@ -79,7 +83,14 @@ void CModule::clear(bool clearFilename)
|
||||
m_InfoNew.reload = 0;
|
||||
m_MissingFunc = NULL;
|
||||
|
||||
for (size_t i=0; i<m_DestroyableIndexes.size(); i++)
|
||||
{
|
||||
delete [] m_Natives[m_DestroyableIndexes[i]];
|
||||
}
|
||||
|
||||
m_DestroyableIndexes.clear();
|
||||
m_Natives.clear();
|
||||
m_NewNatives.clear();
|
||||
}
|
||||
|
||||
bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||
@ -102,6 +113,53 @@ bool CModule::attachMetamod(const char *mmfile, PLUG_LOADTIME now)
|
||||
return true;
|
||||
}
|
||||
|
||||
//this ugly function is ultimately something like O(n^4).
|
||||
//sigh. it shouldn't be needed.
|
||||
void CModule::rewriteNativeLists(AMX_NATIVE_INFO *list)
|
||||
{
|
||||
AMX_NATIVE_INFO *curlist;
|
||||
for (size_t i=0; i<m_Natives.size(); i++)
|
||||
{
|
||||
curlist = m_Natives[i];
|
||||
bool changed = false;
|
||||
bool found = false;
|
||||
CVector<size_t> newlist;
|
||||
for (size_t j=0; curlist[j].func != NULL; j++)
|
||||
{
|
||||
found = false;
|
||||
for (size_t k=0; list[k].func != NULL; k++)
|
||||
{
|
||||
if (strcmp(curlist[j].name, list[k].name) == 0)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found)
|
||||
{
|
||||
changed = true;
|
||||
//don't break, we have to search it all
|
||||
} else {
|
||||
newlist.push_back(j);
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
//now build the new list
|
||||
AMX_NATIVE_INFO *rlist = new AMX_NATIVE_INFO[newlist.size()+1];
|
||||
for (size_t j=0; j<newlist.size(); j++)
|
||||
{
|
||||
rlist[j].func = curlist[newlist[j]].func;
|
||||
rlist[j].name = curlist[newlist[j]].name;
|
||||
}
|
||||
rlist[newlist.size()].func = NULL;
|
||||
rlist[newlist.size()].name = NULL;
|
||||
m_Natives[i] = rlist;
|
||||
m_DestroyableIndexes.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CModule::attachModule()
|
||||
{
|
||||
// old & new
|
||||
@ -126,7 +184,7 @@ bool CModule::attachModule()
|
||||
{
|
||||
case AMXX_OK:
|
||||
m_Status = MODULE_LOADED;
|
||||
return true;
|
||||
break;
|
||||
case AMXX_PARAM:
|
||||
AMXXLOG_Log("[AMXX] Internal Error: Module \"%s\" (version \"%s\") retured \"Invalid parameter\" from Attach func.", m_Filename.c_str(), getVersion());
|
||||
m_Status = MODULE_INTERROR;
|
||||
@ -144,6 +202,13 @@ bool CModule::attachModule()
|
||||
m_Status = MODULE_BADLOAD;
|
||||
}
|
||||
|
||||
if (m_Status == MODULE_LOADED)
|
||||
{
|
||||
AddLibrariesFromString(m_InfoNew.library, LibType_Library, LibSource_Module, this);
|
||||
AddLibrariesFromString(m_InfoNew.libclass, LibType_Class, LibSource_Module, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -155,6 +220,9 @@ bool CModule::queryModule()
|
||||
m_Handle = DLLOAD(m_Filename.c_str()); // load file
|
||||
if (!m_Handle)
|
||||
{
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" failed to load (%s)", m_Filename.c_str(), dlerror());
|
||||
#endif
|
||||
m_Status = MODULE_BADLOAD;
|
||||
return false;
|
||||
}
|
||||
@ -184,10 +252,36 @@ bool CModule::queryModule()
|
||||
return false;
|
||||
case AMXX_IFVERS:
|
||||
if (ifVers < AMXX_INTERFACE_VERSION)
|
||||
m_Status = MODULE_OLD;
|
||||
else
|
||||
{
|
||||
//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;
|
||||
return false;
|
||||
}
|
||||
case AMXX_OK:
|
||||
break;
|
||||
default:
|
||||
@ -203,6 +297,33 @@ bool CModule::queryModule()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Lastly, check to see if this module is able to load on this game mod
|
||||
CHECKGAME_NEW checkGame_New = (CHECKGAME_NEW)DLPROC(m_Handle, "AMXX_CheckGame");
|
||||
|
||||
if (checkGame_New)
|
||||
{
|
||||
// This is an optional check; do not fail modules that do not have it
|
||||
int ret = checkGame_New(g_mod_name.c_str());
|
||||
|
||||
if (ret != AMXX_GAME_OK)
|
||||
{
|
||||
switch (ret)
|
||||
{
|
||||
case AMXX_GAME_BAD:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") reported that it cannot load on game \"%s\"", m_Filename.c_str(), getVersion(), g_mod_name.c_str());
|
||||
m_Status = MODULE_BADGAME;
|
||||
break;
|
||||
default:
|
||||
AMXXLOG_Log("[AMXX] Module \"%s\" (version \"%s\") returned an unknown CheckGame code (value: %d)", m_Filename.c_str(), getVersion(), ret);
|
||||
m_Status = MODULE_BADLOAD;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
m_Status = MODULE_QUERY;
|
||||
return true;
|
||||
} else {
|
||||
@ -217,6 +338,8 @@ bool CModule::detachModule()
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return false;
|
||||
|
||||
RemoveLibraries(this);
|
||||
|
||||
if (m_Amxx)
|
||||
{
|
||||
DETACHMOD_NEW detachFunc_New = (DETACHMOD_NEW)DLPROC(m_Handle, "AMXX_Detach");
|
||||
@ -244,6 +367,38 @@ bool CModule::detachModule()
|
||||
return true;
|
||||
}
|
||||
|
||||
void CModule::CallPluginsUnloaded()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return;
|
||||
|
||||
if (!m_Handle)
|
||||
return;
|
||||
|
||||
PLUGINSUNLOADED_NEW func = (PLUGINSUNLOADED_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloaded");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
void CModule::CallPluginsUnloading()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
return;
|
||||
|
||||
if (!m_Handle)
|
||||
return;
|
||||
|
||||
PLUGINSUNLOADING_NEW func = (PLUGINSUNLOADING_NEW)DLPROC(m_Handle, "AMXX_PluginsUnloading");
|
||||
|
||||
if (!func)
|
||||
return;
|
||||
|
||||
func();
|
||||
}
|
||||
|
||||
void CModule::CallPluginsLoaded()
|
||||
{
|
||||
if (m_Status != MODULE_LOADED)
|
||||
@ -276,6 +431,7 @@ const char* CModule::getStatus() const
|
||||
case MODULE_NEWER: return "newer";
|
||||
case MODULE_INTERROR: return "internal err";
|
||||
case MODULE_NOT64BIT: return "not 64bit";
|
||||
case MODULE_BADGAME: return "bad game";
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,8 @@ enum MODULE_STATUS
|
||||
MODULE_NEWER, // newer interface
|
||||
MODULE_INTERROR, // Internal error
|
||||
MODULE_FUNCNOTPRESENT, // Function not present
|
||||
MODULE_NOT64BIT // Not 64 bit compatible
|
||||
MODULE_NOT64BIT, // Not 64 bit compatible
|
||||
MODULE_BADGAME, // Module cannot load on the current game mod
|
||||
};
|
||||
|
||||
struct amxx_module_info_s
|
||||
@ -59,6 +60,8 @@ struct amxx_module_info_s
|
||||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; //added in version 2
|
||||
const char *library; // added in version 4
|
||||
const char *libclass; // added in version 4
|
||||
};
|
||||
|
||||
#define AMXX_OK 0 /* no error */
|
||||
@ -66,7 +69,10 @@ struct amxx_module_info_s
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
#define AMXX_GAME_OK 0 /* Module can load on this game. */
|
||||
#define AMXX_GAME_BAD 1 /* Module cannot load on this game. */
|
||||
|
||||
#define AMXX_INTERFACE_VERSION 4
|
||||
|
||||
class CModule
|
||||
{
|
||||
@ -90,6 +96,7 @@ public:
|
||||
bool attachModule();
|
||||
bool queryModule();
|
||||
bool detachModule();
|
||||
void rewriteNativeLists(AMX_NATIVE_INFO *list);
|
||||
|
||||
#ifndef FAKEMETA
|
||||
bool attachMetamod(const char *mmfile, PLUG_LOADTIME now);
|
||||
@ -109,9 +116,13 @@ public:
|
||||
inline const char *getFilename() { return m_Filename.c_str(); }
|
||||
inline bool IsMetamod() { return m_Metamod; }
|
||||
|
||||
void CModule::CallPluginsLoaded();
|
||||
void CallPluginsLoaded();
|
||||
void CallPluginsUnloaded();
|
||||
void CallPluginsUnloading();
|
||||
|
||||
CList<AMX_NATIVE_INFO*> m_Natives;
|
||||
CVector<AMX_NATIVE_INFO*> m_Natives;
|
||||
CVector<AMX_NATIVE_INFO*> m_NewNatives; // Natives for new (AMXX, not AMX) plugins only
|
||||
CVector<size_t> m_DestroyableIndexes;
|
||||
};
|
||||
|
||||
#endif //CMODULE_H
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "amx.h"
|
||||
#include "natives.h"
|
||||
#include "debugger.h"
|
||||
#include "libraries.h"
|
||||
|
||||
extern const char *no_function;
|
||||
|
||||
@ -80,14 +81,17 @@ void CPluginMngr::Finalize()
|
||||
m_Finalized = true;
|
||||
}
|
||||
|
||||
int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
int CPluginMngr::loadPluginsFromFile(const char* filename, bool warn)
|
||||
{
|
||||
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);
|
||||
if (warn)
|
||||
{
|
||||
AMXXLOG_Error("[AMXX] Plugins list not found (file \"%s\")", filename);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -98,6 +102,8 @@ int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
|
||||
String line;
|
||||
|
||||
List<String *>::iterator block_iter;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
pluginName[0] = '\0';
|
||||
@ -107,16 +113,51 @@ int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
|
||||
line.clear();
|
||||
line._fread(fp);
|
||||
/** quick hack */
|
||||
char *ptr = const_cast<char *>(line.c_str());
|
||||
while (*ptr)
|
||||
{
|
||||
if (*ptr == ';')
|
||||
{
|
||||
*ptr = '\0';
|
||||
} else {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
sscanf(line.c_str(), "%s %s", pluginName, debug);
|
||||
|
||||
if (!isalnum(*pluginName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isalnum(*debug) && strcmp(debug, "debug") == 0)
|
||||
if (isalnum(*debug) && !strcmp(debug, "debug"))
|
||||
{
|
||||
debugFlag = 1;
|
||||
}
|
||||
|
||||
bool skip = false;
|
||||
for (block_iter = m_BlockList.begin();
|
||||
block_iter != m_BlockList.end();
|
||||
block_iter++)
|
||||
{
|
||||
if ((*block_iter)->compare(pluginName) == 0)
|
||||
{
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skip || !strcmp(debug, "disabled"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (findPlugin(pluginName) != NULL)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CPlugin* plugin = loadPlugin(pluginsDir, pluginName, error, debugFlag);
|
||||
|
||||
if (plugin->getStatusCode() == ps_bad_load)
|
||||
@ -124,7 +165,7 @@ int CPluginMngr::loadPluginsFromFile(const char* filename)
|
||||
char errorMsg[255];
|
||||
sprintf(errorMsg, "%s (plugin \"%s\")", error, pluginName);
|
||||
plugin->setError(errorMsg);
|
||||
AMXXLOG_Log("[AMXX] %s", plugin->getError());
|
||||
AMXXLOG_Error("[AMXX] %s", plugin->getError());
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,11 +188,14 @@ void CPluginMngr::clear()
|
||||
delete [] pNatives;
|
||||
pNatives = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPluginFast(AMX *amx)
|
||||
{
|
||||
return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]);
|
||||
List<String *>::iterator iter = m_BlockList.begin();
|
||||
while (iter != m_BlockList.end())
|
||||
{
|
||||
delete (*iter);
|
||||
iter = m_BlockList.erase(iter);
|
||||
}
|
||||
m_BlockList.clear();
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin* CPluginMngr::findPlugin(AMX *amx)
|
||||
@ -192,6 +236,17 @@ CPluginMngr::CPlugin* CPluginMngr::findPlugin(const char* name)
|
||||
return a;
|
||||
}
|
||||
|
||||
void CPluginMngr::CPlugin::AddToFailCounter(unsigned int i)
|
||||
{
|
||||
failcounter += i;
|
||||
if ((failcounter >= 3)
|
||||
&& (status ))
|
||||
{
|
||||
errorMsg.assign("This plugin is non-GPL which violates AMX Mod X's license.");
|
||||
status = ps_bad_load;
|
||||
}
|
||||
}
|
||||
|
||||
const char* CPluginMngr::CPlugin::getStatus() const
|
||||
{
|
||||
switch (status)
|
||||
@ -219,6 +274,7 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
|
||||
{
|
||||
const char* unk = "unknown";
|
||||
|
||||
failcounter = 0;
|
||||
title.assign(unk);
|
||||
author.assign(unk);
|
||||
version.assign(unk);
|
||||
@ -243,8 +299,8 @@ CPluginMngr::CPlugin::CPlugin(int i, const char* p, const char* n, char* e, int
|
||||
|
||||
if (status == ps_running)
|
||||
{
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause");
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause");
|
||||
m_PauseFwd = registerSPForwardByName(&amx, "plugin_pause", FP_DONE);
|
||||
m_UnpauseFwd = registerSPForwardByName(&amx, "plugin_unpause", FP_DONE);
|
||||
|
||||
if (amx.flags & AMX_FLAG_DEBUG)
|
||||
{
|
||||
@ -293,7 +349,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
||||
}
|
||||
|
||||
char name[sNAMEMAX + 1];
|
||||
int native = amx->usertags[UT_NATIVE];
|
||||
int native = (int)(_INT_PTR)(amx->usertags[UT_NATIVE]);
|
||||
int err = amx_GetNative(amx, native, name);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
@ -302,6 +358,7 @@ static cell AMX_NATIVE_CALL invalid_native(AMX *amx, cell *params)
|
||||
//1 - because we're trapping usage
|
||||
if (!pHandler->HandleNative(name, native, 1))
|
||||
{
|
||||
amx->usertags[UT_NATIVE] = (void *)native;
|
||||
LogError(amx, AMX_ERR_INVNATIVE, NULL);
|
||||
return 0;
|
||||
}
|
||||
@ -377,13 +434,286 @@ void CPluginMngr::CPlugin::pausePlugin()
|
||||
// Unpause a plugin
|
||||
void CPluginMngr::CPlugin::unpausePlugin()
|
||||
{
|
||||
if (isValid())
|
||||
if (isValid() && (getStatusCode() != ps_stopped))
|
||||
{
|
||||
// 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 ||
|
||||
pl->file->IsOldFile())
|
||||
{
|
||||
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);
|
||||
|
||||
/* HACK: see if there's a 'disabled' coming up
|
||||
* new block for scopying flexibility
|
||||
*/
|
||||
if (1)
|
||||
{
|
||||
const char *_ptr = rline.c_str() + strlen(pluginName);
|
||||
while (*_ptr != '\0' && isspace(*_ptr))
|
||||
{
|
||||
_ptr++;
|
||||
}
|
||||
if ((*_ptr != '\0') && !strcmp(_ptr, "disabled"))
|
||||
{
|
||||
String *pString = new String(pluginName);
|
||||
m_BlockList.push_back(pString);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
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,18 +32,23 @@
|
||||
#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_locked,
|
||||
ps_paused,
|
||||
ps_stopped,
|
||||
ps_running,
|
||||
ps_bad_load, //Load failed
|
||||
ps_error, //Erroneous state
|
||||
ps_locked, //UNUSED
|
||||
ps_paused, //Plugin is temporarily paused
|
||||
ps_stopped, //Plugin is ... more temporarily paused
|
||||
ps_running, //Plugin is running
|
||||
};
|
||||
|
||||
class CPluginMngr
|
||||
@ -66,6 +71,7 @@ public:
|
||||
String author;
|
||||
String errorMsg;
|
||||
|
||||
unsigned int failcounter;
|
||||
int m_PauseFwd;
|
||||
int m_UnpauseFwd;
|
||||
int paused_fun;
|
||||
@ -93,9 +99,11 @@ public:
|
||||
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 isStopped() const { return (status == ps_stopped); }
|
||||
inline bool isExecutable(int id) const { return (isValid() && !isPaused()); }
|
||||
|
||||
void Finalize();
|
||||
void AddToFailCounter(unsigned int i);
|
||||
void pausePlugin();
|
||||
void unpausePlugin();
|
||||
void pauseFunction(int id);
|
||||
@ -111,7 +119,7 @@ private:
|
||||
int pCounter;
|
||||
public:
|
||||
CPluginMngr() { head = 0; pCounter = 0; pNatives = NULL; m_Finalized=false;}
|
||||
~CPluginMngr() { clear(); }
|
||||
~CPluginMngr() { clear(); InvalidateCache(); }
|
||||
|
||||
bool m_Finalized;
|
||||
AMX_NATIVE_INFO *pNatives;
|
||||
@ -120,9 +128,9 @@ public:
|
||||
|
||||
CPlugin* loadPlugin(const char* path, const char* name, char* error, int debug);
|
||||
void unloadPlugin(CPlugin** a);
|
||||
int loadPluginsFromFile(const char* filename);
|
||||
int loadPluginsFromFile(const char* filename, bool warn=true);
|
||||
|
||||
CPlugin* findPluginFast(AMX *amx);
|
||||
inline CPlugin* findPluginFast(AMX *amx) { return (CPlugin*)(amx->userdata[UD_FINDPLUGIN]); }
|
||||
CPlugin* findPlugin(AMX *amx);
|
||||
CPlugin* findPlugin(int index);
|
||||
CPlugin* findPlugin(const char* name);
|
||||
@ -145,6 +153,22 @@ public:
|
||||
|
||||
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;
|
||||
List<String *> m_BlockList;
|
||||
};
|
||||
|
||||
#endif //PLUGIN_H
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
String(String &src)
|
||||
String(const String &src)
|
||||
{
|
||||
v = NULL;
|
||||
a_size = 0;
|
||||
@ -107,8 +107,10 @@ public:
|
||||
{
|
||||
clear();
|
||||
} else {
|
||||
Grow(strlen(d) + 1, false);
|
||||
strcpy(v, d);
|
||||
size_t len = strlen(d);
|
||||
Grow(len + 1, false);
|
||||
memcpy(v, d, len);
|
||||
v[len] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,7 +120,7 @@ public:
|
||||
v[0] = '\0';
|
||||
}
|
||||
|
||||
int compare (const char *d)
|
||||
int compare (const char *d) const
|
||||
{
|
||||
if (!v)
|
||||
return strcmp("", d);
|
||||
@ -127,7 +129,7 @@ public:
|
||||
}
|
||||
|
||||
//Added this for amxx inclusion
|
||||
bool empty()
|
||||
bool empty() const
|
||||
{
|
||||
if (!v)
|
||||
return true;
|
||||
@ -138,7 +140,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
size_t size() const
|
||||
{
|
||||
if (v)
|
||||
return strlen(v);
|
||||
@ -148,13 +150,13 @@ public:
|
||||
|
||||
int find(const char c, int index = 0)
|
||||
{
|
||||
size_t len = size();
|
||||
int len = static_cast<int>(size());
|
||||
if (len < 1)
|
||||
return npos;
|
||||
if (index >= (int)len || index < 0)
|
||||
if (index >= len || index < 0)
|
||||
return npos;
|
||||
unsigned int i = 0;
|
||||
for (i=index; i<(int)len; i++)
|
||||
int i = 0;
|
||||
for (i=index; i<len; i++)
|
||||
{
|
||||
if (v[i] == c)
|
||||
{
|
||||
@ -177,6 +179,30 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
void reparse_newlines()
|
||||
{
|
||||
size_t len = size();
|
||||
int offs = 0;
|
||||
char c;
|
||||
if (!len)
|
||||
return;
|
||||
for (size_t i=0; i<len; i++)
|
||||
{
|
||||
c = v[i];
|
||||
if (c == '^' && (i != len-1))
|
||||
{
|
||||
c = v[++i];
|
||||
if (c == 'n')
|
||||
c = '\n';
|
||||
else if (c == 't')
|
||||
c = '\t';
|
||||
offs++;
|
||||
}
|
||||
v[i-offs] = c;
|
||||
}
|
||||
v[len-offs] = '\0';
|
||||
}
|
||||
|
||||
void trim()
|
||||
{
|
||||
if (!v)
|
||||
@ -218,7 +244,7 @@ public:
|
||||
|
||||
if (is_space(v[len-1]))
|
||||
{
|
||||
for (i=len-1; i>=0; i--)
|
||||
for (i=len-1; i<len; i--)
|
||||
{
|
||||
if (!is_space(v[i])
|
||||
|| (is_space(v[i]) && i==0))
|
||||
@ -247,7 +273,7 @@ public:
|
||||
unsigned int i = 0;
|
||||
size_t len = size();
|
||||
//check for bounds
|
||||
if (num == npos || start+num > len-num+1)
|
||||
if (num == npos || start+num > len-start)
|
||||
num = len - start;
|
||||
//do the erasing
|
||||
bool copyflag = false;
|
||||
@ -297,7 +323,7 @@ public:
|
||||
num = len - index;
|
||||
}
|
||||
|
||||
unsigned int i = 0, j=0;
|
||||
unsigned int i = 0;
|
||||
unsigned int nslen = num + 2;
|
||||
|
||||
ns.Grow(nslen);
|
||||
|
@ -34,17 +34,7 @@
|
||||
|
||||
/*********************** CTask ***********************/
|
||||
|
||||
int CTaskMngr::CTask::getTaskId() const
|
||||
{
|
||||
return m_iId;
|
||||
}
|
||||
|
||||
CPluginMngr::CPlugin *CTaskMngr::CTask::getPlugin() const
|
||||
{
|
||||
return m_pPlugin;
|
||||
}
|
||||
|
||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
||||
void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime)
|
||||
{
|
||||
clear();
|
||||
m_bFree = false;
|
||||
@ -53,6 +43,7 @@ void CTaskMngr::CTask::set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags,
|
||||
m_iFunc = iFunc;
|
||||
m_iId = iId;
|
||||
m_fBase = fBase;
|
||||
m_bInExecute = false;
|
||||
|
||||
if (iFlags & 2)
|
||||
{
|
||||
@ -150,6 +141,7 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
||||
//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);
|
||||
@ -157,6 +149,7 @@ void CTaskMngr::CTask::executeIfRequired(float fCurrentTime, float fTimeLimit, f
|
||||
} else {
|
||||
executeForwards(m_iFunc, m_iId);
|
||||
}
|
||||
m_bInExecute = false;
|
||||
}
|
||||
|
||||
if (isFree())
|
||||
@ -193,6 +186,7 @@ CTaskMngr::CTask::CTask()
|
||||
m_bLoop = false;
|
||||
m_bAfterStart = false;
|
||||
m_bBeforeEnd = false;
|
||||
m_bInExecute = false;
|
||||
|
||||
m_fNextExecTime = 0.0f;
|
||||
|
||||
@ -226,7 +220,7 @@ void CTaskMngr::registerTimers(float *pCurrentTime, float *pTimeLimit, float *pT
|
||||
m_pTmr_TimeLeft = pTimeLeft;
|
||||
}
|
||||
|
||||
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
||||
void CTaskMngr::registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat)
|
||||
{
|
||||
// first, search for free tasks
|
||||
TaskListIter iter = m_Tasks.find(CTaskDescriptor(0, NULL, true));
|
||||
|
@ -41,10 +41,11 @@ private:
|
||||
// task settings
|
||||
|
||||
CPluginMngr::CPlugin *m_pPlugin;
|
||||
int m_iId;
|
||||
cell m_iId;
|
||||
int m_iFunc;
|
||||
int m_iRepeat;
|
||||
|
||||
bool m_bInExecute;
|
||||
bool m_bLoop;
|
||||
bool m_bAfterStart;
|
||||
bool m_bBeforeEnd;
|
||||
@ -57,17 +58,19 @@ private:
|
||||
// execution
|
||||
float m_fNextExecTime;
|
||||
public:
|
||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||
void set(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat, float fCurrentTime);
|
||||
void clear();
|
||||
bool isFree() const;
|
||||
|
||||
CPluginMngr::CPlugin *getPlugin() const;
|
||||
int getTaskId() const;
|
||||
inline CPluginMngr::CPlugin *getPlugin() const { return m_pPlugin; }
|
||||
inline AMX *getAMX() const { return m_pPlugin->getAMX(); }
|
||||
inline int getTaskId() const { return m_iId; }
|
||||
|
||||
void executeIfRequired(float fCurrentTime, float fTimeLimit, float fTimeLeft); // also removes the task if needed
|
||||
|
||||
void changeBase(float fNewBase);
|
||||
void resetNextExecTime(float fCurrentTime);
|
||||
inline bool inExecute() const { return m_bInExecute; }
|
||||
|
||||
bool shouldRepeat();
|
||||
|
||||
@ -78,7 +81,7 @@ private:
|
||||
class CTaskDescriptor
|
||||
{
|
||||
public:
|
||||
int m_iId;
|
||||
cell m_iId;
|
||||
AMX *m_pAmx;
|
||||
bool m_bFree;
|
||||
|
||||
@ -92,9 +95,11 @@ private:
|
||||
friend bool operator == (const CTask &left, const CTaskDescriptor &right)
|
||||
{
|
||||
if (right.m_bFree)
|
||||
return left.isFree();
|
||||
return (left.isFree() && !left.inExecute());
|
||||
|
||||
return !left.isFree() && (right.m_pAmx ? left.getPlugin()->getAMX() == right.m_pAmx : true) && left.getTaskId() == right.m_iId;
|
||||
return (!left.isFree()) &&
|
||||
(right.m_pAmx ? left.getAMX() == right.m_pAmx : true) &&
|
||||
(left.getTaskId() == right.m_iId);
|
||||
}
|
||||
};
|
||||
|
||||
@ -112,7 +117,7 @@ public:
|
||||
~CTaskMngr();
|
||||
|
||||
void registerTimers(float *pCurrentTime, float *pTimeLimit, float *pTimeLeft); // The timers will always point to the right value
|
||||
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, int iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
||||
void registerTask(CPluginMngr::CPlugin *pPlugin, int iFunc, int iFlags, cell iId, float fBase, int iParamsLen, const cell *pParams, int iRepeat);
|
||||
|
||||
int removeTasks(int iId, AMX *pAmx); // remove all tasks that match the id and amx
|
||||
int changeTasks(int iId, AMX *pAmx, float fNewBase); // change all tasks that match the id and amx
|
||||
|
@ -37,12 +37,20 @@
|
||||
// Vector
|
||||
template <class T> class CVector
|
||||
{
|
||||
bool Grow()
|
||||
bool Grow(size_t amount)
|
||||
{
|
||||
// automatic grow
|
||||
size_t newSize = m_Size * 2;
|
||||
|
||||
if (newSize == 0)
|
||||
newSize = 8; // a good init value
|
||||
{
|
||||
newSize = 8;
|
||||
}
|
||||
|
||||
while (m_CurrentUsedSize + amount > newSize)
|
||||
{
|
||||
newSize *= 2;
|
||||
}
|
||||
T *newData = new T[newSize];
|
||||
if (!newData)
|
||||
return false;
|
||||
@ -57,12 +65,16 @@ template <class T> class CVector
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GrowIfNeeded()
|
||||
bool GrowIfNeeded(size_t amount)
|
||||
{
|
||||
if (m_CurrentUsedSize >= m_Size)
|
||||
return Grow();
|
||||
if (m_CurrentUsedSize + amount >= m_Size)
|
||||
{
|
||||
return Grow(amount);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChangeSize(size_t size)
|
||||
@ -329,14 +341,13 @@ public:
|
||||
|
||||
bool push_back(const T & elem)
|
||||
{
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
if (!GrowIfNeeded(1))
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Data[m_CurrentUsedSize - 1] = elem;
|
||||
m_Data[m_CurrentUsedSize++] = elem;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -434,13 +445,13 @@ public:
|
||||
|
||||
size_t ofs = where - begin();
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
if (!GrowIfNeeded())
|
||||
if (!GrowIfNeeded(1))
|
||||
{
|
||||
--m_CurrentUsedSize;
|
||||
return false;
|
||||
}
|
||||
|
||||
++m_CurrentUsedSize;
|
||||
|
||||
where = begin() + ofs;
|
||||
|
||||
// Move subsequent entries
|
||||
|
BIN
amxmodx/JIT/amxexecn-darwin.o
Normal file
BIN
amxmodx/JIT/amxexecn-darwin.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
amxmodx/JIT/amxjitsn-darwin.o
Normal file
BIN
amxmodx/JIT/amxjitsn-darwin.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
amxmodx/JIT/helpers-darwin-x86.o
Normal file
BIN
amxmodx/JIT/helpers-darwin-x86.o
Normal 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-darwin-x86.o
Normal file
BIN
amxmodx/JIT/natives-darwin-x86.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
168
amxmodx/Makefile
168
amxmodx/Makefile
@ -1,95 +1,147 @@
|
||||
#(C)2004-2005 AMX Mod X Development Team
|
||||
# (C)2004-2013 AMX Mod X Development Team
|
||||
# Makefile written by David "BAILOPAN" Anderson
|
||||
|
||||
HLSDK = ../hlsdk/SourceCode
|
||||
MM_ROOT = ../metamod/metamod
|
||||
###########################################
|
||||
### EDIT THESE PATHS FOR YOUR OWN SETUP ###
|
||||
###########################################
|
||||
|
||||
HLSDK = ../../hlsdk/multiplayer
|
||||
MM_ROOT = ../../metamod/metamod
|
||||
|
||||
#####################################
|
||||
### EDIT BELOW FOR OTHER PROJECTS ###
|
||||
#####################################
|
||||
|
||||
OPT_FLAGS = -O2 -funroll-loops -s -pipe
|
||||
DEBUG_FLAGS = -g -ggdb3
|
||||
CPP = gcc
|
||||
NAME = amxmodx_mm
|
||||
PROJECT = amxmodx
|
||||
|
||||
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
|
||||
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 sorting.cpp \
|
||||
amxmod_compat.cpp nongpl_matches.cpp CFlagManager.cpp datastructs.cpp \
|
||||
trie_natives.cpp
|
||||
|
||||
LINK = -lz
|
||||
##############################################
|
||||
### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
|
||||
##############################################
|
||||
|
||||
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
|
||||
C_OPT_FLAGS = -DNDEBUG -O2 -funroll-loops -fomit-frame-pointer -pipe
|
||||
C_DEBUG_FLAGS = -D_DEBUG -DDEBUG -g -ggdb3
|
||||
C_GCC4_FLAGS = -fvisibility=hidden
|
||||
CPP_GCC4_FLAGS = -fvisibility-inlines-hidden
|
||||
CPP = gcc
|
||||
CPP_OSX = clang
|
||||
|
||||
LINK = -Lzlib
|
||||
|
||||
INCLUDE = -I. -I$(HLSDK) -I$(HLSDK)/common -I$(HLSDK)/dlls -I$(HLSDK)/engine -I$(HLSDK)/game_shared \
|
||||
-I$(MM_ROOT)
|
||||
|
||||
################################################
|
||||
### DO NOT EDIT BELOW HERE FOR MOST PROJECTS ###
|
||||
################################################
|
||||
|
||||
OS := $(shell uname -s)
|
||||
|
||||
ifeq "$(OS)" "Darwin"
|
||||
OBJECTS += JIT/amxexecn-darwin.o JIT/amxjitsn-darwin.o JIT/natives-darwin-x86.o \
|
||||
JIT/helpers-darwin-x86.o
|
||||
|
||||
CPP = $(CPP_OSX)
|
||||
LIB_EXT = dylib
|
||||
LIB_SUFFIX = _mm
|
||||
CFLAGS += -DOSX
|
||||
LINK += -dynamiclib -lstdc++ -mmacosx-version-min=10.5 -Wl,-read_only_relocs,suppress -lz-darwin
|
||||
else
|
||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o JIT/helpers-x86.o
|
||||
|
||||
LIB_EXT = so
|
||||
LIB_SUFFIX = _mm_i386
|
||||
CFLAGS += -DLINUX
|
||||
LINK += -shared -lz
|
||||
endif
|
||||
|
||||
LINK += -m32 -lm -ldl
|
||||
|
||||
CFLAGS += -DAMX_NOPROPLIST -DPAWN_CELL_SIZE=32 -DJIT -DASM32 -DHAVE_STDINT_H -fno-strict-aliasing \
|
||||
-m32 -Wall -Werror
|
||||
CPPFLAGS += -fno-exceptions -fno-rtti
|
||||
|
||||
BINARY = $(PROJECT)$(LIB_SUFFIX).$(LIB_EXT)
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
BIN_DIR = Debug
|
||||
CFLAGS = $(DEBUG_FLAGS)
|
||||
CFLAGS += $(C_DEBUG_FLAGS)
|
||||
else
|
||||
BIN_DIR = Release
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
CFLAGS += $(C_OPT_FLAGS)
|
||||
LINK += -s
|
||||
endif
|
||||
|
||||
ifeq "$(MMGR)" "true"
|
||||
OBJECTS += mmgr/mmgr.cpp
|
||||
CFLAGS += -DMEMORY_TEST
|
||||
ifeq "$(BINLOG)" "true"
|
||||
LIB_SUFFIX := _bl$(LIB_SUFFIX)
|
||||
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
|
||||
IS_CLANG := $(shell $(CPP) --version | head -1 | grep clang > /dev/null && echo "1" || echo "0")
|
||||
|
||||
ifeq "$(AMD64)" "true"
|
||||
BINARY = $(NAME)_amd64.so
|
||||
CFLAGS += -DPAWN_CELL_SIZE=64 -DHAVE_I64 -m64
|
||||
OBJECTS += JIT/natives-amd64.o
|
||||
ifeq "$(IS_CLANG)" "1"
|
||||
CPP_MAJOR := $(shell $(CPP) --version | grep clang | sed "s/.*version \([0-9]\)*\.[0-9]*.*/\1/")
|
||||
CPP_MINOR := $(shell $(CPP) --version | grep clang | sed "s/.*version [0-9]*\.\([0-9]\)*.*/\1/")
|
||||
else
|
||||
BINARY = $(NAME)_i386.so
|
||||
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
|
||||
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
|
||||
OPT_FLAGS += -march=i686
|
||||
CPP_MAJOR := $(shell $(CPP) -dumpversion >&1 | cut -b1)
|
||||
CPP_MINOR := $(shell $(CPP) -dumpversion >&1 | cut -b3)
|
||||
endif
|
||||
|
||||
OBJ_LINUX := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
# Clang || GCC >= 4
|
||||
ifeq "$(shell expr $(IS_CLANG) \| $(CPP_MAJOR) \>= 4)" "1"
|
||||
CFLAGS += $(C_GCC4_FLAGS)
|
||||
CPPFLAGS += $(CPP_GCC4_FLAGS)
|
||||
endif
|
||||
|
||||
# Clang >= 3 || GCC >= 4.7
|
||||
ifeq "$(shell expr $(IS_CLANG) \& $(CPP_MAJOR) \>= 3 \| $(CPP_MAJOR) \>= 4 \& $(CPP_MINOR) \>= 7)" "1"
|
||||
CFLAGS += -Wno-delete-non-virtual-dtor
|
||||
endif
|
||||
|
||||
# OS is Linux and not using clang
|
||||
ifeq "$(shell expr $(OS) \= Linux \& $(IS_CLANG) \= 0)" "1"
|
||||
LINK += -static-libgcc
|
||||
endif
|
||||
|
||||
OBJ_BIN := $(OBJECTS:%.cpp=$(BIN_DIR)/%.o)
|
||||
|
||||
# This will break if we include other Makefiles, but is fine for now. It allows
|
||||
# us to make a copy of this file that uses altered paths (ie. Makefile.mine)
|
||||
# or other changes without mucking up the original.
|
||||
MAKEFILE_NAME := $(CURDIR)/$(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
|
||||
|
||||
$(BIN_DIR)/%.o: %.cpp
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) -o $@ -c $<
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
|
||||
|
||||
all:
|
||||
mkdir -p $(BIN_DIR)
|
||||
$(MAKE) amxmodx
|
||||
$(MAKE) -f $(MAKEFILE_NAME) $(PROJECT)
|
||||
|
||||
amd64:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true
|
||||
binlog:
|
||||
$(MAKE) -f $(MAKEFILE_NAME) all BINLOG=true
|
||||
|
||||
amd64_mmgr:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true MMGR=true
|
||||
binlog_debug:
|
||||
$(MAKE) -f $(MAKEFILE_NAME) all BINLOG=true DEBUG=true
|
||||
|
||||
amd64_debug_mmgr:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true DEBUG=true MMGR=true
|
||||
|
||||
amd64_debug:
|
||||
rm -f zlib/libz.a
|
||||
$(MAKE) all AMD64=true DEBUG=true
|
||||
|
||||
mmgr:
|
||||
$(MAKE) all MMGR=true
|
||||
|
||||
debug_mmgr:
|
||||
$(MAKE) all MMGR=true DEBUG=true
|
||||
|
||||
amxmodx: $(OBJ_LINUX)
|
||||
$(CPP) $(INCLUDE) $(CFLAGS) $(OBJ_LINUX) $(LINK) -shared -ldl -lm -o$(BIN_DIR)/$(BINARY)
|
||||
$(PROJECT): $(OBJ_BIN)
|
||||
$(CPP) $(INCLUDE) $(OBJ_BIN) $(LINK) -o $(BIN_DIR)/$(BINARY)
|
||||
|
||||
debug:
|
||||
$(MAKE) all DEBUG=true
|
||||
$(MAKE) -f $(MAKEFILE_NAME) all DEBUG=true
|
||||
|
||||
default: all
|
||||
|
||||
clean:
|
||||
rm -rf Release/*.o
|
||||
rm -rf Release/$(BINARY)
|
||||
rm -rf Debug/*.o
|
||||
rm -rf Debug/$(BINARY)
|
||||
rm -rf $(BIN_DIR)/*.o
|
||||
rm -f $(BIN_DIR)/$(BINARY)
|
||||
|
||||
|
435
amxmodx/amx.cpp
435
amxmodx/amx.cpp
@ -18,13 +18,13 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amx.cpp 3707 2008-04-14 19:56:31Z sawce $
|
||||
*/
|
||||
|
||||
#define AMX_NODYNALOAD
|
||||
#define AMX_ANSIONLY
|
||||
#define AMX_ANSIONLY
|
||||
|
||||
#if BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64
|
||||
#if !defined __linux__ && BUILD_PLATFORM == WINDOWS && BUILD_TYPE == RELEASE && BUILD_COMPILER == MSVC && PAWN_CELL_SIZE == 64
|
||||
/* bad bad workaround but we have to prevent a compiler crash :/ */
|
||||
#pragma optimize("g",off)
|
||||
#endif
|
||||
@ -46,8 +46,9 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "osdefs.h"
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
#include <sclinux.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@ -265,6 +266,13 @@ typedef enum {
|
||||
OP_SYSREQ_D,
|
||||
OP_SYMTAG, /* obsolete */
|
||||
OP_BREAK,
|
||||
OP_FLOAT_MUL,
|
||||
OP_FLOAT_DIV,
|
||||
OP_FLOAT_ADD,
|
||||
OP_FLOAT_SUB,
|
||||
OP_FLOAT_TO,
|
||||
OP_FLOAT_ROUND,
|
||||
OP_FLOAT_CMP,
|
||||
/* ----- */
|
||||
OP_NUM_OPCODES
|
||||
} OPCODE;
|
||||
@ -428,7 +436,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr->natives<=hdr->libraries);
|
||||
#if defined AMX_NATIVETABLE
|
||||
if (index<NULL) {
|
||||
if (index<0) {
|
||||
assert(-(index+1)<(sizeof(AMX_NATIVETABLE)/sizeof(AMX_NATIVETABLE)[0]));
|
||||
f=(AMX_NATIVETABLE)[-(index+1)];
|
||||
} else {
|
||||
@ -444,7 +452,7 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
/* As of AMX Mod X 1.56, we don't patch sysreq.c to sysreq.d anymore.
|
||||
* Otherwise, we'd have no way of knowing the last native to be used.
|
||||
*/
|
||||
amx->usertags[UT_NATIVE] = (long)index;
|
||||
amx->usertags[UT_NATIVE] = (void *)index;
|
||||
|
||||
/* Note:
|
||||
* params[0] == number of bytes for the additional parameters passed to the native function
|
||||
@ -454,8 +462,24 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
|
||||
|
||||
amx->error=AMX_ERR_NONE;
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
binlogfuncs_t *logfuncs = (binlogfuncs_t *)amx->usertags[UT_BINLOGS];
|
||||
if (logfuncs)
|
||||
{
|
||||
logfuncs->pfnLogNative(amx, index, (int)(params[0] / sizeof(cell)));
|
||||
logfuncs->pfnLogParams(amx, params);
|
||||
}
|
||||
#endif //BINLOG_ENABLED
|
||||
|
||||
*result = f(amx,params);
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
if (logfuncs)
|
||||
{
|
||||
logfuncs->pfnLogReturn(amx, *result);
|
||||
}
|
||||
#endif
|
||||
|
||||
return amx->error;
|
||||
}
|
||||
#endif /* defined AMX_INIT */
|
||||
@ -487,6 +511,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
cell cip;
|
||||
long codesize;
|
||||
OPCODE op;
|
||||
BROWSEHOOK hook = NULL;
|
||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
||||
cell *opcode_list;
|
||||
#endif
|
||||
@ -502,6 +527,7 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
code=amx->base+(int)hdr->cod;
|
||||
codesize=hdr->dat - hdr->cod;
|
||||
amx->flags|=AMX_FLAG_BROWSE;
|
||||
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
||||
|
||||
/* sanity checks */
|
||||
assert(OP_PUSH_PRI==36);
|
||||
@ -607,11 +633,22 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
case OP_FILL:
|
||||
case OP_HALT:
|
||||
case OP_BOUNDS:
|
||||
case OP_SYSREQ_C:
|
||||
case OP_PUSHADDR:
|
||||
case OP_SYSREQ_D:
|
||||
cip+=sizeof(cell);
|
||||
break;
|
||||
case OP_SYSREQ_C:
|
||||
{
|
||||
if (hook)
|
||||
#if defined __GNUC__ || defined ASM32 || defined JIT
|
||||
hook(amx, opcode_list, &cip);
|
||||
#else
|
||||
hook(amx, NULL, &cip);
|
||||
#endif
|
||||
else
|
||||
cip+=sizeof(cell);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_LOAD_I: /* instructions without parameters */
|
||||
case OP_STOR_I:
|
||||
@ -672,6 +709,13 @@ static int amx_BrowseRelocate(AMX *amx)
|
||||
case OP_SWAP_ALT:
|
||||
case OP_NOP:
|
||||
case OP_BREAK:
|
||||
case OP_FLOAT_MUL:
|
||||
case OP_FLOAT_DIV:
|
||||
case OP_FLOAT_ADD:
|
||||
case OP_FLOAT_SUB:
|
||||
case OP_FLOAT_TO:
|
||||
case OP_FLOAT_ROUND:
|
||||
case OP_FLOAT_CMP:
|
||||
break;
|
||||
|
||||
case OP_CALL: /* opcodes that need relocation */
|
||||
@ -759,7 +803,7 @@ static void expand(unsigned char *code, long codesize, long memsize)
|
||||
do {
|
||||
codesize--;
|
||||
/* no input byte should be shifted out completely */
|
||||
assert(shift<8*sizeof(cell));
|
||||
assert(shift<static_cast<int>(8*sizeof(cell)));
|
||||
/* we work from the end of a sequence backwards; the final code in
|
||||
* a sequence may not have the continuation bit set */
|
||||
assert(shift>0 || (code[(size_t)codesize] & 0x80)==0);
|
||||
@ -796,22 +840,10 @@ static void expand(unsigned char *code, long codesize, long memsize)
|
||||
}
|
||||
#endif /* defined AMX_INIT */
|
||||
|
||||
int AMXAPI amx_Init(AMX *amx,void *program)
|
||||
int AMXAPI amx_Init(AMX *amx, void *program)
|
||||
{
|
||||
AMX_HEADER *hdr;
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||
char libname[sNAMEMAX+8]; /* +1 for '\0', +3 for 'amx' prefix, +4 for extension */
|
||||
#if defined _Windows
|
||||
typedef int (FAR WINAPI *AMX_ENTRY)(AMX _FAR *amx);
|
||||
HINSTANCE hlib;
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
typedef int (*AMX_ENTRY)(AMX *amx);
|
||||
void *hlib;
|
||||
#endif
|
||||
int numlibraries,i;
|
||||
AMX_FUNCSTUB *lib;
|
||||
AMX_ENTRY libinit;
|
||||
#endif
|
||||
BROWSEHOOK hook = NULL;
|
||||
|
||||
if ((amx->flags & AMX_FLAG_RELOC)!=0)
|
||||
return AMX_ERR_INIT; /* already initialized (may not do so twice) */
|
||||
@ -821,22 +853,6 @@ int AMXAPI amx_Init(AMX *amx,void *program)
|
||||
* multi-byte words
|
||||
*/
|
||||
assert(check_endian());
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
amx_Align32((uint32_t*)&hdr->size);
|
||||
amx_Align16(&hdr->magic);
|
||||
amx_Align16((uint16_t*)&hdr->flags);
|
||||
amx_Align16((uint16_t*)&hdr->defsize);
|
||||
amx_Align32((uint32_t*)&hdr->cod);
|
||||
amx_Align32((uint32_t*)&hdr->dat);
|
||||
amx_Align32((uint32_t*)&hdr->hea);
|
||||
amx_Align32((uint32_t*)&hdr->stp);
|
||||
amx_Align32((uint32_t*)&hdr->cip);
|
||||
amx_Align32((uint32_t*)&hdr->publics);
|
||||
amx_Align32((uint32_t*)&hdr->natives);
|
||||
amx_Align32((uint32_t*)&hdr->libraries);
|
||||
amx_Align32((uint32_t*)&hdr->pubvars);
|
||||
amx_Align32((uint32_t*)&hdr->tags);
|
||||
#endif
|
||||
|
||||
if (hdr->magic!=AMX_MAGIC)
|
||||
return AMX_ERR_FORMAT;
|
||||
@ -857,13 +873,7 @@ int AMXAPI amx_Init(AMX *amx,void *program)
|
||||
} /* if */
|
||||
if (hdr->stp<=0)
|
||||
return AMX_ERR_FORMAT;
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
if ((hdr->flags & AMX_FLAG_COMPACT)==0) {
|
||||
ucell *code=(ucell *)((unsigned char *)program+(int)hdr->cod);
|
||||
while (code<(ucell *)((unsigned char *)program+(int)hdr->hea))
|
||||
swapcell(code++);
|
||||
} /* if */
|
||||
#endif
|
||||
|
||||
assert((hdr->flags & AMX_FLAG_COMPACT)!=0 || hdr->hea == hdr->size);
|
||||
if ((hdr->flags & AMX_FLAG_COMPACT)!=0) {
|
||||
#if AMX_COMPACTMARGIN > 2
|
||||
@ -890,111 +900,18 @@ int AMXAPI amx_Init(AMX *amx,void *program)
|
||||
amx->callback=amx_Callback;
|
||||
amx->data=NULL;
|
||||
|
||||
/* also align all addresses in the public function, public variable,
|
||||
* public tag and native function tables --offsets into the name table
|
||||
* (if present) must also be swapped.
|
||||
*/
|
||||
#if BYTE_ORDER==BIG_ENDIAN
|
||||
{ /* local */
|
||||
AMX_FUNCSTUB *fs;
|
||||
int i,num;
|
||||
|
||||
fs=GETENTRY(hdr,natives,0);
|
||||
num=NUMENTRIES(hdr,natives,libraries);
|
||||
for (i=0; i<num; i++) {
|
||||
amx_AlignCell(&fs->address); /* redundant, because it should be zero */
|
||||
if (USENAMETABLE(hdr))
|
||||
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||
} /* for */
|
||||
|
||||
fs=GETENTRY(hdr,publics,0);
|
||||
assert(hdr->publics<=hdr->natives);
|
||||
num=NUMENTRIES(hdr,publics,natives);
|
||||
for (i=0; i<num; i++) {
|
||||
amx_AlignCell(&fs->address);
|
||||
if (USENAMETABLE(hdr))
|
||||
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||
} /* for */
|
||||
|
||||
fs=GETENTRY(hdr,pubvars,0);
|
||||
assert(hdr->pubvars<=hdr->tags);
|
||||
num=NUMENTRIES(hdr,pubvars,tags);
|
||||
for (i=0; i<num; i++) {
|
||||
amx_AlignCell(&fs->address);
|
||||
if (USENAMETABLE(hdr))
|
||||
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||
} /* for */
|
||||
|
||||
fs=GETENTRY(hdr,tags,0);
|
||||
if (hdr->file_version<7) {
|
||||
assert(hdr->tags<=hdr->cod);
|
||||
num=NUMENTRIES(hdr,tags,cod);
|
||||
} else {
|
||||
assert(hdr->tags<=hdr->nametable);
|
||||
num=NUMENTRIES(hdr,tags,nametable);
|
||||
} /* if */
|
||||
for (i=0; i<num; i++) {
|
||||
amx_AlignCell(&fs->address);
|
||||
if (USENAMETABLE(hdr))
|
||||
amx_AlignCell(&((AMX_FUNCSTUBNT*)fs)->nameofs);
|
||||
fs=(AMX_FUNCSTUB*)((unsigned char *)fs+hdr->defsize);
|
||||
} /* for */
|
||||
} /* local */
|
||||
#endif
|
||||
|
||||
/* relocate call and jump instructions */
|
||||
hook = (BROWSEHOOK)amx->usertags[UT_BROWSEHOOK];
|
||||
if (hook)
|
||||
hook(amx, NULL, NULL);
|
||||
amx_BrowseRelocate(amx);
|
||||
|
||||
/* load any extension modules that the AMX refers to */
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
numlibraries=NUMENTRIES(hdr,libraries,pubvars);
|
||||
for (i=0; i<numlibraries; i++) {
|
||||
lib=GETENTRY(hdr,libraries,i);
|
||||
strcpy(libname,"amx");
|
||||
strcat(libname,GETENTRYNAME(hdr,lib));
|
||||
#if defined _Windows
|
||||
strcat(libname,".dll");
|
||||
#if defined __WIN32__
|
||||
hlib=LoadLibraryA(libname);
|
||||
#else
|
||||
hlib=LoadLibrary(libname);
|
||||
if (hlib<=HINSTANCE_ERROR)
|
||||
hlib=NULL;
|
||||
#endif
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
strcat(libname,".so");
|
||||
hlib=dlopen(libname,RTLD_NOW);
|
||||
#endif
|
||||
if (hlib!=NULL) {
|
||||
/* a library that cannot be loaded or that does not have the required
|
||||
* initialization function is simply ignored
|
||||
*/
|
||||
char funcname[sNAMEMAX+9]; /* +1 for '\0', +4 for 'amx_', +4 for 'Init' */
|
||||
strcpy(funcname,"amx_");
|
||||
strcat(funcname,GETENTRYNAME(hdr,lib));
|
||||
strcat(funcname,"Init");
|
||||
#if defined _Windows
|
||||
libinit=(AMX_ENTRY)GetProcAddress(hlib,funcname);
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
libinit=(AMX_ENTRY)dlsym(hlib,funcname);
|
||||
#endif
|
||||
if (libinit!=NULL)
|
||||
libinit(amx);
|
||||
} /* if */
|
||||
lib->address=(ucell)hlib;
|
||||
} /* for */
|
||||
#endif
|
||||
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
#if defined JIT
|
||||
|
||||
#define CODESIZE_JIT 8192 /* approximate size of the code for the JIT */
|
||||
#define CODESIZE_JIT 65536 /* approximate size of the code for the JIT */
|
||||
|
||||
#if defined __WIN32__ /* this also applies to Win32 "console" applications */
|
||||
|
||||
@ -1015,7 +932,7 @@ int AMXAPI amx_Init(AMX *amx,void *program)
|
||||
|
||||
#define ALIGN(addr) (addr)
|
||||
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
|
||||
/* Linux already has mprotect() */
|
||||
/* But wants the address aligned! */
|
||||
@ -1056,26 +973,25 @@ int AMXAPI amx_InitJIT(AMX *amx, void *reloc_table, void *native_code)
|
||||
memcpy(native_code, amx->base, ((AMX_HEADER *)(amx->base))->cod);
|
||||
hdr = (AMX_HEADER *)native_code;
|
||||
|
||||
|
||||
|
||||
/* JIT rulz! (TM) */
|
||||
/* MP: added check for correct compilation */
|
||||
//Fixed bug (thanks T(+)rget)
|
||||
if ((res = asm_runJIT(amx->base, reloc_table, native_code)) == 0)
|
||||
{
|
||||
/* update the required memory size (the previous value was a
|
||||
* conservative estimate, now we know the exact size)
|
||||
*/
|
||||
amx->code_size = (hdr->dat + hdr->stp + 3) & ~3;
|
||||
/* The compiled code is relocatable, since only relative jumps are
|
||||
* used for destinations within the generated code and absoulute
|
||||
* addresses for jumps into the runtime, which is fixed in memory.
|
||||
*/
|
||||
amx->base = (unsigned char*) native_code;
|
||||
amx->cip = hdr->cip;
|
||||
amx->hea = hdr->hea;
|
||||
amx->stp = hdr->stp - sizeof(cell);
|
||||
/* also put a sentinel for strings at the top the stack */
|
||||
*(cell *)((char*)native_code + hdr->dat + hdr->stp - sizeof(cell)) = 0;
|
||||
amx->stk = amx->stp;
|
||||
/* also put a sentinel for strings at the top the stack */
|
||||
*(cell *)((char*)native_code + hdr->dat + amx->stp - sizeof(cell)) = 0;
|
||||
/* update the required memory size (the previous value was a
|
||||
* conservative estimate, now we know the exact size)
|
||||
*/
|
||||
amx->code_size = (hdr->dat + amx->stp + sizeof(cell)) & ~3;
|
||||
} /* if */
|
||||
|
||||
return (res == 0) ? AMX_ERR_NONE : AMX_ERR_INIT_JIT;
|
||||
@ -1098,10 +1014,10 @@ int AMXAPI amx_InitJIT(AMX *amx,void *compiled_program,void *reloc_table)
|
||||
#if defined AMX_CLEANUP
|
||||
int AMXAPI amx_Cleanup(AMX *amx)
|
||||
{
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__) && !defined AMX_NODYNALOAD
|
||||
#if defined _Windows
|
||||
typedef int (FAR WINAPI *AMX_ENTRY)(AMX FAR *amx);
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
typedef int (*AMX_ENTRY)(AMX *amx);
|
||||
#endif
|
||||
AMX_HEADER *hdr;
|
||||
@ -1111,7 +1027,7 @@ int AMXAPI amx_Cleanup(AMX *amx)
|
||||
#endif
|
||||
|
||||
/* unload all extension modules */
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__) && !defined AMX_NODYNALOAD
|
||||
#if (defined _Windows || defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__) && !defined AMX_NODYNALOAD
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr->magic==AMX_MAGIC);
|
||||
numlibraries=NUMENTRIES(hdr,libraries,pubvars);
|
||||
@ -1124,14 +1040,14 @@ int AMXAPI amx_Cleanup(AMX *amx)
|
||||
strcat(funcname,"Cleanup");
|
||||
#if defined _Windows
|
||||
libcleanup=(AMX_ENTRY)GetProcAddress((HINSTANCE)lib->address,funcname);
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
libcleanup=(AMX_ENTRY)dlsym((void*)lib->address,funcname);
|
||||
#endif
|
||||
if (libcleanup!=NULL)
|
||||
libcleanup(amx);
|
||||
#if defined _Windows
|
||||
FreeLibrary((HINSTANCE)lib->address);
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#elif defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
dlclose((void*)lib->address);
|
||||
#endif
|
||||
} /* if */
|
||||
@ -1259,27 +1175,22 @@ int AMXAPI amx_GetNative(AMX *amx, int index, char *funcname)
|
||||
|
||||
int AMXAPI amx_FindNative(AMX *amx, const char *name, int *index)
|
||||
{
|
||||
int first,last,mid,result;
|
||||
int first,last,mid;
|
||||
char pname[sNAMEMAX+1];
|
||||
|
||||
amx_NumNatives(amx, &last);
|
||||
last--; /* last valid index is 1 less than the number of functions */
|
||||
first=0;
|
||||
/* binary search */
|
||||
while (first<=last) {
|
||||
mid=(first+last)/2;
|
||||
/* normal search */
|
||||
for (mid=0; mid<=last; mid++)
|
||||
{
|
||||
amx_GetNative(amx, mid, pname);
|
||||
result=strcmp(pname,name);
|
||||
if (result>0) {
|
||||
last=mid-1;
|
||||
} else if (result<0) {
|
||||
first=mid+1;
|
||||
} else {
|
||||
*index=mid;
|
||||
if (strcmp(pname, name)==0)
|
||||
{
|
||||
*index = mid;
|
||||
return AMX_ERR_NONE;
|
||||
} /* if */
|
||||
} /* while */
|
||||
/* not found, set to an invalid index, so amx_Exec() will fail */
|
||||
} /* if */
|
||||
} /* for */
|
||||
*index=INT_MAX;
|
||||
return AMX_ERR_NOTFOUND;
|
||||
}
|
||||
@ -1492,37 +1403,11 @@ int AMXAPI amx_FindTagId(AMX *amx, cell tag_id, char *tagname)
|
||||
#if defined AMX_XXXUSERDATA
|
||||
int AMXAPI amx_GetUserData(AMX *amx, long tag, void **ptr)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amx!=NULL);
|
||||
assert(tag!=0);
|
||||
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
||||
/* nothing */;
|
||||
if (index>=AMX_USERNUM)
|
||||
return AMX_ERR_USERDATA;
|
||||
*ptr=amx->userdata[index];
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
|
||||
int AMXAPI amx_SetUserData(AMX *amx, long tag, void *ptr)
|
||||
{
|
||||
int index;
|
||||
|
||||
assert(amx!=NULL);
|
||||
assert(tag!=0);
|
||||
/* try to find existing tag */
|
||||
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=tag; index++)
|
||||
/* nothing */;
|
||||
/* if not found, try to find empty tag */
|
||||
if (index>=AMX_USERNUM)
|
||||
for (index=0; index<AMX_USERNUM && amx->usertags[index]!=0; index++)
|
||||
/* nothing */;
|
||||
/* if still not found, quit with error */
|
||||
if (index>=AMX_USERNUM)
|
||||
return AMX_ERR_INDEX;
|
||||
/* set the tag and the value */
|
||||
amx->usertags[index]=tag;
|
||||
amx->userdata[index]=ptr;
|
||||
return AMX_ERR_NONE;
|
||||
}
|
||||
#endif /* AMX_XXXUSERDATA */
|
||||
@ -1595,6 +1480,36 @@ int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f)
|
||||
return err;
|
||||
}
|
||||
|
||||
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
||||
{
|
||||
AMX_FUNCSTUB *func;
|
||||
AMX_HEADER *hdr;
|
||||
int i,numnatives,count=0;
|
||||
AMX_NATIVE funcptr;
|
||||
|
||||
hdr=(AMX_HEADER *)amx->base;
|
||||
assert(hdr!=NULL);
|
||||
assert(hdr->magic==AMX_MAGIC);
|
||||
assert(hdr->natives<=hdr->libraries);
|
||||
numnatives=NUMENTRIES(hdr,natives,libraries);
|
||||
|
||||
count=0;
|
||||
func=GETENTRY(hdr,natives,0);
|
||||
for (i=0; i<numnatives; i++) {
|
||||
if (func->address!=0) {
|
||||
/* this function is located */
|
||||
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
|
||||
if (funcptr!=NULL)
|
||||
{
|
||||
func->address=(ucell)funcptr;
|
||||
count++;
|
||||
}
|
||||
} /* if */
|
||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
||||
} /* for */
|
||||
return count;
|
||||
}
|
||||
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
||||
{
|
||||
AMX_FUNCSTUB *func;
|
||||
@ -1615,12 +1530,12 @@ int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *list, int number)
|
||||
/* this function is not yet located */
|
||||
funcptr=(list!=NULL) ? findfunction(GETENTRYNAME(hdr,func),list,number) : NULL;
|
||||
if (funcptr!=NULL)
|
||||
{
|
||||
{
|
||||
func->address=(ucell)funcptr;
|
||||
} else {
|
||||
no_function = GETENTRYNAME(hdr,func);
|
||||
err=AMX_ERR_NOTFOUND;
|
||||
}
|
||||
}
|
||||
} /* if */
|
||||
func=(AMX_FUNCSTUB*)((unsigned char*)func+hdr->defsize);
|
||||
} /* for */
|
||||
@ -1764,13 +1679,16 @@ static const void * const amx_opcodelist[] = {
|
||||
&&op_file, &&op_line, &&op_symbol, &&op_srange,
|
||||
&&op_jump_pri, &&op_switch, &&op_casetbl, &&op_swap_pri,
|
||||
&&op_swap_alt, &&op_pushaddr, &&op_nop, &&op_sysreq_d,
|
||||
&&op_symtag, &&op_break };
|
||||
&&op_symtag, &&op_break, &&op_float_mul, &&op_float_div,
|
||||
&&op_float_add, &&op_float_sub, &&op_float_to, &&op_float_round,
|
||||
&&op_float_cmp};
|
||||
AMX_HEADER *hdr;
|
||||
AMX_FUNCSTUB *func;
|
||||
unsigned char *code, *data;
|
||||
cell pri,alt,stk,frm,hea;
|
||||
cell reset_stk, reset_hea, *cip;
|
||||
cell offs;
|
||||
cell offs, offs2;
|
||||
REAL fnum, fnum2;
|
||||
ucell codesize;
|
||||
int num,i;
|
||||
|
||||
@ -2616,7 +2534,60 @@ static const void * const amx_opcodelist[] = {
|
||||
NEXT(cip);
|
||||
op_nop:
|
||||
NEXT(cip);
|
||||
op_break:
|
||||
op_float_mul:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) * amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
NEXT(cip);
|
||||
op_float_add:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) + amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
NEXT(cip);
|
||||
op_float_sub:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) - amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
NEXT(cip);
|
||||
op_float_div:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) / amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
NEXT(cip);
|
||||
op_float_to:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
fnum = (REAL)offs;
|
||||
pri = amx_ftoc(fnum);
|
||||
NEXT(cip);
|
||||
op_float_round:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs);
|
||||
if (!offs2)
|
||||
fnum = floor(fnum + 0.5);
|
||||
else if (offs2 == 1)
|
||||
fnum = floor(fnum);
|
||||
else
|
||||
fnum = ceil(fnum);
|
||||
pri = (cell)fnum;
|
||||
NEXT(cip);
|
||||
op_float_cmp:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs);
|
||||
fnum2 = amx_ctof(offs2);
|
||||
if (fnum == fnum2)
|
||||
pri = 0;
|
||||
else if (fnum > fnum2)
|
||||
pri = 1;
|
||||
else
|
||||
pri = -1;
|
||||
NEXT(cip);
|
||||
op_break:
|
||||
if (amx->debug!=NULL) {
|
||||
/* store status */
|
||||
amx->frm=frm;
|
||||
@ -2700,7 +2671,8 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
cell parms[9]; /* registers and parameters for assembler AMX */
|
||||
#else
|
||||
OPCODE op;
|
||||
cell offs;
|
||||
cell offs, offs2;
|
||||
REAL fnum, fnum2;
|
||||
int num;
|
||||
#endif
|
||||
assert(amx!=NULL);
|
||||
@ -3591,6 +3563,59 @@ int AMXAPI amx_Exec(AMX *amx, cell *retval, int index)
|
||||
break;
|
||||
case OP_NOP:
|
||||
break;
|
||||
case OP_FLOAT_MUL:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) * amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
break;
|
||||
case OP_FLOAT_ADD:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) + amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
break;
|
||||
case OP_FLOAT_SUB:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) - amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
break;
|
||||
case OP_FLOAT_DIV:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs) / amx_ctof(offs2);
|
||||
pri = amx_ftoc(fnum);
|
||||
break;
|
||||
case OP_FLOAT_TO:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
fnum = (float)offs;
|
||||
pri = amx_ftoc(fnum);
|
||||
break;
|
||||
case OP_FLOAT_ROUND:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs);
|
||||
if (!offs2)
|
||||
fnum = (REAL)floor(fnum + 0.5);
|
||||
else if (offs2 == 1)
|
||||
fnum = floor(fnum);
|
||||
else
|
||||
fnum = ceil(fnum);
|
||||
pri = (cell)fnum;
|
||||
break;
|
||||
case OP_FLOAT_CMP:
|
||||
offs = *(cell *)(data + (int)stk + sizeof(cell)*1);
|
||||
offs2 = *(cell *)(data + (int)stk + sizeof(cell)*2);
|
||||
fnum = amx_ctof(offs);
|
||||
fnum2 = amx_ctof(offs2);
|
||||
if (fnum == fnum2)
|
||||
pri = 0;
|
||||
else if (fnum > fnum2)
|
||||
pri = 1;
|
||||
else
|
||||
pri = -1;
|
||||
break;
|
||||
case OP_BREAK:
|
||||
assert((amx->flags & AMX_FLAG_BROWSE)==0);
|
||||
if (amx->debug!=NULL) {
|
||||
@ -3670,7 +3695,7 @@ int AMXAPI amx_GetAddr(AMX *amx,cell amx_addr,cell **phys_addr)
|
||||
data=(amx->data!=NULL) ? amx->data : amx->base+(int)hdr->dat;
|
||||
|
||||
assert(phys_addr!=NULL);
|
||||
if (amx_addr>=amx->hea && amx_addr<amx->stk || amx_addr<0 || amx_addr>=amx->stp) {
|
||||
if ((amx_addr>=amx->hea && amx_addr<amx->stk) || amx_addr<0 || amx_addr>=amx->stp) {
|
||||
*phys_addr=NULL;
|
||||
return AMX_ERR_MEMACCESS;
|
||||
} /* if */
|
||||
@ -4069,7 +4094,7 @@ int AMXAPI amx_GetLibraries(AMX *amx)
|
||||
return numLibraries;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
|
||||
|
@ -18,13 +18,13 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amx.h 3006 2006-08-28 11:08:18Z dvander $
|
||||
*/
|
||||
|
||||
#if defined FREEBSD && !defined __FreeBSD__
|
||||
#define __FreeBSD__
|
||||
#endif
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __OpenBSD__ || defined __APPLE__
|
||||
#include <sclinux.h>
|
||||
#endif
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX || defined __APPLE__
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
@ -79,15 +79,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
#if defined __WIN32__ || defined _WIN32 || defined WIN32 /* || defined __MSDOS__ */
|
||||
#if !defined alloca
|
||||
#define alloca(n) _alloca(n)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined arraysize
|
||||
#define arraysize(array) (sizeof(array) / sizeof((array)[0]))
|
||||
#endif
|
||||
@ -175,6 +166,14 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
||||
#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
|
||||
@ -191,7 +190,7 @@ typedef int (AMXAPI *AMX_NATIVE_FILTER)(struct tagAMX *amx, int index);
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __APPLE__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
@ -215,7 +214,7 @@ typedef struct tagAMX_NATIVE_INFO {
|
||||
|
||||
typedef struct tagAMX_FUNCSTUB {
|
||||
ucell address PACKED;
|
||||
char name[sEXPMAX+1] PACKED;
|
||||
char name[sEXPMAX+1];
|
||||
} PACKED AMX_FUNCSTUB;
|
||||
|
||||
typedef struct tagFUNCSTUBNT {
|
||||
@ -240,7 +239,7 @@ typedef struct tagAMX {
|
||||
cell stp PACKED; /* top of the stack: relative to base + amxhdr->dat */
|
||||
int flags PACKED; /* current status, see amx_Flags() */
|
||||
/* user data */
|
||||
long usertags[AMX_USERNUM] PACKED;
|
||||
void _FAR *usertags[AMX_USERNUM] PACKED;
|
||||
//okay userdata[3] in AMX Mod X is for the CPlugin * pointer
|
||||
//we're also gonna set userdata[2] to a special debug structure
|
||||
//lastly, userdata[1] is for opcode_list from amx_BrowseRelocate
|
||||
@ -266,8 +265,8 @@ typedef struct tagAMX {
|
||||
typedef struct tagAMX_HEADER {
|
||||
int32_t size PACKED; /* size of the "file" */
|
||||
uint16_t magic PACKED; /* signature */
|
||||
char file_version PACKED; /* file format version */
|
||||
char amx_version PACKED; /* required version of the AMX */
|
||||
char file_version; /* file format version */
|
||||
char amx_version; /* required version of the AMX */
|
||||
int16_t flags PACKED;
|
||||
int16_t defsize PACKED; /* size of a definition record */
|
||||
int32_t cod PACKED; /* initial value of COD - code block */
|
||||
@ -323,6 +322,7 @@ enum {
|
||||
#define AMX_FLAG_COMPACT 0x04 /* compact encoding */
|
||||
#define AMX_FLAG_BYTEOPC 0x08 /* opcode is a byte (not a cell) */
|
||||
#define AMX_FLAG_NOCHECKS 0x10 /* no array bounds checking; no STMT opcode */
|
||||
#define AMX_FLAG_OLDFILE 0x20 /* Old AMX Mod plugin */
|
||||
#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 */
|
||||
@ -343,6 +343,11 @@ enum {
|
||||
#define UD_OPCODELIST 1
|
||||
#define UD_HANDLER 0
|
||||
#define UT_NATIVE 3
|
||||
#define UT_OPTIMIZER 2
|
||||
#define UT_BROWSEHOOK 1
|
||||
#define UT_BINLOGS 0
|
||||
|
||||
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
|
||||
|
||||
/* for native functions that use floating point parameters, the following
|
||||
* two macros are convenient for casting a "cell" into a "float" type _without_
|
||||
@ -406,6 +411,7 @@ int AMXAPI amx_PushArray(AMX *amx, cell *amx_addr, cell **phys_addr, const cell
|
||||
int AMXAPI amx_PushString(AMX *amx, cell *amx_addr, cell **phys_addr, const char *string, int pack, int use_wchar);
|
||||
int AMXAPI amx_RaiseError(AMX *amx, int error);
|
||||
int AMXAPI amx_Register(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_Reregister(AMX *amx, const AMX_NATIVE_INFO *nativelist, int number);
|
||||
int AMXAPI amx_RegisterToAny(AMX *amx, AMX_NATIVE f);
|
||||
int AMXAPI amx_Release(AMX *amx, cell amx_addr);
|
||||
int AMXAPI amx_SetCallback(AMX *amx, AMX_CALLBACK callback);
|
||||
@ -436,7 +442,7 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
||||
amx_Register((amx), amx_NativeInfo((name),(func)), 1);
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __APPLE__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
@ -445,6 +451,15 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
typedef struct tagBINLOG
|
||||
{
|
||||
void (*pfnLogNative)(AMX *amx, int native, int params);
|
||||
void (*pfnLogReturn)(AMX *amx, cell retval);
|
||||
void (*pfnLogParams)(AMX *amx, cell *params);
|
||||
} binlogfuncs_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -18,7 +18,7 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amxcore.cpp 1733 2005-07-25 06:03:43Z dvander $
|
||||
*/
|
||||
#if defined _UNICODE || defined __UNICODE__ || defined UNICODE
|
||||
# if !defined UNICODE /* for Windows */
|
||||
@ -180,7 +180,7 @@ static cell AMX_NATIVE_CALL setarg(AMX *amx, cell *params)
|
||||
/* adjust the address in "value" in case of an array access */
|
||||
value+=params[2]*sizeof(cell);
|
||||
/* verify the address */
|
||||
if (value<0 || value>=amx->hea && value<amx->stk)
|
||||
if (value<0 || (value>=amx->hea && value<amx->stk))
|
||||
return 0;
|
||||
/* set the value indirectly */
|
||||
* (cell *)(data+(int)value) = params[3];
|
||||
|
@ -20,7 +20,7 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amxdbg.cpp 2345 2006-02-10 19:47:09Z faluco $
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
@ -462,8 +462,8 @@ int AMXAPI dbg_GetVariable(AMX_DBG *amxdbg, const char *symname, ucell scopeaddr
|
||||
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))
|
||||
&& ((codestart == 0 && codeend == 0)
|
||||
|| (amxdbg->symboltbl[index]->codestart >= codestart && amxdbg->symboltbl[index]->codeend <= codeend)))
|
||||
{
|
||||
*sym = amxdbg->symboltbl[index];
|
||||
codestart = amxdbg->symboltbl[index]->codestart;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amxdbg.h 2977 2006-08-27 02:17:18Z damagedsoul $
|
||||
*/
|
||||
|
||||
#ifndef AMXDBG_H_INCLUDED
|
||||
@ -49,7 +49,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __APPLE__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
@ -65,8 +65,8 @@ extern "C" {
|
||||
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 */
|
||||
char file_version; /* file format version */
|
||||
char amx_version; /* 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 */
|
||||
@ -74,51 +74,51 @@ typedef struct tagAMX_DBG_HDR {
|
||||
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;
|
||||
} PACKED AMX_DBG_HDR;
|
||||
#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;
|
||||
const char name[1]; /* ASCII string, zero-terminated */
|
||||
} PACKED AMX_DBG_FILE;
|
||||
|
||||
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;
|
||||
} PACKED AMX_DBG_LINE;
|
||||
|
||||
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) */
|
||||
char ident; /* kind of symbol (function/variable) */
|
||||
char vclass; /* 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;
|
||||
const char name[1]; /* ASCII string, zero-terminated */
|
||||
} PACKED AMX_DBG_SYMBOL;
|
||||
|
||||
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;
|
||||
} PACKED AMX_DBG_SYMDIM;
|
||||
|
||||
typedef struct tagAMX_DBG_TAG {
|
||||
int16_t tag PACKED; /* tag id */
|
||||
const char name[1] PACKED; /* ASCII string, zero-terminated */
|
||||
} AMX_DBG_TAG PACKED;
|
||||
const char name[1]; /* ASCII string, zero-terminated */
|
||||
} PACKED AMX_DBG_TAG;
|
||||
|
||||
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;
|
||||
const char name[1]; /* ASCII string, zero-terminated */
|
||||
} PACKED AMX_DBG_MACHINE;
|
||||
|
||||
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;
|
||||
const char name[1]; /* ASCII string, zero-terminated */
|
||||
} PACKED AMX_DBG_STATE;
|
||||
|
||||
typedef struct tagAMX_DBG {
|
||||
AMX_DBG_HDR _FAR *hdr PACKED; /* points to the AMX_DBG header */
|
||||
@ -128,7 +128,7 @@ typedef struct tagAMX_DBG {
|
||||
AMX_DBG_TAG _FAR **tagtbl PACKED;
|
||||
AMX_DBG_MACHINE _FAR **automatontbl PACKED;
|
||||
AMX_DBG_STATE _FAR **statetbl PACKED;
|
||||
} AMX_DBG PACKED;
|
||||
} PACKED AMX_DBG;
|
||||
|
||||
#if !defined iVARIABLE
|
||||
#define iVARIABLE 1 /* cell that has an address and that can be fetched directly (lvalue) */
|
||||
@ -156,7 +156,7 @@ int AMXAPI dbg_GetArrayDim(AMX_DBG *amxdbg, const AMX_DBG_SYMBOL *sym, const AMX
|
||||
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __APPLE__
|
||||
#pragma pack() /* reset default packing */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=reset
|
||||
|
@ -56,6 +56,8 @@
|
||||
;
|
||||
;History (list of changes)
|
||||
;-------------------------
|
||||
; 10 february 2006 by David Anderson
|
||||
; Addition of float opcodes
|
||||
; 17 february 2005 by Thiadmer Riemersms
|
||||
; Addition of the BREAK opcode, removal of the older debugging opcode table.
|
||||
; 6 march 2004 by Thiadmer Riemersma
|
||||
@ -1406,6 +1408,108 @@ OP_NOP:
|
||||
add esi,4
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_MUL:
|
||||
add esi,4
|
||||
fld dword [edi+ecx+4]
|
||||
fmul dword [edi+ecx+8]
|
||||
sub esp,4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_DIV:
|
||||
add esi,4
|
||||
fld dword [edi+ecx+4]
|
||||
fdiv dword [edi+ecx+8]
|
||||
sub esp,4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_ADD:
|
||||
add esi,4
|
||||
fld dword [edi+ecx+4]
|
||||
fadd dword [edi+ecx+8]
|
||||
sub esp,4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_SUB:
|
||||
add esi,4
|
||||
fld dword [edi+ecx+4]
|
||||
fsub dword [edi+ecx+8]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_TO:
|
||||
add esi,4
|
||||
fild dword [edi+ecx+4]
|
||||
sub esp,4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_ROUND:
|
||||
add esi,4
|
||||
;get the float control word
|
||||
push 0
|
||||
mov ebp,esp
|
||||
fstcw [ebp]
|
||||
mov eax,[ebp]
|
||||
push eax
|
||||
;clear the top bits
|
||||
xor ah,ah
|
||||
;get the control method
|
||||
push edx
|
||||
mov edx,[edi+ecx+8]
|
||||
and edx,3 ;sanity check
|
||||
shl edx,2 ;shift it to right position
|
||||
;set the bits
|
||||
or ah,dl ;set bits 15,14 of FCW to rounding method
|
||||
or ah,3 ;set precision to 64bit
|
||||
mov [ebp], eax
|
||||
fldcw [ebp]
|
||||
;calculate
|
||||
sub esp,4
|
||||
fld dword [edi+ecx+4]
|
||||
test edx,edx
|
||||
jz .correct
|
||||
jmp .skip_correct
|
||||
.correct:
|
||||
fadd st0
|
||||
fadd dword [g_round_nearest]
|
||||
fistp dword [esp]
|
||||
pop eax
|
||||
sar eax,1
|
||||
jmp .done
|
||||
.skip_correct:
|
||||
frndint
|
||||
fistp dword [esp]
|
||||
pop eax
|
||||
.done:
|
||||
pop edx
|
||||
;restore bits
|
||||
pop ebp
|
||||
mov [esp], ebp
|
||||
fldcw [esp]
|
||||
pop ebp
|
||||
GO_ON
|
||||
|
||||
OP_FLOAT_CMP:
|
||||
add esi, 4
|
||||
fld dword [edi+ecx+8]
|
||||
fld dword [edi+ecx+4]
|
||||
fucompp
|
||||
fnstsw ax
|
||||
fwait
|
||||
sahf
|
||||
cmovz eax, [g_flags+4]
|
||||
cmova eax, [g_flags+8]
|
||||
cmovb eax, [g_flags+0]
|
||||
GO_ON
|
||||
|
||||
OP_BREAK:
|
||||
mov ebp,amx ; get amx into ebp
|
||||
@ -1501,6 +1605,14 @@ Start_DATA
|
||||
|
||||
lodb_and DD 0ffh, 0ffffh, 0, 0ffffffffh
|
||||
|
||||
g_round_nearest DD 0.5
|
||||
|
||||
GLOBAL g_flags
|
||||
g_flags:
|
||||
DD -1
|
||||
DD 0
|
||||
DD 1
|
||||
|
||||
GLOBAL amx_opcodelist
|
||||
GLOBAL _amx_opcodelist
|
||||
amx_opcodelist:
|
||||
@ -1642,4 +1754,10 @@ _amx_opcodelist DD OP_INVALID
|
||||
DD OP_SYSREQ_D
|
||||
DD OP_SYMTAG
|
||||
DD OP_BREAK
|
||||
|
||||
DD OP_FLOAT_MUL
|
||||
DD OP_FLOAT_DIV
|
||||
DD OP_FLOAT_ADD
|
||||
DD OP_FLOAT_SUB
|
||||
DD OP_FLOAT_TO
|
||||
DD OP_FLOAT_ROUND
|
||||
DD OP_FLOAT_CMP
|
||||
|
@ -303,10 +303,6 @@
|
||||
%endif
|
||||
%endmacro
|
||||
|
||||
|
||||
section .text
|
||||
|
||||
|
||||
global asm_runJIT, _asm_runJIT
|
||||
global amx_exec_jit, _amx_exec_jit
|
||||
global getMaxCodeSize, _getMaxCodeSize
|
||||
@ -432,13 +428,6 @@ reloc_done:
|
||||
pop ebp
|
||||
ret
|
||||
|
||||
; GWMV:
|
||||
; The code below modifies itself to store the arguments to the Pawn opcodes
|
||||
; in the compiled code. This is fine, but the .text section in an ELF executable
|
||||
; is usually marked read-only, that's why this code is in the .data section.
|
||||
|
||||
section .data exec
|
||||
|
||||
OP_LOAD_PRI:
|
||||
;nop;
|
||||
putval j_load_pri+2
|
||||
@ -1046,7 +1035,7 @@ OP_CALL:
|
||||
j_call:
|
||||
;call 12345678h ; tasm chokes on this out of a sudden
|
||||
_PUSH 0
|
||||
j_call_e8
|
||||
j_call_e8:
|
||||
db 0e8h, 0, 0, 0, 0
|
||||
CHECKCODESIZE j_call
|
||||
|
||||
@ -1876,7 +1865,7 @@ OP_BREAK:
|
||||
jae code_gen_done
|
||||
jmp DWORD [ebx] ; go on with the next opcode
|
||||
%else
|
||||
GO_ON j_break, OP_INVALID
|
||||
GO_ON j_break, OP_FLOAT_MUL
|
||||
j_break:
|
||||
mov ebp,amx
|
||||
cmp DWORD [ebp+_debug], 0
|
||||
@ -1885,6 +1874,116 @@ OP_BREAK:
|
||||
CHECKCODESIZE j_break
|
||||
%endif
|
||||
|
||||
OP_FLOAT_MUL:
|
||||
GO_ON j_float_mul, OP_FLOAT_DIV
|
||||
j_float_mul:
|
||||
fld dword [esi+4]
|
||||
fmul dword [esi+8]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
CHECKCODESIZE j_float_mul
|
||||
|
||||
OP_FLOAT_DIV:
|
||||
GO_ON j_float_div, OP_FLOAT_ADD
|
||||
j_float_div:
|
||||
fld dword [esi+4]
|
||||
fdiv dword [esi+8]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
CHECKCODESIZE j_float_div
|
||||
|
||||
OP_FLOAT_ADD:
|
||||
GO_ON j_float_add, OP_FLOAT_SUB
|
||||
j_float_add:
|
||||
fld dword [esi+4]
|
||||
fadd dword [esi+8]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
CHECKCODESIZE j_float_add
|
||||
|
||||
OP_FLOAT_SUB:
|
||||
GO_ON j_float_sub, OP_FLOAT_TO
|
||||
j_float_sub:
|
||||
fld dword [esi+4]
|
||||
fsub dword [esi+8]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
CHECKCODESIZE j_float_sub
|
||||
|
||||
OP_FLOAT_TO:
|
||||
GO_ON j_float_to, OP_FLOAT_ROUND
|
||||
j_float_to:
|
||||
fild dword [esi+4]
|
||||
sub esp, 4
|
||||
fstp dword [esp]
|
||||
pop eax
|
||||
CHECKCODESIZE j_float_to
|
||||
|
||||
OP_FLOAT_ROUND:
|
||||
GO_ON j_float_round, OP_FLOAT_CMP
|
||||
j_float_round:
|
||||
;get the float control word
|
||||
push 0
|
||||
mov ebp,esp
|
||||
fstcw [ebp]
|
||||
mov eax,[ebp]
|
||||
push eax
|
||||
;clear the top bits
|
||||
xor ah,ah
|
||||
;get the control method
|
||||
push edx
|
||||
mov edx,[esi+8]
|
||||
and edx,3 ;sanity check
|
||||
shl edx,2 ;shift it to right position
|
||||
;set the bits
|
||||
or ah,dl ;set bits 15,14 of FCW to rounding method
|
||||
or ah,3 ;set precision to 64bit
|
||||
mov [ebp], eax
|
||||
fldcw [ebp]
|
||||
;calculate
|
||||
sub esp,4
|
||||
fld dword [esi+4]
|
||||
test edx,edx
|
||||
jz .correct
|
||||
jmp .skip_correct
|
||||
.correct:
|
||||
fadd st0
|
||||
fadd dword [g_round_nearest]
|
||||
fistp dword [esp]
|
||||
pop eax
|
||||
sar eax,1
|
||||
jmp .done
|
||||
.skip_correct:
|
||||
frndint
|
||||
fistp dword [esp]
|
||||
pop eax
|
||||
.done:
|
||||
pop edx
|
||||
;restore bits
|
||||
pop ebp
|
||||
mov [esp], ebp
|
||||
fldcw [esp]
|
||||
pop ebp
|
||||
CHECKCODESIZE j_float_round
|
||||
|
||||
OP_FLOAT_CMP:
|
||||
GO_ON j_float_cmp, OP_INVALID
|
||||
j_float_cmp:
|
||||
fld dword [esi+8]
|
||||
fld dword [esi+4]
|
||||
fucompp
|
||||
fnstsw ax
|
||||
fwait
|
||||
sahf
|
||||
cmovz eax, [g_flagsjit+4]
|
||||
cmova eax, [g_flagsjit+8]
|
||||
cmovb eax, [g_flagsjit+0]
|
||||
CHECKCODESIZE j_float_cmp
|
||||
|
||||
OP_INVALID: ; break from the compiler with an error code
|
||||
mov eax,AMX_ERR_INVINSTR
|
||||
pop esi
|
||||
@ -2006,7 +2105,9 @@ err_heaplow:
|
||||
_CHKMARGIN_HEAP:
|
||||
cmp esi,stp
|
||||
jg err_stacklow
|
||||
cmp dword hea,0
|
||||
mov ebp,amx
|
||||
mov ebp,[ebp+_hlw]
|
||||
cmp dword hea,ebp
|
||||
jl err_heaplow
|
||||
ret
|
||||
|
||||
@ -2137,8 +2238,8 @@ err_divide:
|
||||
jmp _return_popstack
|
||||
|
||||
JIT_OP_SYSREQ:
|
||||
push ecx
|
||||
push esi
|
||||
push ecx
|
||||
push esi
|
||||
mov ebp,amx ; get amx into EBP
|
||||
|
||||
sub esi,edi ; correct STK
|
||||
@ -2172,8 +2273,8 @@ JIT_OP_SYSREQ:
|
||||
|
||||
|
||||
JIT_OP_SYSREQ_D: ; (TR)
|
||||
push ecx
|
||||
push esi
|
||||
push ecx
|
||||
push esi
|
||||
mov ebp,amx ; get amx into EBP
|
||||
|
||||
sub esi,edi ; correct STK
|
||||
@ -2204,8 +2305,8 @@ JIT_OP_SYSREQ_D: ; (TR)
|
||||
|
||||
JIT_OP_BREAK:
|
||||
%ifdef DEBUGSUPPORT
|
||||
push ecx
|
||||
push esi
|
||||
push ecx
|
||||
push esi
|
||||
mov ebp,amx ; get amx into EBP
|
||||
|
||||
sub esi,edi ; correct STK
|
||||
@ -2313,6 +2414,16 @@ jit_switch DD JIT_OP_SWITCH
|
||||
; The table for the browser/relocator function.
|
||||
;
|
||||
|
||||
global g_flagsjit
|
||||
g_flagsjit:
|
||||
DD -1
|
||||
DD 0
|
||||
DD 1
|
||||
|
||||
global g_round_nearest
|
||||
g_round_nearest:
|
||||
DD 0.5
|
||||
|
||||
global amx_opcodelist_jit, _amx_opcodelist_jit
|
||||
|
||||
amx_opcodelist_jit:
|
||||
@ -2455,5 +2566,12 @@ _amx_opcodelist_jit:
|
||||
DD OP_SYSREQ_D ; TR
|
||||
DD OP_SYMTAG ; TR
|
||||
DD OP_BREAK ; TR
|
||||
DD OP_FLOAT_MUL ; DA
|
||||
DD OP_FLOAT_DIV ; DA
|
||||
DD OP_FLOAT_ADD ; DA
|
||||
DD OP_FLOAT_SUB ; DA
|
||||
DD OP_FLOAT_TO ; DA
|
||||
DD OP_FLOAT_ROUND ; DA
|
||||
DD OP_FLOAT_CMP ; DA
|
||||
|
||||
END
|
||||
END:
|
||||
|
117
amxmodx/amxmod_compat.cpp
Normal file
117
amxmodx/amxmod_compat.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "amxmodx.h"
|
||||
#include "amxmod_compat.h"
|
||||
#include "format.h"
|
||||
|
||||
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang)
|
||||
{
|
||||
key = (trans & BCOMPAT_TRANSLATE_KEYMASK);
|
||||
dest = (trans >> BCOMPAT_TRANSLATE_DESTRSH) & BCOMPAT_TRANSLATE_DESTMASK;
|
||||
lang = (trans >> BCOMPAT_TRANSLATE_LANGRSH) & BCOMPAT_TRANSLATE_LANGMASK;
|
||||
|
||||
if (dest == 0x3F)
|
||||
{
|
||||
dest = -1;
|
||||
}
|
||||
|
||||
if (lang == 0x1F)
|
||||
{
|
||||
lang = -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def)
|
||||
{
|
||||
amxtrans_t trans = static_cast<amxtrans_t>(*source);
|
||||
int key, _dest, lang;
|
||||
if (!GetTranslation(trans, key, _dest, lang))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cell amx_addr, *phys_addr;
|
||||
if (amx_Allot(amx, 3, &amx_addr, &phys_addr) != AMX_ERR_NONE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_dest == -1)
|
||||
{
|
||||
*phys_addr = LANG_PLAYER;
|
||||
} else if (_dest == 0) {
|
||||
*phys_addr = LANG_SERVER;
|
||||
} else if (lang >= 0 && lang < g_langMngr.GetLangsNum()) {
|
||||
const char *name = g_langMngr.GetLangName(lang);
|
||||
phys_addr[0] = static_cast<cell>(name[0]);
|
||||
phys_addr[1] = static_cast<cell>(name[1]);
|
||||
phys_addr[2] = static_cast<cell>('\0');
|
||||
} else {
|
||||
*phys_addr = LANG_SERVER;
|
||||
}
|
||||
|
||||
//not optimized but it works, eh
|
||||
//if someone cares they can make a translate() wrapper that takes the key # in directly
|
||||
const char *r_key = g_langMngr.GetKey(key);
|
||||
const char *def = translate(amx, amx_addr, r_key);
|
||||
if (!def)
|
||||
{
|
||||
def = r_key;
|
||||
}
|
||||
amx_Release(amx, amx_addr);
|
||||
|
||||
*_key = g_langMngr.GetKey(key);
|
||||
*_def = def;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_translate(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *key = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
amxtrans_t trans;
|
||||
|
||||
int suki = g_langMngr.GetKeyEntry(key);
|
||||
//Some AMX Mod plugins do not register everything they need. Prevent a crash.
|
||||
if (suki == -1)
|
||||
{
|
||||
suki = g_langMngr.AddKeyEntry(key);
|
||||
}
|
||||
|
||||
if (suki > BCOMPAT_TRANSLATE_KEYMASK)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not enough translation space, aborting!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
trans = suki & BCOMPAT_TRANSLATE_KEYMASK;
|
||||
int dest = static_cast<int>(params[2]);
|
||||
int lang = static_cast<int>(params[3]);
|
||||
if (dest == -1)
|
||||
{
|
||||
trans |= (0x3F << BCOMPAT_TRANSLATE_DESTRSH);
|
||||
} else {
|
||||
trans |= (dest & BCOMPAT_TRANSLATE_DESTMASK) << BCOMPAT_TRANSLATE_DESTRSH;
|
||||
}
|
||||
|
||||
if (lang == -1)
|
||||
{
|
||||
trans |= (0x1F << BCOMPAT_TRANSLATE_LANGRSH);
|
||||
} else {
|
||||
trans |= (lang & BCOMPAT_TRANSLATE_LANGMASK) << BCOMPAT_TRANSLATE_LANGRSH;
|
||||
}
|
||||
|
||||
trans |= BCOMPAT_TRANSLATE_BITS;
|
||||
|
||||
return static_cast<cell>(trans);
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO g_BcompatNatives[] =
|
||||
{
|
||||
{"translate", amx_translate},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
28
amxmodx/amxmod_compat.h
Normal file
28
amxmodx/amxmod_compat.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _INCLUDE_AMXMOD_CORE_COMPAT_H
|
||||
#define _INCLUDE_AMXMOD_CORE_COMPAT_H
|
||||
|
||||
/**
|
||||
* New format for translation:
|
||||
* Note that we only support:
|
||||
* 4k keys
|
||||
* 32 languages
|
||||
* 0000 0000 0000 0000 0000 0000 0000 0000
|
||||
* | key id |
|
||||
* | | <- dest id
|
||||
* | | <- lang id
|
||||
*/
|
||||
|
||||
#define BCOMPAT_TRANSLATE_BITS 0xFF000000
|
||||
#define BCOMPAT_TRANSLATE_KEYMASK 0xFFF
|
||||
#define BCOMPAT_TRANSLATE_DESTMASK 0x3F
|
||||
#define BCOMPAT_TRANSLATE_DESTRSH 12
|
||||
#define BCOMPAT_TRANSLATE_LANGMASK 0x1F
|
||||
#define BCOMPAT_TRANSLATE_LANGRSH 18
|
||||
|
||||
typedef unsigned int amxtrans_t;
|
||||
|
||||
bool GetTranslation(amxtrans_t trans, int &key, int &dest, int &lang);
|
||||
|
||||
extern AMX_NATIVE_INFO g_BcompatNatives[];
|
||||
|
||||
#endif //_INCLUDE_AMXMOD_CORE_COMPAT_H
|
1758
amxmodx/amxmodx.cpp
1758
amxmodx/amxmodx.cpp
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,7 @@
|
||||
#ifndef AMXMODX_H
|
||||
#define AMXMODX_H
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "sclinux.h"
|
||||
@ -41,10 +41,14 @@
|
||||
#include "string.h"
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "mm_pextensions.h" // metamod-p extensions
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
#include "mmgr/mmgr.h"
|
||||
#ifdef _MSC_VER
|
||||
// MSVC8 - replace POSIX functions with ISO C++ conformant ones as they are deprecated
|
||||
#if _MSC_VER >= 1400
|
||||
#define unlink _unlink
|
||||
#define mkdir _mkdir
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "md5.h"
|
||||
@ -61,14 +65,13 @@
|
||||
#include "CLogEvent.h"
|
||||
#include "CForward.h"
|
||||
#include "CCmd.h"
|
||||
#include "CMenu.h"
|
||||
#include "CEvent.h"
|
||||
#include "CLang.h"
|
||||
#include "fakemeta.h"
|
||||
#include "amxxlog.h"
|
||||
|
||||
#define AMXXLOG_Log g_log.Log
|
||||
#define AMX_VERSION "1.60"
|
||||
#define AMXXLOG_Error g_log.LogError
|
||||
|
||||
extern AMX_NATIVE_INFO core_Natives[];
|
||||
extern AMX_NATIVE_INFO time_Natives[];
|
||||
@ -78,8 +81,12 @@ 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[];
|
||||
extern AMX_NATIVE_INFO g_SortNatives[];
|
||||
extern AMX_NATIVE_INFO g_DataStructNatives[];
|
||||
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32)
|
||||
#define DLLOAD(path) (DLHANDLE)LoadLibrary(path)
|
||||
#define DLPROC(m, func) GetProcAddress(m, func)
|
||||
#define DLFREE(m) FreeLibrary(m)
|
||||
@ -89,10 +96,30 @@ extern AMX_NATIVE_INFO vault_Natives[];
|
||||
#define DLFREE(m) dlclose(m)
|
||||
#endif
|
||||
|
||||
#ifndef __linux__
|
||||
#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
|
||||
|
||||
#if defined(_WIN32)
|
||||
typedef HINSTANCE DLHANDLE;
|
||||
#else
|
||||
typedef void* DLHANDLE;
|
||||
#define INFINITE 0xFFFFFFFF
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define PATH_SEP_CHAR '\\'
|
||||
#define ALT_SEP_CHAR '/'
|
||||
#else
|
||||
#define PATH_SEP_CHAR '/'
|
||||
#define ALT_SEP_CHAR '\\'
|
||||
#endif
|
||||
|
||||
#ifndef GETPLAYERAUTHID
|
||||
@ -112,7 +139,7 @@ int UTIL_ReadFlags(const char* c);
|
||||
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_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, char *pMessage);
|
||||
void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const 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);
|
||||
@ -139,8 +166,6 @@ struct fakecmd_t
|
||||
bool fake;
|
||||
};
|
||||
|
||||
extern bool g_IsNewMM;
|
||||
extern pextension_funcs_t *gpMetaPExtFuncs;
|
||||
extern CLog g_log;
|
||||
extern CPluginMngr g_plugins;
|
||||
extern CTaskMngr g_tasksMngr;
|
||||
@ -157,7 +182,6 @@ 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;
|
||||
@ -248,14 +272,17 @@ enum CountModulesMode
|
||||
|
||||
int countModules(CountModulesMode mode);
|
||||
void modules_callPluginsLoaded();
|
||||
void modules_callPluginsUnloaded();
|
||||
void modules_callPluginsUnloading();
|
||||
|
||||
cell* get_amxaddr(AMX *amx, cell amx_addr);
|
||||
char* build_pathname(char *fmt, ...);
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, char *fmt, ...);
|
||||
char* build_pathname(const char *fmt, ...);
|
||||
char* build_pathname_r(char *buffer, size_t maxlen, const 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);
|
||||
extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, int maxlen);
|
||||
|
||||
int amxstring_len(cell* cstr);
|
||||
int load_amxscript(AMX* amx, void** program, const char* path, char error[64], int debug);
|
||||
@ -265,14 +292,14 @@ 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(const char *fmt, ...);
|
||||
void report_error(int code, const 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);
|
||||
void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
extern "C" void LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
|
||||
enum ModuleCallReason
|
||||
{
|
||||
@ -305,11 +332,12 @@ extern int FF_PluginLog;
|
||||
extern int FF_PluginEnd;
|
||||
extern int FF_InconsistentFile;
|
||||
extern int FF_ClientAuthorized;
|
||||
extern int FF_ChangeLevel;
|
||||
extern bool g_coloredmenus;
|
||||
|
||||
#ifdef FAKEMETA
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
#endif
|
||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
||||
|
||||
#define MM_CVAR2_VERS 13
|
||||
|
||||
struct func_s
|
||||
{
|
||||
@ -317,4 +345,14 @@ struct func_s
|
||||
const char *desc;
|
||||
};
|
||||
|
||||
enum AdminProperty
|
||||
{
|
||||
Admin_Auth = 0,
|
||||
Admin_Password,
|
||||
Admin_Access,
|
||||
Admin_Flags
|
||||
};
|
||||
|
||||
extern enginefuncs_t *g_pEngTable;
|
||||
|
||||
#endif // AMXMODX_H
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) ITB CompuPhase, 2001-2002
|
||||
* This file may be freely used. No warranties of any kind.
|
||||
*
|
||||
* Version: $Id$
|
||||
* Version: $Id: amxtime.cpp 2511 2006-04-06 12:56:45Z damagedsoul $
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
@ -54,7 +54,7 @@ static cell AMX_NATIVE_CALL _time(AMX *amx, cell *params)
|
||||
/* the time() function returns the number of seconds since January 1 1970
|
||||
* in Universal Coordinated Time (the successor to Greenwich Mean Time)
|
||||
*/
|
||||
return sec1970;
|
||||
return (cell)sec1970;
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
|
@ -42,7 +42,7 @@
|
||||
#define PACKED
|
||||
#endif
|
||||
|
||||
#if defined __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#else
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
@ -53,7 +53,7 @@
|
||||
|
||||
struct TableEntry
|
||||
{
|
||||
mint8_t cellSize PACKED;
|
||||
mint8_t cellSize;
|
||||
mint32_t origSize PACKED; // contains AMX_HEADER->stp
|
||||
mint32_t offset PACKED;
|
||||
};
|
||||
@ -109,7 +109,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
{
|
||||
DATAREAD(&m_Bh.version, sizeof(int16_t), 1);
|
||||
|
||||
if (m_Bh.version != MAGIC_VERSION)
|
||||
if (m_Bh.version > MAGIC_VERSION)
|
||||
{
|
||||
m_Status = Err_OldFile;
|
||||
fclose(m_pFile);
|
||||
@ -127,7 +127,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
pe = &(m_Bh.plugins[(unsigned)i]);
|
||||
DATAREAD(&pe->cellsize, sizeof(mint8_t), 1);
|
||||
DATAREAD(&pe->disksize, sizeof(int32_t), 1);
|
||||
DATAREAD(&pe->imagesize, sizeof(int32_t), 1);
|
||||
@ -137,7 +137,7 @@ CAmxxReader::CAmxxReader(const char *filename, int cellsize)
|
||||
|
||||
for (mint8_t i = 0; i < m_Bh.numPlugins; i++)
|
||||
{
|
||||
pe = &(m_Bh.plugins[i]);
|
||||
pe = &(m_Bh.plugins[(unsigned)i]);
|
||||
|
||||
if (pe->cellsize == m_CellSize)
|
||||
{
|
||||
@ -300,7 +300,7 @@ size_t CAmxxReader::GetBufferSize()
|
||||
|
||||
#undef DATAREAD
|
||||
#define DATAREAD(addr, itemsize, itemcount) \
|
||||
if (fread(addr, itemsize, itemcount, m_pFile) != itemcount) \
|
||||
if (fread(addr, itemsize, itemcount, m_pFile) != static_cast<size_t>(itemcount)) \
|
||||
{ \
|
||||
if (feof(m_pFile)) \
|
||||
m_Status = Err_FileInvalid; \
|
||||
|
@ -92,6 +92,7 @@ public:
|
||||
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
|
||||
inline bool IsOldFile() const { return m_OldFile; }
|
||||
};
|
||||
|
||||
#endif // __AMXXFILE_H__
|
||||
|
@ -35,19 +35,23 @@
|
||||
// 3 = HL Logs
|
||||
|
||||
#include <time.h>
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32)
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include "amxmodx.h"
|
||||
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32WIN32)
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
|
||||
#include "svn_version.h"
|
||||
|
||||
CLog::CLog()
|
||||
{
|
||||
m_LogType = 0;
|
||||
m_LogFile.clear();
|
||||
m_FoundError = false;
|
||||
m_LoggedErrMap = false;
|
||||
}
|
||||
|
||||
CLog::~CLog()
|
||||
@ -92,11 +96,15 @@ void CLog::CreateNewFile()
|
||||
time(&td);
|
||||
tm *curTime = localtime(&td);
|
||||
|
||||
char file[256];
|
||||
char name[256];
|
||||
int i = 0;
|
||||
|
||||
while (true)
|
||||
{
|
||||
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists
|
||||
snprintf(name, sizeof(name), "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
|
||||
build_pathname_r(file, sizeof(file)-1, "%s", name);
|
||||
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
|
||||
|
||||
if (!pTmpFile)
|
||||
break;
|
||||
@ -104,6 +112,7 @@ void CLog::CreateNewFile()
|
||||
fclose(pTmpFile);
|
||||
++i;
|
||||
}
|
||||
m_LogFile.assign(file);
|
||||
|
||||
// Log logfile start
|
||||
FILE *fp = fopen(m_LogFile.c_str(), "w");
|
||||
@ -113,7 +122,7 @@ void CLog::CreateNewFile()
|
||||
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);
|
||||
fprintf(fp, "AMX Mod X log file started (file \"%s\") (version \"%s\")\n", name, SVN_VERSION_STRING);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
@ -128,7 +137,7 @@ void CLog::MapChange()
|
||||
{
|
||||
// create dir if not existing
|
||||
char file[256];
|
||||
#ifdef __linux
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
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()));
|
||||
@ -143,17 +152,17 @@ void CLog::MapChange()
|
||||
print_srvconsole("[AMXX] Invalid amxx_logging value; setting back to 1...");
|
||||
}
|
||||
|
||||
m_LoggedErrMap = false;
|
||||
|
||||
if (m_LogType == 2)
|
||||
{
|
||||
// create new logfile
|
||||
CreateNewFile();
|
||||
}
|
||||
else if (m_LogType == 1)
|
||||
{
|
||||
} else if (m_LogType == 1) {
|
||||
Log("-------- Mapchange to %s --------", STRING(gpGlobals->mapname));
|
||||
}
|
||||
else
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::Log(const char *fmt, ...)
|
||||
@ -195,7 +204,7 @@ void CLog::Log(const char *fmt, ...)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday);
|
||||
build_pathname_r(file, sizeof(file)-1, "%s/L%04d%02d%02d.log", g_log_dir.c_str(), (curTime->tm_year + 1900), curTime->tm_mon + 1, curTime->tm_mday);
|
||||
pF = fopen(file, "a+");
|
||||
}
|
||||
|
||||
@ -211,9 +220,7 @@ void CLog::Log(const char *fmt, ...)
|
||||
|
||||
// print on server console
|
||||
print_srvconsole("L %s: %s\n", date, msg);
|
||||
}
|
||||
else if (m_LogType == 3)
|
||||
{
|
||||
} else if (m_LogType == 3) {
|
||||
// build message
|
||||
static char msg_[3072];
|
||||
va_list arglst;
|
||||
@ -223,3 +230,55 @@ void CLog::Log(const char *fmt, ...)
|
||||
ALERT(at_logged, "%s\n", msg_);
|
||||
}
|
||||
}
|
||||
|
||||
void CLog::LogError(const char *fmt, ...)
|
||||
{
|
||||
static char file[256];
|
||||
static char name[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, sizeof(msg)-1, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
FILE *pF = NULL;
|
||||
snprintf(name, sizeof(name), "%s/error_%04d%02d%02d.log", g_log_dir.c_str(), curTime->tm_year + 1900, curTime->tm_mon + 1, curTime->tm_mday);
|
||||
build_pathname_r(file, sizeof(file)-1, "%s", name);
|
||||
pF = fopen(file, "a+");
|
||||
|
||||
if (pF)
|
||||
{
|
||||
if (!m_LoggedErrMap)
|
||||
{
|
||||
fprintf(pF, "L %s: Start of error session.\n", date);
|
||||
fprintf(pF, "L %s: Info (map \"%s\") (file \"%s\")\n", date, STRING(gpGlobals->mapname), name);
|
||||
m_LoggedErrMap = true;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,8 @@ class CLog
|
||||
private:
|
||||
String m_LogFile;
|
||||
int m_LogType;
|
||||
bool m_FoundError;
|
||||
bool m_LoggedErrMap;
|
||||
|
||||
void GetLastFile(int &outMonth, int &outDay, String &outFilename);
|
||||
void UseFile(const String &fileName);
|
||||
@ -47,6 +49,7 @@ public:
|
||||
void CloseFile();
|
||||
void MapChange();
|
||||
void Log(const char *fmt, ...);
|
||||
void LogError(const char *fmt, ...);
|
||||
};
|
||||
|
||||
#endif // __AMXXLOG_H__
|
||||
|
362
amxmodx/binlog.cpp
Normal file
362
amxmodx/binlog.cpp
Normal file
@ -0,0 +1,362 @@
|
||||
#if defined BINLOG_ENABLED
|
||||
|
||||
#include <time.h>
|
||||
#include "amxmodx.h"
|
||||
#include "binlog.h"
|
||||
#include "debugger.h"
|
||||
|
||||
BinLog g_BinLog;
|
||||
int g_binlog_level = 0;
|
||||
int g_binlog_maxsize = 0;
|
||||
|
||||
// Helper function to get a filename index
|
||||
#define USHR(x) ((unsigned int)(x)>>1)
|
||||
int LookupFile(AMX_DBG *amxdbg, ucell address)
|
||||
{
|
||||
int high, low, mid;
|
||||
|
||||
high = amxdbg->hdr->files;
|
||||
low = -1;
|
||||
|
||||
while (high - low > 1)
|
||||
{
|
||||
mid = USHR(low + high);
|
||||
if (amxdbg->filetbl[mid]->address <= address)
|
||||
{
|
||||
low = mid;
|
||||
} else {
|
||||
high = mid;
|
||||
}
|
||||
}
|
||||
|
||||
if (low == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return low;
|
||||
}
|
||||
|
||||
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__) || defined(__APPLE__)
|
||||
, 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);
|
||||
|
||||
AMX *amx = NULL;
|
||||
bool debug = false;
|
||||
AMX_DBG *dbg = NULL;
|
||||
CPluginMngr::CPlugin *pl = NULL;
|
||||
|
||||
if (plug != -1)
|
||||
{
|
||||
pl = g_plugins.findPlugin(plug);
|
||||
if ((debug = pl->isDebug()))
|
||||
{
|
||||
amx = pl->getAMX();
|
||||
dbg = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER])->m_pAmxDbg;
|
||||
}
|
||||
}
|
||||
|
||||
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 file;
|
||||
int native = va_arg(ap, int);
|
||||
int params = va_arg(ap, int);
|
||||
fwrite(&native, sizeof(int), 1, fp);
|
||||
fwrite(¶ms, sizeof(int), 1, fp);
|
||||
if (debug)
|
||||
{
|
||||
file = LookupFile(dbg, amx->cip);
|
||||
fwrite(&file, sizeof(int), 1, fp);
|
||||
} else {
|
||||
file = 0;
|
||||
fwrite(&file, 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 file;
|
||||
int num = va_arg(ap, int);
|
||||
fwrite(&num, sizeof(int), 1, fp);
|
||||
if (debug)
|
||||
{
|
||||
file = LookupFile(dbg, amx->cip);
|
||||
fwrite(&file, sizeof(int), 1, fp);
|
||||
} else {
|
||||
file = 0;
|
||||
fwrite(&file, sizeof(int), 1, fp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BinLog_SetLine:
|
||||
{
|
||||
int file;
|
||||
int line = va_arg(ap, int);
|
||||
fwrite(&line, sizeof(int), 1, fp);
|
||||
if (debug)
|
||||
{
|
||||
file = LookupFile(dbg, amx->cip);
|
||||
fwrite(&file, sizeof(int), 1, fp);
|
||||
} else {
|
||||
file = 0;
|
||||
fwrite(&file, 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)
|
||||
{
|
||||
Debugger *pd = NULL;
|
||||
len = (char)strlen(pl->getName());
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
len++;
|
||||
fwrite(pl->getName(), sizeof(char), len, fp);
|
||||
int natives, publics, files;
|
||||
AMX *amx = pl->getAMX();
|
||||
// Write the number of Filenames
|
||||
if (c == 2)
|
||||
{
|
||||
pd = static_cast<Debugger *>(amx->userdata[UD_DEBUGGER]);
|
||||
files = pd->m_pAmxDbg->hdr->files;
|
||||
fwrite(&files, sizeof(int), 1, fp);
|
||||
}
|
||||
amx_NumNatives(amx, &natives);
|
||||
amx_NumPublics(amx, &publics);
|
||||
fwrite(&natives, sizeof(int), 1, fp);
|
||||
fwrite(&publics, sizeof(int), 1, fp);
|
||||
char name[34];
|
||||
// Write the Filenames to the binfile
|
||||
if (c == 2)
|
||||
{
|
||||
AMX_DBG_FILE **ftable = pd->m_pAmxDbg->filetbl;
|
||||
for (int i=0; i<files; i++)
|
||||
{
|
||||
len = (char)strlen(ftable[i]->name);
|
||||
fwrite(&len, sizeof(char), 1, fp);
|
||||
len++;
|
||||
fwrite(ftable[i]->name, sizeof(char), len, fp);
|
||||
}
|
||||
}
|
||||
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
|
84
amxmodx/binlog.h
Normal file
84
amxmodx/binlog.h
Normal file
@ -0,0 +1,84 @@
|
||||
#ifndef _INCLUDE_BINLOG_H
|
||||
#define _INCLUDE_BINLOG_H
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#define BINLOG_MAGIC 0x414D424C
|
||||
#define BINLOG_VERSION 0x0300
|
||||
|
||||
/**
|
||||
* Format of binlog:
|
||||
* uint32 magic
|
||||
* uint16 version
|
||||
* uint8 sizeof(time_t)
|
||||
* uint32 num plugins
|
||||
* [
|
||||
* uint8 status codes
|
||||
* str[int8] filename
|
||||
* if(status==2)
|
||||
* uint32 num filenames
|
||||
* uint32 num natives
|
||||
* uint32 num publics
|
||||
* if (status==2)
|
||||
* [
|
||||
* str[uint8] file name
|
||||
* ]
|
||||
* [
|
||||
* str[uint8] native name
|
||||
* ]
|
||||
* [
|
||||
* str[uint8] public name
|
||||
* ]
|
||||
* ]
|
||||
* [
|
||||
* uint8 operation code
|
||||
* time_t realtime
|
||||
* float gametime
|
||||
* int32 plugin id
|
||||
* <extra info>
|
||||
* ]
|
||||
* If filename id is 0 skip as plugin was not in debug mode, if -1 there was an error.
|
||||
*/
|
||||
|
||||
enum BinLogOp
|
||||
{
|
||||
BinLog_Start=1,
|
||||
BinLog_End,
|
||||
BinLog_NativeCall, //<int32 native id> <int32_t num_params> <int32_t filename id>
|
||||
BinLog_NativeError, //<int32 errornum> <str[int16] string>
|
||||
BinLog_NativeRet, //<cell value>
|
||||
BinLog_CallPubFunc, //<int32 public id> <int32_t filename id>
|
||||
BinLog_SetLine, //<int32 line no#> <int32_t filename id>
|
||||
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
|
608
amxmodx/datastructs.cpp
Normal file
608
amxmodx/datastructs.cpp
Normal file
@ -0,0 +1,608 @@
|
||||
/* 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 "datastructs.h"
|
||||
|
||||
|
||||
// Note: All handles start at 1. 0 and below are invalid handles.
|
||||
// This way, a plugin that doesn't initialize a vector or
|
||||
// string will not be able to modify another plugin's data
|
||||
// on accident.
|
||||
CVector<CellVector*> VectorHolder;
|
||||
|
||||
|
||||
// Array:ArrayCreate(cellsize=1, reserved=32);
|
||||
static cell AMX_NATIVE_CALL ArrayCreate(AMX* amx, cell* params)
|
||||
{
|
||||
// params[1] (cellsize) is how big in cells each element is.
|
||||
// this MUST be greater than 0!
|
||||
int cellsize=params[1];
|
||||
|
||||
// params[2] (reserved) is how many elements to allocate
|
||||
// immediately when the list is created.
|
||||
// this MUST be greater than 0!
|
||||
int reserved=params[2];
|
||||
|
||||
if (cellsize<=0)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array size (%d)", cellsize);
|
||||
return -1;
|
||||
}
|
||||
if (reserved<=0)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid reserved size (%d)", reserved);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Scan through the vector list to see if any are NULL.
|
||||
// NULL means the vector was previously destroyed.
|
||||
for (unsigned int i=0; i < VectorHolder.size(); ++i)
|
||||
{
|
||||
if (VectorHolder[i]==NULL)
|
||||
{
|
||||
VectorHolder[i]=new CellVector(cellsize);
|
||||
VectorHolder[i]->Grow(reserved);
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// None are NULL, create a new vector
|
||||
CellVector* NewVector=new CellVector(cellsize);
|
||||
NewVector->Grow(reserved);
|
||||
|
||||
VectorHolder.push_back(NewVector);
|
||||
|
||||
return VectorHolder.size();
|
||||
}
|
||||
// ArrayClear(Array:which)
|
||||
static cell AMX_NATIVE_CALL ArrayClear(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->Clear();
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArraySize(Array:which)
|
||||
static cell AMX_NATIVE_CALL ArraySize(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return vec->Size();
|
||||
}
|
||||
// ArrayGetArray(Array:which, item, any:output[]);
|
||||
static cell AMX_NATIVE_CALL ArrayGetArray(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->GetArray(params[2],get_amxaddr(amx, params[3]))!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayGetCell(Array:which, item, any:&output);
|
||||
static cell AMX_NATIVE_CALL ArrayGetCell(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell ret;
|
||||
if (vec->GetCell(params[2],&ret)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
// ArrayGetString(Array:which, item, any:output[], size);
|
||||
static cell AMX_NATIVE_CALL ArrayGetString(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->GetString(params[2],get_amxaddr(amx, params[3]),params[4])!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArraySetArray(Array:which, item, any:output[]);
|
||||
static cell AMX_NATIVE_CALL ArraySetArray(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->SetArray(params[2],get_amxaddr(amx, params[3]))!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArraySetCell(Array:which, item, any:&output);
|
||||
static cell AMX_NATIVE_CALL ArraySetCell(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->SetCell(params[2], params[3])!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArraySetString(Array:which, item, any:output[]);
|
||||
static cell AMX_NATIVE_CALL ArraySetString(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->SetString(params[2],get_amxaddr(amx, params[3]))!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid cellvector handle provided (%d:%d:%d)", params[1], params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayPushArray(Array:which, any:output[]);
|
||||
static cell AMX_NATIVE_CALL ArrayPushArray(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetArray(vec->Push(),get_amxaddr(amx, params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayPushCell(Array:which, &any:output);
|
||||
static cell AMX_NATIVE_CALL ArrayPushCell(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetCell(vec->Push(), params[2]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayPushString(Array:which, any:output[]);
|
||||
static cell AMX_NATIVE_CALL ArrayPushString(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec==NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetString(vec->Push(),get_amxaddr(amx, params[2]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL ArrayGetStringHandle(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (vec == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cell* ptr=vec->GetCellPointer(params[2]);
|
||||
|
||||
if (ptr == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return reinterpret_cast<cell>(ptr);
|
||||
|
||||
}
|
||||
// ArrayInsertArrayAfter(Array:which, item, const value[])
|
||||
static cell AMX_NATIVE_CALL ArrayInsertArrayAfter(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2]+1;
|
||||
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayAfter (%d:%d)", params[1], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetArray(item, get_amxaddr(amx, params[3]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayInsertCellAfter(Array:which, item, value[])
|
||||
static cell AMX_NATIVE_CALL ArrayInsertCellAfter(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2]+1;
|
||||
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellAfter (%d:%d)", params[1], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetCell(item, params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayInsertStringAfter(Array:which, item, const value[])
|
||||
static cell AMX_NATIVE_CALL ArrayInsertStringAfter(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2]+1;
|
||||
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringAfter (%d:%d)", params[1], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetString(item, get_amxaddr(amx, params[3]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayInsertArrayBefore(Array:which, item, const value[])
|
||||
static cell AMX_NATIVE_CALL ArrayInsertArrayBefore(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2];
|
||||
|
||||
if (item==vec->Size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertArrayBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetArray(item, get_amxaddr(amx, params[3]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayInsertCellBefore(Array:which, item, const value)
|
||||
static cell AMX_NATIVE_CALL ArrayInsertCellBefore(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2];
|
||||
|
||||
if (item==vec->Size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertCellBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetCell(item, params[3]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
// ArrayInsertStringBefore(Array:which, item, const value[])
|
||||
static cell AMX_NATIVE_CALL ArrayInsertStringBefore(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int item=params[2];
|
||||
|
||||
if (item==vec->Size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
if (vec->ShiftUpFrom(item)!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayInsertStringBefore (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
vec->SetString(item, get_amxaddr(amx, params[3]));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ArraySwap(Array:which, item1, item2)
|
||||
static cell AMX_NATIVE_CALL ArraySwap(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (vec->Swap(params[2], params[3])!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArraySwap (%d , %d:%d)",params[2], params[3], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ArrayDeleteItem(Array:which, item);
|
||||
static cell AMX_NATIVE_CALL ArrayDeleteItem(AMX* amx, cell* params)
|
||||
{
|
||||
CellVector* vec=HandleToVector(amx, params[1]);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (vec->Delete(params[2])!=1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid item specified in ArrayDeleteItem (%d:%d)", params[2], vec->Size());
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// ArrayDestroy(Array:&which)
|
||||
static cell AMX_NATIVE_CALL ArrayDestroy(AMX* amx, cell* params)
|
||||
{
|
||||
// byref the handle here so we can zero it out after destroying
|
||||
// this way they cannot accidentally reuse it
|
||||
cell* handle=get_amxaddr(amx,params[1]);
|
||||
CellVector* vec=HandleToVector(amx, *handle);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
delete vec;
|
||||
|
||||
VectorHolder[*handle-1]=NULL;
|
||||
|
||||
*handle=0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct ArraySort_s
|
||||
{
|
||||
int handle;
|
||||
int forward;
|
||||
cell data;
|
||||
cell size;
|
||||
|
||||
} ArraySort_t;
|
||||
|
||||
static CStack<ArraySort_t *> ArraySortStack;
|
||||
|
||||
int SortArrayList(const void *itema, const void *itemb)
|
||||
{
|
||||
ArraySort_t *Info = ArraySortStack.front();
|
||||
|
||||
return executeForwards(Info->forward, Info->handle, *((int *)itema), *((int *)itemb), Info->data, Info->size);
|
||||
|
||||
}
|
||||
// native ArraySort(Array:array, const comparefunc[], data[]="", data_size=0);
|
||||
static cell AMX_NATIVE_CALL ArraySort(AMX* amx, cell* params)
|
||||
{
|
||||
int handle=params[1];
|
||||
CellVector* vec=HandleToVector(amx, handle);
|
||||
|
||||
if (!vec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is kind of a cheating way to go about this but...
|
||||
// Create an array of integers as big as however many elements are in the vector.
|
||||
// Pass that array to qsort
|
||||
// After the array is sorted out, then create a NEW cellvector
|
||||
// and copy in the old data in the order of what was sorted
|
||||
int len;
|
||||
char* FuncName=get_amxstring(amx, params[2], 0, len);
|
||||
// MySortFunc(Array:array, item1, item2, const data[], data_size)
|
||||
int Forward = registerSPForwardByName(amx, FuncName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
if (Forward < 0)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", FuncName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *IntList=new int[vec->Size()];
|
||||
|
||||
for (int i=0; i< vec->Size(); i++)
|
||||
{
|
||||
IntList[i]=i;
|
||||
}
|
||||
|
||||
ArraySort_t *Info=new ArraySort_t;
|
||||
|
||||
Info->handle=handle;
|
||||
Info->forward=Forward;
|
||||
Info->data=params[3];
|
||||
Info->size=params[4];
|
||||
|
||||
ArraySortStack.push(Info);
|
||||
qsort(IntList, vec->Size(), sizeof(int), SortArrayList);
|
||||
ArraySortStack.pop();
|
||||
|
||||
CellVector* newvec=new CellVector(vec->GetCellCount());
|
||||
|
||||
// Set the new vector's values
|
||||
for (int i=0; i< vec->Size(); i++)
|
||||
{
|
||||
if (newvec->SetArray(newvec->Push(), vec->GetCellPointer(IntList[i]))!=1)
|
||||
{
|
||||
// This should never happen..
|
||||
LogError(amx, AMX_ERR_NATIVE, "Failed to SetArray in ArraySort (i=%d, IntList=%d)",i,IntList[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the old vector
|
||||
delete vec;
|
||||
|
||||
// Now save the new vector in its handle location
|
||||
VectorHolder[handle-1]=newvec;
|
||||
|
||||
// Cleanup
|
||||
delete Info;
|
||||
delete IntList;
|
||||
|
||||
unregisterSPForward(Forward);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
AMX_NATIVE_INFO g_DataStructNatives[] =
|
||||
{
|
||||
{ "ArrayCreate", ArrayCreate },
|
||||
{ "ArrayClear", ArrayClear },
|
||||
{ "ArraySize", ArraySize },
|
||||
{ "ArrayGetArray", ArrayGetArray },
|
||||
{ "ArrayGetCell", ArrayGetCell },
|
||||
{ "ArrayGetString", ArrayGetString },
|
||||
{ "ArraySetArray", ArraySetArray },
|
||||
{ "ArraySetCell", ArraySetCell },
|
||||
{ "ArraySetString", ArraySetString },
|
||||
{ "ArrayPushArray", ArrayPushArray },
|
||||
{ "ArrayPushCell", ArrayPushCell },
|
||||
{ "ArrayPushString", ArrayPushString },
|
||||
{ "ArrayInsertArrayAfter", ArrayInsertArrayAfter },
|
||||
{ "ArrayInsertCellAfter", ArrayInsertCellAfter },
|
||||
{ "ArrayInsertStringAfter", ArrayInsertStringAfter },
|
||||
{ "ArrayInsertArrayBefore", ArrayInsertArrayBefore },
|
||||
{ "ArrayInsertCellBefore", ArrayInsertCellBefore },
|
||||
{ "ArrayInsertStringBefore", ArrayInsertStringBefore },
|
||||
{ "ArraySwap", ArraySwap },
|
||||
{ "ArrayDeleteItem", ArrayDeleteItem },
|
||||
{ "ArrayGetStringHandle", ArrayGetStringHandle },
|
||||
{ "ArrayDestroy", ArrayDestroy },
|
||||
{ "ArraySort", ArraySort },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
321
amxmodx/datastructs.h
Normal file
321
amxmodx/datastructs.h
Normal file
@ -0,0 +1,321 @@
|
||||
/* 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 DATASTRUCTS_H
|
||||
#define DATASTRUCTS_H
|
||||
|
||||
class CellVector
|
||||
{
|
||||
private:
|
||||
cell* data; // allocated with malloc
|
||||
size_t cellcount; // how many cells per element
|
||||
size_t cursize; // current size of the vector (maximum elements)
|
||||
size_t count; // how many units of the vector are in use
|
||||
|
||||
public:
|
||||
CellVector(): data(NULL), cellcount(0), cursize(0), count(0)
|
||||
{
|
||||
};
|
||||
CellVector(int cellsize): data(NULL), cellcount(cellsize), cursize(0), count(0)
|
||||
{
|
||||
};
|
||||
~CellVector()
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
};
|
||||
size_t GetCellCount()
|
||||
{
|
||||
return cellcount;
|
||||
};
|
||||
void Grow(size_t howmany)
|
||||
{
|
||||
cursize+=howmany;
|
||||
if (data)
|
||||
{
|
||||
data=(cell*)realloc(data, (sizeof(cell) * cellcount) * cursize);
|
||||
}
|
||||
else
|
||||
{
|
||||
data=(cell*)malloc((sizeof(cell) * cellcount) * cursize);
|
||||
}
|
||||
};
|
||||
void FreeUnused(void)
|
||||
{
|
||||
if (cursize != count &&
|
||||
data != NULL)
|
||||
{
|
||||
cursize=count;
|
||||
data=(cell*)realloc(data, cursize * (sizeof(cell) * cellcount));
|
||||
}
|
||||
};
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds.
|
||||
int GetArray(size_t which, cell* output)
|
||||
{
|
||||
// make sure it is in bounds.
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// align output data
|
||||
cell* out=data + (cellcount * which);
|
||||
|
||||
memcpy(output, out, sizeof(cell) * cellcount);
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds
|
||||
int GetCell(size_t which, cell* output)
|
||||
{
|
||||
// check bounds
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
*output=*(data + (cellcount * which));
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds
|
||||
int GetString(size_t which, cell* output, size_t size)
|
||||
{
|
||||
// check bounds
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cell* out=data + (cellcount * which);
|
||||
|
||||
size_t count=cellcount;
|
||||
|
||||
while (size-- &&
|
||||
count-- &&
|
||||
(*output++=*out++)!='\0')
|
||||
/* do nothing */ ;
|
||||
|
||||
// If size is zero here, then the string was never null terminated.
|
||||
if (size==0)
|
||||
{
|
||||
*out='\0';
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds
|
||||
int SetArray(size_t which, cell* output)
|
||||
{
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// align output
|
||||
cell* out=data + (cellcount * which);
|
||||
|
||||
memcpy(out, output, sizeof(cell) * cellcount);
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds
|
||||
int SetCell(size_t which, cell output)
|
||||
{
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// align output
|
||||
*(data + (cellcount * which))=output;
|
||||
|
||||
return 1;
|
||||
};
|
||||
// Returns 1 on success
|
||||
// 0 on out of bounds
|
||||
int SetString(size_t which, cell* output)
|
||||
{
|
||||
if (which >= count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// align output
|
||||
cell* out=data + (cellcount * which);
|
||||
|
||||
memcpy(out, output, sizeof(cell) * cellcount);
|
||||
|
||||
// now force a null terminator on the last entry.
|
||||
out+=(cellcount - 1);
|
||||
*out='\0';
|
||||
|
||||
return 1;
|
||||
};
|
||||
int Push()
|
||||
{
|
||||
if (count >= cursize)
|
||||
{
|
||||
// Grow in 8s to cause less reallocation
|
||||
this->Grow(8);
|
||||
};
|
||||
|
||||
this->count++;
|
||||
|
||||
return this->count-1;
|
||||
};
|
||||
int Size()
|
||||
{
|
||||
return this->count;
|
||||
};
|
||||
void Clear()
|
||||
{
|
||||
free(data);
|
||||
data=(cell*)malloc(sizeof(cell) * cellcount);
|
||||
cursize=1;
|
||||
count=0;
|
||||
};
|
||||
cell* GetCellPointer(size_t which)
|
||||
{
|
||||
if (which >= count)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return data + (which * cellcount);
|
||||
};
|
||||
// Shifts all items from this item, and including this item up 1.
|
||||
int ShiftUpFrom(size_t which)
|
||||
{
|
||||
// No point shifting this.
|
||||
if (which > this->count)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
// First make a new item.
|
||||
this->Push();
|
||||
|
||||
// If we got an InsertAfter(lastitem), then which will equal this->count - 1
|
||||
// all we needed to do was Push()
|
||||
if (which == this->count ||
|
||||
which == this->count - 1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate a temporary buffer to store data in
|
||||
size_t tempbuffsize=(sizeof(cell) * cellcount) * (this->count - which);
|
||||
|
||||
cell* temp=(cell*)malloc(tempbuffsize);
|
||||
|
||||
// Copy old data to temp buffer
|
||||
memcpy(temp, GetCellPointer(which), tempbuffsize);
|
||||
|
||||
// Now copy temp buffer to adjusted location
|
||||
memcpy(GetCellPointer(which+1), temp, tempbuffsize);
|
||||
|
||||
// cleanup
|
||||
free(temp);
|
||||
|
||||
return 1;
|
||||
|
||||
};
|
||||
// Shifts all items from this item, and including this item down 1.
|
||||
// This deletes the item specified.
|
||||
int Delete(size_t which)
|
||||
{
|
||||
// No point shifting this.
|
||||
if (which >= this->count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
for (size_t i=which; i<this->count - 1; i++)
|
||||
{
|
||||
memcpy(GetCellPointer(i), GetCellPointer(i + 1), sizeof(cell) * cellcount);
|
||||
}
|
||||
this->count--;
|
||||
return 1;
|
||||
};
|
||||
int Swap(size_t item1, size_t item2)
|
||||
{
|
||||
if (item1 >= this->count ||
|
||||
item2 >= this->count)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make a temp buffer to store item2
|
||||
cell* temp=(cell*)malloc(sizeof(cell) * cellcount);
|
||||
memcpy(temp, GetCellPointer(item2), sizeof(cell) * cellcount);
|
||||
|
||||
// copy item1 to item2
|
||||
memcpy(GetCellPointer(item2), GetCellPointer(item1), sizeof(cell) * cellcount);
|
||||
|
||||
// copy item2 to item1
|
||||
memcpy(GetCellPointer(item1), temp, sizeof(cell) * cellcount);
|
||||
|
||||
// Cleanup
|
||||
free(temp);
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
extern CVector<CellVector*> VectorHolder;
|
||||
|
||||
|
||||
inline CellVector* HandleToVector(AMX* amx, int handle)
|
||||
{
|
||||
if (handle <= 0 ||
|
||||
handle > (int)VectorHolder.size())
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CellVector* ret=VectorHolder[handle-1];
|
||||
|
||||
if (ret == NULL)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", handle);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "debugger.h"
|
||||
#include "binlog.h"
|
||||
|
||||
#if !defined WIN32 && !defined _WIN32
|
||||
#define _snprintf snprintf
|
||||
@ -288,7 +289,7 @@ void Debugger::BeginExec()
|
||||
{
|
||||
Tracer *pTracer = new Tracer();
|
||||
m_pCalls.push_back(pTracer);
|
||||
assert(m_Top == (m_pCalls.size() - 1));
|
||||
assert(m_Top == static_cast<int>(m_pCalls.size() - 1));
|
||||
}
|
||||
|
||||
m_pCalls[m_Top]->Reset();
|
||||
@ -307,6 +308,19 @@ void Debugger::StepI()
|
||||
{
|
||||
assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
|
||||
|
||||
#if defined BINLOG_ENABLED
|
||||
if (g_binlog_level & 32)
|
||||
{
|
||||
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
|
||||
if (pl)
|
||||
{
|
||||
long line;
|
||||
dbg_LookupLine(m_pAmxDbg, m_pAmx->cip, &line);
|
||||
g_BinLog.WriteOp(BinLog_SetLine, pl->getId(), (int)(line + 1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip);
|
||||
}
|
||||
|
||||
@ -363,53 +377,6 @@ bool Debugger::ErrorExists()
|
||||
return (m_pCalls[m_Top]->m_Error != AMX_ERR_NONE);
|
||||
}
|
||||
|
||||
#define FLAG_INDIRECT (1<<0)
|
||||
|
||||
//vaddr - the address of our current index vector
|
||||
//base - the base address of which the array is offset to
|
||||
//dim - the current dimension to search
|
||||
//dimNum - the number of dimensions total
|
||||
//sizes[] - an array containing the dimension sizes
|
||||
//Indexes[] - an output array to contain each dimension's index
|
||||
int WalkArray(cell *vaddr, unsigned char *base, cell *addr, int dim, int dimNum, int &flags, int sizes[], int Indexes[])
|
||||
{
|
||||
cell *my_addr;
|
||||
int idx = 0;
|
||||
|
||||
//if we are the second to last walker, we only need to check the ranges of our vector.
|
||||
if (dim == dimNum - 2)
|
||||
{
|
||||
my_addr = vaddr;
|
||||
//first check the actual vectors themselves
|
||||
for (int i=0; i<sizes[dim]; i++)
|
||||
{
|
||||
if (addr == my_addr)
|
||||
return i;
|
||||
my_addr++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//otherwise, search lower vectors!
|
||||
//vaddr is the address where we can start reading vectors
|
||||
flags |= FLAG_INDIRECT;
|
||||
for (int i=0; i<sizes[dim]; i++)
|
||||
{
|
||||
//the next vector is offset from the last address!
|
||||
//this is funky but that's the internal implementation
|
||||
my_addr = (cell *)((char *)vaddr + i*sizeof(cell) + vaddr[i]);
|
||||
idx = WalkArray(my_addr, base, addr, dim+1, dimNum, flags, sizes, Indexes);
|
||||
if (idx != -1)
|
||||
{
|
||||
Indexes[dim+1] = idx;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Debugger::FormatError(char *buffer, size_t maxLength)
|
||||
{
|
||||
if (!ErrorExists())
|
||||
@ -421,9 +388,9 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
|
||||
int error = pTracer->m_Error;
|
||||
const char *gen_err = GenericError(error);
|
||||
int size = 0;
|
||||
trace_info_t *pTrace = pTracer->GetEnd();
|
||||
cell cip = _CipAsVa(m_pAmx->cip);
|
||||
cell *p_cip = NULL;
|
||||
//trace_info_t *pTrace = pTracer->GetEnd();
|
||||
//cell cip = _CipAsVa(m_pAmx->cip);
|
||||
//cell *p_cip = NULL;
|
||||
int amx_err = AMX_ERR_NONE;
|
||||
|
||||
size += _snprintf(buffer, maxLength, "Run time error %d: %s ", error, gen_err);
|
||||
@ -442,7 +409,7 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
|
||||
num = (int)*p_cip;
|
||||
}*/
|
||||
//New code only requires this...
|
||||
num = m_pAmx->usertags[UT_NATIVE];
|
||||
num = (int)(_INT_PTR)m_pAmx->usertags[UT_NATIVE];
|
||||
amx_err = amx_GetNative(m_pAmx, num, native_name);
|
||||
/*if (num)
|
||||
amx_err = amx_GetNative(m_pAmx, (int)*p_cip, native_name);
|
||||
@ -450,205 +417,6 @@ int Debugger::FormatError(char *buffer, size_t maxLength)
|
||||
amx_err = AMX_ERR_NOTFOUND;*/
|
||||
//if (!amx_err)
|
||||
size += _snprintf(buffer, maxLength, "(native \"%s\")", native_name);
|
||||
} else if (error == AMX_ERR_BOUNDS) {
|
||||
tagAMX_DBG *pDbg = m_pAmxDbg;
|
||||
int symbols = pDbg->hdr->symbols;
|
||||
int index = 0;
|
||||
tagAMX_DBG_SYMBOL **pSymbols = pDbg->symboltbl;
|
||||
tagAMX_DBG_SYMBOL *pSymbol, *pLastSymbol=NULL;
|
||||
const tagAMX_DBG_SYMDIM *pDims;
|
||||
ucell addr = 0;
|
||||
int flags = 0;
|
||||
char v_class, i_dent;
|
||||
cell *arr_addr=NULL, *p_addr=NULL;
|
||||
unsigned char *data = m_pAmx->base + ((AMX_HEADER *)m_pAmx->base)->dat;
|
||||
bool valid=false;
|
||||
//we can't really browse the assembly because
|
||||
// we've no idea what the peephole optimizer did.
|
||||
// so we're gonna try to go out on a limb and guess.
|
||||
if (m_pAmx->alt < 0)
|
||||
{
|
||||
//take a guess that it's local
|
||||
addr = m_pAmx->alt - pTrace->frm;
|
||||
v_class = 1;
|
||||
} else {
|
||||
//take a guess that it's a global
|
||||
//it won't be global if it's passed in from the stack frame, however
|
||||
// doing this with a hardcoded array size is quite rare, and is probably passed
|
||||
// as iREFARRAY not iARRAY!
|
||||
addr = m_pAmx->alt;
|
||||
v_class = 0;
|
||||
}
|
||||
bool found = false;
|
||||
bool _found = true;
|
||||
static char _msgbuf[255];
|
||||
size_t _size = 0;
|
||||
//take a pre-emptive guess at the v_class!
|
||||
//are we GLOBAL (0) or LOCAL (1) ?
|
||||
if (m_pAmx->alt < 0)
|
||||
{
|
||||
v_class = 1;
|
||||
i_dent = iARRAY;
|
||||
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
|
||||
} else {
|
||||
//it's greater than 0, check other things!
|
||||
if (m_pAmx->alt >= m_pAmx->hlw &&
|
||||
m_pAmx->alt <= m_pAmx->stp)
|
||||
{
|
||||
//it's in the stack somewhere... guess that it's a local!
|
||||
v_class = 1;
|
||||
//relocate it
|
||||
m_pAmx->alt -= pTrace->frm;
|
||||
//alt cannot be zero
|
||||
if (m_pAmx->alt < 0)
|
||||
i_dent = iARRAY;
|
||||
else
|
||||
i_dent = iREFARRAY;
|
||||
arr_addr = (cell *)(data + pTrace->frm + m_pAmx->alt);
|
||||
} else {
|
||||
//guess that it's DAT
|
||||
v_class = 0;
|
||||
i_dent = iARRAY;
|
||||
arr_addr = (cell *)(data + m_pAmx->alt);
|
||||
}
|
||||
}
|
||||
for (index = 0; index < symbols; index++)
|
||||
{
|
||||
pSymbol = pSymbols[index];
|
||||
if (pSymbol->codestart <= (ucell)cip &&
|
||||
pSymbol->codeend >= (ucell)cip &&
|
||||
(pSymbol->ident == iARRAY || pSymbol->ident == iREFARRAY))
|
||||
{
|
||||
amx_err = dbg_GetArrayDim(pDbg, pSymbol, &pDims);
|
||||
if (amx_err != AMX_ERR_NONE)
|
||||
continue;
|
||||
//calculate the size of the array. this is important!
|
||||
ucell size = pDims[0].size;
|
||||
ucell aggre = pDims[0].size;
|
||||
valid = false;
|
||||
for (int16_t i=1; i<pSymbol->dim; i++)
|
||||
{
|
||||
aggre *= pDims[i].size;
|
||||
size += aggre;
|
||||
}
|
||||
if (pSymbol->vclass != v_class)
|
||||
continue;
|
||||
if (pSymbol->ident != i_dent)
|
||||
continue;
|
||||
if (v_class == 1)
|
||||
{
|
||||
if (i_dent == iARRAY)
|
||||
{
|
||||
p_addr = (cell *)(data + pTrace->frm + pSymbol->address);
|
||||
} else if (i_dent == iREFARRAY) {
|
||||
//get the variable off the stack, by reference
|
||||
ucell _addr = (ucell)*((cell *)(data + pTrace->frm + pSymbol->address));
|
||||
p_addr = (cell *)(data + _addr);
|
||||
}
|
||||
} else if (v_class == 0) {
|
||||
p_addr = (cell *)(data + pSymbol->address);
|
||||
}
|
||||
//make sure our address is in bounds!
|
||||
if (arr_addr < p_addr || arr_addr > (p_addr + size))
|
||||
continue;
|
||||
int *sizes = new int[pSymbol->dim];
|
||||
int *indexes = new int[pSymbol->dim];
|
||||
for (int i=0; i<pSymbol->dim; i++)
|
||||
{
|
||||
sizes[i] = pDims[i].size;
|
||||
indexes[i] = -1;
|
||||
}
|
||||
flags = 0;
|
||||
if (pSymbol->dim >= 2)
|
||||
{
|
||||
int dims = pSymbol->dim;
|
||||
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, pSymbol->dim, flags, sizes, indexes);
|
||||
if (indexes[0] == -1)
|
||||
{
|
||||
while (indexes[0] == -1 && --dims > 0)
|
||||
{
|
||||
flags = 0;
|
||||
indexes[0] = WalkArray(p_addr, data, arr_addr, 0, dims, flags, sizes, indexes);
|
||||
}
|
||||
}
|
||||
//find the last known good dimension
|
||||
for (dims=pSymbol->dim-1; dims>=0; dims--)
|
||||
{
|
||||
if (indexes[dims] != -1)
|
||||
break;
|
||||
}
|
||||
//check for the "impossible" case.
|
||||
//if we have [X][-1], and X is zero, the array did not walk properly.
|
||||
if (dims >= 0
|
||||
&& indexes[dims] == 0
|
||||
&& !(flags & FLAG_INDIRECT)
|
||||
&& dims < pSymbol->dim - 1)
|
||||
{
|
||||
//here we have the dreaded MIXED CASE. we don't know whether
|
||||
//[-][X] or [0][-] (where - is a bad input) was intended.
|
||||
//first, we take a guess by checking the bounds.
|
||||
cell *_cip = (cell *)_CipAsVa(cip);
|
||||
_cip -= 1;
|
||||
cell bounds = *_cip;
|
||||
if (sizes[dims] != sizes[dims+1])
|
||||
{
|
||||
//we were checking initial bounds
|
||||
if (bounds == sizes[dims] - 1)
|
||||
{
|
||||
indexes[dims] = m_pAmx->pri;
|
||||
} else if (bounds == sizes[dims+1] - 1) {
|
||||
indexes[dims + 1] = m_pAmx->pri;
|
||||
indexes[dims] = 0;
|
||||
} else {
|
||||
//this should really never happen...
|
||||
_found = false;
|
||||
}
|
||||
} else {
|
||||
_found = false;
|
||||
}
|
||||
if (!_found)
|
||||
{
|
||||
//we still don't have a good approximation.
|
||||
//the user did something like:
|
||||
//new X[40][40]
|
||||
//we could do some really complicated and random guesswork
|
||||
// but fact is, we have no way of deterministically knowing
|
||||
// what the user intended.
|
||||
}
|
||||
} else {
|
||||
//set the last know index to our culprit
|
||||
indexes[dims + 1] = m_pAmx->pri;
|
||||
}
|
||||
} else {
|
||||
indexes[0] = m_pAmx->pri;
|
||||
}
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "(array \"%s", pSymbol->name);
|
||||
for (int i=0; i<pSymbol->dim; i++)
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", pDims[i].size);
|
||||
if (_found)
|
||||
{
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (indexed \"");
|
||||
for (int i=0; i<pSymbol->dim; i++)
|
||||
{
|
||||
if (indexes[i] == -1)
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[]");
|
||||
else
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "[%d]", indexes[i]);
|
||||
}
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\")");
|
||||
} else {
|
||||
_size += _snprintf(&(_msgbuf[_size]), sizeof(_msgbuf)-_size, "\") (unknown index \"%d\")", m_pAmx->pri);
|
||||
}
|
||||
found = true;
|
||||
delete [] indexes;
|
||||
delete [] sizes;
|
||||
break;
|
||||
} /* symbol validation */
|
||||
} /* is in valid ranges */
|
||||
if (!found)
|
||||
_msgbuf[0] = '\0';
|
||||
|
||||
size += _snprintf(buffer, maxLength, "%s", _msgbuf);
|
||||
}
|
||||
|
||||
return size;
|
||||
@ -788,15 +556,15 @@ void Debugger::Clear()
|
||||
void Debugger::DisplayTrace(const char *message)
|
||||
{
|
||||
if (message != NULL)
|
||||
AMXXLOG_Log("%s", message);
|
||||
AMXXLOG_Error("%s", message);
|
||||
|
||||
char buffer[512];
|
||||
FormatError(buffer, sizeof(buffer)-1);
|
||||
|
||||
const char *filename = _GetFilename();
|
||||
|
||||
AMXXLOG_Log("[AMXX] Displaying debug trace (plugin \"%s\")", filename);
|
||||
AMXXLOG_Log("[AMXX] %s", buffer);
|
||||
AMXXLOG_Error("[AMXX] Displaying debug trace (plugin \"%s\")", filename);
|
||||
AMXXLOG_Error("[AMXX] %s", buffer);
|
||||
|
||||
int count = 0;
|
||||
long lLine;
|
||||
@ -805,7 +573,7 @@ void Debugger::DisplayTrace(const char *message)
|
||||
while (pTrace)
|
||||
{
|
||||
GetTraceInfo(pTrace, lLine, function, file);
|
||||
AMXXLOG_Log(
|
||||
AMXXLOG_Error(
|
||||
"[AMXX] [%d] %s::%s (line %d)",
|
||||
count,
|
||||
file,
|
||||
@ -840,21 +608,30 @@ const char *Debugger::_GetFilename()
|
||||
void Debugger::FmtGenericMsg(AMX *amx, int error, char buffer[], size_t maxLength)
|
||||
{
|
||||
const char *filename = "";
|
||||
char native[sNAMEMAX+1];
|
||||
|
||||
CList<CScript,AMX*>::iterator a = g_loadedscripts.find(amx);
|
||||
if (a)
|
||||
filename = (*a).getName();
|
||||
size_t len = strlen(filename);
|
||||
for (size_t i=len-1; i>=0; i--)
|
||||
for (size_t i=len-1; i<len; i--)
|
||||
{
|
||||
if (filename[i] == '/' || filename[i] == '\\' && i != len - 1)
|
||||
if ((filename[i] == '/' || filename[i] == '\\') && i != len - 1)
|
||||
{
|
||||
filename = &(filename[i+1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename);
|
||||
if (error == AMX_ERR_EXIT)
|
||||
{
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - %s", error, filename, GenericError(AMX_ERR_EXIT));
|
||||
} else if (error == AMX_ERR_NATIVE) {
|
||||
amx_GetNative(amx, reinterpret_cast<long>(amx->usertags[UT_NATIVE]), native);
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") (native \"%s\") - debug not enabled!", error, filename, native);
|
||||
} else {
|
||||
_snprintf(buffer, maxLength, "Run time error %d (plugin \"%s\") - debug not enabled!", error, filename);
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::GenericMessage(AMX *amx, int err)
|
||||
@ -865,12 +642,14 @@ void Debugger::GenericMessage(AMX *amx, int err)
|
||||
Debugger::FmtGenericMsg(amx, err, buffer, sizeof(buffer)-1);
|
||||
|
||||
if (buffer[0] != '\0')
|
||||
AMXXLOG_Log("[AMXX] %s", buffer);
|
||||
AMXXLOG_Error("[AMXX] %s", buffer);
|
||||
}
|
||||
|
||||
Debugger::~Debugger()
|
||||
{
|
||||
Clear();
|
||||
dbg_FreeInfo(m_pAmxDbg);
|
||||
delete m_pAmxDbg;
|
||||
}
|
||||
|
||||
int Handler::SetErrorHandler(const char *function)
|
||||
@ -879,7 +658,7 @@ int Handler::SetErrorHandler(const char *function)
|
||||
|
||||
error = amx_FindPublic(m_pAmx, function, &m_iErrFunc);
|
||||
|
||||
if (error != AMX_ERR_NONE && m_iErrFunc < 1)
|
||||
if (error != AMX_ERR_NONE && m_iErrFunc < 0)
|
||||
m_iErrFunc = -1;
|
||||
|
||||
return error;
|
||||
@ -891,7 +670,7 @@ int Handler::SetModuleFilter(const char *function)
|
||||
|
||||
error = amx_FindPublic(m_pAmx, function, &m_iModFunc);
|
||||
|
||||
if (error != AMX_ERR_NONE && m_iModFunc < 1)
|
||||
if (error != AMX_ERR_NONE && m_iModFunc < 0)
|
||||
m_iModFunc = -1;
|
||||
|
||||
return error;
|
||||
@ -925,9 +704,9 @@ const char *Handler::GetLastMsg()
|
||||
return m_MsgCache.c_str();
|
||||
}
|
||||
|
||||
int Handler::HandleModule(const char *module)
|
||||
int Handler::HandleModule(const char *module, bool isClass)
|
||||
{
|
||||
if (m_iModFunc < 1)
|
||||
if (m_iModFunc < 0)
|
||||
return 0;
|
||||
|
||||
/**
|
||||
@ -935,14 +714,20 @@ int Handler::HandleModule(const char *module)
|
||||
*/
|
||||
|
||||
cell hea_addr, *phys_addr, retval;
|
||||
Debugger *pd;
|
||||
|
||||
pd = DisableDebugHandler(m_pAmx);
|
||||
|
||||
//temporarily set prenit
|
||||
m_pAmx->flags |= AMX_FLAG_PRENIT;
|
||||
amx_Push(m_pAmx, isClass ? 1 : 0);
|
||||
amx_PushString(m_pAmx, &hea_addr, &phys_addr, module, 0, 0);
|
||||
int err = amx_Exec(m_pAmx, &retval, m_iModFunc);
|
||||
amx_Release(m_pAmx, hea_addr);
|
||||
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
||||
|
||||
EnableDebugHandler(m_pAmx, pd);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
return 0;
|
||||
|
||||
@ -966,6 +751,8 @@ int Handler::HandleNative(const char *native, int index, int trap)
|
||||
|
||||
if (pDebugger && trap)
|
||||
pDebugger->BeginExec();
|
||||
else if (pDebugger && !trap)
|
||||
DisableDebugHandler(m_pAmx);
|
||||
|
||||
cell hea_addr, *phys_addr, retval;
|
||||
|
||||
@ -987,7 +774,7 @@ int Handler::HandleNative(const char *native, int index, int trap)
|
||||
}
|
||||
if (!trap)
|
||||
{
|
||||
AMXXLOG_Log("[AMXX] Runtime failure %d occurred in native filter. Aborting plugin load.", err);
|
||||
AMXXLOG_Error("[AMXX] Runtime failure %d occurred in native filter. Aborting plugin load.", err);
|
||||
return 0;
|
||||
}
|
||||
//handle this manually.
|
||||
@ -998,13 +785,15 @@ int Handler::HandleNative(const char *native, int index, int trap)
|
||||
} else if (err != -1) {
|
||||
LogError(m_pAmx, err, NULL);
|
||||
}
|
||||
AMXXLOG_Log("[AMXX] NOTE: Runtime failures in native filters are not good!");
|
||||
AMXXLOG_Error("[AMXX] NOTE: Runtime failures in native filters are not good!");
|
||||
retval = 0;
|
||||
}
|
||||
if (!trap)
|
||||
m_pAmx->flags &= ~AMX_FLAG_PRENIT;
|
||||
if (pDebugger && trap)
|
||||
pDebugger->EndExec();
|
||||
else if (pDebugger && !trap)
|
||||
EnableDebugHandler(m_pAmx, pDebugger);
|
||||
|
||||
amx_Release(m_pAmx, hea_addr);
|
||||
|
||||
@ -1056,10 +845,10 @@ int Handler::HandleError(const char *msg)
|
||||
pDebugger->DisplayTrace(msg);
|
||||
} else {
|
||||
if (GetLastMsg())
|
||||
AMXXLOG_Log("%s", GetLastMsg());
|
||||
AMXXLOG_Error("%s", GetLastMsg());
|
||||
Debugger::GenericMessage(m_pAmx, err);
|
||||
}
|
||||
AMXXLOG_Log("[AMXX] NOTE: Runtime failures in an error filter are not good!");
|
||||
AMXXLOG_Error("[AMXX] NOTE: Runtime failures in an error filter are not good!");
|
||||
}
|
||||
|
||||
if (pDebugger)
|
||||
@ -1087,7 +876,7 @@ static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
|
||||
if (!pHandler)
|
||||
{
|
||||
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||
AMXXLOG_Log("[AMXX] Plugin not initialized correctly.");
|
||||
AMXXLOG_Error("[AMXX] Plugin not initialized correctly.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1095,7 +884,7 @@ static cell AMX_NATIVE_CALL set_error_filter(AMX *amx, cell *params)
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||
AMXXLOG_Log("[AMXX] Function not found: %s", function);
|
||||
AMXXLOG_Error("[AMXX] Function not found: %s", function);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1175,7 +964,7 @@ static cell AMX_NATIVE_CALL set_native_filter(AMX *amx, cell *params)
|
||||
if (!pHandler)
|
||||
{
|
||||
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||
AMXXLOG_Log("[AMXX] Plugin not initialized correctly.");
|
||||
AMXXLOG_Error("[AMXX] Plugin not initialized correctly.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1194,7 +983,7 @@ static cell AMX_NATIVE_CALL set_native_filter(AMX *amx, cell *params)
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
Debugger::GenericMessage(amx, AMX_ERR_NOTFOUND);
|
||||
AMXXLOG_Log("[AMXX] Function not found: %s", function);
|
||||
AMXXLOG_Error("[AMXX] Function not found: %s", function);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ public:
|
||||
|
||||
struct trace_info
|
||||
{
|
||||
trace_info() : cip(0), frm(0), used(false), next(NULL), prev(NULL) {};
|
||||
trace_info() : cip(0), frm(0), next(NULL), prev(NULL), used(false) {};
|
||||
|
||||
cell cip;
|
||||
cell frm;
|
||||
@ -167,7 +167,7 @@ public:
|
||||
public:
|
||||
int HandleError(const char *msg);
|
||||
int HandleNative(const char *native, int index, int trap);
|
||||
int HandleModule(const char *module);
|
||||
int HandleModule(const char *module, bool isClass=false);
|
||||
public:
|
||||
bool IsHandling() const { return m_Handling; }
|
||||
void SetErrorMsg(const char *msg);
|
||||
@ -176,7 +176,7 @@ public:
|
||||
trace_info_t *GetTrace() const { return m_pTrace; }
|
||||
const char *GetFmtCache() { return m_FmtCache.c_str(); }
|
||||
|
||||
bool IsNativeFiltering() { return (m_iNatFunc > 0); }
|
||||
bool IsNativeFiltering() { return (m_iNatFunc > -1); }
|
||||
bool InNativeFilter() { return m_InNativeFilter; }
|
||||
private:
|
||||
AMX *m_pAmx;
|
||||
|
@ -30,6 +30,7 @@
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "CMenu.h"
|
||||
|
||||
int gmsgAmmoPickup;
|
||||
int gmsgAmmoX;
|
||||
@ -59,10 +60,13 @@ void Client_VGUIMenu(void* mValue)
|
||||
{
|
||||
if (!mPlayer) return;
|
||||
|
||||
mPlayer->vgui = true;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
mPlayer->menu = -(*(int*)mValue);
|
||||
mPlayer->newmenu = -1;
|
||||
break;
|
||||
case 1:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
@ -73,19 +77,26 @@ void Client_ShowMenu(void* mValue)
|
||||
{
|
||||
if (!mPlayer) return;
|
||||
|
||||
mPlayer->vgui = true;
|
||||
|
||||
switch (mState++)
|
||||
{
|
||||
case 0:
|
||||
mPlayer->keys = *(int*)mValue;
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
mPlayer->menu = g_menucmds.findMenuId((char*)mValue);
|
||||
mPlayer->newmenu = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern bool g_bmod_tfc;
|
||||
void Client_TeamInfo(void* mValue)
|
||||
{
|
||||
if (mPlayer) return;
|
||||
if (mPlayer && !g_bmod_tfc) return;
|
||||
static int index;
|
||||
|
||||
switch (mState++)
|
||||
@ -98,6 +109,8 @@ void Client_TeamInfo(void* mValue)
|
||||
char* msg = (char*)mValue;
|
||||
g_players[index].team.assign(msg);
|
||||
g_teamsIds.registerTeam(msg, -1);
|
||||
g_players[index].teamId = g_teamsIds.findTeamId(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -200,9 +213,15 @@ void Client_CurWeapon(void* mValue)
|
||||
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;
|
||||
|
||||
|
||||
if (*(int*)mValue < mPlayer->weapons[iId].clip && // Only update the lastHit vector if the clip size is decreasing
|
||||
*(int*)mValue != -1) // But not if it's a melee weapon
|
||||
{
|
||||
mPlayer->lastHit = mPlayer->lastTrace;
|
||||
}
|
||||
mPlayer->weapons[iId].clip = *(int*)mValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
2910
amxmodx/fakemeta.cpp
2910
amxmodx/fakemeta.cpp
File diff suppressed because it is too large
Load Diff
@ -31,203 +31,7 @@
|
||||
#ifndef __FAKEMETA_H__
|
||||
#define __FAKEMETA_H__
|
||||
|
||||
#ifndef FAKEMETA
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
#else
|
||||
// Fake metamod api for modules
|
||||
|
||||
#include "CList.h"
|
||||
|
||||
// from mplugin.h (metamod)
|
||||
// Flags to indicate current "load" state of plugin.
|
||||
// NOTE: order is important, as greater/less comparisons are made.
|
||||
typedef enum
|
||||
{
|
||||
PL_EMPTY = 0, // empty slot
|
||||
PL_VALID, // has valid info in it
|
||||
PL_BADFILE, // nonexistent file (open failed),
|
||||
// or not a valid plugin file (query failed)
|
||||
PL_OPENED, // dlopened and queried
|
||||
PL_FAILED, // opened, but failed to attach or unattach
|
||||
PL_RUNNING, // attached and running
|
||||
PL_PAUSED, // attached but paused
|
||||
} PLUG_STATUS;
|
||||
|
||||
// from h_export.h (metamod)
|
||||
// Our GiveFnptrsToDll, called by engine.
|
||||
typedef void (WINAPI *GIVE_ENGINE_FUNCTIONS_FN) (enginefuncs_t *pengfuncsFromEngine, globalvars_t *pGlobals);
|
||||
|
||||
// *** CFakeMeta
|
||||
|
||||
class CFakeMeta
|
||||
{
|
||||
private:
|
||||
// Core tables
|
||||
/* DLL_FUNCTIONS m_CoreDllFuncTable;
|
||||
enginefuncs_t m_CoreEngineFuncTable;
|
||||
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable;
|
||||
|
||||
DLL_FUNCTIONS m_CoreDllFuncTable_Post;
|
||||
enginefuncs_t m_CoreEngineFuncTable_Post;
|
||||
NEW_DLL_FUNCTIONS m_CoreNewDllFuncTable_Post; */
|
||||
|
||||
bool AddCorePlugin(); // Adds the core plugin if needed
|
||||
public:
|
||||
class CFakeMetaPlugin
|
||||
{
|
||||
private:
|
||||
// plugin info
|
||||
String m_Path;
|
||||
PLUG_STATUS m_Status;
|
||||
plugin_info_t *m_Info;
|
||||
// Function tables
|
||||
META_FUNCTIONS m_MetaFuncTable;
|
||||
|
||||
DLL_FUNCTIONS m_DllFuncTable;
|
||||
enginefuncs_t m_EngineFuncTable;
|
||||
NEW_DLL_FUNCTIONS m_NewDllFuncTable;
|
||||
|
||||
DLL_FUNCTIONS m_DllFuncTable_Post;
|
||||
enginefuncs_t m_EngineFuncTable_Post;
|
||||
NEW_DLL_FUNCTIONS m_NewDllFuncTable_Post;
|
||||
|
||||
// OS dep handle
|
||||
DLHANDLE m_Handle;
|
||||
public:
|
||||
inline PLUG_STATUS GetStatus() const
|
||||
{ return m_Status; }
|
||||
inline void SetStatus(PLUG_STATUS newStatus)
|
||||
{ m_Status = newStatus; }
|
||||
|
||||
inline plugin_info_t * GetInfo()
|
||||
{ return m_Info; }
|
||||
inline const plugin_info_t * GetInfo() const
|
||||
{ return m_Info; }
|
||||
inline void SetInfo(plugin_info_t *newInfo)
|
||||
{ m_Info = newInfo; }
|
||||
|
||||
inline const char * GetPath()
|
||||
{ return m_Path.c_str(); }
|
||||
|
||||
inline const META_FUNCTIONS &GetMetaFunctions() const
|
||||
{ return m_MetaFuncTable; }
|
||||
|
||||
// Get
|
||||
inline DLL_FUNCTIONS &GetDllFuncTable()
|
||||
{ return m_DllFuncTable; }
|
||||
inline enginefuncs_t &GetEngineFuncTable()
|
||||
{ return m_EngineFuncTable; }
|
||||
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
|
||||
{ return m_NewDllFuncTable; }
|
||||
|
||||
// Get const
|
||||
inline const DLL_FUNCTIONS &GetDllFuncTable() const
|
||||
{ return m_DllFuncTable; }
|
||||
inline const enginefuncs_t &GetEngineFuncTable() const
|
||||
{ return m_EngineFuncTable; }
|
||||
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
|
||||
{ return m_NewDllFuncTable; }
|
||||
|
||||
// Get post
|
||||
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
|
||||
{ return m_DllFuncTable_Post; }
|
||||
inline enginefuncs_t &GetEngineFuncTable_Post()
|
||||
{ return m_EngineFuncTable_Post; }
|
||||
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
|
||||
{ return m_NewDllFuncTable_Post; }
|
||||
|
||||
// Get post const
|
||||
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
|
||||
{ return m_DllFuncTable_Post; }
|
||||
inline const enginefuncs_t &GetEngineFuncTable_Post() const
|
||||
{ return m_EngineFuncTable_Post; }
|
||||
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
|
||||
{ return m_NewDllFuncTable_Post; }
|
||||
|
||||
int Query(mutil_funcs_t *pMetaUtilFuncs); // Also calls GiveFnPtrsToDll
|
||||
int Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGameDllFuncs);
|
||||
int Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
|
||||
int GetEntityAPI2(int interfaceVersion);
|
||||
int GetEntityAPI2_Post(int interfaceVersion);
|
||||
int GetEngineFunctions(int interfaceVersion);
|
||||
int GetEngineFunctions_Post(int interfaceVersion);
|
||||
int GetNewDLLFunctions(int interfaceVersion);
|
||||
int GetNewDLLFunctions_Post(int interfaceVersion);
|
||||
|
||||
CFakeMetaPlugin(const char *path);
|
||||
~CFakeMetaPlugin();
|
||||
}; // CFakeMetaPlugin
|
||||
|
||||
CFakeMeta();
|
||||
~CFakeMeta();
|
||||
|
||||
bool AddPlugin(const char *path /*path relative to moddir*/);
|
||||
void ReleasePlugins();
|
||||
|
||||
// This is public because i don't want to declare all the functions as friends :)
|
||||
// :NOTE: The core is now a special, first plugin!
|
||||
CList<CFakeMetaPlugin> m_Plugins;
|
||||
|
||||
// ****** Meta functions ******
|
||||
// Query all added plugins
|
||||
void Meta_Query(mutil_funcs_t *pMetaUtilFuncs);
|
||||
// Attach all added plugins
|
||||
void Meta_Attach(PLUG_LOADTIME now, meta_globals_t *pMGlobals, gamedll_funcs_t *pGamedllFuncs);
|
||||
// Detach all added plugins
|
||||
void Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
// :NOTE: Meta_Init currently not supported
|
||||
int GetEntityAPI2(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
|
||||
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
|
||||
int GetEntityAPI2_Post(DLL_FUNCTIONS *pFunctionTable /*from metamod*/, int *interfaceVersion /*from metamod*/,
|
||||
DLL_FUNCTIONS *pAMXXFunctionTable /*Functions amxx needs*/);
|
||||
int GetEngineFunctions(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
|
||||
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
|
||||
int GetEngineFunctions_Post(enginefuncs_t *pengfuncsFromEngine, int *interfaceVersion,
|
||||
enginefuncs_t *pAMXXFunctionTable /*Fucntions amxx needs*/);
|
||||
int GetNewDLLFunctions(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
|
||||
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
|
||||
int GetNewDLLFunctions_Post(NEW_DLL_FUNCTIONS *pNewFunctionTable, int *interfaceVersion,
|
||||
NEW_DLL_FUNCTIONS *pAMXXFunctionTable);
|
||||
|
||||
// Get
|
||||
/*inline DLL_FUNCTIONS &GetDllFuncTable()
|
||||
{ return m_CoreDllFuncTable; }
|
||||
inline enginefuncs_t &GetEngineFuncTable()
|
||||
{ return m_CoreEngineFuncTable; }
|
||||
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable()
|
||||
{ return m_CoreNewDllFuncTable; }
|
||||
|
||||
// Get const
|
||||
inline const DLL_FUNCTIONS &GetDllFuncTable() const
|
||||
{ return m_CoreDllFuncTable; }
|
||||
inline const enginefuncs_t &GetEngineFuncTable() const
|
||||
{ return m_CoreEngineFuncTable; }
|
||||
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable() const
|
||||
{ return m_CoreNewDllFuncTable; }
|
||||
|
||||
// Get post
|
||||
inline DLL_FUNCTIONS &GetDllFuncTable_Post()
|
||||
{ return m_CoreDllFuncTable_Post; }
|
||||
inline enginefuncs_t &GetEngineFuncTable_Post()
|
||||
{ return m_CoreEngineFuncTable_Post; }
|
||||
inline NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post()
|
||||
{ return m_CoreNewDllFuncTable_Post; }
|
||||
|
||||
// Get post const
|
||||
inline const DLL_FUNCTIONS &GetDllFuncTable_Post() const
|
||||
{ return m_CoreDllFuncTable_Post; }
|
||||
inline const enginefuncs_t &GetEngineFuncTable_Post() const
|
||||
{ return m_CoreEngineFuncTable_Post; }
|
||||
inline const NEW_DLL_FUNCTIONS &GetNewDllFuncTable_Post() const
|
||||
{ return m_CoreNewDllFuncTable_Post; } */
|
||||
}; // CFakeMeta
|
||||
|
||||
// Fake Metamod
|
||||
// defined in meta_api.cpp
|
||||
extern CFakeMeta g_FakeMeta;
|
||||
|
||||
#endif //FAKEMETA
|
||||
int UnloadMetamodPlugin(void *handle);
|
||||
int LoadMetamodPlugin(const char *path, void **handle, PLUG_LOADTIME now);
|
||||
|
||||
#endif // #ifndef __FAKEMETA_H__
|
||||
|
804
amxmodx/file.cpp
804
amxmodx/file.cpp
@ -5,7 +5,7 @@
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public<EFBFBD> License as published by the
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
@ -43,7 +43,7 @@
|
||||
#endif
|
||||
|
||||
// header file for unlink()
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
@ -51,8 +51,6 @@
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amxmodx.h"
|
||||
|
||||
CVector<FILE *> FileList;
|
||||
@ -141,7 +139,7 @@ static cell AMX_NATIVE_CALL read_file(AMX *amx, cell *params) /* 5 param */
|
||||
|
||||
if ((fp =fopen(build_pathname("%s", szFile), "r")) == NULL)
|
||||
{
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't read file \"%s\"", szFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -185,7 +183,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
{
|
||||
if ((pFile = fopen(sFile, "a")) == NULL)
|
||||
{
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -201,7 +199,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
{
|
||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
||||
{
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -221,7 +219,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
|
||||
if ((pTemp = tmpfile()) == NULL)
|
||||
{
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't create temp file");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -251,7 +249,7 @@ static cell AMX_NATIVE_CALL write_file(AMX *amx, cell *params) /* 3 param */
|
||||
// now rewrite because file can be now smaller...
|
||||
if ((pFile = fopen(sFile, "w")) == NULL)
|
||||
{
|
||||
amx_RaiseError(amx, AMX_ERR_NATIVE);
|
||||
LogError(amx, AMX_ERR_NATIVE, "Couldn't write file \"%s\"", sFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -307,27 +305,7 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
|
||||
char *sFile = get_amxstring(amx, params[1], 0, iLen);
|
||||
char *file = build_pathname("%s", sFile);
|
||||
|
||||
#if defined WIN32 || defined _WIN32
|
||||
DWORD attr = GetFileAttributes(file);
|
||||
|
||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||
return 0;
|
||||
|
||||
if (attr == FILE_ATTRIBUTE_DIRECTORY)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
struct stat s;
|
||||
|
||||
if (stat(file, &s) != 0)
|
||||
return 0;
|
||||
|
||||
if (S_ISDIR(s.st_mode))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
return DirExists(file) ? 1 : 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
||||
@ -378,250 +356,282 @@ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
|
||||
return -1;
|
||||
}
|
||||
|
||||
//ported from Sanji's file access module by BAILOPAN
|
||||
// Important update - now uses new handles
|
||||
static cell AMX_NATIVE_CALL amx_fopen(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int i;
|
||||
int len, j = -1;
|
||||
int len;
|
||||
char *file = build_pathname("%s", get_amxstring(amx, params[1], 1, len));
|
||||
char *flags = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
FILE *fp = fopen(file, flags);
|
||||
|
||||
if (fp == NULL)
|
||||
{
|
||||
// Failed
|
||||
return 0;
|
||||
}
|
||||
return (cell)fp;
|
||||
}
|
||||
|
||||
for (i = 0; i < FileList.size(); i++)
|
||||
static cell AMX_NATIVE_CALL amx_fwrite_blocks(AMX *amx, cell *params)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (FileList.at(i) == NULL)
|
||||
case 1:
|
||||
{
|
||||
j = i;
|
||||
break;
|
||||
char *a = new char[blocks];
|
||||
char *ptr = a;
|
||||
while (btmp--)
|
||||
*ptr++ = 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--)
|
||||
*ptr++ = 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--)
|
||||
*ptr++ = static_cast<int>(*addr++);
|
||||
size_t res = fwrite(a, sizeof(int), blocks, fp);
|
||||
delete [] a;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == -1)
|
||||
{
|
||||
FileList.push_back(fp);
|
||||
j = FileList.size() - 1;
|
||||
} else {
|
||||
FileList.at(j) = fp;
|
||||
}
|
||||
|
||||
return j + 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fclose(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fclose(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fread(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
char *buffer;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
buffer = new char[params[3]]; // SLOW!!! :TODO: Find a better way (auto pointers?)
|
||||
fread(buffer, sizeof(char), params[3], fp);
|
||||
set_amxstring(amx, params[2], buffer, params[3]);
|
||||
delete [] buffer;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fgetc(fp);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fwrite(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
char *buf;
|
||||
int len;
|
||||
|
||||
if (fp)
|
||||
size_t mode = params[3];
|
||||
switch (mode)
|
||||
{
|
||||
buf = format_amxstring(amx, params, 2, len);
|
||||
return fwrite(buf, sizeof(char), strlen(buf), fp);
|
||||
case 1:
|
||||
{
|
||||
char a = static_cast<char>(params[2]);
|
||||
return fwrite(&a, sizeof(char), 1, fp);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
short b = static_cast<short>(params[2]);
|
||||
return fwrite(&b, sizeof(short), 1, fp);
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
int c = static_cast<int>(params[2]);
|
||||
return fwrite(&c, sizeof(int), 1, fp);
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_feof(AMX *amx, cell *params)
|
||||
static cell AMX_NATIVE_CALL amx_fwrite_raw(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
cell *addr = get_amxaddr(amx, params[2]);
|
||||
return fwrite(addr, params[3], params[4], fp);
|
||||
}
|
||||
|
||||
if (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])
|
||||
{
|
||||
if (feof(fp))
|
||||
case 1: //char
|
||||
{
|
||||
return 1;
|
||||
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;
|
||||
}
|
||||
|
||||
return -1;
|
||||
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[4])
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fseek(fp, (long)params[2], params[3]);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fputc(params[2], fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_rewind(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
rewind(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fflush(fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fscanf(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
char *buf;
|
||||
int len;
|
||||
buf = format_amxstring(amx, params, 2, len);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fscanf(fp, "%s", buf);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return fseek(fp, params[2], params[3]);
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_ftell(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return ftell(fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
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;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
{
|
||||
@ -642,164 +652,6 @@ static cell AMX_NATIVE_CALL amx_filesize(AMX *amx, cell *params)
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef UNUSED
|
||||
static cell AMX_NATIVE_CALL amx_fgetl(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
long t;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fread(&t, sizeof(long), 1, fp);
|
||||
return t;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgeti(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
int t;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fread(&t, sizeof(int), 1, fp);
|
||||
return t;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgets(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
short t;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fread(&t, sizeof(short), 1, fp);
|
||||
return t;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputs(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
short size = params[2];
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fwrite(&size, sizeof(short), 1, fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputl(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
long size = params[2];
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fwrite(&size, sizeof(long), 1, fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputi(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
int size = params[2];
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fwrite(&size, sizeof(int), 1, fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fgetf(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
float t;
|
||||
|
||||
if (fp)
|
||||
{
|
||||
fread(&t, sizeof(float), 1, fp);
|
||||
return *(cell*)&t;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fputf(AMX *amx, cell *params)
|
||||
{
|
||||
unsigned int id = params[1] - 1;
|
||||
|
||||
if (id >= FileList.size() || FileList.at(id) == NULL)
|
||||
return 0;
|
||||
|
||||
FILE *fp = FileList.at(id);
|
||||
|
||||
float size = *(float *)((void *)¶ms[2]);
|
||||
|
||||
if (fp)
|
||||
{
|
||||
return fwrite(&size, sizeof(float), 1, fp);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endif //UNUSED
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_build_pathname(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
@ -830,13 +682,13 @@ static cell AMX_NATIVE_CALL amx_open_dir(AMX *amx, cell *params)
|
||||
DIR *dp = opendir(dirname);
|
||||
|
||||
if (!dp)
|
||||
return NULL;
|
||||
return 0;
|
||||
struct dirent *ep = readdir(dp);
|
||||
|
||||
if (!ep)
|
||||
{
|
||||
closedir(dp);
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
set_amxstring(amx, params[2], ep->d_name, params[3]);
|
||||
@ -899,43 +751,153 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
|
||||
#endif
|
||||
}
|
||||
|
||||
//native fgetc( file );
|
||||
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return fgetc(fp);
|
||||
}
|
||||
|
||||
//native fputc( file, data );
|
||||
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return fputc(static_cast<int>(params[2]), fp);
|
||||
}
|
||||
|
||||
//native ungetc( file, data );
|
||||
static cell AMX_NATIVE_CALL amx_ungetc(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
if (!fp)
|
||||
return 0;
|
||||
|
||||
return ungetc(static_cast<int>(params[2]), fp);
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#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 f_old_r[260];
|
||||
char f_new_r[260];
|
||||
|
||||
char *fold = get_amxstring(amx, params[1], 0, len);
|
||||
char *fnew = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
if (params[0] / sizeof(cell) == 3 && params[3])
|
||||
{
|
||||
build_pathname_r(f_old_r, sizeof(f_old_r)-1, "%s", fold);
|
||||
build_pathname_r(f_new_r, sizeof(f_new_r)-1, "%s", fnew);
|
||||
} else {
|
||||
snprintf(f_old_r, sizeof(f_old_r)-1, "%s", fold);
|
||||
snprintf(f_new_r, sizeof(f_new_r)-1, "%s", fnew);
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
return (rename(f_old_r, f_new_r) == 0);
|
||||
#elif defined WIN32
|
||||
return MoveFileA(f_old_r, f_new_r);
|
||||
#endif
|
||||
}
|
||||
|
||||
static cell LoadFileForMe(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *file = get_amxstring(amx, params[1], 0, len);
|
||||
char path[256];
|
||||
|
||||
build_pathname_r(path, sizeof(path), "%s", file);
|
||||
|
||||
byte *addr = LOAD_FILE_FOR_ME(path, &len);
|
||||
if (addr == NULL)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
cell *buffer = get_amxaddr(amx, params[2]);
|
||||
cell maxlength = params[3];
|
||||
cell *bytes_avail = get_amxaddr(amx, params[4]);
|
||||
|
||||
*bytes_avail = len;
|
||||
|
||||
cell count;
|
||||
for (count = 0; count < len && count < maxlength; count++)
|
||||
{
|
||||
buffer[count] = addr[count];
|
||||
}
|
||||
|
||||
FREE_FILE(addr);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL amx_fflush(AMX *amx, cell *params)
|
||||
{
|
||||
FILE *fp = (FILE *)params[1];
|
||||
|
||||
return fflush(fp);
|
||||
}
|
||||
|
||||
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},
|
||||
//Sanji's File Natives
|
||||
{"fopen", amx_fopen},
|
||||
{"fclose", amx_fclose},
|
||||
{"fread", amx_fread},
|
||||
{"filesize", amx_filesize},
|
||||
#ifdef UNUSED
|
||||
{"fgetc", amx_fgetc},
|
||||
{"fwrite", amx_fwrite},
|
||||
{"feof", amx_feof},
|
||||
{"fseek", amx_fseek},
|
||||
{"fputc", amx_fputc},
|
||||
{"rewind", amx_rewind},
|
||||
{"fflush", amx_fflush},
|
||||
{"fscanf", amx_fscanf},
|
||||
{"ftell", amx_ftell},
|
||||
{"fgetl", amx_fgetl},
|
||||
{"fgeti", amx_fgeti},
|
||||
{"fgets", amx_fgets},
|
||||
{"fputs", amx_fputs},
|
||||
{"fputl", amx_fputl},
|
||||
{"fputi", amx_fputi},
|
||||
{"fgetf", amx_fgetf},
|
||||
{"fputf", amx_fputf},
|
||||
#endif
|
||||
{"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},
|
||||
{NULL, NULL}
|
||||
{"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},
|
||||
{"LoadFileForMe", LoadFileForMe},
|
||||
{"fflush", amx_fflush},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -368,7 +368,6 @@ static cell AMX_NATIVE_CALL n_floatatan(AMX *amx, cell *params)
|
||||
* 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);
|
||||
@ -425,6 +424,54 @@ static cell AMX_NATIVE_CALL n_floatatan2(AMX *amx, cell *params)
|
||||
return amx_ftoc(fC);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floatsinh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = sinh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floatcosh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = cosh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
/* Added by DS */
|
||||
static cell AMX_NATIVE_CALL n_floattanh(AMX *amx, cell *params)
|
||||
{
|
||||
/*
|
||||
* params[1] = angle
|
||||
* params[2] = radix
|
||||
*/
|
||||
REAL fA = amx_ctof(params[1]);
|
||||
fA = ToRadians(fA, params[2]);
|
||||
fA = tanh(fA);
|
||||
return amx_ftoc(fA);
|
||||
}
|
||||
|
||||
#if defined __BORLANDC__ || defined __WATCOMC__
|
||||
#pragma argsused
|
||||
#endif
|
||||
@ -457,6 +504,9 @@ AMX_NATIVE_INFO float_Natives[] = {
|
||||
{ "floatacos", n_floatacos },
|
||||
{ "floatatan", n_floatatan },
|
||||
{ "floatatan2", n_floatatan2 },
|
||||
{ "floatsinh", n_floatsinh },
|
||||
{ "floatcosh", n_floatcosh },
|
||||
{ "floattanh", n_floattanh },
|
||||
{ NULL, NULL } /* terminator */
|
||||
};
|
||||
|
||||
|
656
amxmodx/format.cpp
Normal file
656
amxmodx/format.cpp
Normal file
@ -0,0 +1,656 @@
|
||||
#include "amxmodx.h"
|
||||
#include "format.h"
|
||||
#include "datastructs.h"
|
||||
#include "amxmod_compat.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 UPPERDIGITS 0x00000200 /* make alpha digits uppercase */
|
||||
#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; \
|
||||
}
|
||||
|
||||
template size_t atcprintf<cell, cell>(cell *, size_t, const cell *, AMX *, cell *, int *);
|
||||
template size_t atcprintf<char, cell>(char *, size_t, const cell *, AMX *, cell *, int *);
|
||||
template size_t atcprintf<cell, char>(cell *, size_t, const char *, AMX *, cell *, int *);
|
||||
template size_t atcprintf<char, char>(char *, size_t, const char *, AMX *, cell *, int *);
|
||||
|
||||
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, int flags)
|
||||
{
|
||||
int digits; // non-fraction part digits
|
||||
double tmp; // temporary
|
||||
U *buf = *buf_p; // output buffer pointer
|
||||
int val; // temporary
|
||||
int sign = 0; // 0: positive, 1: negative
|
||||
int fieldlength; // for padding
|
||||
int significant_digits = 0; // number of significant digits written
|
||||
const int MAX_SIGNIFICANT_DIGITS = 16;
|
||||
|
||||
// default precision
|
||||
if (prec < 0)
|
||||
{
|
||||
prec = 6;
|
||||
}
|
||||
|
||||
// get the sign
|
||||
if (fval < 0)
|
||||
{
|
||||
fval = -fval;
|
||||
sign = 1;
|
||||
}
|
||||
|
||||
// compute whole-part digits count
|
||||
digits = (int)log10(fval) + 1;
|
||||
|
||||
// Only print 0.something if 0 < fval < 1
|
||||
if (digits < 1)
|
||||
{
|
||||
digits = 1;
|
||||
}
|
||||
|
||||
// compute the field length
|
||||
fieldlength = digits + prec + ((prec > 0) ? 1 : 0) + sign;
|
||||
|
||||
// minus sign BEFORE left padding if padding with zeros
|
||||
if (sign && maxlen && (flags & ZEROPAD))
|
||||
{
|
||||
*buf++ = '-';
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
// right justify if required
|
||||
if ((flags & LADJUST) == 0)
|
||||
{
|
||||
while ((fieldlength < width) && maxlen)
|
||||
{
|
||||
*buf++ = (flags & ZEROPAD) ? '0' : ' ';
|
||||
width--;
|
||||
maxlen--;
|
||||
}
|
||||
}
|
||||
|
||||
// minus sign AFTER left padding if padding with spaces
|
||||
if (sign && maxlen && !(flags & ZEROPAD))
|
||||
{
|
||||
*buf++ = '-';
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
// write the whole part
|
||||
tmp = pow(10.0, digits-1);
|
||||
while ((digits--) && maxlen)
|
||||
{
|
||||
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
||||
{
|
||||
*buf++ = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
val = (int)(fval / tmp);
|
||||
*buf++ = '0' + val;
|
||||
fval -= val * tmp;
|
||||
tmp *= 0.1;
|
||||
}
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
// write the fraction part
|
||||
if (maxlen && prec)
|
||||
{
|
||||
*buf++ = '.';
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
tmp = pow(10.0, prec);
|
||||
|
||||
fval *= tmp;
|
||||
while (prec-- && maxlen)
|
||||
{
|
||||
if (++significant_digits > MAX_SIGNIFICANT_DIGITS)
|
||||
{
|
||||
*buf++ = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp *= 0.1;
|
||||
val = (int)(fval / tmp);
|
||||
*buf++ = '0' + val;
|
||||
fval -= val * tmp;
|
||||
}
|
||||
maxlen--;
|
||||
}
|
||||
|
||||
// left justify if required
|
||||
if (flags & LADJUST)
|
||||
{
|
||||
while ((fieldlength < width) && maxlen)
|
||||
{
|
||||
// right-padding only with spaces, ZEROPAD is ignored
|
||||
*buf++ = ' ';
|
||||
width--;
|
||||
maxlen--;
|
||||
}
|
||||
}
|
||||
|
||||
// update parent's buffer pointer
|
||||
*buf_p = buf;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void AddUInt(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
||||
{
|
||||
U text[32];
|
||||
int digits;
|
||||
U *buf;
|
||||
|
||||
digits = 0;
|
||||
do {
|
||||
text[digits++] = '0' + val % 10;
|
||||
val /= 10;
|
||||
} while (val);
|
||||
|
||||
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 U>
|
||||
void AddInt(U **buf_p, size_t &maxlen, int val, int width, int flags)
|
||||
{
|
||||
U text[32];
|
||||
int digits;
|
||||
int signedVal;
|
||||
U *buf;
|
||||
unsigned int unsignedVal;
|
||||
|
||||
digits = 0;
|
||||
signedVal = val;
|
||||
if (val < 0)
|
||||
{
|
||||
/* we want the unsigned version */
|
||||
unsignedVal = abs(val);
|
||||
} else {
|
||||
unsignedVal = val;
|
||||
}
|
||||
do {
|
||||
text[digits++] = '0' + unsignedVal % 10;
|
||||
unsignedVal /= 10;
|
||||
} while (unsignedVal);
|
||||
|
||||
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 U>
|
||||
void AddHex(U **buf_p, size_t &maxlen, unsigned int val, int width, int flags)
|
||||
{
|
||||
U text[32];
|
||||
int digits;
|
||||
U *buf;
|
||||
U digit;
|
||||
int hexadjust;
|
||||
|
||||
if (flags & UPPERDIGITS)
|
||||
{
|
||||
hexadjust = 'A' - '9' - 1;
|
||||
} else {
|
||||
hexadjust = 'a' - '9' - 1;
|
||||
}
|
||||
|
||||
digits = 0;
|
||||
do
|
||||
{
|
||||
digit = ('0' + val % 16);
|
||||
if (digit > '9')
|
||||
{
|
||||
digit += hexadjust;
|
||||
}
|
||||
|
||||
text[digits++] = digit;
|
||||
val /= 16;
|
||||
} while (val);
|
||||
|
||||
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]));
|
||||
llen--;
|
||||
arg++;
|
||||
break;
|
||||
case 'd':
|
||||
case 'i':
|
||||
CHECK_ARGS(0);
|
||||
AddInt(&buf_p, llen, *get_amxaddr(amx, params[arg]), width, flags);
|
||||
arg++;
|
||||
break;
|
||||
case 'u':
|
||||
CHECK_ARGS(0);
|
||||
AddUInt(&buf_p, llen, static_cast<unsigned int>(*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, flags);
|
||||
arg++;
|
||||
break;
|
||||
case 'X':
|
||||
CHECK_ARGS(0);
|
||||
flags |= UPPERDIGITS;
|
||||
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
|
||||
arg++;
|
||||
break;
|
||||
case 'x':
|
||||
CHECK_ARGS(0);
|
||||
AddHex(&buf_p, llen, static_cast<unsigned int>(*get_amxaddr(amx, params[arg])), width, flags);
|
||||
arg++;
|
||||
break;
|
||||
case 'a':
|
||||
{
|
||||
CHECK_ARGS(0);
|
||||
// %a is passed a pointer directly to a cell string.
|
||||
cell* ptr=reinterpret_cast<cell*>(*get_amxaddr(amx, params[arg]));
|
||||
if (!ptr)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid vector string handle provided (%d)", *get_amxaddr(amx, params[arg]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
AddString(&buf_p, llen, ptr, width, prec);
|
||||
arg++;
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
CHECK_ARGS(0);
|
||||
if (amx->flags & AMX_FLAG_OLDFILE)
|
||||
{
|
||||
cell *addr = get_amxaddr(amx, params[arg]);
|
||||
if (*addr & BCOMPAT_TRANSLATE_BITS)
|
||||
{
|
||||
const char *key, *def;
|
||||
if (!translate_bcompat(amx, addr, &key, &def))
|
||||
{
|
||||
goto break_to_normal_string;
|
||||
}
|
||||
arg++;
|
||||
size_t written = atcprintf(buf_p, llen, def, amx, params, &arg);
|
||||
buf_p += written;
|
||||
llen -= written;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break_to_normal_string:
|
||||
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);
|
||||
}
|
||||
|
11
amxmodx/format.h
Normal file
11
amxmodx/format.h
Normal file
@ -0,0 +1,11 @@
|
||||
#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);
|
||||
|
||||
const char *translate(AMX *amx, cell amxaddr, const char *key);
|
||||
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def);
|
||||
|
||||
#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 = LibType_Library;
|
||||
|
||||
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
|
@ -111,7 +111,7 @@ void MD5::update(FILE *file){
|
||||
unsigned char buffer[1024];
|
||||
int len;
|
||||
|
||||
while (len=fread(buffer, 1, 1024, file))
|
||||
while ((len=fread(buffer, 1, 1024, file)))
|
||||
update(buffer, len);
|
||||
|
||||
fclose (file);
|
||||
@ -185,7 +185,7 @@ unsigned char *MD5::raw_digest(){
|
||||
|
||||
|
||||
|
||||
char *MD5::hex_digest(){
|
||||
const char *MD5::hex_digest(){
|
||||
|
||||
int i;
|
||||
char *s= new char[33];
|
||||
@ -205,7 +205,7 @@ char *MD5::hex_digest(){
|
||||
}
|
||||
|
||||
|
||||
char *MD5::hex_digest(char buffer[33]){
|
||||
const char *MD5::hex_digest(char buffer[33]){
|
||||
|
||||
int i;
|
||||
|
||||
|
@ -59,8 +59,8 @@ public:
|
||||
|
||||
// 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
|
||||
const char *hex_digest (); // digest as a 33-byte ascii-hex string
|
||||
const char *hex_digest (char buffer[33]); //same as above, passing buffer
|
||||
|
||||
|
||||
|
||||
|
835
amxmodx/messages.cpp
Executable file
835
amxmodx/messages.cpp
Executable file
@ -0,0 +1,835 @@
|
||||
#include "amxmodx.h"
|
||||
#include "messages.h"
|
||||
|
||||
Message Msg;
|
||||
//CVector<int> msgHooks[256];
|
||||
RegisteredMessage 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].Hooked()) {
|
||||
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;
|
||||
|
||||
if (inblock)
|
||||
{
|
||||
inblock = false;
|
||||
if (msgBlocks[msgType] == BLOCK_ONCE)
|
||||
{
|
||||
msgBlocks[msgType] = BLOCK_NOT;
|
||||
}
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
} else if (inhook) {
|
||||
|
||||
mres = msgHooks[msgType].Execute((cell)msgType, (cell)msgDest, (cell)ENTINDEX(msgpEntity));
|
||||
|
||||
/*
|
||||
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]].AddHook(id);
|
||||
return id;
|
||||
} else {
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Could not find function \"%s\"", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// unregister_message(msgid, msghandle)
|
||||
static cell AMX_NATIVE_CALL unregister_message(AMX *amx, cell *params)
|
||||
{
|
||||
if (!Msg.Ready())
|
||||
Msg.Init();
|
||||
|
||||
if (params[1]>0 && params[1] < 256)
|
||||
{
|
||||
int id = params[2];
|
||||
if (id != -1)
|
||||
{
|
||||
msgHooks[params[1]].RemoveHook(id);
|
||||
return id;
|
||||
} else {
|
||||
LogError(amx, AMX_ERR_NOTFOUND, "Invalid registered message handle");
|
||||
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},
|
||||
{"unregister_message", unregister_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},
|
||||
};
|
216
amxmodx/messages.h
Executable file
216
amxmodx/messages.h
Executable file
@ -0,0 +1,216 @@
|
||||
#ifndef _MSGS_INCLUDE_H
|
||||
#define _MSGS_INCLUDE_H
|
||||
|
||||
#include <extdll.h>
|
||||
#include <meta_api.h>
|
||||
#include "amx.h"
|
||||
#include "CVector.h"
|
||||
#include "CString.h"
|
||||
#include "sh_stack.h"
|
||||
|
||||
#define MAX_MESSAGES 255
|
||||
|
||||
#define MSGBLOCK_SET 0
|
||||
#define MSGBLOCK_GET 1
|
||||
#define BLOCK_NOT 0
|
||||
#define BLOCK_ONCE 1
|
||||
#define BLOCK_SET 2
|
||||
|
||||
class RegisteredMessage
|
||||
{
|
||||
private:
|
||||
CVector<int> m_Forwards;
|
||||
CStack<int> m_InExecution;
|
||||
bool m_Cleanup;
|
||||
|
||||
public:
|
||||
RegisteredMessage() : m_Cleanup(false) { }
|
||||
~RegisteredMessage() { this->Clear(); }
|
||||
|
||||
void AddHook(int fwd)
|
||||
{
|
||||
m_Forwards.push_back(fwd);
|
||||
}
|
||||
bool RemoveHook(int fwd)
|
||||
{
|
||||
// Don't erase a forward if we're in the middle of execution; this
|
||||
// could throw off the iterator that is going through the forwards
|
||||
// and executing them. Instead, unregister the forward and set it
|
||||
// to -1 from within the vector.
|
||||
if (m_InExecution.size())
|
||||
{
|
||||
this->m_Cleanup = true;
|
||||
|
||||
CVector<int>::iterator iter = m_Forwards.begin();
|
||||
CVector<int>::iterator end = m_Forwards.end();
|
||||
while (iter != end)
|
||||
{
|
||||
if (*iter == fwd)
|
||||
{
|
||||
if (*iter != -1)
|
||||
{
|
||||
unregisterSPForward(*iter);
|
||||
}
|
||||
*iter = -1;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CVector<int>::iterator iter = m_Forwards.begin();
|
||||
CVector<int>::iterator end = m_Forwards.end();
|
||||
while (iter != end)
|
||||
{
|
||||
if (*iter == fwd)
|
||||
{
|
||||
if (fwd != -1)
|
||||
{
|
||||
unregisterSPForward(fwd);
|
||||
|
||||
m_Forwards.erase(iter);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// -1 could be in here more than once
|
||||
m_Forwards.erase(iter);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
while (m_InExecution.size())
|
||||
{
|
||||
m_InExecution.pop();
|
||||
}
|
||||
for (size_t i = 0; i < m_Forwards.size(); i++)
|
||||
{
|
||||
int fwd = m_Forwards[i];
|
||||
|
||||
if (fwd != -1)
|
||||
{
|
||||
unregisterSPForward(m_Forwards[i]);
|
||||
}
|
||||
}
|
||||
|
||||
m_Forwards.clear();
|
||||
}
|
||||
|
||||
cell Execute(cell type, cell dest, cell entity)
|
||||
{
|
||||
m_InExecution.push(1);
|
||||
cell res = 0;
|
||||
cell thisres = 0;
|
||||
for (size_t i = 0; i < m_Forwards.size(); i++)
|
||||
{
|
||||
int fwd = m_Forwards[i];
|
||||
|
||||
if (fwd != -1)
|
||||
{
|
||||
thisres = executeForwards(fwd, type, dest, entity);
|
||||
if (thisres > res)
|
||||
{
|
||||
res = thisres;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
m_InExecution.pop();
|
||||
|
||||
if (m_InExecution.size() == 0 && m_Cleanup)
|
||||
{
|
||||
this->RemoveHook(-1);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
bool Hooked() const
|
||||
{
|
||||
return m_Forwards.size() != 0;
|
||||
}
|
||||
};
|
||||
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 RegisteredMessage msgHooks[256];
|
||||
extern int msgBlocks[256];
|
||||
|
||||
void ClearMessages();
|
||||
|
||||
#endif //_MSGS_INCLUDE_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,116 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004 Jussi Kivilinna
|
||||
*
|
||||
* This file is part of "Metamod All-Mod-Support"-patch for Metamod.
|
||||
*
|
||||
* Metamod is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*
|
||||
* Metamod is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Metamod; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* In addition, as a special exception, the author gives permission to
|
||||
* link the code of this program with the Half-Life Game Engine ("HL
|
||||
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||||
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than the HL Engine and MODs
|
||||
* from Valve. If you modify this file, you may extend this exception
|
||||
* to your version of the file, but you are not obligated to do so. If
|
||||
* you do not wish to do so, delete this exception statement from your
|
||||
* version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MM_PEXTENSIONS_H
|
||||
#define MM_PEXTENSIONS_H
|
||||
|
||||
#include "plinfo.h" // plid_t
|
||||
#include "meta_api.h" // PLUG_LOADTIME
|
||||
/*
|
||||
|
||||
How to use:
|
||||
1. Add new export function 'Meta_PExtGiveFnptrs' to your plugin file.
|
||||
'Meta_PExtGiveFnptrs' will be called right after 'Meta_Query' call.
|
||||
2. Meta_PExtGiveFnptrs is called with interface version 'META_PEXT_VERSION'
|
||||
and pointer to extension function table.
|
||||
3. Meta_PExtGiveFnptrs should return plugin's interface version.
|
||||
4. !NOTE! Metamod will not stop loading plugin even if plugin returns
|
||||
interface version greater than current. Plugin should disable itself in
|
||||
this kind of situation.
|
||||
|
||||
Example:
|
||||
#include "mm_pextensions.h"
|
||||
|
||||
pextension_funcs_t *gpMetaPExtFuncs;
|
||||
|
||||
int Meta_PExtGiveFnptrs(int interfaceVersion, pextension_funcs_t *pMetaPExtFuncs) {
|
||||
if(interfaceVersion < META_PEXT_VERSION) {
|
||||
LOG_DEVELOPER(PLID, "Error! Metamod is too old, please update!");
|
||||
gpMetaPExtFuncs = NULL;
|
||||
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
|
||||
gpMetaPExtFuncs = pMetaPExtFuncs;
|
||||
|
||||
return(META_PEXT_VERSION);
|
||||
}
|
||||
|
||||
Callback functions:
|
||||
- int PEXT_LOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||
Parses 'cmdline' as metamod would parse 'meta load <cmdline>' and loads found
|
||||
plugin. If 'plugin_handle' is set, metamod writes module handle of loaded
|
||||
plugin at it.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
- int PEXT_UNLOAD_PLUGIN_BY_NAME(PLID, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
Parses 'cmdline' as metamod would parse 'meta unload <cmdline>' and
|
||||
unloads found plugin.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
- int PEXT_UNLOAD_PLUGIN_BY_HANDLE(PLID, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
Unloads plugin with 'plugin_handle'.
|
||||
Returns zero on success.
|
||||
For error codes see 'META_ERRNO' in 'types_meta.h'.
|
||||
|
||||
!NOTE! Plugin cannot unload itself!
|
||||
*/
|
||||
|
||||
// Interface version
|
||||
// 1: first version. Used in p13
|
||||
// 2: Complete remake (p14):
|
||||
// pfnLoadMetaPluginByName
|
||||
// pfnUnloadMetaPluginByName
|
||||
// pfnUnloadMetaPluginByHandle
|
||||
// v2 is locked now. Don't modify old functions. If you add new functions, increase META_PEXT_VERSION.
|
||||
#define META_PEXT_VERSION 2
|
||||
|
||||
// Meta PExtension Function table type.
|
||||
typedef struct pextension_funcs_s {
|
||||
int (*pfnLoadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, void **plugin_handle);
|
||||
int (*pfnUnloadMetaPluginByName)(plid_t plid, const char *cmdline, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
int (*pfnUnloadMetaPluginByHandle)(plid_t plid, void *plugin_handle, PLUG_LOADTIME now, PL_UNLOAD_REASON reason);
|
||||
} pextension_funcs_t;
|
||||
|
||||
// Convenience macros for MetaPExtension functions.
|
||||
#define PEXT_LOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnLoadMetaPluginByName)
|
||||
#define PEXT_UNLOAD_PLUGIN_BY_NAME (*gpMetaPExtFuncs->pfnUnloadMetaPluginByName)
|
||||
#define PEXT_UNLOAD_PLUGIN_BY_HANDLE (*gpMetaPExtFuncs->pfnUnloadMetaPluginByHandle)
|
||||
|
||||
// Give plugin extension function table.
|
||||
C_DLLEXPORT int Meta_PExtGiveFnptrs(int interfaceVersion,
|
||||
pextension_funcs_t *pMetaPExtFuncs);
|
||||
typedef int (*META_GIVE_PEXT_FUNCTIONS_FN) (int interfaceVersion,
|
||||
pextension_funcs_t *pMetaPExtFuncs);
|
||||
|
||||
#endif /* MM_PEXTENSIONS_H */
|
1240
amxmodx/modules.cpp
1240
amxmodx/modules.cpp
File diff suppressed because it is too large
Load Diff
@ -35,10 +35,10 @@
|
||||
#include "amx.h"
|
||||
|
||||
#undef DLLEXPORT
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32)
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#define DLLEXPORT __attribute__((visibility("default")))
|
||||
#define WINAPI
|
||||
#endif
|
||||
|
||||
@ -48,7 +48,44 @@
|
||||
#define RELOAD_MODULE 0
|
||||
#define STATIC_MODULE 1
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Player_Name, //String
|
||||
Player_Ip, //String
|
||||
Player_Team, //String
|
||||
Player_Ingame, //bool
|
||||
Player_Authorized, //bool
|
||||
Player_Vgui, //bool
|
||||
Player_Time, //float
|
||||
Player_Playtime, //float
|
||||
Player_MenuExpire, //float
|
||||
Player_Weapons, //struct{int,int}[32]
|
||||
Player_CurrentWeapon, //int
|
||||
Player_TeamID, //int
|
||||
Player_Deaths, //int
|
||||
Player_Aiming, //int
|
||||
Player_Menu, //int
|
||||
Player_Keys, //int
|
||||
Player_Flags, //int[32]
|
||||
Player_Newmenu, //int
|
||||
Player_NewmenuPage, //int
|
||||
} PlayerProp;
|
||||
|
||||
int CheckModules(AMX *amx, char error[128]);
|
||||
bool LoadModule(const char *shortname, PLUG_LOADTIME now, bool simplify=true, bool noFileBail=false);
|
||||
const char *StrCaseStr(const char *as, const char *bs);
|
||||
|
||||
class Debugger;
|
||||
Debugger *DisableDebugHandler(AMX *amx);
|
||||
void EnableDebugHandler(AMX *amx, Debugger *pd);
|
||||
|
||||
bool DirExists(const char *dir);
|
||||
const char* GetFileName(AMX *amx);
|
||||
|
||||
inline cell FloatToCell(float input)
|
||||
{
|
||||
REAL output = input;
|
||||
return *(cell *)&output;
|
||||
}
|
||||
|
||||
#endif // __MODULES_H__
|
||||
|
@ -1,12 +0,0 @@
|
||||
amxmodx.sln
|
||||
amxmodx.suo
|
||||
amxmodx.aps
|
||||
amxmodx.ncb
|
||||
Debug
|
||||
JITDebug
|
||||
JITMemtestRelease
|
||||
JITRelease
|
||||
MaximalSpeed
|
||||
MemtestDebug
|
||||
MemtestRelease
|
||||
Release
|
@ -1,6 +0,0 @@
|
||||
LIBRARY amxx_mm
|
||||
EXPORTS
|
||||
GiveFnptrsToDll @1
|
||||
|
||||
SECTIONS
|
||||
.data READ WRITE
|
@ -1,292 +0,0 @@
|
||||
# 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=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 "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 "amxmodx_mm.mak" CFG="amxmodx_mm - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!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
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "amxmodx_mm - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "release"
|
||||
# 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 "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"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# 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:".\amxmodx_mm.def" /out:"release/amxx_mm.dll" /libpath:"..\extra\lib_win32"
|
||||
# Begin Custom Build
|
||||
TargetPath=.\release\amxx_mm.dll
|
||||
TargetName=amxx_mm
|
||||
InputPath=.\release\amxx_mm.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "amxmodx_mm - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "debug"
|
||||
# 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 "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"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# 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:".\amxmodx_mm.def" /out:"debug/amxx_mm.dll" /pdbtype:sept /libpath:"..\extra\lib_win32"
|
||||
# SUBTRACT LINK32 /incremental:no /nodefaultlib
|
||||
# Begin Custom Build
|
||||
TargetPath=.\debug\amxx_mm.dll
|
||||
TargetName=amxx_mm
|
||||
InputPath=.\debug\amxx_mm.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(TargetName)" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
copy $(TargetPath) D:\SIERRA\Half-Life\cstrike\addons\amx\dlls
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# 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"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amx.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxcore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxmodx.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
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
|
||||
|
||||
SOURCE=..\CEvent.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CFile.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CForward.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CLogEvent.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CMenu.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CMisc.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CModule.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CPlugin.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CString.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CTask.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CVault.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\emsg.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\file.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\float.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\meta_api.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\modules.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\power.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\srvcmd.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\string.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\strptime.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\util.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\vault.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\amxmodx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CCmd.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CEvent.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CFile.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CForward.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CList.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CLogEvent.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CMenu.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CMisc.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CModule.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CPlugin.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CString.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CTask.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\CVault.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\modules.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
@ -1,39 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
JITDebug = JITDebug
|
||||
JITMemtestRelease = JITMemtestRelease
|
||||
JITRelease = JITRelease
|
||||
MaximalSpeed = MaximalSpeed
|
||||
MemtestDebug = MemtestDebug
|
||||
MemtestRelease = MemtestRelease
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.ActiveCfg = Debug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.Build.0 = MemtestDebug|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.ActiveCfg = MemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease.Build.0 = MemtestRelease|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.ActiveCfg = Release|Win32
|
||||
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,874 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="amxmodx"
|
||||
ProjectGUID="{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
|
||||
SccProjectName=""
|
||||
SccLocalPath="">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\debug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\debug/"
|
||||
ObjectFile=".\debug/"
|
||||
ProgramDataBaseFileName=".\debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\JIT\natives-x86.obj ..\zlib\zlib.lib"
|
||||
OutputFile="debug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\debug/amxx_mm.pdb"
|
||||
ImportLibrary=".\debug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\release/amxmodx.pch"
|
||||
AssemblerListingLocation=".\release/"
|
||||
ObjectFile=".\release/"
|
||||
ProgramDataBaseFileName=".\release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
||||
OutputFile="release/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\release/amxx_mm.pdb"
|
||||
ImportLibrary=".\release/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MemtestDebug|Win32"
|
||||
OutputDirectory="MemtestDebug"
|
||||
IntermediateDirectory="MemtestDebug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
StructMemberAlignment="3"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\memtestdebug/amxmodx.pch"
|
||||
AssemblerListingLocation=".\memtestdebug/"
|
||||
ObjectFile=".\memtestdebug/"
|
||||
ProgramDataBaseFileName=".\memtestdebug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
||||
OutputFile="memtestdebug/amxmodx_mm.dll"
|
||||
Version="0.1"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\memtestdebug/amxx_mm.pdb"
|
||||
ImportLibrary=".\memtestdebug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MemtestRelease|Win32"
|
||||
OutputDirectory="MemtestRelease"
|
||||
IntermediateDirectory="MemtestRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\memtestrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\memtestrelease/"
|
||||
ObjectFile=".\memtestrelease/"
|
||||
ProgramDataBaseFileName=".\memtestrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\zlib\zlib.lib ..\JIT\natives-x86.obj"
|
||||
OutputFile="memtestrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="LIBC"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\memtestrelease/amxx_mm.pdb"
|
||||
GenerateMapFile="TRUE"
|
||||
MapExports="TRUE"
|
||||
ImportLibrary=".\memtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITDebug|Win32"
|
||||
OutputDirectory="JITDebug"
|
||||
IntermediateDirectory="JITDebug"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Hry\Half-Life\SDK\Multiplayer Source\pm_shared";"C:\Hry\Half-Life\SDK\Multiplayer Source\dlls";"C:\Hry\Half-Life\SDK\Multiplayer Source\engine";"C:\Hry\Half-Life\SDK\Multiplayer Source\common";C:\Files\Programming\metamod\metamod"
|
||||
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="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitdebug/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitdebug/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\debug/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITRelease|Win32"
|
||||
OutputDirectory="JITRelease"
|
||||
IntermediateDirectory="JITRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
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"
|
||||
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"
|
||||
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/amxx_mm.pdb"
|
||||
GenerateMapFile="FALSE"
|
||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="JITMemtestRelease|Win32"
|
||||
OutputDirectory="JITMemtestRelease"
|
||||
IntermediateDirectory="JITMemtestRelease"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;MEMORY_TEST;JIT;ASM32;PAWN_CELL_SIZE=32"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\jitmemtestrelease/amxmodx.pch"
|
||||
AssemblerListingLocation=".\jitmemtestrelease/"
|
||||
ObjectFile=".\jitmemtestrelease/"
|
||||
ProgramDataBaseFileName=".\jitmemtestrelease/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
|
||||
OutputFile="jitmemtestrelease/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
IgnoreDefaultLibraryNames="MSVCRT"
|
||||
ModuleDefinitionFile=""
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile=".\jitmemtestrelease/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitmemtestrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="MaximalSpeed|Win32"
|
||||
OutputDirectory="MaximalSpeed"
|
||||
IntermediateDirectory="MaximalSpeed"
|
||||
ConfigurationType="2"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GlobalOptimizations="TRUE"
|
||||
InlineFunctionExpansion="1"
|
||||
EnableIntrinsicFunctions="TRUE"
|
||||
FavorSizeOrSpeed="1"
|
||||
OptimizeForProcessor="2"
|
||||
OptimizeForWindowsApplication="TRUE"
|
||||
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="4"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="amxmodx.h"
|
||||
PrecompiledHeaderFile=".\MaximalSpeed/amxmodx.pch"
|
||||
AssemblerListingLocation=".\MaximalSpeed/"
|
||||
ObjectFile=".\MaximalSpeed/"
|
||||
ProgramDataBaseFileName=".\MaximalSpeed/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="TRUE"
|
||||
CompileAs="0"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib ..\jit\jits.lib ..\zlib\zlib.lib"
|
||||
OutputFile="MaximalSpeed/amxmodx_mm.dll"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="TRUE"
|
||||
AdditionalLibraryDirectories="..\extra\lib_win32"
|
||||
ModuleDefinitionFile=""
|
||||
ProgramDatabaseFile=".\MaximalSpeede/amxx_mm.pdb"
|
||||
ImportLibrary=".\jitrelease/amxx_mm.lib"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
MkTypLibCompatible="TRUE"
|
||||
SuppressStartupBanner="TRUE"
|
||||
TargetEnvironment="1"
|
||||
TypeLibraryName=".\release/amxmodx.tlb"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
|
||||
<File
|
||||
RelativePath="..\amx.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxcore.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\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="..\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">
|
||||
<FileConfiguration
|
||||
Name="MemtestDebug|Win32">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
GeneratePreprocessedFile="0"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\file.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\float.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\md5.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meta_api.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\power.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\srvcmd.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\string.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\strptime.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\util.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\vault.cpp">
|
||||
</File>
|
||||
<Filter
|
||||
Name="mmgr"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\mmgr\mmgr.cpp">
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITDebug|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="JITRelease|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MaximalSpeed|Win32"
|
||||
ExcludedFromBuild="TRUE">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl">
|
||||
<File
|
||||
RelativePath="..\amx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxdbg.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxmodx.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxfile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\amxxlog.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CCmd.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CFile.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CForward.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLang.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CList.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CLogEvent.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMenu.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CMisc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CModule.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CPlugin.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CQueue.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\CStack.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="..\md5.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\menus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\modules.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\newmenus.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\resource.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zconf.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\zlib\zlib.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="mmgr"
|
||||
Filter="">
|
||||
<File
|
||||
RelativePath="..\mmgr\mmgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mmgr\nommgr.h">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
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="..\natives-amd64.asm">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\natives-x86.asm">
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
26
amxmodx/msvc10/amxmodx_mm.sln
Normal file
26
amxmodx/msvc10/amxmodx_mm.sln
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx_mm", "amxmodx_mm.vcxproj", "{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
|
439
amxmodx/msvc10/amxmodx_mm.vcxproj
Normal file
439
amxmodx/msvc10/amxmodx_mm.vcxproj
Normal file
@ -0,0 +1,439 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="JITDebugBinLog|Win32">
|
||||
<Configuration>JITDebugBinLog</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="JITDebug|Win32">
|
||||
<Configuration>JITDebug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="JITReleaseBinLog|Win32">
|
||||
<Configuration>JITReleaseBinLog</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="JITRelease|Win32">
|
||||
<Configuration>JITRelease</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}</ProjectGuid>
|
||||
<RootNamespace>amxmodx</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">false</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'">true</LinkIncremental>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">false</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\debug/amxmodx.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(METAMOD)\metamod;$(HLSDK)\multiplayer\common;$(HLSDK)\multiplayer\engine;$(HLSDK)\multiplayer\dlls;$(HLSDK)\multiplayer\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>amxmodx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\jitdebug/amxmodx.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\jitdebug/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\jitdebug/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\jitdebug/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>..\zlib\zlib.lib;..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>0.1</Version>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\extra\lib_win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\jitdebug/amxx_mm.pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>.\jitdebug/amxmodx_mm.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\release/amxmodx.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<AdditionalIncludeDirectories>$(METAMOD)\metamod;$(HLSDK)\multiplayer\common;$(HLSDK)\multiplayer\engine;$(HLSDK)\multiplayer\dlls;$(HLSDK)\multiplayer\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>amxmodx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\jitrelease/amxmodx.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\jitrelease/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\jitrelease/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\jitrelease/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
<ShowIncludes>false</ShowIncludes>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>..\zlib\zlib.lib;..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\extra\lib_win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\jitrelease/amxmodx_mm.pdb</ProgramDatabaseFile>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<ImportLibrary>.\jitrelease/amxmodx_mm.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\debug/amxmodx.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(METAMOD)\metamod;$(HLSDK)\multiplayer\common;$(HLSDK)\multiplayer\engine;$(HLSDK)\multiplayer\dlls;$(HLSDK)\multiplayer\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<StructMemberAlignment>4Bytes</StructMemberAlignment>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>amxmodx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\jitdebugbinlog/amxmodx.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\jitdebugbinlog/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\jitdebugbinlog/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\jitdebugbinlog/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>..\zlib\zlib.lib;..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>0.1</Version>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\extra\lib_win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\jitdebugbinlog/amxmodx_bl_mm.pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>.\jitdebugbinlog/amxmodx_bl_mm.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">
|
||||
<Midl>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MkTypLibCompatible>true</MkTypLibCompatible>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TargetEnvironment>Win32</TargetEnvironment>
|
||||
<TypeLibraryName>.\release/amxmodx.tlb</TypeLibraryName>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<AdditionalIncludeDirectories>$(METAMOD)\metamod;$(HLSDK)\multiplayer\common;$(HLSDK)\multiplayer\engine;$(HLSDK)\multiplayer\dlls;$(HLSDK)\multiplayer\pm_shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<StringPooling>true</StringPooling>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>amxmodx.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>.\jitreleasebinlog/amxmodx.pch</PrecompiledHeaderOutputFile>
|
||||
<AssemblerListingLocation>.\jitreleasebinlog/</AssemblerListingLocation>
|
||||
<ObjectFileName>.\jitreleasebinlog/</ObjectFileName>
|
||||
<ProgramDataBaseFileName>.\jitreleasebinlog/</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<CompileAs>Default</CompileAs>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x0409</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>..\zlib\zlib.lib;..\JIT\amxjitsn.obj;..\JIT\amxexecn.obj;..\JIT\natives-x86.obj;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<AdditionalLibraryDirectories>..\extra\lib_win32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>LIBC;LIBCD;LIBCMTD;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>.\jitreleasebinlog/amxmodx_bl_mm.pdb</ProgramDatabaseFile>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<ImportLibrary>.\jitreleasebinlog/amxmodx_bl_mm.lib</ImportLibrary>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\amx.cpp" />
|
||||
<ClCompile Include="..\amxcore.cpp" />
|
||||
<ClCompile Include="..\amxdbg.cpp" />
|
||||
<ClCompile Include="..\amxmod_compat.cpp" />
|
||||
<ClCompile Include="..\amxmodx.cpp" />
|
||||
<ClCompile Include="..\amxtime.cpp" />
|
||||
<ClCompile Include="..\amxxfile.cpp" />
|
||||
<ClCompile Include="..\amxxlog.cpp" />
|
||||
<ClCompile Include="..\binlog.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CCmd.cpp" />
|
||||
<ClCompile Include="..\CEvent.cpp" />
|
||||
<ClCompile Include="..\CFile.cpp" />
|
||||
<ClCompile Include="..\CFlagManager.cpp" />
|
||||
<ClCompile Include="..\CForward.cpp" />
|
||||
<ClCompile Include="..\CLang.cpp" />
|
||||
<ClCompile Include="..\CLogEvent.cpp" />
|
||||
<ClCompile Include="..\CMenu.cpp" />
|
||||
<ClCompile Include="..\CMisc.cpp" />
|
||||
<ClCompile Include="..\CModule.cpp" />
|
||||
<ClCompile Include="..\CPlugin.cpp" />
|
||||
<ClCompile Include="..\CTask.cpp" />
|
||||
<ClCompile Include="..\CVault.cpp" />
|
||||
<ClCompile Include="..\debugger.cpp" />
|
||||
<ClCompile Include="..\emsg.cpp" />
|
||||
<ClCompile Include="..\fakemeta.cpp" />
|
||||
<ClCompile Include="..\file.cpp" />
|
||||
<ClCompile Include="..\float.cpp" />
|
||||
<ClCompile Include="..\format.cpp">
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libraries.cpp" />
|
||||
<ClCompile Include="..\md5.cpp" />
|
||||
<ClCompile Include="..\messages.cpp" />
|
||||
<ClCompile Include="..\meta_api.cpp" />
|
||||
<ClCompile Include="..\modules.cpp" />
|
||||
<ClCompile Include="..\natives.cpp" />
|
||||
<ClCompile Include="..\newmenus.cpp" />
|
||||
<ClCompile Include="..\nongpl_matches.cpp" />
|
||||
<ClCompile Include="..\optimizer.cpp" />
|
||||
<ClCompile Include="..\power.cpp" />
|
||||
<ClCompile Include="..\sorting.cpp" />
|
||||
<ClCompile Include="..\srvcmd.cpp" />
|
||||
<ClCompile Include="..\string.cpp">
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">All</AssemblerOutput>
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">All</AssemblerOutput>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\strptime.cpp" />
|
||||
<ClCompile Include="..\trie_natives.cpp" />
|
||||
<ClCompile Include="..\util.cpp" />
|
||||
<ClCompile Include="..\vault.cpp" />
|
||||
<ClCompile Include="..\vector.cpp" />
|
||||
<ClCompile Include="..\datastructs.cpp" />
|
||||
<ClCompile Include="..\sdk\amxxmodule.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITDebugBinLog|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITDebug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITReleaseBinLog|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='JITRelease|Win32'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\amx.h" />
|
||||
<ClInclude Include="..\amxdbg.h" />
|
||||
<ClInclude Include="..\amxmod_compat.h" />
|
||||
<ClInclude Include="..\amxmodx.h" />
|
||||
<ClInclude Include="..\amxxfile.h" />
|
||||
<ClInclude Include="..\amxxlog.h" />
|
||||
<ClInclude Include="..\binlog.h" />
|
||||
<ClInclude Include="..\CCmd.h" />
|
||||
<ClInclude Include="..\CEvent.h" />
|
||||
<ClInclude Include="..\CFile.h" />
|
||||
<ClInclude Include="..\CFlagManager.h" />
|
||||
<ClInclude Include="..\CForward.h" />
|
||||
<ClInclude Include="..\CLang.h" />
|
||||
<ClInclude Include="..\CList.h" />
|
||||
<ClInclude Include="..\CLogEvent.h" />
|
||||
<ClInclude Include="..\CMenu.h" />
|
||||
<ClInclude Include="..\CMisc.h" />
|
||||
<ClInclude Include="..\CModule.h" />
|
||||
<ClInclude Include="..\CPlugin.h" />
|
||||
<ClInclude Include="..\CQueue.h" />
|
||||
<ClInclude Include="..\CString.h" />
|
||||
<ClInclude Include="..\CTask.h" />
|
||||
<ClInclude Include="..\CVault.h" />
|
||||
<ClInclude Include="..\CVector.h" />
|
||||
<ClInclude Include="..\datastructs.h" />
|
||||
<ClInclude Include="..\debugger.h" />
|
||||
<ClInclude Include="..\fakemeta.h" />
|
||||
<ClInclude Include="..\format.h" />
|
||||
<ClInclude Include="..\libraries.h" />
|
||||
<ClInclude Include="..\md5.h" />
|
||||
<ClInclude Include="..\messages.h" />
|
||||
<ClInclude Include="..\modules.h" />
|
||||
<ClInclude Include="..\natives.h" />
|
||||
<ClInclude Include="..\newmenus.h" />
|
||||
<ClInclude Include="..\nongpl_matches.h" />
|
||||
<ClInclude Include="..\optimizer.h" />
|
||||
<ClInclude Include="..\resource.h" />
|
||||
<ClInclude Include="..\sh_list.h" />
|
||||
<ClInclude Include="..\sh_stack.h" />
|
||||
<ClInclude Include="..\sh_tinyhash.h" />
|
||||
<ClInclude Include="..\svn_version.h" />
|
||||
<ClInclude Include="..\trie_natives.h" />
|
||||
<ClInclude Include="..\zlib\zconf.h" />
|
||||
<ClInclude Include="..\zlib\zlib.h" />
|
||||
<ClInclude Include="..\sdk\amxxmodule.h" />
|
||||
<ClInclude Include="..\sdk\moduleconfig.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\version.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\amxdefn.asm" />
|
||||
<None Include="..\amxexecn.asm" />
|
||||
<None Include="..\amxjitsn.asm" />
|
||||
<None Include="..\helpers-x86.asm" />
|
||||
<None Include="..\natives-amd64.asm" />
|
||||
<None Include="..\natives-x86.asm" />
|
||||
<None Include="..\..\plugins\include\amxconst.inc" />
|
||||
<None Include="..\..\plugins\include\amxmisc.inc" />
|
||||
<None Include="..\..\plugins\include\amxmodx.inc" />
|
||||
<None Include="..\..\plugins\include\core.inc" />
|
||||
<None Include="..\..\plugins\include\file.inc" />
|
||||
<None Include="..\..\plugins\include\float.inc" />
|
||||
<None Include="..\..\plugins\include\lang.inc" />
|
||||
<None Include="..\..\plugins\include\message_const.inc" />
|
||||
<None Include="..\..\plugins\include\message_stocks.inc" />
|
||||
<None Include="..\..\plugins\include\messages.inc" />
|
||||
<None Include="..\..\plugins\include\sorting.inc" />
|
||||
<None Include="..\..\plugins\include\string.inc" />
|
||||
<None Include="..\..\plugins\include\svn_version.inc" />
|
||||
<None Include="..\..\plugins\include\time.inc" />
|
||||
<None Include="..\..\plugins\include\vault.inc" />
|
||||
<None Include="..\..\plugins\include\vector.inc" />
|
||||
<None Include="..\..\plugins\include\xs.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\amxmod.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\maths.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\mysql.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\translator.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\Vexd_Utilities.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM_const.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM_stock.inc" />
|
||||
<None Include="..\..\plugins\include\amxmod_compat\xtrafun.inc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="..\Jit\helpers-x86.obj" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
426
amxmodx/msvc10/amxmodx_mm.vcxproj.filters
Normal file
426
amxmodx/msvc10/amxmodx_mm.vcxproj.filters
Normal file
@ -0,0 +1,426 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{0d31fe96-c452-4d62-8c7c-0f0f8d69efa8}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{6e1c49c6-6432-4873-bb9a-9d30996955b2}</UniqueIdentifier>
|
||||
<Extensions>h;hpp;hxx;hm;inl</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{721333c3-98b9-4888-a3ec-637a2bd46091}</UniqueIdentifier>
|
||||
<Extensions>rc</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Assembly">
|
||||
<UniqueIdentifier>{e347f4b5-ec94-43d6-b45b-85ab3f146a45}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Assembly\Builds">
|
||||
<UniqueIdentifier>{1cec296a-ddcc-44da-97c4-2a4d0f4d6fc7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="SDK">
|
||||
<UniqueIdentifier>{bbfaec3e-7d17-45ea-8b84-093fa5714022}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Pawn Includes">
|
||||
<UniqueIdentifier>{4022451d-eb5f-4f14-b8d8-2ce23fec6e59}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Pawn Includes\AMX Mod Compat">
|
||||
<UniqueIdentifier>{d4419052-0ddd-415e-bb16-4393b99751be}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\amx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxcore.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxdbg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxmod_compat.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxmodx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxtime.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxxfile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\amxxlog.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\binlog.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CCmd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CFile.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CFlagManager.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CForward.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CLang.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CLogEvent.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CMenu.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CMisc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CModule.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CPlugin.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CTask.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\CVault.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\debugger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\emsg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\fakemeta.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\file.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\float.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\format.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\libraries.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\md5.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\messages.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\meta_api.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\modules.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\natives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\newmenus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\nongpl_matches.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\optimizer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\power.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\sorting.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\srvcmd.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\string.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\strptime.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\trie_natives.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\util.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vault.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\vector.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\datastructs.cpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\sdk\amxxmodule.cpp">
|
||||
<Filter>SDK</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\amx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\amxdbg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\amxmod_compat.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\amxmodx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\amxxfile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\amxxlog.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\binlog.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CCmd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CEvent.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CFile.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CFlagManager.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CForward.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CLang.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CList.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CLogEvent.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CMenu.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CMisc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CModule.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CPlugin.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CQueue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CString.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CTask.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CVault.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\CVector.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\datastructs.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\debugger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\fakemeta.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\format.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\libraries.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\md5.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\messages.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\modules.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\natives.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\newmenus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\nongpl_matches.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\optimizer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sh_list.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sh_stack.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sh_tinyhash.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\svn_version.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\trie_natives.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\zlib\zconf.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\zlib\zlib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sdk\amxxmodule.h">
|
||||
<Filter>SDK</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\sdk\moduleconfig.h">
|
||||
<Filter>SDK</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\version.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\amxdefn.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\amxexecn.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\amxjitsn.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\helpers-x86.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\natives-amd64.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\natives-x86.asm">
|
||||
<Filter>Assembly</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxconst.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmisc.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmodx.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\core.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\file.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\float.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\lang.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\message_const.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\message_stocks.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\messages.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\sorting.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\string.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\svn_version.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\time.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\vault.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\vector.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\xs.inc">
|
||||
<Filter>Pawn Includes</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\amxmod.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\maths.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\mysql.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\translator.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\Vexd_Utilities.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM_const.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\VexdUM_stock.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
<None Include="..\..\plugins\include\amxmod_compat\xtrafun.inc">
|
||||
<Filter>Pawn Includes\AMX Mod Compat</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Object Include="..\Jit\helpers-x86.obj">
|
||||
<Filter>Assembly\Builds</Filter>
|
||||
</Object>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -29,11 +29,17 @@
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "CStack.h"
|
||||
#include "sh_stack.h"
|
||||
#include "natives.h"
|
||||
#include "debugger.h"
|
||||
#include "libraries.h"
|
||||
#include "format.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#if defined(__linux__)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include "sclinux.h"
|
||||
@ -44,12 +50,15 @@
|
||||
// Julien "dJeyL" Laurent
|
||||
|
||||
CVector<regnative *> g_RegNatives;
|
||||
CStack<regnative *> g_NativeStack;
|
||||
CVector<String> g_Libraries;
|
||||
static char g_errorStr[512] = {0};
|
||||
static int g_errorNum = 0;
|
||||
bool g_Initialized = false;
|
||||
|
||||
/* Stack stuff */
|
||||
regnative *g_pCurNative = NULL;
|
||||
AMX *g_pCaller = NULL;
|
||||
cell g_Params[CALLFUNC_MAXPARAMS];
|
||||
int g_CurError = AMX_ERR_NONE;
|
||||
|
||||
int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||
{
|
||||
if (idx < 0 || idx >= (int)g_RegNatives.size())
|
||||
@ -67,39 +76,97 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//parameter stack
|
||||
pNative->caller = amx;
|
||||
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||
CPluginMngr::CPlugin *pNativePlugin = g_plugins.findPluginFast(pNative->amx);
|
||||
|
||||
if (!pNativePlugin->isExecutable(pNative->func))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Called dynanative into a paused plugin.");
|
||||
pPlugin->setStatus(ps_paused);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Save old values on ZE STACK */
|
||||
AMX *pSaveCaller = g_pCaller;
|
||||
cell saveParams[CALLFUNC_MAXPARAMS];
|
||||
regnative *pSaveNative = g_pCurNative;
|
||||
int saveError = g_CurError;
|
||||
|
||||
if (pSaveNative)
|
||||
{
|
||||
for (ucell i = 0; i <= g_Params[0] / sizeof(cell); i++)
|
||||
{
|
||||
saveParams[i] = g_Params[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Save current info */
|
||||
g_CurError = AMX_ERR_NONE;
|
||||
g_pCaller = amx;
|
||||
g_pCurNative = pNative;
|
||||
|
||||
int err = 0;
|
||||
cell ret = 0;
|
||||
g_errorNum = 0;
|
||||
g_NativeStack.push(pNative);
|
||||
if (pNative->style == 0)
|
||||
{
|
||||
amx_Push(pNative->amx, numParams);
|
||||
amx_Push(pNative->amx, pPlugin->getId());
|
||||
for (int i=numParams; i>=1; i--)
|
||||
pNative->params[i] = params[i];
|
||||
for (int i=numParams; i>=0; i--)
|
||||
{
|
||||
g_Params[i] = params[i];
|
||||
}
|
||||
} else if (pNative->style == 1) {
|
||||
//use dJeyL's system .. very clever!
|
||||
/**
|
||||
* use dJeyL's system .. very clever!
|
||||
* NOTE: clever, but doesn't work at all since the JIT does bounds checking
|
||||
* this should REALLY be deprecated
|
||||
*/
|
||||
for (int i=numParams; i>=1; i--)
|
||||
{
|
||||
amx_Push(pNative->amx, params[i]);
|
||||
}
|
||||
}
|
||||
if ( (err=amx_Exec(pNative->amx, &ret, pNative->func)) != AMX_ERR_NONE)
|
||||
|
||||
Debugger *pDebugger = (Debugger *)pNative->amx->userdata[UD_DEBUGGER];
|
||||
if (pDebugger)
|
||||
{
|
||||
g_NativeStack.pop();
|
||||
LogError(pNative->amx, err, "");
|
||||
return 0;
|
||||
pDebugger->BeginExec();
|
||||
}
|
||||
if (g_errorNum)
|
||||
|
||||
err=amx_Exec(pNative->amx, &ret, pNative->func);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
{
|
||||
g_NativeStack.pop();
|
||||
LogError(amx, g_errorNum, g_errorStr);
|
||||
return ret;
|
||||
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_CurError != AMX_ERR_NONE) {
|
||||
LogError(amx, g_CurError, g_errorStr);
|
||||
}
|
||||
|
||||
if (pDebugger)
|
||||
{
|
||||
pDebugger->EndExec();
|
||||
}
|
||||
|
||||
/* Restore everything */
|
||||
g_pCurNative = pSaveNative;
|
||||
g_CurError = saveError;
|
||||
g_pCaller = pSaveCaller;
|
||||
if (pSaveNative)
|
||||
{
|
||||
for (ucell i = 0; i <= saveParams[0] / sizeof(cell); i++)
|
||||
{
|
||||
g_Params[i] = saveParams[i];
|
||||
}
|
||||
}
|
||||
g_NativeStack.pop();
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -107,7 +174,9 @@ int amxx_DynaCallback(int idx, AMX *amx, cell *params)
|
||||
AMX_NATIVE_INFO *BuildNativeTable()
|
||||
{
|
||||
if (g_RegNatives.size() < 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
AMX_NATIVE_INFO *pNatives = new AMX_NATIVE_INFO[g_RegNatives.size() + 1];
|
||||
|
||||
@ -133,7 +202,7 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||
char *err = format_amxstring(amx, params, 2, len);
|
||||
|
||||
_snprintf(g_errorStr, sizeof(g_errorStr), "%s", err);
|
||||
g_errorNum = params[1];
|
||||
g_CurError = params[1];
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -141,13 +210,12 @@ static cell AMX_NATIVE_CALL log_error(AMX *amx, cell *params)
|
||||
//get_string(param, dest[], len)
|
||||
static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
@ -155,20 +223,19 @@ static cell AMX_NATIVE_CALL get_string(AMX *amx, cell *params)
|
||||
int p = params[1];
|
||||
|
||||
int len;
|
||||
char *str = get_amxstring(pNative->caller, pNative->params[p], 0, len);
|
||||
char *str = get_amxstring(g_pCaller, g_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())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
@ -178,46 +245,44 @@ static cell AMX_NATIVE_CALL set_string(AMX *amx, cell *params)
|
||||
int len;
|
||||
char *str = get_amxstring(amx, params[2], 0, len);
|
||||
|
||||
return set_amxstring(pNative->caller, pNative->params[p], str, params[3]);
|
||||
return set_amxstring(g_pCaller, g_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())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
int p = params[1];
|
||||
|
||||
return pNative->params[p];
|
||||
return g_Params[p];
|
||||
}
|
||||
|
||||
//get_param_byref(num)
|
||||
static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->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]);
|
||||
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
||||
|
||||
return addr[0];
|
||||
}
|
||||
@ -225,20 +290,19 @@ static cell AMX_NATIVE_CALL get_param_byref(AMX *amx, cell *params)
|
||||
//set_param_byref(num, val)
|
||||
static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->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]);
|
||||
cell *addr = get_amxaddr(g_pCaller, g_Params[p]);
|
||||
|
||||
addr[0] = params[2];
|
||||
|
||||
@ -248,20 +312,19 @@ static cell AMX_NATIVE_CALL set_param_byref(AMX *amx, cell *params)
|
||||
//get_array(param, dest[], size)
|
||||
static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->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 *source = get_amxaddr(g_pCaller, g_Params[p]);
|
||||
cell *dest = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
@ -274,20 +337,19 @@ static cell AMX_NATIVE_CALL get_array(AMX *amx, cell *params)
|
||||
//set_array(param, source[], size)
|
||||
static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_NativeStack.size())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style)
|
||||
if (g_pCurNative->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 *dest = get_amxaddr(g_pCaller, g_Params[p]);
|
||||
cell *source = get_amxaddr(amx, params[2]);
|
||||
|
||||
int size = params[3];
|
||||
@ -297,26 +359,84 @@ static cell AMX_NATIVE_CALL set_array(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL vdformat(AMX *amx, cell *params)
|
||||
{
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (g_pCurNative->style)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vargPos = static_cast<int>(params[4]);
|
||||
int fargPos = static_cast<int>(params[3]);
|
||||
|
||||
cell max = g_Params[0] / sizeof(cell);
|
||||
if (vargPos > (int)max + 1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid vararg parameter passed: %d", vargPos);
|
||||
return 0;
|
||||
}
|
||||
if (fargPos > (int)max + 1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid fmtarg parameter passed: %d", fargPos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get destination info */
|
||||
cell *fmt;
|
||||
if (fargPos == 0)
|
||||
{
|
||||
if (params[0] / sizeof(cell) != 5)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Expected fmtarg as fifth parameter, found none");
|
||||
return 0;
|
||||
}
|
||||
fmt = get_amxaddr(amx, params[5]);
|
||||
} else {
|
||||
fmt = get_amxaddr(g_pCaller, g_Params[fargPos]);
|
||||
}
|
||||
cell *realdest = get_amxaddr(amx, params[1]);
|
||||
size_t maxlen = static_cast<size_t>(params[2]);
|
||||
cell *dest = realdest;
|
||||
|
||||
/* if this is necessary... */
|
||||
static cell cpbuf[4096];
|
||||
dest = cpbuf;
|
||||
|
||||
/* perform format */
|
||||
size_t total = atcprintf(dest, maxlen, fmt, g_pCaller, g_Params, &vargPos);
|
||||
|
||||
/* copy back */
|
||||
memcpy(realdest, dest, (total+1) * sizeof(cell));
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
//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())
|
||||
if (!g_pCurNative || (g_pCurNative->amx != amx))
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Not currently in a dynamic native");
|
||||
return 0;
|
||||
}
|
||||
regnative *pNative = g_NativeStack.top();
|
||||
if (pNative->style != 1)
|
||||
if (g_pCurNative->style != 1)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Wrong style of dynamic native");
|
||||
return 0;
|
||||
}
|
||||
cell p = params[1];
|
||||
|
||||
AMX *caller = pNative->caller;
|
||||
AMX *caller = g_pCaller;
|
||||
|
||||
unsigned char *data =amx->base+(int)((AMX_HEADER *)amx->base)->dat;
|
||||
unsigned char *realdata = caller->base+(int)((AMX_HEADER *)caller->base)->dat;
|
||||
@ -331,7 +451,7 @@ static cell AMX_NATIVE_CALL register_library(AMX *amx, cell *params)
|
||||
int len;
|
||||
char *lib = get_amxstring(amx, params[1], 0, len);
|
||||
|
||||
AddPluginLibrary(lib);
|
||||
AddLibrary(lib, LibType_Library, LibSource_Plugin, g_plugins.findPluginFast(amx));
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -362,12 +482,16 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
||||
//we'll apply a safety buffer too
|
||||
//make our function
|
||||
int size = amxx_DynaCodesize();
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32)
|
||||
DWORD temp;
|
||||
pNative->pfn = new char[size + 10];
|
||||
VirtualProtect(pNative->pfn, size+10, PAGE_EXECUTE_READWRITE, &temp);
|
||||
#else
|
||||
#elif defined(__GNUC__)
|
||||
# if defined(__APPLE__)
|
||||
pNative->pfn = (char *)valloc(size+10);
|
||||
# else
|
||||
pNative->pfn = (char *)memalign(sysconf(_SC_PAGESIZE), size+10);
|
||||
# endif
|
||||
mprotect((void *)pNative->pfn, size+10, PROT_READ|PROT_WRITE|PROT_EXEC);
|
||||
#endif
|
||||
|
||||
@ -384,27 +508,9 @@ static cell AMX_NATIVE_CALL register_native(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool LibraryExists(const char *name)
|
||||
{
|
||||
for (size_t i=0; i<g_Libraries.size(); i++)
|
||||
{
|
||||
if (stricmp(g_Libraries[i].c_str(), name)==0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddPluginLibrary(const char *name)
|
||||
{
|
||||
String f(name);
|
||||
g_Libraries.push_back(f);
|
||||
}
|
||||
|
||||
void ClearPluginLibraries()
|
||||
{
|
||||
g_Libraries.clear();
|
||||
|
||||
ClearLibraries(LibSource_Plugin);
|
||||
for (size_t i=0; i<g_RegNatives.size(); i++)
|
||||
{
|
||||
delete [] g_RegNatives[i]->pfn;
|
||||
@ -430,6 +536,7 @@ AMX_NATIVE_INFO g_NativeNatives[] = {
|
||||
{"set_float_byref", set_param_byref},
|
||||
{"get_array_f", get_array},
|
||||
{"set_array_f", set_array},
|
||||
{"vdformat", vdformat},
|
||||
{"param_convert", param_convert},
|
||||
//////////////////////////
|
||||
{NULL, NULL},
|
||||
|
@ -32,7 +32,9 @@
|
||||
#define _INCLUDE_NATIVES_H
|
||||
|
||||
//only 16 for now sorry
|
||||
#if !defined CALLFUNC_MAXPARAMS
|
||||
#define CALLFUNC_MAXPARAMS 16
|
||||
#endif
|
||||
|
||||
#define CALLFUNC_FLAG_BYREF 1
|
||||
#define CALLFUNC_FLAG_BYREF_REUSED 2
|
||||
@ -48,9 +50,7 @@ struct regnative
|
||||
String name;
|
||||
char *pfn;
|
||||
int func;
|
||||
AMX *caller;
|
||||
int style;
|
||||
cell params[CALLFUNC_MAXPARAMS];
|
||||
};
|
||||
|
||||
extern "C" void amxx_DynaInit(void *ptr);
|
||||
@ -59,9 +59,7 @@ extern "C" int amxx_DynaFunc(AMX *amx, cell *params);
|
||||
extern "C" int amxx_DynaCodesize();
|
||||
|
||||
AMX_NATIVE_INFO *BuildNativeTable();
|
||||
void AddPluginLibrary(const char *name);
|
||||
void ClearPluginLibraries();
|
||||
bool LibraryExists(const char *name);
|
||||
|
||||
//I couldn't resist :)
|
||||
extern AMX_NATIVE_INFO g_NativeNatives[];
|
||||
|
@ -29,29 +29,93 @@
|
||||
*/
|
||||
|
||||
#include "amxmodx.h"
|
||||
#include "CMenu.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();
|
||||
}
|
||||
}
|
||||
|
||||
Menu::Menu(const char *title, int mid, int tid)
|
||||
void validate_menu_text(char *str)
|
||||
{
|
||||
m_Title.assign(title);
|
||||
menuId = mid;
|
||||
thisId = tid;
|
||||
if (!g_coloredmenus)
|
||||
{
|
||||
size_t offs = 0;
|
||||
while (*str)
|
||||
{
|
||||
if (*str == '\\')
|
||||
{
|
||||
str++;
|
||||
char c = tolower(*str);
|
||||
if (c == 'r' || c == 'w'
|
||||
|| c== 'y' || c == 'd')
|
||||
{
|
||||
str++;
|
||||
offs += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (offs)
|
||||
{
|
||||
*(str-offs) = *str;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
if (offs)
|
||||
{
|
||||
*(str-offs) = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu::Menu(const char *title, AMX *amx, int fid) : m_Title(title), m_ItemColor("\\r"),
|
||||
m_NeverExit(false), m_AutoColors(g_coloredmenus), thisId(0), func(fid),
|
||||
isDestroying(false), items_per_page(7)
|
||||
{
|
||||
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(amx);
|
||||
menuId = g_menucmds.registerMenuId(title, amx);
|
||||
|
||||
if (strcmp(pPlugin->getName(), "war3ft.amxx") == 0)
|
||||
{
|
||||
const char *version = pPlugin->getVersion();
|
||||
if (strncmp(pPlugin->getVersion(), "3.0 RC", 6) == 0
|
||||
&& atoi(&version[6]) <= 8)
|
||||
{
|
||||
g_menucmds.registerMenuCmd(
|
||||
g_plugins.findPluginFast(amx),
|
||||
menuId,
|
||||
-1,
|
||||
g_forwards.duplicateSPForward(fid),
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
m_OptNames[abs(MENU_BACK)].assign("Back");
|
||||
m_OptNames[abs(MENU_MORE)].assign("More");
|
||||
m_OptNames[abs(MENU_EXIT)].assign("Exit");
|
||||
}
|
||||
|
||||
Menu::~Menu()
|
||||
{
|
||||
for (size_t i = 0; i < m_Items.size(); i++)
|
||||
{
|
||||
delete m_Items[i];
|
||||
}
|
||||
|
||||
unregisterSPForward(this->func);
|
||||
|
||||
m_Items.clear();
|
||||
}
|
||||
@ -88,69 +152,144 @@ size_t Menu::GetItemCount()
|
||||
size_t Menu::GetPageCount()
|
||||
{
|
||||
size_t items = GetItemCount();
|
||||
page_t numPages = (items / MENUITEMS) + 1;
|
||||
if (items_per_page == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!items)
|
||||
return 0;
|
||||
|
||||
if (numPages % MENUITEMS == 0)
|
||||
numPages--;
|
||||
|
||||
return numPages;
|
||||
return ((items/items_per_page) + ((items % items_per_page) ? 1 : 0));
|
||||
}
|
||||
|
||||
int Menu::PagekeyToItem(page_t page, item_t key)
|
||||
{
|
||||
page_t pages = GetPageCount();
|
||||
item_t numItems = GetItemCount();
|
||||
size_t start = page * items_per_page;
|
||||
size_t num_pages = GetPageCount();
|
||||
|
||||
if (page >= pages)
|
||||
return MENU_EXIT;
|
||||
|
||||
item_t start = page * 7;
|
||||
|
||||
if (page == 0)
|
||||
if (num_pages == 1 || !items_per_page)
|
||||
{
|
||||
item_t rem = numItems >= 7 ? 7 : numItems;
|
||||
|
||||
if (key == rem)
|
||||
{
|
||||
if (pages > 1)
|
||||
return MENU_MORE;
|
||||
else
|
||||
return MENU_EXIT;
|
||||
}
|
||||
else if (key == rem + 1)
|
||||
if (key > m_Items.size())
|
||||
{
|
||||
return MENU_EXIT;
|
||||
}
|
||||
}
|
||||
else if (page == pages - 1)
|
||||
{
|
||||
//find number of remaining items
|
||||
//for example, 11 items on page 1... means start=7, 11-7=4
|
||||
item_t rem = numItems - start;
|
||||
//however, the last item is actually this -1, so...
|
||||
if (key == rem)
|
||||
{
|
||||
return MENU_EXIT;
|
||||
}
|
||||
else if (key == rem + 1)
|
||||
{
|
||||
return MENU_BACK;
|
||||
} else {
|
||||
return key-1;
|
||||
}
|
||||
} else {
|
||||
if (key == 7)
|
||||
//first page
|
||||
if (page == 0)
|
||||
{
|
||||
return MENU_MORE;
|
||||
}
|
||||
else if (key == 8)
|
||||
{
|
||||
return MENU_BACK;
|
||||
/* The algorithm for spaces here is same as a middle page. */
|
||||
item_t new_key = key;
|
||||
for (size_t i=start; i<(start+key-1) && i<m_Items.size(); i++)
|
||||
{
|
||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
||||
{
|
||||
if (m_Items[i]->blanks[j].EatNumber())
|
||||
{
|
||||
if (!new_key)
|
||||
{
|
||||
break;
|
||||
}
|
||||
new_key--;
|
||||
}
|
||||
if (!new_key)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
key = new_key;
|
||||
if (key == items_per_page + 2)
|
||||
{
|
||||
return MENU_MORE;
|
||||
} else if (key == items_per_page + 3) {
|
||||
return MENU_EXIT;
|
||||
} else {
|
||||
return (start + key - 1);
|
||||
}
|
||||
} else if (page == num_pages - 1) {
|
||||
//last page
|
||||
item_t item_tracker = 0; // tracks how many valid items we have passed so far.
|
||||
size_t remaining = m_Items.size() - start;
|
||||
item_t new_key = key;
|
||||
|
||||
// For every item that takes up a slot (item or padded blank)
|
||||
// we subtract one from new key.
|
||||
// For every item (not blanks), we increase item_tracker.
|
||||
// When new_key equals 0, item_tracker will then be set to
|
||||
// whatever valid item was selected.
|
||||
for (size_t i=m_Items.size() - remaining; i<m_Items.size(); i++)
|
||||
{
|
||||
item_tracker++;
|
||||
|
||||
if (new_key<=1) // If new_key is 0, or will be 0 after the next decrease
|
||||
{
|
||||
new_key=0;
|
||||
break;
|
||||
}
|
||||
|
||||
new_key--;
|
||||
|
||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
||||
{
|
||||
if (m_Items[i]->blanks[j].EatNumber())
|
||||
{
|
||||
new_key--;
|
||||
}
|
||||
if (!new_key)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If new_key doesn't equal zero, then a back/exit button was pressed.
|
||||
if (new_key!=0)
|
||||
{
|
||||
if (key == items_per_page + 1)
|
||||
{
|
||||
return MENU_BACK;
|
||||
}
|
||||
else if (key == items_per_page + 3)
|
||||
{
|
||||
return MENU_EXIT;
|
||||
}
|
||||
// MENU_MORE should never happen here.
|
||||
}
|
||||
// otherwise our item is now start + item_tracker - 1
|
||||
return (start + item_tracker - 1);
|
||||
} else {
|
||||
/* The algorithm for spaces here is a bit harder. We have to subtract
|
||||
* one from the key for each space we find along the way.
|
||||
*/
|
||||
item_t new_key = key;
|
||||
for (size_t i=start; i<(start+items_per_page-1) && i<m_Items.size(); i++)
|
||||
{
|
||||
for (size_t j=0; j<m_Items[i]->blanks.size(); j++)
|
||||
{
|
||||
if (m_Items[i]->blanks[j].EatNumber())
|
||||
{
|
||||
if (!new_key)
|
||||
{
|
||||
break;
|
||||
}
|
||||
new_key--;
|
||||
}
|
||||
if (!new_key)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
key = new_key;
|
||||
if (key > items_per_page && (key-items_per_page<=3))
|
||||
{
|
||||
unsigned int num = key - items_per_page - 1;
|
||||
static int map[] = {MENU_BACK, MENU_MORE, MENU_EXIT};
|
||||
return map[num];
|
||||
} else {
|
||||
return (start + key - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (start + key);
|
||||
}
|
||||
|
||||
bool Menu::Display(int player, page_t page)
|
||||
@ -187,20 +326,51 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
m_Text.clear();
|
||||
|
||||
char buffer[255];
|
||||
if (g_coloredmenus)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
||||
if (items_per_page && (pages != 1))
|
||||
{
|
||||
if (m_AutoColors)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
|
||||
} else {
|
||||
if (m_AutoColors)
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
|
||||
else
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
|
||||
}
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
item_t start = page * 7;
|
||||
item_t end = 0;
|
||||
if (start + 7 <= numItems)
|
||||
enum
|
||||
{
|
||||
end = start + 7;
|
||||
Display_Back = (1<<0),
|
||||
Display_Next = (1<<1),
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
end = numItems;
|
||||
end = numItems - 1;
|
||||
if (end > 10)
|
||||
{
|
||||
end = 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (page == 0)
|
||||
{
|
||||
flags &= ~Display_Back;
|
||||
}
|
||||
|
||||
menuitem *pItem = NULL;
|
||||
@ -209,77 +379,200 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
|
||||
keys = 0;
|
||||
bool enabled = true;
|
||||
int ret = 0;
|
||||
int slots = 0;
|
||||
int option_display = 0;
|
||||
|
||||
for (item_t i = start; i < end; i++)
|
||||
for (item_t i = start; i <= end; i++)
|
||||
{
|
||||
// reset enabled
|
||||
enabled = true;
|
||||
pItem = m_Items[i];
|
||||
|
||||
if (pItem->access && !(pItem->access & g_players[player].flags[0]))
|
||||
{
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
if (pItem->handler != -1)
|
||||
{
|
||||
ret = executeForwards(pItem->handler, player, thisId, i);
|
||||
ret = executeForwards(pItem->handler, static_cast<cell>(player), static_cast<cell>(thisId), static_cast<cell>(i));
|
||||
if (ret == ITEM_ENABLED)
|
||||
{
|
||||
enabled = true;
|
||||
else if (ret == ITEM_DISABLED)
|
||||
} 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)
|
||||
} else if (ret == ITEM_DISABLED) {
|
||||
enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
keys |= (1<<option);
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", ++option, pItem->name.c_str());
|
||||
} else {
|
||||
if (g_coloredmenus)
|
||||
}
|
||||
|
||||
option_display = ++option;
|
||||
if (option_display == 10)
|
||||
{
|
||||
option_display = 0;
|
||||
}
|
||||
|
||||
if (enabled)
|
||||
{
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", ++option, pItem->name.c_str());
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%s%d.\\w %s\n", m_ItemColor.c_str(),option_display, pItem->name.c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option_display, pItem->name.c_str());
|
||||
}
|
||||
} else {
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "\\d%d. %s\n\\w", option_display, pItem->name.c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", pItem->name.c_str());
|
||||
option++;
|
||||
}
|
||||
}
|
||||
slots++;
|
||||
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
|
||||
//now for a weird part >:o
|
||||
//this will either be MORE or BACK..
|
||||
keys |= (1<<option++);
|
||||
if ((page < pages - 1) && (pages > 1))
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "More");
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||
}
|
||||
|
||||
m_Text.append(buffer);
|
||||
|
||||
if (pages > 1)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
if (pages == 0)
|
||||
//attach blanks
|
||||
if (pItem->blanks.size())
|
||||
{
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Exit");
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "%d. %s\n", option, "Back");
|
||||
for (size_t j=0; j<pItem->blanks.size(); j++)
|
||||
{
|
||||
if (pItem->blanks[j].EatNumber())
|
||||
{
|
||||
option++;
|
||||
}
|
||||
m_Text.append(pItem->blanks[j].GetDisplay());
|
||||
m_Text.append("\n");
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (items_per_page)
|
||||
{
|
||||
/* Pad spaces until we reach the end of the max possible items */
|
||||
for (unsigned int i=(unsigned)slots; i<items_per_page; i++)
|
||||
{
|
||||
m_Text.append("\n");
|
||||
option++;
|
||||
}
|
||||
/* Make sure there is at least one visual pad */
|
||||
m_Text.append("\n");
|
||||
|
||||
/* Don't bother if there is only one page */
|
||||
if (pages > 1)
|
||||
{
|
||||
if (flags & Display_Back)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%s%d. \\w%s\n",
|
||||
m_ItemColor.c_str(),
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_BACK)].c_str());
|
||||
} else {
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%d. %s\n",
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_BACK)].c_str());
|
||||
}
|
||||
} else {
|
||||
option++;
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"\\d%d. %s\n\\w",
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_BACK)].c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_BACK)].c_str());
|
||||
}
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
|
||||
if (flags & Display_Next)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%s%d. \\w%s\n",
|
||||
m_ItemColor.c_str(),
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_MORE)].c_str());
|
||||
} else {
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%d. %s\n",
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_MORE)].c_str());
|
||||
}
|
||||
} else {
|
||||
option++;
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"\\d%d. %s\n\\w",
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_MORE)].c_str());
|
||||
} else {
|
||||
_snprintf(buffer, sizeof(buffer)-1, "#. %s\n", m_OptNames[abs(MENU_MORE)].c_str());
|
||||
}
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
} else {
|
||||
/* Keep padding */
|
||||
option += 2;
|
||||
}
|
||||
|
||||
if (!m_NeverExit)
|
||||
{
|
||||
keys |= (1<<option++);
|
||||
if (m_AutoColors)
|
||||
{
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%s%d. \\w%s\n",
|
||||
m_ItemColor.c_str(),
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_EXIT)].c_str());
|
||||
} else {
|
||||
_snprintf(buffer,
|
||||
sizeof(buffer)-1,
|
||||
"%d. %s\n",
|
||||
option == 10 ? 0 : option,
|
||||
m_OptNames[abs(MENU_EXIT)].c_str());
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
m_Text.append(buffer);
|
||||
}
|
||||
|
||||
return m_Text.c_str();
|
||||
}
|
||||
|
||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0) { \
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d", p); \
|
||||
#define GETMENU(p) if (p >= (int)g_NewMenus.size() || p < 0 || !g_NewMenus[p] || g_NewMenus[p]->isDestroying) { \
|
||||
LogError(amx, AMX_ERR_NATIVE, "Invalid menu id %d(%d)", p, g_NewMenus.size()); \
|
||||
return 0; } \
|
||||
Menu *pMenu = g_NewMenus[p];
|
||||
|
||||
@ -289,6 +582,7 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
{
|
||||
int len;
|
||||
char *title = get_amxstring(amx, params[1], 0, len);
|
||||
validate_menu_text(title);
|
||||
char *handler = get_amxstring(amx, params[2], 1, len);
|
||||
|
||||
int func = registerSPForwardByName(amx, handler, FP_CELL, FP_CELL, FP_CELL, FP_DONE);
|
||||
@ -299,13 +593,85 @@ static cell AMX_NATIVE_CALL menu_create(AMX *amx, cell *params)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id = g_menucmds.registerMenuId(title, amx);
|
||||
g_menucmds.registerMenuCmd(g_plugins.findPluginFast(amx), id, 1023, func);
|
||||
Menu *pMenu = new Menu(title, amx, func);
|
||||
|
||||
Menu *pMenu = new Menu(title, id, (int)g_NewMenus.size());
|
||||
g_NewMenus.push_back(pMenu);
|
||||
if (g_MenuFreeStack.empty())
|
||||
{
|
||||
g_NewMenus.push_back(pMenu);
|
||||
pMenu->thisId = (int)g_NewMenus.size() - 1;
|
||||
} else {
|
||||
int pos = g_MenuFreeStack.front();
|
||||
g_MenuFreeStack.pop();
|
||||
g_NewMenus[pos] = pMenu;
|
||||
pMenu->thisId = pos;
|
||||
}
|
||||
|
||||
return (int)g_NewMenus.size() - 1;
|
||||
return pMenu->thisId;
|
||||
}
|
||||
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];
|
||||
|
||||
BlankItem a;
|
||||
|
||||
a.SetBlank();
|
||||
|
||||
if (params[2] == 1)
|
||||
a.SetEatNumber(true);
|
||||
|
||||
else
|
||||
a.SetEatNumber(false);
|
||||
|
||||
item->blanks.push_back(a);
|
||||
|
||||
return 1;
|
||||
}
|
||||
static cell AMX_NATIVE_CALL menu_addtext(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];
|
||||
|
||||
BlankItem a;
|
||||
|
||||
int len;
|
||||
a.SetText(get_amxstring(amx, params[2], 0, len));
|
||||
|
||||
if (params[3] == 1)
|
||||
a.SetEatNumber(true);
|
||||
|
||||
else
|
||||
a.SetEatNumber(false);
|
||||
|
||||
item->blanks.push_back(a);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Adds an item to the menu (returns current item count - 1)
|
||||
@ -318,7 +684,14 @@ static cell AMX_NATIVE_CALL menu_additem(AMX *amx, cell *params)
|
||||
|
||||
GETMENU(params[1]);
|
||||
|
||||
if (!pMenu->items_per_page && pMenu->GetItemCount() >= 10)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Non-paginated menus are limited to 10 items.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
name = get_amxstring(amx, params[2], 0, len);
|
||||
validate_menu_text(name);
|
||||
cmd = get_amxstring(amx, params[3], 1, len);
|
||||
access = params[4];
|
||||
|
||||
@ -354,6 +727,40 @@ static cell AMX_NATIVE_CALL menu_display(AMX *amx, cell *params)
|
||||
|
||||
int player = params[1];
|
||||
int page = params[3];
|
||||
CPlayer* pPlayer = GET_PLAYER_POINTER_I(player);
|
||||
|
||||
/* If the stupid handler keeps drawing menus,
|
||||
* We need to keep cancelling them. But we put in a quick infinite loop
|
||||
* counter to prevent this from going nuts.
|
||||
*/
|
||||
int menu;
|
||||
int loops = 0;
|
||||
while ((menu = pPlayer->newmenu) >= 0)
|
||||
{
|
||||
if ((size_t)menu >= g_NewMenus.size() || !g_NewMenus[menu])
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Menu *pOther = g_NewMenus[menu];
|
||||
|
||||
pPlayer->newmenu = -1;
|
||||
pPlayer->menu = 0;
|
||||
executeForwards(pOther->func,
|
||||
static_cast<cell>(player),
|
||||
static_cast<cell>(pOther->thisId),
|
||||
static_cast<cell>(MENU_EXIT));
|
||||
|
||||
/* Infinite loop counter */
|
||||
if (++loops >= 10)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Plugin called menu_display when item=MENU_EXIT");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// This will set the expire time of the menu to infinite
|
||||
pPlayer->menuexpire = INFINITE;
|
||||
|
||||
return pMenu->Display(player, page);
|
||||
}
|
||||
@ -467,10 +874,211 @@ static cell AMX_NATIVE_CALL menu_item_setcall(AMX *amx, cell *params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
|
||||
{
|
||||
GETMENU(params[1]);
|
||||
|
||||
int len = params[0] / sizeof(cell);
|
||||
if (len < 3)
|
||||
{
|
||||
LogError(amx, AMX_ERR_NATIVE, "Expected 3 parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (params[2])
|
||||
{
|
||||
case MPROP_SET_NUMBER_COLOR:
|
||||
{
|
||||
char *str = get_amxstring(amx, params[3], 0, len);
|
||||
validate_menu_text(str);
|
||||
pMenu->m_ItemColor.assign(str);
|
||||
break;
|
||||
}
|
||||
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);
|
||||
pMenu->m_Title.assign(str);
|
||||
break;
|
||||
}
|
||||
case MPROP_EXITALL:
|
||||
{
|
||||
cell ans = *get_amxaddr(amx, params[3]);
|
||||
if (ans == 1 || ans == 0)
|
||||
{
|
||||
pMenu->m_NeverExit = false;
|
||||
} else if (ans == -1) {
|
||||
pMenu->m_NeverExit = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case MPROP_ORDER:
|
||||
{
|
||||
/* Ignored as of 1.8.0 */
|
||||
break;
|
||||
}
|
||||
case MPROP_NOCOLORS:
|
||||
{
|
||||
pMenu->m_AutoColors = *get_amxaddr(amx, params[3]) ? true : false;
|
||||
break;
|
||||
}
|
||||
case MPROP_PADMENU:
|
||||
{
|
||||
/* Ignored as of 1.8.0 */
|
||||
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;
|
||||
|
||||
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 (params[0] / sizeof(cell) == 4)
|
||||
{
|
||||
cell *addr = get_amxaddr(amx, params[4]);
|
||||
*addr = player->page;
|
||||
}
|
||||
|
||||
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_addtext", menu_addtext},
|
||||
{"menu_pages", menu_pages},
|
||||
{"menu_items", menu_items},
|
||||
{"menu_display", menu_display},
|
||||
@ -480,5 +1088,9 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
|
||||
{"menu_item_setcall", menu_item_setcall},
|
||||
{"menu_item_setcmd", menu_item_setcmd},
|
||||
{"menu_item_setname", menu_item_setname},
|
||||
{"menu_destroy", menu_destroy},
|
||||
{"menu_setprop", menu_setprop},
|
||||
{"menu_cancel", menu_cancel},
|
||||
{"player_menu_info", player_menu_info},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
@ -39,10 +39,61 @@
|
||||
#define ITEM_ENABLED 1
|
||||
#define ITEM_DISABLED 2
|
||||
|
||||
#define MENUITEMS 7
|
||||
#define MAX_MENU_ITEMS 10
|
||||
|
||||
#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
|
||||
#define MPROP_SET_NUMBER_COLOR 10
|
||||
|
||||
typedef int (*MENUITEM_CALLBACK)(int, int, int);
|
||||
|
||||
class BlankItem
|
||||
{
|
||||
private:
|
||||
char *m_text;
|
||||
bool m_num;
|
||||
public:
|
||||
BlankItem() : m_text(NULL), m_num(false) { }
|
||||
BlankItem(BlankItem &src) { this->copyFrom(src); }
|
||||
~BlankItem() { free(m_text); }
|
||||
|
||||
void copyFrom(BlankItem &src)
|
||||
{
|
||||
m_text = src.m_text;
|
||||
m_num = src.m_num;
|
||||
src.m_text = NULL; // stop the src from freeing the buffer
|
||||
}
|
||||
BlankItem &operator = (const BlankItem &src) { this->copyFrom(const_cast<BlankItem&>(src)); return *this; }
|
||||
|
||||
/* is this text instead of a blank */
|
||||
bool IsText() { return m_text != NULL; }
|
||||
|
||||
/* is this a blank instead of text */
|
||||
bool IsBlank() { return m_text == NULL; }
|
||||
|
||||
/* does this item take up a number */
|
||||
bool EatNumber() { return m_num; }
|
||||
|
||||
/* the text this item is to display */
|
||||
const char *GetDisplay() { return m_text == NULL ? "" : m_text; }
|
||||
|
||||
/* sets this item to use a blank */
|
||||
void SetBlank() { free(m_text); m_text = NULL; }
|
||||
|
||||
/* sets this item to display text */
|
||||
void SetText(const char *text) { free(m_text); m_text = strdup(text); }
|
||||
|
||||
/* sets whether or not this item takes up a line */
|
||||
void SetEatNumber(bool val) { m_num = val; }
|
||||
|
||||
};
|
||||
struct menuitem
|
||||
{
|
||||
String name;
|
||||
@ -53,6 +104,8 @@ struct menuitem
|
||||
|
||||
MENUITEM_CALLBACK pfn;
|
||||
size_t id;
|
||||
|
||||
CVector<BlankItem> blanks;
|
||||
};
|
||||
|
||||
typedef unsigned int menu_t;
|
||||
@ -62,7 +115,7 @@ typedef unsigned int page_t;
|
||||
class Menu
|
||||
{
|
||||
public:
|
||||
Menu(const char *title, int menuId, int thisId);
|
||||
Menu(const char *title, AMX *amx, int fid);
|
||||
~Menu();
|
||||
|
||||
menuitem *GetMenuItem(item_t item);
|
||||
@ -75,29 +128,25 @@ public:
|
||||
|
||||
int PagekeyToItem(page_t page, item_t key);
|
||||
int GetMenuMenuid();
|
||||
private:
|
||||
public:
|
||||
CVector<menuitem * > m_Items;
|
||||
|
||||
String m_Title;
|
||||
String m_Text;
|
||||
|
||||
String m_OptNames[4];
|
||||
|
||||
String m_ItemColor;
|
||||
bool m_NeverExit;
|
||||
bool m_AutoColors;
|
||||
|
||||
int menuId;
|
||||
int thisId;
|
||||
int func;
|
||||
bool isDestroying;
|
||||
public:
|
||||
unsigned int items_per_page;
|
||||
};
|
||||
|
||||
/*Menu *CreateMenu(const char *title);
|
||||
Menu *GetMenuById(menu_t menu);
|
||||
menuitem *GetMenuItem(menu_t menu, item_t item);
|
||||
size_t GetMenuPages(menu_t menu);
|
||||
size_t GetMenuItems(menu_t menu);
|
||||
menuitem *AddMenuItem(menu_t menu, const char *name, const char *cmd, int access);
|
||||
bool DisplayMenu(menu_t menu, int player, page_t page);
|
||||
int MenuPagekeyToItem(menu_t menu, page_t page, int key);
|
||||
int FindByMenuid(int menuid);
|
||||
int GetMenuMenuid(menu_t menu);
|
||||
const char *GetItemName(menu_t menu, item_t item);
|
||||
const char *GetItemCmd(menu_t menu, item_t item);*/
|
||||
|
||||
void ClearMenus();
|
||||
|
||||
extern CVector<Menu *> g_NewMenus;
|
||||
|
23
amxmodx/nongpl_matches.cpp
Normal file
23
amxmodx/nongpl_matches.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include <string.h>
|
||||
#include "nongpl_matches.h"
|
||||
|
||||
NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[] =
|
||||
{
|
||||
{"Live", "CZ Gun Game", "czgungame.amxx"},
|
||||
{"Live", "AMXX Gun Game", "czgungame.amxx"},
|
||||
{NULL, NULL, NULL},
|
||||
};
|
||||
|
||||
NONGPL_CVAR_T NONGPL_CVAR_LIST[] =
|
||||
{
|
||||
{"gg_mode", 0},
|
||||
{"gg_warmuptimer", 0},
|
||||
{"gg_ff", 0},
|
||||
{"gg_fflevel", 0},
|
||||
{"gg_stats", 0},
|
||||
{"gg_dm", 0},
|
||||
{"gg_turbo", 0},
|
||||
{"amx_ggreset", 1},
|
||||
{"amx_gg", 1},
|
||||
{NULL, 0},
|
||||
};
|
86
amxmodx/CStack.h → amxmodx/nongpl_matches.h
Executable file → Normal file
86
amxmodx/CStack.h → amxmodx/nongpl_matches.h
Executable file → Normal file
@ -29,77 +29,23 @@
|
||||
* version.
|
||||
*/
|
||||
|
||||
//by David "BAILOPAN" Anderson
|
||||
#ifndef _INCLUDE_CSTACK_H
|
||||
#define _INCLUDE_CSTACK_H
|
||||
#ifndef _INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
||||
#define _INCLUDE_AMXMODX_NONGPL_MATCHES_H_
|
||||
|
||||
template <class T>
|
||||
class CStack
|
||||
struct NONGPL_PLUGIN_T
|
||||
{
|
||||
public:
|
||||
struct CStackItem
|
||||
{
|
||||
public:
|
||||
T item;
|
||||
CStackItem *prev;
|
||||
};
|
||||
|
||||
public:
|
||||
CStack()
|
||||
{
|
||||
mSize = 0;
|
||||
mStack = NULL;
|
||||
}
|
||||
|
||||
~CStack()
|
||||
{
|
||||
CStackItem *p, *t;
|
||||
p = mStack;
|
||||
|
||||
while (p)
|
||||
{
|
||||
t = p->prev;
|
||||
delete p;
|
||||
p = t;
|
||||
}
|
||||
|
||||
mStack = NULL;
|
||||
}
|
||||
|
||||
bool empty()
|
||||
{
|
||||
return (mSize == 0);
|
||||
}
|
||||
|
||||
void push(const T & v)
|
||||
{
|
||||
CStackItem *p = new CStackItem;
|
||||
p->item = v;
|
||||
p->prev = mStack;
|
||||
mStack = p;
|
||||
mSize++;
|
||||
}
|
||||
|
||||
void pop()
|
||||
{
|
||||
CStackItem *p = mStack;
|
||||
mStack = p->prev;
|
||||
delete p;
|
||||
mSize--;
|
||||
}
|
||||
|
||||
T & top()
|
||||
{
|
||||
return mStack->item;
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
private:
|
||||
CStackItem *mStack;
|
||||
size_t mSize;
|
||||
const char *author;
|
||||
const char *title;
|
||||
const char *filename;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_CQUEUE_H
|
||||
struct NONGPL_CVAR_T
|
||||
{
|
||||
const char *cvar;
|
||||
int type;
|
||||
};
|
||||
|
||||
extern NONGPL_PLUGIN_T NONGPL_PLUGIN_LIST[];
|
||||
extern NONGPL_CVAR_T NONGPL_CVAR_LIST[];
|
||||
|
||||
#endif //_INCLUDE_AMXMODX_NONGPL_MATCHES_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
|
@ -39,6 +39,10 @@
|
||||
#include <endian.h>
|
||||
#endif
|
||||
|
||||
#if defined __APPLE__
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Linux NOW has these */
|
||||
#if !defined BIG_ENDIAN
|
||||
#define BIG_ENDIAN 4321
|
||||
|
@ -20,10 +20,10 @@
|
||||
#define stricmp(a,b) strcasecmp(a,b)
|
||||
#define strnicmp(a,b,c) strncasecmp(a,b,c)
|
||||
|
||||
#if defined __linux__ && !defined _snprintf
|
||||
#if ( defined(__linux__) || defined(__APPLE__) ) && !defined _snprintf
|
||||
#define _snprintf snprintf
|
||||
#endif
|
||||
#if defined __linux__ && !defined _vsnprintf
|
||||
#if ( defined(__linux__) || defined(__APPLE__) ) && !defined _vsnprintf
|
||||
//#define _vsnprintf vsnprintf
|
||||
#endif
|
||||
|
||||
@ -40,6 +40,10 @@
|
||||
*/
|
||||
#if !defined __BYTE_ORDER
|
||||
# include <stdlib.h>
|
||||
# if defined __APPLE__
|
||||
# include <sys/types.h>
|
||||
# define __BYTE_ORDER BYTE_ORDER
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined __OpenBSD__
|
||||
|
@ -2240,7 +2240,7 @@ static META_FUNCTIONS g_MetaFunctions_Table =
|
||||
GetEngineFunctions_Post
|
||||
};
|
||||
|
||||
C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
|
||||
C_DLLEXPORT int Meta_Query(const char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t *pMetaUtilFuncs)
|
||||
{
|
||||
if ((int) CVAR_GET_FLOAT("developer") != 0)
|
||||
UTIL_LogPrintf("[%s] dev: called: Meta_Query; version=%s, ours=%s\n",
|
||||
@ -2284,7 +2284,7 @@ C_DLLEXPORT int Meta_Query(char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_
|
||||
}
|
||||
|
||||
#ifdef FN_META_QUERY
|
||||
return FN_META_QUERY();
|
||||
FN_META_QUERY();
|
||||
#endif // FN_META_QUERY
|
||||
|
||||
return 1;
|
||||
@ -2327,14 +2327,14 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
|
||||
}
|
||||
|
||||
#ifdef FN_META_DETACH
|
||||
return FN_META_DETACH();
|
||||
FN_META_DETACH();
|
||||
#endif // FN_META_DETACH
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
// linux prototype
|
||||
C_DLLEXPORT void GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals ) {
|
||||
|
||||
@ -2374,7 +2374,7 @@ C_DLLEXPORT void __stdcall GiveFnptrsToDll( enginefuncs_t* pengfuncsFromEngine,
|
||||
gpGlobals = pGlobals;
|
||||
// NOTE! Have to call logging function _after_ copying into g_engfuncs, so
|
||||
// that g_engfuncs.pfnAlertMessage() can be resolved properly, heh. :)
|
||||
UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag);
|
||||
// UTIL_LogPrintf("[%s] dev: called: GiveFnptrsToDll\n", Plugin_info.logtag);
|
||||
// --> ** Function core
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -2430,11 +2430,14 @@ static amxx_module_info_s g_ModuleInfo =
|
||||
#else // MODULE_RELOAD_ON_MAPCHANGE
|
||||
0,
|
||||
#endif // MODULE_RELOAD_ON_MAPCHANGE
|
||||
MODULE_LOGTAG
|
||||
MODULE_LOGTAG,
|
||||
MODULE_LIBRARY,
|
||||
MODULE_LIBCLASS
|
||||
};
|
||||
|
||||
// Storage for the requested functions
|
||||
PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
||||
PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
@ -2502,6 +2505,18 @@ PFN_FORMAT g_fn_Format;
|
||||
PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||
PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||
PFN_AMX_PUSH g_fn_AmxPush;
|
||||
PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
||||
PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||
PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||
PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||
PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||
PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||
PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||
PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
||||
PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
||||
PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
||||
PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
||||
PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
||||
|
||||
// *** Exports ***
|
||||
C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo)
|
||||
@ -2533,6 +2548,14 @@ C_DLLEXPORT int AMXX_Query(int *interfaceVersion, amxx_module_info_s *moduleInfo
|
||||
// request optional function
|
||||
#define REQFUNC_OPT(name, fptr, type) fptr = (type)reqFnptrFunc(name)
|
||||
|
||||
C_DLLEXPORT int AMXX_CheckGame(const char *game)
|
||||
{
|
||||
#ifdef FN_AMXX_CHECKGAME
|
||||
return FN_AMXX_CHECKGAME(game);
|
||||
#else
|
||||
return AMXX_GAME_OK;
|
||||
#endif
|
||||
}
|
||||
C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
{
|
||||
// Check pointer
|
||||
@ -2552,6 +2575,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
REQFUNC("MergeDefinitionFile", g_fn_MergeDefinition_File, PFN_MERGEDEFINITION_FILE);
|
||||
REQFUNC("Format", g_fn_Format, PFN_FORMAT);
|
||||
REQFUNC("RegisterFunction", g_fn_RegisterFunction, PFN_REGISTERFUNCTION);
|
||||
REQFUNC("RegisterFunctionEx", g_fn_RegisterFunctionEx, PFN_REGISTERFUNCTIONEX);
|
||||
|
||||
// Amx scripts
|
||||
REQFUNC("GetAmxScript", g_fn_GetAmxScript, PFN_GET_AMXSCRIPT);
|
||||
@ -2577,6 +2601,7 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
|
||||
// Natives / Forwards
|
||||
REQFUNC("AddNatives", g_fn_AddNatives, PFN_ADD_NATIVES);
|
||||
REQFUNC("AddNewNatives", g_fn_AddNewNatives, PFN_ADD_NEW_NATIVES);
|
||||
REQFUNC("RaiseAmxError", g_fn_RaiseAmxError, PFN_RAISE_AMXERROR);
|
||||
REQFUNC("RegisterForward", g_fn_RegisterForward, PFN_REGISTER_FORWARD);
|
||||
REQFUNC("RegisterSPForward", g_fn_RegisterSPForward, PFN_REGISTER_SPFORWARD);
|
||||
@ -2611,6 +2636,20 @@ C_DLLEXPORT int AMXX_Attach(PFN_REQ_FNPTR reqFnptrFunc)
|
||||
REQFUNC("GetPlayerFlags", g_fn_GetPlayerFlags, PFN_GETPLAYERFLAGS);
|
||||
REQFUNC("GetPlayerEdict", g_fn_GetPlayerEdict, PFN_GET_PLAYER_EDICT);
|
||||
REQFUNC("amx_Push", g_fn_AmxPush, PFN_AMX_PUSH);
|
||||
REQFUNC("SetPlayerTeamInfo", g_fn_SetTeamInfo, PFN_SET_TEAM_INFO);
|
||||
REQFUNC("PlayerPropAddr", g_fn_PlayerPropAddr, PFN_PLAYER_PROP_ADDR);
|
||||
REQFUNC("RegAuthFunc", g_fn_RegAuthFunc, PFN_REG_AUTH_FUNC);
|
||||
REQFUNC("UnregAuthFunc", g_fn_UnregAuthFunc, PFN_UNREG_AUTH_FUNC);
|
||||
|
||||
//Added in 1.75
|
||||
REQFUNC("FindLibrary", g_fn_FindLibrary, PFN_FINDLIBRARY);
|
||||
REQFUNC("AddLibraries", g_fn_AddLibraries, PFN_ADDLIBRARIES);
|
||||
REQFUNC("RemoveLibraries", g_fn_RemoveLibraries, PFN_REMOVELIBRARIES);
|
||||
REQFUNC("OverrideNatives", g_fn_OverrideNatives, PFN_OVERRIDENATIVES);
|
||||
REQFUNC("GetLocalInfo", g_fn_GetLocalInfo, PFN_GETLOCALINFO);
|
||||
REQFUNC("AmxReregister", g_fn_AmxReRegister, PFN_AMX_REREGISTER);
|
||||
|
||||
REQFUNC("MessageBlock", g_fn_MessageBlock, PFN_MESSAGE_BLOCK);
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
// Memory
|
||||
@ -2646,14 +2685,27 @@ C_DLLEXPORT int AMXX_PluginsLoaded()
|
||||
return AMXX_OK;
|
||||
}
|
||||
|
||||
C_DLLEXPORT void AMXX_PluginsUnloaded()
|
||||
{
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||
FN_AMXX_PLUGINSUNLOADED();
|
||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||
}
|
||||
|
||||
C_DLLEXPORT void AMXX_PluginsUnloading()
|
||||
{
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||
FN_AMXX_PLUGINSUNLOADING();
|
||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||
}
|
||||
|
||||
// Advanced MF functions
|
||||
void MF_Log(const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_Log("[%s] %s", MODULE_LOGTAG, msg);
|
||||
@ -2661,11 +2713,10 @@ void MF_Log(const char *fmt, ...)
|
||||
|
||||
void MF_LogError(AMX *amx, int err, const char *fmt, ...)
|
||||
{
|
||||
// :TODO: Overflow possible here
|
||||
char msg[3072];
|
||||
va_list arglst;
|
||||
va_start(arglst, fmt);
|
||||
vsprintf(msg, fmt, arglst);
|
||||
vsnprintf(msg, sizeof(msg) - 1, fmt, arglst);
|
||||
va_end(arglst);
|
||||
|
||||
g_fn_LogErrorFunc(amx, err, "[%s] %s", MODULE_LOGTAG, msg);
|
||||
@ -2733,6 +2784,16 @@ void ValidateMacros_DontCallThis_Smiley()
|
||||
MF_GetPlayerEdict(0);
|
||||
MF_Format("", 4, "str");
|
||||
MF_RegisterFunction(NULL, "");
|
||||
MF_RegisterFunctionEx(NULL, "");
|
||||
MF_SetPlayerTeamInfo(0, 0, "");
|
||||
MF_PlayerPropAddr(0, 0);
|
||||
MF_RegAuthFunc(NULL);
|
||||
MF_UnregAuthFunc(NULL);
|
||||
MF_FindLibrary(NULL, LibType_Class);
|
||||
MF_AddLibraries(NULL, LibType_Class, NULL);
|
||||
MF_RemoveLibraries(NULL);
|
||||
MF_OverrideNatives(NULL, NULL);
|
||||
MF_MessageBlock(0, 0, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -2912,20 +2973,20 @@ void operator delete[](void *reportedAddress)
|
||||
#else
|
||||
|
||||
#if !defined NO_ALLOC_OVERRIDES && !defined MEMORY_TEST && !defined WIN32
|
||||
void * ::operator new(size_t size) {
|
||||
void * operator new(size_t size) {
|
||||
return(calloc(1, size));
|
||||
}
|
||||
|
||||
void * ::operator new[](size_t size) {
|
||||
void * operator new[](size_t size) {
|
||||
return(calloc(1, size));
|
||||
}
|
||||
|
||||
void ::operator delete(void * ptr) {
|
||||
void operator delete(void * ptr) {
|
||||
if(ptr)
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void ::operator delete[](void * ptr) {
|
||||
void operator delete[](void * ptr) {
|
||||
if(ptr)
|
||||
free(ptr);
|
||||
}
|
||||
@ -2989,7 +3050,7 @@ char* UTIL_VarArgs( char *format, ... )
|
||||
// UTIL_LogPrintf - Prints a logged message to console.
|
||||
// Preceded by LOG: ( timestamp ) < message >
|
||||
//=========================================================
|
||||
void UTIL_LogPrintf( char *fmt, ... )
|
||||
void UTIL_LogPrintf( const char *fmt, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[1024];
|
||||
|
@ -10,6 +10,7 @@
|
||||
// config
|
||||
#include "moduleconfig.h"
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
// metamod include files
|
||||
#ifdef USE_METAMOD
|
||||
#include <extdll.h>
|
||||
@ -19,11 +20,16 @@
|
||||
|
||||
// DLL Export
|
||||
#undef DLLEXPORT
|
||||
#ifndef __linux__
|
||||
#if defined(_WIN32)
|
||||
#define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define DLLEXPORT
|
||||
#define DLLEXPORT __attribute__((visibility("default")))
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX)
|
||||
#define LINUX
|
||||
#elif defined(__APPLE__) && !defined(OSX)
|
||||
#define OSX
|
||||
#endif
|
||||
|
||||
#undef C_DLLEXPORT
|
||||
@ -34,7 +40,8 @@
|
||||
// module interface version was 1
|
||||
// 2 - added logtag to struct (amxx1.1-rc1)
|
||||
// 3 - added new tagAMX structure (amxx1.5)
|
||||
#define AMXX_INTERFACE_VERSION 3
|
||||
// 4 - added new 'library' setting for direct loading
|
||||
#define AMXX_INTERFACE_VERSION 4
|
||||
|
||||
// amxx module info
|
||||
struct amxx_module_info_s
|
||||
@ -44,6 +51,8 @@ struct amxx_module_info_s
|
||||
const char *version;
|
||||
int reload; // reload on mapchange when nonzero
|
||||
const char *logtag; // added in version 2
|
||||
const char *library; // added in version 4
|
||||
const char *libclass; // added in version 4
|
||||
};
|
||||
|
||||
// return values from functions called by amxx
|
||||
@ -52,6 +61,9 @@ struct amxx_module_info_s
|
||||
#define AMXX_PARAM 2 /* Invalid parameter */
|
||||
#define AMXX_FUNC_NOT_PRESENT 3 /* Function not present */
|
||||
|
||||
#define AMXX_GAME_OK 0 /* This module can load on the current game mod. */
|
||||
#define AMXX_GAME_BAD 1 /* This module can not load on the current game mod. */
|
||||
|
||||
// *** Small stuff ***
|
||||
// The next section is copied from the amx.h file
|
||||
// Copyright (c) ITB CompuPhase, 1997-2005
|
||||
@ -59,7 +71,7 @@ struct amxx_module_info_s
|
||||
#if defined HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX
|
||||
#if defined __LCC__ || defined __DMC__ || defined LINUX || defined __APPLE__
|
||||
#if defined HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
@ -153,9 +165,137 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
#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" */
|
||||
#pragma warning(disable:4103) /* disable warning message 4103 that complains
|
||||
* about pragma pack in a header file */
|
||||
#pragma warning(disable:4100) /* "'%$S' : unreferenced formal parameter" */
|
||||
|
||||
#if _MSC_VER >= 1400
|
||||
#if !defined NO_MSVC8_AUTO_COMPAT
|
||||
|
||||
/* Disable deprecation warnings concerning unsafe CRT functions */
|
||||
#if !defined _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
/* Replace the POSIX function with ISO C++ conformant ones as they are now deprecated */
|
||||
#define access _access
|
||||
#define cabs _cabs
|
||||
#define cgets _cgets
|
||||
#define chdir _chdir
|
||||
#define chmod _chmod
|
||||
#define chsize _chsize
|
||||
#define close _close
|
||||
#define cprintf _cprintf
|
||||
#define cputs _cputts
|
||||
#define creat _creat
|
||||
#define cscanf _cscanf
|
||||
#define cwait _cwait
|
||||
#define dup _dup
|
||||
#define dup2 _dup2
|
||||
#define ecvt _ecvt
|
||||
#define eof _eof
|
||||
#define execl _execl
|
||||
#define execle _execle
|
||||
#define execlp _execlp
|
||||
#define execlpe _execlpe
|
||||
#define execv _execv
|
||||
#define execve _execv
|
||||
#define execvp _execvp
|
||||
#define execvpe _execvpe
|
||||
#define fcloseall _fcloseall
|
||||
#define fcvt _fcvt
|
||||
#define fdopen _fdopen
|
||||
#define fgetchar _fgetchar
|
||||
#define filelength _filelength
|
||||
#define fileno _fileno
|
||||
#define flushall _flushall
|
||||
#define fputchar _fputchar
|
||||
#define gcvt _gcvt
|
||||
#define getch _getch
|
||||
#define getche _getche
|
||||
#define getcwd _getcwd
|
||||
#define getpid _getpid
|
||||
#define getw _getw
|
||||
#define hypot _hypot
|
||||
#define inp _inp
|
||||
#define inpw _inpw
|
||||
#define isascii __isascii
|
||||
#define isatty _isatty
|
||||
#define iscsym __iscsym
|
||||
#define iscsymf __iscsymf
|
||||
#define itoa _itoa
|
||||
#define j0 _j0
|
||||
#define j1 _j1
|
||||
#define jn _jn
|
||||
#define kbhit _kbhit
|
||||
#define lfind _lfind
|
||||
#define locking _locking
|
||||
#define lsearch _lsearch
|
||||
#define lseek _lseek
|
||||
#define ltoa _ltoa
|
||||
#define memccpy _memccpy
|
||||
#define memicmp _memicmp
|
||||
#define mkdir _mkdir
|
||||
#define mktemp _mktemp
|
||||
#define open _open
|
||||
#define outp _outp
|
||||
#define outpw _outpw
|
||||
#define putch _putch
|
||||
#define putenv _putenv
|
||||
#define putw _putw
|
||||
#define read _read
|
||||
#define rmdir _rmdir
|
||||
#define rmtmp _rmtmp
|
||||
#define setmode _setmode
|
||||
#define sopen _sopen
|
||||
#define spawnl _spawnl
|
||||
#define spawnle _spawnle
|
||||
#define spawnlp _spawnlp
|
||||
#define spawnlpe _spawnlpe
|
||||
#define spawnv _spawnv
|
||||
#define spawnve _spawnve
|
||||
#define spawnvp _spawnvp
|
||||
#define spawnvpe _spawnvpe
|
||||
#define strcmpi _strcmpi
|
||||
#define strdup _strdup
|
||||
#define stricmp _stricmp
|
||||
#define strlwr _strlwr
|
||||
#define strnicmp _strnicmp
|
||||
#define strnset _strnset
|
||||
#define strrev _strrev
|
||||
#define strset _strset
|
||||
#define strupr _strupr
|
||||
#define swab _swab
|
||||
#define tell _tell
|
||||
#define tempnam _tempnam
|
||||
#define toascii __toascii
|
||||
#define tzset _tzset
|
||||
#define ultoa _ultoa
|
||||
#define umask _umask
|
||||
#define ungetch _ungetch
|
||||
#define unlink _unlink
|
||||
#define wcsdup _wcsdup
|
||||
#define wcsicmp _wcsicmp
|
||||
#define wcsicoll _wcsicoll
|
||||
#define wcslwr _wcslwr
|
||||
#define wcsnicmp _wcsnicmp
|
||||
#define wcsnset _wcsnset
|
||||
#define wcsrev _wcsrev
|
||||
#define wcsset _wcsset
|
||||
#define wcsupr _wcsupr
|
||||
#define write _write
|
||||
#define y0 _y0
|
||||
#define y1 _y1
|
||||
#define yn _yn
|
||||
|
||||
/* Disable deprecation warnings because MSVC8 seemingly thinks the ISO C++ conformant
|
||||
* functions above are deprecated. */
|
||||
#pragma warning (disable:4996)
|
||||
|
||||
#endif
|
||||
#else
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@ -173,7 +313,7 @@ typedef int (AMXAPI *AMX_DEBUG)(struct tagAMX *amx);
|
||||
#endif
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined LINUX || defined __FreeBSD__
|
||||
#if defined LINUX || defined __FreeBSD__ || defined __APPLE__
|
||||
#pragma pack(1) /* structures must be packed (byte-aligned) */
|
||||
#elif defined MACOS && defined __MWERKS__
|
||||
#pragma options align=mac68k
|
||||
@ -260,7 +400,7 @@ enum {
|
||||
};
|
||||
|
||||
#if !defined AMX_NO_ALIGN
|
||||
#if defined __linux__
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
#pragma pack() /* reset default packing */
|
||||
#else
|
||||
#pragma pack(pop) /* reset previous packing */
|
||||
@ -271,7 +411,7 @@ enum {
|
||||
// ***** declare functions *****
|
||||
|
||||
#ifdef USE_METAMOD
|
||||
void UTIL_LogPrintf( char *fmt, ... );
|
||||
void UTIL_LogPrintf( const char *fmt, ... );
|
||||
void UTIL_HudMessage(CBaseEntity *pEntity, const hudtextparms_t &textparms, const char *pMessage);
|
||||
short FixedSigned16( float value, float scale );
|
||||
unsigned short FixedUnsigned16( float value, float scale );
|
||||
@ -698,11 +838,11 @@ int FN_AllowLagCompensation_Post(void);
|
||||
|
||||
|
||||
#ifdef FN_PrecacheModel
|
||||
int FN_PrecacheModel(char *s);
|
||||
int FN_PrecacheModel(const char *s);
|
||||
#endif // FN_PrecacheModel
|
||||
|
||||
#ifdef FN_PrecacheSound
|
||||
int FN_PrecacheSound(char *s);
|
||||
int FN_PrecacheSound(const char *s);
|
||||
#endif // FN_PrecacheSound
|
||||
|
||||
#ifdef FN_SetModel
|
||||
@ -722,7 +862,7 @@ void FN_SetSize(edict_t *e, const float *rgflMin, const float *rgflMax);
|
||||
#endif // FN_SetSize
|
||||
|
||||
#ifdef FN_ChangeLevel
|
||||
void FN_ChangeLevel(char *s1, char *s2);
|
||||
void FN_ChangeLevel(const char *s1, const char *s2);
|
||||
#endif // FN_ChangeLevel
|
||||
|
||||
#ifdef FN_GetSpawnParms
|
||||
@ -946,7 +1086,7 @@ void FN_AlertMessage(ALERT_TYPE atype, char *szFmt, ...);
|
||||
#endif // FN_AlertMessage
|
||||
|
||||
#ifdef FN_EngineFprintf
|
||||
void FN_EngineFprintf(FILE *pfile, char *szFmt, ...);
|
||||
void FN_EngineFprintf(void *pfile, char *szFmt, ...);
|
||||
#endif // FN_EngineFprintf
|
||||
|
||||
#ifdef FN_PvAllocEntPrivateData
|
||||
@ -1010,11 +1150,11 @@ void FN_GetBonePosition(const edict_t *pEdict, int iBone, float *rgflOrigin, flo
|
||||
#endif // FN_GetBonePosition
|
||||
|
||||
#ifdef FN_FunctionFromName
|
||||
unsigned long FN_FunctionFromName(const char *pName);
|
||||
uint32 FN_FunctionFromName(const char *pName);
|
||||
#endif // FN_FunctionFromName
|
||||
|
||||
#ifdef FN_NameForFunction
|
||||
const char *FN_NameForFunction(unsigned long function);
|
||||
const char *FN_NameForFunction(uint32);
|
||||
#endif // FN_NameForFunction
|
||||
|
||||
#ifdef FN_ClientPrintf
|
||||
@ -1058,7 +1198,7 @@ CRC32_t FN_CRC32_Final(CRC32_t pulCRC);
|
||||
#endif // FN_CRC32_Final
|
||||
|
||||
#ifdef FN_RandomLong
|
||||
long FN_RandomLong(long lLow, long lHigh);
|
||||
int32 FN_RandomLong(int32 lLow, int32 lHigh);
|
||||
#endif // FN_RandomLong
|
||||
|
||||
#ifdef FN_RandomFloat
|
||||
@ -1126,19 +1266,19 @@ char *FN_GetInfoKeyBuffer(edict_t *e);
|
||||
#endif // FN_GetInfoKeyBuffer
|
||||
|
||||
#ifdef FN_InfoKeyValue
|
||||
char *FN_InfoKeyValue(char *infobuffer, char *key);
|
||||
char *FN_InfoKeyValue(char *infobuffer, const char *key);
|
||||
#endif // FN_InfoKeyValue
|
||||
|
||||
#ifdef FN_SetKeyValue
|
||||
void FN_SetKeyValue(char *infobuffer, char *key, char *value);
|
||||
void FN_SetKeyValue(char *infobuffer, const char *key, const char *value);
|
||||
#endif // FN_SetKeyValue
|
||||
|
||||
#ifdef FN_SetClientKeyValue
|
||||
void FN_SetClientKeyValue(int clientIndex, char *infobuffer, char *key, char *value);
|
||||
void FN_SetClientKeyValue(int clientIndex, char *infobuffer, const char *key, const char *value);
|
||||
#endif // FN_SetClientKeyValue
|
||||
|
||||
#ifdef FN_IsMapValid
|
||||
int FN_IsMapValid(char *filename);
|
||||
int FN_IsMapValid(const char *filename);
|
||||
#endif // FN_IsMapValid
|
||||
|
||||
#ifdef FN_StaticDecal
|
||||
@ -1146,7 +1286,7 @@ void FN_StaticDecal(const float *origin, int decalIndex, int entityIndex, int mo
|
||||
#endif // FN_StaticDecal
|
||||
|
||||
#ifdef FN_PrecacheGeneric
|
||||
int FN_PrecacheGeneric(char *s);
|
||||
int FN_PrecacheGeneric(const char *s);
|
||||
#endif // FN_PrecacheGeneric
|
||||
|
||||
#ifdef FN_GetPlayerUserId
|
||||
@ -1279,11 +1419,11 @@ const char *FN_GetPlayerAuthId(edict_t *e);
|
||||
|
||||
|
||||
#ifdef FN_PrecacheModel_Post
|
||||
int FN_PrecacheModel_Post(char *s);
|
||||
int FN_PrecacheModel_Post(const char *s);
|
||||
#endif // FN_PrecacheModel_Post
|
||||
|
||||
#ifdef FN_PrecacheSound_Post
|
||||
int FN_PrecacheSound_Post(char *s);
|
||||
int FN_PrecacheSound_Post(const char *s);
|
||||
#endif // FN_PrecacheSound_Post
|
||||
|
||||
#ifdef FN_SetModel_Post
|
||||
@ -1303,7 +1443,7 @@ void FN_SetSize_Post(edict_t *e, const float *rgflMin, const float *rgflMax);
|
||||
#endif // FN_SetSize_Post
|
||||
|
||||
#ifdef FN_ChangeLevel_Post
|
||||
void FN_ChangeLevel_Post(char *s1, char *s2);
|
||||
void FN_ChangeLevel_Post(const char *s1, const char *s2);
|
||||
#endif // FN_ChangeLevel_Post
|
||||
|
||||
#ifdef FN_GetSpawnParms_Post
|
||||
@ -1527,11 +1667,11 @@ void FN_AlertMessage_Post(ALERT_TYPE atype, char *szFmt, ...);
|
||||
#endif // FN_AlertMessage_Post
|
||||
|
||||
#ifdef FN_EngineFprintf_Post
|
||||
void FN_EngineFprintf_Post(FILE *pfile, char *szFmt, ...);
|
||||
void FN_EngineFprintf_Post(void *pfile, char *szFmt, ...);
|
||||
#endif // FN_EngineFprintf_Post
|
||||
|
||||
#ifdef FN_PvAllocEntPrivateData_Post
|
||||
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, long cb);
|
||||
void *FN_PvAllocEntPrivateData_Post(edict_t *pEdict, int32 cb);
|
||||
#endif // FN_PvAllocEntPrivateData_Post
|
||||
|
||||
#ifdef FN_PvEntPrivateData_Post
|
||||
@ -1591,11 +1731,11 @@ void FN_GetBonePosition_Post(const edict_t *pEdict, int iBone, float *rgflOrigin
|
||||
#endif // FN_GetBonePosition_Post
|
||||
|
||||
#ifdef FN_FunctionFromName_Post
|
||||
unsigned long FN_FunctionFromName_Post(const char *pName);
|
||||
uint32 FN_FunctionFromName_Post(const char *pName);
|
||||
#endif // FN_FunctionFromName_Post
|
||||
|
||||
#ifdef FN_NameForFunction_Post
|
||||
const char *FN_NameForFunction_Post(unsigned long function);
|
||||
const char *FN_NameForFunction_Post(uint32);
|
||||
#endif // FN_NameForFunction_Post
|
||||
|
||||
#ifdef FN_ClientPrintf_Post
|
||||
@ -1639,7 +1779,7 @@ CRC32_t FN_CRC32_Final_Post(CRC32_t pulCRC);
|
||||
#endif // FN_CRC32_Final_Post
|
||||
|
||||
#ifdef FN_RandomLong_Post
|
||||
long FN_RandomLong_Post(long lLow, long lHigh);
|
||||
int32 FN_RandomLong_Post(int32 lLow, int32 lHigh);
|
||||
#endif // FN_RandomLong_Post
|
||||
|
||||
#ifdef FN_RandomFloat_Post
|
||||
@ -1707,19 +1847,19 @@ char *FN_GetInfoKeyBuffer_Post(edict_t *e);
|
||||
#endif // FN_GetInfoKeyBuffer_Post
|
||||
|
||||
#ifdef FN_InfoKeyValue_Post
|
||||
char *FN_InfoKeyValue_Post(char *infobuffer, char *key);
|
||||
char *FN_InfoKeyValue_Post(char *infobuffer, const char *key);
|
||||
#endif // FN_InfoKeyValue_Post
|
||||
|
||||
#ifdef FN_SetKeyValue_Post
|
||||
void FN_SetKeyValue_Post(char *infobuffer, char *key, char *value);
|
||||
void FN_SetKeyValue_Post(char *infobuffer, const char *key, const char *value);
|
||||
#endif // FN_SetKeyValue_Post
|
||||
|
||||
#ifdef FN_SetClientKeyValue_Post
|
||||
void FN_SetClientKeyValue_Post(int clientIndex, char *infobuffer, char *key, char *value);
|
||||
void FN_SetClientKeyValue_Post(int clientIndex, char *infobuffer, const char *key, const char *value);
|
||||
#endif // FN_SetClientKeyValue_Post
|
||||
|
||||
#ifdef FN_IsMapValid_Post
|
||||
int FN_IsMapValid_Post(char *filename);
|
||||
int FN_IsMapValid_Post(const char *filename);
|
||||
#endif // FN_IsMapValid_Post
|
||||
|
||||
#ifdef FN_StaticDecal_Post
|
||||
@ -1727,7 +1867,7 @@ void FN_StaticDecal_Post(const float *origin, int decalIndex, int entityIndex, i
|
||||
#endif // FN_StaticDecal_Post
|
||||
|
||||
#ifdef FN_PrecacheGeneric_Post
|
||||
int FN_PrecacheGeneric_Post(char *s);
|
||||
int FN_PrecacheGeneric_Post(const char *s);
|
||||
#endif // FN_PrecacheGeneric_Post
|
||||
|
||||
#ifdef FN_GetPlayerUserId_Post
|
||||
@ -1892,6 +2032,10 @@ int FN_ShouldCollide_Post(edict_t *pentTouched, edict_t *pentOther);
|
||||
void FN_AMXX_QUERY(void);
|
||||
#endif // FN_AMXX_QUERY
|
||||
|
||||
#ifdef FN_AMXX_CHECKGAME
|
||||
int FN_AMXX_CHECKGAME(const char *);
|
||||
#endif // FN_AMXX_CHECKGAME
|
||||
|
||||
#ifdef FN_AMXX_ATTACH
|
||||
void FN_AMXX_ATTACH(void);
|
||||
#endif // FN_AMXX_ATTACH
|
||||
@ -1904,6 +2048,14 @@ void FN_AMXX_DETACH(void);
|
||||
void FN_AMXX_PLUGINSLOADED(void);
|
||||
#endif // FN_AMXX_PLUGINSLOADED
|
||||
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADING
|
||||
void FN_AMXX_PLUGINSUNLOADING(void);
|
||||
#endif // FN_AMXX_PLUGINSUNLOADING
|
||||
|
||||
#ifdef FN_AMXX_PLUGINSUNLOADED
|
||||
void FN_AMXX_PLUGINSUNLOADED(void);
|
||||
#endif // FN_AMXX_PLUGINSUNLOADED
|
||||
|
||||
// *** Types ***
|
||||
typedef void* (*PFN_REQ_FNPTR)(const char * /*name*/);
|
||||
|
||||
@ -1927,12 +2079,49 @@ enum ForwardParam
|
||||
FP_ARRAY, // array; use the return value of prepareArray.
|
||||
};
|
||||
|
||||
enum PlayerProp
|
||||
{
|
||||
Player_Name, //String
|
||||
Player_Ip, //String
|
||||
Player_Team, //String
|
||||
Player_Ingame, //bool
|
||||
Player_Authorized, //bool
|
||||
Player_Vgui, //bool
|
||||
Player_Time, //float
|
||||
Player_Playtime, //float
|
||||
Player_MenuExpire, //float
|
||||
Player_Weapons, //struct{int,int}[32]
|
||||
Player_CurrentWeapon, //int
|
||||
Player_TeamID, //int
|
||||
Player_Deaths, //int
|
||||
Player_Aiming, //int
|
||||
Player_Menu, //int
|
||||
Player_Keys, //int
|
||||
Player_Flags, //int[32]
|
||||
Player_Newmenu, //int
|
||||
Player_NewmenuPage, //int
|
||||
};
|
||||
|
||||
enum LibType
|
||||
{
|
||||
LibType_Library,
|
||||
LibType_Class
|
||||
};
|
||||
|
||||
#define MSGBLOCK_SET 0
|
||||
#define MSGBLOCK_GET 1
|
||||
#define BLOCK_NOT 0
|
||||
#define BLOCK_ONCE 1
|
||||
#define BLOCK_SET 2
|
||||
|
||||
typedef void (*AUTHORIZEFUNC)(int player, const char *authstring);
|
||||
|
||||
typedef int (*PFN_ADD_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||
typedef int (*PFN_ADD_NEW_NATIVES) (const AMX_NATIVE_INFO * /*list*/);
|
||||
typedef char * (*PFN_BUILD_PATHNAME) (const char * /*format*/, ...);
|
||||
typedef char * (*PFN_BUILD_PATHNAME_R) (char * /*buffer*/, size_t /* maxlen */, const char * /* format */, ...);
|
||||
typedef cell * (*PFN_GET_AMXADDR) (AMX * /*amx*/, cell /*offset*/);
|
||||
typedef void (*PFN_PRINT_SRVCONSOLE) (char * /*format*/, ...);
|
||||
typedef void (*PFN_PRINT_SRVCONSOLE) (const char * /*format*/, ...);
|
||||
typedef const char * (*PFN_GET_MODNAME) (void);
|
||||
typedef const char * (*PFN_GET_AMXSCRIPTNAME) (int /*id*/);
|
||||
typedef AMX * (*PFN_GET_AMXSCRIPT) (int /*id*/);
|
||||
@ -1978,6 +2167,7 @@ typedef edict_t * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
||||
#else
|
||||
typedef void * (*PFN_GET_PLAYER_EDICT) (int /*id*/);
|
||||
#endif
|
||||
typedef void * (*PFN_PLAYER_PROP_ADDR) (int /*id*/, int /*prop*/);
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
typedef void * (*PFN_ALLOCATOR) (const char* /*filename*/, const unsigned int /*line*/, const char* /*func*/,
|
||||
@ -1990,8 +2180,8 @@ typedef void (*PFN_DEALLOCATOR) (const char* /*filename*/, const unsigned i
|
||||
typedef int (*PFN_AMX_EXEC) (AMX* /*amx*/, cell* /*return val*/, int /*index*/);
|
||||
typedef int (*PFN_AMX_EXECV) (AMX* /*amx*/, cell* /*return val*/, int /*index*/, int /*numparams*/, cell[] /*params*/);
|
||||
typedef int (*PFN_AMX_ALLOT) (AMX* /*amx*/, int /*length*/, cell* /*amx_addr*/, cell** /*phys_addr*/);
|
||||
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
||||
typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, char* /*func name*/, int* /*index*/);
|
||||
typedef int (*PFN_AMX_FINDPUBLIC) (AMX* /*amx*/, const char* /*func name*/, int* /*index*/);
|
||||
typedef int (*PFN_AMX_FINDNATIVE) (AMX* /*amx*/, const char* /*func name*/, int* /*index*/);
|
||||
typedef int (*PFN_LOAD_AMXSCRIPT) (AMX* /*amx*/, void** /*code*/, const char* /*path*/, char[64] /*error info*/, int /* debug */);
|
||||
typedef int (*PFN_UNLOAD_AMXSCRIPT) (AMX* /*amx*/,void** /*code*/);
|
||||
typedef cell (*PFN_REAL_TO_CELL) (REAL /*x*/);
|
||||
@ -2003,8 +2193,20 @@ typedef void (*PFN_MERGEDEFINITION_FILE) (const char * /*filename*/);
|
||||
typedef const char * (*PFN_FORMAT) (const char * /*fmt*/, ... /*params*/);
|
||||
typedef void (*PFN_REGISTERFUNCTION) (void * /*pfn*/, const char * /*desc*/);
|
||||
typedef int (*PFN_AMX_PUSH) (AMX * /*amx*/, cell /*value*/);
|
||||
typedef int (*PFN_SET_TEAM_INFO) (int /*player */, int /*teamid */, const char * /*name */);
|
||||
typedef void (*PFN_REG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||
typedef void (*PFN_UNREG_AUTH_FUNC) (AUTHORIZEFUNC);
|
||||
typedef int (*PFN_FINDLIBRARY) (const char * /*name*/, LibType /*type*/);
|
||||
typedef size_t (*PFN_ADDLIBRARIES) (const char * /*name*/, LibType /*type*/, void * /*parent*/);
|
||||
typedef size_t (*PFN_REMOVELIBRARIES) (void * /*parent*/);
|
||||
typedef void (*PFN_OVERRIDENATIVES) (AMX_NATIVE_INFO * /*natives*/, const char * /*myname*/);
|
||||
typedef const char * (*PFN_GETLOCALINFO) (const char * /*name*/, const char * /*def*/);
|
||||
typedef int (*PFN_AMX_REREGISTER) (AMX * /*amx*/, AMX_NATIVE_INFO * /*list*/, int /*list*/);
|
||||
typedef void * (*PFN_REGISTERFUNCTIONEX) (void * /*pfn*/, const char * /*desc*/);
|
||||
typedef void (*PFN_MESSAGE_BLOCK) (int /* mode */, int /* message */, int * /* opt */);
|
||||
|
||||
extern PFN_ADD_NATIVES g_fn_AddNatives;
|
||||
extern PFN_ADD_NEW_NATIVES g_fn_AddNewNatives;
|
||||
extern PFN_BUILD_PATHNAME g_fn_BuildPathname;
|
||||
extern PFN_BUILD_PATHNAME_R g_fn_BuildPathnameR;
|
||||
extern PFN_GET_AMXADDR g_fn_GetAmxAddr;
|
||||
@ -2066,11 +2268,24 @@ extern PFN_GET_PLAYER_TEAM g_fn_GetPlayerTeam;
|
||||
extern PFN_REGISTERFUNCTION g_fn_RegisterFunction;
|
||||
extern PFN_REQ_FNPTR g_fn_RequestFunction;
|
||||
extern PFN_AMX_PUSH g_fn_AmxPush;
|
||||
extern PFN_SET_TEAM_INFO g_fn_SetTeamInfo;
|
||||
extern PFN_PLAYER_PROP_ADDR g_fn_PlayerPropAddr;
|
||||
extern PFN_REG_AUTH_FUNC g_fn_RegAuthFunc;
|
||||
extern PFN_UNREG_AUTH_FUNC g_fn_UnregAuthFunc;
|
||||
extern PFN_FINDLIBRARY g_fn_FindLibrary;
|
||||
extern PFN_ADDLIBRARIES g_fn_AddLibraries;
|
||||
extern PFN_REMOVELIBRARIES g_fn_RemoveLibraries;
|
||||
extern PFN_OVERRIDENATIVES g_fn_OverrideNatives;
|
||||
extern PFN_GETLOCALINFO g_fn_GetLocalInfo;
|
||||
extern PFN_AMX_REREGISTER g_fn_AmxReRegister;
|
||||
extern PFN_REGISTERFUNCTIONEX g_fn_RegisterFunctionEx;
|
||||
extern PFN_MESSAGE_BLOCK g_fn_MessageBlock;
|
||||
|
||||
#ifdef MAY_NEVER_BE_DEFINED
|
||||
// Function prototypes for intellisense and similar systems
|
||||
// They understand #if 0 so we use #ifdef MAY_NEVER_BE_DEFINED
|
||||
int MF_AddNatives (const AMX_NATIVE_INFO *list) { }
|
||||
int MF_AddNewNatives (const AMX_NATIVE_INFO *list) { }
|
||||
char * MF_BuildPathname (const char * format, ...) { }
|
||||
char * MF_BuildPathnameR (char *buffer, size_t maxlen, const char *fmt, ...) { }
|
||||
cell * MF_GetAmxAddr (AMX * amx, cell offset) { }
|
||||
@ -2126,9 +2341,22 @@ void MF_RegisterFunction (void *pfn, const char *description) { }
|
||||
void * MF_RequestFunction (const char *description) { }
|
||||
int MF_AmxPush (AMX *amx, cell *params) { }
|
||||
int MF_AmxExec (AMX *amx, cell *retval, int idx) { }
|
||||
int MF_SetPlayerTeamInfo (int id, int teamid, const char *teamname) { }
|
||||
void * MF_PlayerPropAddr (int id, int prop) { }
|
||||
void MF_RegAuthFunc (AUTHORIZEFUNC fn) { }
|
||||
void MF_UnregAuthFunc (AUTHORIZEFUNC fn) { }
|
||||
int MF_FindLibrary (const char *name, LibType type) { }
|
||||
size_t MF_AddLibraries (const char *name, LibType type, void *parent) { }
|
||||
size_t MF_RemoveLibraries (void *parent) { }
|
||||
void MF_OverrideNatives (AMX_NATIVE_INFO *natives, const char *myname) { }
|
||||
const char * MF_GetLocalInfo (const char *name, const char *def) { }
|
||||
int MF_AmxReRegister (AMX *amx, AMX_NATIVE_INFO *list, int number) { return 0; }
|
||||
void * MF_RegisterFunctionEx (void *pfn, const char *description) { }
|
||||
void * MF_MessageBlock (int mode, int msg, int *opt) { }
|
||||
#endif // MAY_NEVER_BE_DEFINED
|
||||
|
||||
#define MF_AddNatives g_fn_AddNatives
|
||||
#define MF_AddNewNatives g_fn_AddNewNatives
|
||||
#define MF_BuildPathname g_fn_BuildPathname
|
||||
#define MF_BuildPathnameR g_fn_BuildPathnameR
|
||||
#define MF_FormatAmxString g_fn_FormatAmxString
|
||||
@ -2189,8 +2417,20 @@ void MF_LogError(AMX *amx, int err, const char *fmt, ...);
|
||||
#define MF_GetPlayerEdict g_fn_GetPlayerEdict
|
||||
#define MF_Format g_fn_Format
|
||||
#define MF_RegisterFunction g_fn_RegisterFunction
|
||||
#define MF_RequestFunction g_fn_RequestFunction;
|
||||
#define MF_RequestFunction g_fn_RequestFunction
|
||||
#define MF_AmxPush g_fn_AmxPush
|
||||
#define MF_SetPlayerTeamInfo g_fn_SetTeamInfo
|
||||
#define MF_PlayerPropAddr g_fn_PlayerPropAddr
|
||||
#define MF_RegAuthFunc g_fn_RegAuthFunc
|
||||
#define MF_UnregAuthFunc g_fn_UnregAuthFunc
|
||||
#define MF_FindLibrary g_fn_FindLibrary
|
||||
#define MF_AddLibraries g_fn_AddLibraries
|
||||
#define MF_RemoveLibraries g_fn_RemoveLibraries
|
||||
#define MF_OverrideNatives g_fn_OverrideNatives
|
||||
#define MF_GetLocalInfo g_fn_GetLocalInfo
|
||||
#define MF_AmxReRegister g_fn_AmxReRegister
|
||||
#define MF_RegisterFunctionEx g_fn_RegisterFunctionEx
|
||||
#define MF_MessageBlock g_fn_MessageBlock
|
||||
|
||||
#ifdef MEMORY_TEST
|
||||
/*** Memory ***/
|
||||
|
@ -3,12 +3,24 @@
|
||||
#ifndef __MODULECONFIG_H__
|
||||
#define __MODULECONFIG_H__
|
||||
|
||||
// Module info
|
||||
/** Module info
|
||||
* -The logtag is the tag that the module's log messages will be
|
||||
* prepended with.
|
||||
* -The library is the name that the #pragma library
|
||||
* message will have prepended.
|
||||
* -The library class is the class of libraries that
|
||||
* a module belongs to (like DBI). Keep it "" to
|
||||
* ignore.
|
||||
* -For both library and library class, you can use a comma
|
||||
* to add multiple entries.
|
||||
*/
|
||||
#define MODULE_NAME "--ENTER NAME HERE--"
|
||||
#define MODULE_VERSION "--ENTER VERSION HERE--"
|
||||
#define MODULE_AUTHOR "--ENTER AUTHOR HERE--"
|
||||
#define MODULE_URL "--ENTER URL HERE--"
|
||||
#define MODULE_LOGTAG "--ENTER LOGTAG HERE--"
|
||||
#define MODULE_LIBRARY "--ENTER LIBRARY HERE--"
|
||||
#define MODULE_LIBCLASS ""
|
||||
// If you want the module not to be reloaded on mapchange, remove / comment out the next line
|
||||
#define MODULE_RELOAD_ON_MAPCHANGE
|
||||
|
||||
@ -31,18 +43,41 @@
|
||||
// It allows you to compile without libstdc++.so as a dependency
|
||||
// #define NO_ALLOC_OVERRIDES
|
||||
|
||||
// - AMXX Init functions
|
||||
// Also consider using FN_META_*
|
||||
// AMXX query
|
||||
// Uncomment this if you are using MSVC8 or greater and want to fix some of the compatibility issues yourself
|
||||
// #define NO_MSVC8_AUTO_COMPAT
|
||||
|
||||
/**
|
||||
* AMXX Init functions
|
||||
* Also consider using FN_META_*
|
||||
*/
|
||||
|
||||
/** AMXX query */
|
||||
//#define FN_AMXX_QUERY OnAmxxQuery
|
||||
// AMXX attach
|
||||
// Do native functions init here (MF_AddNatives)
|
||||
|
||||
/** AMXX Check Game - module API is NOT available here.
|
||||
* Return AMXX_GAME_OK if this module can load on the game, AMXX_GAME_BAD if it cannot.
|
||||
* syntax: int AmxxCheckGame(const char *game)
|
||||
*/
|
||||
//#define FN_AMXX_CHECKGAME AmxxCheckGame
|
||||
|
||||
/** AMXX attach
|
||||
* Do native functions init here (MF_AddNatives)
|
||||
*/
|
||||
//#define FN_AMXX_ATTACH OnAmxxAttach
|
||||
// AMXX detach
|
||||
|
||||
/** AMXX Detach (unload) */
|
||||
//#define FN_AMXX_DETACH OnAmxxDetach
|
||||
// All plugins loaded
|
||||
// Do forward functions init here (MF_RegisterForward)
|
||||
// #define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||
|
||||
/** All plugins loaded
|
||||
* Do forward functions init here (MF_RegisterForward)
|
||||
*/
|
||||
//#define FN_AMXX_PLUGINSLOADED OnPluginsLoaded
|
||||
|
||||
/** All plugins are about to be unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADING OnPluginsUnloading
|
||||
|
||||
/** All plugins are now unloaded */
|
||||
//#define FN_AMXX_PLUGINSUNLOADED OnPluginsUnloaded
|
||||
|
||||
/**** METAMOD ****/
|
||||
// If your module doesn't use metamod, you may close the file now :)
|
||||
|
297
amxmodx/sh_list.h
Normal file
297
amxmodx/sh_list.h
Normal file
@ -0,0 +1,297 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): David "BAILOPAN" Anderson
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE_SMM_LIST_H
|
||||
#define _INCLUDE_SMM_LIST_H
|
||||
|
||||
// MSVC8 fix for offsetof macro redefition warnings
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1400
|
||||
#undef offsetof
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
|
||||
//namespace SourceHook
|
||||
//{
|
||||
//This class is from CSDM for AMX Mod X
|
||||
/*
|
||||
A circular, doubly-linked list with one sentinel node
|
||||
|
||||
Empty:
|
||||
m_Head = sentinel
|
||||
m_Head->next = m_Head;
|
||||
m_Head->prev = m_Head;
|
||||
One element:
|
||||
m_Head = sentinel
|
||||
m_Head->next = node1
|
||||
m_Head->prev = node1
|
||||
node1->next = m_Head
|
||||
node1->prev = m_Head
|
||||
Two elements:
|
||||
m_Head = sentinel
|
||||
m_Head->next = node1
|
||||
m_Head->prev = node2
|
||||
node1->next = node2
|
||||
node1->prev = m_Head
|
||||
node2->next = m_Head
|
||||
node2->prev = node1
|
||||
*/
|
||||
template <class T>
|
||||
class List
|
||||
{
|
||||
public:
|
||||
class iterator;
|
||||
friend class iterator;
|
||||
class ListNode
|
||||
{
|
||||
public:
|
||||
ListNode(const T & o) : obj(o) { };
|
||||
ListNode() { };
|
||||
T obj;
|
||||
ListNode *next;
|
||||
ListNode *prev;
|
||||
};
|
||||
private:
|
||||
// Initializes the sentinel node.
|
||||
// BAIL used malloc instead of new in order to bypass the need for a constructor.
|
||||
ListNode *_Initialize()
|
||||
{
|
||||
ListNode *n = (ListNode *)malloc(sizeof(ListNode));
|
||||
n->next = n;
|
||||
n->prev = n;
|
||||
return n;
|
||||
}
|
||||
public:
|
||||
List() : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
}
|
||||
List(const List &src) : m_Head(_Initialize()), m_Size(0)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
}
|
||||
~List()
|
||||
{
|
||||
clear();
|
||||
|
||||
// Don't forget to free the sentinel
|
||||
if (m_Head)
|
||||
{
|
||||
free(m_Head);
|
||||
m_Head = NULL;
|
||||
}
|
||||
}
|
||||
void push_back(const T &obj)
|
||||
{
|
||||
ListNode *node = new ListNode(obj);
|
||||
|
||||
node->prev = m_Head->prev;
|
||||
node->next = m_Head;
|
||||
m_Head->prev->next = node;
|
||||
m_Head->prev = node;
|
||||
|
||||
m_Size++;
|
||||
}
|
||||
size_t size()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
ListNode *node = m_Head->next;
|
||||
ListNode *temp;
|
||||
m_Head->next = m_Head;
|
||||
m_Head->prev = m_Head;
|
||||
|
||||
// Iterate through the nodes until we find g_Head (the sentinel) again
|
||||
while (node != m_Head)
|
||||
{
|
||||
temp = node->next;
|
||||
delete node;
|
||||
node = temp;
|
||||
}
|
||||
m_Size = 0;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return (m_Size == 0);
|
||||
}
|
||||
T & back()
|
||||
{
|
||||
return m_Head->prev->obj;
|
||||
}
|
||||
private:
|
||||
ListNode *m_Head;
|
||||
size_t m_Size;
|
||||
public:
|
||||
class iterator
|
||||
{
|
||||
friend class List;
|
||||
public:
|
||||
iterator()
|
||||
{
|
||||
m_This = NULL;
|
||||
}
|
||||
iterator(const List &src)
|
||||
{
|
||||
m_This = src.m_Head;
|
||||
}
|
||||
iterator(ListNode *n) : m_This(n)
|
||||
{
|
||||
}
|
||||
iterator(const iterator &where)
|
||||
{
|
||||
m_This = where.m_This;
|
||||
}
|
||||
//pre decrement
|
||||
iterator & operator--()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return *this;
|
||||
}
|
||||
//post decrement
|
||||
iterator operator--(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->prev;
|
||||
return old;
|
||||
}
|
||||
|
||||
//pre increment
|
||||
iterator & operator++()
|
||||
{
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return *this;
|
||||
}
|
||||
//post increment
|
||||
iterator operator++(int)
|
||||
{
|
||||
iterator old(*this);
|
||||
if (m_This)
|
||||
m_This = m_This->next;
|
||||
return old;
|
||||
}
|
||||
|
||||
const T & operator * () const
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
T & operator * ()
|
||||
{
|
||||
return m_This->obj;
|
||||
}
|
||||
|
||||
T * operator -> ()
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
const T * operator -> () const
|
||||
{
|
||||
return &(m_This->obj);
|
||||
}
|
||||
|
||||
bool operator != (const iterator &where) const
|
||||
{
|
||||
return (m_This != where.m_This);
|
||||
}
|
||||
bool operator ==(const iterator &where) const
|
||||
{
|
||||
return (m_This == where.m_This);
|
||||
}
|
||||
private:
|
||||
ListNode *m_This;
|
||||
};
|
||||
public:
|
||||
iterator begin() const
|
||||
{
|
||||
return iterator(m_Head->next);
|
||||
}
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(m_Head);
|
||||
}
|
||||
iterator erase(iterator &where)
|
||||
{
|
||||
ListNode *pNode = where.m_This;
|
||||
iterator iter(where);
|
||||
iter++;
|
||||
|
||||
|
||||
// Works for all cases: empty list, erasing first element, erasing tail, erasing in the middle...
|
||||
pNode->prev->next = pNode->next;
|
||||
pNode->next->prev = pNode->prev;
|
||||
|
||||
delete pNode;
|
||||
m_Size--;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
iterator insert(iterator where, const T &obj)
|
||||
{
|
||||
// Insert obj right before where
|
||||
|
||||
ListNode *node = new ListNode(obj);
|
||||
ListNode *pWhereNode = where.m_This;
|
||||
|
||||
pWhereNode->prev->next = node;
|
||||
node->prev = pWhereNode->prev;
|
||||
pWhereNode->prev = node;
|
||||
node->next = pWhereNode;
|
||||
|
||||
m_Size++;
|
||||
|
||||
return iterator(node);
|
||||
}
|
||||
|
||||
public:
|
||||
void remove(const T & obj)
|
||||
{
|
||||
iterator b;
|
||||
for (b=begin(); b!=end(); b++)
|
||||
{
|
||||
if ( (*b) == obj )
|
||||
{
|
||||
erase( b );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
template <typename U>
|
||||
iterator find(const U & equ)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter=begin(); iter!=end(); iter++)
|
||||
{
|
||||
if ( (*iter) == equ )
|
||||
return iter;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
List & operator =(const List &src)
|
||||
{
|
||||
clear();
|
||||
iterator iter;
|
||||
for (iter=src.begin(); iter!=src.end(); iter++)
|
||||
push_back( (*iter) );
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
//}; //NAMESPACE
|
||||
|
||||
#endif //_INCLUDE_CSDM_LIST_H
|
219
amxmodx/sh_stack.h
Executable file
219
amxmodx/sh_stack.h
Executable file
@ -0,0 +1,219 @@
|
||||
/* ======== SourceMM ========
|
||||
* Copyright (C) 2004-2005 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): Pavol "PM OnoTo" Marko
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef __SH_STACK_H__
|
||||
#define __SH_STACK_H__
|
||||
|
||||
#define SH_STACK_DEFAULT_SIZE 4
|
||||
|
||||
//namespace SourceHook
|
||||
//{/
|
||||
// Vector
|
||||
template <class T> class CStack
|
||||
{
|
||||
T *m_Elements;
|
||||
size_t m_AllocatedSize;
|
||||
size_t m_UsedSize;
|
||||
public:
|
||||
friend class iterator;
|
||||
class iterator
|
||||
{
|
||||
CStack<T> *m_pParent;
|
||||
size_t m_Index;
|
||||
public:
|
||||
iterator(CStack<T> *pParent, size_t id) : m_pParent(pParent), m_Index(id)
|
||||
{
|
||||
}
|
||||
|
||||
iterator(CStack<T> *pParent) : m_pParent(pParent), m_Index(0)
|
||||
{
|
||||
}
|
||||
|
||||
iterator() : m_pParent(NULL), m_Index(0)
|
||||
{
|
||||
}
|
||||
|
||||
T &operator *()
|
||||
{
|
||||
return m_pParent->m_Elements[m_Index];
|
||||
}
|
||||
const T &operator *() const
|
||||
{
|
||||
return m_pParent->m_Elements[m_Index];
|
||||
}
|
||||
|
||||
T * operator->()
|
||||
{
|
||||
return m_pParent->m_Elements + m_Index;
|
||||
}
|
||||
|
||||
const T * operator->() const
|
||||
{
|
||||
return m_pParent->m_Elements + m_Index;
|
||||
}
|
||||
|
||||
iterator & operator++() // preincrement
|
||||
{
|
||||
++m_Index;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator++(int) // postincrement
|
||||
{
|
||||
iterator tmp = *this;
|
||||
++m_Index;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
iterator & operator--() // predecrement
|
||||
{
|
||||
--m_Index;
|
||||
return (*this);
|
||||
}
|
||||
|
||||
iterator operator--(int) // postdecrememnt
|
||||
{
|
||||
iterator tmp = *this;
|
||||
--m_Index;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator & right) const
|
||||
{
|
||||
return (m_pParent == right.m_pParent && m_Index == right.m_Index);
|
||||
}
|
||||
|
||||
bool operator!=(const iterator & right) const
|
||||
{
|
||||
return !(*this == right);
|
||||
}
|
||||
};
|
||||
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
|
||||
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
|
||||
m_UsedSize(0)
|
||||
{
|
||||
}
|
||||
CStack(size_t size) : m_Elements(new T[size]),
|
||||
m_AllocatedSize(size),
|
||||
m_UsedSize(0)
|
||||
{
|
||||
}
|
||||
|
||||
CStack(const CStack &other) : m_Elements(NULL),
|
||||
m_AllocatedSize(0),
|
||||
m_UsedSize(0)
|
||||
{
|
||||
reserve(other.m_AllocatedSize);
|
||||
m_UsedSize = other.m_UsedSize;
|
||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||
m_Elements[i] = other.m_Elements[i];
|
||||
}
|
||||
|
||||
~CStack()
|
||||
{
|
||||
if (m_Elements)
|
||||
delete [] m_Elements;
|
||||
}
|
||||
|
||||
void operator=(const CStack &other)
|
||||
{
|
||||
if (m_AllocatedSize < other.m_AllocatedSize)
|
||||
{
|
||||
if (m_Elements)
|
||||
delete [] m_Elements;
|
||||
m_Elements = new T[other.m_AllocatedSize];
|
||||
m_AllocatedSize = other.m_AllocatedSize;
|
||||
}
|
||||
m_UsedSize = other.m_UsedSize;
|
||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||
m_Elements[i] = other.m_Elements[i];
|
||||
}
|
||||
|
||||
bool push(const T &val)
|
||||
{
|
||||
if (m_UsedSize + 1 == m_AllocatedSize)
|
||||
{
|
||||
// zOHNOES! REALLOCATE!
|
||||
m_AllocatedSize *= 2;
|
||||
T *newElements = new T[m_AllocatedSize];
|
||||
if (!newElements)
|
||||
{
|
||||
m_AllocatedSize /= 2;
|
||||
return false;
|
||||
}
|
||||
if (m_Elements)
|
||||
{
|
||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||
newElements[i] = m_Elements[i];
|
||||
delete [] m_Elements;
|
||||
}
|
||||
m_Elements = newElements;
|
||||
}
|
||||
m_Elements[m_UsedSize++] = val;
|
||||
return true;
|
||||
}
|
||||
void pop()
|
||||
{
|
||||
--m_UsedSize;
|
||||
}
|
||||
|
||||
T &front()
|
||||
{
|
||||
return m_Elements[m_UsedSize - 1];
|
||||
}
|
||||
|
||||
const T &front() const
|
||||
{
|
||||
return m_Elements[m_UsedSize - 1];
|
||||
}
|
||||
|
||||
iterator begin()
|
||||
{
|
||||
return iterator(this, 0);
|
||||
}
|
||||
iterator end()
|
||||
{
|
||||
return iterator(this, m_UsedSize);
|
||||
}
|
||||
|
||||
size_t size()
|
||||
{
|
||||
return m_UsedSize;
|
||||
}
|
||||
size_t capacity()
|
||||
{
|
||||
return m_AllocatedSize;
|
||||
}
|
||||
bool empty()
|
||||
{
|
||||
return m_UsedSize == 0 ? true : false;
|
||||
}
|
||||
bool reserve(size_t size)
|
||||
{
|
||||
if (size > m_AllocatedSize)
|
||||
{
|
||||
T *newElements = new T[size];
|
||||
if (!newElements)
|
||||
return false;
|
||||
if (m_Elements)
|
||||
{
|
||||
for (size_t i = 0; i < m_UsedSize; ++i)
|
||||
newElements[i] = m_Elements[i];
|
||||
delete [] m_Elements;
|
||||
}
|
||||
m_Elements = newElements;
|
||||
m_AllocatedSize = size;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//}; //namespace SourceHook
|
||||
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user