9
0
mirror of https://github.com/VolmitSoftware/Iris.git synced 2026-01-04 15:41:30 +00:00

Compare commits

...

246 Commits

Author SHA1 Message Date
Brian Neumann-Fopiano
cf4796bd12 V+ 2024-07-31 18:45:13 -04:00
Julian Krings
bd89d8a308 change version to show 1.21 compat 2024-08-01 00:20:30 +02:00
Julian Krings
df2186d70f Merge pull request #1110 from VolmitSoftware/v1_21
1.21 Support
2024-07-31 23:52:10 +02:00
Julian Krings
f9638e830f update NMSTools 2024-07-30 12:56:27 +02:00
Julian Krings
cd55a7fed4 fix getBiomeColor for 1.19.2 2024-07-27 15:43:09 +02:00
Julian Krings
fc890a5ba1 fix missing getBiomeColor method 2024-07-27 15:42:51 +02:00
Julian Krings
2ea54b7f2f 1.21 nms bindings 2024-07-24 19:59:01 +02:00
Brian Fopiano
e90e3901f5 Merge pull request #1109 from VolmitSoftware/fixes
Fixes
2024-07-23 15:43:33 -04:00
Brian Fopiano
36d58f29ab Merge pull request #1108 from VolmitSoftware/better_nms
Better NMS
2024-07-23 15:43:21 -04:00
Brian Fopiano
864c7ae27c Merge pull request #1106 from VolmitDev/custom_data
improve custom block/item api to allow custom settings
2024-07-23 15:43:04 -04:00
Julian Krings
6d104a2d1c fix y-coordinate for getting biome 2024-07-23 20:05:05 +02:00
Julian Krings
89e754245d add maxTries to IrisLootTable to prevent crash 2024-07-21 16:00:02 +02:00
Julian Krings
4c68d99c6f fix returning black color in biomes without a color override 2024-07-21 15:50:45 +02:00
Julian Krings
f8f0a65f0a add debug info to the updater 2024-07-21 15:25:31 +02:00
Julian Krings
6ff74639b5 use custom nms gradle plugin 2024-07-18 17:17:05 +02:00
Julian Krings
af80f882da add slope condition to sear/shore/surface decorators 2024-07-09 16:25:07 +02:00
Julian Krings
84ce7372c3 implement dimension zoom options 2024-07-09 16:23:32 +02:00
Julian Krings
e31d39c5f7 fix worldedit selection not updating 2024-07-09 16:19:56 +02:00
Julian Krings
2296c1368b fix WorldEditLink 2024-07-09 16:19:22 +02:00
Brian Fopiano
21d7d96dbc Merge pull request #1107 from RePixelatedMC/master 2024-07-05 00:46:54 -04:00
RePixelatedMC
956e511fe0 Merge remote-tracking branch 'origin/master' 2024-07-04 22:02:42 +02:00
RePixelatedMC
e427887f8c Scary 2024-07-04 22:00:50 +02:00
Julian Krings
88ea43fbbe fix post processing for custom blocks not applying to objects 2024-06-28 18:14:52 +02:00
Julian Krings
29526a80a9 improve custom block/item api to allow custom settings 2024-06-25 13:35:34 +02:00
Julian Krings
48f901fc8c handle null pointer 2024-06-25 13:33:44 +02:00
Julian Krings
6c3f3dc889 update oraxen api 2024-06-24 13:17:11 +02:00
Julian Krings
743410d3ee add nms method to get biome color 2024-06-24 13:16:56 +02:00
Brian Neumann-Fopiano
acccbb028f V+ 2024-06-18 21:32:35 -04:00
Julian Krings
8b31fdc780 Merge pull request #1105 from VolmitDev/jigsaw_dist
Fix jigsaw spawn distances
2024-06-17 17:07:47 +02:00
CrazyDev22
55017b9ac2 Revert "Merge branch 'mca' into jigsaw_dist"
This reverts commit 0288d35c85, reversing
changes made to 8b3577dd0b.
2024-06-16 14:25:47 +02:00
Julian Krings
0288d35c85 Merge branch 'mca' into jigsaw_dist 2024-06-16 14:23:49 +02:00
Julian Krings
8b3577dd0b make divisor used for generating missing jigsaw placement values changeable 2024-06-16 14:06:24 +02:00
Brian Neumann-Fopiano
ced77ec70d V+ 2024-06-09 17:26:08 -04:00
Julian Krings
e1e90f5c8a add toolchain resolver 2024-06-08 08:27:17 +02:00
RePixelatedMC
dc3487583d Merge pull request #25 from VolmitSoftware/merge
merge
2024-06-05 09:53:26 +02:00
RePixelatedMC
e1d73ebcd5 Merge branch 'mca' into merge 2024-06-05 09:53:13 +02:00
RePixelatedMC
d7cf3b9500 no gui for now 2024-06-03 10:03:14 +02:00
Brian Fopiano
8ce4e3c6b2 Merge pull request #1104 from RePixelatedMC/master
small changes
2024-06-01 10:30:21 -04:00
RePixelatedMC
76f7d46b22 e 2024-06-01 16:26:21 +02:00
RePixelatedMC
cfc52ed909 Tuning + Fixed server distro reading for 1.20.6+ 2024-06-01 16:21:57 +02:00
RePixelatedMC
cee94d40e1 Merge branch 'master' of https://github.com/VolmitSoftware/Iris 2024-05-29 10:18:04 +02:00
RePixelatedMC
cad7166cbe Merge pull request #24 from VolmitDev/fix_jigsaw
minor changes to jigsaw
2024-05-25 15:41:05 +02:00
Julian Krings
c05fdbd0ec Merge pull request #1103 from VolmitDev/fix_jigsaw
minor changes to jigsaw placement
2024-05-25 15:39:07 +02:00
CrazyDev22
c9b26ebaff add better backwards compat 2024-05-25 15:34:51 +02:00
CrazyDev22
bee1973390 fix salt not being a long 2024-05-25 15:34:25 +02:00
RePixelatedMC
57efcab0b5 tall_seagrass isnt sticking out of water anymore 2024-05-22 16:55:07 +02:00
RePixelatedMC
b1ab2b84f8 Fixed /iris region going of a chunk instead of x,z coords
Added fast edit commands
- /iris std edit biome is now supported and opens the vscode biome of where you are standing at same with region.
2024-05-22 15:34:45 +02:00
RePixelatedMC
02601e5ee4 Cleanup 2024-05-22 13:32:29 +02:00
RePixelatedMC
070479acf3 Merge branch 'mca' of https://github.com/RePixelatedMC/Iris into PixelatedDev 2024-05-22 13:29:16 +02:00
RePixelatedMC
6b2ba74237 Iris lets the user ingame know when unstable. 2024-05-22 13:28:56 +02:00
RePixelatedMC
619de29710 Merge pull request #23 from VolmitDev/mca
improve iris world protection
2024-05-21 16:39:21 +02:00
CrazyDev22
12556fa98f improve iris world protection 2024-05-21 16:38:28 +02:00
RePixelatedMC
bef4c0497f Merge branch 'mca' of https://github.com/RePixelatedMC/Iris into PixelatedDev 2024-05-21 11:57:03 +02:00
RePixelatedMC
9193497d36 Merge pull request #22 from RePixelatedMC/v3.3
V3.3 x MCA?
2024-05-21 11:56:14 +02:00
RePixelatedMC
ca6affbde9 Merge branch 'master' into v3.3 2024-05-21 11:48:39 +02:00
RePixelatedMC
81c40ce228 Merge branch 'master' of https://github.com/RePixelatedMC/Iris into PixelatedDev 2024-05-21 11:23:52 +02:00
RePixelatedMC
6ba1d571f2 Fallback type when mm not on server 2024-05-21 11:23:24 +02:00
RePixelatedMC
b0663f9b6c Merge branch 'master' into PixelatedDev 2024-05-21 11:22:39 +02:00
RePixelatedMC
3ced6f3e9e Entity Fallback 2024-05-20 14:46:11 +02:00
RePixelatedMC
3146d61efe Merge pull request #19 from VolmitDev/mca
Sync
2024-05-20 14:04:32 +02:00
CrazyDev22
a967b6af85 replace datapack system with a dynamic one 2024-05-20 06:41:38 +02:00
Brian Fopiano
db3bc74364 Merge pull request #1092 from VolmitDev/fix_jigsaw
Jigsaw fixes
2024-05-19 18:21:11 -04:00
CrazyDev22
eb19d9a846 Merge branch 'refs/heads/master' into mca
# Conflicts:
#	build.gradle
#	core/src/main/java/com/volmit/iris/core/ServerConfigurator.java
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java
2024-05-19 20:48:13 +02:00
Julian Krings
96dd299de7 Merge pull request #1102 from VolmitDev/v1_20_R4
move datapack upgrade command under dev
2024-05-19 19:11:43 +02:00
CrazyDev22
aee0806aa8 move datapack upgrade command under dev 2024-05-19 19:10:53 +02:00
Brian Fopiano
e39f13bbb4 Merge pull request #1101 from VolmitDev/v1_20_R4
add datapack upgrade command
2024-05-19 08:49:15 -04:00
CrazyDev22
52ec80d384 add datapack upgrade command 2024-05-19 14:40:19 +02:00
CrazyDev22
d9f8909bdc fix crash when using iris as main world 2024-05-18 23:36:03 +02:00
CrazyDev22
65aa9dc343 minor headless performance improvements 2024-05-18 23:34:53 +02:00
CrazyDev22
9bf7fdf174 headless performance improvements 2024-05-17 20:05:37 +02:00
CrazyDev22
dafb59e5a8 improve chunk existing check 2024-05-17 16:45:59 +02:00
CrazyDev22
79f86ca87d woops wrong height 2024-05-17 16:39:57 +02:00
RePixelatedMC
1749fcf6b5 Merge pull request #18 from VolmitDev/mca
1.20.4 Headless
2024-05-17 16:04:43 +02:00
CrazyDev22
e1a0481cdf implement Headless for 1.20.4 2024-05-17 16:01:21 +02:00
RePixelatedMC
4576b95814 Fixed width offset with /iris std map when dragging 2024-05-16 17:32:32 +02:00
RePixelatedMC
e113fa6a61 Merge branch 'mca' of https://github.com/RePixelatedMC/Iris into PixelatedDev 2024-05-16 16:55:51 +02:00
RePixelatedMC
07228afbff Noise benchmark reworkings 2024-05-16 16:55:14 +02:00
RePixelatedMC
afdffc2453 Merge pull request #17 from VolmitDev/fix_jigsaw
Sync jigsaw
2024-05-16 13:41:35 +02:00
CrazyDev22
6348442962 add y lock to fix offset when placing objects 2024-05-16 13:17:17 +02:00
CrazyDev22
fd10c005b0 disable warp to prevent x/z offsets 2024-05-16 13:15:34 +02:00
CrazyDev22
44500d6af9 fix translation not rotating 2024-05-16 13:12:49 +02:00
CrazyDev22
6ddb0b5304 update gson library 2024-05-16 13:12:11 +02:00
Brian Fopiano
8ce0976f88 Merge pull request #1100 from VolmitDev/v1_20_R4
add 1.20.6 support
2024-05-15 19:52:08 -04:00
CrazyDev22
8345a58f2b change safeguard message 2024-05-15 18:11:05 +02:00
CrazyDev22
f92234297e add 1.20.6 support 2024-05-15 18:07:12 +02:00
RePixelatedMC
6a5bcd5990 Merge pull request #16 from VolmitDev/fix_jigsaw
sync Jigsaw
2024-05-15 17:40:29 +02:00
RePixelatedMC
1fe6d9a636 Merge branch 'mca' of https://github.com/RePixelatedMC/Iris into PixelatedDev
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/tools/IrisWorldDump.java
2024-05-15 09:29:48 +02:00
RePixelatedMC
97f6ab66c3 sync 2024-05-15 09:13:00 +02:00
RePixelatedMC
b78c182d94 Map for studio 2024-05-13 16:30:18 +02:00
CrazyDev22
09a0f83013 add terminating pool overwrite 2024-05-11 12:51:29 +02:00
CrazyDev22
f68d7420e3 woops forgot description for SpreadType 2024-05-11 12:50:40 +02:00
CrazyDev22
55c0fa5f32 add command to sample the distances between structures 2024-05-10 15:58:57 +02:00
CrazyDev22
8b5d1d0298 rewrite jigsaw placement logic to prevent placements from being too close 2024-05-10 15:58:26 +02:00
CrazyDev22
b70e94dc65 make manual jigsaw place use the same calculations as normal 2024-05-10 15:43:01 +02:00
CrazyDev22
49a6552168 add forcePlace option to suppress placement checks 2024-05-10 15:41:42 +02:00
Brian Fopiano
0dd6892b28 Merge pull request #1097 from RePixelatedMC/master
Eco Items support
2024-05-09 15:44:13 -04:00
RePixelatedMC
fec587edad Update README.md 2024-05-07 22:42:28 +02:00
RePixelatedMC
712937d661 Merge pull request #15 from VolmitDev/ecoitems
add Ecoitems support
2024-05-04 16:03:08 +02:00
CrazyDev22
ace434e7b0 add EcoItems support 2024-05-04 13:21:55 +02:00
RePixelatedMC
1e5aa6e8b0 Merge branch 'mca' of https://github.com/RePixelatedMC/Iris into PixelatedDev 2024-05-04 11:26:47 +02:00
RePixelatedMC
441b27f8f4 Merge branch 'VolmitSoftware:master' into mca 2024-05-04 11:26:23 +02:00
RePixelatedMC
3f3bf70212 Merge pull request #14 from VolmitDev/mca
Per World Dimension Types + better Datapack reload
2024-05-04 11:26:05 +02:00
RePixelatedMC
a12eddbedf sync 2024-05-04 11:25:17 +02:00
CrazyDev22
12abc1709e add missing method to NMSBinding1X 2024-05-03 21:18:00 +02:00
CrazyDev22
9e6035e7b4 remove debug code 2024-05-03 21:17:02 +02:00
CrazyDev22
20b41d65d3 fixes to the per world dimensions + optimizations with the register method 2024-05-03 21:01:10 +02:00
CrazyDev22
1593bb2088 make smartVanillaHeight also adjust the logicalHeight 2024-05-03 19:57:34 +02:00
CrazyDev22
d4f9a20379 more removal of unnecessary settings 2024-05-03 19:56:43 +02:00
CrazyDev22
6e247597a4 fix loading the wrong IrisDimension on startup 2024-05-03 19:55:58 +02:00
CrazyDev22
8a8be4545c remove unnecessary minecraft dimension height calculations 2024-05-03 19:11:55 +02:00
CrazyDev22
05f4955989 implement proper datapack reload+per world height 2024-05-03 19:01:33 +02:00
CrazyDev22
93469fb3b4 include translate option into the bounding box of jigsaw pieces 2024-05-01 20:01:10 +02:00
RePixelatedMC
a70258d69f Merge branch 'fix_jigsaw' of https://github.com/VolmitDev/Iris into PixelatedDev 2024-05-01 18:55:02 +02:00
CrazyDev22
c653d852e4 make jigsaw place command use the same method as normal gen 2024-05-01 18:46:22 +02:00
CrazyDev22
40163d25b8 add object shink command for fixing too large/small bounding boxes for objects 2024-05-01 18:44:45 +02:00
CrazyDev22
5b4265783e fix object w/h/d not changing with rotation 2024-05-01 18:42:23 +02:00
CrazyDev22
720417b6c8 fix shrinkwrap method 2024-05-01 18:39:42 +02:00
RePixelatedMC
bb78f412e0 Sync / Progress on dump 2024-05-01 12:21:48 +02:00
RePixelatedMC
a919b91efb Whohoo! we can now read mca files! 2024-04-30 11:14:35 +02:00
Brian Neumann-Fopiano
a3dcf031c9 v+ , and the other v+ lol 2024-04-29 15:45:41 -04:00
RePixelatedMC
56eb4b6b84 Iris is small now! still a bit too big for spigot probably 2024-04-28 11:56:18 +02:00
RePixelatedMC
393cb362db - "Hey stop that! Its my World not yours."
- Safeguard displays itself before the worlds now.
- TODO: Minimize jar 7.5 MB > Under Spigots limit
2024-04-28 11:22:10 +02:00
RePixelatedMC
64e422036c Merge branch 'fix_jigsaw' of https://github.com/VolmitDev/Iris into PixelatedDev 2024-04-27 17:14:16 +02:00
RePixelatedMC
468e7ef018 Merge pull request #1094 from RePixelatedMC/master
Update README.md
2024-04-27 12:42:50 +02:00
RePixelatedMC
e3e4ecbc5c Update README.md 2024-04-27 12:41:29 +02:00
RePixelatedMC
545ffc0e9d splash cleanup 2024-04-27 12:36:41 +02:00
RePixelatedMC
8125c8d5f4 fixes 2024-04-27 12:18:28 +02:00
RePixelatedMC
304b01d0cf Merge pull request #13 from VolmitDev/mca
add hotload
2024-04-27 10:54:38 +02:00
CrazyDev22
a5f687fd76 fix ServerConfigurator 2024-04-26 18:14:40 +02:00
CrazyDev22
fc1761a55b add nms method to hotload Datapacks 2024-04-26 18:14:22 +02:00
RePixelatedMC
e7c9cad7f6 Merge pull request #1093 from RePixelatedMC/3.2.5
3.2.5
2024-04-26 18:06:37 +02:00
RePixelatedMC
979af82122 here crazy 2024-04-26 11:16:09 +02:00
RePixelatedMC
71a62b9c73 Merge pull request #12 from VolmitDev/mca
fix NMSBindings
2024-04-24 17:58:44 +02:00
CrazyDev22
bb020cab25 fix NMSBindings 2024-04-24 17:55:40 +02:00
RePixelatedMC
1ad35c1310 sync multiple mca fixes 2024-04-24 16:01:11 +02:00
CrazyDev22
6470b2f4a9 fix another null pointer 2024-04-23 13:49:30 +02:00
CrazyDev22
c1d5ba55cd fix null pointer 2024-04-23 13:49:10 +02:00
CrazyDev22
100e450514 fix jigsaw piece collision 2024-04-23 13:48:47 +02:00
RePixelatedMC
0f1d1d9860 Merge remote-tracking branch 'VolmitDev/fix_jigsaw' into PixelatedDev 2024-04-23 12:31:26 +02:00
RePixelatedMC
178a462a4e e 2024-04-23 12:29:19 +02:00
RePixelatedMC
8f4ae613f0 Merge branch '3.2.5' of https://github.com/RePixelatedMC/Iris into PixelatedDev
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/commands/CommandIris.java
2024-04-23 11:29:18 +02:00
RePixelatedMC
9e6963b6ce A lot of improvements thanks to CrazyDev! 2024-04-23 11:24:53 +02:00
CrazyDev22
cb9a73c60e rename IrisJigsawDistance to IrisJigsawMinDistance to avoid confusion 2024-04-23 10:28:04 +02:00
CrazyDev22
0e666a4c35 change rng noise for jigsaw component 2024-04-22 14:23:45 +02:00
CrazyDev22
c80138a354 Merge branch 'refs/heads/master' into fix_jigsaw 2024-04-22 14:14:48 +02:00
CrazyDev22
79a4ebcf65 woops 2024-04-19 15:29:28 +02:00
CrazyDev22
a7118aa785 fix jigsaw place command 2024-04-19 15:18:11 +02:00
RePixelatedMC
2555cd23a0 Merge branch 'VolmitSoftware:master' into 3.2.6 2024-04-19 15:17:21 +02:00
RePixelatedMC
484fbeca7b Merge branch '3.2.6' of https://github.com/RePixelatedMC/Iris into PixelatedDev
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/commands/CommandIris.java
#	core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java
2024-04-19 15:16:46 +02:00
RePixelatedMC
9a45e0df10 /iris support report ( gives server info )
and cleaned the main splash screen and fixed /iris import saying its loaded successfully even if it didnt
2024-04-19 15:15:08 +02:00
RePixelatedMC
9175296fc6 rev2.0 2024-04-19 12:43:57 +02:00
RePixelatedMC
5a4a86aeba - Iris Updater
Updates chunks thats it/
2024-04-19 10:14:16 +02:00
Brian Neumann-Fopiano
768fa7beb5 v+ 2024-04-19 02:47:02 -04:00
Julian Krings
6645eb9806 Merge branch 'VolmitSoftware:master' into fix_jigsaw 2024-04-18 16:04:30 +02:00
CrazyDev22
d7a283c99f fix underwater jigsaw placement 2024-04-18 16:00:47 +02:00
Brian Fopiano
8f019cd794 Merge pull request #1088 from RePixelatedMC/PixelatedDev
3.2.5 iris
2024-04-18 07:13:52 -04:00
CrazyDev22
c1d9cc62cb woops 2024-04-17 21:21:18 +02:00
Julian Krings
010a1e9e91 Merge branch 'VolmitSoftware:master' into fix_jigsaw 2024-04-17 21:16:08 +02:00
CrazyDev22
856c926cde add min distance to jigsaw structures 2024-04-17 21:15:15 +02:00
RePixelatedMC
72ed312654 wops 2024-04-16 18:09:03 +02:00
RePixelatedMC
c7fe4723f7 Merge remote-tracking branch 'origin/master' into PixelatedDev 2024-04-16 17:18:51 +02:00
RePixelatedMC
bfbea83a4a - Fixed NMS biome height.
- Improved /iris load
- Improved Vanilla height converter
- Removed WorldCreation unstable message
2024-04-16 17:18:02 +02:00
RePixelatedMC
55c58fe896 Merge pull request #1087 from RePixelatedMC/PixelatedDev
Should work
2024-04-16 16:34:12 +02:00
RePixelatedMC
72949e0950 Update IrisSettings.java 2024-04-16 16:32:52 +02:00
CrazyDev22
61c0ddb15b fix random jigsaw rotation and offset 2024-04-16 13:29:06 +02:00
Brian Neumann-Fopiano
9ac4024e4e v+ 2024-04-15 11:43:09 -04:00
RePixelatedMC
7fb2a51a33 sync 2024-04-12 17:08:13 +02:00
RePixelatedMC
5b7c0b2bc3 Merge branch 'PixelatedDev' of https://github.com/RePixelatedMC/Iris into PixelatedDev
# Conflicts:
#	core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java
#	core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java
2024-04-09 20:07:50 +02:00
RePixelatedMC
fc15175ff9 Improved? 2024-04-09 20:06:32 +02:00
RePixelatedMC
1eec3a09c1 now it should work 2024-04-09 18:05:27 +02:00
RePixelatedMC
60d349dd8b test 2024-04-09 17:05:43 +02:00
RePixelatedMC
0c8d144ffb Merge remote-tracking branch 'VolmitDev/smartHeight' into PixelatedDev 2024-04-09 17:04:45 +02:00
RePixelatedMC
b898f73a05 Fixed another potential mem leak
Added the base of smart320height
2024-04-09 17:04:32 +02:00
CrazyDev22
c2b9b0ba0e add smartVanillaHeight 2024-04-09 16:52:14 +02:00
RePixelatedMC
206a4e9057 Revert "sync laptop"
This reverts commit 63b8a935ae.
2024-04-06 17:07:14 +02:00
RePixelatedMC
83a0a7dd54 sync laptop 2024-04-06 17:06:06 +02:00
RePixelatedMC
63b8a935ae sync laptop 2024-04-05 18:43:30 +02:00
CrazyDev22
16affd11cc fix HMCLeaves leave decay 2024-04-04 23:46:14 +02:00
CrazyDev22
33b0dec9da fix ClassCastException when replacing to IrisBlockData 2024-04-04 23:45:25 +02:00
Brian Neumann-Fopiano
121a463788 v+
Woot
2024-04-03 03:03:32 -04:00
Julian Krings
3625e70948 Merge pull request #1085 from VolmitDev/impl_mmoitem
Impl MMOItems
2024-04-02 19:03:25 +02:00
CrazyDev22
3d90207172 make MMOItems getItemTypes synchronous to reduce lag 2024-04-02 12:03:00 +02:00
CrazyDev22
ca7dc19c81 make mmoitems item creation synchronous 2024-04-01 23:20:11 +02:00
CrazyDev22
d0f16dbbc4 fix using Type::toString instead of Type::getId for mmoitems 2024-04-01 23:18:41 +02:00
CrazyDev22
fd91c223b7 add unload debug tools 2024-04-01 22:08:28 +02:00
CrazyDev22
93690b766c implement MMOItemsDataProvider 2024-04-01 17:26:33 +02:00
CrazyDev22
cc4af9950b fix scanning for item provider instead of block provider to processUpdate 2024-04-01 17:26:10 +02:00
Brian Fopiano
a6281483dd Merge pull request #1084 from RePixelatedMC/PixelatedDev
Pixelated dev
2024-03-31 12:45:06 -04:00
RePixelatedMC
f587816b30 merges 2024-03-31 18:33:35 +02:00
RePixelatedMC
eea3c3ab0b Merge remote-tracking branch 'origin/master' into PixelatedDev
# Conflicts:
#	core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java
#	nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java
#	nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java
#	nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java
#	nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java
#	nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java
#	nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java
2024-03-31 18:25:26 +02:00
RePixelatedMC
ba68ab9e06 f 2024-03-31 17:58:47 +02:00
RePixelatedMC
eb94d97ea4 - Fixed caves breaksurface
- changes
2024-03-31 17:53:10 +02:00
Brian Neumann-Fopiano
04ad02719c d 2024-03-30 18:48:00 -04:00
Brian Fopiano
f68f25b92f Merge pull request #1083 from VolmitDev/fix_object_collision_check
fix object collision check
2024-03-30 17:51:40 -04:00
Brian Fopiano
767cca36c8 Merge pull request #1080 from svdgoor/no-camel-1-19-R3
Cancels Camel spawns on 1-19-R3
2024-03-30 17:50:44 -04:00
Brian Fopiano
b30172fe89 Merge pull request #1082 from VolmitDev/shut_up_spigot
Remove usage of System.out
2024-03-30 17:49:31 -04:00
CrazyDev22
b2934b0cc2 fix object collision check 2024-03-27 19:02:20 +01:00
RePixelatedMC
50686795d0 - Added /iris what region
- Sort of Fixed EngineStatus
- Added /iris hasAccess
- Added /iris irisworlds/worlds
- Added Some dev commands
- Redid / improved the mantle tectonic unload
- Convert still not working so ignore that
- Cleaned Iris of IrisPackBenchmarking.java im redoing it on second thought.
- Adjusted build.gradle
- Renamed some tectonic stuff
- Fixed Eta
- Fixed entities spawning inside blocks or at least it should.
- Lib update fixes all the iris titles/actionbars
- Cave spawning adjustments, now they get engine height if caveStartHeight is too large. <optional>
- Perhaps more?
2024-03-20 11:32:44 +01:00
CrazyDev22
5561a4dc2f fix wrong color bug 2024-03-20 08:46:56 +01:00
CrazyDev22
15b8780e17 remove usage of System.out 2024-03-20 08:44:00 +01:00
svdgoor
15c4d312cb Merge remote-tracking branch 'origin/master' 2024-03-18 17:29:02 +01:00
svdgoor
ccbea89253 prevent spawning camels on 1.19.R3 2024-03-18 17:28:08 +01:00
RePixelatedMC
7b1e666b3b - No studio tectonic clearing. 2024-03-18 11:22:35 +01:00
RePixelatedMC
8af212fca8 - Fixed entities spawning inside blocks or at least it should. 2024-03-17 17:55:08 +01:00
Brian Fopiano
352ee7a622 Merge pull request #1079 from VolmitDev/better_plugin_compat
Better plugin compat
2024-03-17 02:55:19 -04:00
Brian Fopiano
f26d0fac0b Merge pull request #1078 from VolmitDev/fix_v1_19_R3
Remove Cherry Grove from 1.19.4 biomes list
2024-03-17 02:55:03 -04:00
RePixelatedMC
9612fef2a4 - Added /iris what region
- Sort of Fixed EngineStatus
- Added /iris hasAccess
- Added /iris irisworlds/worlds
- Added Some dev commands
- Redid / improved the mantle tectonic unload
- Convert still not working so ignore that
- Cleaned Iris of IrisPackBenchmarking.java im redoing it on second thought.
- Adjusted build.gradle
- Renamed some tectonic stuff
- Perhaps more?
2024-03-16 12:40:40 +01:00
CrazyDev22
a691d49abc fix only the 0 0 chunk being updated 2024-03-08 19:35:07 +01:00
CrazyDev22
289eca35ec fix missing method parameter types 2024-03-07 19:41:28 +01:00
CrazyDev22
e9ca30257c woops 2024-03-07 18:48:09 +01:00
Julian Krings
6b21997baa Merge branch 'VolmitSoftware:master' into better_plugin_compat 2024-03-07 17:24:59 +01:00
CrazyDev22
6d3dbf84ef add HMCLeaves compatibility 2024-03-07 17:24:09 +01:00
CrazyDev22
eb45339c81 add oraxen furniture support 2024-03-07 17:23:32 +01:00
CrazyDev22
65e3fdd26c make implementing blocks that need world context possible 2024-03-07 17:23:00 +01:00
RePixelatedMC
34cad85942 - Fixed Eta 2024-03-01 12:32:53 +01:00
RePixelatedMC
e407679d2b - Improved eta calculation 2024-03-01 11:44:00 +01:00
Julian Krings
8a08a3e148 Remove Cherry Grove from 1.19.4 biomes list 2024-02-27 11:30:40 +01:00
Brian Fopiano
a01d27d273 Merge pull request #1075 from VolmitDev/fix_pregen
Fix Pregen oversight
2024-02-22 18:42:16 -05:00
Brian Fopiano
43f642ae8b Merge pull request #1076 from VolmitDev/custom-spawn-reason
Add implement custom spawn reason
2024-02-22 18:41:59 -05:00
CrazyDev22
93c1265de9 Add implement custom spawn reason 2024-02-22 21:25:37 +01:00
CrazyDev22
d08600fbaa Fix Pregen oversight 2024-02-22 17:27:38 +01:00
RePixelatedMC
fb9f8d28f4 - Lib update fixes all the iris titles/actionbars
- Iris .schem Converter
2024-02-21 21:24:35 +01:00
Brian Fopiano
cd3e9f772d Merge pull request #1074 from MoritzR200/master
Fixed file separators in '/iris import'
2024-02-17 09:54:59 -05:00
Brian Fopiano
7a95441799 Merge pull request #1071 from VolmitDev/fix_nullpointer
Fix nullpointer
2024-02-17 09:54:40 -05:00
Brian Fopiano
9345828c97 Merge pull request #1073 from RePixelatedMC/PixelatedDev
Fixes?
2024-02-17 09:54:14 -05:00
MoritzR200
58d88dd079 Fixed backslashes being used as file separators regardless of platform (in /iris import)). 2024-02-17 13:31:00 +01:00
RePixelatedMC
6cbc2374b3 whoopsies 2024-02-15 20:43:29 +01:00
RePixelatedMC
12bd11386d Merge remote-tracking branch 'CrazyDev/jigsaw_placement_fix' into PixelatedDev 2024-02-14 09:13:37 +01:00
RePixelatedMC
0497045388 - Fixed /Iris height when ran in console
- Added Dynamic worldHeight
2024-02-13 08:51:48 +01:00
Julian Krings
d3f1640855 Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2024-02-12 21:30:19 +01:00
CrazyDev22
960e2fcc61 try again if engine setup fails 2024-02-12 11:43:21 +01:00
CrazyDev22
6a012cf400 fix setup being set before engine setup 2024-02-12 11:42:47 +01:00
Brian Neumann-Fopiano
d658ec2099 oops 2024-02-04 17:37:00 -05:00
RePixelatedMC
c0136585e6 Merge remote-tracking branch 'origin/master' 2024-01-26 10:59:14 +01:00
Julian Krings
ccb7855d7d Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2024-01-20 15:10:05 +01:00
RePixelatedMC
bad547356c Disabled for now 2024-01-14 16:43:39 +01:00
RePixelatedMC
1740bb0021 whoop 2024-01-14 16:35:00 +01:00
RePixelatedMC
669ede5482 remove turbo for now 2024-01-14 10:18:41 +01:00
Julian Krings
27f8ad982a Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2023-12-31 19:15:39 +01:00
Julian Krings
387cf566c9 Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2023-12-30 11:25:33 +01:00
Julian Krings
683a90ed09 Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2023-12-23 20:52:13 +01:00
Julian Krings
d5f74631cd Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2023-12-23 18:37:59 +01:00
Julian Krings
3fe73af5e8 Merge branch 'VolmitSoftware:master' into jigsaw_placement_fix 2023-12-23 10:20:30 +01:00
Julian Krings
7263d102c7 cleanup / possibly fix a bug 2023-11-29 14:34:00 +01:00
Julian Krings
b098c210ce removed unnecessary code 2023-11-24 17:03:32 +01:00
Julian Krings
9843f18c96 Fix jigsaw piece collision/merging 2023-11-22 13:45:55 +01:00
118 changed files with 8012 additions and 3032 deletions

