mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-30 12:29:20 +00:00
Compare commits
664 Commits
2.7.2-1.20
...
old/v3.4.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b279bb7716 | ||
|
|
2976390e78 | ||
|
|
578070dffe | ||
|
|
1f9c72d093 | ||
|
|
a1495a10e5 | ||
|
|
a0d91dbc74 | ||
|
|
eb80ae62b1 | ||
|
|
11ae48bea1 | ||
|
|
b0f4b29a2d | ||
|
|
c38bb1cd01 | ||
|
|
7faa727bd2 | ||
|
|
a8751c80ab | ||
|
|
fd38f0d127 | ||
|
|
537b0f8dd6 | ||
|
|
560f2f4fdc | ||
|
|
7c725a9436 | ||
|
|
6532715490 | ||
|
|
b1bb01665a | ||
|
|
6c69c69868 | ||
|
|
9cd7ad6770 | ||
|
|
b70c9fd4d8 | ||
|
|
412f592e1c | ||
|
|
6c0fa9361f | ||
|
|
b7dcdd2921 | ||
|
|
1d8acd2d62 | ||
|
|
05bf92ca50 | ||
|
|
dd598d18bf | ||
|
|
cc6de4a46d | ||
|
|
9950551ecb | ||
|
|
dfd27ecbff | ||
|
|
ac5d5793ab | ||
|
|
2133a03c21 | ||
|
|
8755449c13 | ||
|
|
9e40259ca2 | ||
|
|
94a7692735 | ||
|
|
86ce02789e | ||
|
|
773c8129c9 | ||
|
|
dbe9f81091 | ||
|
|
288e556f2a | ||
|
|
70822e37de | ||
|
|
8b803a87f0 | ||
|
|
3ae6e92eaf | ||
|
|
0f3c52a5aa | ||
|
|
747be7aa09 | ||
|
|
3f994c18ff | ||
|
|
36b99ae4b0 | ||
|
|
25dbc4dfd6 | ||
|
|
c35366caa4 | ||
|
|
76365e7875 | ||
|
|
57649a9ec5 | ||
|
|
03582751c5 | ||
|
|
13369bbf32 | ||
|
|
f3b1109804 | ||
|
|
7f530a4b32 | ||
|
|
eda44a8ace | ||
|
|
f6a354b890 | ||
|
|
db14861b40 | ||
|
|
457b691add | ||
|
|
d651f204f8 | ||
|
|
a61787ecfe | ||
|
|
093d77bf8a | ||
|
|
0101130d7a | ||
|
|
a3b2a17e2d | ||
|
|
ff0a68c4f6 | ||
|
|
e0034dd718 | ||
|
|
7c6df58c15 | ||
|
|
5d5c5ba9f4 | ||
|
|
85aefcd206 | ||
|
|
34a67dc781 | ||
|
|
1a96128321 | ||
|
|
1b0f4e6af6 | ||
|
|
9eb01dd6ca | ||
|
|
bb6778dc63 | ||
|
|
9a24627ceb | ||
|
|
7583b91d46 | ||
|
|
c418962411 | ||
|
|
8e8366b318 | ||
|
|
a4ad83d462 | ||
|
|
ddf0e79a7e | ||
|
|
2bd3ac7a9b | ||
|
|
5e437b34e3 | ||
|
|
a5ef89a128 | ||
|
|
558b8e4eca | ||
|
|
0a001b8a63 | ||
|
|
6c6c9654c1 | ||
|
|
e21fdf46e0 | ||
|
|
a2ff5f58ed | ||
|
|
b0eedee519 | ||
|
|
e101155a4c | ||
|
|
3c9bcc9bb0 | ||
|
|
6763844030 | ||
|
|
08fa436885 | ||
|
|
df8fa79209 | ||
|
|
8041db4f40 | ||
|
|
18e57e4097 | ||
|
|
cc584ba377 | ||
|
|
0c92c20c65 | ||
|
|
ec8af56f0d | ||
|
|
79341bf562 | ||
|
|
3f24d5c8e1 | ||
|
|
66a1739666 | ||
|
|
29007fdbfa | ||
|
|
be3e8ebd51 | ||
|
|
38ad345f85 | ||
|
|
414f46a08d | ||
|
|
9144606688 | ||
|
|
effb0f5b91 | ||
|
|
bb7bbb6379 | ||
|
|
dafca8e9db | ||
|
|
41b7aec084 | ||
|
|
dfe1cce6de | ||
|
|
fc793592f7 | ||
|
|
c3ac41f894 | ||
|
|
d0688782b1 | ||
|
|
25b41fe62c | ||
|
|
b468478fcb | ||
|
|
b6dc934198 | ||
|
|
f58078e8a0 | ||
|
|
b6457e47e6 | ||
|
|
d275466e1e | ||
|
|
f9cb107728 | ||
|
|
68ad206252 | ||
|
|
288bead792 | ||
|
|
de670ddfd5 | ||
|
|
79d6f34879 | ||
|
|
ceb6c15c97 | ||
|
|
7cf43ad7ab | ||
|
|
ab3397a373 | ||
|
|
8e9f78e982 | ||
|
|
61bbfee640 | ||
|
|
cf4796bd12 | ||
|
|
bd89d8a308 | ||
|
|
df2186d70f | ||
|
|
f9638e830f | ||
|
|
cd55a7fed4 | ||
|
|
fc890a5ba1 | ||
|
|
2ea54b7f2f | ||
|
|
e90e3901f5 | ||
|
|
36d58f29ab | ||
|
|
864c7ae27c | ||
|
|
6d104a2d1c | ||
|
|
89e754245d | ||
|
|
4c68d99c6f | ||
|
|
f8f0a65f0a | ||
|
|
6ff74639b5 | ||
|
|
af80f882da | ||
|
|
84ce7372c3 | ||
|
|
e31d39c5f7 | ||
|
|
2296c1368b | ||
|
|
21d7d96dbc | ||
|
|
956e511fe0 | ||
|
|
e427887f8c | ||
|
|
88ea43fbbe | ||
|
|
29526a80a9 | ||
|
|
48f901fc8c | ||
|
|
6c3f3dc889 | ||
|
|
743410d3ee | ||
|
|
acccbb028f | ||
|
|
8b31fdc780 | ||
|
|
55017b9ac2 | ||
|
|
0288d35c85 | ||
|
|
8b3577dd0b | ||
|
|
ced77ec70d | ||
|
|
e1e90f5c8a | ||
|
|
dc3487583d | ||
|
|
e1d73ebcd5 | ||
|
|
d7cf3b9500 | ||
|
|
8ce4e3c6b2 | ||
|
|
76f7d46b22 | ||
|
|
cfc52ed909 | ||
|
|
cee94d40e1 | ||
|
|
cad7166cbe | ||
|
|
c05fdbd0ec | ||
|
|
c9b26ebaff | ||
|
|
bee1973390 | ||
|
|
57efcab0b5 | ||
|
|
b1ab2b84f8 | ||
|
|
02601e5ee4 | ||
|
|
070479acf3 | ||
|
|
6b2ba74237 | ||
|
|
619de29710 | ||
|
|
12556fa98f | ||
|
|
bef4c0497f | ||
|
|
9193497d36 | ||
|
|
ca6affbde9 | ||
|
|
81c40ce228 | ||
|
|
6ba1d571f2 | ||
|
|
b0663f9b6c | ||
|
|
3ced6f3e9e | ||
|
|
3146d61efe | ||
|
|
a967b6af85 | ||
|
|
db3bc74364 | ||
|
|
eb19d9a846 | ||
|
|
96dd299de7 | ||
|
|
aee0806aa8 | ||
|
|
e39f13bbb4 | ||
|
|
52ec80d384 | ||
|
|
d9f8909bdc | ||
|
|
65aa9dc343 | ||
|
|
9bf7fdf174 | ||
|
|
dafb59e5a8 | ||
|
|
79f86ca87d | ||
|
|
1749fcf6b5 | ||
|
|
e1a0481cdf | ||
|
|
4576b95814 | ||
|
|
e113fa6a61 | ||
|
|
07228afbff | ||
|
|
afdffc2453 | ||
|
|
6348442962 | ||
|
|
fd10c005b0 | ||
|
|
44500d6af9 | ||
|
|
6ddb0b5304 | ||
|
|
8ce0976f88 | ||
|
|
8345a58f2b | ||
|
|
f92234297e | ||
|
|
6a5bcd5990 | ||
|
|
1fe6d9a636 | ||
|
|
97f6ab66c3 | ||
|
|
b78c182d94 | ||
|
|
09a0f83013 | ||
|
|
f68d7420e3 | ||
|
|
55c0fa5f32 | ||
|
|
8b5d1d0298 | ||
|
|
b70e94dc65 | ||
|
|
49a6552168 | ||
|
|
0dd6892b28 | ||
|
|
fec587edad | ||
|
|
712937d661 | ||
|
|
ace434e7b0 | ||
|
|
1e5aa6e8b0 | ||
|
|
441b27f8f4 | ||
|
|
3f3bf70212 | ||
|
|
a12eddbedf | ||
|
|
12abc1709e | ||
|
|
9e6035e7b4 | ||
|
|
20b41d65d3 | ||
|
|
1593bb2088 | ||
|
|
d4f9a20379 | ||
|
|
6e247597a4 | ||
|
|
8a8be4545c | ||
|
|
05f4955989 | ||
|
|
93469fb3b4 | ||
|
|
a70258d69f | ||
|
|
c653d852e4 | ||
|
|
40163d25b8 | ||
|
|
5b4265783e | ||
|
|
720417b6c8 | ||
|
|
bb78f412e0 | ||
|
|
a919b91efb | ||
|
|
a3dcf031c9 | ||
|
|
56eb4b6b84 | ||
|
|
393cb362db | ||
|
|
64e422036c | ||
|
|
468e7ef018 | ||
|
|
e3e4ecbc5c | ||
|
|
545ffc0e9d | ||
|
|
8125c8d5f4 | ||
|
|
304b01d0cf | ||
|
|
a5f687fd76 | ||
|
|
fc1761a55b | ||
|
|
e7c9cad7f6 | ||
|
|
979af82122 | ||
|
|
71a62b9c73 | ||
|
|
bb020cab25 | ||
|
|
1ad35c1310 | ||
|
|
6470b2f4a9 | ||
|
|
c1d5ba55cd | ||
|
|
100e450514 | ||
|
|
0f1d1d9860 | ||
|
|
178a462a4e | ||
|
|
8f4ae613f0 | ||
|
|
9e6963b6ce | ||
|
|
cb9a73c60e | ||
|
|
0e666a4c35 | ||
|
|
c80138a354 | ||
|
|
79a4ebcf65 | ||
|
|
a7118aa785 | ||
|
|
2555cd23a0 | ||
|
|
484fbeca7b | ||
|
|
9a45e0df10 | ||
|
|
9175296fc6 | ||
|
|
5a4a86aeba | ||
|
|
768fa7beb5 | ||
|
|
6645eb9806 | ||
|
|
d7a283c99f | ||
|
|
8f019cd794 | ||
|
|
c1d9cc62cb | ||
|
|
010a1e9e91 | ||
|
|
856c926cde | ||
|
|
72ed312654 | ||
|
|
c7fe4723f7 | ||
|
|
bfbea83a4a | ||
|
|
55c58fe896 | ||
|
|
72949e0950 | ||
|
|
61c0ddb15b | ||
|
|
9ac4024e4e | ||
|
|
7fb2a51a33 | ||
|
|
5b7c0b2bc3 | ||
|
|
fc15175ff9 | ||
|
|
1eec3a09c1 | ||
|
|
60d349dd8b | ||
|
|
0c8d144ffb | ||
|
|
b898f73a05 | ||
|
|
c2b9b0ba0e | ||
|
|
206a4e9057 | ||
|
|
83a0a7dd54 | ||
|
|
63b8a935ae | ||
|
|
16affd11cc | ||
|
|
33b0dec9da | ||
|
|
121a463788 | ||
|
|
3625e70948 | ||
|
|
3d90207172 | ||
|
|
ca7dc19c81 | ||
|
|
d0f16dbbc4 | ||
|
|
fd91c223b7 | ||
|
|
93690b766c | ||
|
|
cc4af9950b | ||
|
|
a6281483dd | ||
|
|
f587816b30 | ||
|
|
eea3c3ab0b | ||
|
|
ba68ab9e06 | ||
|
|
eb94d97ea4 | ||
|
|
04ad02719c | ||
|
|
f68f25b92f | ||
|
|
767cca36c8 | ||
|
|
b30172fe89 | ||
|
|
b2934b0cc2 | ||
|
|
50686795d0 | ||
|
|
5561a4dc2f | ||
|
|
15b8780e17 | ||
|
|
15c4d312cb | ||
|
|
ccbea89253 | ||
|
|
7b1e666b3b | ||
|
|
8af212fca8 | ||
|
|
352ee7a622 | ||
|
|
f26d0fac0b | ||
|
|
9612fef2a4 | ||
|
|
a691d49abc | ||
|
|
289eca35ec | ||
|
|
e9ca30257c | ||
|
|
6b21997baa | ||
|
|
6d3dbf84ef | ||
|
|
eb45339c81 | ||
|
|
65e3fdd26c | ||
|
|
34cad85942 | ||
|
|
e407679d2b | ||
|
|
8a08a3e148 | ||
|
|
a01d27d273 | ||
|
|
43f642ae8b | ||
|
|
93c1265de9 | ||
|
|
d08600fbaa | ||
|
|
fb9f8d28f4 | ||
|
|
cd3e9f772d | ||
|
|
7a95441799 | ||
|
|
9345828c97 | ||
|
|
58d88dd079 | ||
|
|
6cbc2374b3 | ||
|
|
12bd11386d | ||
|
|
0497045388 | ||
|
|
d3f1640855 | ||
|
|
960e2fcc61 | ||
|
|
6a012cf400 | ||
|
|
d658ec2099 | ||
|
|
c9a07bd9d7 | ||
|
|
c0136585e6 | ||
|
|
dc4cfc49ad | ||
|
|
9fc72868d7 | ||
|
|
7d4c9d6c1e | ||
|
|
e68b1a52ee | ||
|
|
955e8622b5 | ||
|
|
82640de06b | ||
|
|
c93cb19563 | ||
|
|
ccb7855d7d | ||
|
|
bad547356c | ||
|
|
1740bb0021 | ||
|
|
20f05bf317 | ||
|
|
669ede5482 | ||
|
|
ab658f58f9 | ||
|
|
1b3916749a | ||
|
|
e29ec657d3 | ||
|
|
04f3a226a1 | ||
|
|
099d1cc362 | ||
|
|
c11e9bf704 | ||
|
|
ffa0b984a0 | ||
|
|
f0f9261ed3 | ||
|
|
ba433bc244 | ||
|
|
27f8ad982a | ||
|
|
9b89ae7846 | ||
|
|
c11b5342e3 | ||
|
|
b9c88f5b12 | ||
|
|
02c7ab71d4 | ||
|
|
8ec1ac9875 | ||
|
|
e03027a386 | ||
|
|
387cf566c9 | ||
|
|
dff7665934 | ||
|
|
9421d788f3 | ||
|
|
d960574b24 | ||
|
|
e8671cbbf0 | ||
|
|
cbf8039eea | ||
|
|
d7415e3711 | ||
|
|
26e71ee6b5 | ||
|
|
f8c42b3e48 | ||
|
|
886bed9634 | ||
|
|
7b7023fc99 | ||
|
|
701bfe4a54 | ||
|
|
290d7a93ab | ||
|
|
729bcc7ba0 | ||
|
|
e46b68e2f3 | ||
|
|
cdf73c4629 | ||
|
|
2f0dd2d172 | ||
|
|
7e5704bf80 | ||
|
|
ef96fb9a0e | ||
|
|
f2370ad814 | ||
|
|
0783620104 | ||
|
|
2193b02c0a | ||
|
|
aef05bad20 | ||
|
|
e002ab6378 | ||
|
|
a2c2b4a2d4 | ||
|
|
3ae896457b | ||
|
|
683a90ed09 | ||
|
|
5685e25234 | ||
|
|
6edf083e7b | ||
|
|
995d1495eb | ||
|
|
d5f74631cd | ||
|
|
dd5b9b2e81 | ||
|
|
ca78200c1c | ||
|
|
d73c2a65ae | ||
|
|
0ee2cb8e3c | ||
|
|
5ba429ec73 | ||
|
|
709825d073 | ||
|
|
3fe73af5e8 | ||
|
|
ccc0b0dd7d | ||
|
|
1114ede267 | ||
|
|
5546f12499 | ||
|
|
4f38acb592 | ||
|
|
39f59e023c | ||
|
|
5ed5322fce | ||
|
|
33b926d547 | ||
|
|
af8778c6cd | ||
|
|
bb4ad08cc5 | ||
|
|
ee4eb7b3f0 | ||
|
|
5bc024a6ee | ||
|
|
0546caeb05 | ||
|
|
a75348d3ee | ||
|
|
3f3f947f43 | ||
|
|
5127b7c959 | ||
|
|
a28df78792 | ||
|
|
4f888f16bc | ||
|
|
55ed9d7132 | ||
|
|
779a56c3a1 | ||
|
|
f6440bde07 | ||
|
|
930dc2fd1c | ||
|
|
1e96fd529b | ||
|
|
167c865bb2 | ||
|
|
4e6b6c11a3 | ||
|
|
bfdb71ca91 | ||
|
|
f590f9824e | ||
|
|
b3a087702d | ||
|
|
1a786fb418 | ||
|
|
650d38e212 | ||
|
|
130cb7ad93 | ||
|
|
85e8ffeaa3 | ||
|
|
db40f608fa | ||
|
|
a7b471682a | ||
|
|
4595fea7d7 | ||
|
|
4580f8d9a4 | ||
|
|
37f76fa133 | ||
|
|
5507c35547 | ||
|
|
350328f99c | ||
|
|
91ec6b773d | ||
|
|
c0fdf23133 | ||
|
|
28523a9593 | ||
|
|
07e0b52ea3 | ||
|
|
008e758da8 | ||
|
|
7ce219a6a8 | ||
|
|
1809d4a53f | ||
|
|
54ae026c2b | ||
|
|
57c647fa0e | ||
|
|
9745f23fb2 | ||
|
|
7d2062f298 | ||
|
|
306a1948cf | ||
|
|
ac4c00d3f2 | ||
|
|
db43bc300e | ||
|
|
6494cded62 | ||
|
|
b5c1e7e2da | ||
|
|
83e311870f | ||
|
|
8fc6e3b335 | ||
|
|
18a69e97b3 | ||
|
|
80d8449f02 | ||
|
|
d830aa1d1a | ||
|
|
d473126d4c | ||
|
|
17f8fe69fb | ||
|
|
7263d102c7 | ||
|
|
815b2235a2 | ||
|
|
f61247f8bb | ||
|
|
205d9d528e | ||
|
|
1044f901bd | ||
|
|
de261a38fd | ||
|
|
81776e60fb | ||
|
|
0c179eae86 | ||
|
|
c30de98449 | ||
|
|
47990cde46 | ||
|
|
b098c210ce | ||
|
|
6edd8bf119 | ||
|
|
de0e124ebb | ||
|
|
5fc012a557 | ||
|
|
32afcc3478 | ||
|
|
a27f37945d | ||
|
|
0adfe6911f | ||
|
|
8bb1964b30 | ||
|
|
cc95e1ae63 | ||
|
|
9843f18c96 | ||
|
|
18ea61fcc0 | ||
|
|
5b3fdb6e62 | ||
|
|
c5220c8d06 | ||
|
|
74e87a7fae | ||
|
|
c809f50c3b | ||
|
|
e7e46f78c7 | ||
|
|
2b449a1f3d | ||
|
|
f257f2c551 | ||
|
|
7f91d73d27 | ||
|
|
15a90edb03 | ||
|
|
b2f1e16d9a | ||
|
|
f544455708 | ||
|
|
5118997188 | ||
|
|
b6ae649cd1 | ||
|
|
a6d0d85b84 | ||
|
|
c71c2494af | ||
|
|
4a3a7bc98d | ||
|
|
4e4f7f693d | ||
|
|
7a729c39a6 | ||
|
|
48b757f693 | ||
|
|
b449938730 | ||
|
|
ba55ff6a4b | ||
|
|
2b4bc621ac | ||
|
|
acac2d0fc5 | ||
|
|
6ff5975918 | ||
|
|
8912cfe37b | ||
|
|
9e02c318a1 | ||
|
|
f6b51c21d5 | ||
|
|
df3e4b055f | ||
|
|
ffcd2b4179 | ||
|
|
7afdbc2a53 | ||
|
|
5004481685 | ||
|
|
1905741a7c | ||
|
|
8bf7451107 | ||
|
|
fdfb708ce0 | ||
|
|
68a4eee8bb | ||
|
|
746ebfffbd | ||
|
|
213f8645bc | ||
|
|
1b2541bd84 | ||
|
|
522de89792 | ||
|
|
5feaa45edf | ||
|
|
9333775e0e | ||
|
|
afd15ad450 | ||
|
|
e7fc9e6fe5 | ||
|
|
021f9b1d0e | ||
|
|
dc21f05482 | ||
|
|
c22ccf71a7 | ||
|
|
d5b9a074e6 | ||
|
|
63e6104736 | ||
|
|
de475c9561 | ||
|
|
3f4fa0c67c | ||
|
|
ca3f228b89 | ||
|
|
2b159041ac | ||
|
|
5fa564969e | ||
|
|
8ba8627281 | ||
|
|
a12cb59a51 | ||
|
|
dd124fab33 | ||
|
|
9f8ef4c1f3 | ||
|
|
563c6d0403 | ||
|
|
1bad0fe048 | ||
|
|
b40dcd3164 | ||
|
|
8a0b443d28 | ||
|
|
5f38503ac5 | ||
|
|
231d1209c9 | ||
|
|
06bc180127 | ||
|
|
fb2221fa8d | ||
|
|
e1c7f38bb8 | ||
|
|
a82fa578eb | ||
|
|
0ecefdcc1c | ||
|
|
8bacc8128b | ||
|
|
3dff96152c | ||
|
|
79e198d441 | ||
|
|
e6cf33e262 | ||
|
|
f839ca674b | ||
|
|
f9427d1258 | ||
|
|
bd2cdc9bd0 | ||
|
|
67352311de | ||
|
|
555a7682e1 | ||
|
|
19d94489d7 | ||
|
|
0175cfa986 | ||
|
|
1b0ff36d51 | ||
|
|
f5c499ab60 | ||
|
|
81e3fd346a | ||
|
|
3bca1f5304 | ||
|
|
593e96a31a | ||
|
|
169b783e4f | ||
|
|
f129742a41 | ||
|
|
01016d1b14 | ||
|
|
a883e43acb | ||
|
|
e0d0657e7b | ||
|
|
e4c27bd49c | ||
|
|
7a31fd31eb | ||
|
|
4f0f2c3213 | ||
|
|
d9889b06ad | ||
|
|
9f5cff4ab8 | ||
|
|
958543a171 | ||
|
|
b8e03f5e13 | ||
|
|
e76218b39f | ||
|
|
7d1a375bda | ||
|
|
dfaa80f1e4 | ||
|
|
8939a903be | ||
|
|
d6f1ea78fa | ||
|
|
f25c4c74be | ||
|
|
1619df1ba3 | ||
|
|
566169cdbf | ||
|
|
ee3e631789 | ||
|
|
8202754988 | ||
|
|
447d7596dc | ||
|
|
7c4568066f | ||
|
|
46ee7a5983 | ||
|
|
5a8ef99afa | ||
|
|
571729cfe4 | ||
|
|
c1de316ed6 | ||
|
|
1e316acd64 | ||
|
|
f89460538d | ||
|
|
0bf0062c2c | ||
|
|
540d1b5801 | ||
|
|
8f0d1b7b7b | ||
|
|
5061791dcf | ||
|
|
ce98264552 | ||
|
|
15e6750e11 | ||
|
|
7a20421580 | ||
|
|
f42f06226c | ||
|
|
cce3d74c52 | ||
|
|
7b9fb880f4 | ||
|
|
2a9b0a54d9 | ||
|
|
373e9e9755 | ||
|
|
4115dd5797 | ||
|
|
57bfd251dc | ||
|
|
d324790f66 | ||
|
|
99d3dba440 | ||
|
|
5a44e79ad1 | ||
|
|
86808017db | ||
|
|
f735db9843 | ||
|
|
5a333c23ac | ||
|
|
4d2d51edfa | ||
|
|
dcfd5a0cd8 | ||
|
|
a821c0da50 | ||
|
|
804147e2c4 | ||
|
|
ed346291f9 | ||
|
|
2190f6eff8 | ||
|
|
ce30e24e42 | ||
|
|
d5e13541c8 | ||
|
|
2e707adaa0 | ||
|
|
4d8e36cb05 | ||
|
|
73b710cdde | ||
|
|
09182bf3f3 | ||
|
|
9a945837cd | ||
|
|
b64c821ef4 | ||
|
|
a9ab3bc519 | ||
|
|
94292cea6e | ||
|
|
b5fdeb2a02 |
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
3
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -40,6 +40,9 @@ body:
|
|||||||
- 1.17.1
|
- 1.17.1
|
||||||
- 1.18
|
- 1.18
|
||||||
- 1.19
|
- 1.19
|
||||||
|
- 1.20
|
||||||
|
- 1.21
|
||||||
|
- 1.22
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
- type: input
|
- type: input
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -10,4 +10,4 @@ libs/
|
|||||||
|
|
||||||
collection/
|
collection/
|
||||||
|
|
||||||
src/main/java/com/volmit/iris/util/uniques/
|
/core/src/main/java/com/volmit/iris/util/uniques/
|
||||||
|
|||||||
@@ -30,14 +30,11 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
|
|||||||
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
3. Add `export JAVA_HOME=$(/usr/libexec/java_home)` as a new line
|
||||||
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
|
||||||
5. Quit & Reopen Terminal and verify with `echo $JAVA_HOME`. It should print a directory
|
5. Quit & Reopen Terminal and verify with `echo $JAVA_HOME`. It should print a directory
|
||||||
3. If this is your first time building Iris for MC 1.18+ run `gradlew setup` inside the root Iris project folder.
|
3. Once the project has setup, run `gradlew iris`
|
||||||
Otherwise, skip this step. Grab a coffee, this may take up to 5 minutes depending on your cpu & internet connection.
|
4. The Iris jar will be placed in `Iris/build/Iris-XXX-XXX.jar` Enjoy! Consider supporting us by buying it on spigot!
|
||||||
4. Once the project has setup, run `gradlew iris`
|
|
||||||
5. The Iris jar will be placed in `Iris/build/Iris-XXX-XXX.jar` Enjoy! Consider supporting us by buying it on spigot!
|
|
||||||
|
|
||||||
### IDE Builds (for development)
|
### IDE Builds (for development)
|
||||||
|
|
||||||
* Run `gradlew setup` any time you get dependency issues with craftbukkit
|
|
||||||
* Configure ITJ Gradle to use JDK 17 (in settings, search for gradle)
|
* Configure ITJ Gradle to use JDK 17 (in settings, search for gradle)
|
||||||
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
* Add a build line in the build.gradle for your own build task to directly compile Iris into your plugins folder if you
|
||||||
prefer.
|
prefer.
|
||||||
@@ -69,7 +66,6 @@ IrisAccess access=IrisToolbelt.createWorld() // If you like builders...
|
|||||||
.name("myWorld") // The world name
|
.name("myWorld") // The world name
|
||||||
.dimension("terrifyinghands")
|
.dimension("terrifyinghands")
|
||||||
.seed(69133742) // The world seed
|
.seed(69133742) // The world seed
|
||||||
.headless(true) // Headless make gen go fast
|
|
||||||
.pregen(PregenTask // Define a pregen job to run
|
.pregen(PregenTask // Define a pregen job to run
|
||||||
.builder()
|
.builder()
|
||||||
.center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks)
|
.center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks)
|
||||||
|
|||||||
357
build.gradle
357
build.gradle
@@ -16,21 +16,23 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
buildscript() {
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://jitpack.io'}
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.github.VolmitSoftware:NMSTools:1.0.1'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'java-library'
|
id 'java-library'
|
||||||
id "io.freefair.lombok" version "6.3.0"
|
id "io.github.goooler.shadow" version "8.1.7"
|
||||||
id "com.github.johnrengelman.shadow" version "7.1.2"
|
|
||||||
id "de.undercouch.download" version "5.0.1"
|
id "de.undercouch.download" version "5.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
version '2.7.2-1.20.1'
|
version '3.4.3-1.19.2-1.21.1'
|
||||||
def nmsVersion = '1.20.1' //[NMS]
|
|
||||||
def apiVersion = '1.20'
|
|
||||||
def specialSourceVersion = '1.11.0' //[NMS]
|
|
||||||
def spigotJarVersion = '1.20.1-R0.1-SNAPSHOT' //[NMS]
|
|
||||||
def name = getRootProject().getName() // Defined in settings.gradle
|
|
||||||
def main = 'com.volmit.iris.Iris'
|
|
||||||
|
|
||||||
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
|
||||||
// ======================== WINDOWS =============================
|
// ======================== WINDOWS =============================
|
||||||
@@ -40,124 +42,139 @@ registerCustomOutputTask('ArcaneArts', 'C://Users/arcane/Documents/development/s
|
|||||||
registerCustomOutputTask('Coco', 'D://mcsm/plugins')
|
registerCustomOutputTask('Coco', 'D://mcsm/plugins')
|
||||||
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
|
||||||
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
|
||||||
|
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
|
||||||
|
registerCustomOutputTask('Pixel', 'D://Iris Dimension Engine/1.20.4 - Development/plugins')
|
||||||
|
registerCustomOutputTask('PixelFury', 'C://Users/RePixelatedMC/Iris/1.21 - Development-v3/plugins')
|
||||||
// ========================== UNIX ==============================
|
// ========================== UNIX ==============================
|
||||||
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
|
||||||
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Desktop/REMOTES/RemoteMinecraft/plugins')
|
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
|
||||||
|
registerCustomOutputTaskUnix('PixelMac', '/Users/test/Desktop/mcserver/plugins')
|
||||||
|
registerCustomOutputTaskUnix('CrazyDev22LT', '/home/julian/Desktop/server/plugins')
|
||||||
// ==============================================================
|
// ==============================================================
|
||||||
|
|
||||||
/**
|
def NMS_BINDINGS = Map.of(
|
||||||
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
|
"v1_21_R1", "1.21.1-R0.1-SNAPSHOT",
|
||||||
*/
|
"v1_20_R4", "1.20.6-R0.1-SNAPSHOT",
|
||||||
file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
|
"v1_20_R3", "1.20.4-R0.1-SNAPSHOT",
|
||||||
|
"v1_20_R2", "1.20.2-R0.1-SNAPSHOT",
|
||||||
|
"v1_20_R1", "1.20.1-R0.1-SNAPSHOT",
|
||||||
|
"v1_19_R3", "1.19.4-R0.1-SNAPSHOT",
|
||||||
|
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
|
||||||
|
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
|
||||||
|
)
|
||||||
|
def JVM_VERSION = Map.of(
|
||||||
|
"v1_21_R1", 21,
|
||||||
|
"v1_20_R4", 21,
|
||||||
|
)
|
||||||
|
NMS_BINDINGS.each { nms ->
|
||||||
|
project(":nms:${nms.key}") {
|
||||||
|
apply plugin: 'java'
|
||||||
|
apply plugin: 'com.volmit.nmstools'
|
||||||
|
|
||||||
/**
|
nmsTools {
|
||||||
* Expand properties into plugin yml
|
it.jvm = JVM_VERSION.getOrDefault(nms.key, 17)
|
||||||
*/
|
it.version = nms.value
|
||||||
processResources {
|
}
|
||||||
filesMatching('**/plugin.yml') {
|
|
||||||
expand(
|
|
||||||
'name': name.toString(),
|
|
||||||
'version': version.toString(),
|
|
||||||
'main': main.toString(),
|
|
||||||
'apiversion': apiVersion.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
dependencies {
|
||||||
* Unified repo
|
implementation project(":core")
|
||||||
*/
|
|
||||||
repositories {
|
|
||||||
mavenLocal {
|
|
||||||
content {
|
|
||||||
includeGroup("org.bukkit")
|
|
||||||
includeGroup("org.spigotmc")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mavenCentral()
|
|
||||||
maven { url "https://arcanearts.jfrog.io/artifactory/archives" }
|
|
||||||
maven { url "https://mvn.lumine.io/repository/maven-public/" }
|
|
||||||
maven { url "https://jitpack.io"}
|
|
||||||
|
|
||||||
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
|
|
||||||
maven { url "https://mvn.lumine.io/repository/maven/" }
|
|
||||||
maven { url "https://repo.triumphteam.dev/snapshots" }
|
|
||||||
maven { url "https://repo.mineinabyss.com/releases" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* We need parameter meta for the decree command system
|
|
||||||
*/
|
|
||||||
compileJava {
|
|
||||||
options.compilerArgs << '-parameters'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure Iris for shading
|
|
||||||
*/
|
|
||||||
shadowJar {
|
shadowJar {
|
||||||
|
NMS_BINDINGS.each {
|
||||||
|
dependsOn(":nms:${it.key}:remap")
|
||||||
|
from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}-mapped.jar")
|
||||||
|
}
|
||||||
|
|
||||||
//minimize()
|
//minimize()
|
||||||
append("plugin.yml")
|
append("plugin.yml")
|
||||||
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
relocate 'com.dfsek.paralithic', 'com.volmit.iris.util.paralithic'
|
||||||
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
relocate 'io.papermc.lib', 'com.volmit.iris.util.paper'
|
||||||
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
relocate 'net.kyori', 'com.volmit.iris.util.kyori'
|
||||||
dependencies {
|
archiveFileName.set("Iris-${project.version}.jar")
|
||||||
include(dependency('io.papermc:paperlib'))
|
|
||||||
include(dependency('com.dfsek:Paralithic'))
|
|
||||||
include(dependency('net.kyori:'))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations.all {
|
dependencies {
|
||||||
|
implementation project(':core')
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations.configureEach {
|
||||||
resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
|
resolutionStrategy.cacheChangingModulesFor 60, 'minutes'
|
||||||
resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
|
resolutionStrategy.cacheDynamicVersionsFor 60, 'minutes'
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
allprojects {
|
||||||
* Dependencies.
|
apply plugin: 'java'
|
||||||
*
|
|
||||||
* Provided or classpath dependencies are not shaded and are available on the runtime classpath
|
|
||||||
*
|
|
||||||
* Shaded dependencies are not available at runtime, nor are they available on mvn central so they
|
|
||||||
* need to be shaded into the jar (increasing binary size)
|
|
||||||
*
|
|
||||||
* Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
|
|
||||||
* plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
|
|
||||||
* these dependencies if they are available on mvn central.
|
|
||||||
*/
|
|
||||||
dependencies {
|
|
||||||
// Provided or Classpath
|
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.24'
|
|
||||||
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
|
||||||
implementation 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT'
|
|
||||||
implementation 'org.bukkit:craftbukkit:1.20.1-R0.1-SNAPSHOT:remapped-mojang' //[NMS]
|
|
||||||
|
|
||||||
// Third Party Integrations
|
repositories {
|
||||||
implementation 'com.github.oraxen:oraxen:1.152.5'
|
mavenCentral()
|
||||||
implementation 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
maven { url "https://repo.papermc.io/repository/maven-public/" }
|
||||||
implementation 'me.clip:placeholderapi:2.11.3'
|
maven { url "https://repo.codemc.org/repository/maven-public" }
|
||||||
//implementation files('libs/CustomItems.jar')
|
maven { url "https://mvn.lumine.io/repository/maven-public/" }
|
||||||
|
maven { url "https://jitpack.io" }
|
||||||
|
|
||||||
// Shaded
|
maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots" }
|
||||||
implementation 'com.dfsek:Paralithic:0.4.0'
|
maven { url "https://mvn.lumine.io/repository/maven/" }
|
||||||
implementation 'io.papermc:paperlib:1.0.5'
|
maven { url "https://repo.triumphteam.dev/snapshots" }
|
||||||
implementation "net.kyori:adventure-text-minimessage:4.13.1"
|
maven { url "https://repo.mineinabyss.com/releases" }
|
||||||
implementation 'net.kyori:adventure-platform-bukkit:4.3.0'
|
maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
|
||||||
implementation 'net.kyori:adventure-api:4.13.1'
|
maven { url "https://repo.oraxen.com/releases" }
|
||||||
implementation 'io.lumine:Mythic-Dist:5.2.1'
|
}
|
||||||
|
|
||||||
// Dynamically Loaded
|
dependencies {
|
||||||
implementation 'io.timeandspace:smoothie-map:2.0.2'
|
// Provided or Classpath
|
||||||
implementation 'it.unimi.dsi:fastutil:8.5.8'
|
compileOnly 'org.projectlombok:lombok:1.18.24'
|
||||||
implementation 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
annotationProcessor 'org.projectlombok:lombok:1.18.24'
|
||||||
implementation 'org.zeroturnaround:zt-zip:1.14'
|
|
||||||
implementation 'com.google.code.gson:gson:2.9.0'
|
// Shaded
|
||||||
implementation 'org.ow2.asm:asm:9.2'
|
implementation 'com.dfsek:Paralithic:0.4.0'
|
||||||
implementation 'com.google.guava:guava:31.1-jre'
|
implementation 'io.papermc:paperlib:1.0.5'
|
||||||
implementation 'bsf:bsf:2.4.0'
|
implementation "net.kyori:adventure-text-minimessage:4.17.0"
|
||||||
implementation 'rhino:js:1.7R2'
|
implementation 'net.kyori:adventure-platform-bukkit:4.3.4'
|
||||||
implementation 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
implementation 'net.kyori:adventure-api:4.17.0'
|
||||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
//implementation 'org.bytedeco:javacpp:1.5.10'
|
||||||
|
//implementation 'org.bytedeco:cuda-platform:12.3-8.9-1.5.10'
|
||||||
|
compileOnly 'io.lumine:Mythic-Dist:5.2.1'
|
||||||
|
compileOnly 'io.lumine:MythicCrucible-Dist:2.0.0'
|
||||||
|
|
||||||
|
// Dynamically Loaded
|
||||||
|
compileOnly 'io.timeandspace:smoothie-map:2.0.2'
|
||||||
|
compileOnly 'it.unimi.dsi:fastutil:8.5.8'
|
||||||
|
compileOnly 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.4.2'
|
||||||
|
compileOnly 'org.zeroturnaround:zt-zip:1.14'
|
||||||
|
compileOnly 'com.google.code.gson:gson:2.10.1'
|
||||||
|
compileOnly 'org.ow2.asm:asm:9.2'
|
||||||
|
compileOnly 'com.google.guava:guava:33.0.0-jre'
|
||||||
|
compileOnly 'bsf:bsf:2.4.0'
|
||||||
|
compileOnly 'rhino:js:1.7R2'
|
||||||
|
compileOnly 'com.github.ben-manes.caffeine:caffeine:3.0.6'
|
||||||
|
compileOnly 'org.apache.commons:commons-lang3:3.12.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need parameter meta for the decree command system
|
||||||
|
*/
|
||||||
|
compileJava {
|
||||||
|
options.compilerArgs << '-parameters'
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
javadoc {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
options.addStringOption('Xdoclint:none', '-quiet')
|
||||||
|
}
|
||||||
|
|
||||||
|
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||||
|
archiveClassifier.set('sources')
|
||||||
|
from sourceSets.main.allSource
|
||||||
|
}
|
||||||
|
|
||||||
|
task javadocJar(type: Jar, dependsOn: javadoc) {
|
||||||
|
archiveClassifier.set('javadoc')
|
||||||
|
from javadoc.destinationDir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (JavaVersion.current().toString() != "17") {
|
if (JavaVersion.current().toString() != "17") {
|
||||||
@@ -178,125 +195,27 @@ if (JavaVersion.current().toString() != "17") {
|
|||||||
System.exit(69);
|
System.exit(69);
|
||||||
}
|
}
|
||||||
|
|
||||||
def buildToolsJar = new File(buildDir, "buildtools/BuildTools.jar");
|
task iris(type: Copy) {
|
||||||
def specialSourceJar = new File(buildDir, "specialsource/SpecialSource.jar");
|
|
||||||
def buildToolsFolder = new File(buildDir, "buildtools");
|
|
||||||
def specialSourceFolder = new File(buildDir, "specialsource");
|
|
||||||
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nmsVersion + ".jar");
|
|
||||||
def outputShadeJar = new File(buildDir, "libs/Iris-" + version + "-all.jar");
|
|
||||||
def ssiJar = new File(buildDir, "specialsource/Iris-" + version + "-all.jar");
|
|
||||||
def ssobfJar = new File(buildDir, "specialsource/Iris-" + version + "-rmo.jar");
|
|
||||||
def ssJar = new File(buildDir, "specialsource/Iris-" + version + "-rma.jar");
|
|
||||||
def homePath = System.properties['user.home']
|
|
||||||
def m2 = new File(homePath + "/.m2/repository")
|
|
||||||
def m2s = m2.getAbsolutePath();
|
|
||||||
|
|
||||||
// ======================== Building Mapped Jars =============================
|
|
||||||
task downloadBuildtools(type: Download) {
|
|
||||||
group "remapping"
|
|
||||||
src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar'
|
|
||||||
dest buildToolsJar
|
|
||||||
onlyIf {
|
|
||||||
!buildToolsJar.exists()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task downloadSpecialSource(type: Download) {
|
|
||||||
group "remapping"
|
|
||||||
src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar'
|
|
||||||
dest specialSourceJar
|
|
||||||
onlyIf {
|
|
||||||
!specialSourceJar.exists()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task executeBuildTools(dependsOn: downloadBuildtools, type: JavaExec)
|
|
||||||
{
|
|
||||||
group "remapping"
|
|
||||||
classpath = files(buildToolsJar)
|
|
||||||
workingDir = buildToolsFolder
|
|
||||||
args = [
|
|
||||||
"--rev",
|
|
||||||
nmsVersion,
|
|
||||||
"--compile",
|
|
||||||
"craftbukkit",
|
|
||||||
"--remap"
|
|
||||||
]
|
|
||||||
onlyIf {
|
|
||||||
!buildToolsHint.exists()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task copyBuildToSpecialSource(type: Copy)
|
|
||||||
{
|
|
||||||
group "remapping"
|
|
||||||
from outputShadeJar
|
|
||||||
into specialSourceFolder
|
|
||||||
dependsOn(downloadSpecialSource, shadowJar)
|
|
||||||
}
|
|
||||||
|
|
||||||
task specialSourceRemapObfuscate(type: JavaExec)
|
|
||||||
{
|
|
||||||
group "remapping"
|
|
||||||
dependsOn(copyBuildToSpecialSource, downloadSpecialSource, shadowJar)
|
|
||||||
workingDir = specialSourceFolder
|
|
||||||
classpath = files(specialSourceJar,
|
|
||||||
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-mojang.jar"))
|
|
||||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
|
||||||
args = [
|
|
||||||
"--live",
|
|
||||||
"-i",
|
|
||||||
ssiJar.getName(),
|
|
||||||
"-o",
|
|
||||||
ssobfJar.getName(),
|
|
||||||
"-m",
|
|
||||||
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-mojang.txt",
|
|
||||||
"--reverse",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
task specialSourceRemap(type: JavaExec)
|
|
||||||
{
|
|
||||||
group "remapping"
|
|
||||||
dependsOn(specialSourceRemapObfuscate)
|
|
||||||
workingDir = specialSourceFolder
|
|
||||||
classpath = files(specialSourceJar,
|
|
||||||
new File(m2s + "/org/spigotmc/spigot/" + spigotJarVersion + "/spigot-" + spigotJarVersion + "-remapped-obf.jar"))
|
|
||||||
mainClass = "net.md_5.specialsource.SpecialSource"
|
|
||||||
args = [
|
|
||||||
"--live",
|
|
||||||
"-i",
|
|
||||||
ssobfJar.getName(),
|
|
||||||
"-o",
|
|
||||||
ssJar.getName(),
|
|
||||||
"-m",
|
|
||||||
m2s + "/org/spigotmc/minecraft-server/" + spigotJarVersion + "/minecraft-server-" + spigotJarVersion + "-maps-spigot.csrg"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks.compileJava.dependsOn(executeBuildTools)
|
|
||||||
|
|
||||||
compileJava {
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
}
|
|
||||||
|
|
||||||
task setup()
|
|
||||||
{
|
|
||||||
group("iris")
|
|
||||||
dependsOn(clean, executeBuildTools)
|
|
||||||
}
|
|
||||||
|
|
||||||
task iris(type: Copy)
|
|
||||||
{
|
|
||||||
group "iris"
|
group "iris"
|
||||||
from ssJar
|
from new File(layout.buildDirectory.asFile.get(), "libs/Iris-${version}.jar")
|
||||||
into buildDir
|
into layout.buildDirectory.asFile.get()
|
||||||
rename { String fileName ->
|
dependsOn(build)
|
||||||
fileName.replace('Iris-' + version + '-rma.jar', "Iris-" + version + ".jar")
|
|
||||||
}
|
|
||||||
dependsOn(specialSourceRemap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// with classifier: 'javadoc' and 'sources'
|
||||||
|
task irisDev(type: Copy) {
|
||||||
|
group "iris"
|
||||||
|
from("core/build/libs/core-javadoc.jar", "core/build/libs/core-sources.jar")
|
||||||
|
rename { String fileName ->
|
||||||
|
fileName.replace("core", "Iris-${version}")
|
||||||
|
}
|
||||||
|
into layout.buildDirectory.asFile.get()
|
||||||
|
dependsOn(iris)
|
||||||
|
dependsOn("core:sourcesJar")
|
||||||
|
dependsOn("core:javadocJar")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def registerCustomOutputTask(name, path) {
|
def registerCustomOutputTask(name, path) {
|
||||||
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
|
||||||
return;
|
return;
|
||||||
@@ -330,3 +249,5 @@ def registerCustomOutputTaskUnix(name, path) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.build.dependsOn(shadowJar)
|
||||||
|
|||||||
92
core/build.gradle
Normal file
92
core/build.gradle
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'java-library'
|
||||||
|
id "io.freefair.lombok" version "8.6"
|
||||||
|
}
|
||||||
|
|
||||||
|
def apiVersion = '1.19'
|
||||||
|
def main = 'com.volmit.iris.Iris'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need parameter meta for the decree command system
|
||||||
|
*/
|
||||||
|
compileJava {
|
||||||
|
options.compilerArgs << '-parameters'
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'}
|
||||||
|
maven { url 'https://repo.auxilor.io/repository/maven-public/' }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependencies.
|
||||||
|
*
|
||||||
|
* Provided or classpath dependencies are not shaded and are available on the runtime classpath
|
||||||
|
*
|
||||||
|
* Shaded dependencies are not available at runtime, nor are they available on mvn central so they
|
||||||
|
* need to be shaded into the jar (increasing binary size)
|
||||||
|
*
|
||||||
|
* Dynamically loaded dependencies are defined in the plugin.yml (updating these must be updated in the
|
||||||
|
* plugin.yml also, otherwise they wont be available). These do not increase binary size). Only declare
|
||||||
|
* these dependencies if they are available on mvn central.
|
||||||
|
*/
|
||||||
|
dependencies {
|
||||||
|
// Provided or Classpath
|
||||||
|
compileOnly 'org.spigotmc:spigot-api:1.20.1-R0.1-SNAPSHOT'
|
||||||
|
compileOnly 'org.apache.logging.log4j:log4j-api:2.19.0'
|
||||||
|
compileOnly 'org.apache.logging.log4j:log4j-core:2.19.0'
|
||||||
|
compileOnly 'commons-io:commons-io:2.14.0'
|
||||||
|
compileOnly 'commons-lang:commons-lang:2.6'
|
||||||
|
compileOnly 'com.github.oshi:oshi-core:5.8.5'
|
||||||
|
compileOnly 'org.lz4:lz4-java:1.8.0'
|
||||||
|
|
||||||
|
// Third Party Integrations
|
||||||
|
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
|
||||||
|
compileOnly 'io.th0rgal:oraxen:1.173.0'
|
||||||
|
compileOnly 'com.github.LoneDev6:api-itemsadder:3.4.1-r4'
|
||||||
|
compileOnly 'com.github.PlaceholderAPI:placeholderapi:2.11.3'
|
||||||
|
compileOnly 'com.github.Ssomar-Developement:SCore:4.23.10.8'
|
||||||
|
compileOnly 'net.Indyuce:MMOItems-API:6.9.5-SNAPSHOT'
|
||||||
|
compileOnly 'com.willfp:EcoItems:5.44.0'
|
||||||
|
//implementation files('libs/CustomItems.jar')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gradle is weird sometimes, we need to delete the plugin yml from the build folder to actually filter properly.
|
||||||
|
*/
|
||||||
|
file(jar.archiveFile.get().getAsFile().getParentFile().getParentFile().getParentFile().getAbsolutePath() + '/build/resources/main/plugin.yml').delete()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand properties into plugin yml
|
||||||
|
*/
|
||||||
|
processResources {
|
||||||
|
filesMatching('**/plugin.yml') {
|
||||||
|
expand(
|
||||||
|
'name': rootProject.name.toString(),
|
||||||
|
'version': rootProject.version.toString(),
|
||||||
|
'main': main.toString(),
|
||||||
|
'apiversion': apiVersion.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,7 +28,7 @@ import com.volmit.iris.core.link.MultiverseCoreLink;
|
|||||||
import com.volmit.iris.core.link.MythicMobsLink;
|
import com.volmit.iris.core.link.MythicMobsLink;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.nms.v20.NMSBinding1_20_1;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
@@ -38,6 +38,8 @@ import com.volmit.iris.engine.object.IrisDimension;
|
|||||||
import com.volmit.iris.engine.object.IrisWorld;
|
import com.volmit.iris.engine.object.IrisWorld;
|
||||||
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
||||||
|
import com.volmit.iris.core.safeguard.IrisSafeguard;
|
||||||
|
import com.volmit.iris.core.safeguard.UtilsSFG;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.exceptions.IrisException;
|
import com.volmit.iris.util.exceptions.IrisException;
|
||||||
@@ -50,6 +52,7 @@ import com.volmit.iris.util.io.InstanceState;
|
|||||||
import com.volmit.iris.util.io.JarScanner;
|
import com.volmit.iris.util.io.JarScanner;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.misc.getHardware;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.Metrics;
|
import com.volmit.iris.util.plugin.Metrics;
|
||||||
@@ -60,6 +63,7 @@ import com.volmit.iris.util.scheduling.J;
|
|||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
import com.volmit.iris.util.scheduling.ShurikenQueue;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
|
import lombok.Getter;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@@ -85,13 +89,22 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.OperatingSystemMXBean;
|
||||||
|
import java.lang.management.ThreadMXBean;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||||
|
import static com.volmit.iris.core.safeguard.ServerBootSFG.passedserversoftware;
|
||||||
|
import static com.volmit.iris.util.misc.getHardware.getCPUModel;
|
||||||
|
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
public class Iris extends VolmitPlugin implements Listener {
|
public class Iris extends VolmitPlugin implements Listener {
|
||||||
public static final String OVERWORLD_TAG = "3004";
|
public static final String OVERWORLD_TAG = "3800";
|
||||||
|
|
||||||
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
private static final Queue<Runnable> syncJobs = new ShurikenQueue<>();
|
||||||
|
|
||||||
@@ -116,6 +129,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
private KMap<Class<? extends IrisService>, IrisService> services;
|
private KMap<Class<? extends IrisService>, IrisService> services;
|
||||||
|
|
||||||
public static VolmitSender getSender() {
|
public static VolmitSender getSender() {
|
||||||
|
if (sender == null) {
|
||||||
|
sender = new VolmitSender(Bukkit.getConsoleSender());
|
||||||
|
sender.setTag(instance.getTag());
|
||||||
|
}
|
||||||
return sender;
|
return sender;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,10 +199,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
public static void msg(String string) {
|
public static void msg(String string) {
|
||||||
try {
|
try {
|
||||||
sender.sendMessage(string);
|
getSender().sendMessage(string);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
try {
|
try {
|
||||||
System.out.println(instance.getTag() + string.replaceAll("(<([^>]+)>)", ""));
|
instance.getLogger().info(instance.getTag() + string.replaceAll("(<([^>]+)>)", ""));
|
||||||
} catch (Throwable ignored1) {
|
} catch (Throwable ignored1) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -308,6 +325,9 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
public static void info(String format, Object... args) {
|
public static void info(String format, Object... args) {
|
||||||
msg(C.WHITE + String.format(format, args));
|
msg(C.WHITE + String.format(format, args));
|
||||||
}
|
}
|
||||||
|
public static void safeguard(String format, Object... args) {
|
||||||
|
msg(C.RESET + String.format(format, args));
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static void later(NastyRunnable object) {
|
public static void later(NastyRunnable object) {
|
||||||
@@ -336,7 +356,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getJavaVersion() {
|
public static int getJavaVersion() {
|
||||||
String version = System.getProperty("java.version");
|
String version = System.getProperty("java.version");
|
||||||
if (version.startsWith("1.")) {
|
if (version.startsWith("1.")) {
|
||||||
version = version.substring(2, 3);
|
version = version.substring(2, 3);
|
||||||
@@ -349,6 +369,13 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
return Integer.parseInt(version);
|
return Integer.parseInt(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getJava() {
|
||||||
|
String javaRuntimeName = System.getProperty("java.vm.name");
|
||||||
|
String javaRuntimeVendor = System.getProperty("java.vendor");
|
||||||
|
String javaRuntimeVersion = System.getProperty("java.vm.version");
|
||||||
|
return String.format("%s %s (build %s)", javaRuntimeName, javaRuntimeVendor, javaRuntimeVersion);
|
||||||
|
}
|
||||||
|
|
||||||
public static void reportErrorChunk(int x, int z, Throwable e, String extra) {
|
public static void reportErrorChunk(int x, int z, Throwable e, String extra) {
|
||||||
if (IrisSettings.get().getGeneral().isDebug()) {
|
if (IrisSettings.get().getGeneral().isDebug()) {
|
||||||
File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt");
|
File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt");
|
||||||
@@ -411,7 +438,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pw.close();
|
pw.close();
|
||||||
System.out.println("DUMPED! See " + fi.getAbsolutePath());
|
Iris.info("DUMPED! See " + fi.getAbsolutePath());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@@ -428,17 +455,15 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
private static void fixShading() {
|
private static void fixShading() {
|
||||||
ShadeFix.fix(ComponentSerializer.class);
|
ShadeFix.fix(ComponentSerializer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enable() {
|
private void enable() {
|
||||||
instance = this;
|
instance = this;
|
||||||
services = new KMap<>();
|
services = new KMap<>();
|
||||||
|
setupAudience();
|
||||||
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
|
||||||
INMS.get();
|
INMS.get();
|
||||||
IO.delete(new File("iris"));
|
IO.delete(new File("iris"));
|
||||||
setupAudience();
|
IrisSafeguard.IrisSafeguardSystem();
|
||||||
sender = new VolmitSender(Bukkit.getConsoleSender());
|
getSender().setTag(getTag());
|
||||||
sender.setTag(getTag());
|
|
||||||
instance = this;
|
|
||||||
compat = IrisCompat.configured(getDataFile("compat.json"));
|
compat = IrisCompat.configured(getDataFile("compat.json"));
|
||||||
linkMultiverseCore = new MultiverseCoreLink();
|
linkMultiverseCore = new MultiverseCoreLink();
|
||||||
linkMythicMobs = new MythicMobsLink();
|
linkMythicMobs = new MythicMobsLink();
|
||||||
@@ -455,6 +480,8 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
J.s(this::setupPapi);
|
J.s(this::setupPapi);
|
||||||
J.a(ServerConfigurator::configure, 20);
|
J.a(ServerConfigurator::configure, 20);
|
||||||
splash();
|
splash();
|
||||||
|
UtilsSFG.splash();
|
||||||
|
|
||||||
autoStartStudio();
|
autoStartStudio();
|
||||||
checkForBukkitWorlds();
|
checkForBukkitWorlds();
|
||||||
IrisToolbelt.retainMantleDataForSlice(String.class.getCanonicalName());
|
IrisToolbelt.retainMantleDataForSlice(String.class.getCanonicalName());
|
||||||
@@ -509,7 +536,7 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
Iris.info("Starting up auto Studio!");
|
Iris.info("Starting up auto Studio!");
|
||||||
try {
|
try {
|
||||||
Player r = new KList<>(getServer().getOnlinePlayers()).getRandom();
|
Player r = new KList<>(getServer().getOnlinePlayers()).getRandom();
|
||||||
Iris.service(StudioSVC.class).open(r != null ? new VolmitSender(r) : sender, 1337, IrisSettings.get().getGenerator().getDefaultWorldType(), (w) -> {
|
Iris.service(StudioSVC.class).open(r != null ? new VolmitSender(r) : getSender(), 1337, IrisSettings.get().getGenerator().getDefaultWorldType(), (w) -> {
|
||||||
J.s(() -> {
|
J.s(() -> {
|
||||||
for (Player i : getServer().getOnlinePlayers()) {
|
for (Player i : getServer().getOnlinePlayers()) {
|
||||||
i.setGameMode(GameMode.SPECTATOR);
|
i.setGameMode(GameMode.SPECTATOR);
|
||||||
@@ -573,19 +600,26 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTag(String subTag) {
|
public String getTag(String subTag) {
|
||||||
|
if (unstablemode) {
|
||||||
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.RED + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
|
}
|
||||||
|
if (warningmode) {
|
||||||
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.GOLD + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
|
}
|
||||||
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
return C.BOLD + "" + C.DARK_GRAY + "[" + C.BOLD + "" + C.IRIS + "Iris" + C.BOLD + C.DARK_GRAY + "]" + C.RESET + "" + C.GRAY + ": ";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setupChecks() {
|
private boolean setupChecks() {
|
||||||
boolean passed = true;
|
boolean passed = true;
|
||||||
Iris.info("Version Information: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion());
|
Iris.info("Version Information: " + instance.getServer().getVersion() + " | " + instance.getServer().getBukkitVersion());
|
||||||
if (!instance.getServer().getBukkitVersion().contains(NMSBinding1_20_1.NMS_VERSION)) {
|
if (INMS.get() instanceof NMSBinding1X) {
|
||||||
passed = false;
|
passed = false;
|
||||||
Iris.warn("============================================");
|
Iris.warn("============================================");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
Iris.warn("Iris is not compatible with this version of Minecraft.\nPlease use " + NMSBinding1_20_1.NMS_VERSION + " or use an older version of Iris.");
|
Iris.warn("Iris is not compatible with this version of Minecraft.");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
Iris.warn("=");
|
Iris.warn("=");
|
||||||
@@ -703,10 +737,10 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
File ff = new File(w.worldFolder(), "iris/pack");
|
File ff = new File(w.worldFolder(), "iris/pack");
|
||||||
if (!ff.exists() || ff.listFiles().length == 0) {
|
if (!ff.exists() || ff.listFiles().length == 0) {
|
||||||
ff.mkdirs();
|
ff.mkdirs();
|
||||||
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
|
service(StudioSVC.class).installIntoWorld(getSender(), dim.getLoadKey(), w.worldFolder());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
|
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void splash() {
|
public void splash() {
|
||||||
@@ -714,12 +748,17 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @NoArgsConstructor
|
|
||||||
String padd = Form.repeat(" ", 8);
|
String padd = Form.repeat(" ", 8);
|
||||||
String padd2 = Form.repeat(" ", 4);
|
String padd2 = Form.repeat(" ", 4);
|
||||||
String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "<rainbow>Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion(),
|
String[] info = {"", "", "", "", "", padd2 + C.IRIS + " Iris", padd2 + C.GRAY + " by " + "<rainbow>Volmit Software", padd2 + C.GRAY + " v" + C.IRIS + getDescription().getVersion()};
|
||||||
};
|
if (unstablemode) {
|
||||||
String[] splash = {
|
info = new String[]{"", "", "", "", "", padd2 + C.RED + " Iris", padd2 + C.GRAY + " by " + C.DARK_RED + "Volmit Software", padd2 + C.GRAY + " v" + C.RED + getDescription().getVersion()};
|
||||||
|
}
|
||||||
|
if (warningmode) {
|
||||||
|
info = new String[]{"", "", "", "", "", padd2 + C.GOLD + " Iris", padd2 + C.GRAY + " by " + C.GOLD + "Volmit Software", padd2 + C.GRAY + " v" + C.GOLD + getDescription().getVersion()};
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] splashstable = {
|
||||||
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ",
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.IRIS + " .(((()))). ",
|
||||||
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ",
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.IRIS + " .((((((())))))). ",
|
||||||
@@ -732,10 +771,75 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
padd + C.GRAY + "" + C.IRIS + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
};
|
};
|
||||||
//@done
|
|
||||||
Iris.info("Server type & version: " + Bukkit.getVersion());
|
String[] splashunstable = {
|
||||||
Iris.info("Bukkit version: " + Bukkit.getBukkitVersion());
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
Iris.info("Java version: " + getJavaVersion());
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.RED + " .(((()))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.RED + " .((((((())))))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.RED + " ((((((((())))))))) " + C.GRAY + " @",
|
||||||
|
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.RED + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||||
|
padd + C.GRAY + "@@@&&" + C.RED + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||||
|
padd + C.GRAY + "@@" + C.RED + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||||
|
padd + C.GRAY + "@" + C.RED + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.RED + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.RED + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
|
};
|
||||||
|
String[] splashwarning = {
|
||||||
|
padd + C.GRAY + " @@@@@@@@@@@@@@" + C.DARK_GRAY + "@@@",
|
||||||
|
padd + C.GRAY + " @@&&&&&&&&&" + C.DARK_GRAY + "&&&&&&" + C.GOLD + " .(((()))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&&&&" + C.DARK_GRAY + "&&&&&" + C.GOLD + " .((((((())))))). ",
|
||||||
|
padd + C.GRAY + "@@@&&&&&" + C.DARK_GRAY + "&&&&&&&" + C.GOLD + " ((((((((())))))))) " + C.GRAY + " @",
|
||||||
|
padd + C.GRAY + "@@@&&&&" + C.DARK_GRAY + "@@@@@&" + C.GOLD + " ((((((((-))))))))) " + C.GRAY + " @@",
|
||||||
|
padd + C.GRAY + "@@@&&" + C.GOLD + " ((((((({ })))))))) " + C.GRAY + " &&@@@",
|
||||||
|
padd + C.GRAY + "@@" + C.GOLD + " ((((((((-))))))))) " + C.DARK_GRAY + "&@@@@@" + C.GRAY + "&&&&@@@",
|
||||||
|
padd + C.GRAY + "@" + C.GOLD + " ((((((((())))))))) " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.GOLD + " '((((((()))))))' " + C.DARK_GRAY + "&&&&&" + C.GRAY + "&&&&&&&&@@@",
|
||||||
|
padd + C.GRAY + "" + C.GOLD + " '(((())))' " + C.DARK_GRAY + "&&&&&&&&" + C.GRAY + "&&&&&&&@@",
|
||||||
|
padd + C.GRAY + " " + C.DARK_GRAY + "@@@" + C.GRAY + "@@@@@@@@@@@@@@"
|
||||||
|
};
|
||||||
|
String[] splash;
|
||||||
|
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||||
|
if (unstablemode) {
|
||||||
|
splash = splashunstable;
|
||||||
|
} else if (warningmode) {
|
||||||
|
splash = splashwarning;
|
||||||
|
} else {
|
||||||
|
splash = splashstable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passedserversoftware) {
|
||||||
|
Iris.info("Server type & version: " + C.RED + Bukkit.getVersion());
|
||||||
|
} else { Iris.info("Server type & version: " + Bukkit.getVersion()); }
|
||||||
|
Iris.info("Java: " + getJava());
|
||||||
|
try {
|
||||||
|
if (getCPUModel().contains("Intel")) {
|
||||||
|
Iris.info("Server Cpu: " + C.BLUE + getCPUModel());
|
||||||
|
}
|
||||||
|
if (getCPUModel().contains("Ryzen")) {
|
||||||
|
Iris.info("Server Cpu: " + C.RED + getCPUModel());
|
||||||
|
}
|
||||||
|
if (!getCPUModel().contains("Ryzen") && !getCPUModel().contains("Intel")) {
|
||||||
|
Iris.info("Server Cpu: " + C.GRAY + getCPUModel());
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e){
|
||||||
|
Iris.info("Server Cpu: " + C.DARK_RED + "Failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.info("Threads: " + C.GRAY + Runtime.getRuntime().availableProcessors());
|
||||||
|
if (!instance.getServer().getVersion().contains("Purpur")) {
|
||||||
|
if (instance.getServer().getVersion().contains("Spigot") && instance.getServer().getVersion().contains("Bukkit")) {
|
||||||
|
Iris.info(C.RED + " Iris requires paper or above to function properly..");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.YELLOW + "Purpur is recommended to use with iris.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (getHardware.getProcessMemory() < 5999) {
|
||||||
|
Iris.warn("6GB+ Ram is recommended");
|
||||||
|
Iris.warn("Process Memory: " + getHardware.getProcessMemory() + " MB");
|
||||||
|
}
|
||||||
|
Iris.info("Bukkit distro: " + Bukkit.getName());
|
||||||
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
|
||||||
setupChecks();
|
setupChecks();
|
||||||
printPacks();
|
printPacks();
|
||||||
@@ -768,4 +872,33 @@ public class Iris extends VolmitPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
Iris.info(" " + dimName + " v" + version);
|
Iris.info(" " + dimName + " v" + version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getIrisVersion() {
|
||||||
|
String input = Iris.instance.getDescription().getVersion();
|
||||||
|
int hyphenIndex = input.indexOf('-');
|
||||||
|
if (hyphenIndex != -1) {
|
||||||
|
String result = input.substring(0, hyphenIndex);
|
||||||
|
result = result.replaceAll("\\.", "");
|
||||||
|
return Integer.parseInt(result);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMCVersion() {
|
||||||
|
try {
|
||||||
|
String version = Bukkit.getVersion();
|
||||||
|
Matcher matcher = Pattern.compile("\\(MC: ([\\d.]+)\\)").matcher(version);
|
||||||
|
if (matcher.find()) {
|
||||||
|
version = matcher.group(1).replaceAll("\\.", "");
|
||||||
|
long versionNumber = Long.parseLong(version);
|
||||||
|
if (versionNumber > Integer.MAX_VALUE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int) versionNumber;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,10 @@ import com.volmit.iris.util.io.IO;
|
|||||||
import com.volmit.iris.util.json.JSONException;
|
import com.volmit.iris.util.json.JSONException;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -41,8 +44,11 @@ public class IrisSettings {
|
|||||||
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
private IrisSettingsConcurrency concurrency = new IrisSettingsConcurrency();
|
||||||
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
private IrisSettingsStudio studio = new IrisSettingsStudio();
|
||||||
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
private IrisSettingsPerformance performance = new IrisSettingsPerformance();
|
||||||
|
private IrisSettingsUpdater updater = new IrisSettingsUpdater();
|
||||||
|
|
||||||
public static int getThreadCount(int c) {
|
public static int getThreadCount(int c) {
|
||||||
|
if (System.getProperty("os.name").toLowerCase().contains("win"))
|
||||||
|
return Runtime.getRuntime().availableProcessors();
|
||||||
return switch (c) {
|
return switch (c) {
|
||||||
case -1, -2, -4 -> Runtime.getRuntime().availableProcessors() / -c;
|
case -1, -2, -4 -> Runtime.getRuntime().availableProcessors() / -c;
|
||||||
case 0, 1, 2 -> 1;
|
case 0, 1, 2 -> 1;
|
||||||
@@ -131,11 +137,12 @@ public class IrisSettings {
|
|||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsConcurrency {
|
public static class IrisSettingsConcurrency {
|
||||||
public int parallelism = -1;
|
public int parallelism = -1;
|
||||||
|
public boolean windowsFullPerformance = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsPerformance {
|
public static class IrisSettingsPerformance {
|
||||||
public boolean trimMantleInStudio = false;
|
public boolean trimMantleInStudio = false;
|
||||||
public int mantleKeepAlive = 30;
|
public int mantleKeepAlive = 30;
|
||||||
public int cacheSize = 4_096;
|
public int cacheSize = 4_096;
|
||||||
public int resourceLoaderCacheSize = 1_024;
|
public int resourceLoaderCacheSize = 1_024;
|
||||||
@@ -143,8 +150,33 @@ public class IrisSettings {
|
|||||||
public int scriptLoaderCacheSize = 512;
|
public int scriptLoaderCacheSize = 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class IrisSettingsUpdater {
|
||||||
|
public double threadMultiplier = 2;
|
||||||
|
public double chunkLoadSensitivity = 0.7;
|
||||||
|
public MsRange emptyMsRange = new MsRange(80, 100);
|
||||||
|
public MsRange defaultMsRange = new MsRange(20, 40);
|
||||||
|
|
||||||
|
public double getThreadMultiplier() {
|
||||||
|
return Math.min(Math.abs(threadMultiplier), 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChunkLoadSensitivity() {
|
||||||
|
return Math.min(chunkLoadSensitivity, 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class MsRange {
|
||||||
|
public int min = 20;
|
||||||
|
public int max = 40;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public static class IrisSettingsGeneral {
|
public static class IrisSettingsGeneral {
|
||||||
|
public boolean DoomsdayAnnihilationSelfDestructMode = false;
|
||||||
public boolean commandSounds = true;
|
public boolean commandSounds = true;
|
||||||
public boolean debug = false;
|
public boolean debug = false;
|
||||||
public boolean disableNMS = false;
|
public boolean disableNMS = false;
|
||||||
@@ -169,6 +201,7 @@ public class IrisSettings {
|
|||||||
public static class IrisSettingsGUI {
|
public static class IrisSettingsGUI {
|
||||||
public boolean useServerLaunchedGuis = true;
|
public boolean useServerLaunchedGuis = true;
|
||||||
public boolean maximumPregenGuiFPS = false;
|
public boolean maximumPregenGuiFPS = false;
|
||||||
|
public boolean colorMode = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@@ -21,9 +21,12 @@ package com.volmit.iris.core;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
import com.volmit.iris.engine.object.IrisDimension;
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.engine.object.IrisRange;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
@@ -55,19 +58,18 @@ public class ServerConfigurator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
private static void increaseKeepAliveSpigot() throws IOException, InvalidConfigurationException {
|
||||||
File spigotConfig = new File("config/spigot.yml");
|
File spigotConfig = new File("spigot.yml");
|
||||||
FileConfiguration f = new YamlConfiguration();
|
FileConfiguration f = new YamlConfiguration();
|
||||||
f.load(spigotConfig);
|
f.load(spigotConfig);
|
||||||
long tt = f.getLong("settings.timeout-time");
|
long tt = f.getLong("settings.timeout-time");
|
||||||
|
|
||||||
if (tt < TimeUnit.MINUTES.toSeconds(5)) {
|
if (tt < TimeUnit.MINUTES.toSeconds(5)) {
|
||||||
Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + TimeUnit.MINUTES.toSeconds(5) + " (5 minutes)");
|
Iris.warn("Updating spigot.yml timeout-time: " + tt + " -> " + TimeUnit.MINUTES.toSeconds(20) + " (5 minutes)");
|
||||||
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
||||||
f.set("settings.timeout-time", TimeUnit.MINUTES.toSeconds(5));
|
f.set("settings.timeout-time", TimeUnit.MINUTES.toSeconds(5));
|
||||||
f.save(spigotConfig);
|
f.save(spigotConfig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
private static void increasePaperWatchdog() throws IOException, InvalidConfigurationException {
|
||||||
File spigotConfig = new File("config/paper-global.yml");
|
File spigotConfig = new File("config/paper-global.yml");
|
||||||
FileConfiguration f = new YamlConfiguration();
|
FileConfiguration f = new YamlConfiguration();
|
||||||
@@ -75,7 +77,7 @@ public class ServerConfigurator {
|
|||||||
long tt = f.getLong("watchdog.early-warning-delay");
|
long tt = f.getLong("watchdog.early-warning-delay");
|
||||||
|
|
||||||
if (tt < TimeUnit.MINUTES.toMillis(3)) {
|
if (tt < TimeUnit.MINUTES.toMillis(3)) {
|
||||||
Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(3) + " (3 minutes)");
|
Iris.warn("Updating paper.yml watchdog early-warning-delay: " + tt + " -> " + TimeUnit.MINUTES.toMillis(15) + " (3 minutes)");
|
||||||
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
Iris.warn("You can disable this change (autoconfigureServer) in Iris settings, then change back the value.");
|
||||||
f.set("watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3));
|
f.set("watchdog.early-warning-delay", TimeUnit.MINUTES.toMillis(3));
|
||||||
f.save(spigotConfig);
|
f.save(spigotConfig);
|
||||||
@@ -91,10 +93,36 @@ public class ServerConfigurator {
|
|||||||
return worlds;
|
return worlds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void installDataPacks(boolean fullInstall) {
|
public static void installDataPacks(boolean fullInstall) {
|
||||||
|
installDataPacks(DataVersion.getDefault(), fullInstall);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
|
||||||
Iris.info("Checking Data Packs...");
|
Iris.info("Checking Data Packs...");
|
||||||
File packs = new File("plugins/Iris/packs");
|
File packs = new File("plugins/Iris/packs");
|
||||||
|
double ultimateMaxHeight = 0;
|
||||||
|
double ultimateMinHeight = 0;
|
||||||
|
if (packs.exists() && packs.isDirectory()) {
|
||||||
|
for (File pack : packs.listFiles()) {
|
||||||
|
IrisData data = IrisData.get(pack);
|
||||||
|
if (pack.isDirectory()) {
|
||||||
|
File dimensionsFolder = new File(pack, "dimensions");
|
||||||
|
if (dimensionsFolder.exists() && dimensionsFolder.isDirectory()) {
|
||||||
|
for (File file : dimensionsFolder.listFiles()) {
|
||||||
|
if (file.isFile() && file.getName().endsWith(".json")) {
|
||||||
|
IrisDimension dim = data.getDimensionLoader().load(file.getName().split("\\Q.\\E")[0]);
|
||||||
|
if (ultimateMaxHeight < dim.getDimensionHeight().getMax()) {
|
||||||
|
ultimateMaxHeight = dim.getDimensionHeight().getMax();
|
||||||
|
}
|
||||||
|
if (ultimateMinHeight > dim.getDimensionHeight().getMin()) {
|
||||||
|
ultimateMinHeight = dim.getDimensionHeight().getMin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (packs.exists()) {
|
if (packs.exists()) {
|
||||||
for (File i : packs.listFiles()) {
|
for (File i : packs.listFiles()) {
|
||||||
@@ -114,7 +142,7 @@ public class ServerConfigurator {
|
|||||||
|
|
||||||
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
|
||||||
for (File dpack : getDatapacksFolder()) {
|
for (File dpack : getDatapacksFolder()) {
|
||||||
dim.installDataPack(() -> data, dpack);
|
dim.installDataPack(fixer, () -> data, dpack, ultimateMaxHeight, ultimateMinHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.core.service.IrisEngineSVC;
|
||||||
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.core.tools.IrisWorldAnalytics;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
|
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAFile;
|
||||||
|
import com.volmit.iris.util.nbt.mca.MCAUtil;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import net.jpountz.lz4.LZ4BlockInputStream;
|
||||||
|
import net.jpountz.lz4.LZ4BlockOutputStream;
|
||||||
|
import net.jpountz.lz4.LZ4FrameInputStream;
|
||||||
|
import net.jpountz.lz4.LZ4FrameOutputStream;
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.bukkit.*;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
@Decree(name = "Developer", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"dev"})
|
||||||
|
public class CommandDeveloper implements DecreeExecutor {
|
||||||
|
private CommandUpdater updater;
|
||||||
|
|
||||||
|
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
|
||||||
|
public void EngineStatus() {
|
||||||
|
List<World> IrisWorlds = new ArrayList<>();
|
||||||
|
int TotalLoadedChunks = 0;
|
||||||
|
int TotalQueuedTectonicPlates = 0;
|
||||||
|
int TotalNotQueuedTectonicPlates = 0;
|
||||||
|
int TotalTectonicPlates = 0;
|
||||||
|
|
||||||
|
long lowestUnloadDuration = 0;
|
||||||
|
long highestUnloadDuration = 0;
|
||||||
|
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
try {
|
||||||
|
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||||
|
IrisWorlds.add(world);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// no
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (World world : IrisWorlds) {
|
||||||
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
TotalQueuedTectonicPlates += (int) engine.getMantle().getToUnload();
|
||||||
|
TotalNotQueuedTectonicPlates += (int) engine.getMantle().getNotQueuedLoadedRegions();
|
||||||
|
TotalTectonicPlates += engine.getMantle().getLoadedRegionCount();
|
||||||
|
if (highestUnloadDuration <= (long) engine.getMantle().getTectonicDuration()) {
|
||||||
|
highestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||||
|
}
|
||||||
|
if (lowestUnloadDuration >= (long) engine.getMantle().getTectonicDuration()) {
|
||||||
|
lowestUnloadDuration = (long) engine.getMantle().getTectonicDuration();
|
||||||
|
}
|
||||||
|
for (Chunk chunk : world.getLoadedChunks()) {
|
||||||
|
if (chunk.isLoaded()) {
|
||||||
|
TotalLoadedChunks++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iris.info("-------------------------");
|
||||||
|
Iris.info(C.DARK_PURPLE + "Engine Status");
|
||||||
|
Iris.info(C.DARK_PURPLE + "Total Loaded Chunks: " + C.LIGHT_PURPLE + TotalLoadedChunks);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit());
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Total Plates: " + C.LIGHT_PURPLE + TotalTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic Active Plates: " + C.LIGHT_PURPLE + TotalNotQueuedTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + TotalQueuedTectonicPlates);
|
||||||
|
Iris.info(C.DARK_PURPLE + "Lowest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(lowestUnloadDuration));
|
||||||
|
Iris.info(C.DARK_PURPLE + "Highest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(highestUnloadDuration));
|
||||||
|
Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize()));
|
||||||
|
Iris.info("-------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Test")
|
||||||
|
public void benchmarkMantle(
|
||||||
|
@Param(description = "The world to bench", aliases = {"world"})
|
||||||
|
World world
|
||||||
|
) throws IOException, ClassNotFoundException {
|
||||||
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
int maxHeight = engine.getTarget().getHeight();
|
||||||
|
File folder = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
int c = 0;
|
||||||
|
//MCAUtil.read()
|
||||||
|
|
||||||
|
File tectonicplates = new File(folder, "mantle");
|
||||||
|
for (File i : Objects.requireNonNull(tectonicplates.listFiles())) {
|
||||||
|
TectonicPlate.read(maxHeight, i);
|
||||||
|
c++;
|
||||||
|
Iris.info("Loaded count: " + c );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Test")
|
||||||
|
public void packBenchmark(
|
||||||
|
@Param(description = "The pack to bench", aliases = {"pack"})
|
||||||
|
IrisDimension dimension
|
||||||
|
) {
|
||||||
|
Iris.info("test");
|
||||||
|
IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "gets wg height")
|
||||||
|
public void whatHeight() {
|
||||||
|
Iris.info("test");
|
||||||
|
sender().sendMessage("Height: " + player().getWorld().getHighestBlockAt(player().getLocation(), HeightMap.MOTION_BLOCKING).getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "check", aliases = {"ck"} )
|
||||||
|
public void check() {
|
||||||
|
sender().sendMessage("Data Pack Biome: " + INMS.get().getTrueBiomeBaseKey(player().getLocation()) + " (ID: " + INMS.get().getTrueBiomeBaseId(INMS.get().getTrueBiomeBase(player().getLocation())) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Upgrade to another Minecraft version")
|
||||||
|
public void upgrade(
|
||||||
|
@Param(description = "The version to upgrade to", defaultValue = "latest") DataVersion version) {
|
||||||
|
sender().sendMessage(C.GREEN + "Upgrading to " + version.getVersion() + "...");
|
||||||
|
ServerConfigurator.installDataPacks(version.get(), false);
|
||||||
|
sender().sendMessage(C.GREEN + "Done upgrading! You can now update your server version to " + version.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "test")
|
||||||
|
public void mca (
|
||||||
|
@Param(description = "String") String world) {
|
||||||
|
try {
|
||||||
|
File[] McaFiles = new File(world, "region").listFiles((dir, name) -> name.endsWith(".mca"));
|
||||||
|
for (File mca : McaFiles) {
|
||||||
|
MCAFile MCARegion = MCAUtil.read(mca);
|
||||||
|
int i = 0;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "test")
|
||||||
|
public void anl (
|
||||||
|
@Param(description = "String") String world) {
|
||||||
|
try {
|
||||||
|
IrisWorldAnalytics a = new IrisWorldAnalytics(world);
|
||||||
|
a.execute();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Decree(description = "UnloadChunks for good reasons.")
|
||||||
|
public void unloadchunks() {
|
||||||
|
List<World> IrisWorlds = new ArrayList<>();
|
||||||
|
int chunksUnloaded = 0;
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
try {
|
||||||
|
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||||
|
IrisWorlds.add(world);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// no
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (World world : IrisWorlds) {
|
||||||
|
for (Chunk chunk : world.getLoadedChunks()) {
|
||||||
|
if (chunk.isLoaded()) {
|
||||||
|
chunk.unload();
|
||||||
|
chunksUnloaded++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iris.info(C.IRIS + "Chunks Unloaded: " + chunksUnloaded);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree
|
||||||
|
public void objects(@Param(defaultValue = "overworld") IrisDimension dimension) {
|
||||||
|
var loader = dimension.getLoader().getObjectLoader();
|
||||||
|
var sender = sender();
|
||||||
|
var keys = loader.getPossibleKeys();
|
||||||
|
var burst = MultiBurst.burst.burst(keys.length);
|
||||||
|
AtomicInteger failed = new AtomicInteger();
|
||||||
|
for (String key : keys) {
|
||||||
|
burst.queue(() -> {
|
||||||
|
if (loader.load(key) == null)
|
||||||
|
failed.incrementAndGet();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
burst.complete();
|
||||||
|
sender.sendMessage(C.RED + "Failed to load " + failed.get() + " of " + keys.length + " objects");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Test", aliases = {"ip"})
|
||||||
|
public void network() {
|
||||||
|
try {
|
||||||
|
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
for (NetworkInterface ni : Collections.list(networkInterfaces)) {
|
||||||
|
Iris.info("Display Name: %s", ni.getDisplayName());
|
||||||
|
Enumeration<InetAddress> inetAddresses = ni.getInetAddresses();
|
||||||
|
for (InetAddress ia : Collections.list(inetAddresses)) {
|
||||||
|
Iris.info("IP: %s", ia.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Test the compression algorithms")
|
||||||
|
public void compression(
|
||||||
|
@Param(description = "base IrisWorld") World world,
|
||||||
|
@Param(description = "raw TectonicPlate File") String path,
|
||||||
|
@Param(description = "Algorithm to Test") String algorithm,
|
||||||
|
@Param(description = "Amount of Tests") int amount) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", Bukkit.getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = new File(path);
|
||||||
|
if (!file.exists()) return;
|
||||||
|
|
||||||
|
Engine engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
if(engine != null) {
|
||||||
|
int height = engine.getTarget().getHeight();
|
||||||
|
ExecutorService service = Executors.newFixedThreadPool(1);
|
||||||
|
VolmitSender sender = sender();
|
||||||
|
service.submit(() -> {
|
||||||
|
try {
|
||||||
|
DataInputStream raw = new DataInputStream(new FileInputStream(file));
|
||||||
|
TectonicPlate plate = new TectonicPlate(height, raw);
|
||||||
|
raw.close();
|
||||||
|
|
||||||
|
double d1 = 0;
|
||||||
|
double d2 = 0;
|
||||||
|
long size = 0;
|
||||||
|
File folder = new File("tmp");
|
||||||
|
folder.mkdirs();
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
File tmp = new File(folder, RandomStringUtils.randomAlphanumeric(10) + "." + algorithm + ".bin");
|
||||||
|
DataOutputStream dos = createOutput(tmp, algorithm);
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
plate.write(dos);
|
||||||
|
dos.close();
|
||||||
|
d1 += System.currentTimeMillis() - start;
|
||||||
|
if (size == 0)
|
||||||
|
size = tmp.length();
|
||||||
|
start = System.currentTimeMillis();
|
||||||
|
DataInputStream din = createInput(tmp, algorithm);
|
||||||
|
new TectonicPlate(height, din);
|
||||||
|
din.close();
|
||||||
|
d2 += System.currentTimeMillis() - start;
|
||||||
|
tmp.delete();
|
||||||
|
}
|
||||||
|
IO.delete(folder);
|
||||||
|
sender.sendMessage(algorithm + " is " + Form.fileSize(size) + " big after compression");
|
||||||
|
sender.sendMessage(algorithm + " Took " + d2/amount + "ms to read");
|
||||||
|
sender.sendMessage(algorithm + " Took " + d1/amount + "ms to write");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
service.shutdown();
|
||||||
|
} else {
|
||||||
|
Iris.info(C.RED + "Engine is null!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataInputStream createInput(File file, String algorithm) throws Throwable {
|
||||||
|
FileInputStream in = new FileInputStream(file);
|
||||||
|
|
||||||
|
return new DataInputStream(switch (algorithm) {
|
||||||
|
case "gzip" -> new GZIPInputStream(in);
|
||||||
|
case "lz4f" -> new LZ4FrameInputStream(in);
|
||||||
|
case "lz4b" -> new LZ4BlockInputStream(in);
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + algorithm);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private DataOutputStream createOutput(File file, String algorithm) throws Throwable {
|
||||||
|
FileOutputStream out = new FileOutputStream(file);
|
||||||
|
|
||||||
|
return new DataOutputStream(switch (algorithm) {
|
||||||
|
case "gzip" -> new GZIPOutputStream(out);
|
||||||
|
case "lz4f" -> new LZ4FrameOutputStream(out);
|
||||||
|
case "lz4b" -> new LZ4BlockOutputStream(out);
|
||||||
|
default -> throw new IllegalStateException("Unexpected value: " + algorithm);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,7 +34,9 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
@Decree(description = "Find a biome")
|
@Decree(description = "Find a biome")
|
||||||
public void biome(
|
public void biome(
|
||||||
@Param(description = "The biome to look for")
|
@Param(description = "The biome to look for")
|
||||||
IrisBiome biome
|
IrisBiome biome,
|
||||||
|
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||||
|
boolean teleport
|
||||||
) {
|
) {
|
||||||
Engine e = engine();
|
Engine e = engine();
|
||||||
|
|
||||||
@@ -43,13 +45,15 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoBiome(biome, player());
|
e.gotoBiome(biome, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Find a region")
|
@Decree(description = "Find a region")
|
||||||
public void region(
|
public void region(
|
||||||
@Param(description = "The region to look for")
|
@Param(description = "The region to look for")
|
||||||
IrisRegion region
|
IrisRegion region,
|
||||||
|
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||||
|
boolean teleport
|
||||||
) {
|
) {
|
||||||
Engine e = engine();
|
Engine e = engine();
|
||||||
|
|
||||||
@@ -58,13 +62,15 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoRegion(region, player());
|
e.gotoRegion(region, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Find a structure")
|
@Decree(description = "Find a structure")
|
||||||
public void structure(
|
public void structure(
|
||||||
@Param(description = "The structure to look for")
|
@Param(description = "The structure to look for")
|
||||||
IrisJigsawStructure structure
|
IrisJigsawStructure structure,
|
||||||
|
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||||
|
boolean teleport
|
||||||
) {
|
) {
|
||||||
Engine e = engine();
|
Engine e = engine();
|
||||||
|
|
||||||
@@ -73,13 +79,15 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoJigsaw(structure, player());
|
e.gotoJigsaw(structure, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Find a point of interest.")
|
@Decree(description = "Find a point of interest.")
|
||||||
public void poi(
|
public void poi(
|
||||||
@Param(description = "The type of PoI to look for.")
|
@Param(description = "The type of PoI to look for.")
|
||||||
String type
|
String type,
|
||||||
|
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||||
|
boolean teleport
|
||||||
) {
|
) {
|
||||||
Engine e = engine();
|
Engine e = engine();
|
||||||
if (e == null) {
|
if (e == null) {
|
||||||
@@ -87,13 +95,15 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoPOI(type, player());
|
e.gotoPOI(type, player(), teleport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Find an object")
|
@Decree(description = "Find an object")
|
||||||
public void object(
|
public void object(
|
||||||
@Param(description = "The object to look for", customHandler = ObjectHandler.class)
|
@Param(description = "The object to look for", customHandler = ObjectHandler.class)
|
||||||
String object
|
String object,
|
||||||
|
@Param(description = "Should you be teleported", defaultValue = "true")
|
||||||
|
boolean teleport
|
||||||
) {
|
) {
|
||||||
Engine e = engine();
|
Engine e = engine();
|
||||||
|
|
||||||
@@ -102,6 +112,6 @@ public class CommandFind implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
e.gotoObject(object, player());
|
e.gotoObject(object, player(), teleport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,652 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.ServerConfigurator;
|
||||||
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
|
import com.volmit.iris.core.tools.IrisBenchmarking;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.object.IrisDimension;
|
||||||
|
import com.volmit.iris.core.safeguard.UtilsSFG;
|
||||||
|
import com.volmit.iris.engine.object.IrisWorld;
|
||||||
|
import com.volmit.iris.engine.platform.BukkitChunkGenerator;
|
||||||
|
import com.volmit.iris.engine.platform.DummyChunkGenerator;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
|
import com.volmit.iris.util.decree.specialhandlers.NullablePlayerHandler;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Difficulty;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.WorldCreator;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.io.Console;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.volmit.iris.Iris.service;
|
||||||
|
import static com.volmit.iris.core.service.EditSVC.deletingWorld;
|
||||||
|
import static com.volmit.iris.core.tools.IrisBenchmarking.inProgress;
|
||||||
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
|
||||||
|
import static com.volmit.iris.core.safeguard.ServerBootSFG.incompatibilities;
|
||||||
|
import static org.bukkit.Bukkit.getServer;
|
||||||
|
|
||||||
|
@Decree(name = "iris", aliases = {"ir", "irs"}, description = "Basic Command")
|
||||||
|
public class CommandIris implements DecreeExecutor {
|
||||||
|
private CommandStudio studio;
|
||||||
|
private CommandPregen pregen;
|
||||||
|
private CommandSettings settings;
|
||||||
|
private CommandObject object;
|
||||||
|
private CommandJigsaw jigsaw;
|
||||||
|
private CommandWhat what;
|
||||||
|
private CommandEdit edit;
|
||||||
|
private CommandFind find;
|
||||||
|
private CommandDeveloper developer;
|
||||||
|
public static boolean worldCreation = false;
|
||||||
|
String WorldEngine;
|
||||||
|
String worldNameToCheck = "YourWorldName";
|
||||||
|
VolmitSender sender = Iris.getSender();
|
||||||
|
|
||||||
|
@Decree(description = "Create a new world", aliases = {"+", "c"})
|
||||||
|
public void create(
|
||||||
|
@Param(aliases = "world-name", description = "The name of the world to create")
|
||||||
|
String name,
|
||||||
|
@Param(aliases = "dimension", description = "The dimension type to create the world with", defaultValue = "default")
|
||||||
|
IrisDimension type,
|
||||||
|
@Param(description = "The seed to generate the world with", defaultValue = "1337")
|
||||||
|
long seed,
|
||||||
|
@Param(description = "If it should convert the dimension to match the vanilla height system.", defaultValue = "false")
|
||||||
|
boolean vanillaheight
|
||||||
|
) {
|
||||||
|
if(sender() instanceof Player) {
|
||||||
|
if (incompatibilities.get("Multiverse-Core")) {
|
||||||
|
sender().sendMessage(C.RED + "Your server has an incompatibility that may corrupt all worlds on the server if not handled properly.");
|
||||||
|
sender().sendMessage(C.RED + "it is strongly advised for you to take action. see log for full detail");
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||||
|
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
if (unstablemode && !incompatibilities.get("Multiverse-Core")) {
|
||||||
|
sender().sendMessage(C.RED + "Your server is experiencing an incompatibility with the Iris plugin.");
|
||||||
|
sender().sendMessage(C.RED + "Please rectify this problem to avoid further complications.");
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
sender().sendMessage(C.RED + "Command ran: /iris create");
|
||||||
|
sender().sendMessage(C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
sender().sendMessage(C.RED + "----------------------------------------------------------------");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name.equals("iris")) {
|
||||||
|
sender().sendMessage(C.RED + "You cannot use the world name \"iris\" for creating worlds as Iris uses this directory for studio worlds.");
|
||||||
|
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (name.equals("Benchmark")) {
|
||||||
|
sender().sendMessage(C.RED + "You cannot use the world name \"Benchmark\" for creating worlds as Iris uses this directory for Benchmarking Packs.");
|
||||||
|
sender().sendMessage(C.RED + "May we suggest the name \"IrisWorld\" instead?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new File(Bukkit.getWorldContainer(), name).exists()) {
|
||||||
|
sender().sendMessage(C.RED + "That folder already exists!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
worldCreation = true;
|
||||||
|
IrisToolbelt.createWorld()
|
||||||
|
.dimension(type.getLoadKey())
|
||||||
|
.name(name)
|
||||||
|
.seed(seed)
|
||||||
|
.sender(sender())
|
||||||
|
.studio(false)
|
||||||
|
.smartVanillaHeight(vanillaheight)
|
||||||
|
.create();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
sender().sendMessage(C.RED + "Exception raised during creation. See the console for more details.");
|
||||||
|
Iris.error("Exception raised during world creation: " + e.getMessage());
|
||||||
|
Iris.reportError(e);
|
||||||
|
worldCreation = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
worldCreation = false;
|
||||||
|
sender().sendMessage(C.GREEN + "Successfully created your world!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Teleport to another world", aliases = {"tp"}, sync = true)
|
||||||
|
public void teleport(
|
||||||
|
@Param(description = "World to teleport to")
|
||||||
|
World world,
|
||||||
|
@Param(description = "Player to teleport", defaultValue = "---", customHandler = NullablePlayerHandler.class)
|
||||||
|
Player player
|
||||||
|
) {
|
||||||
|
if (player == null && sender().isPlayer())
|
||||||
|
player = sender().player();
|
||||||
|
|
||||||
|
final Player target = player;
|
||||||
|
if (target == null) {
|
||||||
|
sender().sendMessage(C.RED + "The specified player does not exist.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
target.teleport(world.getSpawnLocation());
|
||||||
|
new VolmitSender(target).sendMessage(C.GREEN + "You have been teleported to " + world.getName() + ".");
|
||||||
|
}
|
||||||
|
}.runTask(Iris.instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Print version information")
|
||||||
|
public void version() {
|
||||||
|
sender().sendMessage(C.GREEN + "Iris v" + Iris.instance.getDescription().getVersion() + " by Volmit Software");
|
||||||
|
}
|
||||||
|
|
||||||
|
//todo Move to React
|
||||||
|
@Decree(description = "Benchmark your server", origin = DecreeOrigin.CONSOLE)
|
||||||
|
public void serverbenchmark() throws InterruptedException {
|
||||||
|
if(!inProgress) {
|
||||||
|
IrisBenchmarking.runBenchmark();
|
||||||
|
} else {
|
||||||
|
Iris.info(C.RED + "Benchmark already is in progress.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
/todo
|
||||||
|
@Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE)
|
||||||
|
public void packbenchmark(
|
||||||
|
@Param(description = "Dimension to benchmark")
|
||||||
|
IrisDimension type
|
||||||
|
) throws InterruptedException {
|
||||||
|
|
||||||
|
BenchDimension = type.getLoadKey();
|
||||||
|
|
||||||
|
IrisPackBenchmarking.runBenchmark();
|
||||||
|
} */
|
||||||
|
|
||||||
|
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
|
||||||
|
public void height() {
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
sender().sendMessage(C.GREEN + "" + sender().player().getWorld().getMinHeight() + " to " + sender().player().getWorld().getMaxHeight());
|
||||||
|
sender().sendMessage(C.GREEN + "Total Height: " + (sender().player().getWorld().getMaxHeight() - sender().player().getWorld().getMinHeight()));
|
||||||
|
} else {
|
||||||
|
World mainWorld = getServer().getWorlds().get(0);
|
||||||
|
Iris.info(C.GREEN + "" + mainWorld.getMinHeight() + " to " + mainWorld.getMaxHeight());
|
||||||
|
Iris.info(C.GREEN + "Total Height: " + (mainWorld.getMaxHeight() - mainWorld.getMinHeight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "QOL command to open a overworld studio world.", sync = true)
|
||||||
|
public void so() {
|
||||||
|
sender().sendMessage(C.GREEN + "Opening studio for the \"Overworld\" pack (seed: 1337)");
|
||||||
|
Iris.service(StudioSVC.class).open(sender(), 1337, "overworld");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Check access of all worlds.", aliases = {"accesslist"})
|
||||||
|
public void worlds() {
|
||||||
|
KList<World> IrisWorlds = new KList<>();
|
||||||
|
KList<World> BukkitWorlds = new KList<>();
|
||||||
|
|
||||||
|
for (World w : Bukkit.getServer().getWorlds()) {
|
||||||
|
try {
|
||||||
|
Engine engine = IrisToolbelt.access(w).getEngine();
|
||||||
|
if (engine != null) {
|
||||||
|
IrisWorlds.add(w);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
BukkitWorlds.add(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
sender().sendMessage(C.BLUE + "Iris Worlds: ");
|
||||||
|
for (World IrisWorld : IrisWorlds.copy()) {
|
||||||
|
sender().sendMessage(C.IRIS + "- " +IrisWorld.getName());
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GOLD + "Bukkit Worlds: ");
|
||||||
|
for (World BukkitWorld : BukkitWorlds.copy()) {
|
||||||
|
sender().sendMessage(C.GRAY + "- " +BukkitWorld.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Iris.info(C.BLUE + "Iris Worlds: ");
|
||||||
|
for (World IrisWorld : IrisWorlds.copy()) {
|
||||||
|
Iris.info(C.IRIS + "- " +IrisWorld.getName());
|
||||||
|
}
|
||||||
|
Iris.info(C.GOLD + "Bukkit Worlds: ");
|
||||||
|
for (World BukkitWorld : BukkitWorlds.copy()) {
|
||||||
|
Iris.info(C.GRAY + "- " +BukkitWorld.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Remove an Iris world", aliases = {"del", "rm", "delete"}, sync = true)
|
||||||
|
public void remove(
|
||||||
|
@Param(description = "The world to remove")
|
||||||
|
World world,
|
||||||
|
@Param(description = "Whether to also remove the folder (if set to false, just does not load the world)", defaultValue = "true")
|
||||||
|
boolean delete
|
||||||
|
) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Removing world: " + world.getName());
|
||||||
|
try {
|
||||||
|
if (IrisToolbelt.removeWorld(world)) {
|
||||||
|
sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml");
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.YELLOW + "Looks like the world was already removed from bukkit.yml");
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to save bukkit.yml because of " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
IrisToolbelt.evacuate(world, "Deleting world");
|
||||||
|
deletingWorld = true;
|
||||||
|
Bukkit.unloadWorld(world, false);
|
||||||
|
int retries = 12;
|
||||||
|
if (delete) {
|
||||||
|
if (deleteDirectory(world.getWorldFolder())) {
|
||||||
|
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
|
} else {
|
||||||
|
while(true){
|
||||||
|
if (deleteDirectory(world.getWorldFolder())){
|
||||||
|
sender().sendMessage(C.GREEN + "Successfully removed world folder");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
retries--;
|
||||||
|
if (retries == 0){
|
||||||
|
sender().sendMessage(C.RED + "Failed to remove world folder");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
J.sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deletingWorld = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean deleteDirectory(File dir) {
|
||||||
|
if (dir.isDirectory()) {
|
||||||
|
File[] children = dir.listFiles();
|
||||||
|
for (int i = 0; i < children.length; i++) {
|
||||||
|
boolean success = deleteDirectory(children[i]);
|
||||||
|
if (!success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dir.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Updates all chunk in the specified world")
|
||||||
|
public void updater(
|
||||||
|
@Param(description = "World to update chunks at")
|
||||||
|
World world
|
||||||
|
) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ChunkUpdater updater = new ChunkUpdater(world);
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
sender().sendMessage(C.GREEN + "Updating " + world.getName() + " Total chunks: " + Form.f(updater.getChunks()));
|
||||||
|
} else {
|
||||||
|
Iris.info(C.GREEN + "Updating " + world.getName() + " Total chunks: " + Form.f(updater.getChunks()));
|
||||||
|
}
|
||||||
|
updater.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Set aura spins")
|
||||||
|
public void aura(
|
||||||
|
@Param(description = "The h color value", defaultValue = "-20")
|
||||||
|
int h,
|
||||||
|
@Param(description = "The s color value", defaultValue = "7")
|
||||||
|
int s,
|
||||||
|
@Param(description = "The b color value", defaultValue = "8")
|
||||||
|
int b
|
||||||
|
) {
|
||||||
|
IrisSettings.get().getGeneral().setSpinh(h);
|
||||||
|
IrisSettings.get().getGeneral().setSpins(s);
|
||||||
|
IrisSettings.get().getGeneral().setSpinb(b);
|
||||||
|
IrisSettings.get().forceSave();
|
||||||
|
sender().sendMessage("<rainbow>Aura Spins updated to " + h + " " + s + " " + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Bitwise calculations")
|
||||||
|
public void bitwise(
|
||||||
|
@Param(description = "The first value to run calculations on")
|
||||||
|
int value1,
|
||||||
|
@Param(description = "The operator: | & ^ ≺≺ ≻≻ %")
|
||||||
|
String operator,
|
||||||
|
@Param(description = "The second value to run calculations on")
|
||||||
|
int value2
|
||||||
|
) {
|
||||||
|
Integer v = null;
|
||||||
|
switch (operator) {
|
||||||
|
case "|" -> v = value1 | value2;
|
||||||
|
case "&" -> v = value1 & value2;
|
||||||
|
case "^" -> v = value1 ^ value2;
|
||||||
|
case "%" -> v = value1 % value2;
|
||||||
|
case ">>" -> v = value1 >> value2;
|
||||||
|
case "<<" -> v = value1 << value2;
|
||||||
|
}
|
||||||
|
if (v == null) {
|
||||||
|
sender().sendMessage(C.RED + "The operator you entered: (" + operator + ") is invalid!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "" + value1 + " " + C.GREEN + operator.replaceAll("<", "≺").replaceAll(">", "≻").replaceAll("%", "%") + " " + C.GREEN + value2 + C.GREEN + " returns " + C.GREEN + v);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Toggle debug")
|
||||||
|
public void debug(
|
||||||
|
@Param(name = "on", description = "Whether or not debug should be on", defaultValue = "other")
|
||||||
|
Boolean on
|
||||||
|
) {
|
||||||
|
boolean to = on == null ? !IrisSettings.get().getGeneral().isDebug() : on;
|
||||||
|
IrisSettings.get().getGeneral().setDebug(to);
|
||||||
|
IrisSettings.get().forceSave();
|
||||||
|
sender().sendMessage(C.GREEN + "Set debug to: " + to);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Download a project.", aliases = "dl")
|
||||||
|
public void download(
|
||||||
|
@Param(name = "pack", description = "The pack to download", defaultValue = "overworld", aliases = "project")
|
||||||
|
String pack,
|
||||||
|
@Param(name = "branch", description = "The branch to download from", defaultValue = "main")
|
||||||
|
String branch,
|
||||||
|
@Param(name = "trim", description = "Whether or not to download a trimmed version (do not enable when editing)", defaultValue = "false")
|
||||||
|
boolean trim,
|
||||||
|
@Param(name = "overwrite", description = "Whether or not to overwrite the pack with the downloaded one", aliases = "force", defaultValue = "false")
|
||||||
|
boolean overwrite
|
||||||
|
) {
|
||||||
|
sender().sendMessage(C.GREEN + "Downloading pack: " + pack + "/" + branch + (trim ? " trimmed" : "") + (overwrite ? " overwriting" : ""));
|
||||||
|
if (pack.equals("overworld")) {
|
||||||
|
String url = "https://github.com/IrisDimensions/overworld/releases/download/" + Iris.OVERWORLD_TAG + "/overworld.zip";
|
||||||
|
Iris.service(StudioSVC.class).downloadRelease(sender(), url, trim, overwrite);
|
||||||
|
} else {
|
||||||
|
Iris.service(StudioSVC.class).downloadSearch(sender(), "IrisDimensions/" + pack + "/" + branch, trim, overwrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Get metrics for your world", aliases = "measure", origin = DecreeOrigin.PLAYER)
|
||||||
|
public void metrics() {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world())) {
|
||||||
|
sender().sendMessage(C.RED + "You must be in an Iris world");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Sending metrics...");
|
||||||
|
engine().printMetrics(sender());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Reload configuration file (this is also done automatically)")
|
||||||
|
public void reload() {
|
||||||
|
IrisSettings.invalidate();
|
||||||
|
IrisSettings.get();
|
||||||
|
sender().sendMessage(C.GREEN + "Hotloaded settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world")
|
||||||
|
public void updateWorld(
|
||||||
|
@Param(description = "The world to update", contextual = true)
|
||||||
|
World world,
|
||||||
|
@Param(description = "The pack to install into the world", contextual = true, aliases = "dimension")
|
||||||
|
IrisDimension pack,
|
||||||
|
@Param(description = "Make sure to make a backup & read the warnings first!", defaultValue = "false", aliases = "c")
|
||||||
|
boolean confirm,
|
||||||
|
@Param(description = "Should Iris download the pack again for you", defaultValue = "false", name = "fresh-download", aliases = {"fresh", "new"})
|
||||||
|
boolean freshDownload
|
||||||
|
) {
|
||||||
|
if (!confirm) {
|
||||||
|
sender().sendMessage(new String[]{
|
||||||
|
C.RED + "You should always make a backup before using this",
|
||||||
|
C.YELLOW + "Issues caused by this can be, but are not limited to:",
|
||||||
|
C.YELLOW + " - Broken chunks (cut-offs) between old and new chunks (before & after the update)",
|
||||||
|
C.YELLOW + " - Regenerated chunks that do not fit in with the old chunks",
|
||||||
|
C.YELLOW + " - Structures not spawning again when regenerating",
|
||||||
|
C.YELLOW + " - Caves not lining up",
|
||||||
|
C.YELLOW + " - Terrain layers not lining up",
|
||||||
|
C.RED + "Now that you are aware of the risks, and have made a back-up:",
|
||||||
|
C.RED + "/iris ^world " + world.getName() + " " + pack.getLoadKey() + " confirm=true"
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File folder = world.getWorldFolder();
|
||||||
|
folder.mkdirs();
|
||||||
|
|
||||||
|
if (freshDownload) {
|
||||||
|
Iris.service(StudioSVC.class).downloadSearch(sender(), pack.getLoadKey(), false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iris.service(StudioSVC.class).installIntoWorld(sender(), pack.getLoadKey(), folder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Unload an Iris World", origin = DecreeOrigin.PLAYER, sync = true)
|
||||||
|
public void unloadWorld(
|
||||||
|
@Param(description = "The world to unload")
|
||||||
|
World world
|
||||||
|
) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Unloading world: " + world.getName());
|
||||||
|
try {
|
||||||
|
IrisToolbelt.evacuate(world);
|
||||||
|
Bukkit.unloadWorld(world, false);
|
||||||
|
sender().sendMessage(C.GREEN + "World unloaded successfully.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to unload the world: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Load an Iris World", origin = DecreeOrigin.PLAYER, sync = true, aliases = {"import"})
|
||||||
|
public void loadWorld(
|
||||||
|
@Param(description = "The name of the world to load")
|
||||||
|
String world
|
||||||
|
) {
|
||||||
|
World worldloaded = Bukkit.getWorld(world);
|
||||||
|
worldNameToCheck = world;
|
||||||
|
boolean worldExists = doesWorldExist(worldNameToCheck);
|
||||||
|
WorldEngine = world;
|
||||||
|
|
||||||
|
if (!worldExists) {
|
||||||
|
sender().sendMessage(C.YELLOW + world + " Doesnt exist on the server.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File BUKKIT_YML = new File("bukkit.yml");
|
||||||
|
String pathtodim = world + File.separator +"iris"+File.separator +"pack"+File.separator +"dimensions"+File.separator;
|
||||||
|
File directory = new File(Bukkit.getWorldContainer(), pathtodim);
|
||||||
|
|
||||||
|
String dimension = null;
|
||||||
|
if (directory.exists() && directory.isDirectory()) {
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
if (file.isFile()) {
|
||||||
|
String fileName = file.getName();
|
||||||
|
if (fileName.endsWith(".json")) {
|
||||||
|
dimension = fileName.substring(0, fileName.length() - 5);
|
||||||
|
sender().sendMessage(C.BLUE + "Generator: " + dimension);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.GOLD + world + " is not an iris world.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Loading world: " + world);
|
||||||
|
|
||||||
|
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
|
||||||
|
String gen = "Iris:" + dimension;
|
||||||
|
ConfigurationSection section = yml.contains("worlds") ? yml.getConfigurationSection("worlds") : yml.createSection("worlds");
|
||||||
|
if (!section.contains(world)) {
|
||||||
|
section.createSection(world).set("generator", gen);
|
||||||
|
try {
|
||||||
|
yml.save(BUKKIT_YML);
|
||||||
|
Iris.info("Registered \"" + world + "\" in bukkit.yml");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Iris.error("Failed to update bukkit.yml!");
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkForBukkitWorlds(world);
|
||||||
|
sender().sendMessage(C.GREEN + world + " loaded successfully.");
|
||||||
|
}
|
||||||
|
@Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true)
|
||||||
|
public void evacuate(
|
||||||
|
@Param(description = "Evacuate the world")
|
||||||
|
World world
|
||||||
|
) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.RED + "This is not an Iris world. Iris worlds: " + String.join(", ", getServer().getWorlds().stream().filter(IrisToolbelt::isIrisWorld).map(World::getName).toList()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sender().sendMessage(C.GREEN + "Evacuating world" + world.getName());
|
||||||
|
IrisToolbelt.evacuate(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doesWorldExist(String worldName) {
|
||||||
|
File worldContainer = Bukkit.getWorldContainer();
|
||||||
|
File worldDirectory = new File(worldContainer, worldName);
|
||||||
|
return worldDirectory.exists() && worldDirectory.isDirectory();
|
||||||
|
}
|
||||||
|
private void checkForBukkitWorlds(String world) {
|
||||||
|
FileConfiguration fc = new YamlConfiguration();
|
||||||
|
try {
|
||||||
|
fc.load(new File("bukkit.yml"));
|
||||||
|
ConfigurationSection section = fc.getConfigurationSection("worlds");
|
||||||
|
if (section == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> worldsToLoad = Collections.singletonList(world);
|
||||||
|
|
||||||
|
for (String s : section.getKeys(false)) {
|
||||||
|
if (!worldsToLoad.contains(s)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ConfigurationSection entry = section.getConfigurationSection(s);
|
||||||
|
if (!entry.contains("generator", true)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String generator = entry.getString("generator");
|
||||||
|
if (generator.startsWith("Iris:")) {
|
||||||
|
generator = generator.split("\\Q:\\E")[1];
|
||||||
|
} else if (generator.equalsIgnoreCase("Iris")) {
|
||||||
|
generator = IrisSettings.get().getGenerator().getDefaultWorldType();
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Iris.info("2 World: %s | Generator: %s", s, generator);
|
||||||
|
if (Bukkit.getWorlds().stream().anyMatch(w -> w.getName().equals(s))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Iris.info(C.LIGHT_PURPLE + "Preparing Spawn for " + s + "' using Iris:" + generator + "...");
|
||||||
|
new WorldCreator(s)
|
||||||
|
.generator(getDefaultWorldGenerator(s, generator))
|
||||||
|
.environment(IrisData.loadAnyDimension(generator).getEnvironment())
|
||||||
|
.createWorld();
|
||||||
|
Iris.info(C.LIGHT_PURPLE + "Loaded " + s + "!");
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
|
||||||
|
Iris.debug("Default World Generator Called for " + worldName + " using ID: " + id);
|
||||||
|
if (worldName.equals("test")) {
|
||||||
|
try {
|
||||||
|
throw new RuntimeException();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.info(e.getStackTrace()[1].getClassName());
|
||||||
|
if (e.getStackTrace()[1].getClassName().contains("com.onarandombox.MultiverseCore")) {
|
||||||
|
Iris.debug("MVC Test detected, Quick! Send them the dummy!");
|
||||||
|
return new DummyChunkGenerator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IrisDimension dim;
|
||||||
|
if (id == null || id.isEmpty()) {
|
||||||
|
dim = IrisData.loadAnyDimension(IrisSettings.get().getGenerator().getDefaultWorldType());
|
||||||
|
} else {
|
||||||
|
dim = IrisData.loadAnyDimension(id);
|
||||||
|
}
|
||||||
|
Iris.debug("Generator ID: " + id + " requested by bukkit/plugin");
|
||||||
|
|
||||||
|
if (dim == null) {
|
||||||
|
Iris.warn("Unable to find dimension type " + id + " Looking for online packs...");
|
||||||
|
|
||||||
|
service(StudioSVC.class).downloadSearch(new VolmitSender(Bukkit.getConsoleSender()), id, true);
|
||||||
|
dim = IrisData.loadAnyDimension(id);
|
||||||
|
|
||||||
|
if (dim == null) {
|
||||||
|
throw new RuntimeException("Can't find dimension " + id + "!");
|
||||||
|
} else {
|
||||||
|
Iris.info("Resolved missing dimension, proceeding with generation.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iris.debug("Assuming IrisDimension: " + dim.getName());
|
||||||
|
IrisWorld w = IrisWorld.builder()
|
||||||
|
.name(worldName)
|
||||||
|
.seed(1337)
|
||||||
|
.environment(dim.getEnvironment())
|
||||||
|
.worldFolder(new File(Bukkit.getWorldContainer(), worldName))
|
||||||
|
.minHeight(dim.getMinHeight())
|
||||||
|
.maxHeight(dim.getMaxHeight())
|
||||||
|
.build();
|
||||||
|
Iris.debug("Generator Config: " + w.toString());
|
||||||
|
File ff = new File(w.worldFolder(), "iris/pack");
|
||||||
|
if (!ff.exists() || ff.listFiles().length == 0) {
|
||||||
|
ff.mkdirs();
|
||||||
|
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
|
||||||
|
}
|
||||||
|
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@ package com.volmit.iris.core.commands;
|
|||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.edit.JigsawEditor;
|
import com.volmit.iris.core.edit.JigsawEditor;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
|
import com.volmit.iris.engine.framework.placer.WorldObjectPlacer;
|
||||||
import com.volmit.iris.engine.jigsaw.PlannedStructure;
|
import com.volmit.iris.engine.jigsaw.PlannedStructure;
|
||||||
import com.volmit.iris.engine.object.IrisJigsawPiece;
|
import com.volmit.iris.engine.object.IrisJigsawPiece;
|
||||||
import com.volmit.iris.engine.object.IrisJigsawStructure;
|
import com.volmit.iris.engine.object.IrisJigsawStructure;
|
||||||
@@ -34,6 +35,7 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -55,9 +57,16 @@ public class CommandJigsaw implements DecreeExecutor {
|
|||||||
IrisJigsawStructure structure
|
IrisJigsawStructure structure
|
||||||
) {
|
) {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation()), new RNG());
|
try {
|
||||||
sender().sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2));
|
var world = world();
|
||||||
ps.place(world());
|
WorldObjectPlacer placer = new WorldObjectPlacer(world);
|
||||||
|
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation().add(0, world.getMinHeight(), 0)), new RNG(), true);
|
||||||
|
VolmitSender sender = sender();
|
||||||
|
sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2));
|
||||||
|
ps.place(placer, failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!"));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
sender().sendMessage(C.RED + "Failed to place the structure: " + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Create a jigsaw piece")
|
@Decree(description = "Create a jigsaw piece")
|
||||||
@@ -24,6 +24,7 @@ import com.volmit.iris.core.loader.IrisData;
|
|||||||
import com.volmit.iris.core.service.ObjectSVC;
|
import com.volmit.iris.core.service.ObjectSVC;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
import com.volmit.iris.core.service.WandSVC;
|
import com.volmit.iris.core.service.WandSVC;
|
||||||
|
import com.volmit.iris.core.tools.IrisConverter;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.data.Cuboid;
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
@@ -35,6 +36,7 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
|
|||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Direction;
|
import com.volmit.iris.util.math.Direction;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.scheduling.Queue;
|
import com.volmit.iris.util.scheduling.Queue;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@@ -52,7 +54,7 @@ import java.util.*;
|
|||||||
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
|
||||||
public class CommandObject implements DecreeExecutor {
|
public class CommandObject implements DecreeExecutor {
|
||||||
|
|
||||||
private static final Set<Material> skipBlocks = Set.of(Material.GRASS, Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
private static final Set<Material> skipBlocks = Set.of(E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS"), Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH,
|
||||||
Material.POPPY, Material.DANDELION);
|
Material.POPPY, Material.DANDELION);
|
||||||
|
|
||||||
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
|
||||||
@@ -116,10 +118,8 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
BlockState state = world.getBlockAt(xx, yy, zz).getState();
|
tile.toBukkitTry(world.getBlockAt(xx, yy, zz));
|
||||||
tile.toBukkitTry(state);
|
|
||||||
state.update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -197,6 +197,30 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Shrink an object to its minimum size")
|
||||||
|
public void shrink(@Param(description = "The object to shrink", customHandler = ObjectHandler.class) String object) {
|
||||||
|
IrisObject o = IrisData.loadAnyObject(object);
|
||||||
|
sender().sendMessage("Current Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD());
|
||||||
|
o.shrinkwrap();
|
||||||
|
sender().sendMessage("New Object Size: " + o.getW() + " * " + o.getH() + " * " + o.getD());
|
||||||
|
try {
|
||||||
|
o.write(o.getLoadFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
sender().sendMessage("Failed to save object " + o.getLoadFile() + ": " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Convert .schem files in the 'convert' folder to .iob files.")
|
||||||
|
public void convert () {
|
||||||
|
try {
|
||||||
|
IrisConverter.convertSchematics(sender());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(description = "Get a powder that reveals objects", studio = true, aliases = "d")
|
@Decree(description = "Get a powder that reveals objects", studio = true, aliases = "d")
|
||||||
public void dust() {
|
public void dust() {
|
||||||
player().getInventory().addItem(WandSVC.createDust());
|
player().getInventory().addItem(WandSVC.createDust());
|
||||||
@@ -341,7 +365,7 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sender().sendMessage("Placed " + object);
|
sender().sendMessage(C.IRIS + "Placed " + object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +392,7 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
o.write(file);
|
o.write(file, sender());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
sender().sendMessage(C.RED + "Failed to save object because of an IOException: " + e.getMessage());
|
sender().sendMessage(C.RED + "Failed to save object because of an IOException: " + e.getMessage());
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
@@ -413,7 +437,7 @@ public class CommandObject implements DecreeExecutor {
|
|||||||
ObjectSVC service = Iris.service(ObjectSVC.class);
|
ObjectSVC service = Iris.service(ObjectSVC.class);
|
||||||
int actualReverts = Math.min(service.getUndos().size(), amount);
|
int actualReverts = Math.min(service.getUndos().size(), amount);
|
||||||
service.revertChanges(actualReverts);
|
service.revertChanges(actualReverts);
|
||||||
sender().sendMessage("Reverted " + actualReverts + " pastes!");
|
sender().sendMessage(C.BLUE + "Reverted " + actualReverts + C.BLUE +" pastes!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Decree(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DecreeOrigin.PLAYER, studio = true)
|
@Decree(description = "Gets an object wand and grabs the current WorldEdit selection.", aliases = "we", origin = DecreeOrigin.PLAYER, studio = true)
|
||||||
@@ -19,7 +19,9 @@
|
|||||||
package com.volmit.iris.core.commands;
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.gui.PregeneratorJob;
|
import com.volmit.iris.core.gui.PregeneratorJob;
|
||||||
|
import com.volmit.iris.core.pregenerator.LazyPregenerator;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
@@ -27,9 +29,12 @@ import com.volmit.iris.util.decree.annotations.Decree;
|
|||||||
import com.volmit.iris.util.decree.annotations.Param;
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
import com.volmit.iris.util.format.C;
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.math.Position2;
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
@Decree(name = "pregen", aliases = "pregenerate", description = "Pregenerate your Iris worlds!")
|
||||||
public class CommandPregen implements DecreeExecutor {
|
public class CommandPregen implements DecreeExecutor {
|
||||||
@Decree(description = "Pregenerate a world")
|
@Decree(description = "Pregenerate a world")
|
||||||
@@ -40,7 +45,7 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
World world,
|
World world,
|
||||||
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
@Param(aliases = "middle", description = "The center location of the pregen. Use \"me\" for your current location", defaultValue = "0,0")
|
||||||
Vector center
|
Vector center
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
if (sender().isPlayer() && access() == null) {
|
if (sender().isPlayer() && access() == null) {
|
||||||
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
sender().sendMessage(C.RED + "The engine access for this world is null!");
|
||||||
@@ -50,7 +55,8 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
int w = (radius >> 9 + 1) * 2;
|
int w = (radius >> 9 + 1) * 2;
|
||||||
IrisToolbelt.pregenerate(PregenTask
|
IrisToolbelt.pregenerate(PregenTask
|
||||||
.builder()
|
.builder()
|
||||||
.center(new Position2(center))
|
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
|
||||||
|
.gui(true)
|
||||||
.width(w)
|
.width(w)
|
||||||
.height(w)
|
.height(w)
|
||||||
.build(), world);
|
.build(), world);
|
||||||
@@ -67,7 +73,7 @@ public class CommandPregen implements DecreeExecutor {
|
|||||||
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
@Decree(description = "Stop the active pregeneration task", aliases = "x")
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (PregeneratorJob.shutdownInstance()) {
|
if (PregeneratorJob.shutdownInstance()) {
|
||||||
sender().sendMessage(C.GREEN + "Stopped pregeneration task");
|
Iris.info( C.BLUE + "Finishing up mca region...");
|
||||||
} else {
|
} else {
|
||||||
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
sender().sendMessage(C.YELLOW + "No active pregeneration tasks to stop");
|
||||||
}
|
}
|
||||||
@@ -26,12 +26,15 @@ import com.volmit.iris.core.loader.IrisData;
|
|||||||
import com.volmit.iris.core.project.IrisProject;
|
import com.volmit.iris.core.project.IrisProject;
|
||||||
import com.volmit.iris.core.service.ConversionSVC;
|
import com.volmit.iris.core.service.ConversionSVC;
|
||||||
import com.volmit.iris.core.service.StudioSVC;
|
import com.volmit.iris.core.service.StudioSVC;
|
||||||
|
import com.volmit.iris.core.tools.IrisConverter;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
|
import com.volmit.iris.util.decree.DecreeContext;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
import com.volmit.iris.util.decree.annotations.Decree;
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
@@ -45,15 +48,23 @@ import com.volmit.iris.util.io.IO;
|
|||||||
import com.volmit.iris.util.json.JSONArray;
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
import com.volmit.iris.util.json.JSONObject;
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
import com.volmit.iris.util.math.RNG;
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.math.Spiraler;
|
import com.volmit.iris.util.math.Spiraler;
|
||||||
import com.volmit.iris.util.noise.CNG;
|
import com.volmit.iris.util.noise.CNG;
|
||||||
|
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||||
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.O;
|
import com.volmit.iris.util.scheduling.O;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
import com.volmit.iris.util.scheduling.jobs.QueueJob;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.event.inventory.InventoryType;
|
import org.bukkit.event.inventory.InventoryType;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.bukkit.util.BlockVector;
|
import org.bukkit.util.BlockVector;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
@@ -65,14 +76,20 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.attribute.FileTime;
|
import java.nio.file.attribute.FileTime;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
@Decree(name = "studio", aliases = {"std", "s"}, description = "Studio Commands", studio = true)
|
||||||
public class CommandStudio implements DecreeExecutor {
|
public class CommandStudio implements DecreeExecutor {
|
||||||
private CommandFind find;
|
private CommandFind find;
|
||||||
private CommandEdit edit;
|
private CommandEdit edit;
|
||||||
|
//private CommandDeepSearch deepSearch;
|
||||||
|
|
||||||
public static String hrf(Duration duration) {
|
public static String hrf(Duration duration) {
|
||||||
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
|
||||||
@@ -143,12 +160,83 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
sender().sendMessage(C.GREEN + "The \"" + dimension.getName() + "\" pack has version: " + dimension.getVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(name = "regen", description = "Regenerate nearby chunks.", aliases = "rg", sync = true, origin = DecreeOrigin.PLAYER)
|
||||||
|
public void regen(
|
||||||
|
@Param(name = "radius", description = "The radius of nearby cunks", defaultValue = "5")
|
||||||
|
int radius
|
||||||
|
) {
|
||||||
|
if (IrisToolbelt.isIrisWorld(player().getWorld())) {
|
||||||
|
VolmitSender sender = sender();
|
||||||
|
J.a(() -> {
|
||||||
|
DecreeContext.touch(sender);
|
||||||
|
PlatformChunkGenerator plat = IrisToolbelt.access(player().getWorld());
|
||||||
|
Engine engine = plat.getEngine();
|
||||||
|
try {
|
||||||
|
Chunk cx = player().getLocation().getChunk();
|
||||||
|
KList<Runnable> js = new KList<>();
|
||||||
|
BurstExecutor b = MultiBurst.burst.burst();
|
||||||
|
b.setMulticore(false);
|
||||||
|
int rad = engine.getMantle().getRealRadius();
|
||||||
|
for (int i = -(radius + rad); i <= radius + rad; i++) {
|
||||||
|
for (int j = -(radius + rad); j <= radius + rad; j++) {
|
||||||
|
engine.getMantle().getMantle().deleteChunk(i + cx.getX(), j + cx.getZ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = -radius; i <= radius; i++) {
|
||||||
|
for (int j = -radius; j <= radius; j++) {
|
||||||
|
int finalJ = j;
|
||||||
|
int finalI = i;
|
||||||
|
b.queue(() -> plat.injectChunkReplacement(player().getWorld(), finalI + cx.getX(), finalJ + cx.getZ(), (f) -> {
|
||||||
|
synchronized (js) {
|
||||||
|
js.add(f);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b.complete();
|
||||||
|
sender().sendMessage(C.GREEN + "Regenerating " + Form.f(js.size()) + " Sections");
|
||||||
|
QueueJob<Runnable> r = new QueueJob<>() {
|
||||||
|
final KList<Future<?>> futures = new KList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Runnable runnable) {
|
||||||
|
futures.add(J.sfut(runnable));
|
||||||
|
|
||||||
|
if (futures.size() > 64) {
|
||||||
|
while (futures.isNotEmpty()) {
|
||||||
|
try {
|
||||||
|
futures.remove(0).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Regenerating";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.queue(js);
|
||||||
|
r.execute(sender());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
sender().sendMessage("Unable to parse view-distance");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.RED + "You must be in an Iris World to use regen!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(description = "Convert objects in the \"convert\" folder")
|
@Decree(description = "Convert objects in the \"convert\" folder")
|
||||||
public void convert() {
|
public void convert() {
|
||||||
Iris.service(ConversionSVC.class).check(sender());
|
Iris.service(ConversionSVC.class).check(sender());
|
||||||
|
//IrisConverter.convertSchematics(sender());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Decree(description = "Execute a script", aliases = "run", origin = DecreeOrigin.PLAYER)
|
@Decree(description = "Execute a script", aliases = "run", origin = DecreeOrigin.PLAYER)
|
||||||
public void execute(
|
public void execute(
|
||||||
@Param(description = "The script to run")
|
@Param(description = "The script to run")
|
||||||
@@ -218,7 +306,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
Inventory inv = Bukkit.createInventory(null, 27 * 2);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
engine().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
engine().addItems(true, inv, RNG.r, tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
sender().sendMessage(C.RED + "Cannot add items to virtual inventory because of: " + e.getMessage());
|
||||||
@@ -241,13 +329,80 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
inv.clear();
|
inv.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
engine().addItems(true, inv, new RNG(RNG.r.imax()), tables, InventorySlotType.STORAGE, player().getWorld(), player().getLocation().getBlockX(), player().getLocation().getBlockY(), player().getLocation().getBlockZ(), 1);
|
||||||
}, 0, fast ? 5 : 35));
|
}, 0, fast ? 5 : 35));
|
||||||
|
|
||||||
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
sender().sendMessage(C.GREEN + "Opening inventory now!");
|
||||||
player().openInventory(inv);
|
player().openInventory(inv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Decree(description = "Get all structures in a radius of chunks", aliases = "dist", origin = DecreeOrigin.PLAYER)
|
||||||
|
public void distances(@Param(description = "The radius in chunks") int radius) {
|
||||||
|
var engine = engine();
|
||||||
|
if (engine == null) {
|
||||||
|
sender().sendMessage(C.RED + "Only works in an Iris world!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var sender = sender();
|
||||||
|
int d = radius * 2;
|
||||||
|
KMap<String, KList<Position2>> data = new KMap<>();
|
||||||
|
var multiBurst = new MultiBurst("Distance Sampler", Thread.MIN_PRIORITY);
|
||||||
|
var executor = multiBurst.burst(radius * radius);
|
||||||
|
|
||||||
|
sender.sendMessage(C.GRAY + "Generating data...");
|
||||||
|
var loc = player().getLocation();
|
||||||
|
int totalTasks = d * d;
|
||||||
|
AtomicInteger completedTasks = new AtomicInteger(0);
|
||||||
|
int c = J.ar(() -> {
|
||||||
|
sender.sendProgress((double) completedTasks.get() / totalTasks, "Finding structures");
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
new Spiraler(d, d, (x, z) -> executor.queue(() -> {
|
||||||
|
var struct = engine.getStructureAt(x, z);
|
||||||
|
if (struct != null) {
|
||||||
|
data.computeIfAbsent(struct.getLoadKey(), (k) -> new KList<>()).add(new Position2(x, z));
|
||||||
|
}
|
||||||
|
completedTasks.incrementAndGet();
|
||||||
|
})).setOffset(loc.getBlockX(), loc.getBlockZ()).drain();
|
||||||
|
|
||||||
|
executor.complete();
|
||||||
|
multiBurst.close();
|
||||||
|
J.car(c);
|
||||||
|
|
||||||
|
for (var key : data.keySet()) {
|
||||||
|
var list = data.get(key);
|
||||||
|
KList<Long> distances = new KList<>(list.size() - 1);
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
var pos = list.get(i);
|
||||||
|
double dist = Integer.MAX_VALUE;
|
||||||
|
for (var p : list) {
|
||||||
|
if (p.equals(pos)) continue;
|
||||||
|
dist = Math.min(dist, Math.sqrt(Math.pow(pos.getX() - p.getX(), 2) + Math.pow(pos.getZ() - p.getZ(), 2)));
|
||||||
|
}
|
||||||
|
if (dist == Integer.MAX_VALUE) continue;
|
||||||
|
distances.add(Math.round(dist * 16));
|
||||||
|
}
|
||||||
|
long[] array = new long[distances.size()];
|
||||||
|
for (int i = 0; i < distances.size(); i++) {
|
||||||
|
array[i] = distances.get(i);
|
||||||
|
}
|
||||||
|
Arrays.sort(array);
|
||||||
|
long min = array.length > 0 ? array[0] : 0;
|
||||||
|
long max = array.length > 0 ? array[array.length - 1] : 0;
|
||||||
|
long sum = Arrays.stream(array).sum();
|
||||||
|
long avg = array.length > 0 ? Math.round(sum / (double) array.length) : 0;
|
||||||
|
String msg = "%s: %s => min: %s/max: %s -> avg: %s".formatted(key, list.size(), min, max, avg);
|
||||||
|
sender.sendMessage(msg);
|
||||||
|
}
|
||||||
|
if (data.isEmpty()) {
|
||||||
|
sender.sendMessage(C.RED + "No data found!");
|
||||||
|
} else {
|
||||||
|
sender.sendMessage(C.GREEN + "Done!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Decree(description = "Render a world map (External GUI)", aliases = "render")
|
@Decree(description = "Render a world map (External GUI)", aliases = "render")
|
||||||
public void map(
|
public void map(
|
||||||
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
@Param(name = "world", description = "The world to open the generator for", contextual = true)
|
||||||
@@ -281,6 +436,7 @@ public class CommandStudio implements DecreeExecutor {
|
|||||||
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default")
|
@Param(description = "The dimension to profile", contextual = true, defaultValue = "default")
|
||||||
IrisDimension dimension
|
IrisDimension dimension
|
||||||
) {
|
) {
|
||||||
|
// Todo: Make this more accurate
|
||||||
File pack = dimension.getLoadFile().getParentFile().getParentFile();
|
File pack = dimension.getLoadFile().getParentFile().getParentFile();
|
||||||
File report = Iris.instance.getDataFile("profile.txt");
|
File report = Iris.instance.getDataFile("profile.txt");
|
||||||
IrisProject project = new IrisProject(pack);
|
IrisProject project = new IrisProject(pack);
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.core.commands;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.pregenerator.ChunkUpdater;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Decree;
|
||||||
|
import com.volmit.iris.util.decree.annotations.Param;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
|
||||||
|
@Decree(name = "updater", origin = DecreeOrigin.BOTH, description = "Iris World Updater")
|
||||||
|
public class CommandUpdater implements DecreeExecutor {
|
||||||
|
private ChunkUpdater chunkUpdater;
|
||||||
|
|
||||||
|
@Decree(description = "Updates all chunk in the specified world")
|
||||||
|
public void start(
|
||||||
|
@Param(description = "World to update chunks at", contextual = true)
|
||||||
|
World world
|
||||||
|
) {
|
||||||
|
if (!IrisToolbelt.isIrisWorld(world)) {
|
||||||
|
sender().sendMessage(C.GOLD + "This is not an Iris world");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (chunkUpdater != null) {
|
||||||
|
chunkUpdater.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
chunkUpdater = new ChunkUpdater(world);
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
sender().sendMessage(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
||||||
|
} else {
|
||||||
|
Iris.info(C.GREEN + "Updating " + world.getName() + C.GRAY + " Total chunks: " + Form.f(chunkUpdater.getChunks()));
|
||||||
|
}
|
||||||
|
chunkUpdater.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Pause the updater")
|
||||||
|
public void pause( ) {
|
||||||
|
if (chunkUpdater == null) {
|
||||||
|
sender().sendMessage(C.GOLD + "You cant pause something that doesnt exist?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean status = chunkUpdater.pause();
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
if (status) {
|
||||||
|
sender().sendMessage(C.IRIS + "Paused task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
} else {
|
||||||
|
sender().sendMessage(C.IRIS + "Unpause task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (status) {
|
||||||
|
Iris.info(C.IRIS + "Paused task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
} else {
|
||||||
|
Iris.info(C.IRIS + "Unpause task for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Decree(description = "Stops the updater")
|
||||||
|
public void stop() {
|
||||||
|
if (chunkUpdater == null) {
|
||||||
|
sender().sendMessage(C.GOLD + "You cant stop something that doesnt exist?");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (sender().isPlayer()) {
|
||||||
|
sender().sendMessage("Stopping Updater for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
} else {
|
||||||
|
Iris.info("Stopping Updater for: " + C.GRAY + chunkUpdater.getName());
|
||||||
|
}
|
||||||
|
chunkUpdater.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -22,7 +22,9 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.edit.BlockSignal;
|
import com.volmit.iris.core.edit.BlockSignal;
|
||||||
import com.volmit.iris.core.nms.INMS;
|
import com.volmit.iris.core.nms.INMS;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.engine.object.IrisBiome;
|
import com.volmit.iris.engine.object.IrisBiome;
|
||||||
|
import com.volmit.iris.engine.object.IrisRegion;
|
||||||
import com.volmit.iris.util.data.B;
|
import com.volmit.iris.util.data.B;
|
||||||
import com.volmit.iris.util.decree.DecreeExecutor;
|
import com.volmit.iris.util.decree.DecreeExecutor;
|
||||||
import com.volmit.iris.util.decree.DecreeOrigin;
|
import com.volmit.iris.util.decree.DecreeOrigin;
|
||||||
@@ -37,6 +39,7 @@ import org.bukkit.Material;
|
|||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Decree(name = "what", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris What?")
|
@Decree(name = "what", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris What?")
|
||||||
@@ -82,6 +85,19 @@ public class CommandWhat implements DecreeExecutor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Decree(description = "What region am i in?", origin = DecreeOrigin.PLAYER)
|
||||||
|
public void region() {
|
||||||
|
try {
|
||||||
|
Chunk chunk = world().getChunkAt(player().getLocation().getBlockZ() / 16, player().getLocation().getBlockZ() / 16);
|
||||||
|
IrisRegion r = engine().getRegion(chunk);
|
||||||
|
sender().sendMessage("IRegion: " + r.getLoadKey() + " (" + r.getName() + ")");
|
||||||
|
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Decree(description = "What block am i looking at?", origin = DecreeOrigin.PLAYER)
|
@Decree(description = "What block am i looking at?", origin = DecreeOrigin.PLAYER)
|
||||||
public void block() {
|
public void block() {
|
||||||
BlockData bd;
|
BlockData bd;
|
||||||
@@ -147,7 +163,7 @@ public class CommandWhat implements DecreeExecutor {
|
|||||||
|
|
||||||
sender().sendMessage("Found " + v.get() + " Nearby Markers (" + marker + ")");
|
sender().sendMessage("Found " + v.get() + " Nearby Markers (" + marker + ")");
|
||||||
} else {
|
} else {
|
||||||
sender().sendMessage("Iris worlds only.");
|
sender().sendMessage(C.IRIS + "Iris worlds only.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.core.gui;
|
package com.volmit.iris.core.gui;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
import com.volmit.iris.core.events.IrisEngineHotloadEvent;
|
||||||
import com.volmit.iris.engine.object.NoiseStyle;
|
import com.volmit.iris.engine.object.NoiseStyle;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
@@ -61,7 +62,7 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
|
|||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
RollingSequence r = new RollingSequence(20);
|
RollingSequence r = new RollingSequence(20);
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
boolean colorMode = true;
|
boolean colorMode = IrisSettings.get().getGui().colorMode;
|
||||||
double scale = 1;
|
double scale = 1;
|
||||||
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
|
CNG cng = NoiseStyle.STATIC.create(new RNG(RNG.r.nextLong()));
|
||||||
@SuppressWarnings("CanBeFinal")
|
@SuppressWarnings("CanBeFinal")
|
||||||
@@ -275,6 +276,9 @@ public class NoiseExplorerGUI extends JPanel implements MouseWheelListener, List
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
Color color = colorMode ? Color.getHSBColor((float) (n), 1f - (float) (n * n * n * n * n * n), 1f - (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
||||||
|
//Color color = colorMode ? Color.getHSBColor((float) (n), (float) (n * n * n * n * n * n), (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
||||||
|
//Color color = colorMode ? Color.getHSBColor((float) n, (float) (n * n * n * n * n * n), (float) n) : Color.getHSBColor(0f, 0f, (float) n);
|
||||||
|
|
||||||
int rgb = color.getRGB();
|
int rgb = color.getRGB();
|
||||||
img.setRGB(xx, z, rgb);
|
img.setRGB(xx, z, rgb);
|
||||||
} catch (Throwable ignored) {
|
} catch (Throwable ignored) {
|
||||||
@@ -24,6 +24,7 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
|
|||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregenTask;
|
import com.volmit.iris.core.pregenerator.PregenTask;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
@@ -44,6 +45,8 @@ import java.util.concurrent.TimeUnit;
|
|||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
|
||||||
|
|
||||||
public class PregeneratorJob implements PregenListener {
|
public class PregeneratorJob implements PregenListener {
|
||||||
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
|
||||||
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
|
||||||
@@ -86,11 +89,16 @@ public class PregeneratorJob implements PregenListener {
|
|||||||
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (IrisSettings.get().getGui().isUseServerLaunchedGuis()) {
|
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
J.a(this.pregenerator::start, 20);
|
var t = new Thread(() -> {
|
||||||
|
J.sleep(1000);
|
||||||
|
this.pregenerator.start();
|
||||||
|
}, "Iris Pregenerator");
|
||||||
|
t.setPriority(Thread.MIN_PRIORITY);
|
||||||
|
t.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean shutdownInstance() {
|
public static boolean shutdownInstance() {
|
||||||
@@ -55,10 +55,10 @@ public class IrisRenderer {
|
|||||||
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
|
||||||
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
|
||||||
Color c;
|
Color c;
|
||||||
if (g.getMax() <= 0) {
|
if (g.getMax(renderer) <= 0) {
|
||||||
// Max is below water level, so it is most likely an ocean biome
|
// Max is below water level, so it is most likely an ocean biome
|
||||||
c = Color.BLUE;
|
c = Color.BLUE;
|
||||||
} else if (g.getMin() < 0) {
|
} else if (g.getMin(renderer) < 0) {
|
||||||
// Min is below water level, but max is not, so it is most likely a shore biome
|
// Min is below water level, but max is not, so it is most likely a shore biome
|
||||||
c = Color.YELLOW;
|
c = Color.YELLOW;
|
||||||
} else {
|
} else {
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
|
import com.willfp.ecoitems.items.EcoItem;
|
||||||
|
import com.willfp.ecoitems.items.EcoItems;
|
||||||
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
|
||||||
|
public class EcoItemsDataProvider extends ExternalDataProvider {
|
||||||
|
private WrappedField<EcoItem, ItemStack> itemStack;
|
||||||
|
private WrappedField<EcoItem, NamespacedKey> id;
|
||||||
|
|
||||||
|
public EcoItemsDataProvider() {
|
||||||
|
super("EcoItems");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up EcoItems Link...");
|
||||||
|
itemStack = new WrappedField<>(EcoItem.class, "_itemStack");
|
||||||
|
if (this.itemStack.hasFailed()) {
|
||||||
|
Iris.error("Failed to set up EcoItems Link: Unable to fetch ItemStack field!");
|
||||||
|
}
|
||||||
|
id = new WrappedField<>(EcoItem.class, "id");
|
||||||
|
if (this.id.hasFailed()) {
|
||||||
|
Iris.error("Failed to set up EcoItems Link: Unable to fetch id field!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
EcoItem item = EcoItems.INSTANCE.getByID(itemId.key());
|
||||||
|
if (item == null) throw new MissingResourceException("Failed to find Item!", itemId.namespace(), itemId.key());
|
||||||
|
return itemStack.get(item).clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
return new Identifier[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (EcoItem item : EcoItems.INSTANCE.values()) {
|
||||||
|
try {
|
||||||
|
Identifier key = Identifier.fromNamespacedKey(id.get(item));
|
||||||
|
if (getItemStack(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||||
|
return id.namespace().equalsIgnoreCase("ecoitems") && isItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.ssomar.score.api.executableitems.ExecutableItemsAPI;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class ExecutableItemsDataProvider extends ExternalDataProvider {
|
||||||
|
public ExecutableItemsDataProvider() {
|
||||||
|
super("ExecutableItems");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up ExecutableItems Link...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
return ExecutableItemsAPI.getExecutableItemsManager().getExecutableItem(itemId.key())
|
||||||
|
.map(item -> item.buildItem(1, Optional.empty()))
|
||||||
|
.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
return new Identifier[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (String name : ExecutableItemsAPI.getExecutableItemsManager().getExecutableItemIdsList()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("executable_items", name);
|
||||||
|
if (getItemStack(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier key, boolean isItem) {
|
||||||
|
return key.namespace().equalsIgnoreCase("executable_items") && isItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package com.volmit.iris.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
@@ -25,9 +28,19 @@ public abstract class ExternalDataProvider {
|
|||||||
|
|
||||||
public abstract void init();
|
public abstract void init();
|
||||||
|
|
||||||
public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException;
|
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
||||||
|
return getBlockData(blockId, new KMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException;
|
public abstract BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException;
|
||||||
|
|
||||||
|
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
||||||
|
return getItemStack(itemId, new KMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException;
|
||||||
|
|
||||||
|
public void processUpdate(Engine engine, Block block, Identifier blockId) {}
|
||||||
|
|
||||||
public abstract Identifier[] getBlockTypes();
|
public abstract Identifier[] getBlockTypes();
|
||||||
|
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.IrisBlockData;
|
||||||
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
|
import com.volmit.iris.util.reflect.WrappedReturningMethod;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.block.data.type.Leaves;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class HMCLeavesDataProvider extends ExternalDataProvider {
|
||||||
|
private Object apiInstance;
|
||||||
|
private WrappedReturningMethod<Object, Material> worldBlockType;
|
||||||
|
private WrappedReturningMethod<Object, Boolean> setCustomBlock;
|
||||||
|
private Map<String, Object> blockDataMap = Map.of();
|
||||||
|
private Map<String, Supplier<ItemStack>> itemDataField = Map.of();
|
||||||
|
|
||||||
|
public HMCLeavesDataProvider() {
|
||||||
|
super("HMCLeaves");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPluginId() {
|
||||||
|
return "HMCLeaves";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
try {
|
||||||
|
worldBlockType = new WrappedReturningMethod<>((Class<Object>) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType");
|
||||||
|
apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI"));
|
||||||
|
setCustomBlock = new WrappedReturningMethod<>((Class<Object>) apiInstance.getClass(), "setCustomBlock", Location.class, String.class, boolean.class);
|
||||||
|
Object config = getLeavesConfig(apiInstance.getClass());
|
||||||
|
blockDataMap = getMap(config, "blockDataMap");
|
||||||
|
itemDataField = getMap(config, "itemSupplierMap");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Failed to initialize HMCLeavesDataProvider: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
|
Object o = blockDataMap.get(blockId.key());
|
||||||
|
if (o == null)
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
Material material = worldBlockType.invoke(o, new Object[0]);
|
||||||
|
if (material == null)
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
BlockData blockData = Bukkit.createBlockData(material);
|
||||||
|
if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves)
|
||||||
|
leaves.setPersistent(true);
|
||||||
|
return new IrisBlockData(blockData, ExternalDataSVC.buildState(blockId, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
if (!itemDataField.containsKey(itemId.key()))
|
||||||
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
|
return itemDataField.get(itemId.key()).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||||
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
|
blockId = pair.getA();
|
||||||
|
Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), false});
|
||||||
|
if (result == null || !result)
|
||||||
|
Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ());
|
||||||
|
else if (IrisSettings.get().getGenerator().preventLeafDecay) {
|
||||||
|
BlockData blockData = block.getBlockData();
|
||||||
|
if (blockData instanceof Leaves leaves)
|
||||||
|
leaves.setPersistent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (String name : blockDataMap.keySet()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("hmcleaves", name);
|
||||||
|
if (getBlockData(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (String name : itemDataField.keySet()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("hmcleaves", name);
|
||||||
|
if (getItemStack(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||||
|
return (isItem ? itemDataField.keySet() : blockDataMap.keySet()).contains(id.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
private <C, T> Map<String, T> getMap(C config, String name) {
|
||||||
|
WrappedField<C, Map<String, T>> field = new WrappedField<>((Class<C>) config.getClass(), name);
|
||||||
|
return field.get(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <A> A getApiInstance(Class<A> apiClass) {
|
||||||
|
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||||
|
return instance.invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <A, C> C getLeavesConfig(Class<A> apiClass) {
|
||||||
|
WrappedReturningMethod<A, A> instance = new WrappedReturningMethod<>(apiClass, "getInstance");
|
||||||
|
WrappedField<A, C> config = new WrappedField<>(apiClass, "config");
|
||||||
|
return config.get(instance.invoke());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,10 @@ public record Identifier(String namespace, String key) {
|
|||||||
|
|
||||||
private static final String DEFAULT_NAMESPACE = "minecraft";
|
private static final String DEFAULT_NAMESPACE = "minecraft";
|
||||||
|
|
||||||
|
public static Identifier fromNamespacedKey(NamespacedKey key) {
|
||||||
|
return new Identifier(key.getNamespace(), key.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
public static Identifier fromString(String id) {
|
public static Identifier fromString(String id) {
|
||||||
String[] strings = id.split(":", 2);
|
String[] strings = id.split(":", 2);
|
||||||
if (strings.length == 1) {
|
if (strings.length == 1) {
|
||||||
@@ -46,7 +46,7 @@ public class IrisPapiExpansion extends PlaceholderExpansion {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean persist() {
|
public boolean persist() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.link;
|
|||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import dev.lone.itemsadder.api.CustomBlock;
|
import dev.lone.itemsadder.api.CustomBlock;
|
||||||
import dev.lone.itemsadder.api.CustomStack;
|
import dev.lone.itemsadder.api.CustomStack;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
@@ -32,12 +33,12 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
return CustomBlock.getBaseBlockData(blockId.toString());
|
return CustomBlock.getBaseBlockData(blockId.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
CustomStack stack = CustomStack.getInstance(itemId.toString());
|
CustomStack stack = CustomStack.getInstance(itemId.toString());
|
||||||
if (stack == null) {
|
if (stack == null) {
|
||||||
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import net.Indyuce.mmoitems.MMOItems;
|
||||||
|
import net.Indyuce.mmoitems.api.ItemTier;
|
||||||
|
import net.Indyuce.mmoitems.api.Type;
|
||||||
|
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
public class MMOItemsDataProvider extends ExternalDataProvider {
|
||||||
|
|
||||||
|
public MMOItemsDataProvider() {
|
||||||
|
super("MMOItems");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up MMOItems Link...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
|
int id = -1;
|
||||||
|
try {
|
||||||
|
id = Integer.parseInt(blockId.key());
|
||||||
|
} catch (NumberFormatException ignored) {}
|
||||||
|
CustomBlock block = api().getCustomBlocks().getBlock(id);
|
||||||
|
if (block == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
return block.getState().getBlockData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
String[] parts = itemId.namespace().split("_", 2);
|
||||||
|
if (parts.length != 2)
|
||||||
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
|
CompletableFuture<ItemStack> future = new CompletableFuture<>();
|
||||||
|
Runnable run = () -> {
|
||||||
|
try {
|
||||||
|
var type = api().getTypes().get(parts[1]);
|
||||||
|
int level = -1;
|
||||||
|
ItemTier tier = null;
|
||||||
|
|
||||||
|
if (customNbt != null) {
|
||||||
|
level = (int) customNbt.getOrDefault("level", -1);
|
||||||
|
tier = api().getTiers().get(String.valueOf(customNbt.get("tier")));
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemStack itemStack;
|
||||||
|
if (type == null) {
|
||||||
|
future.complete(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level != -1 && tier != null) {
|
||||||
|
itemStack = api().getItem(type, itemId.key(), level, tier);
|
||||||
|
} else {
|
||||||
|
itemStack = api().getItem(type, itemId.key());
|
||||||
|
}
|
||||||
|
future.complete(itemStack);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
future.completeExceptionally(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (Bukkit.isPrimaryThread()) run.run();
|
||||||
|
else J.s(run);
|
||||||
|
ItemStack item = null;
|
||||||
|
try {
|
||||||
|
item = future.get();
|
||||||
|
} catch (InterruptedException | ExecutionException ignored) {}
|
||||||
|
if (item == null)
|
||||||
|
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (Integer id : api().getCustomBlocks().getBlockIds()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("mmoitems", String.valueOf(id));
|
||||||
|
if (getBlockData(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
Runnable run = () -> {
|
||||||
|
for (Type type : api().getTypes().getAll()) {
|
||||||
|
for (String name : api().getTemplates().getTemplateNames(type)) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("mmoitems_" + type.getId(), name);
|
||||||
|
if (getItemStack(key) != null)
|
||||||
|
names.add(key);
|
||||||
|
} catch (MissingResourceException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (Bukkit.isPrimaryThread()) run.run();
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
J.sfut(run).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
Iris.error("Failed getting MMOItems item types!");
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier id, boolean isItem) {
|
||||||
|
return isItem ? id.namespace().split("_", 2).length == 2 : id.namespace().equals("mmoitems");
|
||||||
|
}
|
||||||
|
|
||||||
|
private MMOItems api() {
|
||||||
|
return MMOItems.plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
/*
|
||||||
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
|
*
|
||||||
|
* 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisBlockData;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
|
import io.lumine.mythic.bukkit.BukkitAdapter;
|
||||||
|
import io.lumine.mythic.bukkit.utils.serialize.Chroma;
|
||||||
|
import io.lumine.mythiccrucible.MythicCrucible;
|
||||||
|
import io.lumine.mythiccrucible.items.CrucibleItem;
|
||||||
|
import io.lumine.mythiccrucible.items.ItemManager;
|
||||||
|
import io.lumine.mythiccrucible.items.blocks.CustomBlockItemContext;
|
||||||
|
import io.lumine.mythiccrucible.items.furniture.FurnitureItemContext;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class MythicCrucibleDataProvider extends ExternalDataProvider {
|
||||||
|
|
||||||
|
private ItemManager itemManager;
|
||||||
|
|
||||||
|
public MythicCrucibleDataProvider() {
|
||||||
|
super("MythicCrucible");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
Iris.info("Setting up MythicCrucible Link...");
|
||||||
|
try {
|
||||||
|
this.itemManager = MythicCrucible.inst().getItemManager();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("Failed to set up MythicCrucible Link: Unable to fetch MythicCrucible instance!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
|
CrucibleItem crucibleItem = this.itemManager.getItem(blockId.key())
|
||||||
|
.orElseThrow(() -> new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()));
|
||||||
|
CustomBlockItemContext blockItemContext = crucibleItem.getBlockData();
|
||||||
|
FurnitureItemContext furnitureItemContext = crucibleItem.getFurnitureData();
|
||||||
|
if (furnitureItemContext != null) {
|
||||||
|
return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
||||||
|
} else if (blockItemContext != null) {
|
||||||
|
return blockItemContext.getBlockData();
|
||||||
|
}
|
||||||
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
|
Optional<CrucibleItem> opt = this.itemManager.getItem(itemId.key());
|
||||||
|
return BukkitAdapter.adapt(opt.orElseThrow(() ->
|
||||||
|
new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()))
|
||||||
|
.getMythicItem()
|
||||||
|
.generateItemStack(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getBlockTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (CrucibleItem item : this.itemManager.getItems()) {
|
||||||
|
if (item.getBlockData() == null) continue;
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("crucible", item.getInternalName());
|
||||||
|
if (getBlockData(key) != null) {
|
||||||
|
Iris.info("getBlockTypes: Block loaded '" + item.getInternalName() + "'");
|
||||||
|
names.add(key);
|
||||||
|
}
|
||||||
|
} catch (MissingResourceException ignored) {}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Identifier[] getItemTypes() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
for (CrucibleItem item : this.itemManager.getItems()) {
|
||||||
|
try {
|
||||||
|
Identifier key = new Identifier("crucible", item.getInternalName());
|
||||||
|
if (getItemStack(key) != null) {
|
||||||
|
Iris.info("getItemTypes: Item loaded '" + item.getInternalName() + "'");
|
||||||
|
names.add(key);
|
||||||
|
}
|
||||||
|
} catch (MissingResourceException ignored) {}
|
||||||
|
}
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||||
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
|
var state = pair.getB();
|
||||||
|
blockId = pair.getA();
|
||||||
|
|
||||||
|
Optional<CrucibleItem> item = itemManager.getItem(blockId.key());
|
||||||
|
if (item.isEmpty()) return;
|
||||||
|
FurnitureItemContext furniture = item.get().getFurnitureData();
|
||||||
|
if (furniture == null) return;
|
||||||
|
|
||||||
|
float yaw = 0;
|
||||||
|
BlockFace face = BlockFace.NORTH;
|
||||||
|
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
|
||||||
|
RNG rng = new RNG(seed);
|
||||||
|
if ("true".equals(state.get("randomYaw"))) {
|
||||||
|
yaw = rng.f(0, 360);
|
||||||
|
} else if (state.containsKey("yaw")) {
|
||||||
|
yaw = Float.parseFloat(state.get("yaw"));
|
||||||
|
}
|
||||||
|
if ("true".equals(state.get("randomFace"))) {
|
||||||
|
BlockFace[] faces = BlockFace.values();
|
||||||
|
face = faces[rng.i(0, faces.length - 1)];
|
||||||
|
} else if (state.containsKey("face")) {
|
||||||
|
face = BlockFace.valueOf(state.get("face").toUpperCase());
|
||||||
|
}
|
||||||
|
if (face == BlockFace.SELF) {
|
||||||
|
face = BlockFace.NORTH;
|
||||||
|
}
|
||||||
|
|
||||||
|
BiomeColor type = null;
|
||||||
|
Chroma color = null;
|
||||||
|
try {
|
||||||
|
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
|
||||||
|
} catch (NullPointerException | IllegalArgumentException ignored) {}
|
||||||
|
if (type != null) {
|
||||||
|
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
|
||||||
|
if (biomeColor == null) return;
|
||||||
|
color = Chroma.of(biomeColor.getRGB());
|
||||||
|
}
|
||||||
|
furniture.place(block, face, yaw, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidProvider(Identifier key, boolean isItem) {
|
||||||
|
return key.namespace().equalsIgnoreCase("crucible");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,25 +19,45 @@
|
|||||||
package com.volmit.iris.core.link;
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.service.ExternalDataSVC;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.data.B;
|
||||||
|
import com.volmit.iris.util.data.IrisBlockData;
|
||||||
|
import com.volmit.iris.util.math.RNG;
|
||||||
import com.volmit.iris.util.reflect.WrappedField;
|
import com.volmit.iris.util.reflect.WrappedField;
|
||||||
import io.th0rgal.oraxen.api.OraxenItems;
|
import io.th0rgal.oraxen.api.OraxenItems;
|
||||||
import io.th0rgal.oraxen.items.ItemBuilder;
|
import io.th0rgal.oraxen.items.ItemBuilder;
|
||||||
|
import io.th0rgal.oraxen.mechanics.Mechanic;
|
||||||
import io.th0rgal.oraxen.mechanics.MechanicFactory;
|
import io.th0rgal.oraxen.mechanics.MechanicFactory;
|
||||||
import io.th0rgal.oraxen.mechanics.MechanicsManager;
|
import io.th0rgal.oraxen.mechanics.MechanicsManager;
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic;
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanic;
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory;
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.block.BlockMechanicFactory;
|
||||||
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureFactory;
|
||||||
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.furniture.FurnitureMechanic;
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.noteblock.NoteBlockMechanicFactory;
|
||||||
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
|
import io.th0rgal.oraxen.mechanics.provided.gameplay.stringblock.StringBlockMechanicFactory;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Color;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.MultipleFacing;
|
import org.bukkit.block.data.MultipleFacing;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.ItemDisplay;
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.MissingResourceException;
|
import java.util.MissingResourceException;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class OraxenDataProvider extends ExternalDataProvider {
|
public class OraxenDataProvider extends ExternalDataProvider {
|
||||||
|
|
||||||
@@ -59,7 +79,7 @@ public class OraxenDataProvider extends ExternalDataProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
|
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
|
||||||
MechanicFactory factory = getFactory(blockId);
|
MechanicFactory factory = getFactory(blockId);
|
||||||
if (factory instanceof NoteBlockMechanicFactory f)
|
if (factory instanceof NoteBlockMechanicFactory f)
|
||||||
return f.createNoteBlockData(blockId.key());
|
return f.createNoteBlockData(blockId.key());
|
||||||
@@ -69,16 +89,75 @@ public class OraxenDataProvider extends ExternalDataProvider {
|
|||||||
return newBlockData;
|
return newBlockData;
|
||||||
} else if (factory instanceof StringBlockMechanicFactory f) {
|
} else if (factory instanceof StringBlockMechanicFactory f) {
|
||||||
return f.createTripwireData(blockId.key());
|
return f.createTripwireData(blockId.key());
|
||||||
|
} else if (factory instanceof FurnitureFactory) {
|
||||||
|
return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
|
||||||
} else
|
} else
|
||||||
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack getItemStack(Identifier itemId) throws MissingResourceException {
|
public ItemStack getItemStack(Identifier itemId, KMap<String, Object> customNbt) throws MissingResourceException {
|
||||||
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
|
Optional<ItemBuilder> opt = OraxenItems.getOptionalItemById(itemId.key());
|
||||||
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
|
return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||||
|
var pair = ExternalDataSVC.parseState(blockId);
|
||||||
|
var state = pair.getB();
|
||||||
|
blockId = pair.getA();
|
||||||
|
Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key());
|
||||||
|
if (mechanic instanceof FurnitureMechanic f) {
|
||||||
|
float yaw = 0;
|
||||||
|
BlockFace face = BlockFace.NORTH;
|
||||||
|
|
||||||
|
long seed = engine.getSeedManager().getSeed() + Cache.key(block.getX(), block.getZ()) + block.getY();
|
||||||
|
RNG rng = new RNG(seed);
|
||||||
|
if ("true".equals(state.get("randomYaw"))) {
|
||||||
|
yaw = rng.f(0, 360);
|
||||||
|
} else if (state.containsKey("yaw")) {
|
||||||
|
yaw = Float.parseFloat(state.get("yaw"));
|
||||||
|
}
|
||||||
|
if ("true".equals(state.get("randomFace"))) {
|
||||||
|
BlockFace[] faces = BlockFace.values();
|
||||||
|
face = faces[rng.i(0, faces.length - 1)];
|
||||||
|
} else if (state.containsKey("face")) {
|
||||||
|
face = BlockFace.valueOf(state.get("face").toUpperCase());
|
||||||
|
}
|
||||||
|
if (face == BlockFace.SELF) {
|
||||||
|
face = BlockFace.NORTH;
|
||||||
|
}
|
||||||
|
ItemStack itemStack = OraxenItems.getItemById(f.getItemID()).build();
|
||||||
|
Entity entity = f.place(block.getLocation(), itemStack, yaw, face, false);
|
||||||
|
|
||||||
|
Consumer<ItemStack> setter = null;
|
||||||
|
if (entity instanceof ItemFrame frame) {
|
||||||
|
itemStack = frame.getItem();
|
||||||
|
setter = frame::setItem;
|
||||||
|
} else if (entity instanceof ItemDisplay display) {
|
||||||
|
itemStack = display.getItemStack();
|
||||||
|
setter = display::setItemStack;
|
||||||
|
}
|
||||||
|
if (setter == null || itemStack == null) return;
|
||||||
|
|
||||||
|
BiomeColor type = null;
|
||||||
|
try {
|
||||||
|
type = BiomeColor.valueOf(state.get("matchBiome").toUpperCase());
|
||||||
|
} catch (NullPointerException | IllegalArgumentException ignored) {}
|
||||||
|
|
||||||
|
if (type != null) {
|
||||||
|
var biomeColor = INMS.get().getBiomeColor(block.getLocation(), type);
|
||||||
|
if (biomeColor == null) return;
|
||||||
|
var potionColor = Color.fromARGB(biomeColor.getAlpha(), biomeColor.getRed(), biomeColor.getGreen(), biomeColor.getBlue());
|
||||||
|
if (itemStack.getItemMeta() instanceof PotionMeta meta) {
|
||||||
|
meta.setColor(potionColor);
|
||||||
|
itemStack.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setter.accept(itemStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Identifier[] getBlockTypes() {
|
public Identifier[] getBlockTypes() {
|
||||||
KList<Identifier> names = new KList<>();
|
KList<Identifier> names = new KList<>();
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.volmit.iris.core.link;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||||
|
import com.volmit.iris.util.data.Cuboid;
|
||||||
|
import com.volmit.iris.util.data.KCache;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class WorldEditLink {
|
||||||
|
private static final AtomicCache<Boolean> active = new AtomicCache<>();
|
||||||
|
|
||||||
|
public static Cuboid getSelection(Player p) {
|
||||||
|
if (!hasWorldEdit())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object instance = Class.forName("com.sk89q.worldedit.WorldEdit").getDeclaredMethod("getInstance").invoke(null);
|
||||||
|
Object sessionManager = instance.getClass().getDeclaredMethod("getSessionManager").invoke(instance);
|
||||||
|
Class<?> bukkitAdapter = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter");
|
||||||
|
Object world = bukkitAdapter.getDeclaredMethod("adapt", World.class).invoke(null, p.getWorld());
|
||||||
|
Object player = bukkitAdapter.getDeclaredMethod("adapt", Player.class).invoke(null, p);
|
||||||
|
Object localSession = sessionManager.getClass().getDeclaredMethod("getIfPresent", Class.forName("com.sk89q.worldedit.session.SessionOwner")).invoke(sessionManager, player);
|
||||||
|
if (localSession == null) return null;
|
||||||
|
|
||||||
|
Object region = null;
|
||||||
|
try {
|
||||||
|
region = localSession.getClass().getDeclaredMethod("getSelection", Class.forName("com.sk89q.worldedit.world.World")).invoke(localSession, world);
|
||||||
|
} catch (InvocationTargetException ignored) {}
|
||||||
|
if (region == null) return null;
|
||||||
|
|
||||||
|
Object min = region.getClass().getDeclaredMethod("getMinimumPoint").invoke(region);
|
||||||
|
Object max = region.getClass().getDeclaredMethod("getMaximumPoint").invoke(region);
|
||||||
|
return new Cuboid(p.getWorld(),
|
||||||
|
(int) min.getClass().getDeclaredMethod("x").invoke(min),
|
||||||
|
(int) min.getClass().getDeclaredMethod("y").invoke(min),
|
||||||
|
(int) min.getClass().getDeclaredMethod("z").invoke(min),
|
||||||
|
(int) min.getClass().getDeclaredMethod("x").invoke(max),
|
||||||
|
(int) min.getClass().getDeclaredMethod("y").invoke(max),
|
||||||
|
(int) min.getClass().getDeclaredMethod("z").invoke(max)
|
||||||
|
);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Could not get selection");
|
||||||
|
e.printStackTrace();
|
||||||
|
active.reset();
|
||||||
|
active.aquire(() -> false);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasWorldEdit() {
|
||||||
|
return active.aquire(() -> Bukkit.getPluginManager().isPluginEnabled("WorldEdit"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,10 +50,10 @@ public class ObjectResourceLoader extends ResourceLoader<IrisObject> {
|
|||||||
try {
|
try {
|
||||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||||
IrisObject t = new IrisObject(0, 0, 0);
|
IrisObject t = new IrisObject(0, 0, 0);
|
||||||
t.read(j);
|
|
||||||
t.setLoadKey(name);
|
t.setLoadKey(name);
|
||||||
t.setLoader(manager);
|
t.setLoader(manager);
|
||||||
t.setLoadFile(j);
|
t.setLoadFile(j);
|
||||||
|
t.read(j);
|
||||||
logLoad(j, t);
|
logLoad(j, t);
|
||||||
tlt.addAndGet(p.getMilliseconds());
|
tlt.addAndGet(p.getMilliseconds());
|
||||||
return t;
|
return t;
|
||||||
@@ -40,6 +40,8 @@ import com.volmit.iris.util.scheduling.ChronoLatch;
|
|||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -52,6 +54,8 @@ import java.util.zip.GZIPInputStream;
|
|||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(exclude = "manager")
|
||||||
|
@ToString(exclude = "manager")
|
||||||
public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
|
public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
|
||||||
public static final AtomicDouble tlt = new AtomicDouble(0);
|
public static final AtomicDouble tlt = new AtomicDouble(0);
|
||||||
private static final int CACHE_SIZE = 100000;
|
private static final int CACHE_SIZE = 100000;
|
||||||
@@ -358,7 +362,12 @@ public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
|
|||||||
if (folderCache.get() == null) {
|
if (folderCache.get() == null) {
|
||||||
KList<File> fc = new KList<>();
|
KList<File> fc = new KList<>();
|
||||||
|
|
||||||
for (File i : root.listFiles()) {
|
File[] files = root.listFiles();
|
||||||
|
if (files == null) {
|
||||||
|
throw new IllegalStateException("Failed to list files in " + root);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (File i : files) {
|
||||||
if (i.isDirectory()) {
|
if (i.isDirectory()) {
|
||||||
if (i.getName().equals(folderName)) {
|
if (i.getName().equals(folderName)) {
|
||||||
fc.add(i);
|
fc.add(i);
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
|
||||||
|
public interface IMemoryWorld extends Listener, AutoCloseable {
|
||||||
|
|
||||||
|
World getBukkit();
|
||||||
|
|
||||||
|
Chunk getChunk(int x, int z);
|
||||||
|
|
||||||
|
ChunkGenerator.ChunkData getChunkData(int x, int z);
|
||||||
|
}
|
||||||
@@ -1,77 +1,87 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.nms.v20.NMSBinding1_20_1;
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
import org.bukkit.Bukkit;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
|
||||||
import org.bukkit.Bukkit;
|
import java.util.Map;
|
||||||
|
|
||||||
public class INMS {
|
public class INMS {
|
||||||
//@builder
|
private static final Map<String, String> REVISION = Map.of(
|
||||||
private static final KMap<String, Class<? extends INMSBinding>> bindings = new KMap<String, Class<? extends INMSBinding>>()
|
"1.20.5", "v1_20_R4",
|
||||||
.qput("v1_20_R1", NMSBinding1_20_1.class);
|
"1.20.6", "v1_20_R4",
|
||||||
//@done
|
"1.21", "v1_21_R1",
|
||||||
private static final INMSBinding binding = bind();
|
"1.21.1", "v1_21_R1"
|
||||||
|
);
|
||||||
public static INMSBinding get() {
|
//@done
|
||||||
return binding;
|
private static final INMSBinding binding = bind();
|
||||||
}
|
|
||||||
|
public static INMSBinding get() {
|
||||||
public static String getNMSTag() {
|
return binding;
|
||||||
if (IrisSettings.get().getGeneral().isDisableNMS()) {
|
}
|
||||||
return "BUKKIT";
|
|
||||||
}
|
public static String getNMSTag() {
|
||||||
|
if (IrisSettings.get().getGeneral().isDisableNMS()) {
|
||||||
try {
|
return "BUKKIT";
|
||||||
return Bukkit.getServer().getClass().getCanonicalName().split("\\Q.\\E")[3];
|
}
|
||||||
} catch (Throwable e) {
|
|
||||||
Iris.reportError(e);
|
try {
|
||||||
Iris.error("Failed to determine server nms version!");
|
String name = Bukkit.getServer().getClass().getCanonicalName();
|
||||||
e.printStackTrace();
|
if (name.equals("org.bukkit.craftbukkit.CraftServer")) {
|
||||||
}
|
return REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0], "BUKKIT");
|
||||||
|
} else {
|
||||||
return "BUKKIT";
|
return name.split("\\Q.\\E")[3];
|
||||||
}
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
private static INMSBinding bind() {
|
Iris.reportError(e);
|
||||||
String code = getNMSTag();
|
Iris.error("Failed to determine server nms version!");
|
||||||
Iris.info("Locating NMS Binding for " + code);
|
e.printStackTrace();
|
||||||
|
}
|
||||||
if (bindings.containsKey(code)) {
|
|
||||||
try {
|
return "BUKKIT";
|
||||||
INMSBinding b = bindings.get(code).getConstructor().newInstance();
|
}
|
||||||
Iris.info("Craftbukkit " + code + " <-> " + b.getClass().getSimpleName() + " Successfully Bound");
|
|
||||||
|
private static INMSBinding bind() {
|
||||||
return b;
|
String code = getNMSTag();
|
||||||
} catch (Throwable e) {
|
Iris.info("Locating NMS Binding for " + code);
|
||||||
Iris.reportError(e);
|
|
||||||
e.printStackTrace();
|
try {
|
||||||
}
|
Class<?> clazz = Class.forName("com.volmit.iris.core.nms."+code+".NMSBinding");
|
||||||
}
|
try {
|
||||||
|
Object b = clazz.getConstructor().newInstance();
|
||||||
Iris.info("Craftbukkit " + code + " <-> " + NMSBinding1X.class.getSimpleName() + " Successfully Bound");
|
if (b instanceof INMSBinding binding) {
|
||||||
Iris.warn("Note: Some features of Iris may not work the same since you are on an unsupported version of Minecraft.");
|
Iris.info("Craftbukkit " + code + " <-> " + b.getClass().getSimpleName() + " Successfully Bound");
|
||||||
Iris.warn("Note: If this is a new version, expect an update soon.");
|
return binding;
|
||||||
|
}
|
||||||
return new NMSBinding1X();
|
} catch (Throwable e) {
|
||||||
}
|
Iris.reportError(e);
|
||||||
}
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException|NoClassDefFoundError classNotFoundException) {}
|
||||||
|
|
||||||
|
Iris.info("Craftbukkit " + code + " <-> " + NMSBinding1X.class.getSimpleName() + " Successfully Bound");
|
||||||
|
Iris.warn("Note: Some features of Iris may not work the same since you are on an unsupported version of Minecraft.");
|
||||||
|
Iris.warn("Note: If this is a new version, expect an update soon.");
|
||||||
|
|
||||||
|
return new NMSBinding1X();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,24 +18,40 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.nms;
|
package com.volmit.iris.core.nms;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.math.Vector3d;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.*;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.WorldCreator;
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.entity.Dolphin;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.generator.structure.Structure;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public interface INMSBinding {
|
public interface INMSBinding {
|
||||||
|
boolean hasTile(Material material);
|
||||||
|
|
||||||
boolean hasTile(Location l);
|
boolean hasTile(Location l);
|
||||||
|
|
||||||
CompoundTag serializeTile(Location location);
|
KMap<String, Object> serializeTile(Location location);
|
||||||
|
|
||||||
void deserializeTile(CompoundTag s, Location newPosition);
|
void deserializeTile(KMap<String, Object> s, Location newPosition);
|
||||||
|
|
||||||
CompoundTag serializeEntity(Entity location);
|
CompoundTag serializeEntity(Entity location);
|
||||||
|
|
||||||
@@ -67,6 +83,8 @@ public interface INMSBinding {
|
|||||||
|
|
||||||
Object getBiomeBase(Object registry, Biome biome);
|
Object getBiomeBase(Object registry, Biome biome);
|
||||||
|
|
||||||
|
KList<Biome> getBiomes();
|
||||||
|
|
||||||
boolean isBukkit();
|
boolean isBukkit();
|
||||||
|
|
||||||
int getBiomeId(Biome biome);
|
int getBiomeId(Biome biome);
|
||||||
@@ -81,6 +99,10 @@ public interface INMSBinding {
|
|||||||
|
|
||||||
int countCustomBiomes();
|
int countCustomBiomes();
|
||||||
|
|
||||||
|
default boolean setBlock(World world, int x, int y, int z, BlockData data, int flag, int updateDepth) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk);
|
void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk);
|
||||||
|
|
||||||
default boolean supportsDataPacks() {
|
default boolean supportsDataPacks() {
|
||||||
@@ -90,4 +112,40 @@ public interface INMSBinding {
|
|||||||
MCAPaletteAccess createPalette();
|
MCAPaletteAccess createPalette();
|
||||||
|
|
||||||
void injectBiomesFromMantle(Chunk e, Mantle mantle);
|
void injectBiomesFromMantle(Chunk e, Mantle mantle);
|
||||||
|
|
||||||
|
ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException;
|
||||||
|
|
||||||
|
void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException;
|
||||||
|
|
||||||
|
Vector3d getBoundingbox(org.bukkit.entity.EntityType entity);
|
||||||
|
|
||||||
|
Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason);
|
||||||
|
|
||||||
|
Color getBiomeColor(Location location, BiomeColor type);
|
||||||
|
|
||||||
|
default DataVersion getDataVersion() {
|
||||||
|
return DataVersion.V1192;
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getSpawnChunkCount(World world) {
|
||||||
|
return 441;
|
||||||
|
}
|
||||||
|
|
||||||
|
KList<String> getStructureKeys();
|
||||||
|
|
||||||
|
default BlockData getBlockData(CompoundTag tag) {
|
||||||
|
Iris.error("Unsupported version!");
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
default IMemoryWorld createMemoryWorld(WorldCreator creator) throws IOException {
|
||||||
|
return createMemoryWorld(switch (creator.environment()) {
|
||||||
|
case NORMAL -> NamespacedKey.minecraft("overworld");
|
||||||
|
case NETHER -> NamespacedKey.minecraft("the_nether");
|
||||||
|
case THE_END -> NamespacedKey.minecraft("the_end");
|
||||||
|
default -> throw new IllegalArgumentException("Illegal dimension (" + creator.environment() + ")");
|
||||||
|
}, creator);
|
||||||
|
}
|
||||||
|
|
||||||
|
IMemoryWorld createMemoryWorld(NamespacedKey levelType, WorldCreator creator) throws IOException;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
|
public enum BiomeColor {
|
||||||
|
FOG,
|
||||||
|
WATER,
|
||||||
|
WATER_FOG,
|
||||||
|
SKY,
|
||||||
|
FOLIAGE,
|
||||||
|
GRASS
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class BlockPos {
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
private int z;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.volmit.iris.core.nms.container;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class Pair<A, B> {
|
||||||
|
private A a;
|
||||||
|
private B b;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1192.DataFixerV1192;
|
||||||
|
import com.volmit.iris.core.nms.datapack.v1206.DataFixerV1206;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
//https://minecraft.wiki/w/Pack_format
|
||||||
|
@Getter
|
||||||
|
public enum DataVersion {
|
||||||
|
V1192("1.19.2", 10, DataFixerV1192::new),
|
||||||
|
V1205("1.20.6", 41, DataFixerV1206::new);
|
||||||
|
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
||||||
|
@Getter(AccessLevel.NONE)
|
||||||
|
private final Supplier<IDataFixer> constructor;
|
||||||
|
private final String version;
|
||||||
|
private final int packFormat;
|
||||||
|
|
||||||
|
DataVersion(String version, int packFormat, Supplier<IDataFixer> constructor) {
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.packFormat = packFormat;
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDataFixer get() {
|
||||||
|
return cache.computeIfAbsent(this, k -> constructor.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IDataFixer getDefault() {
|
||||||
|
return INMS.get().getDataVersion().get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DataVersion getLatest() {
|
||||||
|
return values()[values().length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack;
|
||||||
|
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
public interface IDataFixer {
|
||||||
|
|
||||||
|
JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json);
|
||||||
|
|
||||||
|
JSONObject fixDimension(JSONObject json);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack.v1192;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
public class DataFixerV1192 implements IDataFixer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixDimension(JSONObject json) {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.volmit.iris.core.nms.datapack.v1206;
|
||||||
|
|
||||||
|
import com.volmit.iris.core.nms.datapack.IDataFixer;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawn;
|
||||||
|
import com.volmit.iris.engine.object.IrisBiomeCustomSpawnType;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.json.JSONArray;
|
||||||
|
import com.volmit.iris.util.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class DataFixerV1206 implements IDataFixer {
|
||||||
|
@Override
|
||||||
|
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||||
|
int spawnRarity = biome.getSpawnRarity();
|
||||||
|
if (spawnRarity > 0) {
|
||||||
|
json.put("creature_spawn_probability", Math.min(spawnRarity/20d, 0.9999999));
|
||||||
|
}
|
||||||
|
|
||||||
|
var spawns = biome.getSpawns();
|
||||||
|
if (spawns != null && spawns.isNotEmpty()) {
|
||||||
|
JSONObject spawners = new JSONObject();
|
||||||
|
KMap<IrisBiomeCustomSpawnType, JSONArray> groups = new KMap<>();
|
||||||
|
|
||||||
|
for (IrisBiomeCustomSpawn i : spawns) {
|
||||||
|
JSONArray g = groups.computeIfAbsent(i.getGroup(), (k) -> new JSONArray());
|
||||||
|
JSONObject o = new JSONObject();
|
||||||
|
o.put("type", "minecraft:" + i.getType().name().toLowerCase());
|
||||||
|
o.put("weight", i.getWeight());
|
||||||
|
o.put("minCount", Math.min(i.getMinCount()/20d, 0));
|
||||||
|
o.put("maxCount", Math.min(i.getMaxCount()/20d, 0.9999999));
|
||||||
|
g.put(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IrisBiomeCustomSpawnType i : groups.k()) {
|
||||||
|
spawners.put(i.name().toLowerCase(Locale.ROOT), groups.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
json.put("spawners", spawners);
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject fixDimension(JSONObject json) {
|
||||||
|
if (!(json.get("monster_spawn_light_level") instanceof JSONObject lightLevel))
|
||||||
|
return json;
|
||||||
|
var value = (JSONObject) lightLevel.remove("value");
|
||||||
|
lightLevel.put("max_inclusive", value.get("max_inclusive"));
|
||||||
|
lightLevel.put("min_inclusive", value.get("min_inclusive"));
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,17 +19,32 @@
|
|||||||
package com.volmit.iris.core.nms.v1X;
|
package com.volmit.iris.core.nms.v1X;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.IMemoryWorld;
|
||||||
import com.volmit.iris.core.nms.INMSBinding;
|
import com.volmit.iris.core.nms.INMSBinding;
|
||||||
|
import com.volmit.iris.core.nms.container.BiomeColor;
|
||||||
|
import com.volmit.iris.core.nms.container.BlockPos;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.math.Vector3d;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
|
||||||
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
|
||||||
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
import com.volmit.iris.util.nbt.tag.CompoundTag;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.*;
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.data.BlockData;
|
||||||
|
import org.bukkit.entity.Dolphin;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.generator.ChunkGenerator;
|
import org.bukkit.generator.ChunkGenerator;
|
||||||
|
import org.bukkit.generator.structure.Structure;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class NMSBinding1X implements INMSBinding {
|
public class NMSBinding1X implements INMSBinding {
|
||||||
private static final boolean supportsCustomHeight = testCustomHeight();
|
private static final boolean supportsCustomHeight = testCustomHeight();
|
||||||
@@ -49,24 +64,68 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTile(Material material) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasTile(Location l) {
|
public boolean hasTile(Location l) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompoundTag serializeTile(Location location) {
|
public KMap<String, Object> serializeTile(Location location) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deserializeTile(KMap<String, Object> s, Location newPosition) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectBiomesFromMantle(Chunk e, Mantle mantle) {
|
public void injectBiomesFromMantle(Chunk e, Mantle mantle) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deserializeTile(CompoundTag s, Location newPosition) {
|
public ItemStack applyCustomNbt(ItemStack itemStack, KMap<String, Object> customNbt) throws IllegalArgumentException {
|
||||||
|
return itemStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector3d getBoundingbox() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) {
|
||||||
|
return location.getWorld().spawnEntity(location, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Color getBiomeColor(Location location, BiomeColor type) {
|
||||||
|
return Color.GREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KList<String> getStructureKeys() {
|
||||||
|
var list = Registry.STRUCTURE.stream()
|
||||||
|
.map(Structure::getKey)
|
||||||
|
.map(NamespacedKey::toString)
|
||||||
|
.toList();
|
||||||
|
return new KList<>(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IMemoryWorld createMemoryWorld(NamespacedKey levelType, WorldCreator creator) throws IOException {
|
||||||
|
throw new IOException("Unsupported version!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -143,6 +202,11 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KList<Biome> getBiomes() {
|
||||||
|
return new KList<>(Biome.values()).qdel(Biome.CUSTOM);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBukkit() {
|
public boolean isBukkit() {
|
||||||
return true;
|
return true;
|
||||||
@@ -177,6 +241,11 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MCAPaletteAccess createPalette() {
|
public MCAPaletteAccess createPalette() {
|
||||||
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");
|
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");
|
||||||
@@ -0,0 +1,352 @@
|
|||||||
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.data.cache.Cache;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.mantle.MantleFlag;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
|
import com.volmit.iris.util.profile.LoadBalancer;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
public class ChunkUpdater {
|
||||||
|
private final AtomicBoolean paused = new AtomicBoolean();
|
||||||
|
private final AtomicBoolean cancelled = new AtomicBoolean();
|
||||||
|
private final KMap<Long, Pair<Long, AtomicInteger>> lastUse = new KMap<>();
|
||||||
|
private final RollingSequence chunksPerSecond = new RollingSequence(5);
|
||||||
|
private final AtomicInteger totalMaxChunks = new AtomicInteger();
|
||||||
|
private final AtomicInteger chunksProcessed = new AtomicInteger();
|
||||||
|
private final AtomicInteger chunksProcessedLast = new AtomicInteger();
|
||||||
|
private final AtomicInteger chunksUpdated = new AtomicInteger();
|
||||||
|
private final AtomicBoolean serverEmpty = new AtomicBoolean(true);
|
||||||
|
private final AtomicLong lastCpsTime = new AtomicLong(M.ms());
|
||||||
|
private final int coreLimit = (int) Math.max(Runtime.getRuntime().availableProcessors() * IrisSettings.get().getUpdater().getThreadMultiplier(), 1);
|
||||||
|
private final Semaphore semaphore = new Semaphore(256);
|
||||||
|
private final LoadBalancer loadBalancer = new LoadBalancer(semaphore, 256, IrisSettings.get().getUpdater().emptyMsRange);
|
||||||
|
private final AtomicLong startTime = new AtomicLong();
|
||||||
|
private final Dimensions dimensions;
|
||||||
|
private final PregenTask task;
|
||||||
|
private final ExecutorService executor = Executors.newFixedThreadPool(coreLimit);
|
||||||
|
private final ExecutorService chunkExecutor = Executors.newFixedThreadPool(coreLimit);
|
||||||
|
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||||
|
private final CountDownLatch latch;
|
||||||
|
private final Engine engine;
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
public ChunkUpdater(World world) {
|
||||||
|
this.engine = IrisToolbelt.access(world).getEngine();
|
||||||
|
this.world = world;
|
||||||
|
this.dimensions = calculateWorldDimensions(new File(world.getWorldFolder(), "region"));
|
||||||
|
this.task = dimensions.task();
|
||||||
|
this.totalMaxChunks.set(dimensions.count * 1024);
|
||||||
|
this.latch = new CountDownLatch(totalMaxChunks.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return world.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChunks() {
|
||||||
|
return totalMaxChunks.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
unloadAndSaveAllChunks();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean pause() {
|
||||||
|
unloadAndSaveAllChunks();
|
||||||
|
if (paused.get()) {
|
||||||
|
paused.set(false);
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
paused.set(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
unloadAndSaveAllChunks();
|
||||||
|
cancelled.set(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
Iris.info("Updating..");
|
||||||
|
try {
|
||||||
|
startTime.set(System.currentTimeMillis());
|
||||||
|
scheduler.scheduleAtFixedRate(() -> {
|
||||||
|
try {
|
||||||
|
if (!paused.get()) {
|
||||||
|
long eta = computeETA();
|
||||||
|
int processed = chunksProcessed.get();
|
||||||
|
double last = processed - chunksProcessedLast.getAndSet(processed);
|
||||||
|
double cps = last / ((M.ms() - lastCpsTime.getAndSet(M.ms())) / 1000d);
|
||||||
|
chunksPerSecond.put(cps);
|
||||||
|
double percentage = ((double) processed / (double) totalMaxChunks.get()) * 100;
|
||||||
|
if (!cancelled.get()) {
|
||||||
|
Iris.info("Updated: " + Form.f(processed) + " of " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta,
|
||||||
|
2), percentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}, 0, 3, TimeUnit.SECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(this::unloadChunks, 0, 1, TimeUnit.SECONDS);
|
||||||
|
scheduler.scheduleAtFixedRate(() -> {
|
||||||
|
boolean empty = Bukkit.getOnlinePlayers().isEmpty();
|
||||||
|
if (serverEmpty.getAndSet(empty) == empty)
|
||||||
|
return;
|
||||||
|
loadBalancer.setRange(empty ? IrisSettings.get().getUpdater().emptyMsRange : IrisSettings.get().getUpdater().defaultMsRange);
|
||||||
|
}, 0, 10, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
var t = new Thread(() -> {
|
||||||
|
run();
|
||||||
|
close();
|
||||||
|
}, "Iris Chunk Updater - " + world.getName());
|
||||||
|
t.setPriority(Thread.MAX_PRIORITY);
|
||||||
|
t.start();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
loadBalancer.close();
|
||||||
|
semaphore.acquire(256);
|
||||||
|
|
||||||
|
executor.shutdown();
|
||||||
|
executor.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
|
chunkExecutor.shutdown();
|
||||||
|
chunkExecutor.awaitTermination(5, TimeUnit.SECONDS);
|
||||||
|
scheduler.shutdownNow();
|
||||||
|
unloadAndSaveAllChunks();
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
if (cancelled.get()) {
|
||||||
|
Iris.info("Updated: " + Form.f(chunksUpdated.get()) + " Chunks");
|
||||||
|
Iris.info("Irritated: " + Form.f(chunksProcessed.get()) + " of " + Form.f(totalMaxChunks.get()));
|
||||||
|
Iris.info("Stopped updater.");
|
||||||
|
} else {
|
||||||
|
Iris.info("Processed: " + Form.f(chunksProcessed.get()) + " Chunks");
|
||||||
|
Iris.info("Finished Updating: " + Form.f(chunksUpdated.get()) + " Chunks");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void run() {
|
||||||
|
task.iterateRegions((rX, rZ) -> {
|
||||||
|
if (cancelled.get())
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (paused.get()) {
|
||||||
|
J.sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rX < dimensions.min.getX() || rX > dimensions.max.getX() || rZ < dimensions.min.getZ() || rZ > dimensions.max.getZ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PregenTask.iterateRegion(rX, rZ, (x, z) -> {
|
||||||
|
while (paused.get() && !cancelled.get()) {
|
||||||
|
J.sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
semaphore.acquire();
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunkExecutor.submit(() -> {
|
||||||
|
try {
|
||||||
|
if (!cancelled.get())
|
||||||
|
processChunk(x, z);
|
||||||
|
} finally {
|
||||||
|
latch.countDown();
|
||||||
|
semaphore.release();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processChunk(int x, int z) {
|
||||||
|
if (!loadChunksIfGenerated(x, z)) {
|
||||||
|
chunksProcessed.getAndIncrement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Chunk c = world.getChunkAt(x, z);
|
||||||
|
engine.getMantle().getMantle().getChunk(c);
|
||||||
|
engine.updateChunk(c);
|
||||||
|
|
||||||
|
for (int xx = -1; xx <= 1; xx++) {
|
||||||
|
for (int zz = -1; zz <= 1; zz++) {
|
||||||
|
var counter = lastUse.get(Cache.key(x + xx, z + zz));
|
||||||
|
if (counter != null) counter.getB().decrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
chunksUpdated.incrementAndGet();
|
||||||
|
chunksProcessed.getAndIncrement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadChunksIfGenerated(int x, int z) {
|
||||||
|
if (engine.getMantle().getMantle().hasFlag(x, z, MantleFlag.ETCHED))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
|
if (!PaperLib.isChunkGenerated(world, x + dx, z + dz)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AtomicBoolean generated = new AtomicBoolean(true);
|
||||||
|
CountDownLatch latch = new CountDownLatch(9);
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
|
int xx = x + dx;
|
||||||
|
int zz = z + dz;
|
||||||
|
executor.submit(() -> {
|
||||||
|
try {
|
||||||
|
Chunk c;
|
||||||
|
try {
|
||||||
|
c = PaperLib.getChunkAtAsync(world, xx, zz, false, true)
|
||||||
|
.thenApply(chunk -> {
|
||||||
|
chunk.addPluginChunkTicket(Iris.instance);
|
||||||
|
return chunk;
|
||||||
|
}).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
generated.set(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c.isLoaded()) {
|
||||||
|
var future = J.sfut(() -> c.load(false));
|
||||||
|
if (future != null) future.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c.isGenerated())
|
||||||
|
generated.set(false);
|
||||||
|
|
||||||
|
var pair = lastUse.computeIfAbsent(Cache.key(c), k -> new Pair<>(0L, new AtomicInteger(-1)));
|
||||||
|
pair.setA(M.ms());
|
||||||
|
pair.getB().updateAndGet(i -> i == -1 ? 1 : ++i);
|
||||||
|
} finally {
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Iris.info("Interrupted while waiting for chunks to load");
|
||||||
|
}
|
||||||
|
return generated.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void unloadChunks() {
|
||||||
|
for (var key : new ArrayList<>(lastUse.keySet())) {
|
||||||
|
if (key == null) continue;
|
||||||
|
var pair = lastUse.get(key);
|
||||||
|
if (pair == null) continue;
|
||||||
|
var lastUseTime = pair.getA();
|
||||||
|
var counter = pair.getB();
|
||||||
|
if (lastUseTime == null || counter == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (M.ms() - lastUseTime >= 5000 && counter.get() == 0) {
|
||||||
|
int x = Cache.keyX(key);
|
||||||
|
int z = Cache.keyZ(key);
|
||||||
|
J.s(() -> {
|
||||||
|
world.removePluginChunkTicket(x, z, Iris.instance);
|
||||||
|
world.unloadChunk(x, z);
|
||||||
|
lastUse.remove(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unloadAndSaveAllChunks() {
|
||||||
|
try {
|
||||||
|
J.sfut(() -> {
|
||||||
|
if (world == null) {
|
||||||
|
Iris.warn("World was null somehow...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unloadChunks();
|
||||||
|
world.save();
|
||||||
|
}).get();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long computeETA() {
|
||||||
|
return (long) (totalMaxChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total?
|
||||||
|
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers)
|
||||||
|
((totalMaxChunks.get() - chunksProcessed.get()) * ((double) (M.ms() - startTime.get()) / (double) chunksProcessed.get())) :
|
||||||
|
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
|
||||||
|
((totalMaxChunks.get() - chunksProcessed.get()) / chunksPerSecond.getAverage()) * 1000
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dimensions calculateWorldDimensions(File regionDir) {
|
||||||
|
File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca"));
|
||||||
|
|
||||||
|
int minX = Integer.MAX_VALUE;
|
||||||
|
int maxX = Integer.MIN_VALUE;
|
||||||
|
int minZ = Integer.MAX_VALUE;
|
||||||
|
int maxZ = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (File file : files) {
|
||||||
|
String[] parts = file.getName().split("\\.");
|
||||||
|
int x = Integer.parseInt(parts[1]);
|
||||||
|
int z = Integer.parseInt(parts[2]);
|
||||||
|
|
||||||
|
minX = Math.min(minX, x);
|
||||||
|
maxX = Math.max(maxX, x);
|
||||||
|
minZ = Math.min(minZ, z);
|
||||||
|
maxZ = Math.max(maxZ, z);
|
||||||
|
}
|
||||||
|
int oX = minX + ((maxX - minX) / 2);
|
||||||
|
int oZ = minZ + ((maxZ - minZ) / 2);
|
||||||
|
|
||||||
|
int height = maxX - minX + 1;
|
||||||
|
int width = maxZ - minZ + 1;
|
||||||
|
|
||||||
|
return new Dimensions(new Position2(minX, minZ), new Position2(maxX, maxZ), height * width, PregenTask.builder()
|
||||||
|
.width((int) Math.ceil(width / 2d))
|
||||||
|
.height((int) Math.ceil(height / 2d))
|
||||||
|
.center(new Position2(oX, oZ))
|
||||||
|
.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Dimensions(Position2 min, Position2 max, int count, PregenTask task) { }
|
||||||
|
}
|
||||||
@@ -19,7 +19,11 @@
|
|||||||
package com.volmit.iris.core.pregenerator;
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.pack.IrisPack;
|
||||||
|
import com.volmit.iris.core.tools.IrisPackBenchmarking;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KSet;
|
import com.volmit.iris.util.collection.KSet;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
@@ -34,6 +38,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
|
||||||
public class IrisPregenerator {
|
public class IrisPregenerator {
|
||||||
private final PregenTask task;
|
private final PregenTask task;
|
||||||
private final PregeneratorMethod generator;
|
private final PregeneratorMethod generator;
|
||||||
@@ -44,10 +49,11 @@ public class IrisPregenerator {
|
|||||||
private final RollingSequence chunksPerSecond;
|
private final RollingSequence chunksPerSecond;
|
||||||
private final RollingSequence chunksPerMinute;
|
private final RollingSequence chunksPerMinute;
|
||||||
private final RollingSequence regionsPerMinute;
|
private final RollingSequence regionsPerMinute;
|
||||||
private final AtomicInteger generated;
|
private final KList<Integer> chunksPerSecondHistory;
|
||||||
|
private static AtomicInteger generated;
|
||||||
private final AtomicInteger generatedLast;
|
private final AtomicInteger generatedLast;
|
||||||
private final AtomicInteger generatedLastMinute;
|
private final AtomicInteger generatedLastMinute;
|
||||||
private final AtomicInteger totalChunks;
|
private static AtomicInteger totalChunks;
|
||||||
private final AtomicLong startTime;
|
private final AtomicLong startTime;
|
||||||
private final ChronoLatch minuteLatch;
|
private final ChronoLatch minuteLatch;
|
||||||
private final AtomicReference<String> currentGeneratorMethod;
|
private final AtomicReference<String> currentGeneratorMethod;
|
||||||
@@ -72,6 +78,7 @@ public class IrisPregenerator {
|
|||||||
chunksPerSecond = new RollingSequence(10);
|
chunksPerSecond = new RollingSequence(10);
|
||||||
chunksPerMinute = new RollingSequence(10);
|
chunksPerMinute = new RollingSequence(10);
|
||||||
regionsPerMinute = new RollingSequence(10);
|
regionsPerMinute = new RollingSequence(10);
|
||||||
|
chunksPerSecondHistory = new KList<>();
|
||||||
generated = new AtomicInteger(0);
|
generated = new AtomicInteger(0);
|
||||||
generatedLast = new AtomicInteger(0);
|
generatedLast = new AtomicInteger(0);
|
||||||
generatedLastMinute = new AtomicInteger(0);
|
generatedLastMinute = new AtomicInteger(0);
|
||||||
@@ -85,6 +92,7 @@ public class IrisPregenerator {
|
|||||||
int secondGenerated = generated.get() - generatedLast.get();
|
int secondGenerated = generated.get() - generatedLast.get();
|
||||||
generatedLast.set(generated.get());
|
generatedLast.set(generated.get());
|
||||||
chunksPerSecond.put(secondGenerated);
|
chunksPerSecond.put(secondGenerated);
|
||||||
|
chunksPerSecondHistory.add(secondGenerated);
|
||||||
|
|
||||||
if (minuteLatch.flip()) {
|
if (minuteLatch.flip()) {
|
||||||
int minuteGenerated = generated.get() - generatedLastMinute.get();
|
int minuteGenerated = generated.get() - generatedLastMinute.get();
|
||||||
@@ -102,19 +110,27 @@ public class IrisPregenerator {
|
|||||||
|
|
||||||
if (cl.flip()) {
|
if (cl.flip()) {
|
||||||
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
|
||||||
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage);
|
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||||
|
Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
||||||
|
} else {
|
||||||
|
Iris.info("Benchmarking: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1000;
|
return 1000;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private long computeETA() {
|
private long computeETA() {
|
||||||
return (long) ((totalChunks.get() - generated.get()) *
|
return (long) (totalChunks.get() > 1024 ? // Generated chunks exceed 1/8th of total?
|
||||||
((double) (M.ms() - startTime.get()) / (double) generated.get()));
|
// If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers)
|
||||||
|
((totalChunks.get() - generated.get()) * ((double) (M.ms() - startTime.get()) / (double) generated.get())) :
|
||||||
|
// If no, use quick function (which is less accurate over time but responds better to the initial delay)
|
||||||
|
((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void close() {
|
public void close() {
|
||||||
shutdown.set(true);
|
shutdown.set(true);
|
||||||
}
|
}
|
||||||
@@ -126,6 +142,11 @@ public class IrisPregenerator {
|
|||||||
task.iterateRegions((x, z) -> visitRegion(x, z, true));
|
task.iterateRegions((x, z) -> visitRegion(x, z, true));
|
||||||
task.iterateRegions((x, z) -> visitRegion(x, z, false));
|
task.iterateRegions((x, z) -> visitRegion(x, z, false));
|
||||||
shutdown();
|
shutdown();
|
||||||
|
if (!IrisPackBenchmarking.benchmarkInProgress) {
|
||||||
|
Iris.info(C.IRIS + "Pregen stopped.");
|
||||||
|
} else {
|
||||||
|
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkRegions() {
|
private void checkRegions() {
|
||||||
@@ -142,7 +163,10 @@ public class IrisPregenerator {
|
|||||||
generator.close();
|
generator.close();
|
||||||
ticker.interrupt();
|
ticker.interrupt();
|
||||||
listener.onClose();
|
listener.onClose();
|
||||||
getMantle().trim(0);
|
Mantle mantle = getMantle();
|
||||||
|
if (mantle != null) {
|
||||||
|
mantle.trim(0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void visitRegion(int x, int z, boolean regions) {
|
private void visitRegion(int x, int z, boolean regions) {
|
||||||
@@ -0,0 +1,286 @@
|
|||||||
|
package com.volmit.iris.core.pregenerator;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.io.IO;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
|
import com.volmit.iris.util.math.Position2;
|
||||||
|
import com.volmit.iris.util.math.RollingSequence;
|
||||||
|
import com.volmit.iris.util.math.Spiraler;
|
||||||
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import io.papermc.lib.PaperLib;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LazyPregenerator extends Thread implements Listener {
|
||||||
|
@Getter
|
||||||
|
private static LazyPregenerator instance;
|
||||||
|
private final LazyPregenJob job;
|
||||||
|
private final File destination;
|
||||||
|
private final int maxPosition;
|
||||||
|
private World world;
|
||||||
|
private final long rate;
|
||||||
|
private final ChronoLatch latch;
|
||||||
|
private static AtomicInteger lazyGeneratedChunks;
|
||||||
|
private final AtomicInteger generatedLast;
|
||||||
|
private final AtomicInteger lazyTotalChunks;
|
||||||
|
private final AtomicLong startTime;
|
||||||
|
private final RollingSequence chunksPerSecond;
|
||||||
|
private final RollingSequence chunksPerMinute;
|
||||||
|
|
||||||
|
private static final Map<String, LazyPregenJob> jobs = new HashMap<>();
|
||||||
|
|
||||||
|
public LazyPregenerator(LazyPregenJob job, File destination) {
|
||||||
|
this.job = job;
|
||||||
|
this.destination = destination;
|
||||||
|
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||||
|
}).count();
|
||||||
|
this.world = Bukkit.getWorld(job.getWorld());
|
||||||
|
this.rate = Math.round((1D / (job.getChunksPerMinute() / 60D)) * 1000D);
|
||||||
|
this.latch = new ChronoLatch(15000);
|
||||||
|
this.startTime = new AtomicLong(M.ms());
|
||||||
|
this.chunksPerSecond = new RollingSequence(10);
|
||||||
|
this.chunksPerMinute = new RollingSequence(10);
|
||||||
|
lazyGeneratedChunks = new AtomicInteger(0);
|
||||||
|
this.generatedLast = new AtomicInteger(0);
|
||||||
|
this.lazyTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
|
||||||
|
jobs.put(job.getWorld(), job);
|
||||||
|
LazyPregenerator.instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LazyPregenerator(File file) throws IOException {
|
||||||
|
this(new Gson().fromJson(IO.readAll(file), LazyPregenJob.class), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void loadLazyGenerators() {
|
||||||
|
for (World i : Bukkit.getWorlds()) {
|
||||||
|
File lazygen = new File(i.getWorldFolder(), "lazygen.json");
|
||||||
|
if (lazygen.exists()) {
|
||||||
|
try {
|
||||||
|
LazyPregenerator p = new LazyPregenerator(lazygen);
|
||||||
|
p.start();
|
||||||
|
Iris.info("Started Lazy Pregenerator: " + p.job);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void on(WorldUnloadEvent e) {
|
||||||
|
if (e.getWorld().equals(world)) {
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
while (!interrupted()) {
|
||||||
|
J.sleep(rate);
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
saveNow();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
if (latch.flip() && !job.paused) {
|
||||||
|
long eta = computeETA();
|
||||||
|
save();
|
||||||
|
int secondGenerated = lazyGeneratedChunks.get() - generatedLast.get();
|
||||||
|
generatedLast.set(lazyGeneratedChunks.get());
|
||||||
|
secondGenerated = secondGenerated / 15;
|
||||||
|
chunksPerSecond.put(secondGenerated);
|
||||||
|
chunksPerMinute.put(secondGenerated * 60);
|
||||||
|
if (!job.isSilent()) {
|
||||||
|
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(lazyGeneratedChunks.get()) + " of " + Form.f(lazyTotalChunks.get()) + " " + Form.f((int) chunksPerMinute.getAverage()) + "/m ETA: " + Form.duration((double) eta, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lazyGeneratedChunks.get() >= lazyTotalChunks.get()) {
|
||||||
|
if (job.isHealing()) {
|
||||||
|
int pos = (job.getHealingPosition() + 1) % maxPosition;
|
||||||
|
job.setHealingPosition(pos);
|
||||||
|
tickRegenerate(getChunk(pos));
|
||||||
|
} else {
|
||||||
|
Iris.info("Completed Lazy Gen!");
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int pos = job.getPosition() + 1;
|
||||||
|
job.setPosition(pos);
|
||||||
|
if (!job.paused) {
|
||||||
|
tickGenerate(getChunk(pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long computeETA() {
|
||||||
|
return (long) ((lazyTotalChunks.get() - lazyGeneratedChunks.get()) / chunksPerMinute.getAverage()) * 1000;
|
||||||
|
// todo broken
|
||||||
|
}
|
||||||
|
|
||||||
|
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
|
private void tickGenerate(Position2 chunk) {
|
||||||
|
executorService.submit(() -> {
|
||||||
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
|
if (PaperLib.isPaper()) {
|
||||||
|
PaperLib.getChunkAtAsync(world, chunk.getX(), chunk.getZ(), true)
|
||||||
|
.thenAccept((i) -> {
|
||||||
|
Iris.verbose("Generated Async " + chunk);
|
||||||
|
latch.countDown();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
J.s(() -> {
|
||||||
|
world.getChunkAt(chunk.getX(), chunk.getZ());
|
||||||
|
Iris.verbose("Generated " + chunk);
|
||||||
|
latch.countDown();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
lazyGeneratedChunks.addAndGet(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tickRegenerate(Position2 chunk) {
|
||||||
|
J.s(() -> world.regenerateChunk(chunk.getX(), chunk.getZ()));
|
||||||
|
Iris.verbose("Regenerated " + chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position2 getChunk(int position) {
|
||||||
|
int p = -1;
|
||||||
|
AtomicInteger xx = new AtomicInteger();
|
||||||
|
AtomicInteger zz = new AtomicInteger();
|
||||||
|
Spiraler s = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
|
||||||
|
xx.set(x);
|
||||||
|
zz.set(z);
|
||||||
|
});
|
||||||
|
|
||||||
|
while (s.hasNext() && p++ < position) {
|
||||||
|
s.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Position2(xx.get(), zz.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
J.a(() -> {
|
||||||
|
try {
|
||||||
|
saveNow();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setPausedLazy(World world) {
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
if (isPausedLazy(world)){
|
||||||
|
job.paused = false;
|
||||||
|
} else {
|
||||||
|
job.paused = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( job.paused) {
|
||||||
|
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Paused");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.BLUE + "LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Resumed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isPausedLazy(World world) {
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
return job != null && job.isPaused();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdownInstance(World world) throws IOException {
|
||||||
|
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " Shutting down..");
|
||||||
|
LazyPregenJob job = jobs.get(world.getName());
|
||||||
|
File worldDirectory = new File(Bukkit.getWorldContainer(), world.getName());
|
||||||
|
File lazyFile = new File(worldDirectory, "lazygen.json");
|
||||||
|
|
||||||
|
if (job == null) {
|
||||||
|
Iris.error("No Lazygen job found for world: " + world.getName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!job.isPaused()) {
|
||||||
|
job.setPaused(true);
|
||||||
|
}
|
||||||
|
save();
|
||||||
|
jobs.remove(world.getName());
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (lazyFile.exists()){
|
||||||
|
lazyFile.delete();
|
||||||
|
J.sleep(1000);
|
||||||
|
}
|
||||||
|
Iris.info("LazyGen: " + C.IRIS + world.getName() + C.BLUE + " File deleted and instance closed.");
|
||||||
|
}
|
||||||
|
}.runTaskLater(Iris.instance, 20L);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("Failed to shutdown Lazygen for " + world.getName());
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
saveNow();
|
||||||
|
interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void saveNow() throws IOException {
|
||||||
|
IO.writeAll(this.destination, new Gson().toJson(job));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
public static class LazyPregenJob {
|
||||||
|
private String world;
|
||||||
|
@Builder.Default
|
||||||
|
private int healingPosition = 0;
|
||||||
|
@Builder.Default
|
||||||
|
private boolean healing = false;
|
||||||
|
@Builder.Default
|
||||||
|
private int chunksPerMinute = 32;
|
||||||
|
@Builder.Default
|
||||||
|
private int radiusBlocks = 5000;
|
||||||
|
@Builder.Default
|
||||||
|
private int position = 0;
|
||||||
|
@Builder.Default
|
||||||
|
boolean silent = false;
|
||||||
|
@Builder.Default
|
||||||
|
boolean paused = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -35,6 +35,8 @@ public class PregenTask {
|
|||||||
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
|
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
|
||||||
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
|
||||||
|
|
||||||
|
@Builder.Default
|
||||||
|
private boolean gui = false;
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Position2 center = new Position2(0, 0);
|
private Position2 center = new Position2(0, 0);
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
@@ -23,20 +23,24 @@ import com.volmit.iris.core.pregenerator.PregenListener;
|
|||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.parallel.MultiBurst;
|
import com.volmit.iris.util.parallel.MultiBurst;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
public class AsyncPregenMethod implements PregeneratorMethod {
|
public class AsyncPregenMethod implements PregeneratorMethod {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final MultiBurst burst;
|
private final MultiBurst burst;
|
||||||
private final KList<Future<?>> future;
|
private final KList<Future<?>> future;
|
||||||
|
private final Map<Chunk, Long> lastUse;
|
||||||
|
|
||||||
public AsyncPregenMethod(World world, int threads) {
|
public AsyncPregenMethod(World world, int threads) {
|
||||||
if (!PaperLib.isPaper()) {
|
if (!PaperLib.isPaper()) {
|
||||||
@@ -44,8 +48,9 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
burst = MultiBurst.burst;
|
burst = new MultiBurst("Iris Async Pregen", Thread.MIN_PRIORITY);
|
||||||
future = new KList<>(1024);
|
future = new KList<>(256);
|
||||||
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unloadAndSaveAllChunks() {
|
private void unloadAndSaveAllChunks() {
|
||||||
@@ -56,8 +61,12 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Chunk i : world.getLoadedChunks()) {
|
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||||
i.unload(true);
|
Long lastUseTime = lastUse.get(i);
|
||||||
|
if (lastUseTime != null && M.ms() - lastUseTime >= 10000) {
|
||||||
|
i.unload();
|
||||||
|
lastUse.remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
@@ -68,23 +77,18 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
|
|
||||||
private void completeChunk(int x, int z, PregenListener listener) {
|
private void completeChunk(int x, int z, PregenListener listener) {
|
||||||
try {
|
try {
|
||||||
future.add(PaperLib.getChunkAtAsync(world, x, z, true).thenApply((i) -> {
|
PaperLib.getChunkAtAsync(world, x, z, true).thenAccept((i) -> {
|
||||||
if (i == null) {
|
lastUse.put(i, M.ms());
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
return 0;
|
}).get();
|
||||||
}));
|
} catch (InterruptedException ignored) {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForChunksPartial(int maxWaiting) {
|
private void waitForChunksPartial(int maxWaiting) {
|
||||||
future.removeWhere(Objects::isNull);
|
|
||||||
|
|
||||||
while (future.size() > maxWaiting) {
|
while (future.size() > maxWaiting) {
|
||||||
try {
|
try {
|
||||||
Future<?> i = future.remove(0);
|
Future<?> i = future.remove(0);
|
||||||
@@ -113,8 +117,6 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
future.removeWhere(Objects::isNull);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,6 +133,7 @@ public class AsyncPregenMethod implements PregeneratorMethod {
|
|||||||
public void close() {
|
public void close() {
|
||||||
waitForChunks();
|
waitForChunks();
|
||||||
unloadAndSaveAllChunks();
|
unloadAndSaveAllChunks();
|
||||||
|
burst.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -18,25 +18,33 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.pregenerator.methods;
|
package com.volmit.iris.core.pregenerator.methods;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.IrisSettings;
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.pregenerator.PregenListener;
|
import com.volmit.iris.core.pregenerator.PregenListener;
|
||||||
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
import com.volmit.iris.core.pregenerator.PregeneratorMethod;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.mantle.Mantle;
|
import com.volmit.iris.util.mantle.Mantle;
|
||||||
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class MedievalPregenMethod implements PregeneratorMethod {
|
public class MedievalPregenMethod implements PregeneratorMethod {
|
||||||
private final World world;
|
private final World world;
|
||||||
private final KList<CompletableFuture<?>> futures;
|
private final KList<CompletableFuture<?>> futures;
|
||||||
|
private final Map<Chunk, Long> lastUse;
|
||||||
|
|
||||||
public MedievalPregenMethod(World world) {
|
public MedievalPregenMethod(World world) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
futures = new KList<>();
|
futures = new KList<>();
|
||||||
|
this.lastUse = new KMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForChunks() {
|
private void waitForChunks() {
|
||||||
@@ -52,11 +60,19 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void unloadAndSaveAllChunks() {
|
private void unloadAndSaveAllChunks() {
|
||||||
waitForChunks();
|
|
||||||
try {
|
try {
|
||||||
J.sfut(() -> {
|
J.sfut(() -> {
|
||||||
for (Chunk i : world.getLoadedChunks()) {
|
if (world == null) {
|
||||||
i.unload(true);
|
Iris.warn("World was null somehow...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Chunk i : new ArrayList<>(lastUse.keySet())) {
|
||||||
|
Long lastUseTime = lastUse.get(i);
|
||||||
|
if (lastUseTime != null && M.ms() - lastUseTime >= 10) {
|
||||||
|
i.unload();
|
||||||
|
lastUse.remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
world.save();
|
world.save();
|
||||||
}).get();
|
}).get();
|
||||||
@@ -104,6 +120,8 @@ public class MedievalPregenMethod implements PregeneratorMethod {
|
|||||||
listener.onChunkGenerating(x, z);
|
listener.onChunkGenerating(x, z);
|
||||||
futures.add(J.sfut(() -> {
|
futures.add(J.sfut(() -> {
|
||||||
world.getChunkAt(x, z);
|
world.getChunkAt(x, z);
|
||||||
|
Chunk c = Bukkit.getWorld(world.getUID()).getChunkAt(x, z);
|
||||||
|
lastUse.put(c, M.ms());
|
||||||
listener.onChunkGenerated(x, z);
|
listener.onChunkGenerated(x, z);
|
||||||
listener.onChunkCleaned(x, z);
|
listener.onChunkCleaned(x, z);
|
||||||
}));
|
}));
|
||||||
@@ -22,6 +22,7 @@ import com.volmit.iris.Iris;
|
|||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.loader.IrisRegistrant;
|
import com.volmit.iris.core.loader.IrisRegistrant;
|
||||||
import com.volmit.iris.core.loader.ResourceLoader;
|
import com.volmit.iris.core.loader.ResourceLoader;
|
||||||
|
import com.volmit.iris.engine.framework.ListFunction;
|
||||||
import com.volmit.iris.engine.object.annotations.*;
|
import com.volmit.iris.engine.object.annotations.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
@@ -309,6 +310,24 @@ public class SchemaBuilder {
|
|||||||
fancyType = "Enchantment Type";
|
fancyType = "Enchantment Type";
|
||||||
prop.put("$ref", "#/definitions/" + key);
|
prop.put("$ref", "#/definitions/" + key);
|
||||||
description.add(SYMBOL_TYPE__N + " Must be a valid Enchantment Type (use ctrl+space for auto complete!)");
|
description.add(SYMBOL_TYPE__N + " Must be a valid Enchantment Type (use ctrl+space for auto complete!)");
|
||||||
|
} else if (k.isAnnotationPresent(RegistryListFunction.class)) {
|
||||||
|
var functionClass = k.getDeclaredAnnotation(RegistryListFunction.class).value();
|
||||||
|
try {
|
||||||
|
var instance = functionClass.getDeclaredConstructor().newInstance();
|
||||||
|
String key = instance.key();
|
||||||
|
fancyType = instance.fancyName();
|
||||||
|
|
||||||
|
if (!definitions.containsKey(key)) {
|
||||||
|
JSONObject j = new JSONObject();
|
||||||
|
j.put("enum", instance.apply(data));
|
||||||
|
definitions.put(key, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
prop.put("$ref", "#/definitions/" + key);
|
||||||
|
description.add(SYMBOL_TYPE__N + " Must be a valid " + fancyType + " (use ctrl+space for auto complete!)");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.error("Could not execute apply method in " + functionClass.getName());
|
||||||
|
}
|
||||||
} else if (k.getType().equals(PotionEffectType.class)) {
|
} else if (k.getType().equals(PotionEffectType.class)) {
|
||||||
String key = "enum-potion-effect-type";
|
String key = "enum-potion-effect-type";
|
||||||
|
|
||||||
@@ -378,6 +397,10 @@ public class SchemaBuilder {
|
|||||||
description.add(SYMBOL_LIMIT__N + " Requires at least " + t.min() + " entries.");
|
description.add(SYMBOL_LIMIT__N + " Requires at least " + t.min() + " entries.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (t.max() > 0) {
|
||||||
|
prop.put("maxItems", t.max());
|
||||||
|
description.add(SYMBOL_LIMIT__N + " Maximum allowed entries are " + t.max() + ".");
|
||||||
|
}
|
||||||
|
|
||||||
String arrayType = getType(t.type());
|
String arrayType = getType(t.type());
|
||||||
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
|
||||||
|
public class IrisSafeguard {
|
||||||
|
public static boolean unstablemode = false;
|
||||||
|
public static boolean warningmode = false;
|
||||||
|
public static boolean stablemode = false;
|
||||||
|
|
||||||
|
public static void IrisSafeguardSystem() {
|
||||||
|
Iris.info("Enabled Iris SafeGuard");
|
||||||
|
ServerBootSFG.BootCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
|
||||||
|
public class ModesSFG {
|
||||||
|
public static void selectMode() {
|
||||||
|
if (IrisSafeguard.unstablemode) {
|
||||||
|
Iris.safeguard(C.DARK_RED + "Iris is running in Unstable Mode");
|
||||||
|
unstable();
|
||||||
|
}
|
||||||
|
if (IrisSafeguard.warningmode) {
|
||||||
|
Iris.safeguard(C.GOLD + "Iris is running in Warning Mode");
|
||||||
|
warning();
|
||||||
|
}
|
||||||
|
if (IrisSafeguard.stablemode) {
|
||||||
|
stable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stable() {
|
||||||
|
Iris.safeguard(C.BLUE + "Iris is running Stable");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void unstable() {
|
||||||
|
|
||||||
|
UtilsSFG.printIncompatibleWarnings();
|
||||||
|
|
||||||
|
if (IrisSafeguard.unstablemode) {
|
||||||
|
Iris.info("");
|
||||||
|
Iris.info(C.DARK_GRAY + "--==<" + C.RED + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||||
|
Iris.info(C.RED + "Iris is running in unstable mode which may cause the following issues:");
|
||||||
|
Iris.info(C.DARK_RED + "Server Issues");
|
||||||
|
Iris.info(C.RED + "- Server won't boot");
|
||||||
|
Iris.info(C.RED + "- Data Loss");
|
||||||
|
Iris.info(C.RED + "- Unexpected behavior.");
|
||||||
|
Iris.info(C.RED + "- And More...");
|
||||||
|
Iris.info(C.DARK_RED + "World Issues");
|
||||||
|
Iris.info(C.RED + "- Worlds can't load due to corruption.");
|
||||||
|
Iris.info(C.RED + "- Worlds may slowly corrupt until they can't load.");
|
||||||
|
Iris.info(C.RED + "- World data loss.");
|
||||||
|
Iris.info(C.RED + "- And More...");
|
||||||
|
Iris.info(C.DARK_RED + "ATTENTION: " + C.RED + "While running Iris in unstable mode, you won't be eligible for support.");
|
||||||
|
Iris.info(C.DARK_RED + "CAUSE: " + C.RED + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
|
||||||
|
if (IrisSettings.get().getGeneral().DoomsdayAnnihilationSelfDestructMode) {
|
||||||
|
Iris.info(C.DARK_RED + "Boot Unstable is set to true, continuing with the startup process.");
|
||||||
|
} else {
|
||||||
|
Iris.info(C.DARK_RED + "Go to plugins/iris/settings.json and set DoomsdayAnnihilationSelfDestructMode to true if you wish to proceed.");
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(Long.MAX_VALUE);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// no
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Iris.info("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void warning() {
|
||||||
|
|
||||||
|
UtilsSFG.printIncompatibleWarnings();
|
||||||
|
|
||||||
|
if (IrisSafeguard.warningmode) {
|
||||||
|
Iris.info("");
|
||||||
|
Iris.info(C.DARK_GRAY + "--==<" + C.GOLD + " IMPORTANT " + C.DARK_GRAY + ">==--");
|
||||||
|
Iris.info(C.GOLD + "Iris is running in warning mode which may cause the following issues:");
|
||||||
|
Iris.info(C.YELLOW + "- Data Loss");
|
||||||
|
Iris.info(C.YELLOW + "- Errors");
|
||||||
|
Iris.info(C.YELLOW + "- Broken worlds");
|
||||||
|
Iris.info(C.YELLOW + "- Unexpected behavior.");
|
||||||
|
Iris.info(C.YELLOW + "- And perhaps further complications.");
|
||||||
|
Iris.info(C.GOLD + "CAUSE: " + C.YELLOW + UtilsSFG.MSGIncompatibleWarnings());
|
||||||
|
Iris.info("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
public class PerformanceSFG {
|
||||||
|
public static void calculatePerformance() {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,169 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.StandardOpenOption;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.StringJoiner;
|
||||||
|
|
||||||
|
import static com.volmit.iris.Iris.getJavaVersion;
|
||||||
|
import static com.volmit.iris.Iris.instance;
|
||||||
|
import static com.volmit.iris.core.safeguard.IrisSafeguard.*;
|
||||||
|
|
||||||
|
public class ServerBootSFG {
|
||||||
|
public static final Map<String, Boolean> incompatibilities = new HashMap<>();
|
||||||
|
public static boolean isJDK17 = true;
|
||||||
|
public static boolean hasEnoughDiskSpace = true;
|
||||||
|
public static boolean isJRE = false;
|
||||||
|
public static boolean hasPrivileges = true;
|
||||||
|
public static boolean unsuportedversion = false;
|
||||||
|
protected static boolean safeguardPassed;
|
||||||
|
public static boolean passedserversoftware = true;
|
||||||
|
protected static int count;
|
||||||
|
protected static byte severityLow;
|
||||||
|
protected static byte severityMedium;
|
||||||
|
protected static byte severityHigh;
|
||||||
|
public static String allIncompatibilities;
|
||||||
|
|
||||||
|
public static void BootCheck() {
|
||||||
|
Iris.info("Checking for possible conflicts..");
|
||||||
|
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||||
|
Plugin[] plugins = pluginManager.getPlugins();
|
||||||
|
|
||||||
|
incompatibilities.clear();
|
||||||
|
incompatibilities.put("Multiverse-Core", false);
|
||||||
|
incompatibilities.put("dynmap", false);
|
||||||
|
incompatibilities.put("TerraformGenerator", false);
|
||||||
|
incompatibilities.put("Stratos", false);
|
||||||
|
|
||||||
|
String pluginName;
|
||||||
|
for (Plugin plugin : plugins) {
|
||||||
|
pluginName = plugin.getName();
|
||||||
|
Boolean flag = incompatibilities.get(pluginName);
|
||||||
|
if (flag != null && !flag) {
|
||||||
|
severityHigh++;
|
||||||
|
incompatibilities.put(pluginName, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringJoiner joiner = new StringJoiner(", ");
|
||||||
|
for (Map.Entry<String, Boolean> entry : incompatibilities.entrySet()) {
|
||||||
|
if (entry.getValue()) {
|
||||||
|
joiner.add(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Legacy ServerInfo
|
||||||
|
String distro = Bukkit.getName().toLowerCase();
|
||||||
|
if (
|
||||||
|
!distro.contains("purpur") &&
|
||||||
|
!distro.contains("paper") &&
|
||||||
|
!distro.contains("spigot") &&
|
||||||
|
!distro.contains("pufferfish") &&
|
||||||
|
!distro.contains("bukkit")) {
|
||||||
|
|
||||||
|
|
||||||
|
passedserversoftware = false;
|
||||||
|
joiner.add("Server Software");
|
||||||
|
severityMedium++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (INMS.get() instanceof NMSBinding1X) {
|
||||||
|
unsuportedversion = true;
|
||||||
|
joiner.add("Unsupported Minecraft Version");
|
||||||
|
severityHigh++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!List.of(17, 21).contains(getJavaVersion())) {
|
||||||
|
isJDK17 = false;
|
||||||
|
joiner.add("Unsupported Java version");
|
||||||
|
severityMedium++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isJDK()) {
|
||||||
|
isJRE = true;
|
||||||
|
joiner.add("Unsupported JDK");
|
||||||
|
severityMedium++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (!hasPrivileges()){
|
||||||
|
// hasPrivileges = false;
|
||||||
|
// joiner.add("Insufficient Privileges");
|
||||||
|
// severityMedium++;
|
||||||
|
// } Some servers dont like this
|
||||||
|
|
||||||
|
if (!enoughDiskSpace()){
|
||||||
|
hasEnoughDiskSpace = false;
|
||||||
|
joiner.add("Insufficient Disk Space");
|
||||||
|
severityMedium++;
|
||||||
|
}
|
||||||
|
|
||||||
|
allIncompatibilities = joiner.toString();
|
||||||
|
|
||||||
|
safeguardPassed = (severityHigh == 0 && severityMedium == 0 && severityLow == 0);
|
||||||
|
count = severityHigh + severityMedium + severityLow;
|
||||||
|
if (safeguardPassed) {
|
||||||
|
stablemode = true;
|
||||||
|
Iris.safeguard("Stable mode has been activated.");
|
||||||
|
}
|
||||||
|
if (!safeguardPassed) {
|
||||||
|
if (severityMedium >= 1 && severityHigh == 0) {
|
||||||
|
warningmode = true;
|
||||||
|
Iris.safeguard("Warning mode has been activated.");
|
||||||
|
}
|
||||||
|
if (severityHigh >= 1) {
|
||||||
|
unstablemode = true;
|
||||||
|
Iris.safeguard("Unstable mode has been activated.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static boolean isJDK() {
|
||||||
|
try {
|
||||||
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||||
|
// If the compiler is null, it means this is a JRE environment, not a JDK.
|
||||||
|
return compiler != null;
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public static boolean hasPrivileges() {
|
||||||
|
Path pv = Paths.get(Bukkit.getWorldContainer() + "iristest.json");
|
||||||
|
try (FileChannel fc = FileChannel.open(pv, StandardOpenOption.CREATE, StandardOpenOption.DELETE_ON_CLOSE, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
|
||||||
|
if (Files.isReadable(pv) && Files.isWritable(pv)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean enoughDiskSpace() {
|
||||||
|
File freeSpace = new File(Bukkit.getWorldContainer() + ".");
|
||||||
|
double gigabytes = freeSpace.getFreeSpace() / (1024.0 * 1024.0 * 1024.0);
|
||||||
|
if (gigabytes > 3){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean checkJavac(String path) {
|
||||||
|
return !path.isEmpty() && (new File(path, "javac").exists() || new File(path, "javac.exe").exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package com.volmit.iris.core.safeguard;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
|
||||||
|
public class UtilsSFG {
|
||||||
|
public static void splash() {
|
||||||
|
ModesSFG.selectMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void printIncompatibleWarnings() {
|
||||||
|
// String SupportedIrisVersion = getDescription().getVersion(); //todo Automatic version
|
||||||
|
|
||||||
|
if (ServerBootSFG.safeguardPassed) {
|
||||||
|
Iris.safeguard(C.BLUE + "0 Conflicts found");
|
||||||
|
} else {
|
||||||
|
if (IrisSafeguard.unstablemode) {
|
||||||
|
Iris.safeguard(C.DARK_RED + "" + ServerBootSFG.count + " Conflicts found");
|
||||||
|
}
|
||||||
|
if (IrisSafeguard.warningmode) {
|
||||||
|
Iris.safeguard(C.YELLOW + "" + ServerBootSFG.count + " Conflicts found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ServerBootSFG.incompatibilities.get("Multiverse-Core")) {
|
||||||
|
Iris.safeguard(C.RED + "Multiverse");
|
||||||
|
Iris.safeguard(C.RED + "- The plugin Multiverse is not compatible with the server.");
|
||||||
|
Iris.safeguard(C.RED + "- If you want to have a world manager, consider using PhantomWorlds or MyWorlds instead.");
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.incompatibilities.get("dynmap")) {
|
||||||
|
Iris.safeguard(C.RED + "Dynmap");
|
||||||
|
Iris.safeguard(C.RED + "- The plugin Dynmap is not compatible with the server.");
|
||||||
|
Iris.safeguard(C.RED + "- If you want to have a map plugin like Dynmap, consider Bluemap.");
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.incompatibilities.get("TerraformGenerator") || ServerBootSFG.incompatibilities.get("Stratos")) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Terraform Generator / Stratos");
|
||||||
|
Iris.safeguard(C.YELLOW + "- Iris is not compatible with other worldgen plugins.");
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.unsuportedversion) {
|
||||||
|
Iris.safeguard(C.RED + "Server Version");
|
||||||
|
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.21.1");
|
||||||
|
}
|
||||||
|
if (!ServerBootSFG.passedserversoftware) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
|
||||||
|
Iris.safeguard(C.YELLOW + "- Please consider using Paper or Purpur instead.");
|
||||||
|
}
|
||||||
|
if (!ServerBootSFG.hasPrivileges) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Insufficient Privileges");
|
||||||
|
Iris.safeguard(C.YELLOW + "- The server has insufficient Privileges to run iris. Please contact support.");
|
||||||
|
}
|
||||||
|
if (!ServerBootSFG.hasEnoughDiskSpace) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Insufficient Disk Space");
|
||||||
|
Iris.safeguard(C.YELLOW + "- The server has insufficient Free DiskSpace to run iris required 3GB+.");
|
||||||
|
}
|
||||||
|
if (!ServerBootSFG.isJDK17) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Unsupported java version");
|
||||||
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JDK " + Iris.getJavaVersion());
|
||||||
|
}
|
||||||
|
if (ServerBootSFG.isJRE) {
|
||||||
|
Iris.safeguard(C.YELLOW + "Unsupported Server JDK");
|
||||||
|
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JRE " + Iris.getJavaVersion());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String MSGIncompatibleWarnings() {
|
||||||
|
return ServerBootSFG.allIncompatibilities;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@
|
|||||||
package com.volmit.iris.core.service;
|
package com.volmit.iris.core.service;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
import com.volmit.iris.core.loader.IrisData;
|
import com.volmit.iris.core.loader.IrisData;
|
||||||
import com.volmit.iris.core.tools.IrisToolbelt;
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
import com.volmit.iris.engine.framework.Engine;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
@@ -124,6 +125,7 @@ public class BoardSVC implements IrisService, BoardProvider {
|
|||||||
int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight();
|
int y = player.getLocation().getBlockY() - player.getWorld().getMinHeight();
|
||||||
int z = player.getLocation().getBlockZ();
|
int z = player.getLocation().getBlockZ();
|
||||||
|
|
||||||
|
|
||||||
lines.add("&7&m ");
|
lines.add("&7&m ");
|
||||||
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
lines.add(C.GREEN + "Speed" + C.GRAY + ": " + Form.f(engine.getGeneratedPerSecond(), 0) + "/s " + Form.duration(1000D / engine.getGeneratedPerSecond(), 0));
|
||||||
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
lines.add(C.AQUA + "Cache" + C.GRAY + ": " + Form.f(IrisData.cacheSize()));
|
||||||
@@ -131,10 +133,11 @@ public class BoardSVC implements IrisService, BoardProvider {
|
|||||||
lines.add("&7&m ");
|
lines.add("&7&m ");
|
||||||
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
lines.add(C.AQUA + "Region" + C.GRAY + ": " + engine.getRegion(x, z).getName());
|
||||||
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
lines.add(C.AQUA + "Biome" + C.GRAY + ": " + engine.getBiomeOrMantle(x, y, z).getName());
|
||||||
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z) + player.getWorld().getMinHeight()));
|
lines.add(C.AQUA + "Height" + C.GRAY + ": " + Math.round(engine.getHeight(x, z)));
|
||||||
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
lines.add(C.AQUA + "Slope" + C.GRAY + ": " + Form.f(engine.getComplex().getSlopeStream().get(x, z), 2));
|
||||||
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
lines.add(C.AQUA + "BUD/s" + C.GRAY + ": " + Form.f(engine.getBlockUpdatesPerSecond()));
|
||||||
lines.add("&7&m ");
|
lines.add("&7&m ");
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,9 +20,12 @@ package com.volmit.iris.core.service;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.nms.INMS;
|
||||||
|
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
|
||||||
import com.volmit.iris.engine.object.*;
|
import com.volmit.iris.engine.object.*;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KMap;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
import com.volmit.iris.util.format.Form;
|
import com.volmit.iris.util.format.Form;
|
||||||
import com.volmit.iris.util.function.Consumer2;
|
import com.volmit.iris.util.function.Consumer2;
|
||||||
import com.volmit.iris.util.io.Converter;
|
import com.volmit.iris.util.io.Converter;
|
||||||
@@ -37,13 +40,16 @@ import com.volmit.iris.util.nbt.tag.ListTag;
|
|||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.block.data.type.Jigsaw;
|
import org.bukkit.block.data.type.Jigsaw;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ConversionSVC implements IrisService {
|
public class ConversionSVC implements IrisService {
|
||||||
private KList<Converter> converters;
|
private KList<Converter> converters;
|
||||||
@@ -122,7 +128,7 @@ public class ConversionSVC implements IrisService {
|
|||||||
@SuppressWarnings("unchecked") ListTag<CompoundTag> paletteList = (ListTag<CompoundTag>) compound.getListTag("palette");
|
@SuppressWarnings("unchecked") ListTag<CompoundTag> paletteList = (ListTag<CompoundTag>) compound.getListTag("palette");
|
||||||
for (int i = 0; i < paletteList.size(); i++) {
|
for (int i = 0; i < paletteList.size(); i++) {
|
||||||
CompoundTag cp = paletteList.get(i);
|
CompoundTag cp = paletteList.get(i);
|
||||||
palette.add(NBTWorld.getBlockData(cp));
|
palette.add(INMS.get().getBlockData(cp));
|
||||||
}
|
}
|
||||||
IrisJigsawPiece piece = new IrisJigsawPiece();
|
IrisJigsawPiece piece = new IrisJigsawPiece();
|
||||||
IrisObject object = new IrisObject(w, h, d);
|
IrisObject object = new IrisObject(w, h, d);
|
||||||
@@ -135,20 +141,37 @@ public class ConversionSVC implements IrisService {
|
|||||||
int z = pos.get(2).asInt();
|
int z = pos.get(2).asInt();
|
||||||
BlockData bd = palette.get(cp.getInt("state")).clone();
|
BlockData bd = palette.get(cp.getInt("state")).clone();
|
||||||
|
|
||||||
|
piece.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
if (bd.getMaterial().equals(Material.JIGSAW) && cp.containsKey("nbt")) {
|
if (bd.getMaterial().equals(Material.JIGSAW) && cp.containsKey("nbt")) {
|
||||||
piece.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
//.setObject(in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
IrisPosition spos = new IrisPosition(object.getSigned(x, y, z));
|
IrisPosition spos = new IrisPosition(object.getSigned(x, y, z));
|
||||||
CompoundTag nbt = cp.getCompoundTag("nbt");
|
CompoundTag nbt = cp.getCompoundTag("nbt");
|
||||||
CompoundTag finalState = new CompoundTag();
|
CompoundTag finalState = new CompoundTag();
|
||||||
finalState.putString("Name", nbt.getString("final_state"));
|
finalState.putString("Name", nbt.getString("final_state"));
|
||||||
BlockData jd = bd.clone();
|
BlockData jd = bd.clone();
|
||||||
bd = NBTWorld.getBlockData(finalState);
|
bd = INMS.get().getBlockData(finalState);
|
||||||
String joint = nbt.getString("joint");
|
String joint = nbt.getString("joint");
|
||||||
String pool = nbt.getString("pool");
|
String pool = nbt.getString("pool");
|
||||||
String poolId = toPoolName(pool);
|
String poolId = toPoolName(pool);
|
||||||
String name = nbt.getString("name");
|
String name = nbt.getString("name");
|
||||||
String target = nbt.getString("target");
|
String target = nbt.getString("target");
|
||||||
pools.computeIfAbsent(poolId, (k) -> new IrisJigsawPool());
|
pools.computeIfAbsent(poolId, (k) -> {
|
||||||
|
IrisJigsawPool irisPool = new IrisJigsawPool();
|
||||||
|
|
||||||
|
String basePath = in.toURI().relativize(folder.toURI()).getPath();
|
||||||
|
File baseFolder = new File(in.toURI().relativize(folder.toURI()).toString());
|
||||||
|
String[] paths = FileUtils.listFiles(folder, null, true)
|
||||||
|
.stream()
|
||||||
|
.map(path -> path.getPath().replaceAll("\\.nbt$", "")).toArray(String[]::new);
|
||||||
|
|
||||||
|
KList<String> poolList = new KList<>();
|
||||||
|
for (int ii = 0; ii < Objects.requireNonNull(paths).length; ii++) {
|
||||||
|
String lastSegment = paths[ii].substring(paths[ii].lastIndexOf("\\") + 1);
|
||||||
|
poolList.add(basePath + lastSegment);
|
||||||
|
}
|
||||||
|
irisPool.setPieces(poolList);
|
||||||
|
return irisPool;
|
||||||
|
});
|
||||||
IrisJigsawPieceConnector connector = new IrisJigsawPieceConnector();
|
IrisJigsawPieceConnector connector = new IrisJigsawPieceConnector();
|
||||||
connector.setName(name);
|
connector.setName(name);
|
||||||
connector.setTargetName(target);
|
connector.setTargetName(target);
|
||||||
@@ -169,10 +192,14 @@ public class ConversionSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (piece.getObject().isBlank() || piece.getObject().isEmpty()) {
|
||||||
|
Iris.info(C.RED + "Failed Setting object with path: " + in.toURI().relativize(folder.toURI()).getPath() + file.getName().split("\\Q.\\E")[0]);
|
||||||
|
}
|
||||||
jpool.getPieces().addIfMissing(id);
|
jpool.getPieces().addIfMissing(id);
|
||||||
object.write(new File(destObjects, file.getName().split("\\Q.\\E")[0] + ".iob"));
|
object.write(new File(destObjects, file.getName().split("\\Q.\\E")[0] + ".iob"));
|
||||||
IO.writeAll(new File(destPieces, file.getName().split("\\Q.\\E")[0] + ".json"), new JSONObject(new Gson().toJson(piece)).toString(4));
|
IO.writeAll(new File(destPieces, file.getName().split("\\Q.\\E")[0] + ".json"), new JSONObject(new Gson().toJson(piece)).toString(4));
|
||||||
Iris.info("[Jigsaw]: (" + Form.pc((double) at.get() / (double) total.get(), 0) + ") Exported Piece: " + id);
|
Iris.info("[Jigsaw]: (" + Form.pc((double) at.get() / (double) total.get(), 0).replace("%", "%%") + ") Exported Piece: " + id);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -33,6 +33,7 @@ import org.bukkit.event.world.WorldUnloadEvent;
|
|||||||
|
|
||||||
public class EditSVC implements IrisService {
|
public class EditSVC implements IrisService {
|
||||||
private KMap<World, BlockEditor> editors;
|
private KMap<World, BlockEditor> editors;
|
||||||
|
public static boolean deletingWorld = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
@@ -71,11 +72,12 @@ public class EditSVC implements IrisService {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void on(WorldUnloadEvent e) {
|
public void on(WorldUnloadEvent e) {
|
||||||
if (editors.containsKey(e.getWorld())) {
|
if (editors.containsKey(e.getWorld()) && !deletingWorld) {
|
||||||
editors.remove(e.getWorld()).close();
|
editors.remove(e.getWorld()).close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
for (World i : editors.k()) {
|
for (World i : editors.k()) {
|
||||||
if (M.ms() - editors.get(i).last() > 1000) {
|
if (M.ms() - editors.get(i).last() > 1000) {
|
||||||
@@ -1,118 +1,174 @@
|
|||||||
/*
|
/*
|
||||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||||
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
* Copyright (c) 2022 Arcane Arts (Volmit Software)
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.volmit.iris.core.service;
|
package com.volmit.iris.core.service;
|
||||||
|
|
||||||
import com.volmit.iris.Iris;
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.core.link.ExternalDataProvider;
|
import com.volmit.iris.core.link.*;
|
||||||
import com.volmit.iris.core.link.Identifier;
|
import com.volmit.iris.core.nms.container.Pair;
|
||||||
import com.volmit.iris.core.link.ItemAdderDataProvider;
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
import com.volmit.iris.core.link.OraxenDataProvider;
|
import com.volmit.iris.util.collection.KList;
|
||||||
import com.volmit.iris.util.collection.KList;
|
import com.volmit.iris.util.collection.KMap;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.event.server.PluginEnableEvent;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.event.server.PluginEnableEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
import java.util.MissingResourceException;
|
|
||||||
import java.util.Optional;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
@Data
|
|
||||||
public class ExternalDataSVC implements IrisService {
|
@Data
|
||||||
|
public class ExternalDataSVC implements IrisService {
|
||||||
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
|
|
||||||
|
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
@Override
|
||||||
Iris.info("Loading ExternalDataProvider...");
|
public void onEnable() {
|
||||||
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
|
Iris.info("Loading ExternalDataProvider...");
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
|
||||||
providers.add(new OraxenDataProvider());
|
|
||||||
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
|
providers.add(new OraxenDataProvider());
|
||||||
Iris.info("Oraxen found, loading OraxenDataProvider...");
|
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
|
||||||
}
|
Iris.info("Oraxen found, loading OraxenDataProvider...");
|
||||||
providers.add(new ItemAdderDataProvider());
|
}
|
||||||
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
|
providers.add(new MythicCrucibleDataProvider());
|
||||||
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
|
if (Bukkit.getPluginManager().getPlugin("MythicCrucible") != null) {
|
||||||
}
|
Iris.info("MythicCrucible found, loading MythicCrucibleDataProvider...");
|
||||||
|
}
|
||||||
for (ExternalDataProvider p : providers) {
|
providers.add(new ItemAdderDataProvider());
|
||||||
if (p.isReady()) {
|
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
|
||||||
activeProviders.add(p);
|
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
|
||||||
p.init();
|
}
|
||||||
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
|
providers.add(new ExecutableItemsDataProvider());
|
||||||
}
|
if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) {
|
||||||
}
|
Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider...");
|
||||||
}
|
}
|
||||||
|
providers.add(new HMCLeavesDataProvider());
|
||||||
@Override
|
if (Bukkit.getPluginManager().getPlugin("HMCLeaves") != null) {
|
||||||
public void onDisable() {
|
Iris.info("BlockAdder found, loading HMCLeavesDataProvider...");
|
||||||
}
|
}
|
||||||
|
providers.add(new MMOItemsDataProvider());
|
||||||
@EventHandler
|
if (Bukkit.getPluginManager().getPlugin("MMOItems") != null) {
|
||||||
public void onPluginEnable(PluginEnableEvent e) {
|
Iris.info("MMOItems found, loading MMOItemsDataProvider...");
|
||||||
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
|
}
|
||||||
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
|
providers.add(new EcoItemsDataProvider());
|
||||||
activeProviders.add(edp);
|
if (Bukkit.getPluginManager().getPlugin("EcoItems") != null) {
|
||||||
edp.init();
|
Iris.info("EcoItems found, loading EcoItemsDataProvider...");
|
||||||
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
|
}
|
||||||
});
|
|
||||||
}
|
for (ExternalDataProvider p : providers) {
|
||||||
}
|
if (p.isReady()) {
|
||||||
|
activeProviders.add(p);
|
||||||
public Optional<BlockData> getBlockData(Identifier key) {
|
p.init();
|
||||||
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
|
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
|
||||||
if (provider.isEmpty())
|
}
|
||||||
return Optional.empty();
|
}
|
||||||
try {
|
}
|
||||||
return Optional.of(provider.get().getBlockData(key));
|
|
||||||
} catch (MissingResourceException e) {
|
@Override
|
||||||
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
public void onDisable() {
|
||||||
return Optional.empty();
|
}
|
||||||
}
|
|
||||||
}
|
@EventHandler
|
||||||
|
public void onPluginEnable(PluginEnableEvent e) {
|
||||||
public Optional<ItemStack> getItemStack(Identifier key) {
|
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
|
||||||
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
|
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
|
||||||
if (provider.isEmpty()) {
|
activeProviders.add(edp);
|
||||||
Iris.warn("No matching Provider found for modded material \"%s\"!", key);
|
edp.init();
|
||||||
return Optional.empty();
|
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
|
||||||
}
|
});
|
||||||
try {
|
}
|
||||||
return Optional.of(provider.get().getItemStack(key));
|
}
|
||||||
} catch (MissingResourceException e) {
|
|
||||||
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
public Optional<BlockData> getBlockData(final Identifier key) {
|
||||||
return Optional.empty();
|
var pair = parseState(key);
|
||||||
}
|
Identifier mod = pair.getA();
|
||||||
}
|
|
||||||
|
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(mod, false)).findFirst();
|
||||||
public Identifier[] getAllBlockIdentifiers() {
|
if (provider.isEmpty())
|
||||||
KList<Identifier> names = new KList<>();
|
return Optional.empty();
|
||||||
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
|
try {
|
||||||
return names.toArray(new Identifier[0]);
|
return Optional.of(provider.get().getBlockData(mod, pair.getB()));
|
||||||
}
|
} catch (MissingResourceException e) {
|
||||||
|
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
||||||
public Identifier[] getAllItemIdentifiers() {
|
return Optional.empty();
|
||||||
KList<Identifier> names = new KList<>();
|
}
|
||||||
activeProviders.forEach(p -> names.add(p.getItemTypes()));
|
}
|
||||||
return names.toArray(new Identifier[0]);
|
|
||||||
}
|
public Optional<ItemStack> getItemStack(Identifier key, KMap<String, Object> customNbt) {
|
||||||
}
|
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, true)).findFirst();
|
||||||
|
if (provider.isEmpty()) {
|
||||||
|
Iris.warn("No matching Provider found for modded material \"%s\"!", key);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Optional.of(provider.get().getItemStack(key, customNbt));
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void processUpdate(Engine engine, Block block, Identifier blockId) {
|
||||||
|
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, false)).findFirst();
|
||||||
|
if (provider.isEmpty()) {
|
||||||
|
Iris.warn("No matching Provider found for modded material \"%s\"!", blockId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
provider.get().processUpdate(engine, block, blockId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier[] getAllBlockIdentifiers() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
activeProviders.forEach(p -> names.add(p.getBlockTypes()));
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Identifier[] getAllItemIdentifiers() {
|
||||||
|
KList<Identifier> names = new KList<>();
|
||||||
|
activeProviders.forEach(p -> names.add(p.getItemTypes()));
|
||||||
|
return names.toArray(new Identifier[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pair<Identifier, KMap<String, String>> parseState(Identifier key) {
|
||||||
|
if (!key.key().contains("[") || !key.key().contains("]")) {
|
||||||
|
return new Pair<>(key, new KMap<>());
|
||||||
|
}
|
||||||
|
String state = key.key().split("\\Q[\\E")[1].split("\\Q]\\E")[0];
|
||||||
|
KMap<String, String> stateMap = new KMap<>();
|
||||||
|
if (!state.isEmpty()) {
|
||||||
|
Arrays.stream(state.split(",")).forEach(s -> stateMap.put(s.split("=")[0], s.split("=")[1]));
|
||||||
|
}
|
||||||
|
return new Pair<>(new Identifier(key.namespace(), key.key().split("\\Q[\\E")[0]), stateMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Identifier buildState(Identifier key, KMap<String, String> state) {
|
||||||
|
if (state.isEmpty()) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
String path = state.entrySet()
|
||||||
|
.stream()
|
||||||
|
.map(e -> e.getKey() + "=" + e.getValue())
|
||||||
|
.collect(Collectors.joining(",", key.key() + "[", "]"));
|
||||||
|
return new Identifier(key.namespace(), path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,317 @@
|
|||||||
|
package com.volmit.iris.core.service;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
|
import com.volmit.iris.core.IrisSettings;
|
||||||
|
import com.volmit.iris.core.tools.IrisToolbelt;
|
||||||
|
import com.volmit.iris.engine.framework.Engine;
|
||||||
|
import com.volmit.iris.engine.platform.PlatformChunkGenerator;
|
||||||
|
import com.volmit.iris.util.collection.KList;
|
||||||
|
import com.volmit.iris.util.collection.KMap;
|
||||||
|
import com.volmit.iris.util.format.C;
|
||||||
|
import com.volmit.iris.util.format.Form;
|
||||||
|
import com.volmit.iris.util.mantle.TectonicPlate;
|
||||||
|
import com.volmit.iris.util.misc.getHardware;
|
||||||
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
|
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||||
|
import com.volmit.iris.util.scheduling.Looper;
|
||||||
|
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.server.PluginDisableEvent;
|
||||||
|
import org.bukkit.event.server.ServerLoadEvent;
|
||||||
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
|
import org.bukkit.event.world.WorldUnloadEvent;
|
||||||
|
import org.checkerframework.checker.units.qual.A;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class IrisEngineSVC implements IrisService {
|
||||||
|
public static IrisEngineSVC instance;
|
||||||
|
public boolean isServerShuttingDown = false;
|
||||||
|
public boolean isServerLoaded = false;
|
||||||
|
private static final AtomicInteger tectonicLimit = new AtomicInteger(30);
|
||||||
|
private ReentrantLock lastUseLock;
|
||||||
|
private KMap<World, Long> lastUse;
|
||||||
|
private List<World> IrisWorlds;
|
||||||
|
private Looper cacheTicker;
|
||||||
|
private Looper trimTicker;
|
||||||
|
private Looper unloadTicker;
|
||||||
|
private Looper updateTicker;
|
||||||
|
private PrecisionStopwatch trimAlive;
|
||||||
|
private PrecisionStopwatch unloadAlive;
|
||||||
|
public PrecisionStopwatch trimActiveAlive;
|
||||||
|
public PrecisionStopwatch unloadActiveAlive;
|
||||||
|
private AtomicInteger TotalTectonicPlates;
|
||||||
|
private AtomicInteger TotalQueuedTectonicPlates;
|
||||||
|
private AtomicInteger TotalNotQueuedTectonicPlates;
|
||||||
|
private AtomicBoolean IsUnloadAlive;
|
||||||
|
private AtomicBoolean IsTrimAlive;
|
||||||
|
ChronoLatch cl;
|
||||||
|
|
||||||
|
public List<World> corruptedIrisWorlds = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
this.cl = new ChronoLatch(5000);
|
||||||
|
lastUse = new KMap<>();
|
||||||
|
lastUseLock = new ReentrantLock();
|
||||||
|
IrisWorlds = new ArrayList<>();
|
||||||
|
IsUnloadAlive = new AtomicBoolean(true);
|
||||||
|
IsTrimAlive = new AtomicBoolean(true);
|
||||||
|
trimActiveAlive = new PrecisionStopwatch();
|
||||||
|
unloadActiveAlive = new PrecisionStopwatch();
|
||||||
|
trimAlive = new PrecisionStopwatch();
|
||||||
|
unloadAlive = new PrecisionStopwatch();
|
||||||
|
TotalTectonicPlates = new AtomicInteger();
|
||||||
|
TotalQueuedTectonicPlates = new AtomicInteger();
|
||||||
|
TotalNotQueuedTectonicPlates = new AtomicInteger();
|
||||||
|
tectonicLimit.set(2);
|
||||||
|
long t = getHardware.getProcessMemory();
|
||||||
|
while (t > 200) {
|
||||||
|
tectonicLimit.getAndAdd(1);
|
||||||
|
t = t - 200;
|
||||||
|
}
|
||||||
|
this.setup();
|
||||||
|
this.TrimLogic();
|
||||||
|
this.UnloadLogic();
|
||||||
|
|
||||||
|
trimAlive.begin();
|
||||||
|
unloadAlive.begin();
|
||||||
|
trimActiveAlive.begin();
|
||||||
|
unloadActiveAlive.begin();
|
||||||
|
|
||||||
|
updateTicker.start();
|
||||||
|
cacheTicker.start();
|
||||||
|
//trimTicker.start();
|
||||||
|
//unloadTicker.start();
|
||||||
|
instance = this;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void engineStatus() {
|
||||||
|
boolean trimAlive = trimTicker.isAlive();
|
||||||
|
boolean unloadAlive = unloadTicker.isAlive();
|
||||||
|
Iris.info("Status:");
|
||||||
|
Iris.info("- Trim: " + trimAlive);
|
||||||
|
Iris.info("- Unload: " + unloadAlive);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getTectonicLimit() {
|
||||||
|
return tectonicLimit.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldUnload(WorldUnloadEvent event) {
|
||||||
|
updateWorlds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onWorldLoad(WorldLoadEvent event) {
|
||||||
|
updateWorlds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onServerBoot(ServerLoadEvent event) {
|
||||||
|
isServerLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPluginDisable(PluginDisableEvent event) {
|
||||||
|
if (event.getPlugin().equals(Iris.instance)) {
|
||||||
|
isServerShuttingDown = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateWorlds() {
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
try {
|
||||||
|
if (IrisToolbelt.access(world).getEngine() != null) {
|
||||||
|
IrisWorlds.add(world);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// no
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setup() {
|
||||||
|
cacheTicker = new Looper() {
|
||||||
|
@Override
|
||||||
|
protected long loop() {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
lastUseLock.lock();
|
||||||
|
try {
|
||||||
|
for (World key : new ArrayList<>(lastUse.keySet())) {
|
||||||
|
Long last = lastUse.get(key);
|
||||||
|
if (last == null)
|
||||||
|
continue;
|
||||||
|
if (now - last > 60000) {
|
||||||
|
lastUse.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lastUseLock.unlock();
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
updateTicker = new Looper() {
|
||||||
|
@Override
|
||||||
|
protected long loop() {
|
||||||
|
try {
|
||||||
|
TotalQueuedTectonicPlates.set(0);
|
||||||
|
TotalNotQueuedTectonicPlates.set(0);
|
||||||
|
TotalTectonicPlates.set(0);
|
||||||
|
for (World world : IrisWorlds) {
|
||||||
|
Engine engine = Objects.requireNonNull(IrisToolbelt.access(world)).getEngine();
|
||||||
|
TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload());
|
||||||
|
TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions());
|
||||||
|
TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount());
|
||||||
|
}
|
||||||
|
if (!isServerShuttingDown && isServerLoaded) {
|
||||||
|
if (!trimTicker.isAlive()) {
|
||||||
|
Iris.info(C.RED + "TrimTicker found dead! Booting it up!");
|
||||||
|
try {
|
||||||
|
TrimLogic();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("What happened?");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unloadTicker.isAlive()) {
|
||||||
|
Iris.info(C.RED + "UnloadTicker found dead! Booting it up!");
|
||||||
|
try {
|
||||||
|
UnloadLogic();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Iris.error("What happened?");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
public void TrimLogic() {
|
||||||
|
if (trimTicker == null || !trimTicker.isAlive()) {
|
||||||
|
trimTicker = new Looper() {
|
||||||
|
private final Supplier<Engine> supplier = createSupplier();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long loop() {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
trimAlive.reset();
|
||||||
|
try {
|
||||||
|
Engine engine = supplier.get();
|
||||||
|
if (engine != null) {
|
||||||
|
engine.getMantle().trim(tectonicLimit.get() / lastUse.size());
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
Iris.info(C.RED + "EngineSVC: Failed to trim.");
|
||||||
|
e.printStackTrace();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = lastUse.size();
|
||||||
|
long time = (size > 0 ? 1000 / size : 1000) - (System.currentTimeMillis() - start);
|
||||||
|
if (time <= 0)
|
||||||
|
return 0;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
trimTicker.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void UnloadLogic() {
|
||||||
|
if (unloadTicker == null || !unloadTicker.isAlive()) {
|
||||||
|
unloadTicker = new Looper() {
|
||||||
|
private final Supplier<Engine> supplier = createSupplier();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected long loop() {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
unloadAlive.reset();
|
||||||
|
try {
|
||||||
|
Engine engine = supplier.get();
|
||||||
|
if (engine != null) {
|
||||||
|
long unloadStart = System.currentTimeMillis();
|
||||||
|
int count = engine.getMantle().unloadTectonicPlate(tectonicLimit.get() / lastUse.size());
|
||||||
|
if (count > 0) {
|
||||||
|
Iris.debug(C.GOLD + "Unloaded " + C.YELLOW + count + " TectonicPlates in " + C.RED + Form.duration(System.currentTimeMillis() - unloadStart, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.reportError(e);
|
||||||
|
Iris.info(C.RED + "EngineSVC: Failed to unload.");
|
||||||
|
e.printStackTrace();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int size = lastUse.size();
|
||||||
|
long time = (size > 0 ? 1000 / size : 1000) - (System.currentTimeMillis() - start);
|
||||||
|
if (time <= 0)
|
||||||
|
return 0;
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
unloadTicker.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Supplier<Engine> createSupplier() {
|
||||||
|
AtomicInteger i = new AtomicInteger();
|
||||||
|
return () -> {
|
||||||
|
List<World> worlds = Bukkit.getWorlds();
|
||||||
|
if (i.get() >= worlds.size()) {
|
||||||
|
i.set(0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
for (int j = 0; j < worlds.size(); j++) {
|
||||||
|
World world = worlds.get(i.getAndIncrement());
|
||||||
|
PlatformChunkGenerator generator = IrisToolbelt.access(world);
|
||||||
|
if (i.get() >= worlds.size()) {
|
||||||
|
i.set(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (generator != null) {
|
||||||
|
Engine engine = generator.getEngine();
|
||||||
|
boolean closed = engine.getMantle().getData().isClosed();
|
||||||
|
if (engine != null && !engine.isStudio() && !closed) {
|
||||||
|
lastUseLock.lock();
|
||||||
|
lastUse.put(world, System.currentTimeMillis());
|
||||||
|
lastUseLock.unlock();
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
Iris.info(C.RED + "EngineSVC: Failed to create supplier.");
|
||||||
|
e.printStackTrace();
|
||||||
|
Iris.reportError(e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() {
|
||||||
|
cacheTicker.interrupt();
|
||||||
|
trimTicker.interrupt();
|
||||||
|
unloadTicker.interrupt();
|
||||||
|
lastUse.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,9 +18,11 @@
|
|||||||
|
|
||||||
package com.volmit.iris.core.service;
|
package com.volmit.iris.core.service;
|
||||||
|
|
||||||
|
import com.volmit.iris.Iris;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
|
|
||||||
@@ -68,19 +70,22 @@ public class ObjectSVC implements IrisService {
|
|||||||
* @param blocks The blocks to remove
|
* @param blocks The blocks to remove
|
||||||
*/
|
*/
|
||||||
private void revert(Map<Block, BlockData> blocks) {
|
private void revert(Map<Block, BlockData> blocks) {
|
||||||
int amount = 0;
|
|
||||||
Iterator<Map.Entry<Block, BlockData>> it = blocks.entrySet().iterator();
|
Iterator<Map.Entry<Block, BlockData>> it = blocks.entrySet().iterator();
|
||||||
while (it.hasNext()) {
|
Bukkit.getScheduler().runTask(Iris.instance, () -> {
|
||||||
Map.Entry<Block, BlockData> entry = it.next();
|
int amount = 0;
|
||||||
BlockData data = entry.getValue();
|
while (it.hasNext()) {
|
||||||
entry.getKey().setBlockData(data, false);
|
Map.Entry<Block, BlockData> entry = it.next();
|
||||||
it.remove();
|
BlockData data = entry.getValue();
|
||||||
|
entry.getKey().setBlockData(data, false);
|
||||||
|
|
||||||
amount++;
|
it.remove();
|
||||||
|
|
||||||
if (amount > 200) {
|
amount++;
|
||||||
J.s(() -> revert(blocks), 1);
|
|
||||||
|
if (amount > 200) {
|
||||||
|
J.s(() -> revert(blocks), 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ public class StudioSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dir = zipFiles.length == 1 && zipFiles[0].isDirectory() ? zipFiles[0] : null;
|
dir = zipFiles.length > 1 ? work : zipFiles[0].isDirectory() ? zipFiles[0] : null;
|
||||||
} catch (NullPointerException e) {
|
} catch (NullPointerException e) {
|
||||||
Iris.reportError(e);
|
Iris.reportError(e);
|
||||||
sender.sendMessage("Error when finding home directory. Are there any non-text characters in the file name?");
|
sender.sendMessage("Error when finding home directory. Are there any non-text characters in the file name?");
|
||||||
@@ -183,7 +183,7 @@ public class TreeSVC implements IrisService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
|
public void setTile(int xx, int yy, int zz, TileData tile) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ public class TreeSVC implements IrisService {
|
|||||||
boolean isUseAll = worldAccess.getEngine().getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL);
|
boolean isUseAll = worldAccess.getEngine().getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL);
|
||||||
|
|
||||||
// Retrieve objectPlacements of type `species` from biome
|
// Retrieve objectPlacements of type `species` from biome
|
||||||
IrisBiome biome = worldAccess.getEngine().getBiome(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
IrisBiome biome = worldAccess.getEngine().getBiome(location.getBlockX(), location.getBlockY()-worldAccess.getTarget().getWorld().minHeight(), location.getBlockZ());
|
||||||
placements.addAll(matchObjectPlacements(biome.getObjects(), size, type));
|
placements.addAll(matchObjectPlacements(biome.getObjects(), size, type));
|
||||||
|
|
||||||
// Add more or find any in the region
|
// Add more or find any in the region
|
||||||
@@ -30,9 +30,13 @@ import com.volmit.iris.util.format.C;
|
|||||||
import com.volmit.iris.util.math.M;
|
import com.volmit.iris.util.math.M;
|
||||||
import com.volmit.iris.util.matter.Matter;
|
import com.volmit.iris.util.matter.Matter;
|
||||||
import com.volmit.iris.util.matter.WorldMatter;
|
import com.volmit.iris.util.matter.WorldMatter;
|
||||||
|
import com.volmit.iris.util.misc.E;
|
||||||
import com.volmit.iris.util.plugin.IrisService;
|
import com.volmit.iris.util.plugin.IrisService;
|
||||||
import com.volmit.iris.util.plugin.VolmitSender;
|
import com.volmit.iris.util.plugin.VolmitSender;
|
||||||
import com.volmit.iris.util.scheduling.J;
|
import com.volmit.iris.util.scheduling.J;
|
||||||
|
import com.volmit.iris.util.scheduling.S;
|
||||||
|
import com.volmit.iris.util.scheduling.SR;
|
||||||
|
import com.volmit.iris.util.scheduling.jobs.Job;
|
||||||
import org.bukkit.*;
|
import org.bukkit.*;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
@@ -51,9 +55,16 @@ import org.bukkit.util.Vector;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class WandSVC implements IrisService {
|
public class WandSVC implements IrisService {
|
||||||
|
private static final Particle CRIT_MAGIC = E.getOrDefault(Particle.class, "CRIT_MAGIC", "CRIT");
|
||||||
|
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
|
||||||
|
private static final int MS_PER_TICK = Integer.parseInt(System.getProperty("iris.ms_per_tick", "30"));
|
||||||
|
|
||||||
private static ItemStack dust;
|
private static ItemStack dust;
|
||||||
|
private static ItemStack wand;
|
||||||
|
|
||||||
public static void pasteSchematic(IrisObject s, Location at) {
|
public static void pasteSchematic(IrisObject s, Location at) {
|
||||||
s.place(at);
|
s.place(at);
|
||||||
@@ -74,14 +85,81 @@ public class WandSVC implements IrisService {
|
|||||||
Location[] f = getCuboid(p);
|
Location[] f = getCuboid(p);
|
||||||
Cuboid c = new Cuboid(f[0], f[1]);
|
Cuboid c = new Cuboid(f[0], f[1]);
|
||||||
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
|
IrisObject s = new IrisObject(c.getSizeX(), c.getSizeY(), c.getSizeZ());
|
||||||
for (Block b : c) {
|
|
||||||
if (b.getType().equals(Material.AIR)) {
|
var it = c.chunkedIterator();
|
||||||
continue;
|
|
||||||
|
int total = c.getSizeX() * c.getSizeY() * c.getSizeZ();
|
||||||
|
var latch = new CountDownLatch(1);
|
||||||
|
new Job() {
|
||||||
|
private int i;
|
||||||
|
private Chunk chunk;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Scanning Selection";
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
|
@Override
|
||||||
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b);
|
public void execute() {
|
||||||
}
|
new SR() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
var time = M.ms() + MS_PER_TICK;
|
||||||
|
while (time > M.ms()) {
|
||||||
|
if (!it.hasNext()) {
|
||||||
|
if (chunk != null) {
|
||||||
|
chunk.removePluginChunkTicket(Iris.instance);
|
||||||
|
chunk = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel();
|
||||||
|
latch.countDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
var b = it.next();
|
||||||
|
var bChunk = b.getChunk();
|
||||||
|
if (chunk == null) {
|
||||||
|
chunk = bChunk;
|
||||||
|
chunk.addPluginChunkTicket(Iris.instance);
|
||||||
|
} else if (chunk != bChunk) {
|
||||||
|
chunk.removePluginChunkTicket(Iris.instance);
|
||||||
|
chunk = bChunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.getType().equals(Material.AIR))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BlockVector bv = b.getLocation().subtract(c.getLowerNE().toVector()).toVector().toBlockVector();
|
||||||
|
s.setUnsigned(bv.getBlockX(), bv.getBlockY(), bv.getBlockZ(), b);
|
||||||
|
} finally {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void completeWork() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTotalWork() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWorkCompleted() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}.execute(new VolmitSender(p), true, () -> {});
|
||||||
|
try {
|
||||||
|
latch.await();
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
@@ -161,11 +239,11 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack createDust() {
|
public static ItemStack createDust() {
|
||||||
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
|
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
|
||||||
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
|
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||||
ItemMeta im = is.getItemMeta();
|
ItemMeta im = is.getItemMeta();
|
||||||
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
|
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
|
||||||
im.setUnbreakable(true);
|
im.setUnbreakable(true);
|
||||||
im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_PLACED_ON, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DESTROYS, ItemFlag.HIDE_ENCHANTS);
|
im.addItemFlags(ItemFlag.values());
|
||||||
im.setLore(new KList<String>().qadd("Right click on a block to reveal it's placement structure!"));
|
im.setLore(new KList<String>().qadd("Right click on a block to reveal it's placement structure!"));
|
||||||
is.setItemMeta(im);
|
is.setItemMeta(im);
|
||||||
|
|
||||||
@@ -205,11 +283,11 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public static ItemStack createWand(Location a, Location b) {
|
public static ItemStack createWand(Location a, Location b) {
|
||||||
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
ItemStack is = new ItemStack(Material.BLAZE_ROD);
|
||||||
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
|
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
|
||||||
ItemMeta im = is.getItemMeta();
|
ItemMeta im = is.getItemMeta();
|
||||||
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
|
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
|
||||||
im.setUnbreakable(true);
|
im.setUnbreakable(true);
|
||||||
im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES, ItemFlag.HIDE_PLACED_ON, ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DESTROYS, ItemFlag.HIDE_ENCHANTS);
|
im.addItemFlags(ItemFlag.values());
|
||||||
im.setLore(new KList<String>().add(locationToString(a), locationToString(b)));
|
im.setLore(new KList<String>().add(locationToString(a), locationToString(b)));
|
||||||
is.setItemMeta(im);
|
is.setItemMeta(im);
|
||||||
|
|
||||||
@@ -226,17 +304,19 @@ public class WandSVC implements IrisService {
|
|||||||
return getCuboidFromItem(p.getInventory().getItemInMainHand());
|
return getCuboidFromItem(p.getInventory().getItemInMainHand());
|
||||||
}
|
}
|
||||||
|
|
||||||
Cuboid c = WorldEditLink.getSelection(p);
|
if (IrisSettings.get().getWorld().worldEditWandCUI) {
|
||||||
|
Cuboid c = WorldEditLink.getSelection(p);
|
||||||
|
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
return new Location[]{c.getLowerNE(), c.getUpperSW()};
|
return new Location[]{c.getLowerNE(), c.getUpperSW()};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isHoldingWand(Player p) {
|
public static boolean isHoldingWand(Player p) {
|
||||||
return isHoldingIrisWand(p) || WorldEditLink.getSelection(p) != null;
|
return isHoldingIrisWand(p) || (IrisSettings.get().getWorld().worldEditWandCUI && WorldEditLink.getSelection(p) != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isHoldingIrisWand(Player p) {
|
public static boolean isHoldingIrisWand(Player p) {
|
||||||
@@ -251,7 +331,6 @@ public class WandSVC implements IrisService {
|
|||||||
* @return True if it is
|
* @return True if it is
|
||||||
*/
|
*/
|
||||||
public static boolean isWand(ItemStack is) {
|
public static boolean isWand(ItemStack is) {
|
||||||
ItemStack wand = createWand();
|
|
||||||
if (is.getItemMeta() == null) return false;
|
if (is.getItemMeta() == null) return false;
|
||||||
return is.getType().equals(wand.getType()) &&
|
return is.getType().equals(wand.getType()) &&
|
||||||
is.getItemMeta().getDisplayName().equals(wand.getItemMeta().getDisplayName()) &&
|
is.getItemMeta().getDisplayName().equals(wand.getItemMeta().getDisplayName()) &&
|
||||||
@@ -261,7 +340,7 @@ public class WandSVC implements IrisService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
ItemStack wand = createWand();
|
wand = createWand();
|
||||||
dust = createDust();
|
dust = createDust();
|
||||||
|
|
||||||
J.ar(() -> {
|
J.ar(() -> {
|
||||||
@@ -309,9 +388,9 @@ public class WandSVC implements IrisService {
|
|||||||
*/
|
*/
|
||||||
public void draw(Location[] d, Player p) {
|
public void draw(Location[] d, Player p) {
|
||||||
Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
Vector gx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
||||||
d[0].getWorld().spawnParticle(Particle.CRIT_MAGIC, d[0], 1, 0.5 + gx.getX(), 0.5 + gx.getY(), 0.5 + gx.getZ(), 0, null, false);
|
d[0].getWorld().spawnParticle(CRIT_MAGIC, d[0], 1, 0.5 + gx.getX(), 0.5 + gx.getY(), 0.5 + gx.getZ(), 0, null, false);
|
||||||
Vector gxx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
Vector gxx = Vector.getRandom().subtract(Vector.getRandom()).normalize().clone().multiply(0.65);
|
||||||
d[1].getWorld().spawnParticle(Particle.CRIT, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
|
d[1].getWorld().spawnParticle(CRIT_MAGIC, d[1], 1, 0.5 + gxx.getX(), 0.5 + gxx.getY(), 0.5 + gxx.getZ(), 0, null, false);
|
||||||
|
|
||||||
if (!d[0].getWorld().equals(d[1].getWorld())) {
|
if (!d[0].getWorld().equals(d[1].getWorld())) {
|
||||||
return;
|
return;
|
||||||
@@ -368,7 +447,7 @@ public class WandSVC implements IrisService {
|
|||||||
int r = color.getRed();
|
int r = color.getRed();
|
||||||
int g = color.getGreen();
|
int g = color.getGreen();
|
||||||
int b = color.getBlue();
|
int b = color.getBlue();
|
||||||
p.spawnParticle(Particle.REDSTONE, lv.getX(), lv.getY(), lv.getZ(), 1, 0, 0, 0, 0, new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), 0.75f));
|
p.spawnParticle(REDSTONE, lv.getX(), lv.getY(), lv.getZ(), 1, 0, 0, 0, 0, new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b), 0.75f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -381,7 +460,7 @@ public class WandSVC implements IrisService {
|
|||||||
if (e.getHand() != EquipmentSlot.HAND)
|
if (e.getHand() != EquipmentSlot.HAND)
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
if (isHoldingWand(e.getPlayer())) {
|
if (isHoldingIrisWand(e.getPlayer())) {
|
||||||
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
|
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
|
||||||
e.setCancelled(true);
|
e.setCancelled(true);
|
||||||
e.getPlayer().getInventory().setItemInMainHand(update(true, Objects.requireNonNull(e.getClickedBlock()).getLocation(), e.getPlayer().getInventory().getItemInMainHand()));
|
e.getPlayer().getInventory().setItemInMainHand(update(true, Objects.requireNonNull(e.getClickedBlock()).getLocation(), e.getPlayer().getInventory().getItemInMainHand()));
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user