View File

@@ -31,7 +31,7 @@ Consider supporting our development by buying Iris on spigot! We work hard to ma
4. Use `CTRL + X`, then Press `Y`, Then `ENTER`
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.
Otherwise, skip this step. Grab a coffee, this may take up to 5 minutes depending on your cpu & internet connection.
Otherwise, skip this step. Grab a coffee, this may take up to 45 minutes depending on your cpu & internet connection.
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!
@@ -69,7 +69,6 @@ IrisAccess access=IrisToolbelt.createWorld() // If you like builders...
.name("myWorld") // The world name
.dimension("terrifyinghands")
.seed(69133742) // The world seed
.headless(true) // Headless make gen go fast
.pregen(PregenTask // Define a pregen job to run
.builder()
.center(new Position2(0,0)) // REGION coords (1 region = 32x32 chunks)

View File

@@ -1,5 +1,3 @@
import java.util.function.Consumer
/*
* Iris is a World Generator for Minecraft Bukkit Servers
* Copyright (c) 2021 Arcane Arts (Volmit Software)
@@ -18,15 +16,23 @@ import java.util.function.Consumer
* 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 {
id 'java'
id 'java-library'
id "com.github.johnrengelman.shadow" version "7.1.2"
id "io.github.goooler.shadow" version "8.1.7"
id "de.undercouch.download" version "5.0.1"
}
version '3.0.0-1.19.2-1.20.4'
def specialSourceVersion = '1.11.0' //[NMS]
version '3.4.0-1.19.2-1.21'
// ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED
// ======================== WINDOWS =============================
@@ -37,13 +43,16 @@ registerCustomOutputTask('Coco', 'D://mcsm/plugins')
registerCustomOutputTask('Strange', 'D://Servers/1.17 Test Server/plugins')
registerCustomOutputTask('Vatuu', 'D://Minecraft/Servers/1.19.4/plugins')
registerCustomOutputTask('CrazyDev22', 'C://Users/Julian/Desktop/server/plugins')
registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.1 - Iris Coding/plugins')
registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Development/plugins')
// ========================== UNIX ==============================
registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins')
registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins')
registerCustomOutputTaskUnix('PsychoLT', '/Users/brianfopiano/Developer/RemoteGit/Server/plugins')
registerCustomOutputTaskUnix('CrazyDev22LT', '/home/julian/Desktop/server/plugins')
// ==============================================================
def NMS_BINDINGS = Map.of(
"v1_21_R1", "1.21-R0.1-SNAPSHOT",
"v1_20_R4", "1.20.6-R0.1-SNAPSHOT",
"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",
@@ -51,137 +60,31 @@ def NMS_BINDINGS = Map.of(
"v1_19_R2", "1.19.3-R0.1-SNAPSHOT",
"v1_19_R1", "1.19.2-R0.1-SNAPSHOT"
)
NMS_BINDINGS.each {
def key = it.key
def value = it.value
def nms = value.split("-")[0];
project(":nms:${key}") {
apply plugin: 'java-library'
apply plugin: 'de.undercouch.download'
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 {
it.jvm = JVM_VERSION.getOrDefault(nms.key, 17)
it.version = nms.value
}
dependencies {
implementation project(":core")
compileOnly "org.spigotmc:spigot-api:${value}"
compileOnly "org.bukkit:craftbukkit:${value}:remapped-mojang" //[NMS]
}
def buildToolsJar = new File(rootProject.buildDir, "tools/BuildTools.jar")
def specialSourceJar = new File(rootProject.buildDir, "tools/SpecialSource.jar")
def buildToolsFolder = new File(buildDir, "buildtools")
def specialSourceFolder = new File(buildDir, "specialsource")
def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nms + ".jar")
def outputJar = new File(buildDir, "libs/${key}.jar")
def ssiJar = new File(buildDir, "specialsource/${key}.jar")
def ssobfJar = new File(buildDir, "specialsource/${key}-rmo.jar")
def ssJar = new File(buildDir, "specialsource/${key}-rma.jar")
def homePath = System.properties['user.home']
def m2 = new File(homePath + "/.m2/repository")
def m2s = m2.getAbsolutePath();
// ======================== Building Mapped Jars =============================
ext {
executeBuildTools = new Runnable() {
@Override
void run() {
//Download
if (!buildToolsJar.exists()) {
download.run {
src 'https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar'
dest buildToolsJar
}
}
//Execute
if (!buildToolsHint.exists()) {
buildToolsFolder.mkdirs()
project.javaexec {
classpath = files(buildToolsJar)
workingDir = buildToolsFolder
args = [
"--rev",
nms,
"--compile",
"craftbukkit",
"--remap"
]
}
}
}
}
}
tasks.register("executeBuildTools") {
doLast {
property("executeBuildTools").run();
}
}
tasks.build.doLast {
//Download
if (!specialSourceJar.exists()) {
download.run {
src 'https://repo.maven.apache.org/maven2/net/md-5/SpecialSource/' + specialSourceVersion + '/SpecialSource-'+specialSourceVersion+'-shaded.jar'
dest specialSourceJar
}
}
specialSourceFolder.mkdirs();
//Copy
copy {
from outputJar
into specialSourceFolder
}
//obfuscate
javaexec {
workingDir = specialSourceFolder
classpath = files(specialSourceJar,
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-mojang.jar"))
mainClass = "net.md_5.specialsource.SpecialSource"
args = [
"--live",
"-i",
ssiJar.getName(),
"-o",
ssobfJar.getName(),
"-m",
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-mojang.txt",
"--reverse",
]
}
//remap
javaexec {
workingDir = specialSourceFolder
classpath = files(specialSourceJar,
new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-obf.jar"))
mainClass = "net.md_5.specialsource.SpecialSource"
args = [
"--live",
"-i",
ssobfJar.getName(),
"-o",
ssJar.getName(),
"-m",
m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-spigot.csrg"
]
}
//copy
copy {
from ssJar
into outputJar.getParentFile()
rename {
outputJar.getName()
}
}
}
}
}
shadowJar {
NMS_BINDINGS.each {dependsOn(":nms:${it.key}:build")}
NMS_BINDINGS.each {
dependsOn(":nms:${it.key}:remap")
from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}-mapped.jar")
}
//minimize()
append("plugin.yml")
@@ -193,9 +96,6 @@ shadowJar {
dependencies {
implementation project(':core')
NMS_BINDINGS.each {
implementation project(":nms:${it.key}")
}
}
configurations.configureEach {
@@ -207,12 +107,6 @@ allprojects {
apply plugin: 'java'
repositories {
mavenLocal {
content {
includeGroup("org.bukkit")
includeGroup("org.spigotmc")
}
}
mavenCentral()
maven { url "https://repo.papermc.io/repository/maven-public/"}
maven { url "https://repo.codemc.org/repository/maven-public" }
@@ -224,6 +118,7 @@ allprojects {
maven { url "https://repo.triumphteam.dev/snapshots" }
maven { url "https://repo.mineinabyss.com/releases" }
maven { url 'https://hub.jeff-media.com/nexus/repository/jeff-media-public/' }
maven { url "https://repo.oraxen.com/releases" }
}
dependencies {
@@ -235,8 +130,10 @@ allprojects {
implementation 'com.dfsek:Paralithic:0.4.0'
implementation 'io.papermc:paperlib:1.0.5'
implementation "net.kyori:adventure-text-minimessage:4.13.1"
implementation 'net.kyori:adventure-platform-bukkit:4.3.0'
implementation 'net.kyori:adventure-platform-bukkit:4.3.2'
implementation 'net.kyori:adventure-api:4.13.1'
//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'
// Dynamically Loaded
@@ -244,9 +141,9 @@ allprojects {
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.9.0'
compileOnly 'com.google.code.gson:gson:2.10.1'
compileOnly 'org.ow2.asm:asm:9.2'
compileOnly 'com.google.guava:guava:31.1-jre'
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'
@@ -282,34 +179,11 @@ if (JavaVersion.current().toString() != "17") {
task iris(type: Copy) {
group "iris"
from new File(buildDir, "libs/Iris-${version}.jar")
into buildDir
from new File(layout.buildDirectory.asFile.get(), "libs/Iris-${version}.jar")
into layout.buildDirectory.asFile.get()
dependsOn(build)
}
task setup() {
group "iris"
dependsOn(clean)
NMS_BINDINGS.each {
dependsOn(":nms:${it.key}:clean");
}
doLast {
NMS_BINDINGS.each {
project(":nms:${it.key}").property("executeBuildTools").run();
}
}
}
NMS_BINDINGS.keySet().forEach {
def nms = it
tasks.register("setup-${nms}") {
group "iris"
dependsOn(":nms:${nms}:clean")
dependsOn(":nms:${nms}:executeBuildTools")
}
}
def registerCustomOutputTask(name, path) {
if (!System.properties['os.name'].toLowerCase().contains('windows')) {
return;

View File

@@ -19,7 +19,7 @@
plugins {
id 'java'
id 'java-library'
id "io.freefair.lombok" version "6.3.0"
id "io.freefair.lombok" version "8.6"
}
def apiVersion = '1.19'
@@ -33,6 +33,11 @@ compileJava {
options.encoding = "UTF-8"
}
repositories {
maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'}
maven { url 'https://repo.auxilor.io/repository/maven-public/' }
}
/**
* Dependencies.
*
@@ -57,10 +62,12 @@ dependencies {
// Third Party Integrations
compileOnly 'com.ticxo.playeranimator:PlayerAnimator:R1.2.7'
compileOnly 'com.github.oraxen:oraxen:1.158.0'
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')
}

View File

@@ -128,6 +128,10 @@ public class Iris extends VolmitPlugin implements Listener {
private KMap<Class<? extends IrisService>, IrisService> services;
public static VolmitSender getSender() {
if (sender == null) {
sender = new VolmitSender(Bukkit.getConsoleSender());
sender.setTag(instance.getTag());
}
return sender;
}
@@ -194,10 +198,10 @@ public class Iris extends VolmitPlugin implements Listener {
public static void msg(String string) {
try {
sender.sendMessage(string);
getSender().sendMessage(string);
} catch (Throwable e) {
try {
System.out.println(instance.getTag() + string.replaceAll("(<([^>]+)>)", ""));
instance.getLogger().info(instance.getTag() + string.replaceAll("(<([^>]+)>)", ""));
} catch (Throwable ignored1) {
}
@@ -364,6 +368,13 @@ public class Iris extends VolmitPlugin implements Listener {
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) {
if (IrisSettings.get().getGeneral().isDebug()) {
File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt");
@@ -426,7 +437,7 @@ public class Iris extends VolmitPlugin implements Listener {
}
pw.close();
System.out.println("DUMPED! See " + fi.getAbsolutePath());
Iris.info("DUMPED! See " + fi.getAbsolutePath());
} catch (Throwable e) {
e.printStackTrace();
}
@@ -446,14 +457,12 @@ public class Iris extends VolmitPlugin implements Listener {
private void enable() {
instance = this;
services = new KMap<>();
setupAudience();
initialize("com.volmit.iris.core.service").forEach((i) -> services.put((Class<? extends IrisService>) i.getClass(), (IrisService) i));
INMS.get();
IO.delete(new File("iris"));
setupAudience();
IrisSafeguard.IrisSafeguardSystem();
sender = new VolmitSender(Bukkit.getConsoleSender());
sender.setTag(getTag());
instance = this;
getSender().setTag(getTag());
compat = IrisCompat.configured(getDataFile("compat.json"));
linkMultiverseCore = new MultiverseCoreLink();
linkMythicMobs = new MythicMobsLink();
@@ -526,7 +535,7 @@ public class Iris extends VolmitPlugin implements Listener {
Iris.info("Starting up auto Studio!");
try {
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(() -> {
for (Player i : getServer().getOnlinePlayers()) {
i.setGameMode(GameMode.SPECTATOR);
@@ -727,10 +736,10 @@ public class Iris extends VolmitPlugin implements Listener {
File ff = new File(w.worldFolder(), "iris/pack");
if (!ff.exists() || ff.listFiles().length == 0) {
ff.mkdirs();
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), w.worldFolder());
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() {
@@ -797,13 +806,11 @@ public class Iris extends VolmitPlugin implements Listener {
} else {
splash = splashstable;
}
OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
String osArch = osBean.getArch();
String osName = osBean.getName();
if (!passedserversoftware) {
Iris.info("Server type & version: " + C.RED + Bukkit.getVersion());
} else { Iris.info("Server type & version: " + Bukkit.getVersion()); }
Iris.info("Java: " + getJava());
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..");
@@ -811,38 +818,11 @@ public class Iris extends VolmitPlugin implements Listener {
Iris.info(C.YELLOW + "Purpur is recommended to use with iris.");
}
}
Iris.info("Server OS: " + osName + " (" + osArch + ")");
try {
if (warningmode){
Iris.info("Server Cpu: " + C.GOLD + getCPUModel());
} else {
if(unstablemode){
Iris.info("Server Cpu: " + C.DARK_RED + getCPUModel());
} else {
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("Process Threads: " + Runtime.getRuntime().availableProcessors());
Iris.info("Process Memory: " + getHardware.getProcessMemory() + " MB");
Iris.info("Free DiskSpace: " + Form.ofSize(freeSpace.getFreeSpace(), 1024));
if (getHardware.getProcessMemory() < 5999) {
Iris.warn("6GB+ Ram is recommended");
Iris.warn("Process Memory: " + getHardware.getProcessMemory() + " MB");
}
Iris.info("Bukkit version: " + Bukkit.getBukkitVersion());
Iris.info("Java version: " + getJavaVersion());
Iris.info("Bukkit distro: " + Bukkit.getName());
Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes());
setupChecks();
printPacks();

View File

@@ -24,6 +24,7 @@ import com.volmit.iris.util.io.IO;
import com.volmit.iris.util.json.JSONException;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.ChronoLatch;
import lombok.Data;
import java.io.File;
@@ -135,7 +136,7 @@ public class IrisSettings {
@Data
public static class IrisSettingsPerformance {
public boolean trimMantleInStudio = false;
public boolean trimMantleInStudio = false;
public int mantleKeepAlive = 30;
public int cacheSize = 4_096;
public int resourceLoaderCacheSize = 1_024;
@@ -145,7 +146,7 @@ public class IrisSettings {
@Data
public static class IrisSettingsGeneral {
public boolean ignoreBootMode = false;
public boolean DoomsdayAnnihilationSelfDestructMode = false;
public boolean commandSounds = true;
public boolean debug = false;
public boolean disableNMS = false;

View File

@@ -21,9 +21,12 @@ package com.volmit.iris.core;
import com.volmit.iris.Iris;
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.nms.datapack.IDataFixer;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisBiomeCustom;
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.KSet;
import com.volmit.iris.util.format.C;
@@ -90,10 +93,36 @@ public class ServerConfigurator {
return worlds;
}
public static void installDataPacks(boolean fullInstall) {
installDataPacks(DataVersion.getDefault(), fullInstall);
}
public static void installDataPacks(IDataFixer fixer, boolean fullInstall) {
Iris.info("Checking Data 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()) {
for (File i : packs.listFiles()) {
@@ -113,7 +142,7 @@ public class ServerConfigurator {
Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath());
for (File dpack : getDatapacksFolder()) {
dim.installDataPack(() -> data, dpack);
dim.installDataPack(fixer, () -> data, dpack, ultimateMaxHeight, ultimateMinHeight);
}
}
}

View File

@@ -74,7 +74,7 @@ public class CommandDeepSearch implements DecreeExecutor {
}
DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder()
.world(worldName)
.world(world)
.radiusBlocks(radius)
.position(0)
.build();

View File

@@ -19,10 +19,22 @@
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.nms.v1X.NMSBinding1X;
import com.volmit.iris.core.pregenerator.ChunkUpdater;
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.engine.framework.Engine;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IrisBiome;
import com.volmit.iris.engine.object.IrisCave;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisEntity;
import com.volmit.iris.util.data.Dimension;
import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin;
import com.volmit.iris.util.decree.annotations.Decree;
@@ -31,56 +43,183 @@ 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.math.Spiraler;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
import com.volmit.iris.util.plugin.VolmitSender;
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
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.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EntityType;
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 CommandTurboPregen turboPregen;
private CommandUpdater updater;
@Decree(description = "Get Loaded TectonicPlates Count", origin = DecreeOrigin.BOTH, sync = true)
public void EngineStatus(
@Param(description = "World")
World world
) {
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;
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
}
}
Engine engine = IrisToolbelt.access(world).getEngine();
if(engine != null) {
long lastUseSize = engine.getMantle().getLastUseMapMemoryUsage();
Iris.info("-------------------------");
Iris.info(C.DARK_PURPLE + "Engine Status");
Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit());
Iris.info(C.DARK_PURPLE + "Tectonic Loaded Plates: " + C.LIGHT_PURPLE + engine.getMantle().getLoadedRegionCount());
Iris.info(C.DARK_PURPLE + "Tectonic Plates: " + C.LIGHT_PURPLE + engine.getMantle().getNotClearedLoadedRegions());
Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + engine.getMantle().getToUnload());
Iris.info(C.DARK_PURPLE + "Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration((long) engine.getMantle().getTectonicDuration()));
Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize()));
Iris.info(C.DARK_PURPLE + "LastUse Size: " + C.LIGHT_PURPLE + Form.mem(lastUseSize));
Iris.info("-------------------------");
} else {
Iris.info(C.RED + "Engine is null!");
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", origin = DecreeOrigin.BOTH)
public void test() {
Iris.info("Test Developer CMD Executed");
@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 = "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);
}
} 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(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")

View File

@@ -20,21 +20,27 @@ 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;
@@ -49,8 +55,10 @@ 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;
@@ -59,6 +67,7 @@ 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 {
@@ -71,11 +80,9 @@ public class CommandIris implements DecreeExecutor {
private CommandWhat what;
private CommandEdit edit;
private CommandFind find;
private CommandSupport support;
private CommandDeveloper developer;
public static @Getter String BenchDimension;
public static boolean worldCreation = false;
String WorldToLoad;
String WorldEngine;
String worldNameToCheck = "YourWorldName";
VolmitSender sender = Iris.getSender();
@@ -87,7 +94,9 @@ public class CommandIris implements DecreeExecutor {
@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
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")) {
@@ -131,6 +140,7 @@ public class CommandIris implements DecreeExecutor {
.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.");
@@ -184,7 +194,7 @@ public class CommandIris implements DecreeExecutor {
}
/*
/todo Fix PREGEN
/todo
@Decree(description = "Benchmark a pack", origin = DecreeOrigin.CONSOLE)
public void packbenchmark(
@Param(description = "Dimension to benchmark")
@@ -196,28 +206,16 @@ public class CommandIris implements DecreeExecutor {
IrisPackBenchmarking.runBenchmark();
} */
/* /todo Different approach this feels useless atm
@Decree(description = "Check for instabilities", origin = DecreeOrigin.CONSOLE)
public void fixunstable() throws InterruptedException {
if (unstablemode){
sender().sendMessage(C.RED + "Incompatibilities are posted in console..");
Iris.info(C.RED + "Your server is experiencing an incompatibility with the Iris plugin.");
Iris.info(C.RED + "Please rectify this problem to avoid further complications.");
Iris.info(C.RED + "----------------------------------------------------------------");
Iris.info(C.RED + "Command ran: /iris fixunstable");
UtilsSFG.printIncompatibleWarnings();
Iris.info(C.RED + "----------------------------------------------------------------");
} else {
Iris.info(C.BLUE + "Iris is running stable..");
sender().sendMessage("Iris is running stable..");
}
} */
@Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER)
public void height() {
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()));
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)
@@ -226,6 +224,44 @@ public class CommandIris implements DecreeExecutor {
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")
@@ -234,7 +270,7 @@ public class CommandIris implements DecreeExecutor {
boolean delete
) {
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()));
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());
@@ -286,6 +322,24 @@ public class CommandIris implements DecreeExecutor {
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")
@@ -417,7 +471,7 @@ public class CommandIris implements DecreeExecutor {
World world
) {
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()));
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());
@@ -445,9 +499,9 @@ public class CommandIris implements DecreeExecutor {
sender().sendMessage(C.YELLOW + world + " Doesnt exist on the server.");
return;
}
WorldToLoad = world;
File BUKKIT_YML = new File("bukkit.yml");
String pathtodim = world + "\\iris\\pack\\dimensions\\";
String pathtodim = world + File.separator +"iris"+File.separator +"pack"+File.separator +"dimensions"+File.separator;
File directory = new File(Bukkit.getWorldContainer(), pathtodim);
String dimension = null;
@@ -481,9 +535,10 @@ public class CommandIris implements DecreeExecutor {
} catch (IOException e) {
Iris.error("Failed to update bukkit.yml!");
e.printStackTrace();
return;
}
}
checkForBukkitWorlds();
checkForBukkitWorlds(world);
sender().sendMessage(C.GREEN + world + " loaded successfully.");
}
@Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true)
@@ -492,7 +547,7 @@ public class CommandIris implements DecreeExecutor {
World world
) {
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()));
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());
@@ -504,7 +559,7 @@ public class CommandIris implements DecreeExecutor {
File worldDirectory = new File(worldContainer, worldName);
return worldDirectory.exists() && worldDirectory.isDirectory();
}
private void checkForBukkitWorlds() {
private void checkForBukkitWorlds(String world) {
FileConfiguration fc = new YamlConfiguration();
try {
fc.load(new File("bukkit.yml"));
@@ -513,9 +568,9 @@ public class CommandIris implements DecreeExecutor {
return;
}
List<String> worldsToLoad = Collections.singletonList(WorldToLoad);
List<String> worldsToLoad = Collections.singletonList(world);
for (String s : section.getKeys(false)) {
for (String s : section.getKeys(false)) {
if (!worldsToLoad.contains(s)) {
continue;
}
@@ -594,6 +649,6 @@ public class CommandIris implements DecreeExecutor {
ff.mkdirs();
service(StudioSVC.class).installIntoWorld(sender, dim.getLoadKey(), ff.getParentFile());
}
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey());
return new BukkitChunkGenerator(w, false, ff, dim.getLoadKey(), false);
}
}

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.core.commands;
import com.volmit.iris.Iris;
import com.volmit.iris.core.edit.JigsawEditor;
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.object.IrisJigsawPiece;
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.Form;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import java.io.File;
@@ -55,9 +57,16 @@ public class CommandJigsaw implements DecreeExecutor {
IrisJigsawStructure structure
) {
PrecisionStopwatch p = PrecisionStopwatch.start();
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation()), new RNG());
sender().sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2));
ps.place(world());
try {
var world = world();
WorldObjectPlacer placer = new WorldObjectPlacer(world);
PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation().add(0, world.getMinHeight(), 0)), new RNG());
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")

View File

@@ -35,6 +35,7 @@ import com.volmit.iris.util.decree.specialhandlers.ObjectHandler;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.Direction;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.misc.E;
import com.volmit.iris.util.scheduling.Queue;
import org.bukkit.*;
import org.bukkit.block.Block;
@@ -52,7 +53,7 @@ import java.util.*;
@Decree(name = "object", aliases = "o", origin = DecreeOrigin.PLAYER, studio = true, description = "Iris object manipulation")
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);
public static IObjectPlacer createPlacer(World world, Map<Block, BlockData> futureBlockChanges) {
@@ -197,6 +198,20 @@ 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 = "Get a powder that reveals objects", studio = true, aliases = "d")
public void dust() {
player().getInventory().addItem(WandSVC.createDust());

View File

@@ -56,6 +56,7 @@ public class CommandPregen implements DecreeExecutor {
IrisToolbelt.pregenerate(PregenTask
.builder()
.center(new Position2(center.getBlockX() >> 9, center.getBlockZ() >> 9))
.gui(true)
.width(w)
.height(w)
.build(), world);

View File

@@ -26,6 +26,7 @@ import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.project.IrisProject;
import com.volmit.iris.core.service.ConversionSVC;
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.engine.framework.Engine;
import com.volmit.iris.engine.object.*;
@@ -73,6 +74,7 @@ import java.nio.file.Files;
import java.nio.file.attribute.FileTime;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
@@ -84,7 +86,7 @@ import java.util.function.Supplier;
public class CommandStudio implements DecreeExecutor {
private CommandFind find;
private CommandEdit edit;
private CommandDeepSearch deepSearch;
//private CommandDeepSearch deepSearch;
public static String hrf(Duration duration) {
return duration.toString().substring(2).replaceAll("(\\d[HMS])(?!$)", "$1 ").toLowerCase();
@@ -229,9 +231,9 @@ public class CommandStudio implements DecreeExecutor {
@Decree(description = "Convert objects in the \"convert\" folder")
public void convert() {
Iris.service(ConversionSVC.class).check(sender());
//IrisConverter.convertSchematics(sender());
}
@Decree(description = "Execute a script", aliases = "run", origin = DecreeOrigin.PLAYER)
public void execute(
@Param(description = "The script to run")
@@ -331,6 +333,63 @@ public class CommandStudio implements DecreeExecutor {
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") 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();
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));
}
})).setOffset(loc.getBlockX(), loc.getBlockZ()).drain();
executor.complete();
multiBurst.close();
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")
public void map(
@Param(name = "world", description = "The world to open the generator for", contextual = true)

View File

@@ -0,0 +1,82 @@
/*
* 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.loader.IrisData;
import com.volmit.iris.core.pregenerator.ChunkUpdater;
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.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension;
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.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.misc.Hastebin;
import com.volmit.iris.util.misc.Platform;
import com.volmit.iris.util.misc.getHardware;
import com.volmit.iris.util.nbt.mca.MCAFile;
import com.volmit.iris.util.nbt.mca.MCAUtil;
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.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
import oshi.SystemInfo;
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.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
@Decree(name = "Support", origin = DecreeOrigin.BOTH, description = "Iris World Manager", aliases = {"support"})
public class CommandSupport implements DecreeExecutor {
@Decree(description = "report")
public void report() {
try {
if (sender().isPlayer()) sender().sendMessage(C.GOLD + "Creating report..");
if (!sender().isPlayer()) Iris.info(C.GOLD + "Creating report..");
Hastebin.enviornment(sender());
} catch (Exception e) {
Iris.info(C.RED + "Something went wrong: ");
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,107 @@
/*
* 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;
}
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(
@Param(description = "World to pause the Updater at")
World world
) {
if (!IrisToolbelt.isIrisWorld(world)) {
sender().sendMessage(C.GOLD + "This is not an Iris world");
return;
}
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 + world.getName());
} else {
sender().sendMessage(C.IRIS + "Unpause task for: " + C.GRAY + world.getName());
}
} else {
if (status) {
Iris.info(C.IRIS + "Paused task for: " + C.GRAY + world.getName());
} else {
Iris.info(C.IRIS + "Unpause task for: " + C.GRAY + world.getName());
}
}
}
@Decree(description = "Stops the updater")
public void stop(
@Param(description = "World to stop the Updater at")
World world
) {
if (!IrisToolbelt.isIrisWorld(world)) {
sender().sendMessage(C.GOLD + "This is not an Iris world");
return;
}
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 + world.getName());
} else {
Iris.info("Stopping Updater for: " + C.GRAY + world.getName());
}
chunkUpdater.stop();
}
}

View File

@@ -22,7 +22,9 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.edit.BlockSignal;
import com.volmit.iris.core.nms.INMS;
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.IrisRegion;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.decree.DecreeExecutor;
import com.volmit.iris.util.decree.DecreeOrigin;
@@ -37,6 +39,7 @@ import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@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)
public void block() {
BlockData bd;
@@ -147,7 +163,7 @@ public class CommandWhat implements DecreeExecutor {
sender().sendMessage("Found " + v.get() + " Nearby Markers (" + marker + ")");
} else {
sender().sendMessage("Iris worlds only.");
sender().sendMessage(C.IRIS + "Iris worlds only.");
}
}
}

View File

@@ -24,6 +24,7 @@ import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.PregenListener;
import com.volmit.iris.core.pregenerator.PregenTask;
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.util.collection.KList;
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.function.Consumer;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmarkInProgress;
public class PregeneratorJob implements PregenListener {
private static final Color COLOR_EXISTS = parseColor("#4d7d5b");
private static final Color COLOR_BLACK = parseColor("#4d7d5b");
@@ -86,7 +89,7 @@ public class PregeneratorJob implements PregenListener {
max.setZ(Math.max((zz << 5) + 31, max.getZ()));
});
if (IrisSettings.get().getGui().isUseServerLaunchedGuis()) {
if (IrisSettings.get().getGui().isUseServerLaunchedGuis() && task.isGui()) {
open();
}

View File

@@ -55,10 +55,10 @@ public class IrisRenderer {
IrisBiome b = renderer.getBiome((int) Math.round(x), renderer.getMaxHeight() - 1, (int) Math.round(z));
IrisBiomeGeneratorLink g = b.getGenerators().get(0);
Color c;
if (g.getMax() <= 0) {
if (g.getMax(renderer) <= 0) {
// Max is below water level, so it is most likely an ocean biome
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
c = Color.YELLOW;
} else {

View File

@@ -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;
}
}

View File

@@ -3,6 +3,7 @@ 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;
@@ -20,12 +21,12 @@ public class ExecutableItemsDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
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) throws MissingResourceException {
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()));

View File

@@ -1,8 +1,11 @@
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.RequiredArgsConstructor;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
@@ -25,9 +28,19 @@ public abstract class ExternalDataProvider {
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();

View File

@@ -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());
}
}

View File

@@ -6,6 +6,10 @@ public record Identifier(String namespace, String key) {
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) {
String[] strings = id.split(":", 2);
if (strings.length == 1) {

View File

@@ -2,6 +2,7 @@ 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 dev.lone.itemsadder.api.CustomBlock;
import dev.lone.itemsadder.api.CustomStack;
import org.bukkit.block.data.BlockData;
@@ -32,12 +33,12 @@ public class ItemAdderDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
return CustomBlock.getBaseBlockData(blockId.toString());
}
@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());
if (stack == null) {
throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key());

View File

@@ -0,0 +1,128 @@
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.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 = customNbt.containsKey("level") ? (int) customNbt.get("level") : -1;
var 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;
}
}

View File

@@ -19,25 +19,45 @@
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 com.volmit.iris.util.reflect.WrappedField;
import io.th0rgal.oraxen.api.OraxenItems;
import io.th0rgal.oraxen.items.ItemBuilder;
import io.th0rgal.oraxen.mechanics.Mechanic;
import io.th0rgal.oraxen.mechanics.MechanicFactory;
import io.th0rgal.oraxen.mechanics.MechanicsManager;
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.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.stringblock.StringBlockMechanicFactory;
import org.bukkit.Bukkit;
import org.bukkit.Color;
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.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.meta.PotionMeta;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Optional;
import java.util.function.Consumer;
public class OraxenDataProvider extends ExternalDataProvider {
@@ -59,7 +79,7 @@ public class OraxenDataProvider extends ExternalDataProvider {
}
@Override
public BlockData getBlockData(Identifier blockId) throws MissingResourceException {
public BlockData getBlockData(Identifier blockId, KMap<String, String> state) throws MissingResourceException {
MechanicFactory factory = getFactory(blockId);
if (factory instanceof NoteBlockMechanicFactory f)
return f.createNoteBlockData(blockId.key());
@@ -69,16 +89,75 @@ public class OraxenDataProvider extends ExternalDataProvider {
return newBlockData;
} else if (factory instanceof StringBlockMechanicFactory f) {
return f.createTripwireData(blockId.key());
} else if (factory instanceof FurnitureFactory) {
return new IrisBlockData(B.getAir(), ExternalDataSVC.buildState(blockId, state));
} else
throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key());
}
@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());
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
public Identifier[] getBlockTypes() {
KList<Identifier> names = new KList<>();

View File

@@ -1,12 +1,19 @@
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 Boolean enabled = null;
private static final AtomicCache<Boolean> active = new AtomicCache<>();
public static Cuboid getSelection(Player p) {
if (!hasWorldEdit())
@@ -15,29 +22,38 @@ public class WorldEditLink {
try {
Object instance = Class.forName("com.sk89q.worldedit.WorldEdit").getDeclaredMethod("getInstance").invoke(null);
Object sessionManager = instance.getClass().getDeclaredMethod("getSessionManager").invoke(instance);
Object player = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter").getDeclaredMethod("adapt", Player.class).invoke(null, p);
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);
Object world = Class.forName("com.sk89q.worldedit.bukkit.BukkitAdapter").getDeclaredMethod("adapt", World.class).invoke(null, p.getWorld());
Object region = localSession.getClass().getDeclaredMethod("getSelection", world.getClass()).invoke(localSession, world);
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("getX").invoke(min),
(int) min.getClass().getDeclaredMethod("getY").invoke(min),
(int) min.getClass().getDeclaredMethod("getZ").invoke(min),
(int) min.getClass().getDeclaredMethod("getX").invoke(max),
(int) min.getClass().getDeclaredMethod("getY").invoke(max),
(int) min.getClass().getDeclaredMethod("getZ").invoke(max)
(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 ignored) {
} catch (Throwable e) {
Iris.error("Could not get selection");
e.printStackTrace();
active.reset();
active.aquire(() -> false);
}
return null;
}
public static boolean hasWorldEdit() {
if (enabled == null)
enabled = Bukkit.getPluginManager().isPluginEnabled("WorldEdit");
return enabled;
return active.aquire(() -> Bukkit.getPluginManager().isPluginEnabled("WorldEdit"));
}
}

View File

@@ -362,7 +362,12 @@ public class ResourceLoader<T extends IrisRegistrant> implements MeteredCache {
if (folderCache.get() == null) {
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.getName().equals(folderName)) {
fc.add(i);

View File

@@ -23,7 +23,14 @@ import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.nms.v1X.NMSBinding1X;
import org.bukkit.Bukkit;
import java.util.Map;
public class INMS {
private static final Map<String, String> REVISION = Map.of(
"1.20.5", "v1_20_R4",
"1.20.6", "v1_20_R4",
"1.21", "v1_21_R1"
);
//@done
private static final INMSBinding binding = bind();
@@ -37,7 +44,12 @@ public class INMS {
}
try {
return Bukkit.getServer().getClass().getCanonicalName().split("\\Q.\\E")[3];
String name = Bukkit.getServer().getClass().getCanonicalName();
if (name.equals("org.bukkit.craftbukkit.CraftServer")) {
return REVISION.getOrDefault(Bukkit.getServer().getBukkitVersion().split("-")[0], "BUKKIT");
} else {
return name.split("\\Q.\\E")[3];
}
} catch (Throwable e) {
Iris.reportError(e);
Iris.error("Failed to determine server nms version!");

View File

@@ -18,10 +18,13 @@
package com.volmit.iris.core.nms;
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.math.Vector3d;
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
import com.volmit.iris.util.nbt.tag.CompoundTag;
@@ -32,9 +35,13 @@ import org.bukkit.WorldCreator;
import org.bukkit.block.Biome;
import org.bukkit.entity.Dolphin;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import java.awt.*;
public interface INMSBinding {
boolean hasTile(Location l);
@@ -103,4 +110,14 @@ public interface INMSBinding {
void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos);
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;
}
}

View File

@@ -0,0 +1,10 @@
package com.volmit.iris.core.nms.container;
public enum BiomeColor {
FOG,
WATER,
WATER_FOG,
SKY,
FOLIAGE,
GRASS
}

View File

@@ -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];
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -20,11 +20,13 @@ package com.volmit.iris.core.nms.v1X;
import com.volmit.iris.Iris;
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.math.Vector3d;
import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer;
import com.volmit.iris.util.nbt.mca.palette.MCAPaletteAccess;
import com.volmit.iris.util.nbt.tag.CompoundTag;
@@ -34,9 +36,13 @@ import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.entity.Dolphin;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.inventory.ItemStack;
import java.awt.*;
public class NMSBinding1X implements INMSBinding {
private static final boolean supportsCustomHeight = testCustomHeight();
@@ -85,6 +91,20 @@ public class NMSBinding1X implements INMSBinding {
}
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 void deserializeTile(CompoundTag s, Location newPosition) {
@@ -203,6 +223,11 @@ public class NMSBinding1X implements INMSBinding {
}
@Override
public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) {
return null;
}
@Override
public MCAPaletteAccess createPalette() {
Iris.error("Cannot use the global data palette! Iris is incapable of using MCA generation on this version of minecraft!");

View File

@@ -0,0 +1,318 @@
package com.volmit.iris.core.pregenerator;
import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt;
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.format.Form;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.math.Spiraler;
import com.volmit.iris.util.scheduling.J;
import io.papermc.lib.PaperLib;
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 AtomicBoolean paused;
private AtomicBoolean cancelled;
private KMap<Chunk, Long> lastUse;
private final RollingSequence chunksPerSecond;
private final AtomicInteger worldheightsize;
private final AtomicInteger worldwidthsize;
private final AtomicInteger totalChunks;
private final AtomicInteger totalMaxChunks;
private final AtomicInteger totalMcaregions;
private final AtomicInteger position;
private AtomicInteger chunksProcessed;
private AtomicInteger chunksUpdated;
private AtomicLong startTime;
private ExecutorService executor;
private ExecutorService chunkExecutor;
private ScheduledExecutorService scheduler;
private CompletableFuture future;
private CountDownLatch latch;
private final Object pauseLock;
private final Engine engine;
private final World world;
public ChunkUpdater(World world) {
this.engine = IrisToolbelt.access(world).getEngine();
this.chunksPerSecond = new RollingSequence(5);
this.world = world;
this.lastUse = new KMap();
this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1));
this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0));
int m = Math.max(worldheightsize.get(), worldwidthsize.get());
this.executor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors() / 3, 1));
this.chunkExecutor = Executors.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors() / 3, 1));
this.scheduler = Executors.newScheduledThreadPool(1);
this.future = new CompletableFuture<>();
this.startTime = new AtomicLong();
this.worldheightsize.set(m);
this.worldwidthsize.set(m);
this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16) * (worldwidthsize.get() / 16));
this.chunksProcessed = new AtomicInteger();
this.chunksUpdated = new AtomicInteger();
this.position = new AtomicInteger(0);
this.latch = new CountDownLatch(totalMaxChunks.get());
this.paused = new AtomicBoolean(false);
this.pauseLock = new Object();
this.cancelled = new AtomicBoolean(false);
this.totalChunks = new AtomicInteger(0);
this.totalMcaregions = new AtomicInteger(0);
}
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();
long elapsedSeconds = (System.currentTimeMillis() - startTime.get()) / 1000;
int processed = chunksProcessed.get();
double cps = elapsedSeconds > 0 ? processed / (double) elapsedSeconds : 0;
chunksPerSecond.put(cps);
double percentage = ((double) chunksProcessed.get() / (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);
CompletableFuture.runAsync(() -> {
for (int i = 0; i < totalMaxChunks.get(); i++) {
if (paused.get()) {
synchronized (pauseLock) {
try {
pauseLock.wait();
} catch (InterruptedException e) {
Iris.error("Interrupted while waiting for executor: ");
e.printStackTrace();
break;
}
}
}
executor.submit(() -> {
if (!cancelled.get()) {
processNextChunk();
}
latch.countDown();
});
}
}).thenRun(() -> {
try {
latch.await();
close();
} catch (Exception e) {
Thread.currentThread().interrupt();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public void close() {
try {
unloadAndSaveAllChunks();
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
chunkExecutor.shutdown();
chunkExecutor.awaitTermination(5, TimeUnit.SECONDS);
scheduler.shutdownNow();
} 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 processNextChunk() {
int pos = position.getAndIncrement();
int[] coords = getChunk(pos);
if (loadChunksIfGenerated(coords[0], coords[1])) {
Chunk c = world.getChunkAt(coords[0], coords[1]);
engine.updateChunk(c);
chunksUpdated.incrementAndGet();
}
chunksProcessed.getAndIncrement();
}
private boolean loadChunksIfGenerated(int x, int z) {
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);
KList<Future<?>> futures = new KList<>(9);
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
int xx = x + dx;
int zz = z + dz;
futures.add(chunkExecutor.submit(() -> {
Chunk c;
try {
c = PaperLib.getChunkAtAsync(world, xx, zz, false).get();
} catch (InterruptedException | ExecutionException e) {
generated.set(false);
return;
}
if (!c.isLoaded()) {
CountDownLatch latch = new CountDownLatch(1);
J.s(() -> {
c.load(false);
latch.countDown();
});
try {
latch.await();
} catch (InterruptedException ignored) {}
}
if (!c.isGenerated()) {
generated.set(false);
}
lastUse.put(c, M.ms());
}));
}
}
while (!futures.isEmpty()) {
futures.removeIf(Future::isDone);
try {
Thread.sleep(50);
} catch (InterruptedException ignored) {}
}
return generated.get();
}
private void unloadAndSaveAllChunks() {
try {
J.sfut(() -> {
if (world == null) {
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 >= 5000) {
i.unload();
lastUse.remove(i);
}
}
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
);
}
public int calculateWorldDimensions(File regionDir, Integer o) {
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]);
if (x < minX) minX = x;
if (x > maxX) maxX = x;
if (z < minZ) minZ = z;
if (z > maxZ) maxZ = z;
}
int height = (maxX - minX + 1) * 32 * 16;
int width = (maxZ - minZ + 1) * 32 * 16;
if (o == 1) {
return height;
}
if (o == 0) {
return width;
}
return 0;
}
public int[] getChunk(int position) {
int p = -1;
AtomicInteger xx = new AtomicInteger();
AtomicInteger zz = new AtomicInteger();
Spiraler s = new Spiraler(worldheightsize.get() * 2, worldwidthsize.get() * 2, (x, z) -> {
xx.set(x);
zz.set(z);
});
while (s.hasNext() && p++ < position) {
s.next();
}
int[] coords = new int[2];
coords[0] = xx.get();
coords[1] = zz.get();
return coords;
}
}

View File

@@ -5,18 +5,16 @@ import com.volmit.iris.Iris;
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.util.collection.KList;
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.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.math.Spiraler;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import io.papermc.lib.PaperLib;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
@@ -33,7 +31,6 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
@@ -56,10 +53,12 @@ public class DeepSearchPregenerator extends Thread implements Listener {
private final RollingSequence chunksPerMinute;
private final AtomicInteger chunkCachePos;
private final AtomicInteger chunkCacheSize;
private int pos;
private final AtomicInteger foundCacheLast;
private final AtomicInteger foundCache;
private LinkedHashMap<Integer, Position2> chunkCache;
private final ReentrantLock cacheLock = new ReentrantLock();
private KList<Position2> chunkQueue;
private final ReentrantLock cacheLock;
private static final Map<String, DeepSearchJob> jobs = new HashMap<>();
@@ -69,11 +68,13 @@ public class DeepSearchPregenerator extends Thread implements Listener {
this.chunkCachePos = new AtomicInteger(1000);
this.foundCacheLast = new AtomicInteger();
this.foundCache = new AtomicInteger();
this.cacheLock = new ReentrantLock();
this.destination = destination;
this.chunkCache = new LinkedHashMap();
this.chunkCache = new LinkedHashMap<>();
this.maxPosition = new Spiraler(job.getRadiusBlocks() * 2, job.getRadiusBlocks() * 2, (x, z) -> {
}).count();
this.world = Bukkit.getWorld(job.getWorld());
this.world = Bukkit.getWorld(job.getWorld().getUID());
this.chunkQueue = new KList<>();
this.latch = new ChronoLatch(3000);
this.startTime = new AtomicLong(M.ms());
this.chunksPerSecond = new RollingSequence(10);
@@ -81,7 +82,9 @@ public class DeepSearchPregenerator extends Thread implements Listener {
foundChunks = new AtomicInteger(0);
this.foundLast = new AtomicInteger(0);
this.foundTotalChunks = new AtomicInteger((int) Math.ceil(Math.pow((2.0 * job.getRadiusBlocks()) / 16, 2)));
jobs.put(job.getWorld(), job);
this.pos = 0;
jobs.put(job.getWorld().getName(), job);
DeepSearchPregenerator.instance = this;
}
@@ -108,29 +111,22 @@ public class DeepSearchPregenerator extends Thread implements Listener {
// chunkCache(); //todo finish this
if (latch.flip() && !job.paused) {
if (cacheLock.isLocked()) {
Iris.info("DeepFinder: Caching: " + chunkCachePos.get() + " Of " + chunkCacheSize.get());
} else {
long eta = computeETA();
save();
int secondGenerated = foundChunks.get() - foundLast.get();
foundLast.set(foundChunks.get());
secondGenerated = secondGenerated / 3;
chunksPerSecond.put(secondGenerated);
chunksPerMinute.put(secondGenerated * 60);
Iris.info("DeepFinder: " + C.IRIS + world.getName() + C.RESET + " Searching: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
}
long eta = computeETA();
save();
int secondGenerated = foundChunks.get() - foundLast.get();
foundLast.set(foundChunks.get());
secondGenerated = secondGenerated / 3;
chunksPerSecond.put(secondGenerated);
chunksPerMinute.put(secondGenerated * 60);
Iris.info("deepFinder: " + C.IRIS + world.getName() + C.RESET + " RTT: " + Form.f(foundChunks.get()) + " of " + Form.f(foundTotalChunks.get()) + " " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2));
}
if (foundChunks.get() >= foundTotalChunks.get()) {
Iris.info("Completed DeepSearch!");
interrupt();
} else {
int pos = job.getPosition() + 1;
job.setPosition(pos);
if (!job.paused) {
tickSearch(getChunk(pos));
}
}
}
@@ -141,22 +137,18 @@ public class DeepSearchPregenerator extends Thread implements Listener {
private final ExecutorService executorService = Executors.newSingleThreadExecutor();
private void tickSearch(Position2 chunk) {
executorService.submit(() -> {
CountDownLatch latch = new CountDownLatch(1);
try {
findInChunk(world, chunk.getX(), chunk.getZ());
} catch (IOException e) {
throw new RuntimeException(e);
private void queueSystem(Position2 chunk) {
if (chunkQueue.isEmpty()) {
for (int limit = 512; limit != 0; limit--) {
pos = job.getPosition() + 1;
chunkQueue.add(getChunk(pos));
}
Iris.verbose("Generated Async " + chunk);
latch.countDown();
} else {
//MCAUtil.read();
}
try {
latch.await();
} catch (InterruptedException ignored) {}
foundChunks.addAndGet(1);
});
}
private void findInChunk(World world, int x, int z) throws IOException {
@@ -271,7 +263,7 @@ public class DeepSearchPregenerator extends Thread implements Listener {
@Data
@Builder
public static class DeepSearchJob {
private String world;
private World world;
@Builder.Default
private int radiusBlocks = 5000;
@Builder.Default

View File

@@ -19,7 +19,9 @@
package com.volmit.iris.core.pregenerator;
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.format.C;
import com.volmit.iris.util.format.Form;
@@ -30,15 +32,12 @@ import com.volmit.iris.util.math.RollingSequence;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import lombok.Getter;
import lombok.Setter;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark;
public class IrisPregenerator {
private final PregenTask task;
@@ -50,6 +49,7 @@ public class IrisPregenerator {
private final RollingSequence chunksPerSecond;
private final RollingSequence chunksPerMinute;
private final RollingSequence regionsPerMinute;
private final KList<Integer> chunksPerSecondHistory;
private static AtomicInteger generated;
private final AtomicInteger generatedLast;
private final AtomicInteger generatedLastMinute;
@@ -62,8 +62,6 @@ public class IrisPregenerator {
private final KSet<Position2> net;
private final ChronoLatch cl;
private final ChronoLatch saveLatch = new ChronoLatch(30000);
static long long_generatedChunks = 0;
static long long_totalChunks = 0;
public IrisPregenerator(PregenTask task, PregeneratorMethod generator, PregenListener listener) {
this.listener = listenify(listener);
@@ -80,6 +78,7 @@ public class IrisPregenerator {
chunksPerSecond = new RollingSequence(10);
chunksPerMinute = new RollingSequence(10);
regionsPerMinute = new RollingSequence(10);
chunksPerSecondHistory = new KList<>();
generated = new AtomicInteger(0);
generatedLast = new AtomicInteger(0);
generatedLastMinute = new AtomicInteger(0);
@@ -93,6 +92,7 @@ public class IrisPregenerator {
int secondGenerated = generated.get() - generatedLast.get();
generatedLast.set(generated.get());
chunksPerSecond.put(secondGenerated);
chunksPerSecondHistory.add(secondGenerated);
if (minuteLatch.flip()) {
int minuteGenerated = generated.get() - generatedLastMinute.get();
@@ -100,8 +100,6 @@ public class IrisPregenerator {
chunksPerMinute.put(minuteGenerated);
regionsPerMinute.put((double) minuteGenerated / 1024D);
}
long_generatedChunks = generated.get();
long_totalChunks = totalChunks.get();
listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(),
regionsPerMinute.getAverage(),
@@ -112,10 +110,10 @@ public class IrisPregenerator {
if (cl.flip()) {
double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100;
if(benchmark) {
Iris.info(C.GREEN +"Benchmark: " + C.WHITE + 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("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage);
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;
@@ -128,17 +126,10 @@ public class IrisPregenerator {
// 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 //
((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000
);
}
public static long getLongGeneratedChunks() {
return long_generatedChunks;
}
public static long getLongTotalChunks() {
return long_totalChunks;
}
public void close() {
shutdown.set(true);
@@ -151,6 +142,11 @@ public class IrisPregenerator {
task.iterateRegions((x, z) -> visitRegion(x, z, true));
task.iterateRegions((x, z) -> visitRegion(x, z, false));
shutdown();
if (!IrisPackBenchmarking.benchmarkInProgress) {
Iris.info(C.IRIS + "Pregen stopped.");
} else {
IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory);
}
}
private void checkRegions() {
@@ -167,7 +163,10 @@ public class IrisPregenerator {
generator.close();
ticker.interrupt();
listener.onClose();
getMantle().trim(0, 0);
Mantle mantle = getMantle();
if (mantle != null) {
mantle.trim(0, 0);
}
}
private void visitRegion(int x, int z, boolean regions) {

View File

@@ -35,6 +35,8 @@ public class PregenTask {
private static final KList<Position2> ORDER_CENTER = computeChunkOrder();
private static final KMap<Position2, KList<Position2>> ORDERS = new KMap<>();
@Builder.Default
private boolean gui = false;
@Builder.Default
private Position2 center = new Position2(0, 0);
@Builder.Default

View File

@@ -44,10 +44,10 @@ public class ModesSFG {
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().ignoreBootMode) {
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 ignoreBootMode to true if you wish to proceed.");
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(1000);

View File

@@ -3,11 +3,11 @@ 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.apache.logging.log4j.core.util.ExecutorServices;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import javax.print.attribute.standard.Severity;
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;
@@ -15,11 +15,9 @@ 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 java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static com.volmit.iris.Iris.getJavaVersion;
import static com.volmit.iris.Iris.instance;
@@ -42,7 +40,7 @@ public class ServerBootSFG {
public static void BootCheck() {
Iris.info("Checking for possible conflicts..");
org.bukkit.plugin.PluginManager pluginManager = Bukkit.getPluginManager();
PluginManager pluginManager = Bukkit.getPluginManager();
Plugin[] plugins = pluginManager.getPlugins();
incompatibilities.clear();
@@ -67,24 +65,29 @@ public class ServerBootSFG {
joiner.add(entry.getKey());
}
}
// Legacy ServerInfo
String distro = Bukkit.getName().toLowerCase();
if (
!instance.getServer().getVersion().contains("Purpur") &&
!instance.getServer().getVersion().contains("Paper") &&
!instance.getServer().getVersion().contains("Spigot") &&
!instance.getServer().getVersion().contains("Pufferfish") &&
!instance.getServer().getVersion().contains("Bukkit")) {
!distro.contains("purpur") &&
!distro.contains("paper") &&
!distro.contains("spigot") &&
!distro.contains("pufferfish") &&
!distro.contains("bukkit")) {
passedserversoftware = false;
joiner.add("Server Software");
severityHigh++;
severityMedium++;
}
if (INMS.get() instanceof NMSBinding1X) {
unsuportedversion = true;
joiner.add("Unsupported Minecraft Version");
severityHigh++;
}
if (getJavaVersion() != 17) {
if (!List.of(17, 21).contains(getJavaVersion())) {
isJDK17 = false;
joiner.add("Unsupported Java version");
severityMedium++;
@@ -128,25 +131,15 @@ public class ServerBootSFG {
}
}
public static boolean isJDK() {
String path = System.getProperty("sun.boot.library.path");
if (path != null) {
String javacPath = "";
if (path.endsWith(File.separator + "bin")) {
javacPath = path;
} else {
int libIndex = path.lastIndexOf(File.separator + "lib");
if (libIndex > 0) {
javacPath = path.substring(0, libIndex) + File.separator + "bin";
}
}
if (checkJavac(javacPath))
return true;
}
path = System.getProperty("java.home");
return path != null && checkJavac(path + File.separator + "bin");
}
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)) {

View File

@@ -37,7 +37,7 @@ public class UtilsSFG {
}
if (ServerBootSFG.unsuportedversion) {
Iris.safeguard(C.RED + "Server Version");
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.20.4");
Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.20.6");
}
if (!ServerBootSFG.passedserversoftware) {
Iris.safeguard(C.YELLOW + "Unsupported Server Software");
@@ -53,11 +53,11 @@ public class UtilsSFG {
}
if (!ServerBootSFG.isJDK17) {
Iris.safeguard(C.YELLOW + "Unsupported java version");
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 Instead of JDK " + Iris.getJavaVersion());
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 Instead of JRE " + Iris.getJavaVersion());
Iris.safeguard(C.YELLOW + "- Please consider using JDK 17 (or 21 for 1.20.6) Instead of JRE " + Iris.getJavaVersion());
}
}
}

View File

@@ -1,119 +1,170 @@
/*
* 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.service;
import com.volmit.iris.Iris;
import com.volmit.iris.core.link.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.plugin.IrisService;
import lombok.Data;
import org.bukkit.Bukkit;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.inventory.ItemStack;
import java.util.MissingResourceException;
import java.util.Optional;
@Data
public class ExternalDataSVC implements IrisService {
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
@Override
public void onEnable() {
Iris.info("Loading ExternalDataProvider...");
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
providers.add(new OraxenDataProvider());
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
Iris.info("Oraxen found, loading OraxenDataProvider...");
}
providers.add(new ItemAdderDataProvider());
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
}
providers.add(new ExecutableItemsDataProvider());
if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) {
Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider...");
}
for (ExternalDataProvider p : providers) {
if (p.isReady()) {
activeProviders.add(p);
p.init();
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
}
}
}
@Override
public void onDisable() {
}
@EventHandler
public void onPluginEnable(PluginEnableEvent e) {
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
activeProviders.add(edp);
edp.init();
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
});
}
}
public Optional<BlockData> getBlockData(Identifier key) {
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(key, false)).findFirst();
if (provider.isEmpty())
return Optional.empty();
try {
return Optional.of(provider.get().getBlockData(key));
} catch (MissingResourceException e) {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
}
}
public Optional<ItemStack> getItemStack(Identifier key) {
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));
} catch (MissingResourceException e) {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
}
}
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]);
}
}
/*
* 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.service;
import com.volmit.iris.Iris;
import com.volmit.iris.core.link.*;
import com.volmit.iris.core.nms.container.Pair;
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.plugin.IrisService;
import lombok.Data;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.EventHandler;
import org.bukkit.event.server.PluginEnableEvent;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.stream.Collectors;
@Data
public class ExternalDataSVC implements IrisService {
private KList<ExternalDataProvider> providers = new KList<>(), activeProviders = new KList<>();
@Override
public void onEnable() {
Iris.info("Loading ExternalDataProvider...");
Bukkit.getPluginManager().registerEvents(this, Iris.instance);
providers.add(new OraxenDataProvider());
if (Bukkit.getPluginManager().getPlugin("Oraxen") != null) {
Iris.info("Oraxen found, loading OraxenDataProvider...");
}
providers.add(new ItemAdderDataProvider());
if (Bukkit.getPluginManager().getPlugin("ItemAdder") != null) {
Iris.info("ItemAdder found, loading ItemAdderDataProvider...");
}
providers.add(new ExecutableItemsDataProvider());
if (Bukkit.getPluginManager().getPlugin("ExecutableItems") != null) {
Iris.info("ExecutableItems found, loading ExecutableItemsDataProvider...");
}
providers.add(new HMCLeavesDataProvider());
if (Bukkit.getPluginManager().getPlugin("HMCLeaves") != null) {
Iris.info("BlockAdder found, loading HMCLeavesDataProvider...");
}
providers.add(new MMOItemsDataProvider());
if (Bukkit.getPluginManager().getPlugin("MMOItems") != null) {
Iris.info("MMOItems found, loading MMOItemsDataProvider...");
}
providers.add(new EcoItemsDataProvider());
if (Bukkit.getPluginManager().getPlugin("EcoItems") != null) {
Iris.info("EcoItems found, loading EcoItemsDataProvider...");
}
for (ExternalDataProvider p : providers) {
if (p.isReady()) {
activeProviders.add(p);
p.init();
Iris.info("Enabled ExternalDataProvider for %s.", p.getPluginId());
}
}
}
@Override
public void onDisable() {
}
@EventHandler
public void onPluginEnable(PluginEnableEvent e) {
if (activeProviders.stream().noneMatch(p -> p.getPlugin().equals(e.getPlugin()))) {
providers.stream().filter(p -> p.isReady() && p.getPlugin().equals(e.getPlugin())).findFirst().ifPresent(edp -> {
activeProviders.add(edp);
edp.init();
Iris.info("Enabled ExternalDataProvider for %s.", edp.getPluginId());
});
}
}
public Optional<BlockData> getBlockData(final Identifier key) {
var pair = parseState(key);
Identifier mod = pair.getA();
Optional<ExternalDataProvider> provider = activeProviders.stream().filter(p -> p.isValidProvider(mod, false)).findFirst();
if (provider.isEmpty())
return Optional.empty();
try {
return Optional.of(provider.get().getBlockData(mod, pair.getB()));
} catch (MissingResourceException e) {
Iris.error(e.getMessage() + " - [" + e.getClassName() + ":" + e.getKey() + "]");
return Optional.empty();
}
}
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);
}
}

View File

@@ -1,35 +1,76 @@
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.ArrayList;
import java.util.List;
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 final ReentrantLock lastUseLock = new ReentrantLock();
private final KMap<World, Long> lastUse = new KMap<>();
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) {
@@ -37,15 +78,69 @@ public class IrisEngineSVC implements IrisService {
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();
//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
@@ -57,7 +152,7 @@ public class IrisEngineSVC implements IrisService {
Long last = lastUse.get(key);
if (last == null)
continue;
if (now - last > 60000) { // 1 minute
if (now - last > 60000) {
lastUse.remove(key);
}
}
@@ -67,57 +162,115 @@ public class IrisEngineSVC implements IrisService {
return 1000;
}
};
trimTicker = new Looper() {
private final Supplier<Engine> supplier = createSupplier();
updateTicker = new Looper() {
@Override
protected long loop() {
long start = System.currentTimeMillis();
try {
Engine engine = supplier.get();
if (engine != null) {
engine.getMantle().trim(tectonicLimit.get() / lastUse.size());
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());
}
} catch (Throwable e) {
Iris.reportError(e);
// return -1;
}
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();
}
}
int size = lastUse.size();
long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start);
if (time <= 0)
return 0;
return time;
}
};
unloadTicker = new Looper() {
private final Supplier<Engine> supplier = createSupplier();
@Override
protected long loop() {
long start = System.currentTimeMillis();
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));
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 (Throwable e) {
Iris.reportError(e);
} catch (Exception e) {
return -1;
}
int size = lastUse.size();
long time = (size > 0 ? 1000/size : 1000) - (System.currentTimeMillis() - start);
if (time <= 0)
return 0;
return time;
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();
@@ -136,7 +289,8 @@ public class IrisEngineSVC implements IrisService {
if (generator != null) {
Engine engine = generator.getEngine();
if (engine != null) {
boolean closed = engine.getMantle().getData().isClosed();
if (engine != null && !engine.isStudio() && !closed) {
lastUseLock.lock();
lastUse.put(world, System.currentTimeMillis());
lastUseLock.unlock();
@@ -145,6 +299,8 @@ public class IrisEngineSVC implements IrisService {
}
}
} catch (Throwable e) {
Iris.info(C.RED + "EngineSVC: Failed to create supplier.");
e.printStackTrace();
Iris.reportError(e);
}
return null;

View File

@@ -240,7 +240,7 @@ public class TreeSVC implements IrisService {
boolean isUseAll = worldAccess.getEngine().getDimension().getTreeSettings().getMode().equals(IrisTreeModes.ALL);
// 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));
// Add more or find any in the region

View File

@@ -30,9 +30,11 @@ import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.matter.Matter;
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.VolmitSender;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.S;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.enchantments.Enchantment;
@@ -53,6 +55,9 @@ import java.util.ArrayList;
import java.util.Objects;
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 ItemStack dust;
private static ItemStack wand;
@@ -162,11 +167,11 @@ public class WandSVC implements IrisService {
*/
public static ItemStack createDust() {
ItemStack is = new ItemStack(Material.GLOWSTONE_DUST);
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
ItemMeta im = is.getItemMeta();
im.setDisplayName(C.BOLD + "" + C.YELLOW + "Dust of Revealing");
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!"));
is.setItemMeta(im);
@@ -206,11 +211,11 @@ public class WandSVC implements IrisService {
*/
public static ItemStack createWand(Location a, Location b) {
ItemStack is = new ItemStack(Material.BLAZE_ROD);
is.addUnsafeEnchantment(Enchantment.ARROW_INFINITE, 1);
is.addUnsafeEnchantment(Enchantment.FIRE_ASPECT, 1);
ItemMeta im = is.getItemMeta();
im.setDisplayName(C.BOLD + "" + C.GOLD + "Wand of Iris");
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)));
is.setItemMeta(im);
@@ -311,9 +316,9 @@ public class WandSVC implements IrisService {
*/
public void draw(Location[] d, Player p) {
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);
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())) {
return;
@@ -370,7 +375,7 @@ public class WandSVC implements IrisService {
int r = color.getRed();
int g = color.getGreen();
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));
}
}
}
@@ -383,7 +388,7 @@ public class WandSVC implements IrisService {
if (e.getHand() != EquipmentSlot.HAND)
return;
try {
if (isHoldingWand(e.getPlayer())) {
if (isHoldingIrisWand(e.getPlayer())) {
if (e.getAction().equals(Action.LEFT_CLICK_BLOCK)) {
e.setCancelled(true);
e.getPlayer().getInventory().setItemInMainHand(update(true, Objects.requireNonNull(e.getClickedBlock()).getLocation(), e.getPlayer().getInventory().getItemInMainHand()));

View File

@@ -1,31 +0,0 @@
package com.volmit.iris.core.service;
import com.volmit.iris.Iris;
import com.volmit.iris.util.plugin.IrisService;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.plugin.java.JavaPlugin;
import static java.lang.System.getLogger;
public class WorldLoadSFG implements IrisService {
private JavaPlugin plugin;
@EventHandler
public void onWorldLoad(WorldLoadEvent event) {
World world = event.getWorld();
}
@Override
public void onEnable() {
this.plugin = Iris.instance;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@Override
public void onDisable() {
}
}

View File

@@ -28,7 +28,6 @@ import java.io.InputStreamReader;
import static com.google.common.math.LongMath.isPrime;
import static com.volmit.iris.util.misc.getHardware.getCPUModel;
import static com.volmit.iris.util.misc.getHardware.getDiskModel;
public class IrisBenchmarking {
static String ServerOS;
static String filePath = "benchmark.dat";
@@ -180,12 +179,12 @@ public class IrisBenchmarking {
Iris.info("- Data Compression: " + formatDouble(calculateDataCompression) + " MBytes/Sec");
if (WindowsDiskSpeed) {
Iris.info("Disk Model: " + getDiskModel());
//Iris.info("Disk Model: " + getDiskModel());
Iris.info(C.BLUE + "- Running with Windows System Assessment Tool");
Iris.info("- Sequential 64.0 Write: " + C.BLUE + formatDouble(avgWriteSpeedMBps) + " Mbps");
Iris.info("- Sequential 64.0 Read: " + C.BLUE + formatDouble(avgReadSpeedMBps) + " Mbps");
} else {
Iris.info("Disk Model: " + getDiskModel());
// Iris.info("Disk Model: " + getDiskModel());
Iris.info(C.GREEN + "- Running in Native Mode");
Iris.info("- Average Write Speed: " + C.GREEN + formatDouble(avgWriteSpeedMBps) + " Mbps");
Iris.info("- Average Read Speed: " + C.GREEN + formatDouble(avgReadSpeedMBps) + " Mbps");

View File

@@ -0,0 +1,395 @@
package com.volmit.iris.core.tools;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.nbt.io.NBTUtil;
import com.volmit.iris.util.nbt.io.NamedTag;
import com.volmit.iris.util.nbt.tag.*;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.reflect.V;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.util.Vector;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
public class IrisConverter {
public static void convertSchematics(VolmitSender sender) {
File folder = Iris.instance.getDataFolder("convert");
FilenameFilter filter = (dir, name) -> name.endsWith(".schem");
File[] fileList = folder.listFiles(filter);
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(() -> {
for (File schem : fileList) {
try {
PrecisionStopwatch p = new PrecisionStopwatch();
boolean largeObject = false;
NamedTag tag = null;
try {
tag = NBTUtil.read(schem);
} catch (IOException e) {
Iris.info(C.RED + "Failed to read: " + schem.getName());
throw new RuntimeException(e);
}
CompoundTag compound = (CompoundTag) tag.getTag();
if (compound.containsKey("Palette") && compound.containsKey("Width") && compound.containsKey("Height") && compound.containsKey("Length")) {
int objW = ((ShortTag) compound.get("Width")).getValue();
int objH = ((ShortTag) compound.get("Height")).getValue();
int objD = ((ShortTag) compound.get("Length")).getValue();
int mv = objW * objH * objD;
AtomicInteger v = new AtomicInteger(0);
AtomicInteger fv = new AtomicInteger(0);
if (mv > 500_000) {
largeObject = true;
Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
Iris.info(C.GRAY + "- It may take a while");
if (sender.isPlayer()) {
J.a(() -> {
// while (v.get() != mv) {
// double pr = ((double) v.get() / (double ) mv);
// sender.sendProgress(pr, "Converting");
// J.sleep(16);
// }
});
}
}
CompoundTag paletteTag = (CompoundTag) compound.get("Palette");
Map<Integer, BlockData> blockmap = new HashMap<>(paletteTag.size(), 0.9f);
for (Map.Entry<String, Tag<?>> entry : paletteTag.getValue().entrySet()) {
String blockName = entry.getKey();
BlockData bd = Bukkit.createBlockData(blockName);
Tag<?> blockTag = entry.getValue();
int blockId = ((IntTag) blockTag).getValue();
blockmap.put(blockId, bd);
}
ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData");
byte[] originalBlockArray = byteArray.getValue();
int b = 0;
int a = 0;
Map<Integer, Byte> y = new HashMap<>();
Map<Integer, Byte> x = new HashMap<>();
Map<Integer, Byte> z = new HashMap<>();
// Height adjustments
for (int h = 0; h < objH; h++) {
if (b == 0) {
y.put(h, (byte) 0);
}
if (b > 0) {
y.put(h, (byte) 1);
}
a = 0;
b = 0;
for (int d = 0; d < objD; d++) {
for (int w = 0; w < objW; w++) {
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
if(db.getAsString().contains("minecraft:air")) {
a++;
} else {
b++;
}
fv.getAndAdd(1);
}
}
}
fv.set(0);
// Width adjustments
for (int w = 0; w < objW; w++) {
if (b == 0) {
x.put(w, (byte) 0);
}
if (b > 0) {
x.put(w, (byte) 1);
}
a = 0;
b = 0;
for (int h = 0; h < objH; h++) {
for (int d = 0; d < objD; d++) {
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
if(db.getAsString().contains("minecraft:air")) {
a++;
} else {
b++;
}
fv.getAndAdd(1);
}
}
}
fv.set(0);
// Depth adjustments
for (int d = 0; d < objD; d++) {
if (b == 0) {
z.put(d, (byte) 0);
}
if (b > 0) {
z.put(d, (byte) 1);
}
a = 0;
b = 0;
for (int h = 0; h < objH; h++) {
for (int w = 0; w < objW; w++) {
BlockData db = blockmap.get((int) originalBlockArray[fv.get()]);
if(db.getAsString().contains("minecraft:air")) {
a++;
} else {
b++;
}
fv.getAndAdd(1);
}
}
}
fv.set(0);
int CorrectObjH = getCorrectY(y, objH);
int CorrectObjW = getCorrectX(x, objW);
int CorrectObjD = getCorrectZ(z, objD);
//IrisObject object = new IrisObject(CorrectObjW, CorrectObjH, CorrectObjH);
IrisObject object = new IrisObject(objW, objH, objD);
Vector originalVector = new Vector(objW,objH,objD);
int[] yc = null;
int[] xc = null;
int[] zc = null;
int fo = 0;
int so = 0;
int o = 0;
int c = 0;
for (Integer i : y.keySet()) {
if (y.get(i) == 0) {
o++;
}
if (y.get(i) == 1) {
c++;
if (c == 1) {
fo = o;
}
o = 0;
}
}
so = o;
yc = new int[]{fo, so};
fo = 0;
so = 0;
o = 0;
c = 0;
for (Integer i : x.keySet()) {
if (x.get(i) == 0) {
o++;
}
if (x.get(i) == 1) {
c++;
if (c == 1) {
fo = o;
}
o = 0;
}
}
so = o;
xc = new int[]{fo, so};
fo = 0;
so = 0;
o = 0;
c = 0;
for (Integer i : z.keySet()) {
if (z.get(i) == 0) {
o++;
}
if (z.get(i) == 1) {
c++;
if (c == 1) {
fo = o;
}
o = 0;
}
}
so = o;
zc = new int[]{fo, so};
int h1, h2, w1, w2, v1 = 0, volume = objW * objH * objD;
Map<Integer, Integer> blockLocationMap = new LinkedHashMap<>();
boolean hasAir = false;
int pos = 0;
for (int i : originalBlockArray) {
blockLocationMap.put(pos, i);
pos++;
}
for (int h = 0; h < objH; h++) {
for (int d = 0; d < objD; d++) {
for (int w = 0; w < objW; w++) {
BlockData bd = blockmap.get((int) originalBlockArray[v.get()]);
if (!bd.getMaterial().isAir()) {
object.setUnsigned(w, h, d, bd);
}
v.getAndAdd(1);
}
}
}
try {
object.write(new File(folder, schem.getName().replace(".schem", ".iob")));
} catch (IOException e) {
Iris.info(C.RED + "Failed to save: " + schem.getName());
throw new RuntimeException(e);
}
if (sender.isPlayer()) {
if (largeObject) {
sender.sendMessage(C.IRIS + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
}
}
if (largeObject) {
Iris.info(C.GRAY + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis()));
} else {
Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob"));
}
// schem.delete();
}
} catch (Exception e) {
Iris.info(C.RED + "Failed to convert: " + schem.getName());
if (sender.isPlayer()) {
sender.sendMessage(C.RED + "Failed to convert: " + schem.getName());
}
e.printStackTrace();
Iris.reportError(e);
}
}
});
}
public static boolean isNewPointFurther(int[] originalPoint, int[] oldPoint, int[] newPoint) {
int oX = oldPoint[1];
int oY = oldPoint[2];
int oZ = oldPoint[3];
int nX = newPoint[1];
int nY = newPoint[2];
int nZ = newPoint[3];
int orX = originalPoint[1];
int orY = originalPoint[2];
int orZ = originalPoint[3];
double oldDistance = Math.sqrt(Math.pow(oX - orX, 2) + Math.pow(oY - orY, 2) + Math.pow(oZ - orZ, 2));
double newDistance = Math.sqrt(Math.pow(nX - orX, 2) + Math.pow(nY - orY, 2) + Math.pow(nZ - orZ, 2));
if (newDistance > oldDistance) {
return true;
}
return false;
}
public static int[] getCoordinates(int pos, int obX, int obY, int obZ) {
int z = 0;
int[] coords = new int[4];
for (int h = 0; h < obY; h++) {
for (int d = 0; d < obZ; d++) {
for (int w = 0; w < obX; w++) {
if (z == pos) {
coords[1] = w;
coords[2] = h;
coords[3] = d;
return coords;
}
z++;
}
}
}
return null;
}
public static int getCorrectY(Map<Integer, Byte> y, int H) {
int fo = 0;
int so = 0;
int o = 0;
int c = 0;
for (Integer i : y.keySet()) {
if (y.get(i) == 0) {
o++;
}
if (y.get(i) == 1) {
c++;
if(c == 1){
fo = o;
}
o = 0;
}
}
so = o;
return H = H - (fo + so);
}
public static int getCorrectX(Map<Integer, Byte> x, int W) {
int fo = 0;
int so = 0;
int o = 0;
int c = 0;
for (Integer i : x.keySet()) {
if (x.get(i) == 0) {
o++;
}
if (x.get(i) == 1) {
c++;
if(c == 1){
fo = o;
}
o = 0;
}
}
so = o;
return W = W - (fo + so);
}
public static int getCorrectZ(Map<Integer, Byte> z, int D) {
int fo = 0;
int so = 0;
int o = 0;
int c = 0;
for (Integer i : z.keySet()) {
if (z.get(i) == 0) {
o++;
}
if (z.get(i) == 1) {
c++;
if(c == 1){
fo = o;
}
o = 0;
}
}
so = o;
return D = D - (fo + so);
}
}

View File

@@ -46,10 +46,6 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark;
import static com.volmit.iris.core.safeguard.IrisSafeguard.unstablemode;
/**
@@ -86,6 +82,11 @@ public class IrisCreator {
* the world itself. Studio worlds are deleted when they are unloaded.
*/
private boolean studio = false;
/**
* Benchmark mode
*/
private boolean benchmark = false;
private boolean smartVanillaHeight = false;
public static boolean removeFromBukkitYml(String name) throws IOException {
YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML);
@@ -110,15 +111,8 @@ public class IrisCreator {
* @return the IrisAccess
* @throws IrisException shit happens
*/
IrisPackBenchmarking PackBench = new IrisPackBenchmarking();
public World create() throws IrisException {
if (unstablemode){
Iris.info(C.RED + "Your server is experiencing an incompatibility with the Iris plugin. Please rectify this problem to avoid further complications.");
Iris.info(C.RED + "----------------------------------------------------------------");
Iris.info(C.RED + "Operation ran: Loading Iris World..");
UtilsSFG.printIncompatibleWarnings();
Iris.info(C.RED + "----------------------------------------------------------------");
}
if (Bukkit.isPrimaryThread()) {
throw new IrisException("You cannot invoke create() on the main thread.");
}
@@ -149,6 +143,7 @@ public class IrisCreator {
.name(name)
.seed(seed)
.studio(studio)
.smartVanillaHeight(smartVanillaHeight)
.create();
ServerConfigurator.installDataPacks(false);
@@ -193,7 +188,7 @@ public class IrisCreator {
done.set(true);
if (sender.isPlayer()) {
if (sender.isPlayer() && !benchmark) {
J.s(() -> {
sender.player().teleport(new Location(world.get(), 0, world.get().getHighestBlockYAt(0, 0), 0));
});

View File

@@ -2,169 +2,200 @@ package com.volmit.iris.core.tools;
import com.volmit.iris.Iris;
import com.volmit.iris.core.pregenerator.IrisPregenerator;
import com.volmit.iris.core.pregenerator.LazyPregenerator;
import com.volmit.iris.core.pregenerator.PregenTask;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.exceptions.IrisException;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.scheduling.J;
import org.apache.commons.io.FileUtils;
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
import lombok.Getter;
import org.bukkit.Bukkit;
import java.io.File;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static com.volmit.iris.core.commands.CommandIris.BenchDimension;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.time.Clock;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.concurrent.*;
public class IrisPackBenchmarking {
public static boolean loaded = false;
public static boolean benchmark = false;
static boolean cancelled = false;
static boolean pregenInProgress = false;
static long startTime;
static long totalChunks;
static long generatedChunks;
static double elapsedTimeNs;
@Getter
public static IrisPackBenchmarking instance;
public static boolean benchmarkInProgress = false;
private IrisDimension IrisDimension;
private int radius;
private boolean finished = false;
PrecisionStopwatch stopwatch;
public static void runBenchmark() {
// IrisPackBenchmarking IrisPackBenchmarking = new IrisPackBenchmarking();
benchmark = true;
Iris.info(C.BLUE + "Benchmarking Dimension: " + C.AQUA + BenchDimension);
//progress();
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
Iris.info(C.GOLD + "Setting everything up..");
try {
String BenchmarkFolder = "\\Benchmark";
File folder = new File(BenchmarkFolder);
if (folder.exists() && folder.isDirectory()) {
FileUtils.deleteDirectory(folder);
Iris.debug("Deleted old Benchmark");
} else {
Iris.info(C.GOLD + "Old Benchmark not found!");
if(folder.exists()){
Iris.info(C.RED + "FAILED To remove old Benchmark!");
//cancelled = true;
public IrisPackBenchmarking(IrisDimension dimension, int r) {
instance = this;
this.IrisDimension = dimension;
this.radius = r;
runBenchmark();
}
}
private void runBenchmark() {
this.stopwatch = new PrecisionStopwatch();
ExecutorService service = Executors.newSingleThreadExecutor();
service.submit(() -> {
Iris.info("Setting up benchmark environment ");
benchmarkInProgress = true;
File file = new File("benchmark");
if (file.exists()) {
deleteDirectory(file.toPath());
}
createBenchmark();
while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) {
J.sleep(1000);
Iris.debug("Iris PackBenchmark: Waiting...");
}
Iris.info("Starting Benchmark!");
stopwatch.begin();
startBenchmark();
});
}
public boolean getBenchmarkInProgress() {
return benchmarkInProgress;
}
public void finishedBenchmark(KList<Integer> cps) {
try {
String time = Form.duration(stopwatch.getMillis());
Engine engine = IrisToolbelt.access(Bukkit.getWorld("benchmark")).getEngine();
Iris.info("-----------------");
Iris.info("Results:");
Iris.info("- Total time: " + time);
Iris.info("- Average CPS: " + calculateAverage(cps));
Iris.info(" - Median CPS: " + calculateMedian(cps));
Iris.info(" - Highest CPS: " + findHighest(cps));
Iris.info(" - Lowest CPS: " + findLowest(cps));
Iris.info("-----------------");
Iris.info("Creating a report..");
File profilers = new File("plugins" + File.separator + "Iris" + File.separator + "packbenchmarks");
profilers.mkdir();
File results = new File("plugins " + File.separator + "Iris", IrisDimension.getName() + LocalDateTime.now(Clock.systemDefaultZone()) + ".txt");
results.createNewFile();
KMap<String, Double> metrics = engine.getMetrics().pull();
try (FileWriter writer = new FileWriter(results)) {
writer.write("-----------------\n");
writer.write("Results:\n");
writer.write("Dimension: " + IrisDimension.getName() + "\n");
writer.write("- Date of Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n");
writer.write("\n");
writer.write("Metrics");
for (String m : metrics.k()) {
double i = metrics.get(m);
writer.write("- " + m + ": " + i);
}
} catch (Exception e) {
throw new RuntimeException();
writer.write("- " + metrics);
writer.write("Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n");
writer.write("- Total time: " + time + "\n");
writer.write("- Average CPS: " + calculateAverage(cps) + "\n");
writer.write(" - Median CPS: " + calculateMedian(cps) + "\n");
writer.write(" - Highest CPS: " + findHighest(cps) + "\n");
writer.write(" - Lowest CPS: " + findLowest(cps) + "\n");
writer.write("-----------------\n");
Iris.info("Finished generating a report!");
} catch (IOException e) {
Iris.error("An error occurred writing to the file.");
e.printStackTrace();
}
}).thenRun(() -> {
Iris.info(C.GOLD + "Creating Benchmark Environment");
createBenchmark();
}).thenRun(() -> {
Iris.info( C.BLUE + "Benchmark Started!");
boolean done = false;
startBenchmarkTimer();
startBenchmark();
basicScheduler();
}).thenRun(() -> {
});
// cancelled = future.cancel(true);
try {
future.get();
} catch (InterruptedException | ExecutionException e) {
Bukkit.getServer().unloadWorld("benchmark", true);
stopwatch.end();
} catch (Exception e) {
Iris.error("Something has gone wrong!");
e.printStackTrace();
}
}
private static void results(){
double averageCps = calculateAverageCPS();
Iris.info("Benchmark Dimension: " + BenchDimension);
Iris.info("Speeds");
Iris.info("- Average CPS: " + roundToTwoDecimalPlaces(averageCps));
Iris.info("Duration: " + roundToTwoDecimalPlaces(elapsedTimeNs));
}
private static void basicScheduler() {
while (true) {
totalChunks = IrisPregenerator.getLongTotalChunks();
generatedChunks = IrisPregenerator.getLongGeneratedChunks();
if(totalChunks > 0) {
if (generatedChunks >= totalChunks) {
Iris.info("Benchmark Completed!");
elapsedTimeNs = stopBenchmarkTimer();
results();
break;
}
}
//J.sleep(100); test
}
}
static void createBenchmark(){
private void createBenchmark(){
try {
IrisToolbelt.createWorld()
.dimension(BenchDimension)
.name("Benchmark")
.dimension(IrisDimension.getName())
.name("benchmark")
.seed(1337)
.studio(false)
.benchmark(true)
.create();
} catch (IrisException e) {
throw new RuntimeException(e);
}
}
static void startBenchmark(){
private void startBenchmark(){
int x = 0;
int z = 0;
IrisToolbelt.pregenerate(PregenTask
.builder()
.gui(false)
.center(new Position2(x, z))
.width(5)
.height(5)
.build(), Bukkit.getWorld("Benchmark")
.build(), Bukkit.getWorld("benchmark")
);
}
static void startLazyBenchmark(){
int x = 0;
int z = 0;
LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder()
//.world("Benchmark")
.healingPosition(0)
.healing(false)
.chunksPerMinute(3200)
.radiusBlocks(5000)
.position(0)
.build();
LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, new File("plugins/Iris/lazygen.json"));
pregenerator.start();
}
public static double calculateAverageCPS() {
double elapsedTimeSec = elapsedTimeNs / 1_000_000_000.0; // Convert to seconds
return generatedChunks / elapsedTimeSec;
}
private static void startBenchmarkTimer() {
startTime = System.nanoTime();
}
private static double stopBenchmarkTimer() {
long endTime = System.nanoTime();
return (endTime - startTime) / 1_000_000_000.0;
}
public static void deleteDirectory(File dir) {
File[] files = dir.listFiles();
if(files != null) {
for(File file: files) {
if(file.isDirectory()) {
deleteDirectory(file);
} else {
file.delete();
}
}
private double calculateAverage(KList<Integer> list) {
double sum = 0;
for (int num : list) {
sum += num;
}
dir.delete();
return sum / list.size();
}
private static double roundToTwoDecimalPlaces(double value) {
return Double.parseDouble(String.format("%.2f", value));
private double calculateMedian(KList<Integer> list) {
Collections.sort(list);
int middle = list.size() / 2;
if (list.size() % 2 == 1) {
return list.get(middle);
} else {
return (list.get(middle - 1) + list.get(middle)) / 2.0;
}
}
private int findLowest(KList<Integer> list) {
return Collections.min(list);
}
private int findHighest(KList<Integer> list) {
return Collections.max(list);
}
private boolean deleteDirectory(Path dir) {
try {
Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}

View File

@@ -32,6 +32,7 @@ public class IrisWorldCreator {
private String name;
private boolean studio = false;
private String dimensionName = null;
private boolean smartVanillaHeight = false;
private long seed = 1337;
public IrisWorldCreator() {
@@ -63,6 +64,11 @@ public class IrisWorldCreator {
return this;
}
public IrisWorldCreator smartVanillaHeight(boolean smartVanillaHeight) {
this.smartVanillaHeight = smartVanillaHeight;
return this;
}
public WorldCreator create() {
IrisDimension dim = IrisData.loadAnyDimension(dimensionName);
@@ -76,7 +82,7 @@ public class IrisWorldCreator {
.build();
ChunkGenerator g = new BukkitChunkGenerator(w, studio, studio
? dim.getLoader().getDataFolder() :
new File(w.worldFolder(), "iris/pack"), dimensionName);
new File(w.worldFolder(), "iris/pack"), dimensionName, smartVanillaHeight);
return new WorldCreator(name)

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.core.wand;
import com.volmit.iris.util.data.Cuboid;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.misc.E;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.entity.Player;
@@ -29,6 +30,7 @@ import org.bukkit.util.Vector;
import java.awt.*;
public class WandSelection {
private static final Particle REDSTONE = E.getOrDefault(Particle.class, "REDSTONE", "DUST");
private final Cuboid c;
private final Player p;
@@ -101,7 +103,7 @@ public class WandSelection {
int g = color.getGreen();
int b = color.getBlue();
p.spawnParticle(Particle.REDSTONE, a.getX(), a.getY(), a.getZ(),
p.spawnParticle(REDSTONE, a.getX(), a.getY(), a.getZ(),
1, 0, 0, 0, 0,
new Particle.DustOptions(org.bukkit.Color.fromRGB(r, g, b),
(float) dist * 3f));

View File

@@ -124,6 +124,7 @@ public class IrisComplex implements DataProvider {
ProceduralStream.of((x, z) -> focusRegion,
Interpolated.of(a -> 0D, a -> focusRegion))
: regionStyleStream
.zoom(engine.getDimension().getRegionZoom())
.selectRarity(data.getRegionLoader().loadAll(engine.getDimension().getRegions()))
.cache2D("regionStream", engine, cacheSize).waste("Region Stream");
regionIDStream = regionIdentityStream.convertCached((i) -> new UUID(Double.doubleToLongBits(i),
@@ -131,6 +132,7 @@ public class IrisComplex implements DataProvider {
caveBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getCaveBiomeStyle().create(rng.nextParallelRNG(InferredType.CAVE.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(r.getCaveBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getCaveBiomes()))
.onNull(emptyBiome)
@@ -139,6 +141,8 @@ public class IrisComplex implements DataProvider {
landBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getLandBiomeStyle().create(rng.nextParallelRNG(InferredType.LAND.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(engine.getDimension().getLandZoom())
.zoom(r.getLandBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getLandBiomes(), (t) -> t.setInferredType(InferredType.LAND)))
).convertAware2D(ProceduralStream::get)
@@ -147,6 +151,8 @@ public class IrisComplex implements DataProvider {
seaBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getSeaBiomeStyle().create(rng.nextParallelRNG(InferredType.SEA.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(engine.getDimension().getSeaZoom())
.zoom(r.getSeaBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getSeaBiomes(), (t) -> t.setInferredType(InferredType.SEA)))
).convertAware2D(ProceduralStream::get)
@@ -155,6 +161,7 @@ public class IrisComplex implements DataProvider {
shoreBiomeStream = regionStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getRegion().get(x, z))
.convert((r)
-> engine.getDimension().getShoreBiomeStyle().create(rng.nextParallelRNG(InferredType.SHORE.ordinal()), getData()).stream()
.zoom(engine.getDimension().getBiomeZoom())
.zoom(r.getShoreBiomeZoom())
.selectRarity(data.getBiomeLoader().loadAll(r.getShoreBiomes(), (t) -> t.setInferredType(InferredType.SHORE)))
).convertAware2D(ProceduralStream::get).cache2D("shoreBiomeStream", engine, cacheSize).waste("Shore Biome Stream");
@@ -292,7 +299,7 @@ public class IrisComplex implements DataProvider {
double b = 0;
for (IrisGenerator gen : generators) {
b += bx.getGenLinkMax(gen.getLoadKey());
b += bx.getGenLinkMax(gen.getLoadKey(), engine);
}
return b;
@@ -311,7 +318,7 @@ public class IrisComplex implements DataProvider {
double b = 0;
for (IrisGenerator gen : generators) {
b += bx.getGenLinkMin(gen.getLoadKey());
b += bx.getGenLinkMin(gen.getLoadKey(), engine);
}
return b;

View File

@@ -19,8 +19,6 @@
package com.volmit.iris.engine;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.tools.IrisPackBenchmarking;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.EngineMantle;
@@ -47,9 +45,6 @@ import java.io.IOException;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark;
import static com.volmit.iris.core.safeguard.PerformanceSFG.*;
@Data
@EqualsAndHashCode(exclude = "engine")
@ToString(exclude = "engine")
@@ -290,17 +285,10 @@ public class IrisEngineMantle implements EngineMantle {
x = Math.max(x, c);
x = (Math.max(x, 16) + 16) >> 4;
x = x % 2 == 0 ? x + 1 : x;
if (benchmark){
x = 4;
Iris.info("Mantle Size: " + x + " Chunks " + C.BLUE + "BENCHMARK MODE");
} else {
Iris.info("Mantle Size: " + x + " Chunks");
Iris.info(" Object Mantle Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")");
Iris.info(" Jigsaw Mantle Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")");
Iris.info(" Carving Mantle Size: " + c + " (" + ((Math.max(c, 16) + 16) >> 4) + ")");
}
Iris.info("Mantle Size: " + x + " Chunks");
Iris.info(" Object Mantle Size: " + u + " (" + ((Math.max(u, 16) + 16) >> 4) + ")");
Iris.info(" Jigsaw Mantle Size: " + jig + " (" + ((Math.max(jig, 16) + 16) >> 4) + ")");
Iris.info(" Carving Mantle Size: " + c + " (" + ((Math.max(c, 16) + 16) >> 4) + ")");
return x;
}

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.engine.data.chunk;
import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.data.IrisBlockData;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
@@ -120,6 +121,8 @@ public class LinkedTerrainChunk implements TerrainChunk {
@Override
public synchronized void setBlock(int x, int y, int z, BlockData blockData) {
if (blockData instanceof IrisBlockData d)
blockData = d.getBase();
rawChunkData.setBlock(x, y, z, blockData);
}

View File

@@ -20,6 +20,7 @@ package com.volmit.iris.engine.data.chunk;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.BiomeBaseInjector;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.nbt.mca.Chunk;
import com.volmit.iris.util.nbt.mca.NBTWorld;
import lombok.AllArgsConstructor;
@@ -88,6 +89,8 @@ public class MCATerrainChunk implements TerrainChunk {
if (blockData == null) {
Iris.error("NULL BD");
}
if (blockData instanceof IrisBlockData data)
blockData = data.getBase();
mcaChunk.setBlockStateAt(xx, y, zz, NBTWorld.getCompound(blockData), false);
}

View File

@@ -39,6 +39,10 @@ public class IrisSeaFloorDecorator extends IrisEngineDecorator {
if (decorator != null) {
if (!decorator.isStacking()) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (height >= 0 || height < getEngine().getHeight()) {
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));

View File

@@ -45,6 +45,11 @@ public class IrisShoreLineDecorator extends IrisEngineDecorator {
IrisDecorator decorator = getDecorator(biome, realX, realZ);
if (decorator != null) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (!decorator.isStacking()) {
if (null != decorator.getBlockDataForTop(biome, getRng(), realX, height, realZ, getData())) {
data.set(x, height, z, decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData()));

View File

@@ -53,6 +53,11 @@ public class IrisSurfaceDecorator extends IrisEngineDecorator {
boolean underwater = height < getDimension().getFluidHeight();
if (decorator != null) {
if (!decorator.isForcePlace() && !decorator.getSlopeCondition().isDefault()
&& !decorator.getSlopeCondition().isValid(getComplex().getSlopeStream().get(realX, realZ))) {
return;
}
if (!decorator.isStacking()) {
bd = decorator.getBlockData100(biome, getRng(), realX, height, realZ, getData());

View File

@@ -22,10 +22,12 @@ import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.gui.components.RenderType;
import com.volmit.iris.core.gui.components.Renderer;
import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.nms.container.BlockPos;
import com.volmit.iris.core.nms.container.Pair;
import com.volmit.iris.core.service.ExternalDataSVC;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
@@ -38,6 +40,7 @@ import com.volmit.iris.util.context.ChunkContext;
import com.volmit.iris.util.context.IrisContext;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.format.C;
@@ -254,6 +257,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (B.isUpdatable(data)) {
getMantle().updateBlock(x, y, z);
}
if (data instanceof IrisBlockData d) {
getMantle().getMantle().set(x, y, z, d.getCustom());
} else {
getMantle().getMantle().remove(x, y, z, Identifier.class);
}
}
void blockUpdatedMetric();
@@ -261,72 +269,80 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
@ChunkCoordinates
@Override
default void updateChunk(Chunk c) {
if (c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() + 1)
&& c.getWorld().isChunkLoaded(c.getX(), c.getZ() + 1)
&& c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ())
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX(), c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ())
&& c.getWorld().isChunkLoaded(c.getX() + 1, c.getZ() - 1)
&& c.getWorld().isChunkLoaded(c.getX() - 1, c.getZ() + 1) && getMantle().getMantle().isLoaded(c)) {
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, tile) -> {
int betterY = y + getWorld().minHeight();
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile.getData()))
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), tile.getData().getTileId());
});
}));
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
KMap<Long, Integer> updates = new KMap<>();
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (!B.isFluid(c.getBlock(x & 15, y, z & 15).getBlockData())) {
return;
}
boolean u = false;
if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.DOWN).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.WEST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.EAST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.SOUTH).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.NORTH).getBlockData())) {
u = true;
}
if (u) {
updates.compute(Cache.key(x & 15, z & 15), (k, vv) -> {
if (vv != null) {
return Math.max(vv, y);
}
return y;
});
}
});
updates.forEach((k, v) -> update(Cache.keyX(k), v, Cache.keyZ(k), c, r));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (v != null && v.isUpdate()) {
int vx = x & 15;
int vz = z & 15;
update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ())));
if (vx > 0 && vx < 15 && vz > 0 && vz < 15) {
updateLighting(x, y, z, c);
}
}
});
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());
}, RNG.r.i(0, 20)));
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
if (c.getWorld().isChunkLoaded(c.getX() + x, c.getZ() + z))
continue;
Iris.debug("Chunk %s, %s [%s, %s] is not loaded".formatted(c.getX() + x, c.getZ() + z, x, z));
return;
}
}
if (!getMantle().getMantle().isLoaded(c)) {
Iris.debug("Mantle Chunk " + c.getX() + c.getX() + " is not loaded");
return;
}
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.TILE, () -> J.s(() -> {
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), TileWrapper.class, (x, y, z, tile) -> {
int betterY = y + getWorld().minHeight();
if (!TileData.setTileState(c.getBlock(x, betterY, z), tile.getData()))
Iris.warn("Failed to set tile entity data at [%d %d %d | %s] for tile %s!", x, betterY, z, c.getBlock(x, betterY, z).getBlockData().getMaterial().getKey(), tile.getData().getTileId());
});
}));
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.CUSTOM, () -> J.s(() -> {
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), Identifier.class, (x, y, z, v) -> {
Iris.service(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v);
});
}));
getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> {
PrecisionStopwatch p = PrecisionStopwatch.start();
KMap<Long, Integer> updates = new KMap<>();
RNG r = new RNG(Cache.key(c.getX(), c.getZ()));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterCavern.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (!B.isFluid(c.getBlock(x & 15, y, z & 15).getBlockData())) {
return;
}
boolean u = false;
if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.DOWN).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.WEST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.EAST).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.SOUTH).getBlockData())) {
u = true;
} else if (B.isAir(c.getBlock(x & 15, y, z & 15).getRelative(BlockFace.NORTH).getBlockData())) {
u = true;
}
if (u) {
updates.compute(Cache.key(x & 15, z & 15), (k, vv) -> {
if (vv != null) {
return Math.max(vv, y);
}
return y;
});
}
});
updates.forEach((k, v) -> update(Cache.keyX(k), v, Cache.keyZ(k), c, r));
getMantle().getMantle().iterateChunk(c.getX(), c.getZ(), MatterUpdate.class, (x, yf, z, v) -> {
int y = yf + getWorld().minHeight();
if (v != null && v.isUpdate()) {
int vx = x & 15;
int vz = z & 15;
update(x, y, z, c, new RNG(Cache.key(c.getX(), c.getZ())));
if (vx > 0 && vx < 15 && vz > 0 && vz < 15) {
updateLighting(x, y, z, c);
}
}
});
getMantle().getMantle().deleteChunkSlice(c.getX(), c.getZ(), MatterUpdate.class);
getMetrics().getUpdates().put(p.getMilliseconds());
}, RNG.r.i(0, 20)));
}
@BlockCoordinates

View File

@@ -0,0 +1,127 @@
package com.volmit.iris.engine.framework.placer;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
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.engine.framework.IrisLootEvent;
import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.object.IObjectPlacer;
import com.volmit.iris.engine.object.InventorySlotType;
import com.volmit.iris.engine.object.IrisLootTable;
import com.volmit.iris.engine.object.TileData;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.math.RNG;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.InventoryHolder;
@Getter
@EqualsAndHashCode(exclude = {"engine", "mantle"})
public class WorldObjectPlacer implements IObjectPlacer {
private final World world;
private final Engine engine;
private final EngineMantle mantle;
public WorldObjectPlacer(World world) {
var a = IrisToolbelt.access(world);
if (a == null || a.getEngine() == null) throw new IllegalStateException(world.getName() + " is not an Iris World!");
this.world = world;
this.engine = a.getEngine();
this.mantle = engine.getMantle();
}
@Override
public int getHighest(int x, int z, IrisData data) {
return mantle.getHighest(x, z, data);
}
@Override
public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
return mantle.getHighest(x, z, data, ignoreFluid);
}
@Override
public void set(int x, int y, int z, BlockData d) {
Block block = world.getBlockAt(x, y + world.getMinHeight(), z);
if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return;
InventorySlotType slot = null;
if (B.isStorageChest(d)) {
slot = InventorySlotType.STORAGE;
}
if (slot != null) {
RNG rx = new RNG(Cache.key(x, z));
KList<IrisLootTable> tables = engine.getLootTables(rx, block);
try {
Bukkit.getPluginManager().callEvent(new IrisLootEvent(engine, block, slot, tables));
if (!tables.isEmpty()){
Iris.debug("IrisLootEvent has been accessed");
}
if (tables.isEmpty())
return;
InventoryHolder m = (InventoryHolder) block.getState();
engine.addItems(false, m.getInventory(), rx, tables, slot, x, y, z, 15);
} catch (Throwable e) {
Iris.reportError(e);
}
}
block.setBlockData(d);
}
@Override
public BlockData get(int x, int y, int z) {
return world.getBlockAt(x, y + world.getMinHeight(), z).getBlockData();
}
@Override
public boolean isPreventingDecay() {
return mantle.isPreventingDecay();
}
@Override
public boolean isCarved(int x, int y, int z) {
return mantle.isCarved(x, y, z);
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y + world.getMinHeight(), z).getType().isSolid();
}
@Override
public boolean isUnderwater(int x, int z) {
return mantle.isUnderwater(x, z);
}
@Override
public int getFluidHeight() {
return mantle.getFluidHeight();
}
@Override
public boolean isDebugSmartBore() {
return mantle.isDebugSmartBore();
}
@Override
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState();
tile.toBukkitTry(state);
state.update();
}
}

View File

@@ -20,29 +20,19 @@ package com.volmit.iris.engine.jigsaw;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine;
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.context.IrisContext;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.math.AxisAlignedBB;
import com.volmit.iris.util.math.BlockPosition;
import com.volmit.iris.util.math.RNG;
import lombok.AccessLevel;
import lombok.Data;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import org.bukkit.inventory.InventoryHolder;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import org.bukkit.util.BlockVector;
import java.util.ArrayList;
import java.util.List;
@SuppressWarnings("ALL")
@Data
public class PlannedPiece {
private IrisPosition position;
@@ -50,11 +40,19 @@ public class PlannedPiece {
private IrisObject ogObject;
private IrisJigsawPiece piece;
private IrisObjectRotation rotation;
@EqualsAndHashCode.Exclude
private IrisData data;
private KList<IrisJigsawPieceConnector> connected;
private boolean dead = false;
private AxisAlignedBB box;
@EqualsAndHashCode.Exclude
private PlannedStructure structure;
@EqualsAndHashCode.Exclude
@Setter(AccessLevel.NONE)
private ParentConnection parent = null;
@EqualsAndHashCode.Exclude
@Setter(AccessLevel.NONE)
private KMap<IrisJigsawPieceConnector, IrisPosition> realPositions;
public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece) {
this(structure, position, piece, 0, 0, 0);
@@ -76,6 +74,7 @@ public class PlannedPiece {
this.object.setLoadKey(piece.getObject());
this.ogObject.setLoadKey(piece.getObject());
this.connected = new KList<>();
this.realPositions = new KMap<>();
}
@@ -94,7 +93,15 @@ public class PlannedPiece {
}
BlockVector v = getObject().getCenter();
box = object.getAABB().shifted(position.add(new IrisPosition(object.getCenter())));
IrisPosition pos = new IrisPosition();
IrisObjectPlacement options = piece.getPlacementOptions();
if (options != null && options.getTranslate() != null) {
IrisObjectTranslate translate = options.getTranslate();
pos.setX(translate.getX());
pos.setY(translate.getY());
pos.setZ(translate.getZ());
}
box = object.getAABB().shifted(position.add(new IrisPosition(object.getCenter())).add(pos));
return box;
}
@@ -126,11 +133,21 @@ public class PlannedPiece {
return c;
}
public boolean connect(IrisJigsawPieceConnector c) {
if (piece.getConnectors().contains(c)) {
return connected.addIfMissing(c);
}
public KList<IrisJigsawPieceConnector> getChildConnectors() {
ParentConnection pc = getParent();
KList<IrisJigsawPieceConnector> c = getConnected().copy();
if (pc != null) c.removeIf(i -> i.equals(pc.connector));
return c;
}
public boolean connect(IrisJigsawPieceConnector c, PlannedPiece p, IrisJigsawPieceConnector pc) {
if (piece.getConnectors().contains(c) && p.getPiece().getConnectors().contains(pc)) {
if (connected.contains(c) || p.connected.contains(pc)) return false;
connected.add(c);
p.connected.add(pc);
p.parent = new ParentConnection(this, c, p, pc);
return true;
}
return false;
}
@@ -162,108 +179,29 @@ public class PlannedPiece {
}
public boolean isFull() {
return connected.size() >= piece.getConnectors().size() || isDead();
return connected.size() >= piece.getConnectors().size();
}
public void place(World world) {
PlatformChunkGenerator a = IrisToolbelt.access(world);
int minY = 0;
if (a != null) {
minY = a.getEngine().getMinHeight();
if (!a.getEngine().getDimension().isBedrock())
minY--; //If the dimension has no bedrock, allow it to go a block lower
public void setRealPositions(int x, int y, int z, IObjectPlacer placer) {
boolean isUnderwater = piece.getPlacementOptions().isUnderwater();
for (IrisJigsawPieceConnector c : piece.getConnectors()) {
var pos = c.getPosition().add(new IrisPosition(x, 0, z));
if (y < 0) {
pos.setY(pos.getY() + placer.getHighest(pos.getX(), pos.getZ(), getData(), isUnderwater) + (object.getH() / 2));
} else {
pos.setY(pos.getY() + y);
}
realPositions.put(c, pos);
}
}
getPiece().getPlacementOptions().setTranslate(new IrisObjectTranslate());
getPiece().getPlacementOptions().setRotation(rotation);
int finalMinY = minY;
RNG rng = getStructure().getRng().nextParallelRNG(37555);
// TODO: REAL CLASSES!!!!!!!
getOgObject().place(position.getX() + getObject().getCenter().getBlockX(), position.getY() + getObject().getCenter().getBlockY(), position.getZ() + getObject().getCenter().getBlockZ(), new IObjectPlacer() {
@Override
public int getHighest(int x, int z, IrisData data) {
return position.getY();
}
@Override
public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
return position.getY();
}
@Override
public void set(int x, int y, int z, BlockData d) {
Block block = world.getBlockAt(x, y, z);
//Prevent blocks being set in or bellow bedrock
if (y <= finalMinY || block.getType() == Material.BEDROCK) return;
block.setBlockData(d);
if (a != null && getPiece().getPlacementOptions().getLoot().isNotEmpty() &&
block.getState() instanceof InventoryHolder) {
IrisLootTable table = getPiece().getPlacementOptions().getTable(block.getBlockData(), getData());
if (table == null) return;
Engine engine = a.getEngine();
engine.addItems(false, ((InventoryHolder) block.getState()).getInventory(),
rng.nextParallelRNG(BlockPosition.toLong(x, y, z)),
new KList<>(table), InventorySlotType.STORAGE, x, y, z, 15);
}
}
@Override
public BlockData get(int x, int y, int z) {
return world.getBlockAt(x, y, z).getBlockData();
}
@Override
public boolean isPreventingDecay() {
return false;
}
@Override
public boolean isCarved(int x, int y, int z) {
return false;
}
@Override
public boolean isSolid(int x, int y, int z) {
return world.getBlockAt(x, y, z).getType().isSolid();
}
@Override
public boolean isUnderwater(int x, int z) {
return false;
}
@Override
public int getFluidHeight() {
return 0;
}
@Override
public boolean isDebugSmartBore() {
return false;
}
@Override
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
BlockState state = world.getBlockAt(xx, yy, zz).getState();
tile.toBukkitTry(state);
state.update();
}
@Override
public Engine getEngine() {
if (IrisToolbelt.isIrisWorld(world)) {
return IrisToolbelt.access(world).getEngine();
}
return IrisContext.get().getEngine();
}
}, piece.getPlacementOptions(), rng, getData());
public record ParentConnection(PlannedPiece parent, IrisJigsawPieceConnector parentConnector, PlannedPiece self, IrisJigsawPieceConnector connector) {
public IrisPosition getTargetPosition() {
var pos = parent.realPositions.get(parentConnector);
if (pos == null) return null;
return pos.add(new IrisPosition(parentConnector.getDirection().toVector()))
.sub(connector.getPosition())
.sub(new IrisPosition(self.object.getCenter()));
}
}
}

View File

@@ -21,20 +21,21 @@ package com.volmit.iris.engine.jigsaw;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.framework.placer.WorldObjectPlacer;
import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.mantle.Mantle;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.matter.slices.JigsawPieceMatter;
import com.volmit.iris.util.matter.slices.container.JigsawPieceContainer;
import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer;
import com.volmit.iris.util.scheduling.J;
import lombok.Data;
import org.bukkit.Axis;
import org.bukkit.World;
import org.bukkit.block.TileState;
import org.bukkit.block.data.BlockData;
import java.util.function.Consumer;
@Data
public class PlannedStructure {
@@ -75,33 +76,44 @@ public class PlannedStructure {
}
}
public void place(MantleWriter placer, Mantle e, Engine eng) {
public boolean place(IObjectPlacer placer, Mantle e, Engine eng) {
IrisObjectPlacement options = new IrisObjectPlacement();
options.getRotation().setEnabled(false);
options.setRotation(IrisObjectRotation.of(0,0,0));
int startHeight = pieces.get(0).getPosition().getY();
boolean placed = false;
for (PlannedPiece i : pieces) {
place(i, startHeight, options, placer, e, eng);
if (place(i, startHeight, options, placer, e, eng))
placed = true;
}
if (placed) {
Position2 chunkPos = new Position2(position.getX() >> 4, position.getZ() >> 4);
Position2 regionPos = new Position2(chunkPos.getX() >> 5, chunkPos.getZ() >> 5);
JigsawStructuresContainer slice = e.get(regionPos.getX(), 0, regionPos.getZ(), JigsawStructuresContainer.class);
if (slice == null) slice = new JigsawStructuresContainer();
slice.add(structure, chunkPos);
e.set(regionPos.getX(), 0, regionPos.getZ(), slice);
}
return placed;
}
public void place(PlannedPiece i, int startHeight, IrisObjectPlacement o, MantleWriter placer, Mantle e, Engine eng) {
public boolean place(PlannedPiece i, int startHeight, IrisObjectPlacement o, IObjectPlacer placer, Mantle e, Engine eng) {
IrisObjectPlacement options = o;
if (i.getPiece().getPlacementOptions() != null) {
options = i.getPiece().getPlacementOptions();
options.getRotation().setEnabled(false);
options.setRotateTowardsSlope(false);
options.setWarp(new IrisGeneratorStyle(NoiseStyle.FLAT));
} else {
options.setMode(i.getPiece().getPlaceMode());
}
IrisObject vo = i.getOgObject();
IrisObject v = i.getObject();
int sx = (v.getW() / 2);
int sz = (v.getD() / 2);
int xx = i.getPosition().getX() + sx;
int zz = i.getPosition().getZ() + sz;
RNG rngf = new RNG(Cache.key(xx, zz));
int offset = i.getPosition().getY() - startHeight;
int height;
@@ -109,12 +121,23 @@ public class PlannedStructure {
if (i.getStructure().getStructure().getOverrideYRange() != null) {
height = (int) i.getStructure().getStructure().getOverrideYRange().get(rng, xx, zz, getData());
} else {
height = placer.getHighest(xx, zz, getData());
height = placer.getHighest(xx, zz, getData(), options.isUnderwater());
}
} else {
height = i.getStructure().getStructure().getLockY();
}
PlannedPiece.ParentConnection connection = i.getParent();
if (connection != null && connection.connector().isLockY()) {
var pos = connection.getTargetPosition();
if (pos != null) {
height = pos.getY();
offset = 0;
} else {
Iris.warn("Failed to get target position for " + v.getLoadKey());
}
}
height += offset + (v.getH() / 2);
if (options.getMode().equals(ObjectPlaceMode.PAINT)) {
@@ -123,75 +146,18 @@ public class PlannedStructure {
int id = rng.i(0, Integer.MAX_VALUE);
JigsawPieceContainer container = JigsawPieceContainer.toContainer(i.getPiece());
vo.place(xx, height, zz, new IObjectPlacer() {
@Override
public int getHighest(int x, int z, IrisData data) {
return placer.getHighest(x, z, data);
i.setRealPositions(xx, height, zz, placer);
return v.place(xx, height, zz, placer, options, rng, (b, data) -> {
e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id);
e.set(b.getX(), b.getY(), b.getZ(), container);
if (data instanceof IrisBlockData d) {
e.set(b.getX(), b.getY(), b.getZ(), d.getCustom());
}
@Override
public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) {
return placer.getHighest(x, z, data, ignoreFluid);
}
@Override
public void set(int x, int y, int z, BlockData d) {
placer.setData(x, y, z, container);
placer.set(x, y, z, d);
}
@Override
public BlockData get(int x, int y, int z) {
placer.setData(x, y, z, container);
return placer.get(x, y, z);
}
@Override
public boolean isPreventingDecay() {
return placer.isPreventingDecay();
}
@Override
public boolean isCarved(int x, int y, int z) {
return placer.isCarved(x, y, z);
}
@Override
public boolean isSolid(int x, int y, int z) {
return placer.isSolid(x, y, z);
}
@Override
public boolean isUnderwater(int x, int z) {
return placer.isUnderwater(x, z);
}
@Override
public int getFluidHeight() {
return placer.getFluidHeight();
}
@Override
public boolean isDebugSmartBore() {
return placer.isDebugSmartBore();
}
@Override
public void setTile(int xx, int yy, int zz, TileData<? extends TileState> tile) {
placer.setTile(xx, yy, zz, tile);
}
@Override
public Engine getEngine() {
return placer.getEngine();
}
}, options, rng, (b, data) -> e.set(b.getX(), b.getY(), b.getZ(), v.getLoadKey() + "@" + id), null, getData());
}, null, getData().getEngine() != null ? getData() : eng.getData()) != -1;
}
public void place(World world) {
for (PlannedPiece i : pieces) {
Iris.sq(() -> i.place(world));
}
public void place(WorldObjectPlacer placer, Consumer<Boolean> consumer) {
J.s(() -> consumer.accept(place(placer, placer.getMantle().getMantle(), placer.getEngine())));
}
private void generateOutwards() {
@@ -227,9 +193,7 @@ public class PlannedStructure {
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, IrisJigsawPiece idea) {
if (!piece.getPiece().getPlacementOptions().getRotation().isEnabled()) {
if (generateRotatedPiece(piece, pieceConnector, idea, 0, 0, 0)) {
return true;
}
return generateRotatedPiece(piece, pieceConnector, idea, 0, 0, 0);
}
KList<Integer> forder1 = new KList<Integer>().qadd(0).qadd(1).qadd(2).qadd(3).shuffle(rng);
@@ -276,7 +240,7 @@ public class PlannedStructure {
}
private boolean generateRotatedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, IrisJigsawPiece idea, int x, int y, int z) {
return generateRotatedPiece(piece, pieceConnector, idea, IrisObjectRotation.of(x, y, z));
return generateRotatedPiece(piece, pieceConnector, idea, IrisObjectRotation.of(x * 90D, y * 90D, z * 90D));
}
private boolean generatePositionedPiece(PlannedPiece piece, IrisJigsawPieceConnector pieceConnector, PlannedPiece test, IrisJigsawPieceConnector testConnector) {
@@ -300,8 +264,7 @@ public class PlannedStructure {
return false;
}
piece.connect(pieceConnector);
test.connect(testConnector);
piece.connect(pieceConnector, test, testConnector);
pieces.add(test);
return true;
@@ -310,7 +273,8 @@ public class PlannedStructure {
private KList<IrisJigsawPiece> getShuffledPiecesFor(IrisJigsawPieceConnector c) {
KList<IrisJigsawPiece> p = new KList<>();
for (String i : c.getPools().shuffleCopy(rng)) {
KList<String> pools = terminating && getStructure().getTerminatePool() != null ? new KList<>(getStructure().getTerminatePool()) : c.getPools().shuffleCopy(rng);
for (String i : pools) {
for (String j : getData().getJigsawPoolLoader().load(i).getPieces().shuffleCopy(rng)) {
IrisJigsawPiece pi = getData().getJigsawPieceLoader().load(j);
@@ -336,7 +300,9 @@ public class PlannedStructure {
}
public KList<PlannedPiece> getPiecesWithAvailableConnectors() {
return pieces.copy().removeWhere(PlannedPiece::isFull);
KList<PlannedPiece> available = pieces.copy().removeWhere(PlannedPiece::isFull);
if (!terminating) available.removeIf(PlannedPiece::isDead);
return available;
}
public int getVolume() {

View File

@@ -23,6 +23,7 @@ import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.engine.IrisComplex;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.engine.framework.SeedManager;
import com.volmit.iris.engine.mantle.components.MantleJigsawComponent;
import com.volmit.iris.engine.mantle.components.MantleObjectComponent;
import com.volmit.iris.engine.object.IObjectPlacer;
@@ -298,7 +299,7 @@ public interface EngineMantle extends IObjectPlacer {
default long getToUnload(){
return getMantle().getToUnload().size();
}
default long getNotClearedLoadedRegions(){
default long getNotQueuedLoadedRegions(){
return getMantle().getLoadedRegions().size() - getMantle().getToUnload().size();
}
default double getTectonicDuration(){

View File

@@ -23,13 +23,18 @@ import com.volmit.iris.engine.mantle.EngineMantle;
import com.volmit.iris.engine.mantle.IrisMantleComponent;
import com.volmit.iris.engine.mantle.MantleWriter;
import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.context.ChunkContext;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.mantle.MantleFlag;
import com.volmit.iris.util.math.Position2;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer;
import com.volmit.iris.util.noise.CNG;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -38,22 +43,21 @@ public class MantleJigsawComponent extends IrisMantleComponent {
public MantleJigsawComponent(EngineMantle engineMantle) {
super(engineMantle, MantleFlag.JIGSAW);
cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getSeedManager().getJigsaw()));
cng = NoiseStyle.STATIC.create(new RNG(jigsaw()));
}
@Override
public void generateLayer(MantleWriter writer, int x, int z, ChunkContext context) {
RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
int xxx = 8 + (x << 4);
int zzz = 8 + (z << 4);
IrisRegion region = getComplex().getRegionStream().get(xxx, zzz);
IrisBiome biome = getComplex().getTrueBiomeStream().get(xxx, zzz);
generateJigsaw(writer, rng, x, z, biome, region);
generateJigsaw(writer, x, z, biome, region);
}
@ChunkCoordinates
private void generateJigsaw(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region) {
boolean placed = false;
private void generateJigsaw(MantleWriter writer, int x, int z, IrisBiome biome, IrisRegion region) {
long seed = cng.fit(Integer.MIN_VALUE, Integer.MIN_VALUE, x, z);
if (getDimension().getStronghold() != null) {
List<Position2> poss = getDimension().getStrongholds(seed());
@@ -62,51 +66,71 @@ public class MantleJigsawComponent extends IrisMantleComponent {
for (Position2 pos : poss) {
if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) {
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold());
place(writer, pos.toIris(), structure, rng);
placed = true;
place(writer, pos.toIris(), structure, new RNG(seed));
return;
}
}
}
}
if (!placed) {
for (IrisJigsawStructurePlacement i : biome.getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
place(writer, position, structure, rng);
placed = true;
}
}
}
KSet<Position2> cachedRegions = new KSet<>();
KMap<String, KSet<Position2>> cache = new KMap<>();
KMap<Position2, Double> distanceCache = new KMap<>();
boolean placed = placeStructures(writer, seed, x, z, biome.getJigsawStructures(), cachedRegions, cache, distanceCache);
if (!placed)
placed = placeStructures(writer, seed, x, z, region.getJigsawStructures(), cachedRegions, cache, distanceCache);
if (!placed)
placeStructures(writer, seed, x, z, getDimension().getJigsawStructures(), cachedRegions, cache, distanceCache);
}
if (!placed) {
for (IrisJigsawStructurePlacement i : region.getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
place(writer, position, structure, rng);
placed = true;
}
}
}
@ChunkCoordinates
private boolean placeStructures(MantleWriter writer, long seed, int x, int z, KList<IrisJigsawStructurePlacement> structures,
KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
IrisJigsawStructurePlacement i = pick(structures, seed, x, z);
if (i == null || checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache))
return false;
RNG rng = new RNG(seed);
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
return place(writer, position, structure, rng);
}
if (!placed) {
for (IrisJigsawStructurePlacement i : getDimension().getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15));
IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure());
place(writer, position, structure, rng);
@ChunkCoordinates
private boolean checkMinDistances(KMap<String, Integer> minDistances, int x, int z, KSet<Position2> cachedRegions, KMap<String, KSet<Position2>> cache, KMap<Position2, Double> distanceCache) {
int range = 0;
for (int d : minDistances.values())
range = Math.max(range, d);
for (int xx = -range; xx <= range; xx++) {
for (int zz = -range; zz <= range; zz++) {
Position2 pos = new Position2((xx + x) >> 5, (zz + z) >> 5);
if (cachedRegions.contains(pos)) continue;
cachedRegions.add(pos);
JigsawStructuresContainer container = getMantle().get(pos.getX(), 0, pos.getZ(), JigsawStructuresContainer.class);
if (container == null) continue;
for (String key : container.getStructures()) {
cache.computeIfAbsent(key, k -> new KSet<>()).addAll(container.getPositions(key));
}
}
}
Position2 pos = new Position2(x, z);
for (String structure : minDistances.keySet()) {
if (!cache.containsKey(structure)) continue;
double minDist = minDistances.get(structure);
minDist = minDist * minDist;
for (Position2 sPos : cache.get(structure)) {
double dist = distanceCache.computeIfAbsent(sPos, position2 -> position2.distance(pos));
if (minDist > dist) return true;
}
}
return false;
}
@ChunkCoordinates
public IrisJigsawStructure guess(int x, int z) {
// todo The guess doesnt bring into account that the placer may return -1
boolean t = false;
RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z));
// todo doesnt bring skipped placements into account
long seed = cng.fit(Integer.MIN_VALUE, Integer.MIN_VALUE, x, z);
IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8);
IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8);
@@ -122,29 +146,26 @@ public class MantleJigsawComponent extends IrisMantleComponent {
}
}
for (IrisJigsawStructurePlacement i : biome.getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
return getData().getJigsawStructureLoader().load(i.getStructure());
}
}
IrisJigsawStructurePlacement i = pick(biome.getJigsawStructures(), seed, x, z);
if (i == null) i = pick(region.getJigsawStructures(), seed, x, z);
if (i == null) i = pick(getDimension().getJigsawStructures(), seed, x, z);
return i != null ? getData().getJigsawStructureLoader().load(i.getStructure()) : null;
}
for (IrisJigsawStructurePlacement i : region.getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
return getData().getJigsawStructureLoader().load(i.getStructure());
}
}
for (IrisJigsawStructurePlacement i : getDimension().getJigsawStructures()) {
if (rng.nextInt(i.getRarity()) == 0) {
return getData().getJigsawStructureLoader().load(i.getStructure());
}
}
return null;
@Nullable
@ChunkCoordinates
private IrisJigsawStructurePlacement pick(List<IrisJigsawStructurePlacement> structures, long seed, int x, int z) {
return IRare.pick(structures.stream()
.filter(p -> p.shouldPlace(getDimension().getJigsawStructureDivisor(), jigsaw(), x, z))
.toList(), new RNG(seed).nextDouble());
}
@BlockCoordinates
private void place(MantleWriter writer, IrisPosition position, IrisJigsawStructure structure, RNG rng) {
new PlannedStructure(structure, position, rng).place(writer, getMantle(), writer.getEngine());
private boolean place(MantleWriter writer, IrisPosition position, IrisJigsawStructure structure, RNG rng) {
return new PlannedStructure(structure, position, rng).place(writer, getMantle(), writer.getEngine());
}
private long jigsaw() {
return getEngineMantle().getEngine().getSeedManager().getJigsaw();
}
}

View File

@@ -27,6 +27,7 @@ import com.volmit.iris.engine.object.*;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.context.ChunkContext;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.documentation.BlockCoordinates;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.mantle.MantleFlag;
@@ -103,6 +104,9 @@ public class MantleObjectComponent extends IrisMantleComponent {
if (objectPlacement.isDolphinTarget() && objectPlacement.isUnderwater() && B.isStorageChest(data)) {
writer.setData(b.getX(), b.getY(), b.getZ(), MatterStructurePOI.BURIED_TREASURE);
}
if (data instanceof IrisBlockData d) {
writer.setData(b.getX(), b.getY(), b.getZ(), d.getCustom());
}
}, null, getData());
}
}

View File

@@ -194,13 +194,14 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return getCustomDerivitives() != null && getCustomDerivitives().isNotEmpty();
}
public double getGenLinkMax(String loadKey) {
public double getGenLinkMax(String loadKey, Engine engine) {
Integer v = genCacheMax.aquire(() ->
{
KMap<String, Integer> l = new KMap<>();
for (IrisBiomeGeneratorLink i : getGenerators()) {
l.put(i.getGenerator(), i.getMax());
l.put(i.getGenerator(), i.getMax(engine));
}
return l;
@@ -209,13 +210,13 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return v == null ? 0 : v;
}
public double getGenLinkMin(String loadKey) {
public double getGenLinkMin(String loadKey, Engine engine) {
Integer v = genCacheMin.aquire(() ->
{
KMap<String, Integer> l = new KMap<>();
for (IrisBiomeGeneratorLink i : getGenerators()) {
l.put(i.getGenerator(), i.getMin());
l.put(i.getGenerator(), i.getMin(engine));
}
return l;
@@ -450,26 +451,26 @@ public class IrisBiome extends IrisRegistrant implements IRare {
return real;
}
public int getMaxHeight() {
public int getMaxHeight(Engine engine) {
return maxHeight.aquire(() ->
{
int maxHeight = 0;
for (IrisBiomeGeneratorLink i : getGenerators()) {
maxHeight += i.getMax();
maxHeight += i.getMax(engine);
}
return maxHeight;
});
}
public int getMaxWithObjectHeight(IrisData data) {
public int getMaxWithObjectHeight(IrisData data, Engine engine) {
return maxWithObjectHeight.aquire(() ->
{
int maxHeight = 0;
for (IrisBiomeGeneratorLink i : getGenerators()) {
maxHeight += i.getMax();
maxHeight += i.getMax(engine);
}
int gg = 0;

View File

@@ -19,6 +19,7 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.datapack.IDataFixer;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
@@ -68,8 +69,10 @@ public class IrisBiomeCustom {
@Desc("The biome's category type")
private IrisBiomeCustomCategory category = IrisBiomeCustomCategory.plains;
@MinNumber(0)
@MaxNumber(20)
@Desc("The spawn rarity of any defined spawners")
private int spawnRarity = -1;
private int spawnRarity = 0;
@Desc("The color of the sky, top half of sky. (hex format)")
private String skyColor = "#79a8e1";
@@ -89,7 +92,7 @@ public class IrisBiomeCustom {
@Desc("The color of foliage (hex format). Leave blank / don't define to not change")
private String foliageColor = "";
public String generateJson() {
public String generateJson(IDataFixer fixer) {
JSONObject effects = new JSONObject();
effects.put("sky_color", parseColor(getSkyColor()));
effects.put("fog_color", parseColor(getFogColor()));
@@ -155,7 +158,7 @@ public class IrisBiomeCustom {
j.put("spawners", spawners);
}
return j.toString(4);
return fixer.fixCustomBiome(this, j).toString(4);
}
private int parseColor(String c) {

View File

@@ -18,13 +18,13 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.interpolation.IrisInterpolation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.*;
import lombok.experimental.Accessors;
@Snippet("generator-layer")
@@ -39,22 +39,23 @@ public class IrisBiomeGeneratorLink {
@RegistryListResource(IrisGenerator.class)
@Desc("The generator id")
private String generator = "default";
@DependsOn({"min", "max"})
@DependsOn({ "min", "max" })
@Required
@MinNumber(-2032) // TODO: WARNING HEIGHT
@MaxNumber(2032) // TODO: WARNING HEIGHT
@Desc("The min block value (value + fluidHeight)")
@Getter(AccessLevel.NONE)
private int min = 0;
@DependsOn({"min", "max"})
@DependsOn({ "min", "max" })
@Required
@MinNumber(-2032) // TODO: WARNING HEIGHT
@MaxNumber(2032) // TODO: WARNING HEIGHT
@Getter(AccessLevel.NONE)
@Desc("The max block value (value + fluidHeight)")
private int max = 0;
public IrisGenerator getCachedGenerator(DataProvider g) {
return gen.aquire(() ->
{
return gen.aquire(() -> {
IrisGenerator gen = g.getData().getGeneratorLoader().load(getGenerator());
if (gen == null) {
@@ -65,6 +66,70 @@ public class IrisBiomeGeneratorLink {
});
}
private int[] getBiomeGeneratorsRaw(Engine engine) {
int max = engine.getDimension().getMinHeight();
int min = engine.getDimension().getMaxHeight();
for (IrisBiome biome : engine.getAllBiomes()) {
for (IrisBiomeGeneratorLink i : biome.getGenerators()) {
int biomeRawMax = i.getMaxRaw();
int biomeRawMin = i.getMinRaw();
if (max < biomeRawMax)
max = biomeRawMax;
if (min > biomeRawMin)
min = biomeRawMin;
}
}
return new int[] { min, max };
}
private int calculateHeight(Engine engine, int option) {
int dmx = engine.getDimension().getMaxHeight();
int dmn = engine.getDimension().getMinHeight();
int[] heights = getBiomeGeneratorsRaw(engine);
int gmx = heights[1];
int gmn = heights[0];
int mx = getMaxRaw();
int mn = getMinRaw();
if (engine.getDimension().isSmartVanillaHeight()) {
if (mx > 0)
mx = Math.min((int) (((float) mx / (float) gmx) * 300.0f), 300);
if (mx < 0)
mx = Math.min((int) (((float) mx / (float) gmn) * 300.0f), 56);
if (mn > 0)
mn = Math.min((int) (((float) mn / (float) gmx) * 300.0f), 300);
if (mn < 0)
mn = Math.min((int) (((float) mn / (float) gmn) * 300.0f), 56);
}
if (option == 1) {
return mx;
}
if (option == 0) {
return mn;
}
Iris.error("Fatal Generator error!");
return 0;
}
public int getMax(Engine engine) {
return calculateHeight(engine, 1);
}
public int getMin(Engine engine) {
return calculateHeight(engine, 0);
}
private int getMaxRaw() {
return max;
}
private int getMinRaw() {
return min;
}
public double getHeight(DataProvider xg, double x, double z, long seed) {
double g = getCachedGenerator(xg).getHeight(x, z, seed);
g = g < 0 ? 0 : g;

View File

@@ -82,13 +82,17 @@ public class IrisCavePlacer implements IRare {
}
if (y == -1) {
int h = (int) caveStartHeight.get(rng, x, z, data);
int ma = breakSurface ? h : (int) (engine.getComplex().getHeightStream().get(x, z) - 9);
y = Math.min(h, ma);
if(!breakSurface) {
int eH = engine.getHeight(x, z);
if (caveStartHeight.getMax() > eH) {
caveStartHeight.setMax(eH);
}
}
y = (int) caveStartHeight.get(rng, x, z, data);
}
try {
cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), waterHint);
cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), waterHint);
} catch (Throwable e) {
e.printStackTrace();
fail.set(true);

View File

@@ -55,6 +55,8 @@ public class IrisDecorator {
@ArrayType(min = 1, type = IrisBlockData.class)
@Desc("When set, the decorator will never place onto any of these blocks.")
private KList<IrisBlockData> blacklist;
@Desc("The slope at which this decorator can be placed. Range from 0 to 10 by default. Calculated from a 3-block radius from the center of the decorator placement.")
private IrisSlopeClip slopeCondition = new IrisSlopeClip();
@DependsOn({"scaleStack", "stackMin", "stackMax"})
@Desc("If stackMax is set to true, use this to limit its max height for large caverns")
private int absoluteMaxStack = 30;

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.nms.datapack.IDataFixer;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
@@ -207,6 +208,8 @@ public class IrisDimension extends IrisRegistrant {
private IrisCarving carving = new IrisCarving();
@Desc("Configuration of fluid bodies such as rivers & lakes")
private IrisFluidBodies fluidBodies = new IrisFluidBodies();
@Desc("forceConvertTo320Height")
private Boolean forceConvertTo320Height = false;
@Desc("The world environment")
private Environment environment = Environment.NORMAL;
@RegistryListResource(IrisRegion.class)
@@ -217,6 +220,8 @@ public class IrisDimension extends IrisRegistrant {
@ArrayType(min = 1, type = IrisJigsawStructurePlacement.class)
@Desc("Jigsaw structures")
private KList<IrisJigsawStructurePlacement> jigsawStructures = new KList<>();
@Desc("The jigsaw structure divisor to use when generating missing jigsaw placement values")
private double jigsawStructureDivisor = 18;
@Required
@MinNumber(0)
@MaxNumber(1024)
@@ -228,6 +233,8 @@ public class IrisDimension extends IrisRegistrant {
private IrisRange dimensionHeightEnd = new IrisRange(-64, 320);
@Desc("Define the min and max Y bounds of this dimension. Please keep in mind that Iris internally generates from 0 to (max - min). \n\nFor example at -64 to 320, Iris is internally generating to 0 to 384, then on outputting chunks, it shifts it down by the min height (64 blocks). The default is -64 to 320. \n\nThe fluid height is placed at (fluid height + min height). So a fluid height of 63 would actually show up in the world at 1.")
private IrisRange dimensionHeightNether = new IrisRange(-64, 320);
@Desc("Enable smart vanilla height")
private boolean smartVanillaHeight = false;
@RegistryListResource(IrisBiome.class)
@Desc("Keep this either undefined or empty. Setting any biome name into this will force iris to only generate the specified biome. Great for testing.")
private String focus = "";
@@ -237,7 +244,7 @@ public class IrisDimension extends IrisRegistrant {
@MinNumber(0.0001)
@MaxNumber(512)
@Desc("Zoom in or out the biome size. Higher = bigger biomes")
private double biomeZoom = 5D;
private double biomeZoom = 1D;
@MinNumber(0)
@MaxNumber(360)
@Desc("You can rotate the input coordinates by an angle. This can make terrain appear more natural (less sharp corners and lines). This literally rotates the entire dimension by an angle. Hint: Try 12 degrees or something not on a 90 or 45 degree angle.")
@@ -439,7 +446,7 @@ public class IrisDimension extends IrisRegistrant {
return landBiomeStyle;
}
public boolean installDataPack(DataProvider data, File datapacks) {
public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, double ultimateMaxHeight, double ultimateMinHeight) {
boolean write = false;
boolean changed = false;
@@ -459,7 +466,7 @@ public class IrisDimension extends IrisRegistrant {
Iris.verbose(" Installing Data Pack Biome: " + output.getPath());
output.getParentFile().mkdirs();
try {
IO.writeAll(output, j.generateJson());
IO.writeAll(output, j.generateJson(fixer));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
@@ -470,7 +477,9 @@ public class IrisDimension extends IrisRegistrant {
if (!dimensionHeight.equals(new IrisRange(-64, 320)) && this.name.equalsIgnoreCase("overworld")) {
Iris.verbose(" Installing Data Pack Dimension Types: \"minecraft:overworld\", \"minecraft:the_nether\", \"minecraft:the_end\"");
changed = writeDimensionType(changed, datapacks);
dimensionHeight.setMax(ultimateMaxHeight);
dimensionHeight.setMin(ultimateMinHeight);
changed = writeDimensionType(fixer, changed, datapacks);
}
if (write) {
@@ -509,13 +518,13 @@ public class IrisDimension extends IrisRegistrant {
}
public boolean writeDimensionType(boolean changed, File datapacks) {
public boolean writeDimensionType(IDataFixer fixer, boolean changed, File datapacks) {
File dimTypeOverworld = new File(datapacks, "iris/data/minecraft/dimension_type/overworld.json");
if (!dimTypeOverworld.exists())
changed = true;
dimTypeOverworld.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeOverworld, generateDatapackJsonOverworld());
IO.writeAll(dimTypeOverworld, generateDatapackJsonOverworld(fixer));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
@@ -527,7 +536,7 @@ public class IrisDimension extends IrisRegistrant {
changed = true;
dimTypeNether.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeNether, generateDatapackJsonNether());
IO.writeAll(dimTypeNether, generateDatapackJsonNether(fixer));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
@@ -539,7 +548,7 @@ public class IrisDimension extends IrisRegistrant {
changed = true;
dimTypeEnd.getParentFile().mkdirs();
try {
IO.writeAll(dimTypeEnd, generateDatapackJsonEnd());
IO.writeAll(dimTypeEnd, generateDatapackJsonEnd(fixer));
} catch (IOException e) {
Iris.reportError(e);
e.printStackTrace();
@@ -548,27 +557,27 @@ public class IrisDimension extends IrisRegistrant {
return changed;
}
private String generateDatapackJsonOverworld() {
private String generateDatapackJsonOverworld(IDataFixer fixer) {
JSONObject obj = new JSONObject(DP_OVERWORLD_DEFAULT);
obj.put("min_y", dimensionHeight.getMin());
obj.put("height", dimensionHeight.getMax() - dimensionHeight.getMin());
obj.put("logical_height", logicalHeight);
return obj.toString(4);
return fixer.fixDimension(obj).toString(4);
}
private String generateDatapackJsonNether() {
private String generateDatapackJsonNether(IDataFixer fixer) {
JSONObject obj = new JSONObject(DP_NETHER_DEFAULT);
obj.put("min_y", dimensionHeightNether.getMin());
obj.put("height", dimensionHeightNether.getMax() - dimensionHeightNether.getMin());
obj.put("logical_height", logicalHeightNether);
return obj.toString(4);
return fixer.fixDimension(obj).toString(4);
}
private String generateDatapackJsonEnd() {
private String generateDatapackJsonEnd(IDataFixer fixer) {
JSONObject obj = new JSONObject(DP_END_DEFAULT);
obj.put("min_y", dimensionHeightEnd.getMin());
obj.put("height", dimensionHeightEnd.getMax() - dimensionHeightEnd.getMin());
obj.put("logical_height", logicalHeightEnd);
return obj.toString(4);
return fixer.fixDimension(obj).toString(4);
}
}

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.loader.IrisRegistrant;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.collection.KList;
@@ -28,6 +29,7 @@ import com.volmit.iris.util.format.C;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.misc.E;
import com.volmit.iris.util.plugin.Chunks;
import com.volmit.iris.util.plugin.VolmitSender;
import com.volmit.iris.util.scheduling.J;
@@ -41,6 +43,7 @@ import org.bukkit.*;
import org.bukkit.attribute.Attributable;
import org.bukkit.entity.*;
import org.bukkit.entity.Panda.Gene;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.loot.LootContext;
@@ -63,10 +66,14 @@ import java.util.concurrent.atomic.AtomicReference;
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisEntity extends IrisRegistrant {
private static final Particle ITEM = E.getOrDefault(Particle.class, "ITEM_CRACK", "ITEM");
@Required
@Desc("The type of entity to spawn. To spawn a mythic mob, set this type to unknown and define mythic type.")
private EntityType type = EntityType.UNKNOWN;
@Desc("The SpawnReason to spawn the entity with.")
private CreatureSpawnEvent.SpawnReason reason = CreatureSpawnEvent.SpawnReason.NATURAL;
@Desc("The custom name of this entity")
private String customName = "";
@@ -381,7 +388,7 @@ public class IrisEntity extends IrisRegistrant {
if (e.getLocation().getBlock().getType().isSolid() || ((LivingEntity) e).getEyeLocation().getBlock().getType().isSolid()) {
e.teleport(start.add(new Vector(0, 0.1, 0)));
ItemStack itemCrackData = new ItemStack(((LivingEntity) e).getEyeLocation().clone().subtract(0, 2, 0).getBlock().getBlockData().getMaterial());
e.getWorld().spawnParticle(Particle.ITEM_CRACK, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
e.getWorld().spawnParticle(ITEM, ((LivingEntity) e).getEyeLocation(), 6, 0.2, 0.4, 0.2, 0.06f, itemCrackData);
if (M.r(0.2)) {
e.getWorld().playSound(e.getLocation(), Sound.BLOCK_CHORUS_FLOWER_GROW, 0.8f, 0.1f);
}
@@ -457,7 +464,7 @@ public class IrisEntity extends IrisRegistrant {
}
return at.getWorld().spawnEntity(at, getType());
return INMS.get().spawnEntity(at, getType(), getReason());
}
public boolean isCitizens() {

View File

@@ -19,21 +19,28 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.engine.data.cache.AtomicCache;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.object.annotations.*;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.math.Vector3d;
import com.volmit.iris.util.matter.MatterMarker;
import com.volmit.iris.util.matter.slices.MarkerMatter;
import io.lumine.mythic.bukkit.adapters.BukkitEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.BoundingBox;
@Snippet("entity-spawn")
@Accessors(chain = true)
@@ -165,12 +172,19 @@ public class IrisEntitySpawn implements IRare {
return null;
}
Entity e = irisEntity.spawn(g, at.add(0.5, 0, 0.5), rng.aquire(() -> new RNG(g.getSeedManager().getEntity())));
Vector3d boundingBox = INMS.get().getBoundingbox(irisEntity.getType());
if (!ignoreSurfaces && boundingBox != null) {
boolean isClearForSpawn = isAreaClearForSpawn(at, boundingBox);
if (!isClearForSpawn) {
return null;
}
}
Entity e = irisEntity.spawn(g, at.add(0.5, 0.5, 0.5), rng.aquire(() -> new RNG(g.getSeedManager().getEntity())));
if (e != null) {
Iris.debug("Spawned " + C.DARK_AQUA + "Entity<" + getEntity() + "> " + C.GREEN + e.getType() + C.LIGHT_PURPLE + " @ " + C.GRAY + e.getLocation().getX() + ", " + e.getLocation().getY() + ", " + e.getLocation().getZ());
}
return e;
} catch (Throwable e) {
Iris.reportError(e);
@@ -179,4 +193,25 @@ public class IrisEntitySpawn implements IRare {
return null;
}
}
private boolean isAreaClearForSpawn(Location center, Vector3d boundingBox) {
World world = center.getWorld();
int startX = center.getBlockX() - (int) (boundingBox.x / 2);
int endX = center.getBlockX() + (int) (boundingBox.x / 2);
int startY = center.getBlockY();
int endY = center.getBlockY() + (int) boundingBox.y;
int startZ = center.getBlockZ() - (int) (boundingBox.z / 2);
int endZ = center.getBlockZ() + (int) (boundingBox.z / 2);
for (int x = startX; x <= endX; x++) {
for (int y = startY; y <= endY; y++) {
for (int z = startZ; z <= endZ; z++) {
if (world.getBlockAt(x, y, z).getType() != Material.AIR) {
return false;
}
}
}
}
return true;
}
}

View File

@@ -0,0 +1,29 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.annotations.Snippet;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Snippet("jigsaw-structure-min-distance")
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Desc("Represents the min distance between jigsaw structure placements")
@Data
public class IrisJigsawMinDistance {
@Required
@RegistryListResource(IrisJigsawStructure.class)
@Desc("The structure to check against")
private String structure;
@Required
@MinNumber(0)
@Desc("The min distance in blocks to a placed structure\nWARNING: The performance impact scales exponentially!")
private int distance;
}

View File

@@ -101,19 +101,12 @@ public class IrisJigsawPiece extends IrisRegistrant {
}
public IrisJigsawPiece copy() {
IrisJigsawPiece p = new IrisJigsawPiece();
p.setObject(getObject());
p.setLoader(getLoader());
p.setLoadKey(getLoadKey());
p.setLoadFile(getLoadFile());
p.setConnectors(new KList<>());
p.setPlacementOptions(getPlacementOptions());
for (IrisJigsawPieceConnector i : getConnectors()) {
p.getConnectors().add(i.copy());
}
return p;
var gson = getLoader().getGson();
IrisJigsawPiece copy = gson.fromJson(gson.toJson(this), IrisJigsawPiece.class);
copy.setLoader(getLoader());
copy.setLoadKey(getLoadKey());
copy.setLoadFile(getLoadFile());
return copy;
}
public boolean isTerminal() {

View File

@@ -79,6 +79,9 @@ public class IrisJigsawPieceConnector {
@Required
private IrisDirection direction = IrisDirection.UP_POSITIVE_Y;
@Desc("Lock the Y position of this connector")
private boolean lockY = false;
public String toString() {
return direction.getFace().name() + "@(" + position.getX() + "," + position.getY() + "," + position.getZ() + ")";
}

View File

@@ -56,6 +56,10 @@ public class IrisJigsawStructure extends IrisRegistrant {
@Desc("If set to true, iris will look for any pieces with only one connector in valid pools for edge connectors and attach them to 'terminate' the paths/piece connectors. Essentially it caps off ends. For example in a village, Iris would add houses to the ends of roads where possible. For terminators to be selected, they can only have one connector or they wont be chosen.")
private boolean terminate = true;
@RegistryListResource(IrisJigsawPool.class)
@Desc("The pool to use when terminating pieces")
private String terminatePool = null;
@Desc("Override the y range instead of placing on the height map")
private IrisStyledRange overrideYRange = null;

View File

@@ -18,17 +18,24 @@
package com.volmit.iris.engine.object;
import com.volmit.iris.Iris;
import com.volmit.iris.engine.object.annotations.ArrayType;
import com.volmit.iris.engine.object.annotations.Desc;
import com.volmit.iris.engine.object.annotations.MaxNumber;
import com.volmit.iris.engine.object.annotations.MinNumber;
import com.volmit.iris.engine.object.annotations.RegistryListResource;
import com.volmit.iris.engine.object.annotations.Required;
import com.volmit.iris.engine.object.annotations.Snippet;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.math.RNG;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Snippet("jigsaw-structure-placement")
@Accessors(chain = true)
@NoArgsConstructor
@@ -36,13 +43,99 @@ import lombok.experimental.Accessors;
@Desc("Represents a jigsaw structure placer")
@Data
@EqualsAndHashCode(callSuper = false)
public class IrisJigsawStructurePlacement {
public class IrisJigsawStructurePlacement implements IRare {
@RegistryListResource(IrisJigsawStructure.class)
@Required
@Desc("The structure to place")
private String structure;
@Required
@Desc("The 1 in X chance rarity")
@Desc("The 1 in X chance rarity applies when generating multiple structures at once")
private int rarity = 100;
@Required
@Desc("The salt to use when generating the structure (to differentiate structures)")
@MinNumber(Long.MIN_VALUE)
@MaxNumber(Long.MAX_VALUE)
private long salt = 0;
@Required
@MinNumber(0)
@Desc("Average distance in chunks between two neighboring generation attempts")
private int spacing = -1;
@Required
@MinNumber(0)
@Desc("Minimum distance in chunks between two neighboring generation attempts\nThe maximum distance of two neighboring generation attempts is 2*spacing - separation")
private int separation = -1;
@Desc("The method used to spread the structure")
private SpreadType spreadType = SpreadType.TRIANGULAR;
@ArrayType(type = IrisJigsawMinDistance.class)
@Desc("List of minimum distances to check for")
private KList<IrisJigsawMinDistance> minDistances = new KList<>();
public KMap<String, Integer> collectMinDistances() {
KMap<String, Integer> map = new KMap<>();
for (IrisJigsawMinDistance d : minDistances) {
map.compute(d.getStructure(), (k, v) -> v != null ? Math.min(toChunks(d.getDistance()), v) : toChunks(d.getDistance()));
}
return map;
}
private int toChunks(int blocks) {
return (int) Math.ceil(blocks / 16d);
}
private void calculateMissing(double divisor, long seed) {
seed = seed + hashCode();
if (salt == 0) {
salt = new RNG(seed).nextLong(Integer.MIN_VALUE, Integer.MAX_VALUE);
}
if (separation == -1 || spacing == -1) {
separation = (int) Math.round(rarity / divisor);
spacing = new RNG(seed).nextInt(separation, separation * 2);
}
}
@ChunkCoordinates
public boolean shouldPlace(double divisor, long seed, int x, int z) {
calculateMissing(divisor, seed);
if (separation > spacing) {
separation = spacing;
Iris.warn("JigsawStructurePlacement: separation must be less than or equal to spacing");
}
int i = Math.floorDiv(x, spacing);
int j = Math.floorDiv(z, spacing);
RNG rng = new RNG(i * 341873128712L + j * 132897987541L + seed + salt);
int k = spacing - separation;
int l = spreadType.apply(rng, k);
int m = spreadType.apply(rng, k);
return i * spacing + l == x && j * spacing + m == z;
}
@Desc("Spread type")
public enum SpreadType {
@Desc("Linear spread")
LINEAR(RNG::i),
@Desc("Triangular spread")
TRIANGULAR((rng, bound) -> (rng.i(bound) + rng.i(bound)) / 2);
private final SpreadMethod method;
SpreadType(SpreadMethod method) {
this.method = method;
}
public int apply(RNG rng, int bound) {
return method.apply(rng, bound);
}
}
private interface SpreadMethod {
int apply(RNG rng, int bound);
}
}

View File

@@ -29,7 +29,6 @@ import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import com.volmit.iris.util.json.JSONObject;
import com.volmit.iris.util.math.RNG;
import com.volmit.iris.util.noise.CNG;
import lombok.AllArgsConstructor;
@@ -146,7 +145,7 @@ public class IrisLoot {
// TODO Better Third Party Item Acquisition
private ItemStack getItemStack(RNG rng) {
if (!type.startsWith("minecraft:") && type.contains(":")) {
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type));
Optional<ItemStack> opt = Iris.service(ExternalDataSVC.class).getItemStack(Identifier.fromString(type), customNbt);
if (opt.isEmpty()) {
Iris.warn("Unknown Material: " + type);
return new ItemStack(Material.AIR);

View File

@@ -59,6 +59,10 @@ public class IrisLootTable extends IrisRegistrant {
@Desc("The minimum amount of loot that can be picked in this table at a time.")
private int minPicked = 1;
@MinNumber(1)
@Desc("The maximum amount of tries to generate loot")
private int maxTries = 10;
@Desc("The loot in this table")
@ArrayType(min = 1, type = IrisLoot.class)
private KList<IrisLoot> loot = new KList<>();
@@ -67,9 +71,10 @@ public class IrisLootTable extends IrisRegistrant {
KList<ItemStack> lootf = new KList<>();
int m = 0;
int c = 0;
int mx = rng.i(getMinPicked(), getMaxPicked());
while (m < mx) {
while (m < mx && c++ < getMaxTries()) {
int num = rng.i(loot.size());
IrisLoot l = loot.get(num);

View File

@@ -136,6 +136,8 @@ public class IrisObjectPlacement {
@ArrayType(type = String.class)
@Desc("List of objects to this object is forbidden to collied with")
private KList<String> forbiddenCollisions = new KList<>();
@Desc("Ignore any placement restrictions for this object")
private boolean forcePlace = false;
private transient AtomicCache<TableCache> cache = new AtomicCache<>();
public IrisObjectPlacement toPlacement(String... place) {

View File

@@ -101,6 +101,11 @@ public class IrisObjectRotation {
i.setPosition(rotate(i.getPosition()));
i.setDirection(rotate(i.getDirection()));
}
try {
var translate = piece.getPlacementOptions().getTranslate();
var pos = rotate(new IrisPosition(translate.getX(), translate.getY(), translate.getZ()));
translate.setX(pos.getX()).setY(pos.getY()).setZ(pos.getZ());
} catch (NullPointerException ignored) {}
return piece;
}

View File

@@ -1,413 +1,444 @@
/*
* 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.engine.platform;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisWorld;
import com.volmit.iris.engine.object.StudioMode;
import com.volmit.iris.engine.platform.studio.StudioGenerator;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
import com.volmit.iris.util.io.ReactiveFolder;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@EqualsAndHashCode(callSuper = true)
@Data
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator, Listener {
private static final int LOAD_LOCKS = Runtime.getRuntime().availableProcessors() * 4;
private final Semaphore loadLock;
private final IrisWorld world;
private final File dataLocation;
private final String dimensionKey;
private final ReactiveFolder folder;
private final ReentrantLock lock = new ReentrantLock();
private final KList<BlockPopulator> populators;
private final ChronoLatch hotloadChecker;
private final AtomicBoolean setup;
private final boolean studio;
private final AtomicInteger a = new AtomicInteger(0);
private Engine engine;
private Looper hotloader;
private StudioMode lastMode;
private DummyBiomeProvider dummyBiomeProvider;
@Setter
private StudioGenerator studioGenerator;
private boolean initialized = false;
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) {
setup = new AtomicBoolean(false);
studioGenerator = null;
dummyBiomeProvider = new DummyBiomeProvider();
populators = new KList<>();
loadLock = new Semaphore(LOAD_LOCKS);
this.world = world;
this.hotloadChecker = new ChronoLatch(1000, false);
this.studio = studio;
this.dataLocation = dataLocation;
this.dimensionKey = dimensionKey;
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
}
private static Field getField(Class clazz, String fieldName)
throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
@EventHandler
public void onWorldInit(WorldInitEvent event) {
try {
if (!initialized) {
world.setRawWorldSeed(event.getWorld().getSeed());
if (world.name().equals(event.getWorld().getName())) {
INMS.get().inject(event.getWorld().getSeed(), getEngine(event.getWorld()), event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void setupEngine() {
IrisData data = IrisData.get(dataLocation);
IrisDimension dimension = data.getDimensionLoader().load(dimensionKey);
if (dimension == null) {
Iris.error("Oh No! There's no pack in " + data.getDataFolder().getPath() + " or... there's no dimension for the key " + dimensionKey);
IrisDimension test = IrisData.loadAnyDimension(dimensionKey);
if (test != null) {
Iris.warn("Looks like " + dimensionKey + " exists in " + test.getLoadFile().getPath() + " ");
Iris.service(StudioSVC.class).installIntoWorld(Iris.getSender(), dimensionKey, dataLocation.getParentFile().getParentFile());
Iris.warn("Attempted to install into " + data.getDataFolder().getPath());
data.dump();
data.clearLists();
test = data.getDimensionLoader().load(dimensionKey);
if (test != null) {
Iris.success("Woo! Patched the Engine!");
dimension = test;
} else {
Iris.error("Failed to patch dimension!");
throw new RuntimeException("Missing Dimension: " + dimensionKey);
}
} else {
Iris.error("Nope, you don't have an installation containing " + dimensionKey + " try downloading it?");
throw new RuntimeException("Missing Dimension: " + dimensionKey);
}
}
lastMode = StudioMode.NORMAL;
engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
populators.clear();
}
@Override
public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) {
try {
loadLock.acquire();
IrisBiomeStorage st = new IrisBiomeStorage();
TerrainChunk tc = TerrainChunk.createUnsafe(world, st);
Hunk<BlockData> blocks = Hunk.view(tc);
Hunk<Biome> biomes = Hunk.view(tc, tc.getMinHeight(), tc.getMaxHeight());
this.world.bind(world);
getEngine().generate(x << 4, z << 4, blocks, biomes, true);
Iris.debug("Regenerated " + x + " " + z);
int t = 0;
for (int i = getEngine().getHeight() >> 4; i >= 0; i--) {
if (!world.isChunkLoaded(x, z)) {
continue;
}
Chunk c = world.getChunkAt(x, z);
for (Entity ee : c.getEntities()) {
if (ee instanceof Player) {
continue;
}
J.s(ee::remove);
}
J.s(() -> engine.getWorldManager().onChunkLoad(c, false));
int finalI = i;
jobs.accept(() -> {
for (int xx = 0; xx < 16; xx++) {
for (int yy = 0; yy < 16; yy++) {
for (int zz = 0; zz < 16; zz++) {
if (yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) {
continue;
}
c.getBlock(xx, yy + (finalI << 4) + world.getMinHeight(), zz)
.setBlockData(tc.getBlockData(xx, yy + (finalI << 4) + world.getMinHeight(), zz), false);
}
}
}
});
}
loadLock.release();
} catch (Throwable e) {
loadLock.release();
Iris.error("======================================");
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
ChunkData d = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
}
}
}
}
private Engine getEngine(WorldInfo world) {
if (setup.get()) {
return getEngine();
}
lock.lock();
if (setup.get()) {
return getEngine();
}
setup.set(true);
getWorld().setRawWorldSeed(world.getSeed());
setupEngine();
this.hotloader = studio ? new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
} : null;
if (studio) {
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
}
lock.unlock();
return engine;
}
@Override
public void close() {
withExclusiveControl(() -> {
if (isStudio()) {
hotloader.interrupt();
}
getEngine().close();
folder.clear();
populators.clear();
});
}
@Override
public boolean isStudio() {
return studio;
}
@Override
public void hotload() {
if (!isStudio()) {
return;
}
withExclusiveControl(() -> getEngine().hotload());
}
public void withExclusiveControl(Runnable r) {
J.a(() -> {
try {
loadLock.acquire(LOAD_LOCKS);
r.run();
loadLock.release(LOAD_LOCKS);
} catch (Throwable e) {
Iris.reportError(e);
}
});
}
@Override
public void touch(World world) {
getEngine(world);
}
@Override
public void generateNoise(@NotNull WorldInfo world, @NotNull Random random, int x, int z, @NotNull ChunkGenerator.ChunkData d) {
try {
getEngine(world);
computeStudioGenerator();
TerrainChunk tc = TerrainChunk.create(d, new IrisBiomeStorage());
this.world.bind(world);
if (studioGenerator != null) {
studioGenerator.generateChunk(getEngine(), tc, x, z);
} else {
ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(tc);
BiomeGridHunkHolder biomes = new BiomeGridHunkHolder(tc, tc.getMinHeight(), tc.getMaxHeight());
getEngine().generate(x << 4, z << 4, blocks, biomes, false);
blocks.apply();
biomes.apply();
}
Iris.debug("Generated " + x + " " + z);
} catch (Throwable e) {
Iris.error("======================================");
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
}
}
}
}
@Override
public int getBaseHeight(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull HeightMap heightMap) {
return 4;
}
private void computeStudioGenerator() {
if (!getEngine().getDimension().getStudioMode().equals(lastMode)) {
lastMode = getEngine().getDimension().getStudioMode();
getEngine().getDimension().getStudioMode().inject(this);
}
}
@NotNull
@Override
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return populators;
}
@Override
public boolean isParallelCapable() {
return true;
}
@Override
public boolean shouldGenerateCaves() {
return false;
}
@Override
public boolean shouldGenerateDecorations() {
return false;
}
@Override
public boolean shouldGenerateMobs() {
return false;
}
@Override
public boolean shouldGenerateStructures() {
return false;
}
@Override
public boolean shouldGenerateNoise() {
return false;
}
@Override
public boolean shouldGenerateSurface() {
return false;
}
@Override
public boolean shouldGenerateBedrock() {
return false;
}
@Nullable
@Override
public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) {
return dummyBiomeProvider;
}
}
/*
* 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.engine.platform;
import com.volmit.iris.Iris;
import com.volmit.iris.core.loader.IrisData;
import com.volmit.iris.core.nms.INMS;
import com.volmit.iris.core.service.StudioSVC;
import com.volmit.iris.engine.IrisEngine;
import com.volmit.iris.engine.data.chunk.TerrainChunk;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.engine.framework.EngineTarget;
import com.volmit.iris.engine.object.IrisDimension;
import com.volmit.iris.engine.object.IrisWorld;
import com.volmit.iris.engine.object.StudioMode;
import com.volmit.iris.engine.platform.studio.StudioGenerator;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.data.IrisBiomeStorage;
import com.volmit.iris.util.hunk.Hunk;
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
import com.volmit.iris.util.io.ReactiveFolder;
import com.volmit.iris.util.scheduling.ChronoLatch;
import com.volmit.iris.util.scheduling.J;
import com.volmit.iris.util.scheduling.Looper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import org.bukkit.*;
import org.bukkit.block.Biome;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Consumer;
@EqualsAndHashCode(callSuper = true)
@Data
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator, Listener {
private static final int LOAD_LOCKS = Runtime.getRuntime().availableProcessors() * 4;
private final Semaphore loadLock;
private final IrisWorld world;
private final File dataLocation;
private final String dimensionKey;
private final ReactiveFolder folder;
private final ReentrantLock lock = new ReentrantLock();
private final KList<BlockPopulator> populators;
private final ChronoLatch hotloadChecker;
private final AtomicBoolean setup;
private final boolean studio;
private final AtomicInteger a = new AtomicInteger(0);
private final boolean smartVanillaHeight;
private Engine engine;
private Looper hotloader;
private StudioMode lastMode;
private DummyBiomeProvider dummyBiomeProvider;
@Setter
private StudioGenerator studioGenerator;
private boolean initialized = false;
public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey, boolean smartVanillaHeight) {
setup = new AtomicBoolean(false);
studioGenerator = null;
dummyBiomeProvider = new DummyBiomeProvider();
populators = new KList<>();
loadLock = new Semaphore(LOAD_LOCKS);
this.world = world;
this.hotloadChecker = new ChronoLatch(1000, false);
this.studio = studio;
this.dataLocation = dataLocation;
this.dimensionKey = dimensionKey;
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
this.smartVanillaHeight = smartVanillaHeight;
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
}
private static Field getField(Class clazz, String fieldName)
throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class superClass = clazz.getSuperclass();
if (superClass == null) {
throw e;
} else {
return getField(superClass, fieldName);
}
}
}
@EventHandler
public void onWorldInit(WorldInitEvent event) {
try {
if (!initialized) {
world.setRawWorldSeed(event.getWorld().getSeed());
if (world.name().equals(event.getWorld().getName())) {
Engine engine = getEngine(event.getWorld());
if (engine == null) {
Iris.warn("Failed to get Engine!");
J.s(() -> {
Engine engine1 = getEngine(event.getWorld());
if (engine1 != null) {
try {
INMS.get().inject(event.getWorld().getSeed(), engine1, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true;
} catch (Throwable e) {
e.printStackTrace();
}
}
}, 10);
} else {
INMS.get().inject(event.getWorld().getSeed(), engine, event.getWorld());
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
initialized = true;
}
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private void setupEngine() {
IrisData data = IrisData.get(dataLocation);
IrisDimension dimension = data.getDimensionLoader().load(dimensionKey);
if (dimension == null) {
Iris.error("Oh No! There's no pack in " + data.getDataFolder().getPath() + " or... there's no dimension for the key " + dimensionKey);
IrisDimension test = IrisData.loadAnyDimension(dimensionKey);
if (test != null) {
Iris.warn("Looks like " + dimensionKey + " exists in " + test.getLoadFile().getPath() + " ");
Iris.service(StudioSVC.class).installIntoWorld(Iris.getSender(), dimensionKey, dataLocation.getParentFile().getParentFile());
Iris.warn("Attempted to install into " + data.getDataFolder().getPath());
data.dump();
data.clearLists();
test = data.getDimensionLoader().load(dimensionKey);
if (test != null) {
Iris.success("Woo! Patched the Engine!");
dimension = test;
} else {
Iris.error("Failed to patch dimension!");
throw new RuntimeException("Missing Dimension: " + dimensionKey);
}
} else {
Iris.error("Nope, you don't have an installation containing " + dimensionKey + " try downloading it?");
throw new RuntimeException("Missing Dimension: " + dimensionKey);
}
}
if (smartVanillaHeight) {
dimension.setSmartVanillaHeight(true);
try (FileWriter writer = new FileWriter(data.getDimensionLoader().fileFor(dimension))) {
writer.write(data.getGson().toJson(dimension));
} catch (IOException e) {
e.printStackTrace();
}
}
lastMode = StudioMode.NORMAL;
engine = new IrisEngine(new EngineTarget(world, dimension, data), studio);
populators.clear();
}
@Override
public void injectChunkReplacement(World world, int x, int z, Consumer<Runnable> jobs) {
try {
loadLock.acquire();
IrisBiomeStorage st = new IrisBiomeStorage();
TerrainChunk tc = TerrainChunk.createUnsafe(world, st);
Hunk<BlockData> blocks = Hunk.view(tc);
Hunk<Biome> biomes = Hunk.view(tc, tc.getMinHeight(), tc.getMaxHeight());
this.world.bind(world);
getEngine().generate(x << 4, z << 4, blocks, biomes, true);
Iris.debug("Regenerated " + x + " " + z);
int t = 0;
for (int i = getEngine().getHeight() >> 4; i >= 0; i--) {
if (!world.isChunkLoaded(x, z)) {
continue;
}
Chunk c = world.getChunkAt(x, z);
for (Entity ee : c.getEntities()) {
if (ee instanceof Player) {
continue;
}
J.s(ee::remove);
}
J.s(() -> engine.getWorldManager().onChunkLoad(c, false));
int finalI = i;
jobs.accept(() -> {
for (int xx = 0; xx < 16; xx++) {
for (int yy = 0; yy < 16; yy++) {
for (int zz = 0; zz < 16; zz++) {
if (yy + (finalI << 4) >= engine.getHeight() || yy + (finalI << 4) < 0) {
continue;
}
c.getBlock(xx, yy + (finalI << 4) + world.getMinHeight(), zz)
.setBlockData(tc.getBlockData(xx, yy + (finalI << 4) + world.getMinHeight(), zz), false);
}
}
}
});
}
loadLock.release();
} catch (Throwable e) {
loadLock.release();
Iris.error("======================================");
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
ChunkData d = Bukkit.createChunkData(world);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
}
}
}
}
private Engine getEngine(WorldInfo world) {
if (setup.get()) {
return getEngine();
}
lock.lock();
try {
if (setup.get()) {
return getEngine();
}
getWorld().setRawWorldSeed(world.getSeed());
setupEngine();
setup.set(true);
this.hotloader = studio ? new Looper() {
@Override
protected long loop() {
if (hotloadChecker.flip()) {
folder.check();
}
return 250;
}
} : null;
if (studio) {
hotloader.setPriority(Thread.MIN_PRIORITY);
hotloader.start();
hotloader.setName(getTarget().getWorld().name() + " Hotloader");
}
return engine;
} finally {
lock.unlock();
}
}
@Override
public void close() {
withExclusiveControl(() -> {
if (isStudio()) {
hotloader.interrupt();
}
getEngine().close();
folder.clear();
populators.clear();
});
}
@Override
public boolean isStudio() {
return studio;
}
@Override
public void hotload() {
if (!isStudio()) {
return;
}
withExclusiveControl(() -> getEngine().hotload());
}
public void withExclusiveControl(Runnable r) {
J.a(() -> {
try {
loadLock.acquire(LOAD_LOCKS);
r.run();
loadLock.release(LOAD_LOCKS);
} catch (Throwable e) {
Iris.reportError(e);
}
});
}
@Override
public void touch(World world) {
getEngine(world);
}
@Override
public void generateNoise(@NotNull WorldInfo world, @NotNull Random random, int x, int z, @NotNull ChunkGenerator.ChunkData d) {
try {
getEngine(world);
computeStudioGenerator();
TerrainChunk tc = TerrainChunk.create(d, new IrisBiomeStorage());
this.world.bind(world);
if (studioGenerator != null) {
studioGenerator.generateChunk(getEngine(), tc, x, z);
} else {
ChunkDataHunkHolder blocks = new ChunkDataHunkHolder(tc);
BiomeGridHunkHolder biomes = new BiomeGridHunkHolder(tc, tc.getMinHeight(), tc.getMaxHeight());
getEngine().generate(x << 4, z << 4, blocks, biomes, false);
blocks.apply();
biomes.apply();
}
Iris.debug("Generated " + x + " " + z);
} catch (Throwable e) {
Iris.error("======================================");
e.printStackTrace();
Iris.reportErrorChunk(x, z, e, "CHUNK");
Iris.error("======================================");
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
d.setBlock(i, 0, j, Material.RED_GLAZED_TERRACOTTA.createBlockData());
}
}
}
}
@Override
public int getBaseHeight(@NotNull WorldInfo worldInfo, @NotNull Random random, int x, int z, @NotNull HeightMap heightMap) {
return 4;
}
private void computeStudioGenerator() {
if (!getEngine().getDimension().getStudioMode().equals(lastMode)) {
lastMode = getEngine().getDimension().getStudioMode();
getEngine().getDimension().getStudioMode().inject(this);
}
}
@NotNull
@Override
public List<BlockPopulator> getDefaultPopulators(@NotNull World world) {
return populators;
}
@Override
public boolean isParallelCapable() {
return true;
}
@Override
public boolean shouldGenerateCaves() {
return false;
}
@Override
public boolean shouldGenerateDecorations() {
return false;
}
@Override
public boolean shouldGenerateMobs() {
return false;
}
@Override
public boolean shouldGenerateStructures() {
return false;
}
@Override
public boolean shouldGenerateNoise() {
return false;
}
@Override
public boolean shouldGenerateSurface() {
return false;
}
@Override
public boolean shouldGenerateBedrock() {
return false;
}
@Nullable
@Override
public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) {
return dummyBiomeProvider;
}
}

View File

@@ -25,6 +25,7 @@ import com.volmit.iris.core.service.ExternalDataSVC;
import com.volmit.iris.engine.object.IrisCompat;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.misc.E;
import com.volmit.iris.util.scheduling.ChronoLatch;
import it.unimi.dsi.fastutil.ints.*;
import org.bukkit.Bukkit;
@@ -46,6 +47,7 @@ public class B {
private static final KMap<String, BlockData> custom = new KMap<>();
private static final Material AIR_MATERIAL = Material.AIR;
private static final Material SHORT_GRASS = E.getOrDefault(Material.class, "GRASS", "SHORT_GRASS");
private static final BlockData AIR = AIR_MATERIAL.createBlockData();
private static final IntSet foliageCache = buildFoliageCache();
private static final IntSet deepslateCache = buildDeepslateCache();
@@ -85,7 +87,7 @@ public class B {
WHITE_TULIP,
FERN,
LARGE_FERN,
GRASS,
SHORT_GRASS,
TALL_GRASS
}).forEach((i) -> b.add(i.ordinal()));
@@ -143,7 +145,7 @@ public class B {
private static IntSet buildDecorantCache() {
IntSet b = new IntOpenHashSet();
Arrays.stream(new Material[]{
GRASS,
SHORT_GRASS,
TALL_GRASS,
TALL_SEAGRASS,
FERN,

View File

@@ -0,0 +1,127 @@
package com.volmit.iris.util.data;
import com.volmit.iris.core.link.Identifier;
import lombok.Data;
import lombok.NonNull;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SoundGroup;
import org.bukkit.block.*;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.structure.Mirror;
import org.bukkit.block.structure.StructureRotation;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@Data
public class IrisBlockData implements BlockData {
private final @NonNull BlockData base;
private final @NotNull Identifier custom;
@NotNull
@Override
public Material getMaterial() {
return base.getMaterial();
}
@NotNull
@Override
public String getAsString() {
return base.getAsString();
}
@NotNull
@Override
public String getAsString(boolean b) {
return base.getAsString(b);
}
@NotNull
@Override
public BlockData merge(@NotNull BlockData blockData) {
return new IrisBlockData(base.merge(blockData), custom);
}
@Override
public boolean matches(@Nullable BlockData blockData) {
if (blockData instanceof IrisBlockData b)
return custom.equals(b.custom) && base.matches(b.base);
return base.matches(blockData);
}
@NotNull
@Override
public BlockData clone() {
return new IrisBlockData(base.clone(), custom);
}
@NotNull
@Override
public SoundGroup getSoundGroup() {
return base.getSoundGroup();
}
@Override
public int getLightEmission() {
return base.getLightEmission();
}
@Override
public boolean isOccluding() {
return base.isOccluding();
}
@Override
public boolean requiresCorrectToolForDrops() {
return base.requiresCorrectToolForDrops();
}
@Override
public boolean isPreferredTool(@NotNull ItemStack itemStack) {
return base.isPreferredTool(itemStack);
}
@NotNull
@Override
public PistonMoveReaction getPistonMoveReaction() {
return base.getPistonMoveReaction();
}
@Override
public boolean isSupported(@NotNull Block block) {
return base.isSupported(block);
}
@Override
public boolean isSupported(@NotNull Location location) {
return base.isSupported(location);
}
@Override
public boolean isFaceSturdy(@NotNull BlockFace blockFace, @NotNull BlockSupport blockSupport) {
return base.isFaceSturdy(blockFace, blockSupport);
}
@NotNull
@Override
public Material getPlacementMaterial() {
return base.getPlacementMaterial();
}
@Override
public void rotate(@NotNull StructureRotation structureRotation) {
base.rotate(structureRotation);
}
@Override
public void mirror(@NotNull Mirror mirror) {
base.mirror(mirror);
}
@NotNull
@Override
public BlockState createBlockState() {
return base.createBlockState();
}
}

View File

@@ -0,0 +1,36 @@
package com.volmit.iris.util.decree.handlers;
import com.volmit.iris.core.nms.datapack.DataVersion;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.decree.DecreeParameterHandler;
import com.volmit.iris.util.decree.exceptions.DecreeParsingException;
public class DataVersionHandler implements DecreeParameterHandler<DataVersion> {
@Override
public KList<DataVersion> getPossibilities() {
return new KList<>(DataVersion.values());
}
@Override
public String toString(DataVersion version) {
return version.getVersion();
}
@Override
public DataVersion parse(String in, boolean force) throws DecreeParsingException {
if (in.equalsIgnoreCase("latest")) {
return DataVersion.getLatest();
}
for (DataVersion v : DataVersion.values()) {
if (v.getVersion().equalsIgnoreCase(in)) {
return v;
}
}
throw new DecreeParsingException("Unable to parse data version \"" + in + "\"");
}
@Override
public boolean supports(Class<?> type) {
return DataVersion.class.equals(type);
}
}

View File

@@ -19,6 +19,7 @@
package com.volmit.iris.util.hunk.view;
import com.volmit.iris.util.data.B;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.hunk.Hunk;
import org.bukkit.block.data.BlockData;
import org.bukkit.generator.ChunkGenerator.ChunkData;
@@ -72,7 +73,8 @@ public class ChunkDataHunkView implements Hunk<BlockData> {
}
try {
if (t instanceof IrisBlockData d)
t = d.getBase();
chunk.setBlock(x, y + chunk.getMinHeight(), z, t);
} catch (Throwable ignored) {

View File

@@ -212,7 +212,7 @@ public class UIElement implements Element {
im.setLore(getLore().copy());
if (isEnchanted()) {
im.addEnchant(Enchantment.DURABILITY, 1, true);
im.addEnchant(Enchantment.FIRE_ASPECT, 1, true);
}
is.setItemMeta(im);

View File

@@ -21,6 +21,7 @@ package com.volmit.iris.util.mantle;
import com.google.common.util.concurrent.AtomicDouble;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.service.IrisEngineSVC;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.data.cache.Cache;
import com.volmit.iris.engine.framework.Engine;
@@ -59,6 +60,7 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public class Mantle {
private static final boolean disableClear = System.getProperty("disableClear", "false").equals("true");
private final File dataFolder;
@Getter
private final int worldHeight;
@@ -423,17 +425,17 @@ public class Mantle {
ioTrim.set(true);
unloadLock.lock();
try {
if (lastUse != null) {
if (lastUse != null && IrisEngineSVC.instance != null) {
if (!lastUse.isEmpty()) {
Iris.debug("Trimming Tectonic Plates older than " + Form.duration(adjustedIdleDuration.get(), 0));
for (Long i : new ArrayList<>(lastUse.keySet())) {
for (long i : new ArrayList<>(lastUse.keySet())) {
double finalAdjustedIdleDuration = adjustedIdleDuration.get();
hyperLock.withLong(i, () -> {
Long lastUseTime = lastUse.get(i);
if (lastUseTime != null && M.ms() - lastUseTime >= finalAdjustedIdleDuration) {
toUnload.add(i);
Iris.debug("Tectonic Region added to unload");
//Iris.panic();
IrisEngineSVC.instance.trimActiveAlive.reset();
}
});
}
@@ -452,37 +454,47 @@ public class Mantle {
AtomicInteger i = new AtomicInteger();
unloadLock.lock();
BurstExecutor burst = null;
try {
KList<Long> copy = toUnload.copy();
burst = MultiBurst.burst.burst(copy.size());
burst.setMulticore(copy.size() > tectonicLimit);
for (long id : copy) {
burst.queue(() ->
hyperLock.withLong(id, () -> {
TectonicPlate m = loadedRegions.get(id);
if (m != null) {
try {
m.write(fileForRegion(dataFolder, id));
loadedRegions.remove(id);
lastUse.remove(id);
toUnload.remove(id);
i.incrementAndGet();
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + Cache.keyX(id) + " " + Cache.keyZ(id));
} catch (IOException e) {
Iris.reportError(e);
}
}
}));
if (IrisEngineSVC.instance != null) {
try {
KList<Long> copy = toUnload.copy();
if (!disableClear) toUnload.clear();
burst = MultiBurst.burst.burst(copy.size());
burst.setMulticore(copy.size() > tectonicLimit);
for (int j = 0; j < copy.size(); j++) {
Long id = copy.get(j);
if (id == null) {
Iris.error("Null id in unloadTectonicPlate at index " + j);
continue;
}
}
burst.complete();
} catch (Throwable e) {
e.printStackTrace();
if (burst != null)
burst.queue(() ->
hyperLock.withLong(id, () -> {
TectonicPlate m = loadedRegions.get(id);
if (m != null) {
try {
m.write(fileForRegion(dataFolder, id));
loadedRegions.remove(id);
lastUse.remove(id);
if (disableClear) toUnload.remove(id);
i.incrementAndGet();
Iris.debug("Unloaded Tectonic Plate " + C.DARK_GREEN + Cache.keyX(id) + " " + Cache.keyZ(id));
IrisEngineSVC.instance.unloadActiveAlive.reset();
} catch (IOException e) {
Iris.reportError(e);
}
}
}));
}
burst.complete();
} finally {
unloadLock.unlock();
ioTectonicUnload.set(true);
} catch (Throwable e) {
e.printStackTrace();
if (burst != null)
burst.complete();
} finally {
unloadLock.unlock();
ioTectonicUnload.set(true);
}
return i.get();
}
return i.get();
}

View File

@@ -33,7 +33,8 @@ public enum MantleFlag {
CLEANED,
PLANNED,
ETCHED,
TILE;
TILE,
CUSTOM;
static StateList getStateList() {
return new StateList(MantleFlag.values());

View File

@@ -18,6 +18,7 @@
package com.volmit.iris.util.matter.slices;
import com.volmit.iris.util.data.IrisBlockData;
import com.volmit.iris.util.data.palette.Palette;
import com.volmit.iris.util.matter.Sliced;
import org.bukkit.Bukkit;
@@ -39,7 +40,11 @@ public class BlockMatter extends RawMatter<BlockData> {
public BlockMatter(int width, int height, int depth) {
super(width, height, depth, BlockData.class);
registerWriter(World.class, ((w, d, x, y, z) -> w.getBlockAt(x, y, z).setBlockData(d)));
registerWriter(World.class, ((w, d, x, y, z) -> {
if (d instanceof IrisBlockData c)
w.getBlockAt(x, y, z).setBlockData(c.getBase());
else w.getBlockAt(x, y, z).setBlockData(d);
}));
registerReader(World.class, (w, x, y, z) -> {
BlockData d = w.getBlockAt(x, y, z).getBlockData();
return d.getMaterial().isAir() ? null : d;

View File

@@ -0,0 +1,36 @@
package com.volmit.iris.util.matter.slices;
import com.volmit.iris.core.link.Identifier;
import com.volmit.iris.util.data.palette.Palette;
import com.volmit.iris.util.matter.Sliced;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@Sliced
public class IdentifierMatter extends RawMatter<Identifier> {
public IdentifierMatter() {
this(1, 1, 1);
}
public IdentifierMatter(int width, int height, int depth) {
super(width, height, depth, Identifier.class);
}
@Override
public Palette<Identifier> getGlobalPalette() {
return null;
}
@Override
public void writeNode(Identifier b, DataOutputStream dos) throws IOException {
dos.writeUTF(b.toString());
}
@Override
public Identifier readNode(DataInputStream din) throws IOException {
return Identifier.fromString(din.readUTF());
}
}

View File

@@ -0,0 +1,35 @@
package com.volmit.iris.util.matter.slices;
import com.volmit.iris.util.data.palette.Palette;
import com.volmit.iris.util.matter.Sliced;
import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@Sliced
public class JigsawStructuresMatter extends RawMatter<JigsawStructuresContainer> {
public JigsawStructuresMatter() {
this(1, 1, 1);
}
public JigsawStructuresMatter(int width, int height, int depth) {
super(width, height, depth, JigsawStructuresContainer.class);
}
@Override
public Palette<JigsawStructuresContainer> getGlobalPalette() {
return null;
}
@Override
public void writeNode(JigsawStructuresContainer b, DataOutputStream dos) throws IOException {
b.write(dos);
}
@Override
public JigsawStructuresContainer readNode(DataInputStream din) throws IOException {
return new JigsawStructuresContainer(din);
}
}

View File

@@ -0,0 +1,62 @@
package com.volmit.iris.util.matter.slices.container;
import com.volmit.iris.engine.object.IrisJigsawStructure;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.documentation.ChunkCoordinates;
import com.volmit.iris.util.math.Position2;
import org.jetbrains.annotations.Unmodifiable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class JigsawStructuresContainer {
private final Map<String, List<Position2>> map = new KMap<>();
public JigsawStructuresContainer() {}
public JigsawStructuresContainer(DataInputStream din) throws IOException {
int s0 = din.readInt();
for (int i = 0; i < s0; i++) {
int s1 = din.readInt();
KList<Position2> list = new KList<>(s1);
for (int j = 0; j < s1; j++) {
list.add(new Position2(din.readInt(), din.readInt()));
}
map.put(din.readUTF(), list);
}
}
public void write(DataOutputStream dos) throws IOException {
dos.writeInt(map.size());
for (String key : map.keySet()) {
List<Position2> list = map.get(key);
dos.writeInt(list.size());
for (Position2 pos : list) {
dos.writeInt(pos.getX());
dos.writeInt(pos.getZ());
}
dos.writeUTF(key);
}
}
@Unmodifiable
public Set<String> getStructures() {
return Collections.unmodifiableSet(map.keySet());
}
@Unmodifiable
public List<Position2> getPositions(String structure) {
return Collections.unmodifiableList(map.get(structure));
}
@ChunkCoordinates
public void add(IrisJigsawStructure structure, Position2 pos) {
map.computeIfAbsent(structure.getLoadKey(), k -> new KList<>()).add(pos);
}
}

View File

@@ -0,0 +1,12 @@
package com.volmit.iris.util.misc;
public class E {
public static <T extends Enum<T>> T getOrDefault(Class<T> enumClass, String name, String fallback) {
try {
return Enum.valueOf(enumClass, name);
} catch (Throwable e) {
return Enum.valueOf(enumClass, fallback);
}
}
}

View File

@@ -0,0 +1,135 @@
package com.volmit.iris.util.misc;
import com.volmit.iris.Iris;
import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.framework.Engine;
import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.format.C;
import com.volmit.iris.util.format.Form;
import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.TextComponent;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import oshi.SystemInfo;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
public class Hastebin {
public static void enviornment(CommandSender sender) {
// Construct the server information
StringBuilder sb = new StringBuilder();
SystemInfo systemInfo = new SystemInfo();
KList<String> disks = new KList<>(getHardware.getDisk());
KList<String> interfaces = new KList<>(getHardware.getInterfaces());
KList<String> displays = new KList<>(getHardware.getEDID());
KList<String> sensors = new KList<>(getHardware.getSensors());
KList<String> gpus = new KList<>(getHardware.getGraphicsCards());
KList<String> powersources = new KList<>(getHardware.getPowerSources());
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);
}
}
sb.append(" -- == Iris Info == -- \n");
sb.append("Iris Version Version: ").append(Iris.instance.getDescription().getVersion()).append("\n");
sb.append("- Iris Worlds");
for (World w : IrisWorlds.copy()) {
sb.append(" - ").append(w.getName());
}
sb.append("- Bukkit Worlds");
for (World w : BukkitWorlds.copy()) {
sb.append(" - ").append(w.getName());
}
sb.append(" -- == Platform Overview == -- " + "\n");
sb.append("Server Type: ").append(Bukkit.getVersion()).append("\n");
sb.append("Server Uptime: ").append(Form.stampTime(systemInfo.getOperatingSystem().getSystemUptime())).append("\n");
sb.append("Version: ").append(Platform.getVersion()).append(" - Platform: ").append(Platform.getName()).append("\n");
sb.append("Java Vendor: ").append(Platform.ENVIRONMENT.getJavaVendor()).append(" - Java Version: ").append(Platform.ENVIRONMENT.getJavaVersion()).append("\n");
sb.append(" -- == Processor Overview == -- " + "\n");
sb.append("CPU Model: ").append(getHardware.getCPUModel());
sb.append("CPU Architecture: ").append(Platform.CPU.getArchitecture()).append(" Available Processors: ").append(Platform.CPU.getAvailableProcessors()).append("\n");
sb.append("CPU Load: ").append(Form.pc(Platform.CPU.getCPULoad())).append(" CPU Live Process Load: ").append(Form.pc(Platform.CPU.getLiveProcessCPULoad())).append("\n");
sb.append("-=" + " Graphics " + "=- " + "\n");
for (String gpu : gpus) {
sb.append(" ").append(gpu).append("\n");
}
sb.append(" -- == Memory Information == -- " + "\n");
sb.append("Physical Memory - Total: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getTotalMemory())).append(" Free: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getFreeMemory())).append(" Used: ").append(Form.memSize(Platform.MEMORY.PHYSICAL.getUsedMemory())).append("\n");
sb.append("Virtual Memory - Total: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getTotalMemory())).append(" Free: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getFreeMemory())).append(" Used: ").append(Form.memSize(Platform.MEMORY.VIRTUAL.getUsedMemory())).append("\n");
sb.append(" -- == Storage Information == -- " + "\n");
for (String disk : disks) {
sb.append(" ").append(sb.append(disk)).append("\n");
}
sb.append(" -- == Interface Information == -- "+ "\n" );
for (String inter : interfaces) {
sb.append(" ").append(inter).append("\n");
}
sb.append(" -- == Display Information == -- "+ "\n" );
for (String display : displays) {
sb.append(display).append("\n");
}
sb.append(" -- == Sensor Information == -- " + "\n");
for (String sensor : sensors) {
sb.append(" ").append(sensor).append("\n");
}
sb.append(" -- == Power Information == -- " + "\n");
for (String power : powersources) {
sb.append(" ").append(power).append("\n");
}
try {
String hastebinUrl = uploadToHastebin(sb.toString());
// Create the clickable message
TextComponent message = new TextComponent("[Link]");
TextComponent link = new TextComponent(hastebinUrl);
link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, hastebinUrl));
message.addExtra(link);
// Send the clickable message to the player
sender.spigot().sendMessage(message);
} catch (Exception e) {
sender.sendMessage(C.DARK_RED + "Failed to upload server information to Hastebin.");
}
}
private static String uploadToHastebin(String content) throws Exception {
URL url = new URL("https://paste.bytecode.ninja/documents");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "text/plain");
conn.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
wr.writeBytes(content);
wr.flush();
wr.close();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String response = br.readLine();
br.close();
return "https://paste.bytecode.ninja/" + response.split("\"")[3];
}
}

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