From 9843f18c96959b8bf8007eaaeb506814ee1b526c Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Wed, 22 Nov 2023 13:45:55 +0100 Subject: [PATCH 01/98] Fix jigsaw piece collision/merging --- .../java/com/volmit/iris/engine/jigsaw/PlannedStructure.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index c8d0dcad4..762534340 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -28,7 +28,6 @@ import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.mantle.Mantle; 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 lombok.Data; import org.bukkit.Axis; @@ -361,10 +360,6 @@ public class PlannedStructure { public boolean collidesWith(PlannedPiece piece, PlannedPiece ignore) { for (PlannedPiece i : pieces) { - if (i.equals(ignore)) { - continue; - } - if (i.collidesWith(piece)) { return true; } From b098c210ceec39c961196336add627f6da0a8791 Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Fri, 24 Nov 2023 17:03:32 +0100 Subject: [PATCH 02/98] removed unnecessary code --- .../iris/engine/jigsaw/PlannedStructure.java | 71 ++----------------- 1 file changed, 6 insertions(+), 65 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 762534340..81986c252 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -74,7 +74,7 @@ public class PlannedStructure { } } - public void place(MantleWriter placer, Mantle e, Engine eng) { + public void place(IObjectPlacer placer, Mantle e, Engine eng) { IrisObjectPlacement options = new IrisObjectPlacement(); options.getRotation().setEnabled(false); int startHeight = pieces.get(0).getPosition().getY(); @@ -84,7 +84,7 @@ public class PlannedStructure { } } - public void place(PlannedPiece i, int startHeight, IrisObjectPlacement o, MantleWriter placer, Mantle e, Engine eng) { + public void place(PlannedPiece i, int startHeight, IrisObjectPlacement o, IObjectPlacer placer, Mantle e, Engine eng) { IrisObjectPlacement options = o; if (i.getPiece().getPlacementOptions() != null) { @@ -122,69 +122,10 @@ 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); - } - - @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 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()); + vo.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); + }, null, getData()); } public void place(World world) { From 7263d102c74b7c8099246b4023ecbe8f95b775ca Mon Sep 17 00:00:00 2001 From: Julian Krings Date: Wed, 29 Nov 2023 14:34:00 +0100 Subject: [PATCH 03/98] cleanup / possibly fix a bug --- .../components/MantleJigsawComponent.java | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index fccbd9630..fdb272015 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -23,6 +23,7 @@ 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.context.ChunkContext; import com.volmit.iris.util.documentation.BlockCoordinates; import com.volmit.iris.util.documentation.ChunkCoordinates; @@ -53,8 +54,6 @@ public class MantleJigsawComponent extends IrisMantleComponent { @ChunkCoordinates private void generateJigsaw(MantleWriter writer, RNG rng, int x, int z, IrisBiome biome, IrisRegion region) { - boolean placed = false; - if (getDimension().getStronghold() != null) { List poss = getDimension().getStrongholds(seed()); @@ -63,43 +62,30 @@ public class MantleJigsawComponent extends IrisMantleComponent { if (x == pos.getX() >> 4 && z == pos.getZ() >> 4) { IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(getDimension().getStronghold()); place(writer, pos.toIris(), structure, rng); - placed = true; + 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; - } - } - } + boolean placed = placeStructures(writer, rng, x, z, biome.getJigsawStructures()); + if (!placed) + placed = placeStructures(writer, rng, x, z, region.getJigsawStructures()); + if (!placed) + placeStructures(writer, rng, x, z, getDimension().getJigsawStructures()); + } - 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; - } - } - } - - 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 placeStructures(MantleWriter writer, RNG rng, int x, int z, KList structures) { + for (IrisJigsawStructurePlacement i : structures) { + 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); + return true; } } + return false; } @ChunkCoordinates From 9fc72868d7874fbd16f291ddeb05e26c5af7e84a Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Fri, 26 Jan 2024 10:57:03 +0100 Subject: [PATCH 04/98] disabled perms check --- .../com/volmit/iris/core/safeguard/ServerBootSFG.java | 10 +++++----- .../java/com/volmit/iris/core/safeguard/UtilsSFG.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index b2945e010..6fc87f183 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -96,11 +96,11 @@ public class ServerBootSFG { severityMedium++; } - if (!hasPrivileges()){ - hasPrivileges = false; - joiner.add("Insufficient Privileges"); - severityMedium++; - } +// if (!hasPrivileges()){ +// hasPrivileges = false; +// joiner.add("Insufficient Privileges"); +// severityMedium++; +// } Some servers dont like this if (!enoughDiskSpace()){ hasEnoughDiskSpace = false; diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java index c9155c7b3..11516c028 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java @@ -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.2"); + Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.20.4"); } if (!ServerBootSFG.passedserversoftware) { Iris.safeguard(C.YELLOW + "Unsupported Server Software"); From d658ec209980dd7fbdfe882b51a2acbf4dfe6985 Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Sun, 4 Feb 2024 17:37:00 -0500 Subject: [PATCH 05/98] oops --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ea7d53891..0cf2c067d 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.0.0-1.19.2-1.20.4' +version '3.2.0-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From 6a012cf400fcc87d1c1566b75204f971f2649878 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 12 Feb 2024 11:42:47 +0100 Subject: [PATCH 06/98] fix setup being set before engine setup --- .../engine/platform/BukkitChunkGenerator.java | 828 +++++++++--------- 1 file changed, 415 insertions(+), 413 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index f63b6d12a..c033df855 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -1,413 +1,415 @@ -/* - * 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 . - */ - -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 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 jobs) { - try { - loadLock.acquire(); - IrisBiomeStorage st = new IrisBiomeStorage(); - TerrainChunk tc = TerrainChunk.createUnsafe(world, st); - Hunk blocks = Hunk.view(tc); - Hunk 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 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 . + */ + +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 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 jobs) { + try { + loadLock.acquire(); + IrisBiomeStorage st = new IrisBiomeStorage(); + TerrainChunk tc = TerrainChunk.createUnsafe(world, st); + Hunk blocks = Hunk.view(tc); + Hunk 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 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; + } +} From 960e2fcc610b4eff7b3f5fbf9d630c5bd1dd5208 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 12 Feb 2024 11:43:21 +0100 Subject: [PATCH 07/98] try again if engine setup fails --- .../engine/platform/BukkitChunkGenerator.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index c033df855..50206b6d1 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -126,9 +126,26 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun 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; + 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) { From 0497045388556027290a50c13445a38f9540cb99 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 13 Feb 2024 08:51:48 +0100 Subject: [PATCH 08/98] - Fixed /Iris height when ran in console - Added Dynamic worldHeight --- .../com/volmit/iris/core/IrisSettings.java | 3 +- .../volmit/iris/core/ServerConfigurator.java | 27 +++++++++++++- .../iris/core/commands/CommandIris.java | 37 +++++++------------ .../iris/engine/object/IrisDimension.java | 7 +++- .../com/volmit/iris/util/plugin/Command.java | 3 ++ 5 files changed, 50 insertions(+), 27 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index ea17736ab..335207de5 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -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; diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index 98a5fc7be..936b8e26a 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -24,6 +24,7 @@ import com.volmit.iris.core.nms.INMS; 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; @@ -94,6 +95,30 @@ public class ServerConfigurator { public static void installDataPacks(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")) { + Iris.info("Found JSON File: " + file.getName() + " in " + dimensionsFolder.getPath()); + 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 +138,7 @@ public class ServerConfigurator { Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); for (File dpack : getDatapacksFolder()) { - dim.installDataPack(() -> data, dpack); + dim.installDataPack(() -> data, dpack, ultimateMaxHeight, ultimateMinHeight); } } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 3601b3f11..699aa2616 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -59,6 +59,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 { @@ -184,7 +185,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 +197,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() instanceof Player) { + 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) @@ -234,7 +223,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()); @@ -417,7 +406,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()); @@ -492,7 +481,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()); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index bb1cf5cf1..488171296 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -22,9 +22,11 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; 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.collection.KList; import com.volmit.iris.util.data.DataProvider; +import com.volmit.iris.util.data.Dimension; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.Position2; @@ -40,6 +42,7 @@ import org.bukkit.Material; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; +import java.io.DataInput; import java.io.File; import java.io.IOException; @@ -439,7 +442,7 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } - public boolean installDataPack(DataProvider data, File datapacks) { + public boolean installDataPack(DataProvider data, File datapacks, double ultimateMaxHeight, double ultimateMinHeight) { boolean write = false; boolean changed = false; @@ -470,6 +473,8 @@ 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\""); + dimensionHeight.setMax(ultimateMaxHeight); + dimensionHeight.setMin(ultimateMinHeight); changed = writeDimensionType(changed, datapacks); } diff --git a/core/src/main/java/com/volmit/iris/util/plugin/Command.java b/core/src/main/java/com/volmit/iris/util/plugin/Command.java index bd9cd546c..c223c84b4 100644 --- a/core/src/main/java/com/volmit/iris/util/plugin/Command.java +++ b/core/src/main/java/com/volmit/iris/util/plugin/Command.java @@ -18,6 +18,8 @@ package com.volmit.iris.util.plugin; +import com.volmit.iris.util.format.C; + import java.lang.annotation.Retention; import java.lang.annotation.Target; @@ -28,4 +30,5 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; @Target(FIELD) public @interface Command { String value() default ""; + } From 6cbc2374b381b9677e639c0e2148804e25694d34 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Thu, 15 Feb 2024 20:43:29 +0100 Subject: [PATCH 09/98] whoopsies --- .../src/main/java/com/volmit/iris/core/ServerConfigurator.java | 1 - .../main/java/com/volmit/iris/core/commands/CommandIris.java | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index 936b8e26a..cee4cd053 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -105,7 +105,6 @@ public class ServerConfigurator { if (dimensionsFolder.exists() && dimensionsFolder.isDirectory()) { for (File file : dimensionsFolder.listFiles()) { if (file.isFile() && file.getName().endsWith(".json")) { - Iris.info("Found JSON File: " + file.getName() + " in " + dimensionsFolder.getPath()); IrisDimension dim = data.getDimensionLoader().load(file.getName().split("\\Q.\\E")[0]); if (ultimateMaxHeight < dim.getDimensionHeight().getMax()) { ultimateMaxHeight = dim.getDimensionHeight().getMax(); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 699aa2616..dce8d8db0 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -49,6 +49,7 @@ 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.Collections; @@ -199,7 +200,7 @@ public class CommandIris implements DecreeExecutor { @Decree(description = "Print world height information", origin = DecreeOrigin.PLAYER) public void height() { - if (sender() instanceof Player) { + 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 { From 58d88dd079b5de6c621e14d434ea05bde783956b Mon Sep 17 00:00:00 2001 From: MoritzR200 Date: Sat, 17 Feb 2024 13:31:00 +0100 Subject: [PATCH 10/98] Fixed backslashes being used as file separators regardless of platform (in /iris import)). --- .../main/java/com/volmit/iris/core/commands/CommandIris.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 3601b3f11..d610f1529 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -447,7 +447,7 @@ public class CommandIris implements DecreeExecutor { } 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; From fb9f8d28f4c4597073031dee58242c3043c85d01 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Wed, 21 Feb 2024 21:24:35 +0100 Subject: [PATCH 11/98] - Lib update fixes all the iris titles/actionbars - Iris .schem Converter --- build.gradle | 4 +- .../iris/core/commands/CommandStudio.java | 6 +- .../volmit/iris/core/tools/IrisConverter.java | 126 ++++++++++++++++++ 3 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java diff --git a/build.gradle b/build.gradle index 0cf2c067d..eeca2a32a 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ 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/Iris Development/plugins') // ========================== UNIX ============================== registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins') registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins') @@ -235,7 +235,7 @@ 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' compileOnly 'io.lumine:Mythic-Dist:5.2.1' diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 621915632..188ddf298 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -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.*; @@ -228,7 +229,10 @@ public class CommandStudio implements DecreeExecutor { @Decree(description = "Convert objects in the \"convert\" folder") public void convert() { - Iris.service(ConversionSVC.class).check(sender()); + //Iris.service(ConversionSVC.class).check(sender()); + IrisConverter.convertSchematics(sender()); + + } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java new file mode 100644 index 000000000..da882f56c --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -0,0 +1,126 @@ +package com.volmit.iris.core.tools; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.*; +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.math.M; +import com.volmit.iris.util.math.RollingSequence; +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.VolmitPlugin; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.Looper; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import javassist.bytecode.ByteArray; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.BlockVector; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.HashMap; +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) { + Map blockmap = new HashMap<>(); + File folder = Iris.instance.getDataFolder("convert"); + + FilenameFilter filter = (dir, name) -> name.endsWith(".schem"); + File[] fileList = folder.listFiles(filter); + for (File schem : fileList) { + try { + ExecutorService executorService = Executors.newFixedThreadPool(1); + executorService.submit(() -> { + 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(); + IrisObject object = new IrisObject(objW, objH, objD); + int mv = objW * objH * objD; + AtomicInteger v = new AtomicInteger(0); + if (mv > 100000) { + 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"); + for (Map.Entry> 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[] l = byteArray.getValue(); + + for (int h = 0; h < objH; h++) { + for (int d = 0; d < objD; d++) { + for (int w = 0; w < objW; w++) { + BlockData db = blockmap.get((int) l[v.get()]); + object.setUnsigned(w, h, d, db); + 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) { + 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()); + e.printStackTrace(); + Iris.reportError(e); + } + } + } +} + + + From d08600fbaa3d1f9a8fd678cc4fe4af2471bc1089 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 22 Feb 2024 17:27:38 +0100 Subject: [PATCH 12/98] Fix Pregen oversight --- .../com/volmit/iris/core/pregenerator/IrisPregenerator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 11128d04a..95275a759 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -167,7 +167,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) { From 93c1265de9de23dca493ad581818b3787381e2a7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 22 Feb 2024 21:25:37 +0100 Subject: [PATCH 13/98] Add implement custom spawn reason --- .../main/java/com/volmit/iris/core/nms/INMSBinding.java | 4 ++++ .../java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java | 7 +++++++ .../java/com/volmit/iris/engine/object/IrisEntity.java | 7 ++++++- .../com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java | 8 ++++++++ .../com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java | 7 +++++++ .../com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java | 8 ++++++++ .../com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java | 8 ++++++++ .../com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java | 7 +++++++ .../com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java | 8 ++++++++ 9 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 270a04504..a57ac3653 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -32,6 +32,9 @@ 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.event.entity.EntitySpawnEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; @@ -103,4 +106,5 @@ 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; + Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason); } diff --git a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index 04c95b4ed..b799345c3 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -34,6 +34,8 @@ 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; @@ -85,6 +87,11 @@ public class NMSBinding1X implements INMSBinding { } + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return location.getWorld().spawnEntity(location, type); + } + @Override public void deserializeTile(CompoundTag s, Location newPosition) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java index 8dabc091d..61de43e69 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java @@ -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; @@ -41,6 +42,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; @@ -67,6 +69,9 @@ public class IrisEntity extends IrisRegistrant { @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 = ""; @@ -457,7 +462,7 @@ public class IrisEntity extends IrisRegistrant { } - return at.getWorld().spawnEntity(at, getType()); + return INMS.get().spawnEntity(at, getType(), getReason()); } public boolean isCitizens() { diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java index eec445bee..7c00035a6 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java @@ -40,9 +40,12 @@ import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock; import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftWarden; import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; 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 org.jetbrains.annotations.NotNull; @@ -483,6 +486,11 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java index bcdda2dea..87b3f478c 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java @@ -43,6 +43,8 @@ import org.bukkit.craftbukkit.v1_19_R2.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_19_R2.inventory.CraftItemStack; 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 org.jetbrains.annotations.NotNull; @@ -483,6 +485,11 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index f11974faf..78d8cb1a5 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -45,6 +45,8 @@ import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; 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 org.jetbrains.annotations.NotNull; @@ -486,6 +488,12 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 02169ff3f..e87bc5699 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -45,6 +45,8 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; 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 org.jetbrains.annotations.NotNull; @@ -487,6 +489,12 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 1f02cf3ab..91baf4efa 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -46,6 +46,8 @@ import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey; 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 org.jetbrains.annotations.NotNull; @@ -486,6 +488,11 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 167400d19..5e6c63702 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -46,6 +46,8 @@ import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; 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 org.jetbrains.annotations.NotNull; @@ -486,6 +488,12 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + + @Override + public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { From 8a08a3e1489b001a079b681141702fa4e96190fe Mon Sep 17 00:00:00 2001 From: Julian Krings <47589149+CrazyDev05@users.noreply.github.com> Date: Tue, 27 Feb 2024 11:30:40 +0100 Subject: [PATCH 14/98] Remove Cherry Grove from 1.19.4 biomes list --- .../main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index 78d8cb1a5..fb46544a5 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -278,7 +278,7 @@ public class NMSBinding implements INMSBinding { @Override public KList getBiomes() { - return new KList<>(Biome.values()).qadd(Biome.CHERRY_GROVE).qdel(Biome.CUSTOM); + return new KList<>(Biome.values()).qdel(Biome.CHERRY_GROVE).qdel(Biome.CUSTOM); } @Override From e407679d2b10ffe55f8d80c09088e656209fb25c Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Fri, 1 Mar 2024 11:44:00 +0100 Subject: [PATCH 15/98] - Improved eta calculation --- .../com/volmit/iris/core/pregenerator/IrisPregenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index 11128d04a..b335151c6 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -128,7 +128,7 @@ 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()) * 100 // ); } From 34cad8594230ccb91180dc8afeebbac273a1a584 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Fri, 1 Mar 2024 12:32:53 +0100 Subject: [PATCH 16/98] - Fixed Eta --- .../com/volmit/iris/core/pregenerator/IrisPregenerator.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index b335151c6..c23b6c6fd 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -115,7 +115,7 @@ public class IrisPregenerator { 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); } 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("Pregen: " + 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,7 +128,7 @@ 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()) * 100 // + ((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000 ); } From 65e3fdd26cf4067781d0a93d10fc2002f7aacf3b Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 17:23:00 +0100 Subject: [PATCH 17/98] make implementing blocks that need world context possible --- .../iris/core/link/ExternalDataProvider.java | 3 + .../iris/core/service/ExternalDataSVC.java | 249 +++++++++--------- .../engine/data/chunk/LinkedTerrainChunk.java | 3 + .../engine/data/chunk/MCATerrainChunk.java | 3 + .../volmit/iris/engine/framework/Engine.java | 11 + .../volmit/iris/util/data/IrisBlockData.java | 127 +++++++++ .../util/hunk/view/ChunkDataHunkView.java | 4 +- .../volmit/iris/util/mantle/MantleFlag.java | 3 +- .../iris/util/matter/slices/BlockMatter.java | 7 +- .../util/matter/slices/IdentifierMatter.java | 36 +++ 10 files changed, 324 insertions(+), 122 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java create mode 100644 core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java diff --git a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java index ee4d46bfc..b3104d2e5 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java @@ -1,8 +1,10 @@ package com.volmit.iris.core.link; +import com.volmit.iris.engine.framework.Engine; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; @@ -28,6 +30,7 @@ public abstract class ExternalDataProvider { public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException; public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException; + public void processUpdate(Engine engine, Location location, Identifier blockId) {}; public abstract Identifier[] getBlockTypes(); diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index de6d2ac81..a7136fe51 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -1,119 +1,130 @@ -/* - * 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 . - */ - -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 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 getBlockData(Identifier key) { - Optional 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 getItemStack(Identifier key) { - Optional 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 names = new KList<>(); - activeProviders.forEach(p -> names.add(p.getBlockTypes())); - return names.toArray(new Identifier[0]); - } - - public Identifier[] getAllItemIdentifiers() { - KList 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 . + */ + +package com.volmit.iris.core.service; + +import com.volmit.iris.Iris; +import com.volmit.iris.core.link.*; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.plugin.IrisService; +import lombok.Data; +import org.bukkit.Bukkit; +import org.bukkit.Location; +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 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 getBlockData(Identifier key) { + Optional 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 getItemStack(Identifier key) { + Optional 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 void processUpdate(Engine engine, Location location, Identifier blockId) { + Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, true)).findFirst(); + if (provider.isEmpty()) { + Iris.warn("No matching Provider found for modded material \"%s\"!", blockId); + return; + } + provider.get().processUpdate(engine, location, blockId); + } + + public Identifier[] getAllBlockIdentifiers() { + KList names = new KList<>(); + activeProviders.forEach(p -> names.add(p.getBlockTypes())); + return names.toArray(new Identifier[0]); + } + + public Identifier[] getAllItemIdentifiers() { + KList names = new KList<>(); + activeProviders.forEach(p -> names.add(p.getItemTypes())); + return names.toArray(new Identifier[0]); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java b/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java index cbf18c1e6..015efd0e9 100644 --- a/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java +++ b/core/src/main/java/com/volmit/iris/engine/data/chunk/LinkedTerrainChunk.java @@ -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); } diff --git a/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java b/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java index 31b24a665..2da3db43a 100644 --- a/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java +++ b/core/src/main/java/com/volmit/iris/engine/data/chunk/MCATerrainChunk.java @@ -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); } diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index 4d57cdf83..d80b23d1b 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -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,9 @@ 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()); + } } void blockUpdatedMetric(); @@ -277,6 +283,11 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat 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, new Location(c.getWorld(), x, y + getWorld().minHeight(), z), v); + }); + })); getMantle().getMantle().raiseFlag(c.getX(), c.getZ(), MantleFlag.UPDATE, () -> J.s(() -> { PrecisionStopwatch p = PrecisionStopwatch.start(); diff --git a/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java new file mode 100644 index 000000000..dce36cd17 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java @@ -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(); + } +} diff --git a/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java b/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java index a9267f3fc..62cb7fc61 100644 --- a/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java +++ b/core/src/main/java/com/volmit/iris/util/hunk/view/ChunkDataHunkView.java @@ -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 { } try { - + if (t instanceof IrisBlockData d) + t = d.getBase(); chunk.setBlock(x, y + chunk.getMinHeight(), z, t); } catch (Throwable ignored) { diff --git a/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java b/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java index 03d98dee6..6bb5f1e6f 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/MantleFlag.java @@ -33,7 +33,8 @@ public enum MantleFlag { CLEANED, PLANNED, ETCHED, - TILE; + TILE, + CUSTOM; static StateList getStateList() { return new StateList(MantleFlag.values()); diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java b/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java index 9a0de90ba..cf6eef776 100644 --- a/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/BlockMatter.java @@ -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 { 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; diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java b/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java new file mode 100644 index 000000000..5777c6320 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/IdentifierMatter.java @@ -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 { + + public IdentifierMatter() { + this(1, 1, 1); + } + + public IdentifierMatter(int width, int height, int depth) { + super(width, height, depth, Identifier.class); + } + + @Override + public Palette 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()); + } +} From eb45339c818b642e6a39ffa18e4f37a6f97479a7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 17:23:32 +0100 Subject: [PATCH 18/98] add oraxen furniture support --- .../iris/core/link/OraxenDataProvider.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java index 068c8c18e..feaacb769 100644 --- a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java @@ -19,17 +19,25 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; +import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.data.IrisBlockData; 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.Chunk; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.MultipleFacing; @@ -69,6 +77,8 @@ 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(), blockId); } else throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); } @@ -79,6 +89,14 @@ public class OraxenDataProvider extends ExternalDataProvider { return opt.orElseThrow(() -> new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key())).build(); } + @Override + public void processUpdate(Engine engine, Location location, Identifier blockId) { + Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key()); + if (mechanic instanceof FurnitureMechanic f) { + f.place(location); + } + } + @Override public Identifier[] getBlockTypes() { KList names = new KList<>(); From 6d3dbf84ef18ed773359ea6d6e3f7946d9caf586 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 17:24:09 +0100 Subject: [PATCH 19/98] add HMCLeaves compatibility --- .../iris/core/link/HMCLeavesDataProvider.java | 121 ++++++++++++++++++ .../iris/core/service/ExternalDataSVC.java | 4 + 2 files changed, 125 insertions(+) create mode 100644 core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java new file mode 100644 index 000000000..e060569f1 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -0,0 +1,121 @@ +package com.volmit.iris.core.link; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.util.collection.KList; +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.data.BlockData; +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 worldBlockType; + private WrappedReturningMethod setCustomBlock; + private Map blockDataMap = Map.of(); + private Map> itemDataField = Map.of(); + + public HMCLeavesDataProvider() { + super("HMCLeaves"); + } + + @Override + public String getPluginId() { + return "HMCLeaves"; + } + + @Override + public void init() { + try { + worldBlockType = new WrappedReturningMethod<>((Class) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType"); + apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI")); + setCustomBlock = new WrappedReturningMethod<>((Class) apiInstance.getClass(), "setCustomBlock"); + 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) 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()); + return Bukkit.createBlockData(material); + } + + @Override + public ItemStack getItemStack(Identifier itemId) 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, Location location, Identifier blockId) { + setCustomBlock.invoke(apiInstance, new Object[]{location, blockId.key(), true}); + } + + @Override + public Identifier[] getBlockTypes() { + KList 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 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 Map getMap(C config, String name) { + WrappedField> field = new WrappedField<>((Class) config.getClass(), name); + return field.get(config); + } + + private A getApiInstance(Class apiClass) { + WrappedReturningMethod instance = new WrappedReturningMethod<>(apiClass, "getInstance"); + return instance.invoke(); + } + + private C getLeavesConfig(Class apiClass) { + WrappedReturningMethod instance = new WrappedReturningMethod<>(apiClass, "getInstance"); + WrappedField config = new WrappedField<>(apiClass, "config"); + return config.get(instance.invoke()); + } +} diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index a7136fe51..d466269ad 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -56,6 +56,10 @@ public class ExternalDataSVC implements IrisService { 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..."); + } for (ExternalDataProvider p : providers) { if (p.isReady()) { From e9ca30257c6287b834e5cbb830083b7528a0784a Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 18:48:09 +0100 Subject: [PATCH 20/98] woops --- .../java/com/volmit/iris/core/link/HMCLeavesDataProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java index e060569f1..1dd0e5327 100644 --- a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -3,6 +3,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; +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; @@ -53,7 +54,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { Material material = worldBlockType.invoke(o, new Object[0]); if (material == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); - return Bukkit.createBlockData(material); + return new IrisBlockData(Bukkit.createBlockData(material), blockId); } @Override From 289eca35ec82f56327a0b7d5a3a72fdbd362b3a7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 7 Mar 2024 19:41:28 +0100 Subject: [PATCH 21/98] fix missing method parameter types --- .../java/com/volmit/iris/core/link/HMCLeavesDataProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java index 1dd0e5327..2f7d87222 100644 --- a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -37,7 +37,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { try { worldBlockType = new WrappedReturningMethod<>((Class) Class.forName("io.github.fisher2911.hmcleaves.data.BlockData"), "worldBlockType"); apiInstance = getApiInstance(Class.forName("io.github.fisher2911.hmcleaves.api.HMCLeavesAPI")); - setCustomBlock = new WrappedReturningMethod<>((Class) apiInstance.getClass(), "setCustomBlock"); + setCustomBlock = new WrappedReturningMethod<>((Class) apiInstance.getClass(), "setCustomBlock", Location.class, String.class, boolean.class); Object config = getLeavesConfig(apiInstance.getClass()); blockDataMap = getMap(config, "blockDataMap"); itemDataField = getMap(config, "itemSupplierMap"); From a691d49abc8774ea96be4db591427b316046794d Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 8 Mar 2024 19:35:07 +0100 Subject: [PATCH 22/98] fix only the 0 0 chunk being updated --- .../volmit/iris/core/link/ExternalDataProvider.java | 4 ++-- .../iris/core/link/HMCLeavesDataProvider.java | 13 ++++++++++--- .../volmit/iris/core/link/OraxenDataProvider.java | 7 +++---- .../volmit/iris/core/service/ExternalDataSVC.java | 6 +++--- .../com/volmit/iris/engine/framework/Engine.java | 4 +++- 5 files changed, 21 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java index b3104d2e5..7e3b4d00e 100644 --- a/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/ExternalDataProvider.java @@ -4,7 +4,7 @@ import com.volmit.iris.engine.framework.Engine; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; -import org.bukkit.Location; +import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; @@ -30,7 +30,7 @@ public abstract class ExternalDataProvider { public abstract BlockData getBlockData(Identifier blockId) throws MissingResourceException; public abstract ItemStack getItemStack(Identifier itemId) throws MissingResourceException; - public void processUpdate(Engine engine, Location location, Identifier blockId) {}; + public void processUpdate(Engine engine, Block block, Identifier blockId) {}; public abstract Identifier[] getBlockTypes(); diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java index 2f7d87222..3e0a384c9 100644 --- a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -9,7 +9,9 @@ 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; @@ -54,7 +56,10 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { Material material = worldBlockType.invoke(o, new Object[0]); if (material == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); - return new IrisBlockData(Bukkit.createBlockData(material), blockId); + BlockData blockData = Bukkit.createBlockData(material); + if (blockData instanceof Leaves leaves) + leaves.setPersistent(true); + return new IrisBlockData(blockData, blockId); } @Override @@ -65,8 +70,10 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { } @Override - public void processUpdate(Engine engine, Location location, Identifier blockId) { - setCustomBlock.invoke(apiInstance, new Object[]{location, blockId.key(), true}); + public void processUpdate(Engine engine, Block block, Identifier blockId) { + Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), true}); + if (result == null || !result) + Iris.warn("Failed to set custom block! " + blockId.key() + " " + block.getX() + " " + block.getY() + " " + block.getZ()); } @Override diff --git a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java index feaacb769..58e21883d 100644 --- a/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/OraxenDataProvider.java @@ -36,9 +36,8 @@ 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.Chunk; -import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.MultipleFacing; import org.bukkit.inventory.ItemStack; @@ -90,10 +89,10 @@ public class OraxenDataProvider extends ExternalDataProvider { } @Override - public void processUpdate(Engine engine, Location location, Identifier blockId) { + public void processUpdate(Engine engine, Block block, Identifier blockId) { Mechanic mechanic = getFactory(blockId).getMechanic(blockId.key()); if (mechanic instanceof FurnitureMechanic f) { - f.place(location); + f.place(block.getLocation()); } } diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index d466269ad..53f566586 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -25,7 +25,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.plugin.IrisService; import lombok.Data; import org.bukkit.Bukkit; -import org.bukkit.Location; +import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; import org.bukkit.event.EventHandler; import org.bukkit.event.server.PluginEnableEvent; @@ -111,13 +111,13 @@ public class ExternalDataSVC implements IrisService { } } - public void processUpdate(Engine engine, Location location, Identifier blockId) { + public void processUpdate(Engine engine, Block block, Identifier blockId) { Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, true)).findFirst(); if (provider.isEmpty()) { Iris.warn("No matching Provider found for modded material \"%s\"!", blockId); return; } - provider.get().processUpdate(engine, location, blockId); + provider.get().processUpdate(engine, block, blockId); } public Identifier[] getAllBlockIdentifiers() { diff --git a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java index d80b23d1b..e1f6560dc 100644 --- a/core/src/main/java/com/volmit/iris/engine/framework/Engine.java +++ b/core/src/main/java/com/volmit/iris/engine/framework/Engine.java @@ -259,6 +259,8 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat } if (data instanceof IrisBlockData d) { getMantle().getMantle().set(x, y, z, d.getCustom()); + } else { + getMantle().getMantle().remove(x, y, z, Identifier.class); } } @@ -285,7 +287,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat })); 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, new Location(c.getWorld(), x, y + getWorld().minHeight(), z), v); + Iris.service(ExternalDataSVC.class).processUpdate(this, c.getBlock(x & 15, y + getWorld().minHeight(), z & 15), v); }); })); From 9612fef2a4bd8f670786e064096fb2d87b1ae81f Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sat, 16 Mar 2024 12:40:40 +0100 Subject: [PATCH 23/98] - 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? --- build.gradle | 4 +- .../iris/core/commands/CommandDeveloper.java | 134 ++++++-- .../iris/core/commands/CommandIris.java | 40 +++ .../iris/core/commands/CommandWhat.java | 18 +- .../core/pregenerator/IrisPregenerator.java | 11 +- .../iris/core/service/IrisEngineSVC.java | 155 ++++++++- .../volmit/iris/core/tools/IrisConverter.java | 315 ++++++++++++++++-- .../volmit/iris/core/tools/IrisCreator.java | 12 +- .../iris/core/tools/IrisPackBenchmarking.java | 130 +------- .../volmit/iris/engine/IrisEngineMantle.java | 20 +- .../iris/engine/mantle/EngineMantle.java | 2 +- .../com/volmit/iris/util/mantle/Mantle.java | 65 ++-- 12 files changed, 669 insertions(+), 237 deletions(-) diff --git a/build.gradle b/build.gradle index eeca2a32a..bcd5a3319 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ 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/Iris Development/plugins') +registerCustomOutputTask('Pixel', 'C://Users/repix/Iris Dimension Engine/1.20.4 - Iris Development/plugins') // ========================== UNIX ============================== registerCustomOutputTaskUnix('CyberpwnLT', '/Users/danielmills/development/server/plugins') registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDevelopment/Server/plugins') @@ -246,7 +246,7 @@ allprojects { compileOnly 'org.zeroturnaround:zt-zip:1.14' compileOnly 'com.google.code.gson:gson:2.9.0' 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' diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 898b99fca..06c2f15b0 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -38,9 +38,13 @@ 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 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; @@ -51,33 +55,119 @@ public class CommandDeveloper implements DecreeExecutor { private CommandTurboPregen turboPregen; @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 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(); + 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("-------------------------"); + } - 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!"); + @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 = "UnloadChunks for good reasons.") + public void unloadchunks() { + List 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 networkInterfaces = NetworkInterface.getNetworkInterfaces(); + for (NetworkInterface ni : Collections.list(networkInterfaces)) { + Iris.info("Display Name: %s", ni.getDisplayName()); + Enumeration inetAddresses = ni.getInetAddresses(); + for (InetAddress ia : Collections.list(inetAddresses)) { + Iris.info("IP: %s", ia.getHostAddress()); + } + } + } catch (Exception e) { + e.printStackTrace(); } } + @Decree(description = "Test", origin = DecreeOrigin.BOTH) public void test() { Iris.info("Test Developer CMD Executed"); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index dce8d8db0..471189d9e 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -24,6 +24,7 @@ import com.volmit.iris.core.loader.IrisData; 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; @@ -52,6 +53,7 @@ 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; @@ -216,6 +218,44 @@ public class CommandIris implements DecreeExecutor { Iris.service(StudioSVC.class).open(sender(), 1337, "overworld"); } + @Decree(description = "Check if iris has access to that specific world") + public void hasAccess( + @Param(description = "The world to access", aliases = {"world"}) + World world + ) { + Engine engine = IrisToolbelt.access(world).getEngine(); + if (engine != null) { + sender().sendMessage("Access granted successfully."); + } else { + sender().sendMessage(C.RED + "Failed to grant access."); + } + } + + @Decree(description = "All Iris Worlds on the server.", aliases = {"worlds"}) + public void irisworlds() { + List IrisWorlds = new ArrayList<>(); + for (World world : Bukkit.getWorlds()) { + try { + if (IrisToolbelt.access(world).getEngine() != null) { + IrisWorlds.add(world); + } + } catch (Exception e) { + // no + } + } + if (sender().isPlayer()) { + sender.sendMessage(C.IRIS + "Iris Worlds:"); + for (World world : IrisWorlds) { + sender.sendMessage(C.GREEN + "- " + world.getName()); + } + } else { + Iris.info(C.IRIS + "Iris Worlds:"); + for (World world : IrisWorlds) { + sender.sendMessage(C.GREEN + "- " + world.getName()); + } + } + } + @Decree(description = "Remove an Iris world", aliases = {"del", "rm", "delete"}, sync = true) public void remove( @Param(description = "The world to remove") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java b/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java index 3686ad81a..48d8c726e 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandWhat.java @@ -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."); } } } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index c23b6c6fd..b693e0034 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -19,9 +19,7 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; -import com.volmit.iris.core.tools.IrisPackBenchmarking; import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.M; @@ -30,15 +28,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; @@ -112,11 +107,7 @@ 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); - } else { - 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); - } + 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); } return 1000; } diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index 6f3f79535..767e9c166 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -4,32 +4,67 @@ import com.volmit.iris.Iris; 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.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; private static final AtomicInteger tectonicLimit = new AtomicInteger(30); private final ReentrantLock lastUseLock = new ReentrantLock(); private final KMap lastUse = new KMap<>(); + private List IrisWorlds; private Looper cacheTicker; + private Looper freezeTicker; 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 corruptedIrisWorlds = new ArrayList<>(); @Override public void onEnable() { + this.cl = new ChronoLatch(5000); + 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 +72,50 @@ public class IrisEngineSVC implements IrisService { t = t - 200; } this.setup(); + trimAlive.begin(); + unloadAlive.begin(); + trimActiveAlive.begin(); + unloadActiveAlive.begin(); + + updateTicker.start(); cacheTicker.start(); trimTicker.start(); unloadTicker.start(); + freezeTicker.start(); + instance = this; + } public static int getTectonicLimit() { return tectonicLimit.get(); } + public void EngineReport() { + Iris.info(C.RED + "CRITICAL ENGINE FAILURE! The Tectonic Trim subsystem has not responded for: " + Form.duration(trimAlive.getMillis()) + "."); + } + + @EventHandler + public void onWorldUnload(WorldUnloadEvent event) { + updateWorlds(); + } + + @EventHandler + public void onWorldLoad(WorldLoadEvent event) { + updateWorlds(); + } + + 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 +127,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,11 +137,81 @@ public class IrisEngineSVC implements IrisService { return 1000; } }; + + updateTicker = new Looper() { + @Override + protected long loop() { + try { + TotalQueuedTectonicPlates.set(0); + TotalNotQueuedTectonicPlates.set(0); + TotalTectonicPlates.set(0); + for (World world : IrisWorlds) { + Engine engine = IrisToolbelt.access(world).getEngine(); + TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload()); + TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions()); + TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount()); + } + } catch (Exception e) { + return -1; + } + return 1000; + } + }; + + freezeTicker = new Looper() { + @Override + protected long loop() { + if (cl.flip()) { + if (!unloadTicker.isAlive()) { + Iris.debug(C.YELLOW + "UnloadTicker Found dead?"); + } + if (!trimTicker.isAlive()) { + Iris.debug(C.YELLOW + "UnloadTicker Found dead?"); + } + Runtime runtime = Runtime.getRuntime(); + long usedMemory = runtime.totalMemory() - runtime.freeMemory(); + long maxMemory = runtime.maxMemory(); + double memoryUsagePercentage = ((double) usedMemory / (double) maxMemory); + double externalTrim = trimActiveAlive.getMillis(); + double externalUnload = unloadActiveAlive.getMillis(); + double localTrim = trimAlive.getMillis(); + double localUnload = unloadAlive.getMillis(); + if (localTrim > 120000) { + Iris.info(C.YELLOW + "EngineSVC Alert! The Trim subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + "."); + } + if (localUnload > 120000) { + Iris.info(C.YELLOW + "EngineSVC Alert! The Tectonic subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + "."); + } + + if (memoryUsagePercentage > 0.9 && tectonicLimit.get() < TotalTectonicPlates.get()) { + if (localTrim > 30000 && externalTrim > 10000) { + Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Trim subsystem has not trimmed for: " + Form.duration(trimAlive.getMillis()) + "."); + IsTrimAlive.set(false); + } else { + Iris.info(C.IRIS + "EngineSVC reports activity within the Trim subsystem system!"); + IsTrimAlive.set(true); + } + + if (localUnload > 30000 && externalUnload > 12000 && TotalQueuedTectonicPlates.get() != 0) { + Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Unload subsystem has not unloaded for: " + Form.duration(trimAlive.getMillis()) + "."); + IsUnloadAlive.set(false); + } else { + Iris.info(C.IRIS + "EngineSVC reports activity within the Unload subsystem system!"); + IsUnloadAlive.set(true); + } + } + } + return 1; + } + + }; + trimTicker = new Looper() { private final Supplier supplier = createSupplier(); @Override protected long loop() { long start = System.currentTimeMillis(); + trimAlive.reset(); try { Engine engine = supplier.get(); if (engine != null) { @@ -79,7 +219,9 @@ public class IrisEngineSVC implements IrisService { } } catch (Throwable e) { Iris.reportError(e); - // return -1; + Iris.info(C.RED + "EngineSVC: Failed to trim. Please contact support!"); + e.printStackTrace(); + return -1; } int size = lastUse.size(); @@ -96,6 +238,7 @@ public class IrisEngineSVC implements IrisService { @Override protected long loop() { long start = System.currentTimeMillis(); + unloadAlive.reset(); try { Engine engine = supplier.get(); if (engine != null) { @@ -107,6 +250,8 @@ public class IrisEngineSVC implements IrisService { } } catch (Throwable e) { Iris.reportError(e); + Iris.info(C.RED + "EngineSVC: Failed to unload. Please contact support!"); + e.printStackTrace(); return -1; } @@ -145,6 +290,8 @@ public class IrisEngineSVC implements IrisService { } } } catch (Throwable e) { + Iris.info(C.RED + "EngineSVC: Failed to create supplier. Please contact support!"); + e.printStackTrace(); Iris.reportError(e); } return null; diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java index da882f56c..fb4d344eb 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -2,30 +2,26 @@ package com.volmit.iris.core.tools; import com.volmit.iris.Iris; import com.volmit.iris.engine.object.*; -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.math.M; -import com.volmit.iris.util.math.RollingSequence; 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.VolmitPlugin; 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.Looper; import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import javassist.bytecode.ByteArray; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; import org.bukkit.Bukkit; -import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.data.BlockData; -import org.bukkit.util.BlockVector; +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; @@ -33,15 +29,14 @@ import java.util.concurrent.atomic.AtomicInteger; public class IrisConverter { public static void convertSchematics(VolmitSender sender) { - Map blockmap = new HashMap<>(); 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 { - ExecutorService executorService = Executors.newFixedThreadPool(1); - executorService.submit(() -> { PrecisionStopwatch p = new PrecisionStopwatch(); boolean largeObject = false; NamedTag tag = null; @@ -57,24 +52,26 @@ public class IrisConverter { int objW = ((ShortTag) compound.get("Width")).getValue(); int objH = ((ShortTag) compound.get("Height")).getValue(); int objD = ((ShortTag) compound.get("Length")).getValue(); - IrisObject object = new IrisObject(objW, objH, objD); int mv = objW * objH * objD; AtomicInteger v = new AtomicInteger(0); - if (mv > 100000) { + 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); - } +// 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 blockmap = new HashMap<>(paletteTag.size(), 0.9f); for (Map.Entry> entry : paletteTag.getValue().entrySet()) { String blockName = entry.getKey(); BlockData bd = Bukkit.createBlockData(blockName); @@ -84,18 +81,179 @@ public class IrisConverter { } ByteArrayTag byteArray = (ByteArrayTag) compound.get("BlockData"); - byte[] l = byteArray.getValue(); + byte[] originalBlockArray = byteArray.getValue(); + int b = 0; + int a = 0; + Map y = new HashMap<>(); + Map x = new HashMap<>(); + Map 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 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 db = blockmap.get((int) l[v.get()]); - object.setUnsigned(w, h, d, db); + 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) { @@ -103,7 +261,11 @@ public class IrisConverter { 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())); @@ -112,13 +274,120 @@ public class IrisConverter { } // 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 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 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 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); } } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 7e6285d07..3e90aced1 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -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,10 @@ public class IrisCreator { * the world itself. Studio worlds are deleted when they are unloaded. */ private boolean studio = false; + /** + * Benchmark mode + */ + private boolean benchmark = false; public static boolean removeFromBukkitYml(String name) throws IOException { YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML); @@ -110,7 +110,7 @@ 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."); @@ -193,7 +193,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)); }); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 13577cc82..60c9aa76b 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -21,97 +21,28 @@ import static com.volmit.iris.core.commands.CommandIris.BenchDimension; 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; + public static IrisPackBenchmarking instance; + long totalChunks; + long generatedChunks; + double elapsedTimeNs; - public static void runBenchmark() { - // IrisPackBenchmarking IrisPackBenchmarking = new IrisPackBenchmarking(); - benchmark = true; - Iris.info(C.BLUE + "Benchmarking Dimension: " + C.AQUA + BenchDimension); - //progress(); - CompletableFuture 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; - - } - } - } catch (Exception e) { - throw new RuntimeException(); - } - - }).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) { - 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)); + public void runBenchmark() { } - 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(){ + public void createBenchmark(){ try { IrisToolbelt.createWorld() .dimension(BenchDimension) .name("Benchmark") .seed(1337) .studio(false) + .benchmark(true) .create(); } catch (IrisException e) { throw new RuntimeException(e); } } - static void startBenchmark(){ + public void startBenchmark(){ int x = 0; int z = 0; IrisToolbelt.pregenerate(PregenTask @@ -122,49 +53,4 @@ public class IrisPackBenchmarking { .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(); - } - } - } - dir.delete(); - } - private static double roundToTwoDecimalPlaces(double value) { - return Double.parseDouble(String.format("%.2f", value)); - } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java b/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java index f61d90531..8e28490d8 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisEngineMantle.java @@ -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; } diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 25aca5aed..62e18e0d8 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -298,7 +298,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(){ diff --git a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java index e71652a28..52982442c 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -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; @@ -423,7 +424,7 @@ 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())) { @@ -433,7 +434,7 @@ public class Mantle { 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 +453,41 @@ public class Mantle { AtomicInteger i = new AtomicInteger(); unloadLock.lock(); BurstExecutor burst = null; - try { - KList 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 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)); + IrisEngineSVC.instance.unloadActiveAlive.reset(); + } catch (IOException e) { + Iris.reportError(e); + } } - } - })); + })); - } - burst.complete(); - } catch (Throwable e) { - e.printStackTrace(); - if (burst != null) + } 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(); } From 8af212fca84c749bdc5fbced1000aca858aa4fd2 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sun, 17 Mar 2024 17:55:08 +0100 Subject: [PATCH 24/98] - Fixed entities spawning inside blocks or at least it should. --- .../iris/core/commands/CommandDeveloper.java | 18 ++++++--- .../com/volmit/iris/core/nms/INMSBinding.java | 9 +++-- .../iris/core/nms/v1X/NMSBinding1X.java | 10 +++++ .../iris/engine/object/IrisEntitySpawn.java | 39 ++++++++++++++++++- .../iris/core/nms/v1_19_R1/NMSBinding.java | 27 +++++++++++++ .../iris/core/nms/v1_19_R2/NMSBinding.java | 28 +++++++++++++ .../iris/core/nms/v1_19_R3/NMSBinding.java | 28 +++++++++++++ .../iris/core/nms/v1_20_R1/NMSBinding.java | 28 +++++++++++++ .../iris/core/nms/v1_20_R2/NMSBinding.java | 27 +++++++++++++ .../iris/core/nms/v1_20_R3/NMSBinding.java | 34 ++++++++++++++++ 10 files changed, 237 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 06c2f15b0..8363cd146 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -20,9 +20,12 @@ package com.volmit.iris.core.commands; 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.v1X.NMSBinding1X; import com.volmit.iris.core.service.IrisEngineSVC; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisEntity; import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.annotations.Decree; @@ -31,7 +34,9 @@ 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.Vector3d; 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; @@ -40,6 +45,8 @@ import org.apache.commons.lang.RandomStringUtils; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EntityType; import java.io.*; import java.net.InetAddress; @@ -126,6 +133,12 @@ public class CommandDeveloper implements DecreeExecutor { } + @Decree(description = "test") + public void test() throws NoSuchFieldException, IllegalAccessException { + Iris.info("CMD Executed"); + Vector3d box2 = INMS.get().getBoundingbox(EntityType.CREEPER); + } + @Decree(description = "UnloadChunks for good reasons.") public void unloadchunks() { List IrisWorlds = new ArrayList<>(); @@ -168,11 +181,6 @@ public class CommandDeveloper implements DecreeExecutor { } } - @Decree(description = "Test", origin = DecreeOrigin.BOTH) - public void test() { - Iris.info("Test Developer CMD Executed"); - } - @Decree(description = "Test the compression algorithms") public void compression( @Param(description = "base IrisWorld") World world, diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 270a04504..5989a50d8 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -19,16 +19,15 @@ package com.volmit.iris.core.nms; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisEntity; 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; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.WorldCreator; +import org.bukkit.*; import org.bukkit.block.Biome; import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; @@ -103,4 +102,6 @@ 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); } diff --git a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java index 04c95b4ed..754915c2c 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java +++ b/core/src/main/java/com/volmit/iris/core/nms/v1X/NMSBinding1X.java @@ -25,6 +25,7 @@ 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; @@ -85,6 +86,10 @@ public class NMSBinding1X implements INMSBinding { } + public Vector3d getBoundingbox() { + return null; + } + @Override public void deserializeTile(CompoundTag s, Location newPosition) { @@ -203,6 +208,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!"); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java index 9b2aa6fb0..a507c342f 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntitySpawn.java @@ -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; + } } diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java index eec445bee..ff0433491 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java @@ -10,6 +10,7 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -24,6 +25,7 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -54,8 +56,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -483,6 +487,29 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java index bcdda2dea..7609c6195 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java @@ -10,6 +10,7 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -25,6 +26,7 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -54,8 +56,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -483,6 +487,30 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index f11974faf..2244ed16c 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -10,6 +10,7 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -25,6 +26,7 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -56,8 +58,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -486,6 +490,30 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 02169ff3f..4852ee5fa 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -10,6 +10,7 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -25,6 +26,7 @@ import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityDimensions; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -45,6 +47,7 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack; import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -56,8 +59,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -474,6 +479,29 @@ public class NMSBinding implements INMSBinding { cd.getHandle().setGotFish(true); } + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = net.minecraft.world.entity.EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(net.minecraft.world.entity.EntityType.class)) { + try { + net.minecraft.world.entity.EntityType entityType = (net.minecraft.world.entity.EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException { ServerLevel serverLevel = ((CraftWorld)world).getHandle(); Class clazz = serverLevel.getChunkSource().chunkMap.generator.getClass(); diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 1f02cf3ab..e39897d6b 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -10,6 +10,7 @@ import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; @@ -26,6 +27,7 @@ import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -57,8 +59,10 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -486,6 +490,29 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 167400d19..0cf438604 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -5,16 +5,21 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisEntity; 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.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.matter.MatterBiomeInject; import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import io.lumine.mythic.bukkit.adapters.BukkitEntity; import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; @@ -26,6 +31,8 @@ import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; +import net.minecraft.tags.EntityTypeTags; +import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; @@ -44,6 +51,7 @@ import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin; import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; +import org.bukkit.entity.Creeper; import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.generator.ChunkGenerator; @@ -57,8 +65,11 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Optional; +import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; public class NMSBinding implements INMSBinding { @@ -486,6 +497,29 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { From 7b1e666b3b492d81f29103b4b80e652f6d02b935 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Mon, 18 Mar 2024 11:22:35 +0100 Subject: [PATCH 25/98] - No studio tectonic clearing. --- .../main/java/com/volmit/iris/core/service/IrisEngineSVC.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index 767e9c166..a998e9bd4 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -281,7 +281,7 @@ public class IrisEngineSVC implements IrisService { if (generator != null) { Engine engine = generator.getEngine(); - if (engine != null) { + if (engine != null && !engine.isStudio()) { lastUseLock.lock(); lastUse.put(world, System.currentTimeMillis()); lastUseLock.unlock(); @@ -290,7 +290,7 @@ public class IrisEngineSVC implements IrisService { } } } catch (Throwable e) { - Iris.info(C.RED + "EngineSVC: Failed to create supplier. Please contact support!"); + Iris.info(C.RED + "EngineSVC: Failed to create supplier."); e.printStackTrace(); Iris.reportError(e); } From ccbea892533c970a7bfe7e1e8e7dca4ce686ae5b Mon Sep 17 00:00:00 2001 From: svdgoor Date: Mon, 18 Mar 2024 17:28:08 +0100 Subject: [PATCH 26/98] prevent spawning camels on 1.19.R3 --- .../java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index 78d8cb1a5..8a2728a53 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -491,6 +491,9 @@ public class NMSBinding implements INMSBinding { @Override public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + if (type == EntityType.CAMEL) { + return null; + } return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } From 15b8780e178000b641f230c4b84a1fc8e5a381f7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 20 Mar 2024 08:44:00 +0100 Subject: [PATCH 27/98] remove usage of System.out --- core/src/main/java/com/volmit/iris/Iris.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index a39306991..8d384fb38 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -128,6 +128,10 @@ public class Iris extends VolmitPlugin implements Listener { private KMap, 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) { } @@ -426,7 +430,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(); } @@ -451,9 +455,7 @@ public class Iris extends VolmitPlugin implements Listener { 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 +528,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,7 +729,7 @@ 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()); From 5561a4dc2f51ecb7aa9564738b9e0e260eefe4a3 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 20 Mar 2024 08:46:56 +0100 Subject: [PATCH 28/98] fix wrong color bug --- core/src/main/java/com/volmit/iris/Iris.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 8d384fb38..03e1fa249 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -450,10 +450,10 @@ 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) i.getClass(), (IrisService) i)); INMS.get(); IO.delete(new File("iris")); - setupAudience(); IrisSafeguard.IrisSafeguardSystem(); getSender().setTag(getTag()); compat = IrisCompat.configured(getDataFile("compat.json")); From 50686795d02580e493cf50b10c73382e4c7fb8e7 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Wed, 20 Mar 2024 11:32:44 +0100 Subject: [PATCH 29/98] - 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. - Perhaps more? --- .../volmit/iris/core/commands/CommandDeveloper.java | 12 +++++++++++- .../volmit/iris/engine/object/IrisCavePlacer.java | 10 +++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 8363cd146..3509c262e 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -25,6 +25,9 @@ import com.volmit.iris.core.nms.v1X.NMSBinding1X; import com.volmit.iris.core.service.IrisEngineSVC; 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.IrisEntity; import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; @@ -44,6 +47,7 @@ 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; @@ -136,7 +140,13 @@ public class CommandDeveloper implements DecreeExecutor { @Decree(description = "test") public void test() throws NoSuchFieldException, IllegalAccessException { Iris.info("CMD Executed"); - Vector3d box2 = INMS.get().getBoundingbox(EntityType.CREEPER); + Engine engine = IrisToolbelt.access(player().getWorld()).getEngine(); + Location at = player().getLocation(); + IrisBiome caveBiome = engine.getMantle().getComplex().getCaveBiomeStream().get(at.getBlockX(), at.getBlockZ()); + if (!caveBiome.getName().contains("Subterranean Land")) { + sender().sendMessage("Cool cave?: " + caveBiome.getName()); + } + } @Decree(description = "UnloadChunks for good reasons.") diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java index 17dd4623d..911323e4a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java @@ -52,6 +52,8 @@ public class IrisCavePlacer implements IRare { private String cave; @Desc("If set to true, this cave is allowed to break the surface") private boolean breakSurface = true; + @Desc("If set to true, this cave is allowed to get placed above the terrain level") + private boolean ignoreHeightLimit = false; @Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.") private IrisStyledRange caveStartHeight = new IrisStyledRange(13, 120, new IrisGeneratorStyle(NoiseStyle.STATIC)); @@ -82,13 +84,19 @@ public class IrisCavePlacer implements IRare { } if (y == -1) { + if(!ignoreHeightLimit) { + int eH = engine.getHeight(x, z); + if (caveStartHeight.getMax() > eH) { + caveStartHeight.setMax(eH); + } + } 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); } 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); From b2934b0cc27b2949bbca6d9a22da238c1538380d Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 27 Mar 2024 19:02:20 +0100 Subject: [PATCH 30/98] fix object collision check --- .../java/com/volmit/iris/engine/object/IrisObject.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 03a306a1c..8b5924e41 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -23,6 +23,7 @@ import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.PlacedObject; import com.volmit.iris.engine.framework.placer.HeightmapObjectPlacer; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; @@ -698,12 +699,15 @@ public class IrisObject extends IrisRegistrant { if (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty()) { Engine engine = rdata.getEngine(); - String key; BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { for (int j = y - Math.floorDiv(h, 2) + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) { for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) { - key = engine.getObjectPlacementKey(i, j, k); + PlacedObject p = engine.getObjectPlacement(i, j, k); + if (p == null) continue; + IrisObject o = p.getObject(); + if (o == null) continue; + String key = o.getLoadKey(); if (key != null) { if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) { // Iris.debug("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k); From 04ad02719c9e73d95e5cfd2d0b8e64b111aeeb7f Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Sat, 30 Mar 2024 18:48:00 -0400 Subject: [PATCH 31/98] d --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0cf2c067d..8fc97007b 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.2.0-1.19.2-1.20.4' +version '3.2.1-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From eb94d97ea41930fe5733b8b4abbf87a4851782d2 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sun, 31 Mar 2024 17:53:10 +0200 Subject: [PATCH 32/98] - Fixed caves breaksurface - changes --- core/src/main/java/com/volmit/iris/Iris.java | 9 +- .../com/volmit/iris/core/IrisSettings.java | 1 + .../iris/core/commands/CommandDeepSearch.java | 2 +- .../iris/core/commands/CommandDeveloper.java | 21 +- .../iris/core/commands/CommandIris.java | 2 - .../iris/core/commands/CommandPregen.java | 1 + .../volmit/iris/core/gui/PregeneratorJob.java | 5 +- .../pregenerator/DeepSearchPregenerator.java | 70 +++---- .../core/pregenerator/IrisPregenerator.java | 29 +-- .../iris/core/pregenerator/PregenTask.java | 2 + .../iris/core/safeguard/ServerBootSFG.java | 33 +--- .../iris/core/service/IrisEngineSVC.java | 108 +++++------ .../iris/core/service/WorldLoadSFG.java | 31 --- .../iris/core/tools/IrisPackBenchmarking.java | 179 ++++++++++++++++-- .../iris/engine/mantle/EngineMantle.java | 1 + .../engine/object/IrisBiomeGeneratorLink.java | 12 ++ .../iris/engine/object/IrisCavePlacer.java | 8 +- 17 files changed, 320 insertions(+), 194 deletions(-) delete mode 100644 core/src/main/java/com/volmit/iris/core/service/WorldLoadSFG.java diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index a39306991..70031c5ee 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -364,6 +364,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"); @@ -804,6 +811,7 @@ public class Iris extends VolmitPlugin implements Listener { 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.."); @@ -842,7 +850,6 @@ public class Iris extends VolmitPlugin implements Listener { Iris.warn("6GB+ Ram is recommended"); } Iris.info("Bukkit version: " + Bukkit.getBukkitVersion()); - Iris.info("Java version: " + getJavaVersion()); Iris.info("Custom Biomes: " + INMS.get().countCustomBiomes()); setupChecks(); printPacks(); diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 335207de5..4abe1ba79 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,6 +177,7 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; + // public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java index 96c91305f..d8cd6a260 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeepSearch.java @@ -74,7 +74,7 @@ public class CommandDeepSearch implements DecreeExecutor { } DeepSearchPregenerator.DeepSearchJob DeepSearchJob = DeepSearchPregenerator.DeepSearchJob.builder() - .world(worldName) + .world(world) .radiusBlocks(radius) .position(0) .build(); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 3509c262e..759596ea5 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -23,12 +23,15 @@ import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.nms.INMS; import com.volmit.iris.core.nms.v1X.NMSBinding1X; 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; @@ -137,15 +140,19 @@ public class CommandDeveloper implements DecreeExecutor { } + @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 = "test") public void test() throws NoSuchFieldException, IllegalAccessException { - Iris.info("CMD Executed"); - Engine engine = IrisToolbelt.access(player().getWorld()).getEngine(); - Location at = player().getLocation(); - IrisBiome caveBiome = engine.getMantle().getComplex().getCaveBiomeStream().get(at.getBlockX(), at.getBlockZ()); - if (!caveBiome.getName().contains("Subterranean Land")) { - sender().sendMessage("Cool cave?: " + caveBiome.getName()); - } + IrisEngineSVC.instance.engineStatus(); } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 471189d9e..fc8a2d90b 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -76,8 +76,6 @@ public class CommandIris implements DecreeExecutor { private CommandEdit edit; private CommandFind find; private CommandDeveloper developer; - - public static @Getter String BenchDimension; public static boolean worldCreation = false; String WorldToLoad; String WorldEngine; diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java index 73f93091d..e3ed1c844 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandPregen.java @@ -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); diff --git a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java index 25f3ee710..6d3534971 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java +++ b/core/src/main/java/com/volmit/iris/core/gui/PregeneratorJob.java @@ -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(); } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java index c0a20534c..c60724d2a 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/DeepSearchPregenerator.java @@ -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 chunkCache; - private final ReentrantLock cacheLock = new ReentrantLock(); + private KList chunkQueue; + private final ReentrantLock cacheLock; private static final Map 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 diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java index b693e0034..b5b705900 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/IrisPregenerator.java @@ -19,7 +19,11 @@ 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; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.M; @@ -45,6 +49,7 @@ public class IrisPregenerator { private final RollingSequence chunksPerSecond; private final RollingSequence chunksPerMinute; private final RollingSequence regionsPerMinute; + private final KList chunksPerSecondHistory; private static AtomicInteger generated; private final AtomicInteger generatedLast; private final AtomicInteger generatedLastMinute; @@ -57,8 +62,6 @@ public class IrisPregenerator { private final KSet 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); @@ -75,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); @@ -88,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(); @@ -95,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(), @@ -107,7 +110,11 @@ public class IrisPregenerator { if (cl.flip()) { double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100; - Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); + if (!IrisPackBenchmarking.benchmarkInProgress) { + Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); + } else { + Iris.info("Benchmarking: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); + } } return 1000; } @@ -123,13 +130,6 @@ public class IrisPregenerator { ); } - public static long getLongGeneratedChunks() { - return long_generatedChunks; - } - public static long getLongTotalChunks() { - return long_totalChunks; - } - public void close() { shutdown.set(true); @@ -142,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() { diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java index 4abe057f8..015a418a1 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/PregenTask.java @@ -35,6 +35,8 @@ public class PregenTask { private static final KList ORDER_CENTER = computeChunkOrder(); private static final KMap> ORDERS = new KMap<>(); + @Builder.Default + private boolean gui = false; @Builder.Default private Position2 center = new Position2(0, 0); @Builder.Default diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index 6fc87f183..754744e41 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -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 javax.tools.JavaCompiler; +import javax.tools.ToolProvider; import java.io.File; import java.nio.channels.FileChannel; import java.nio.file.Files; @@ -17,9 +17,6 @@ import java.nio.file.StandardOpenOption; import java.util.HashMap; 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; @@ -128,25 +125,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)) { diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index a998e9bd4..b2595e3ad 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -1,6 +1,7 @@ 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; @@ -17,6 +18,8 @@ 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; @@ -30,12 +33,13 @@ 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 lastUse = new KMap<>(); + private ReentrantLock lastUseLock; + private KMap lastUse; private List IrisWorlds; private Looper cacheTicker; - private Looper freezeTicker; private Looper trimTicker; private Looper unloadTicker; private Looper updateTicker; @@ -55,6 +59,8 @@ public class IrisEngineSVC implements IrisService { @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); @@ -81,11 +87,19 @@ public class IrisEngineSVC implements IrisService { cacheTicker.start(); trimTicker.start(); unloadTicker.start(); - freezeTicker.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(); } @@ -104,6 +118,18 @@ public class IrisEngineSVC implements IrisService { 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 { @@ -146,11 +172,33 @@ public class IrisEngineSVC implements IrisService { TotalNotQueuedTectonicPlates.set(0); TotalTectonicPlates.set(0); for (World world : IrisWorlds) { - Engine engine = IrisToolbelt.access(world).getEngine(); + Engine engine = Objects.requireNonNull(IrisToolbelt.access(world)).getEngine(); TotalQueuedTectonicPlates.addAndGet((int) engine.getMantle().getToUnload()); TotalNotQueuedTectonicPlates.addAndGet((int) engine.getMantle().getNotQueuedLoadedRegions()); TotalTectonicPlates.addAndGet(engine.getMantle().getLoadedRegionCount()); } + if (!isServerShuttingDown && isServerLoaded) { + if (!trimTicker.isAlive()) { + Iris.info(C.IRIS + "TrimTicker found dead! Booting it up!"); + try { + trimTicker.start(); + } catch (Exception e) { + Iris.error("What happened?"); + e.printStackTrace(); + } + } + + if (!unloadTicker.isAlive()) { + Iris.info(C.IRIS + "UnloadTicker found dead! Booting it up!"); + try { + unloadTicker.start(); + } catch (Exception e) { + Iris.error("What happened?"); + e.printStackTrace(); + } + } + } + } catch (Exception e) { return -1; } @@ -158,54 +206,6 @@ public class IrisEngineSVC implements IrisService { } }; - freezeTicker = new Looper() { - @Override - protected long loop() { - if (cl.flip()) { - if (!unloadTicker.isAlive()) { - Iris.debug(C.YELLOW + "UnloadTicker Found dead?"); - } - if (!trimTicker.isAlive()) { - Iris.debug(C.YELLOW + "UnloadTicker Found dead?"); - } - Runtime runtime = Runtime.getRuntime(); - long usedMemory = runtime.totalMemory() - runtime.freeMemory(); - long maxMemory = runtime.maxMemory(); - double memoryUsagePercentage = ((double) usedMemory / (double) maxMemory); - double externalTrim = trimActiveAlive.getMillis(); - double externalUnload = unloadActiveAlive.getMillis(); - double localTrim = trimAlive.getMillis(); - double localUnload = unloadAlive.getMillis(); - if (localTrim > 120000) { - Iris.info(C.YELLOW + "EngineSVC Alert! The Trim subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + "."); - } - if (localUnload > 120000) { - Iris.info(C.YELLOW + "EngineSVC Alert! The Tectonic subsystem has exceeded its expected response time: " + Form.duration(trimAlive.getMillis()) + "."); - } - - if (memoryUsagePercentage > 0.9 && tectonicLimit.get() < TotalTectonicPlates.get()) { - if (localTrim > 30000 && externalTrim > 10000) { - Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Trim subsystem has not trimmed for: " + Form.duration(trimAlive.getMillis()) + "."); - IsTrimAlive.set(false); - } else { - Iris.info(C.IRIS + "EngineSVC reports activity within the Trim subsystem system!"); - IsTrimAlive.set(true); - } - - if (localUnload > 30000 && externalUnload > 12000 && TotalQueuedTectonicPlates.get() != 0) { - Iris.info(C.RED + "CRITICAL EngineSVC FAILURE! The Tectonic Unload subsystem has not unloaded for: " + Form.duration(trimAlive.getMillis()) + "."); - IsUnloadAlive.set(false); - } else { - Iris.info(C.IRIS + "EngineSVC reports activity within the Unload subsystem system!"); - IsUnloadAlive.set(true); - } - } - } - return 1; - } - - }; - trimTicker = new Looper() { private final Supplier supplier = createSupplier(); @Override @@ -250,7 +250,7 @@ public class IrisEngineSVC implements IrisService { } } catch (Throwable e) { Iris.reportError(e); - Iris.info(C.RED + "EngineSVC: Failed to unload. Please contact support!"); + Iris.info(C.RED + "EngineSVC: Failed to unload."); e.printStackTrace(); return -1; } diff --git a/core/src/main/java/com/volmit/iris/core/service/WorldLoadSFG.java b/core/src/main/java/com/volmit/iris/core/service/WorldLoadSFG.java deleted file mode 100644 index 845edf054..000000000 --- a/core/src/main/java/com/volmit/iris/core/service/WorldLoadSFG.java +++ /dev/null @@ -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() { - - } -} diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java index 60c9aa76b..7993cf6e7 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisPackBenchmarking.java @@ -2,38 +2,132 @@ 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 { + @Getter public static IrisPackBenchmarking instance; - long totalChunks; - long generatedChunks; - double elapsedTimeNs; + public static boolean benchmarkInProgress = false; + private IrisDimension IrisDimension; + private int radius; + private boolean finished = false; + PrecisionStopwatch stopwatch; - public void runBenchmark() { + 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 void createBenchmark(){ + + public boolean getBenchmarkInProgress() { + return benchmarkInProgress; + } + + public void finishedBenchmark(KList 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 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); + } + 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(); + } + + Bukkit.getServer().unloadWorld("benchmark", true); + stopwatch.end(); + } catch (Exception e) { + Iris.error("Something has gone wrong!"); + e.printStackTrace(); + } + } + private void createBenchmark(){ try { IrisToolbelt.createWorld() - .dimension(BenchDimension) - .name("Benchmark") + .dimension(IrisDimension.getName()) + .name("benchmark") .seed(1337) .studio(false) .benchmark(true) @@ -42,15 +136,66 @@ public class IrisPackBenchmarking { throw new RuntimeException(e); } } - public 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") ); } + + private double calculateAverage(KList list) { + double sum = 0; + for (int num : list) { + sum += num; + } + return sum / list.size(); + } + + private double calculateMedian(KList 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 list) { + return Collections.min(list); + } + + private int findHighest(KList list) { + return Collections.max(list); + } + + private boolean deleteDirectory(Path dir) { + try { + Files.walkFileTree(dir, new SimpleFileVisitor() { + @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; + } + } } \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java index 62e18e0d8..187b41685 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/EngineMantle.java @@ -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; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 177283f74..2571389ca 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.data.DataProvider; @@ -69,6 +70,17 @@ public class IrisBiomeGeneratorLink { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; +// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { +// if (max > 320 || min > 320) { +// double scaleFactor = 320.0 / Math.max(max, min); +// min *= (int) scaleFactor; +// max *= (int) scaleFactor; +// if (min < 0) { +// +// } +// } +// } + // todo This return IrisInterpolation.lerp(min, max, g); } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java index 911323e4a..acaa55904 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisCavePlacer.java @@ -52,8 +52,6 @@ public class IrisCavePlacer implements IRare { private String cave; @Desc("If set to true, this cave is allowed to break the surface") private boolean breakSurface = true; - @Desc("If set to true, this cave is allowed to get placed above the terrain level") - private boolean ignoreHeightLimit = false; @Desc("The height range this cave can spawn at. If breakSurface is false, the output of this range will be clamped by the current world height to prevent surface breaking.") private IrisStyledRange caveStartHeight = new IrisStyledRange(13, 120, new IrisGeneratorStyle(NoiseStyle.STATIC)); @@ -84,15 +82,13 @@ public class IrisCavePlacer implements IRare { } if (y == -1) { - if(!ignoreHeightLimit) { + if(!breakSurface) { int eH = engine.getHeight(x, z); if (caveStartHeight.getMax() > eH) { caveStartHeight.setMax(eH); } } - 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); + y = (int) caveStartHeight.get(rng, x, z, data); } try { From ba68ab9e06d633f853c579273719d894c90b95ec Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sun, 31 Mar 2024 17:58:47 +0200 Subject: [PATCH 33/98] f --- .../java/com/volmit/iris/core/commands/CommandStudio.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 188ddf298..7e3f7e5a6 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -229,13 +229,10 @@ 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()); - - + 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") From f587816b302e23274fd50926e9e9bb5f661fef5a Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sun, 31 Mar 2024 18:33:35 +0200 Subject: [PATCH 34/98] merges --- .../iris/core/nms/v1_19_R1/NMSBinding.java | 63 +++++++++-------- .../iris/core/nms/v1_19_R2/NMSBinding.java | 2 +- .../iris/core/nms/v1_19_R3/NMSBinding.java | 66 +++++++++--------- .../iris/core/nms/v1_20_R1/NMSBinding.java | 2 +- .../iris/core/nms/v1_20_R2/NMSBinding.java | 62 ++++++++--------- .../iris/core/nms/v1_20_R3/NMSBinding.java | 69 +++++++++---------- 6 files changed, 127 insertions(+), 137 deletions(-) diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java index 2317f0fcb..49c921288 100644 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java +++ b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java @@ -1,5 +1,34 @@ package com.volmit.iris.core.nms.v1_19_R1; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; + +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; +import org.bukkit.craftbukkit.v1_19_R1.CraftServer; +import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock; +import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; @@ -16,6 +45,7 @@ import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; + import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; @@ -32,39 +62,8 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import org.bukkit.craftbukkit.v1_19_R1.CraftChunk; -import org.bukkit.craftbukkit.v1_19_R1.CraftServer; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock; -import org.bukkit.craftbukkit.v1_19_R1.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftDolphin; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftWarden; -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; -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 org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -514,7 +513,7 @@ public class NMSBinding implements INMSBinding { } @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java index 07a28b5cd..8aa76bc52 100644 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java +++ b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java @@ -515,7 +515,7 @@ public class NMSBinding implements INMSBinding { } @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java index 7648ba946..c32354ae9 100644 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java @@ -1,5 +1,34 @@ package com.volmit.iris.core.nms.v1_19_R3; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; + +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_19_R3.CraftChunk; +import org.bukkit.craftbukkit.v1_19_R3.CraftServer; +import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; +import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; @@ -16,6 +45,7 @@ import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; + import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; @@ -34,38 +64,8 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import org.bukkit.craftbukkit.v1_19_R3.CraftChunk; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; -import org.bukkit.craftbukkit.v1_19_R3.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_19_R3.entity.CraftDolphin; -import org.bukkit.craftbukkit.v1_19_R3.inventory.CraftItemStack; -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 org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -492,7 +492,6 @@ public class NMSBinding implements INMSBinding { biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); } - public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { Field[] fields = EntityType.class.getDeclaredFields(); for (Field field : fields) { @@ -516,10 +515,9 @@ public class NMSBinding implements INMSBinding { return null; } - @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { - if (type == EntityType.CAMEL) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { + if (type == org.bukkit.entity.EntityType.CAMEL) { return null; } return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); diff --git a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java index 38db0098a..165f97808 100644 --- a/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java +++ b/nms/v1_20_R1/src/main/java/com/volmit/iris/core/nms/v1_20_R1/NMSBinding.java @@ -505,7 +505,7 @@ public class NMSBinding implements INMSBinding { } @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } diff --git a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java index 3e20e15f2..73a15d89c 100644 --- a/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java +++ b/nms/v1_20_R2/src/main/java/com/volmit/iris/core/nms/v1_20_R2/NMSBinding.java @@ -1,5 +1,34 @@ package com.volmit.iris.core.nms.v1_20_R2; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; + +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_20_R2.CraftChunk; +import org.bukkit.craftbukkit.v1_20_R2.CraftServer; +import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_20_R2.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; @@ -16,6 +45,7 @@ import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; + import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; @@ -35,38 +65,8 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import org.bukkit.craftbukkit.v1_20_R2.CraftChunk; -import org.bukkit.craftbukkit.v1_20_R2.CraftServer; -import org.bukkit.craftbukkit.v1_20_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R2.entity.CraftDolphin; -import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey; -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 org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -516,7 +516,7 @@ public class NMSBinding implements INMSBinding { } @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } diff --git a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java index 125fe23ca..01fa75d94 100644 --- a/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java +++ b/nms/v1_20_R3/src/main/java/com/volmit/iris/core/nms/v1_20_R3/NMSBinding.java @@ -1,14 +1,41 @@ package com.volmit.iris.core.nms.v1_20_R3; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; + +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_20_R3.CraftChunk; +import org.bukkit.craftbukkit.v1_20_R3.CraftServer; +import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.volmit.iris.Iris; import com.volmit.iris.core.nms.INMSBinding; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisEntity; 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.hunk.Hunk; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; @@ -18,8 +45,7 @@ import com.volmit.iris.util.nbt.io.NBTUtil; import com.volmit.iris.util.nbt.mca.NBTWorld; import com.volmit.iris.util.nbt.mca.palette.*; import com.volmit.iris.util.nbt.tag.CompoundTag; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import io.lumine.mythic.bukkit.adapters.BukkitEntity; + import it.unimi.dsi.fastutil.objects.Object2IntMap; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; @@ -31,7 +57,6 @@ import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerLevel; -import net.minecraft.tags.EntityTypeTags; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.biome.BiomeSource; import net.minecraft.world.level.block.Block; @@ -40,40 +65,8 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ChunkStatus; import net.minecraft.world.level.chunk.LevelChunk; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; - -import org.bukkit.craftbukkit.v1_20_R3.CraftChunk; -import org.bukkit.craftbukkit.v1_20_R3.CraftServer; -import org.bukkit.craftbukkit.v1_20_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData; -import org.bukkit.craftbukkit.v1_20_R3.entity.CraftDolphin; -import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack; -import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey; -import org.bukkit.entity.Creeper; -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 org.jetbrains.annotations.NotNull; import sun.misc.Unsafe; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -524,7 +517,7 @@ public class NMSBinding implements INMSBinding { @Override - public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } From cc4af9950ba1efc995ad30148f80561e27218cf7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 1 Apr 2024 17:26:10 +0200 Subject: [PATCH 35/98] fix scanning for item provider instead of block provider to processUpdate --- .../main/java/com/volmit/iris/core/service/ExternalDataSVC.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index 53f566586..cda593408 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -112,7 +112,7 @@ public class ExternalDataSVC implements IrisService { } public void processUpdate(Engine engine, Block block, Identifier blockId) { - Optional provider = activeProviders.stream().filter(p -> p.isValidProvider(blockId, true)).findFirst(); + Optional 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; From 93690b766c41bde28af3f207bb1defa163f8766a Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 1 Apr 2024 17:26:33 +0200 Subject: [PATCH 36/98] implement MMOItemsDataProvider --- core/build.gradle | 5 ++ .../iris/core/link/MMOItemsDataProvider.java | 84 +++++++++++++++++++ .../iris/core/service/ExternalDataSVC.java | 4 + 3 files changed, 93 insertions(+) create mode 100644 core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java diff --git a/core/build.gradle b/core/build.gradle index 76d773096..b15995f34 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -33,6 +33,10 @@ compileJava { options.encoding = "UTF-8" } +repositories { + maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'} +} + /** * Dependencies. * @@ -61,6 +65,7 @@ dependencies { 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' //implementation files('libs/CustomItems.jar') } diff --git a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java new file mode 100644 index 000000000..b57a8c664 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java @@ -0,0 +1,84 @@ +package com.volmit.iris.core.link; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KList; +import net.Indyuce.mmoitems.MMOItems; +import net.Indyuce.mmoitems.api.Type; +import net.Indyuce.mmoitems.api.block.CustomBlock; +import org.bukkit.block.data.BlockData; +import org.bukkit.inventory.ItemStack; + +import java.util.MissingResourceException; + +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) 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) throws MissingResourceException { + String[] parts = itemId.namespace().split("_", 2); + if (parts.length != 2) + throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); + ItemStack item = api().getItem(parts[1], itemId.key()); + if (item == null) + throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); + return item; + } + + @Override + public Identifier[] getBlockTypes() { + KList 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 names = new KList<>(); + for (Type type : api().getTypes().getAll()) { + for (String name : api().getTemplates().getTemplateNames(type)) { + try { + Identifier key = new Identifier("mmoitems_" + type, 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 ? id.namespace().split("_", 2).length == 2 : id.namespace().equals("mmoitems"); + } + + private MMOItems api() { + return MMOItems.plugin; + } +} diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index cda593408..00bc519c1 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -60,6 +60,10 @@ public class ExternalDataSVC implements IrisService { 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..."); + } for (ExternalDataProvider p : providers) { if (p.isReady()) { From fd91c223b705dc1dfe7408fa0fa230fa54d87021 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 1 Apr 2024 22:08:28 +0200 Subject: [PATCH 37/98] add unload debug tools --- .../java/com/volmit/iris/util/mantle/Mantle.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java index 52982442c..b89804537 100644 --- a/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java +++ b/core/src/main/java/com/volmit/iris/util/mantle/Mantle.java @@ -60,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; @@ -427,7 +428,7 @@ public class Mantle { 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); @@ -456,9 +457,16 @@ public class Mantle { if (IrisEngineSVC.instance != null) { try { KList copy = toUnload.copy(); + if (!disableClear) toUnload.clear(); burst = MultiBurst.burst.burst(copy.size()); burst.setMulticore(copy.size() > tectonicLimit); - for (long id : copy) { + 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.queue(() -> hyperLock.withLong(id, () -> { TectonicPlate m = loadedRegions.get(id); @@ -467,7 +475,7 @@ public class Mantle { m.write(fileForRegion(dataFolder, id)); loadedRegions.remove(id); lastUse.remove(id); - toUnload.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(); @@ -476,7 +484,6 @@ public class Mantle { } } })); - } burst.complete(); } catch (Throwable e) { From d0f16dbbc4baea25d2964617e44d8ba781dd3fe2 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 1 Apr 2024 23:18:41 +0200 Subject: [PATCH 38/98] fix using Type::toString instead of Type::getId for mmoitems --- .../java/com/volmit/iris/core/link/MMOItemsDataProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java index b57a8c664..68e353b07 100644 --- a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java @@ -63,7 +63,7 @@ public class MMOItemsDataProvider extends ExternalDataProvider { for (Type type : api().getTypes().getAll()) { for (String name : api().getTemplates().getTemplateNames(type)) { try { - Identifier key = new Identifier("mmoitems_" + type, name); + Identifier key = new Identifier("mmoitems_" + type.getId(), name); if (getItemStack(key) != null) names.add(key); } catch (MissingResourceException ignored) { From ca7dc19c81ae105f85d998e75cec175e064acca2 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 1 Apr 2024 23:20:11 +0200 Subject: [PATCH 39/98] make mmoitems item creation synchronous --- .../iris/core/link/MMOItemsDataProvider.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java index 68e353b07..edf25e3c1 100644 --- a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java @@ -2,13 +2,17 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; import com.volmit.iris.util.collection.KList; +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 { @@ -37,7 +41,16 @@ public class MMOItemsDataProvider extends ExternalDataProvider { String[] parts = itemId.namespace().split("_", 2); if (parts.length != 2) throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); - ItemStack item = api().getItem(parts[1], itemId.key()); + CompletableFuture future = new CompletableFuture<>(); + if (Bukkit.isPrimaryThread()) { + future.complete(api().getItem(parts[1], itemId.key())); + } else { + J.s(() -> future.complete(api().getItem(parts[1], itemId.key()))); + } + 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; From 3d90207172b7750cc3cb79c794cc199a0fec5472 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 2 Apr 2024 12:03:00 +0200 Subject: [PATCH 40/98] make MMOItems getItemTypes synchronous to reduce lag --- .../iris/core/link/MMOItemsDataProvider.java | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java index edf25e3c1..4445f3e9d 100644 --- a/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/MMOItemsDataProvider.java @@ -42,11 +42,9 @@ public class MMOItemsDataProvider extends ExternalDataProvider { if (parts.length != 2) throw new MissingResourceException("Failed to find ItemData!", itemId.namespace(), itemId.key()); CompletableFuture future = new CompletableFuture<>(); - if (Bukkit.isPrimaryThread()) { - future.complete(api().getItem(parts[1], itemId.key())); - } else { - J.s(() -> future.complete(api().getItem(parts[1], itemId.key()))); - } + Runnable run = () -> future.complete(api().getItem(parts[1], itemId.key())); + if (Bukkit.isPrimaryThread()) run.run(); + else J.s(run); ItemStack item = null; try { item = future.get(); @@ -73,15 +71,26 @@ public class MMOItemsDataProvider extends ExternalDataProvider { @Override public Identifier[] getItemTypes() { KList names = new KList<>(); - 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) { + 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]); } From 121a46378874085a7e3ae8d73db9a17ce3ac4e9d Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Wed, 3 Apr 2024 03:03:32 -0400 Subject: [PATCH 41/98] v+ Woot --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f03557fdf..2b06a50d5 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.2.1-1.19.2-1.20.4' +version '3.2.2-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From 33b0dec9daa00566c846f6623ab5945d87e8a022 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 4 Apr 2024 23:45:25 +0200 Subject: [PATCH 42/98] fix ClassCastException when replacing to IrisBlockData --- .../main/java/com/volmit/iris/engine/object/IrisObject.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 8b5924e41..5225c4b23 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -29,6 +29,7 @@ import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.context.IrisContext; import com.volmit.iris.util.data.B; +import com.volmit.iris.util.data.IrisBlockData; import com.volmit.iris.util.format.Form; import com.volmit.iris.util.interpolation.IrisInterpolation; import com.volmit.iris.util.json.JSONObject; @@ -811,7 +812,7 @@ public class IrisObject extends IrisRegistrant { if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); - if (newData.getMaterial() == data.getMaterial()) + if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisBlockData || data instanceof IrisBlockData)) data = data.merge(newData); else data = newData; From 16affd11cce67e964d6efc248f34cf7974a0aa67 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 4 Apr 2024 23:46:14 +0200 Subject: [PATCH 43/98] fix HMCLeaves leave decay --- .../volmit/iris/core/link/HMCLeavesDataProvider.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java index 3e0a384c9..44c695a28 100644 --- a/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java +++ b/core/src/main/java/com/volmit/iris/core/link/HMCLeavesDataProvider.java @@ -1,6 +1,7 @@ package com.volmit.iris.core.link; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.data.IrisBlockData; @@ -57,7 +58,7 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { if (material == null) throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); BlockData blockData = Bukkit.createBlockData(material); - if (blockData instanceof Leaves leaves) + if (IrisSettings.get().getGenerator().preventLeafDecay && blockData instanceof Leaves leaves) leaves.setPersistent(true); return new IrisBlockData(blockData, blockId); } @@ -71,9 +72,14 @@ public class HMCLeavesDataProvider extends ExternalDataProvider { @Override public void processUpdate(Engine engine, Block block, Identifier blockId) { - Boolean result = setCustomBlock.invoke(apiInstance, new Object[]{block.getLocation(), blockId.key(), true}); + 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 From 63b8a935ae65c254b75921d4308fcce1a9c05fc5 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 5 Apr 2024 18:43:30 +0200 Subject: [PATCH 44/98] sync laptop --- .../com/volmit/iris/core/IrisSettings.java | 2 +- .../volmit/iris/engine/object/IrisBiome.java | 2 +- .../engine/object/IrisBiomeGeneratorLink.java | 25 +++++++++++-------- .../iris/engine/object/IrisDimension.java | 3 +++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 4abe1ba79..a4fc25838 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,7 +177,7 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; - // public boolean forceConvertTo320Height = false; + public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index c08d3fa11..ecb8d8230 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -450,7 +450,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { return real; } - public int getMaxHeight() { + public int getMaxHeight(int test) { return maxHeight.aquire(() -> { int maxHeight = 0; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 2571389ca..b9a04cde7 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -22,6 +22,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.AtomicCache; 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; @@ -66,20 +67,24 @@ public class IrisBiomeGeneratorLink { }); } + public int getMax() { + return 320; + } + public double getHeight(DataProvider xg, double x, double z, long seed) { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; -// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { -// if (max > 320 || min > 320) { -// double scaleFactor = 320.0 / Math.max(max, min); -// min *= (int) scaleFactor; -// max *= (int) scaleFactor; -// if (min < 0) { -// -// } -// } -// } + if (xg.getData().getEngine().getDimension().getForceConvertTo320Height()) { + if (max > 320 || min > 320) { + double scaleFactor = 320.0 / Math.max(max, min); + min *= (int) scaleFactor; + max *= (int) scaleFactor; + if (min < 0) { + min = 10; + } + } + } // todo This return IrisInterpolation.lerp(min, max, g); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 488171296..97899593a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -210,6 +211,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) From 83a0a7dd544ee1eb8618bb5c4576ebfe4c92dda4 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 5 Apr 2024 18:43:30 +0200 Subject: [PATCH 45/98] sync laptop --- .../com/volmit/iris/core/IrisSettings.java | 2 +- .../volmit/iris/engine/object/IrisBiome.java | 2 +- .../engine/object/IrisBiomeGeneratorLink.java | 25 +++++++++++-------- .../iris/engine/object/IrisDimension.java | 3 +++ 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index 4abe1ba79..a4fc25838 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,7 +177,7 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; - // public boolean forceConvertTo320Height = false; + public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index c08d3fa11..ecb8d8230 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -450,7 +450,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { return real; } - public int getMaxHeight() { + public int getMaxHeight(int test) { return maxHeight.aquire(() -> { int maxHeight = 0; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 2571389ca..b9a04cde7 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -22,6 +22,7 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.AtomicCache; 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; @@ -66,20 +67,24 @@ public class IrisBiomeGeneratorLink { }); } + public int getMax() { + return 320; + } + public double getHeight(DataProvider xg, double x, double z, long seed) { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; -// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { -// if (max > 320 || min > 320) { -// double scaleFactor = 320.0 / Math.max(max, min); -// min *= (int) scaleFactor; -// max *= (int) scaleFactor; -// if (min < 0) { -// -// } -// } -// } + if (xg.getData().getEngine().getDimension().getForceConvertTo320Height()) { + if (max > 320 || min > 320) { + double scaleFactor = 320.0 / Math.max(max, min); + min *= (int) scaleFactor; + max *= (int) scaleFactor; + if (min < 0) { + min = 10; + } + } + } // todo This return IrisInterpolation.lerp(min, max, g); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 488171296..97899593a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -210,6 +211,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) From 206a4e905708b66275e5caa5c5cd35f6f3903485 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Sat, 6 Apr 2024 17:07:14 +0200 Subject: [PATCH 46/98] Revert "sync laptop" This reverts commit 63b8a935ae65c254b75921d4308fcce1a9c05fc5. --- .../com/volmit/iris/core/IrisSettings.java | 2 +- .../volmit/iris/engine/object/IrisBiome.java | 2 +- .../engine/object/IrisBiomeGeneratorLink.java | 25 ++++++++----------- .../iris/engine/object/IrisDimension.java | 3 --- 4 files changed, 12 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index a4fc25838..4abe1ba79 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,7 +177,7 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; - public boolean forceConvertTo320Height = false; + // public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index ecb8d8230..c08d3fa11 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -450,7 +450,7 @@ public class IrisBiome extends IrisRegistrant implements IRare { return real; } - public int getMaxHeight(int test) { + public int getMaxHeight() { return maxHeight.aquire(() -> { int maxHeight = 0; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index b9a04cde7..2571389ca 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -22,7 +22,6 @@ import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.AtomicCache; 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; @@ -67,24 +66,20 @@ public class IrisBiomeGeneratorLink { }); } - public int getMax() { - return 320; - } - public double getHeight(DataProvider xg, double x, double z, long seed) { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; - if (xg.getData().getEngine().getDimension().getForceConvertTo320Height()) { - if (max > 320 || min > 320) { - double scaleFactor = 320.0 / Math.max(max, min); - min *= (int) scaleFactor; - max *= (int) scaleFactor; - if (min < 0) { - min = 10; - } - } - } +// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { +// if (max > 320 || min > 320) { +// double scaleFactor = 320.0 / Math.max(max, min); +// min *= (int) scaleFactor; +// max *= (int) scaleFactor; +// if (min < 0) { +// +// } +// } +// } // todo This return IrisInterpolation.lerp(min, max, g); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 97899593a..488171296 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,7 +19,6 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; @@ -211,8 +210,6 @@ 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) From c2b9b0ba0e80ec7f9a3b409fe836f252006df259 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 9 Apr 2024 16:52:14 +0200 Subject: [PATCH 47/98] add smartVanillaHeight --- core/src/main/java/com/volmit/iris/Iris.java | 2 +- .../com/volmit/iris/core/commands/CommandIris.java | 2 +- .../com/volmit/iris/core/tools/IrisCreator.java | 2 ++ .../volmit/iris/core/tools/IrisWorldCreator.java | 8 +++++++- .../volmit/iris/engine/object/IrisDimension.java | 2 ++ .../iris/engine/platform/BukkitChunkGenerator.java | 14 +++++++++++++- 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index e32c8239d..9fec3b7e8 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -739,7 +739,7 @@ public class Iris extends VolmitPlugin implements Listener { 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() { diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index bf7b05b48..16a110bf1 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -622,6 +622,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); } } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index 3e90aced1..e67908d0f 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -86,6 +86,7 @@ public class IrisCreator { * Benchmark mode */ private boolean benchmark = false; + private boolean smartVanillaHeight = false; public static boolean removeFromBukkitYml(String name) throws IOException { YamlConfiguration yml = YamlConfiguration.loadConfiguration(BUKKIT_YML); @@ -149,6 +150,7 @@ public class IrisCreator { .name(name) .seed(seed) .studio(studio) + .smartVanillaHeight(smartVanillaHeight) .create(); ServerConfigurator.installDataPacks(false); diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java index cd6c17a91..b815d3809 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisWorldCreator.java @@ -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) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 488171296..e23d0d4dd 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -231,6 +231,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 = ""; diff --git a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java index 50206b6d1..ce0bebd74 100644 --- a/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java +++ b/core/src/main/java/com/volmit/iris/engine/platform/BukkitChunkGenerator.java @@ -58,6 +58,8 @@ 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; @@ -82,6 +84,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun 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; @@ -91,7 +94,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun private boolean initialized = false; - public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey) { + public BukkitChunkGenerator(IrisWorld world, boolean studio, File dataLocation, String dimensionKey, boolean smartVanillaHeight) { setup = new AtomicBoolean(false); studioGenerator = null; dummyBiomeProvider = new DummyBiomeProvider(); @@ -103,6 +106,7 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun 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); } @@ -181,6 +185,14 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun 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); From b898f73a054ea1d4c171b6ff30b9ff90fcaa906c Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 9 Apr 2024 17:04:32 +0200 Subject: [PATCH 48/98] Fixed another potential mem leak Added the base of smart320height --- build.gradle | 2 +- .../iris/core/commands/CommandIris.java | 51 +++---- .../iris/core/commands/CommandStudio.java | 2 +- .../core/gui/components/IrisRenderer.java | 4 +- .../iris/core/service/IrisEngineSVC.java | 137 ++++++++++-------- .../com/volmit/iris/engine/IrisComplex.java | 4 +- .../volmit/iris/engine/object/IrisBiome.java | 17 ++- .../engine/object/IrisBiomeGeneratorLink.java | 50 +++++-- 8 files changed, 150 insertions(+), 117 deletions(-) diff --git a/build.gradle b/build.gradle index 2b06a50d5..51b518b72 100644 --- a/build.gradle +++ b/build.gradle @@ -37,7 +37,7 @@ 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.4 - Iris Development/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') diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index bf7b05b48..a5c66f743 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -30,6 +30,7 @@ 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; @@ -216,41 +217,41 @@ public class CommandIris implements DecreeExecutor { Iris.service(StudioSVC.class).open(sender(), 1337, "overworld"); } - @Decree(description = "Check if iris has access to that specific world") - public void hasAccess( - @Param(description = "The world to access", aliases = {"world"}) - World world - ) { - Engine engine = IrisToolbelt.access(world).getEngine(); - if (engine != null) { - sender().sendMessage("Access granted successfully."); - } else { - sender().sendMessage(C.RED + "Failed to grant access."); - } - } + @Decree(description = "Check access of all worlds.", aliases = {"accesslist"}) + public void worlds() { + KList IrisWorlds = new KList<>(); + KList BukkitWorlds = new KList<>(); - @Decree(description = "All Iris Worlds on the server.", aliases = {"worlds"}) - public void irisworlds() { - List IrisWorlds = new ArrayList<>(); - for (World world : Bukkit.getWorlds()) { + for (World w : Bukkit.getServer().getWorlds()) { try { - if (IrisToolbelt.access(world).getEngine() != null) { - IrisWorlds.add(world); + Engine engine = IrisToolbelt.access(w).getEngine(); + if (engine != null) { + IrisWorlds.add(w); } } catch (Exception e) { - // no + BukkitWorlds.add(w); } } + if (sender().isPlayer()) { - sender.sendMessage(C.IRIS + "Iris Worlds:"); - for (World world : IrisWorlds) { - sender.sendMessage(C.GREEN + "- " + world.getName()); + 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.IRIS + "Iris Worlds:"); - for (World world : IrisWorlds) { - sender.sendMessage(C.GREEN + "- " + world.getName()); + 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()); + } + } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 7e3f7e5a6..bea1dcd2b 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -85,7 +85,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(); diff --git a/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java b/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java index 2820b8999..a96432427 100644 --- a/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java +++ b/core/src/main/java/com/volmit/iris/core/gui/components/IrisRenderer.java @@ -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 { diff --git a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java index b2595e3ad..2220ccc26 100644 --- a/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/IrisEngineSVC.java @@ -78,6 +78,9 @@ public class IrisEngineSVC implements IrisService { t = t - 200; } this.setup(); + this.TrimLogic(); + this.UnloadLogic(); + trimAlive.begin(); unloadAlive.begin(); trimActiveAlive.begin(); @@ -85,8 +88,8 @@ public class IrisEngineSVC implements IrisService { updateTicker.start(); cacheTicker.start(); - trimTicker.start(); - unloadTicker.start(); + //trimTicker.start(); + //unloadTicker.start(); instance = this; } @@ -104,10 +107,6 @@ public class IrisEngineSVC implements IrisService { return tectonicLimit.get(); } - public void EngineReport() { - Iris.info(C.RED + "CRITICAL ENGINE FAILURE! The Tectonic Trim subsystem has not responded for: " + Form.duration(trimAlive.getMillis()) + "."); - } - @EventHandler public void onWorldUnload(WorldUnloadEvent event) { updateWorlds(); @@ -179,9 +178,9 @@ public class IrisEngineSVC implements IrisService { } if (!isServerShuttingDown && isServerLoaded) { if (!trimTicker.isAlive()) { - Iris.info(C.IRIS + "TrimTicker found dead! Booting it up!"); + Iris.info(C.RED + "TrimTicker found dead! Booting it up!"); try { - trimTicker.start(); + TrimLogic(); } catch (Exception e) { Iris.error("What happened?"); e.printStackTrace(); @@ -189,9 +188,9 @@ public class IrisEngineSVC implements IrisService { } if (!unloadTicker.isAlive()) { - Iris.info(C.IRIS + "UnloadTicker found dead! Booting it up!"); + Iris.info(C.RED + "UnloadTicker found dead! Booting it up!"); try { - unloadTicker.start(); + UnloadLogic(); } catch (Exception e) { Iris.error("What happened?"); e.printStackTrace(); @@ -205,63 +204,72 @@ public class IrisEngineSVC implements IrisService { return 1000; } }; + } + public void TrimLogic() { + if (trimTicker == null || !trimTicker.isAlive()) { + trimTicker = new Looper() { + private final Supplier supplier = createSupplier(); - trimTicker = new Looper() { - private final Supplier 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. Please contact support!"); - 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 = new Looper() { - private final Supplier 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)); + @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; } - } 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; - } - }; + 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 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 createSupplier() { @@ -281,7 +289,8 @@ public class IrisEngineSVC implements IrisService { if (generator != null) { Engine engine = generator.getEngine(); - if (engine != null && !engine.isStudio()) { + boolean closed = engine.getMantle().getData().isClosed(); + if (engine != null && !engine.isStudio() && !closed) { lastUseLock.lock(); lastUse.put(world, System.currentTimeMillis()); lastUseLock.unlock(); diff --git a/core/src/main/java/com/volmit/iris/engine/IrisComplex.java b/core/src/main/java/com/volmit/iris/engine/IrisComplex.java index db92954a8..3b271951f 100644 --- a/core/src/main/java/com/volmit/iris/engine/IrisComplex.java +++ b/core/src/main/java/com/volmit/iris/engine/IrisComplex.java @@ -292,7 +292,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 +311,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; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java index c08d3fa11..d75dca7ad 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiome.java @@ -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 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 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; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 2571389ca..5a7ccdb7a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -18,14 +18,14 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; 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") @@ -45,11 +45,13 @@ public class IrisBiomeGeneratorLink { @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"}) @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; @@ -66,21 +68,41 @@ public class IrisBiomeGeneratorLink { }); } + private int calculateHeight(Engine engine, int option) { + int dmx = engine.getDimension().getMaxHeight(); + int dmn = engine.getDimension().getMinHeight(); + int mx = max; // 500 + int mn = min; // 160 + if (true) { // todo after merge + if (mx > 0) mx = Math.min((int)(((float)mx / (float)dmx) * 300.0f), 300); + if (mx < 0) mx = Math.min((int)(((float)mx / (float)dmn) * 300.0f), 56); + + if (mn > 0) mn = Math.min((int)(((float)mn / (float)dmx) * 300.0f), 300); + if (mn < 0) mn = Math.min((int)(((float)mn / (float)dmn) * 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); + } + public double getHeight(DataProvider xg, double x, double z, long seed) { double g = getCachedGenerator(xg).getHeight(x, z, seed); g = g < 0 ? 0 : g; g = g > 1 ? 1 : g; -// if (IrisSettings.get().getGenerator().forceConvertTo320Height) { -// if (max > 320 || min > 320) { -// double scaleFactor = 320.0 / Math.max(max, min); -// min *= (int) scaleFactor; -// max *= (int) scaleFactor; -// if (min < 0) { -// -// } -// } -// } - // todo This return IrisInterpolation.lerp(min, max, g); } From 60d349dd8b9ade4d367eb9d6b13bcfb93770356c Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 9 Apr 2024 17:05:43 +0200 Subject: [PATCH 49/98] test --- .../com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 5a7ccdb7a..f28f24eb2 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -73,7 +73,7 @@ public class IrisBiomeGeneratorLink { int dmn = engine.getDimension().getMinHeight(); int mx = max; // 500 int mn = min; // 160 - if (true) { // todo after merge + if (engine.getDimension().isSmartVanillaHeight()) { if (mx > 0) mx = Math.min((int)(((float)mx / (float)dmx) * 300.0f), 300); if (mx < 0) mx = Math.min((int)(((float)mx / (float)dmn) * 300.0f), 56); From 1eec3a09c16736aaa473e69c5b52118f1d2488cd Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 9 Apr 2024 18:05:27 +0200 Subject: [PATCH 50/98] now it should work --- .../main/java/com/volmit/iris/core/commands/CommandIris.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index bfc40822a..d07c0ef42 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -90,7 +90,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")) { @@ -134,6 +136,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."); From fc15175ff93ea798f66876e509041dd51818bce6 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 9 Apr 2024 20:06:32 +0200 Subject: [PATCH 51/98] Improved? --- .../engine/object/IrisBiomeGeneratorLink.java | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index f28f24eb2..5a7a71920 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -19,7 +19,6 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.annotations.*; @@ -40,14 +39,14 @@ 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 @@ -56,8 +55,7 @@ public class IrisBiomeGeneratorLink { 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) { @@ -68,18 +66,42 @@ 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 mx = max; // 500 - int mn = min; // 160 + int[] heights = getBiomeGeneratorsRaw(engine); + int gmx = heights[1]; + int gmn = heights[0]; + + int mx = max; + int mn = min; if (engine.getDimension().isSmartVanillaHeight()) { - if (mx > 0) mx = Math.min((int)(((float)mx / (float)dmx) * 300.0f), 300); - if (mx < 0) mx = Math.min((int)(((float)mx / (float)dmn) * 300.0f), 56); - - if (mn > 0) mn = Math.min((int)(((float)mn / (float)dmx) * 300.0f), 300); - if (mn < 0) mn = Math.min((int)(((float)mn / (float)dmn) * 300.0f), 56); + 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) { @@ -95,10 +117,19 @@ public class IrisBiomeGeneratorLink { 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; From 7fb2a51a3327831e1dda9803db29494e0123fa7f Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:08:13 +0200 Subject: [PATCH 52/98] sync --- .../iris/core/pregenerator/ChunkUpdater.java | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java new file mode 100644 index 000000000..ec191cbb9 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -0,0 +1,119 @@ +package com.volmit.iris.core.pregenerator; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +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.nbt.mca.Chunk; +import com.volmit.iris.util.nbt.mca.MCAFile; +import com.volmit.iris.util.nbt.mca.MCAUtil; +import org.bukkit.World; + +import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +public class ChunkUpdater { + private AtomicBoolean cancelled = new AtomicBoolean(false); + private KList cache; + private final RollingSequence chunksPerSecond; + private final RollingSequence mcaregionsPerSecond; + 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 final KMap chunk; + private final File[] McaFiles; + private final World world; + + public ChunkUpdater(World world) { + this.chunksPerSecond = new RollingSequence(10); + this.mcaregionsPerSecond = new RollingSequence(10); + this.world = world; + this.chunk = new KMap<>(); + this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); + this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1)); + this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0)); + this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16 ) * (worldwidthsize.get() / 16)); + this.position = new AtomicInteger(0); + this.cancelled = new AtomicBoolean(false); + this.cache = new KList<>(); + this.totalChunks = new AtomicInteger(0); + this.totalMcaregions = new AtomicInteger(0); + Initialize(); + + } + + public void Initialize() { + Iris.info("Initializing.."); + try { + for (File file : McaFiles) { + MCAFile MCARegion = MCAUtil.read(file); + //MCARegion.hasChunk(x,z); + + + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void cache() { + int position = this.position.get(); + for(; position < this.totalMaxChunks.get(); position++) { + cache.add(getChunk(position)); + } + } + + 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 Position2 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(); + } + + return new Position2(xx.get(), zz.get()); + } +} From 9ac4024e4e0fb24732eda81078ab5901d245157f Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Mon, 15 Apr 2024 11:43:09 -0400 Subject: [PATCH 53/98] v+ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2b06a50d5..087324e56 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.2.2-1.19.2-1.20.4' +version '3.2.3-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From 61c0ddb15bb90e597a2a18e2bb66f51b73a0e088 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 16 Apr 2024 13:29:06 +0200 Subject: [PATCH 54/98] fix random jigsaw rotation and offset --- .../iris/engine/jigsaw/PlannedStructure.java | 15 +++++---------- .../iris/engine/object/IrisJigsawPiece.java | 15 ++------------- .../com/volmit/iris/engine/object/IrisObject.java | 12 +++++++++--- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index dd7eade40..4510af468 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -23,7 +23,6 @@ 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.object.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.mantle.Mantle; @@ -32,8 +31,6 @@ import com.volmit.iris.util.matter.slices.container.JigsawPieceContainer; import lombok.Data; import org.bukkit.Axis; import org.bukkit.World; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; @Data public class PlannedStructure { @@ -76,7 +73,7 @@ public class PlannedStructure { public void 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(); for (PlannedPiece i : pieces) { @@ -90,11 +87,11 @@ public class PlannedStructure { if (i.getPiece().getPlacementOptions() != null) { options = i.getPiece().getPlacementOptions(); options.getRotation().setEnabled(false); + options.setRotateTowardsSlope(false); } else { options.setMode(i.getPiece().getPlaceMode()); } - IrisObject vo = i.getOgObject(); IrisObject v = i.getObject(); int sx = (v.getW() / 2); int sz = (v.getD() / 2); @@ -122,7 +119,7 @@ public class PlannedStructure { int id = rng.i(0, Integer.MAX_VALUE); JigsawPieceContainer container = JigsawPieceContainer.toContainer(i.getPiece()); - vo.place(xx, height, zz, placer, options, rng, (b, data) -> { + 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); }, null, getData()); @@ -167,9 +164,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 forder1 = new KList().qadd(0).qadd(1).qadd(2).qadd(3).shuffle(rng); @@ -216,7 +211,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) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java index 72feb927c..93c9f07bc 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java @@ -101,19 +101,8 @@ 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(); + return gson.fromJson(gson.toJson(this), IrisJigsawPiece.class); } public boolean isTerminal() { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 5225c4b23..c4306c115 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -533,10 +533,16 @@ public class IrisObject extends IrisRegistrant { } else if (min == hWest) { slopeRotationY = 270; } + + double newRotation = config.getRotation().getYAxis().getMin() + slopeRotationY; + if (newRotation == 0) { + config.getRotation().setYAxis(new IrisAxisRotationClamp(false, false, 0, 0, 90)); + config.getRotation().setEnabled(config.getRotation().canRotateX() || config.getRotation().canRotateZ()); + } else { + config.getRotation().setYAxis(new IrisAxisRotationClamp(true, false, newRotation, newRotation, 90)); + config.getRotation().setEnabled(true); + } } - double newRotation = config.getRotation().getYAxis().getMin() + slopeRotationY; - config.getRotation().setYAxis(new IrisAxisRotationClamp(true, false, newRotation, newRotation, 90)); - config.getRotation().setEnabled(true); } if (config.isSmartBore()) { From 72949e09509a240c5e55c8802447e03f56199a79 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Tue, 16 Apr 2024 16:32:52 +0200 Subject: [PATCH 55/98] Update IrisSettings.java --- core/src/main/java/com/volmit/iris/core/IrisSettings.java | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/core/IrisSettings.java b/core/src/main/java/com/volmit/iris/core/IrisSettings.java index a4fc25838..335207de5 100644 --- a/core/src/main/java/com/volmit/iris/core/IrisSettings.java +++ b/core/src/main/java/com/volmit/iris/core/IrisSettings.java @@ -177,7 +177,6 @@ public class IrisSettings { public static class IrisSettingsGenerator { public String defaultWorldType = "overworld"; public int maxBiomeChildDepth = 4; - public boolean forceConvertTo320Height = false; public boolean preventLeafDecay = true; } From bfbea83a4aa0c91995e8ac50911eac9402e53f8b Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 16 Apr 2024 17:18:02 +0200 Subject: [PATCH 56/98] - Fixed NMS biome height. - Improved /iris load - Improved Vanilla height converter - Removed WorldCreation unstable message --- .../iris/core/commands/CommandDeveloper.java | 29 ++++++++- .../iris/core/commands/CommandIris.java | 11 ++-- .../iris/core/pregenerator/ChunkUpdater.java | 62 ++++++++++++------- .../volmit/iris/core/tools/IrisCreator.java | 7 --- .../engine/object/IrisBiomeGeneratorLink.java | 4 +- .../com/volmit/iris/util/nbt/mca/Chunk.java | 5 +- 6 files changed, 79 insertions(+), 39 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 759596ea5..4bb6d9e52 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -22,6 +22,7 @@ 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.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; @@ -40,7 +41,10 @@ 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; @@ -61,6 +65,7 @@ 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; @@ -150,9 +155,29 @@ public class CommandDeveloper implements DecreeExecutor { } + @Decree(description = "Test") + public void updater( + @Param(description = "Updater for chunks") + World world + ) { + Iris.info("test"); + ChunkUpdater updater = new ChunkUpdater(world); + updater.start(); + + + } + @Decree(description = "test") - public void test() throws NoSuchFieldException, IllegalAccessException { - IrisEngineSVC.instance.engineStatus(); + 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(); + } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index d07c0ef42..6ec02ef7f 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -78,7 +78,6 @@ public class CommandIris implements DecreeExecutor { private CommandFind find; private CommandDeveloper developer; public static boolean worldCreation = false; - String WorldToLoad; String WorldEngine; String worldNameToCheck = "YourWorldName"; VolmitSender sender = Iris.getSender(); @@ -477,7 +476,7 @@ 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 + File.separator +"iris"+File.separator +"pack"+File.separator +"dimensions"+File.separator; File directory = new File(Bukkit.getWorldContainer(), pathtodim); @@ -515,7 +514,7 @@ public class CommandIris implements DecreeExecutor { e.printStackTrace(); } } - checkForBukkitWorlds(); + checkForBukkitWorlds(world); sender().sendMessage(C.GREEN + world + " loaded successfully."); } @Decree(description = "Evacuate an iris world", origin = DecreeOrigin.PLAYER, sync = true) @@ -536,7 +535,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")); @@ -545,9 +544,9 @@ public class CommandIris implements DecreeExecutor { return; } - List worldsToLoad = Collections.singletonList(WorldToLoad); + List worldsToLoad = Collections.singletonList(world); - for (String s : section.getKeys(false)) { + for (String s : section.getKeys(false)) { if (!worldsToLoad.contains(s)) { continue; } diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index ec191cbb9..15feee7fb 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -3,22 +3,42 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; 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.Position2; import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.Spiraler; import com.volmit.iris.util.nbt.mca.Chunk; import com.volmit.iris.util.nbt.mca.MCAFile; import com.volmit.iris.util.nbt.mca.MCAUtil; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import it.unimi.dsi.fastutil.ints.IntArrays; import org.bukkit.World; +import org.ehcache.Cache; +import org.ehcache.CacheManager; +import org.ehcache.config.builders.CacheConfigurationBuilder; +import org.ehcache.config.builders.CacheManagerBuilder; +import org.ehcache.config.builders.ResourcePoolsBuilder; +import org.ehcache.config.units.EntryUnit; +import org.ehcache.config.units.MemoryUnit; +import org.ehcache.spi.serialization.Serializer; +import org.ehcache.spi.serialization.SerializerException; + import java.io.File; -import java.util.concurrent.ExecutorService; + +import java.nio.ByteBuffer; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.locks.ReentrantLock; + public class ChunkUpdater { - private AtomicBoolean cancelled = new AtomicBoolean(false); - private KList cache; + private AtomicBoolean cancelled; + private KList chunkMap; private final RollingSequence chunksPerSecond; private final RollingSequence mcaregionsPerSecond; private final AtomicInteger worldheightsize; @@ -27,49 +47,46 @@ public class ChunkUpdater { private final AtomicInteger totalMaxChunks; private final AtomicInteger totalMcaregions; private final AtomicInteger position; - private final KMap chunk; private final File[] McaFiles; private final World world; public ChunkUpdater(World world) { + File cacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache"); + File chunkCacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache" + File.separator + "spiral"); this.chunksPerSecond = new RollingSequence(10); this.mcaregionsPerSecond = new RollingSequence(10); this.world = world; - this.chunk = new KMap<>(); + this.chunkMap = new KList<>(); this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1)); this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0)); this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16 ) * (worldwidthsize.get() / 16)); this.position = new AtomicInteger(0); this.cancelled = new AtomicBoolean(false); - this.cache = new KList<>(); this.totalChunks = new AtomicInteger(0); this.totalMcaregions = new AtomicInteger(0); - Initialize(); + } + public void start() { + Initialize(); } public void Initialize() { Iris.info("Initializing.."); try { - for (File file : McaFiles) { - MCAFile MCARegion = MCAUtil.read(file); - //MCARegion.hasChunk(x,z); - - + for (File mca : McaFiles) { + MCAFile MCARegion = MCAUtil.read(mca); + for (int pos = 0; pos != totalMaxChunks.get(); pos++) { + int[] coords = getChunk(pos); + if(MCARegion.hasChunk(coords[0], coords[1])) chunkMap.add(coords); + } } + Iris.info("Finished Initializing.."); } catch (Exception e) { e.printStackTrace(); } } - public void cache() { - int position = this.position.get(); - for(; position < this.totalMaxChunks.get(); position++) { - cache.add(getChunk(position)); - } - } - public int calculateWorldDimensions(File regionDir, Integer o) { File[] files = regionDir.listFiles((dir, name) -> name.endsWith(".mca")); @@ -101,7 +118,7 @@ public class ChunkUpdater { return 0; } - public Position2 getChunk(int position) { + public int[] getChunk(int position) { int p = -1; AtomicInteger xx = new AtomicInteger(); AtomicInteger zz = new AtomicInteger(); @@ -113,7 +130,10 @@ public class ChunkUpdater { while (s.hasNext() && p++ < position) { s.next(); } + int[] coords = new int[2]; + coords[0] = xx.get(); + coords[1] = zz.get(); - return new Position2(xx.get(), zz.get()); + return coords; } } diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java index e67908d0f..6096582d2 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisCreator.java @@ -113,13 +113,6 @@ public class IrisCreator { */ 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."); } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java index 5a7a71920..00c2e4fac 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeGeneratorLink.java @@ -90,8 +90,8 @@ public class IrisBiomeGeneratorLink { int gmx = heights[1]; int gmn = heights[0]; - int mx = max; - int mn = min; + int mx = getMaxRaw(); + int mn = getMinRaw(); if (engine.getDimension().isSmartVanillaHeight()) { if (mx > 0) mx = Math.min((int) (((float) mx / (float) gmx) * 300.0f), 300); diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java index 6437bbe0e..70f78306b 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java @@ -27,10 +27,12 @@ import com.volmit.iris.util.nbt.io.NamedTag; import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer; import com.volmit.iris.util.nbt.tag.CompoundTag; import com.volmit.iris.util.nbt.tag.ListTag; +import org.bukkit.World; import java.io.*; import static com.volmit.iris.util.nbt.mca.LoadFlags.*; +import static org.bukkit.Bukkit.getServer; public class Chunk { public static final int DEFAULT_DATA_VERSION = 2730; @@ -95,11 +97,12 @@ public class Chunk { if ((level = data.getCompoundTag("Level")) == null) { throw new IllegalArgumentException("data does not contain \"Level\" tag"); } + World mainWorld = getServer().getWorlds().get(0); dataVersion = data.getInt("DataVersion"); inhabitedTime = level.getLong("InhabitedTime"); lastUpdate = level.getLong("LastUpdate"); if ((loadFlags & BIOMES) != 0) { - biomes = INMS.get().newBiomeContainer(0, 256, level.getIntArray("Biomes")); + biomes = INMS.get().newBiomeContainer(mainWorld.getMinHeight(), mainWorld.getMaxHeight(), level.getIntArray("Biomes")); } if ((loadFlags & HEIGHTMAPS) != 0) { heightMaps = level.getCompoundTag("Heightmaps"); From 72ed312654ae39726990d381b02c7c6b4f858816 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 16 Apr 2024 18:09:03 +0200 Subject: [PATCH 57/98] wops --- .../iris/core/pregenerator/ChunkUpdater.java | 22 ------------------- .../com/volmit/iris/util/nbt/mca/Chunk.java | 3 ++- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index 15feee7fb..1e40ab566 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -2,40 +2,18 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; 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.Position2; import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.math.Spiraler; -import com.volmit.iris.util.nbt.mca.Chunk; import com.volmit.iris.util.nbt.mca.MCAFile; import com.volmit.iris.util.nbt.mca.MCAUtil; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.scheduling.J; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import it.unimi.dsi.fastutil.ints.IntArrays; import org.bukkit.World; -import org.ehcache.Cache; -import org.ehcache.CacheManager; -import org.ehcache.config.builders.CacheConfigurationBuilder; -import org.ehcache.config.builders.CacheManagerBuilder; -import org.ehcache.config.builders.ResourcePoolsBuilder; -import org.ehcache.config.units.EntryUnit; -import org.ehcache.config.units.MemoryUnit; -import org.ehcache.spi.serialization.Serializer; -import org.ehcache.spi.serialization.SerializerException; import java.io.File; -import java.nio.ByteBuffer; -import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; - public class ChunkUpdater { private AtomicBoolean cancelled; private KList chunkMap; diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java index 70f78306b..fdd0b969b 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java @@ -73,10 +73,11 @@ public class Chunk { } public static Chunk newChunk() { + World mainWorld = getServer().getWorlds().get(0); Chunk c = new Chunk(0); c.dataVersion = DEFAULT_DATA_VERSION; c.data = new CompoundTag(); - c.biomes = INMS.get().newBiomeContainer(0, 256); + c.biomes = INMS.get().newBiomeContainer(mainWorld.getMinHeight(), mainWorld.getMaxHeight()); c.data.put("Level", defaultLevel()); c.status = "full"; return c; From 856c926cde27cbe04a11a2722b0f0a57565610fe Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 17 Apr 2024 21:15:15 +0200 Subject: [PATCH 58/98] add min distance to jigsaw structures --- .../iris/engine/jigsaw/PlannedStructure.java | 23 +++++-- .../components/MantleJigsawComponent.java | 58 ++++++++++++++--- .../engine/object/IrisJigsawDistance.java | 31 ++++++++++ .../object/IrisJigsawStructurePlacement.java | 19 ++++++ .../matter/slices/JigsawStructuresMatter.java | 35 +++++++++++ .../container/JigsawStructuresContainer.java | 62 +++++++++++++++++++ 6 files changed, 214 insertions(+), 14 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java create mode 100644 core/src/main/java/com/volmit/iris/util/matter/slices/JigsawStructuresMatter.java create mode 100644 core/src/main/java/com/volmit/iris/util/matter/slices/container/JigsawStructuresContainer.java diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 4510af468..ab402cf4c 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -26,8 +26,10 @@ import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.*; import com.volmit.iris.util.collection.KList; 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.container.JigsawPieceContainer; +import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer; import lombok.Data; import org.bukkit.Axis; import org.bukkit.World; @@ -71,17 +73,28 @@ public class PlannedStructure { } } - public void place(IObjectPlacer placer, Mantle e, Engine eng) { + public boolean place(IObjectPlacer placer, Mantle e, Engine eng) { IrisObjectPlacement options = new IrisObjectPlacement(); 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, IObjectPlacer 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) { @@ -119,10 +132,10 @@ public class PlannedStructure { int id = rng.i(0, Integer.MAX_VALUE); JigsawPieceContainer container = JigsawPieceContainer.toContainer(i.getPiece()); - v.place(xx, height, zz, placer, options, rng, (b, data) -> { + 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); - }, null, getData()); + }, null, getData()) != -1; } public void place(World world) { diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index d9255ef12..14ebeb45d 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -24,12 +24,15 @@ 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 java.util.List; @@ -68,21 +71,58 @@ public class MantleJigsawComponent extends IrisMantleComponent { } } - boolean placed = placeStructures(writer, rng, x, z, biome.getJigsawStructures()); + KSet cachedRegions = new KSet<>(); + KMap> cache = new KMap<>(); + KMap distanceCache = new KMap<>(); + boolean placed = placeStructures(writer, rng, x, z, biome.getJigsawStructures(), cachedRegions, cache, distanceCache); if (!placed) - placed = placeStructures(writer, rng, x, z, region.getJigsawStructures()); + placed = placeStructures(writer, rng, x, z, region.getJigsawStructures(), cachedRegions, cache, distanceCache); if (!placed) - placeStructures(writer, rng, x, z, getDimension().getJigsawStructures()); + placeStructures(writer, rng, x, z, getDimension().getJigsawStructures(), cachedRegions, cache, distanceCache); } @ChunkCoordinates - private boolean placeStructures(MantleWriter writer, RNG rng, int x, int z, KList structures) { + private boolean placeStructures(MantleWriter writer, RNG rng, int x, int z, KList structures, + KSet cachedRegions, KMap> cache, KMap distanceCache) { for (IrisJigsawStructurePlacement i : structures) { if (rng.nextInt(i.getRarity()) == 0) { + if (checkDistances(i.collectDistances(), x, z, cachedRegions, cache, distanceCache)) + continue; 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); - return true; + if (place(writer, position, structure, rng)) + return true; + } + } + return false; + } + + @ChunkCoordinates + private boolean checkDistances(KMap distances, int x, int z, KSet cachedRegions, KMap> cache, KMap distanceCache) { + int range = 0; + for (int d : distances.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 : distances.keySet()) { + if (!cache.containsKey(structure)) continue; + double maxDist = distances.get(structure); + maxDist = maxDist * maxDist; + for (Position2 sPos : cache.get(structure)) { + double dist = distanceCache.computeIfAbsent(sPos, position2 -> position2.distance(pos)); + if (dist > maxDist) return true; } } return false; @@ -91,7 +131,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { @ChunkCoordinates public IrisJigsawStructure guess(int x, int z) { // todo The guess doesnt bring into account that the placer may return -1 - boolean t = false; + // todo doesnt bring skipped placements into account RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_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); @@ -130,7 +170,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { } @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()); } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java new file mode 100644 index 000000000..17cbda4c2 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java @@ -0,0 +1,31 @@ +package com.volmit.iris.engine.object; + +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 lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +@Snippet("jigsaw-structure-distance") +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Represents the min distance between jigsaw structure placements") +@Data +public class IrisJigsawDistance { + @Required + @RegistryListResource(IrisJigsawStructure.class) + @Desc("The structure to check against") + private String structure; + + @Required + @MinNumber(0) + @MaxNumber(5000) + @Desc("The min distance in blocks to a placed structure\nWARNING: The performance impact scales exponentially!") + private int distance; +} diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index 609658e2d..2bb6faa70 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -18,10 +18,13 @@ package com.volmit.iris.engine.object; +import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; 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 lombok.AllArgsConstructor; import lombok.Data; import lombok.EqualsAndHashCode; @@ -45,4 +48,20 @@ public class IrisJigsawStructurePlacement { @Required @Desc("The 1 in X chance rarity") private int rarity = 100; + + @ArrayType(type = IrisJigsawDistance.class) + @Desc("List of distances to check for") + private KList distances = new KList<>(); + + public KMap collectDistances() { + KMap map = new KMap<>(); + for (IrisJigsawDistance d : distances) { + 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); + } } diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/JigsawStructuresMatter.java b/core/src/main/java/com/volmit/iris/util/matter/slices/JigsawStructuresMatter.java new file mode 100644 index 000000000..55803b946 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/JigsawStructuresMatter.java @@ -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 { + public JigsawStructuresMatter() { + this(1, 1, 1); + } + + public JigsawStructuresMatter(int width, int height, int depth) { + super(width, height, depth, JigsawStructuresContainer.class); + } + + @Override + public Palette 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); + } +} diff --git a/core/src/main/java/com/volmit/iris/util/matter/slices/container/JigsawStructuresContainer.java b/core/src/main/java/com/volmit/iris/util/matter/slices/container/JigsawStructuresContainer.java new file mode 100644 index 000000000..68d0f388f --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/matter/slices/container/JigsawStructuresContainer.java @@ -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> 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 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 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 getStructures() { + return Collections.unmodifiableSet(map.keySet()); + } + + @Unmodifiable + public List 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); + } +} From c1d9cc62cbea71055aae43e54d3eb03fa5a84f2b Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 17 Apr 2024 21:21:18 +0200 Subject: [PATCH 59/98] woops --- .../java/com/volmit/iris/engine/object/IrisJigsawPiece.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java index 93c9f07bc..c69aca0e4 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPiece.java @@ -102,7 +102,11 @@ public class IrisJigsawPiece extends IrisRegistrant { public IrisJigsawPiece copy() { var gson = getLoader().getGson(); - return gson.fromJson(gson.toJson(this), IrisJigsawPiece.class); + IrisJigsawPiece copy = gson.fromJson(gson.toJson(this), IrisJigsawPiece.class); + copy.setLoader(getLoader()); + copy.setLoadKey(getLoadKey()); + copy.setLoadFile(getLoadFile()); + return copy; } public boolean isTerminal() { From d7a283c99f5e17d59f7c24edd9b886d53505214d Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 18 Apr 2024 16:00:47 +0200 Subject: [PATCH 60/98] fix underwater jigsaw placement --- .../java/com/volmit/iris/engine/jigsaw/PlannedStructure.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index ab402cf4c..fe727eebb 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -118,7 +118,7 @@ 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(); From 768fa7beb57a230b31a2444b002d63c68ad43d3d Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Fri, 19 Apr 2024 02:47:02 -0400 Subject: [PATCH 61/98] v+ --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 90fe9be65..2484924d8 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.2.3-1.19.2-1.20.4' +version '3.2.4-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From 5a4a86aebaef66f46d499557f2c206a80716f39d Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:14:16 +0200 Subject: [PATCH 62/98] - Iris Updater Updates chunks thats it/ --- build.gradle | 2 + .../iris/core/commands/CommandIris.java | 20 ++++ .../iris/core/pregenerator/ChunkUpdater.java | 91 ++++++++++++++++--- 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index 90fe9be65..0f7f8c7d5 100644 --- a/build.gradle +++ b/build.gradle @@ -237,6 +237,8 @@ allprojects { implementation "net.kyori:adventure-text-minimessage:4.13.1" 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 diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index 6ec02ef7f..c7f204a52 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -21,6 +21,7 @@ package com.volmit.iris.core.commands; import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; +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; @@ -37,6 +38,7 @@ 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; @@ -317,6 +319,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") diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index 1e40ab566..c9c32726a 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -1,18 +1,27 @@ 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.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.nbt.mca.MCAFile; -import com.volmit.iris.util.nbt.mca.MCAUtil; +import io.papermc.lib.PaperLib; +import org.bukkit.Chunk; import org.bukkit.World; import java.io.File; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; public class ChunkUpdater { private AtomicBoolean cancelled; @@ -25,12 +34,19 @@ public class ChunkUpdater { 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 ScheduledExecutorService scheduler; private final File[] McaFiles; + private final Engine engine; private final World world; public ChunkUpdater(World world) { File cacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache"); File chunkCacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache" + File.separator + "spiral"); + this.engine = IrisToolbelt.access(world).getEngine(); this.chunksPerSecond = new RollingSequence(10); this.mcaregionsPerSecond = new RollingSequence(10); this.world = world; @@ -38,33 +54,82 @@ public class ChunkUpdater { this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1)); this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0)); - this.totalMaxChunks = new AtomicInteger((worldheightsize.get() / 16 ) * (worldwidthsize.get() / 16)); + int m = Math.max(worldheightsize.get(), worldwidthsize.get()); + this.executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() - 2); + this.scheduler = Executors.newScheduledThreadPool(1); + 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.cancelled = new AtomicBoolean(false); this.totalChunks = new AtomicInteger(0); this.totalMcaregions = new AtomicInteger(0); } - public void start() { - Initialize(); + public int getChunks() { + return totalMaxChunks.get(); } - public void Initialize() { - Iris.info("Initializing.."); + public void start() { + update(); + } + + + private void update() { + Iris.info("Updating.."); try { - for (File mca : McaFiles) { - MCAFile MCARegion = MCAUtil.read(mca); - for (int pos = 0; pos != totalMaxChunks.get(); pos++) { - int[] coords = getChunk(pos); - if(MCARegion.hasChunk(coords[0], coords[1])) chunkMap.add(coords); + startTime.set(System.currentTimeMillis()); + scheduler.scheduleAtFixedRate(() -> { + try { + 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; + 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); + + for (int i = 0; i < totalMaxChunks.get(); i++) { + executor.submit(this::processNextChunk); } - Iris.info("Finished Initializing.."); + + executor.shutdown(); + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + scheduler.shutdownNow(); + Iris.info("Processed: " + Form.f(chunksProcessed.get()) + " Chunks"); + Iris.info("Finished Updating: " + Form.f(chunksUpdated.get()) + " Chunks"); } catch (Exception e) { e.printStackTrace(); } } + private void processNextChunk() { + int pos = position.getAndIncrement(); + int[] coords = getChunk(pos); + if (PaperLib.isChunkGenerated(world, coords[0], coords[1])) { + Chunk chunk = world.getChunkAt(coords[0], coords[1]); + engine.updateChunk(chunk); + chunksUpdated.getAndIncrement(); + } + chunksProcessed.getAndIncrement(); + } + + 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")); From 9175296fc6974cdc81a8062c3a6ea7f2805238be Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:43:57 +0200 Subject: [PATCH 63/98] rev2.0 --- .../iris/core/pregenerator/ChunkUpdater.java | 86 ++++++++++++++++--- 1 file changed, 75 insertions(+), 11 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index c9c32726a..0e783d4c7 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -4,28 +4,30 @@ 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.reflect.V; +import com.volmit.iris.util.scheduling.J; import io.papermc.lib.PaperLib; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; import java.io.File; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +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 cancelled; - private KList chunkMap; + private KMap lastUse; private final RollingSequence chunksPerSecond; private final RollingSequence mcaregionsPerSecond; private final AtomicInteger worldheightsize; @@ -50,7 +52,7 @@ public class ChunkUpdater { this.chunksPerSecond = new RollingSequence(10); this.mcaregionsPerSecond = new RollingSequence(10); this.world = world; - this.chunkMap = new KList<>(); + this.lastUse = new KMap(); this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); this.worldheightsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 1)); this.worldwidthsize = new AtomicInteger(calculateWorldDimensions(new File(world.getWorldFolder(), "region"), 0)); @@ -74,6 +76,7 @@ public class ChunkUpdater { } public void start() { + unloadAndSaveAllChunks(); update(); } @@ -90,7 +93,7 @@ public class ChunkUpdater { double cps = elapsedSeconds > 0 ? processed / (double) elapsedSeconds : 0; chunksPerSecond.put(cps); double percentage = ((double) chunksProcessed.get() / (double) totalMaxChunks.get()) * 100; - Iris.info("Updated: " + Form.f(processed) + " of : " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta, 2), percentage); + 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(); } @@ -113,14 +116,75 @@ public class ChunkUpdater { private void processNextChunk() { int pos = position.getAndIncrement(); int[] coords = getChunk(pos); - if (PaperLib.isChunkGenerated(world, coords[0], coords[1])) { - Chunk chunk = world.getChunkAt(coords[0], coords[1]); - engine.updateChunk(chunk); - chunksUpdated.getAndIncrement(); + if (areAllChunksGenerated(coords[0], coords[1])) { + CompletableFuture chunkFuture = loadChunksIfGenerated(coords[0], coords[1]); + chunkFuture.thenAccept(chunk -> { + Chunk c = world.getChunkAt(coords[0], coords[1]); + engine.updateChunk(c); + chunksUpdated.getAndIncrement(); + }); } chunksProcessed.getAndIncrement(); } + private boolean areAllChunksGenerated(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; + } + } + } + return true; + } + + private CompletableFuture loadChunksIfGenerated(int x, int z) { + CompletableFuture future = new CompletableFuture<>(); + if (areAllChunksGenerated(x, z)) { + Runnable task = () -> { + try { + for (int dx = -1; dx <= 1; dx++) { + for (int dz = -1; dz <= 1; dz++) { + Chunk c = world.getChunkAt(x + dx, z + dz); + world.loadChunk(c); + lastUse.put(c, M.ms()); + } + } + future.complete(null); + } catch (Exception e) { + future.completeExceptionally(e); + } + }; + Bukkit.getScheduler().runTask(Iris.instance, task); + } else { + future.completeExceptionally(new IllegalStateException("Not all chunks are generated")); + } + return future; + } + + + 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) From 9a45e0df108ffb29e04f7a109b21f4cd065bfbcf Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Fri, 19 Apr 2024 15:15:08 +0200 Subject: [PATCH 64/98] /iris support report ( gives server info ) and cleaned the main splash screen and fixed /iris import saying its loaded successfully even if it didnt --- core/src/main/java/com/volmit/iris/Iris.java | 31 +--- .../iris/core/commands/CommandIris.java | 2 + .../iris/core/commands/CommandSupport.java | 82 ++++++++++ .../iris/core/tools/IrisBenchmarking.java | 5 +- .../com/volmit/iris/util/misc/Hastebin.java | 135 ++++++++++++++++ .../com/volmit/iris/util/misc/Platform.java | 145 +++++++++++++++++ .../volmit/iris/util/misc/getHardware.java | 152 ++++++++++++++++-- 7 files changed, 506 insertions(+), 46 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java create mode 100644 core/src/main/java/com/volmit/iris/util/misc/Hastebin.java create mode 100644 core/src/main/java/com/volmit/iris/util/misc/Platform.java diff --git a/core/src/main/java/com/volmit/iris/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 9fec3b7e8..950913796 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -806,9 +806,6 @@ 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()); @@ -821,35 +818,9 @@ 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("Custom Biomes: " + INMS.get().countCustomBiomes()); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index c7f204a52..ad77d9268 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -78,6 +78,7 @@ public class CommandIris implements DecreeExecutor { private CommandWhat what; private CommandEdit edit; private CommandFind find; + private CommandSupport support; private CommandDeveloper developer; public static boolean worldCreation = false; String WorldEngine; @@ -532,6 +533,7 @@ public class CommandIris implements DecreeExecutor { } catch (IOException e) { Iris.error("Failed to update bukkit.yml!"); e.printStackTrace(); + return; } } checkForBukkitWorlds(world); diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java b/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java new file mode 100644 index 000000000..0f7baad0d --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandSupport.java @@ -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 . + */ + +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(); + } + } + + +} + + diff --git a/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java b/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java index 300a4467f..79bf1b643 100644 --- a/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisBenchmarking.java @@ -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"); diff --git a/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java b/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java new file mode 100644 index 000000000..11e253b31 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/misc/Hastebin.java @@ -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 disks = new KList<>(getHardware.getDisk()); + KList interfaces = new KList<>(getHardware.getInterfaces()); + KList displays = new KList<>(getHardware.getEDID()); + KList sensors = new KList<>(getHardware.getSensors()); + KList gpus = new KList<>(getHardware.getGraphicsCards()); + KList powersources = new KList<>(getHardware.getPowerSources()); + + KList IrisWorlds = new KList<>(); + KList 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]; + } + + +} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/misc/Platform.java b/core/src/main/java/com/volmit/iris/util/misc/Platform.java new file mode 100644 index 000000000..afbf7c8c3 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/misc/Platform.java @@ -0,0 +1,145 @@ +package com.volmit.iris.util.misc; + +import com.sun.management.OperatingSystemMXBean; + +import java.io.File; +import java.lang.management.ManagementFactory; + +@SuppressWarnings("restriction") +public class Platform { + public static String getVersion() { + return getSystem().getVersion(); + } + + public static String getName() { + return getSystem().getName(); + } + + private static OperatingSystemMXBean getSystem() { + return (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean(); + } + + public static class ENVIRONMENT { + public static boolean canRunBatch() { + return getSystem().getName().toLowerCase().contains("windows"); + } + + public static String getJavaHome() { + return System.getProperty("java.home"); + } + + public static String getJavaVendor() { + return System.getProperty("java.vendor"); + } + + public static String getJavaVersion() { + return System.getProperty("java.version"); + } + } + + public static class STORAGE { + public static long getAbsoluteTotalSpace() { + long t = 0; + + for (File i : getRoots()) { + t += getTotalSpace(i); + } + + return t; + } + + public static long getTotalSpace() { + return getTotalSpace(new File(".")); + } + + public static long getTotalSpace(File root) { + return root.getTotalSpace(); + } + + public static long getAbsoluteFreeSpace() { + long t = 0; + + for (File i : getRoots()) { + t += getFreeSpace(i); + } + + return t; + } + + public static long getFreeSpace() { + return getFreeSpace(new File(".")); + } + + public static long getFreeSpace(File root) { + return root.getFreeSpace(); + } + + public static long getUsedSpace() { + return getTotalSpace() - getFreeSpace(); + } + + public static long getUsedSpace(File root) { + return getTotalSpace(root) - getFreeSpace(root); + } + + public static long getAbsoluteUsedSpace() { + return getAbsoluteTotalSpace() - getAbsoluteFreeSpace(); + } + + public static File[] getRoots() { + return File.listRoots(); + } + } + + public static class MEMORY { + public static class PHYSICAL { + public static long getTotalMemory() { + return getSystem().getTotalPhysicalMemorySize(); + } + + public static long getFreeMemory() { + return getSystem().getFreePhysicalMemorySize(); + } + + public static long getUsedMemory() { + return getTotalMemory() - getFreeMemory(); + } + } + + public static class VIRTUAL { + public static long getTotalMemory() { + return getSystem().getTotalSwapSpaceSize(); + } + + public static long getFreeMemory() { + return getSystem().getFreeSwapSpaceSize(); + } + + public static long getUsedMemory() { + return getTotalMemory() - getFreeMemory(); + } + + public static long getCommittedVirtualMemory() { + return getSystem().getCommittedVirtualMemorySize(); + } + } + } + + public static class CPU { + public static int getAvailableProcessors() { + return getSystem().getAvailableProcessors(); + } + + public static double getCPULoad() { + return getSystem().getSystemCpuLoad(); + } + + public static double getLiveProcessCPULoad() { + return getSystem().getProcessCpuLoad(); + } + + public static String getArchitecture() { + return getSystem().getArch(); + } + } +} \ No newline at end of file diff --git a/core/src/main/java/com/volmit/iris/util/misc/getHardware.java b/core/src/main/java/com/volmit/iris/util/misc/getHardware.java index 0b9a52033..0e494e27c 100644 --- a/core/src/main/java/com/volmit/iris/util/misc/getHardware.java +++ b/core/src/main/java/com/volmit/iris/util/misc/getHardware.java @@ -1,11 +1,24 @@ package com.volmit.iris.util.misc; -import oshi.SystemInfo; -import oshi.hardware.CentralProcessor; -import oshi.hardware.HWDiskStore; -import oshi.software.os.OperatingSystem; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import org.jetbrains.annotations.Nullable; +import oshi.SystemInfo; +import oshi.hardware.*; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.EdidUtil; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.Arrays; +import java.util.Collections; +import java.util.Enumeration; import java.util.List; +import java.util.stream.Collectors; public class getHardware { public static String getServerOS() { @@ -44,14 +57,127 @@ public class getHardware { } } - public static String getDiskModel() { - SystemInfo systemInfo = new SystemInfo(); - List diskStores = systemInfo.getHardware().getDiskStores(); - if (!diskStores.isEmpty()) { - HWDiskStore firstDisk = diskStores.get(0); - return firstDisk.getModel(); - } else { - return "Unknown Disk Model"; + public static KList getSensors() { + try { + KList temps = new KList<>(); + SystemInfo systemInfo = new SystemInfo(); + temps.add("CPU Temperature: " + systemInfo.getHardware().getSensors().getCpuTemperature()); + temps.add("CPU Voltage: " + systemInfo.getHardware().getSensors().getCpuTemperature()); + temps.add("Fan Speeds: " + Arrays.toString(systemInfo.getHardware().getSensors().getFanSpeeds())); + return temps.copy(); + } catch (Exception e) { + e.printStackTrace(); } + return null; } -} + + public static KList getGraphicsCards() { + try { + KList gpus = new KList<>(); + SystemInfo systemInfo = new SystemInfo(); + for (GraphicsCard gpu : systemInfo.getHardware().getGraphicsCards()) { + gpus.add(C.BLUE + "Gpu Model: " + C.GRAY + gpu.getName()); + gpus.add("- vRam Size: " + C.GRAY + Form.memSize(gpu.getVRam())); + gpus.add("- Vendor: " + C.GRAY + gpu.getVendor()); + } + return gpus.copy(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static KList getDisk() { + try { + KList systemDisks = new KList<>(); + SystemInfo systemInfo = new SystemInfo(); + List diskStores = systemInfo.getHardware().getDiskStores(); + OperatingSystem operatingSystem = systemInfo.getOperatingSystem(); + List fileStores = operatingSystem.getFileSystem().getFileStores(); + + for (HWDiskStore disk : diskStores) { + systemDisks.add(C.BLUE + "Disk: " + disk.getName()); + systemDisks.add("- Model: " + disk.getModel()); + systemDisks.add("Partitions: " + disk.getPartitions()); + for (OSFileStore partition : fileStores) { + systemDisks.add(C.BLUE + "- Name: " + partition.getName()); + systemDisks.add(" - Description: " + partition.getDescription()); + systemDisks.add(" - Total Space: " + Form.memSize(partition.getTotalSpace())); + systemDisks.add(" - Free Space: " + Form.memSize(partition.getFreeSpace())); + systemDisks.add(" - Mount: " + partition.getMount()); + systemDisks.add(" - Label: " + partition.getLabel()); + } + systemDisks.add(C.DARK_GRAY + "-=" + C.BLUE +" Since Boot " + C.DARK_GRAY + "=- "); + systemDisks.add("- Total Reads: " + Form.memSize(disk.getReadBytes())); + systemDisks.add("- Total Writes: " + Form.memSize(disk.getWriteBytes())); + } + if (systemDisks.isEmpty()) { + systemDisks.add("Failed to get disks."); + } + return systemDisks.copy(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static KList getPowerSources() { + try { + KList systemPowerSources = new KList<>(); + SystemInfo systemInfo = new SystemInfo(); + List powerSources = systemInfo.getHardware().getPowerSources(); + for (PowerSource powersource : powerSources) { + systemPowerSources.add(C.BLUE + "- Name: " + powersource.getName()); + systemPowerSources.add("- RemainingCapacityPercent: " + powersource.getRemainingCapacityPercent()); + systemPowerSources.add("- Power Usage Rate: " + powersource.getPowerUsageRate()); + systemPowerSources.add("- Power OnLine: " + powersource.isPowerOnLine()); + systemPowerSources.add("- Capacity Units: " + powersource.getCapacityUnits()); + systemPowerSources.add("- Cycle Count: " + powersource.getCycleCount()); + } + if (systemPowerSources.isEmpty()) { + systemPowerSources.add("No PowerSources."); + } + return systemPowerSources.copy(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static KList getEDID() { + try { + KList systemEDID = new KList<>(); + SystemInfo systemInfo = new SystemInfo(); + HardwareAbstractionLayer hardware = systemInfo.getHardware(); + List displays = hardware.getDisplays(); + for (Display display : displays) { + systemEDID.add("Display: " + display.getEdid()); + } + if (!systemEDID.isEmpty()) { + systemEDID.add("No displays"); + } + return systemEDID.copy(); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + public static KList getInterfaces() { + try { + KList interfaces = new KList<>(); + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + for (NetworkInterface ni : Collections.list(networkInterfaces)) { + interfaces.add(C.BLUE + "Display Name: %s", ni.getDisplayName()); + Enumeration inetAddresses = ni.getInetAddresses(); + for (InetAddress ia : Collections.list(inetAddresses)) { + interfaces.add("IP: %s", ia.getHostAddress()); + } + return interfaces.copy(); + } + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} \ No newline at end of file From a7118aa785b3c1cf84eab13016ccfecfe59fa1b3 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 19 Apr 2024 15:18:11 +0200 Subject: [PATCH 65/98] fix jigsaw place command --- .../iris/core/commands/CommandJigsaw.java | 2 +- .../volmit/iris/engine/jigsaw/PlannedPiece.java | 17 +++++++---------- .../iris/engine/jigsaw/PlannedStructure.java | 14 ++++++++++++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java index 922041241..a59aa2a69 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java @@ -57,7 +57,7 @@ public class CommandJigsaw implements DecreeExecutor { 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()); + ps.place(world(), failed -> sender().sendMessage(failed == 0 ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place " + failed + " pieces!")); } @Decree(description = "Create a jigsaw piece") diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index e93fe5c7d..d2b0d43ea 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -165,7 +165,7 @@ public class PlannedPiece { return connected.size() >= piece.getConnectors().size() || isDead(); } - public void place(World world) { + public boolean place(World world) { PlatformChunkGenerator a = IrisToolbelt.access(world); int minY = 0; @@ -175,14 +175,16 @@ public class PlannedPiece { if (!a.getEngine().getDimension().isBedrock()) minY--; //If the dimension has no bedrock, allow it to go a block lower } + Engine engine = a != null ? a.getEngine() : IrisContext.get().getEngine(); getPiece().getPlacementOptions().setTranslate(new IrisObjectTranslate()); - getPiece().getPlacementOptions().setRotation(rotation); + getPiece().getPlacementOptions().getRotation().setEnabled(false); + getPiece().getPlacementOptions().setRotateTowardsSlope(false); 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() { + return getObject().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(); @@ -207,7 +209,6 @@ public class PlannedPiece { 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); @@ -258,12 +259,8 @@ public class PlannedPiece { @Override public Engine getEngine() { - if (IrisToolbelt.isIrisWorld(world)) { - return IrisToolbelt.access(world).getEngine(); - } - - return IrisContext.get().getEngine(); + return engine; } - }, piece.getPlacementOptions(), rng, getData()); + }, piece.getPlacementOptions(), rng, getData().getEngine() == null ? engine.getData() : getData()) != -1; } } diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index fe727eebb..36cdcaa00 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -34,6 +34,9 @@ import lombok.Data; import org.bukkit.Axis; import org.bukkit.World; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.IntConsumer; + @Data public class PlannedStructure { private static ConcurrentLinkedHashMap objectRotationCache @@ -138,9 +141,16 @@ public class PlannedStructure { }, null, getData()) != -1; } - public void place(World world) { + public void place(World world, IntConsumer consumer) { + AtomicInteger processed = new AtomicInteger(); + AtomicInteger failures = new AtomicInteger(); for (PlannedPiece i : pieces) { - Iris.sq(() -> i.place(world)); + Iris.sq(() -> { + if (!i.place(world)) failures.incrementAndGet(); + if (processed.incrementAndGet() == pieces.size()) { + consumer.accept(failures.get()); + } + }); } } From 79a4ebcf65c08d65fd05c1ccd84f4b3340fec85d Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 19 Apr 2024 15:29:28 +0200 Subject: [PATCH 66/98] woops --- .../engine/mantle/components/MantleJigsawComponent.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 14ebeb45d..2236723fc 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -118,11 +118,11 @@ public class MantleJigsawComponent extends IrisMantleComponent { Position2 pos = new Position2(x, z); for (String structure : distances.keySet()) { if (!cache.containsKey(structure)) continue; - double maxDist = distances.get(structure); - maxDist = maxDist * maxDist; + double minDist = distances.get(structure); + minDist = minDist * minDist; for (Position2 sPos : cache.get(structure)) { double dist = distanceCache.computeIfAbsent(sPos, position2 -> position2.distance(pos)); - if (dist > maxDist) return true; + if (minDist > dist) return true; } } return false; From 0e666a4c35786ca7c87f28e746c4a0a895d06f4d Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Mon, 22 Apr 2024 14:23:45 +0200 Subject: [PATCH 67/98] change rng noise for jigsaw component --- .../mantle/components/MantleJigsawComponent.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 2236723fc..69f815fb1 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -18,6 +18,7 @@ package com.volmit.iris.engine.mantle.components; +import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.IrisMantleComponent; @@ -34,20 +35,25 @@ 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 com.volmit.iris.util.noise.NoiseType; import java.util.List; public class MantleJigsawComponent extends IrisMantleComponent { - private final CNG cng; public MantleJigsawComponent(EngineMantle engineMantle) { super(engineMantle, MantleFlag.JIGSAW); - cng = NoiseStyle.STATIC.create(new RNG(engineMantle.getEngine().getSeedManager().getJigsaw())); + } + + private RNG applyNoise(int x, int z) { + long seed = Cache.key(x, z) + getEngineMantle().getEngine().getSeedManager().getJigsaw(); + CNG cng = CNG.signatureFast(new RNG(seed), NoiseType.WHITE, NoiseType.GLOB); + return new RNG((long) (seed * cng.noise(x, z))); } @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)); + RNG rng = applyNoise(x, z); int xxx = 8 + (x << 4); int zzz = 8 + (z << 4); IrisRegion region = getComplex().getRegionStream().get(xxx, zzz); @@ -132,7 +138,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { public IrisJigsawStructure guess(int x, int z) { // todo The guess doesnt bring into account that the placer may return -1 // todo doesnt bring skipped placements into account - RNG rng = new RNG(cng.fit(-Integer.MAX_VALUE, Integer.MAX_VALUE, x, z)); + RNG rng = applyNoise(x, z); IrisBiome biome = getEngineMantle().getEngine().getSurfaceBiome((x << 4) + 8, (z << 4) + 8); IrisRegion region = getEngineMantle().getEngine().getRegion((x << 4) + 8, (z << 4) + 8); From cb9a73c60ed397c1414f4444f146f1683d113c2f Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 23 Apr 2024 10:28:04 +0200 Subject: [PATCH 68/98] rename IrisJigsawDistance to IrisJigsawMinDistance to avoid confusion --- .../mantle/components/MantleJigsawComponent.java | 10 +++++----- ...sJigsawDistance.java => IrisJigsawMinDistance.java} | 6 ++---- .../engine/object/IrisJigsawStructurePlacement.java | 10 +++++----- 3 files changed, 12 insertions(+), 14 deletions(-) rename core/src/main/java/com/volmit/iris/engine/object/{IrisJigsawDistance.java => IrisJigsawMinDistance.java} (85%) diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 69f815fb1..f10ff67c7 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -92,7 +92,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { KSet cachedRegions, KMap> cache, KMap distanceCache) { for (IrisJigsawStructurePlacement i : structures) { if (rng.nextInt(i.getRarity()) == 0) { - if (checkDistances(i.collectDistances(), x, z, cachedRegions, cache, distanceCache)) + if (checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache)) continue; IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); @@ -104,9 +104,9 @@ public class MantleJigsawComponent extends IrisMantleComponent { } @ChunkCoordinates - private boolean checkDistances(KMap distances, int x, int z, KSet cachedRegions, KMap> cache, KMap distanceCache) { + private boolean checkMinDistances(KMap minDistances, int x, int z, KSet cachedRegions, KMap> cache, KMap distanceCache) { int range = 0; - for (int d : distances.values()) + for (int d : minDistances.values()) range = Math.max(range, d); for (int xx = -range; xx <= range; xx++) { @@ -122,9 +122,9 @@ public class MantleJigsawComponent extends IrisMantleComponent { } } Position2 pos = new Position2(x, z); - for (String structure : distances.keySet()) { + for (String structure : minDistances.keySet()) { if (!cache.containsKey(structure)) continue; - double minDist = distances.get(structure); + double minDist = minDistances.get(structure); minDist = minDist * minDist; for (Position2 sPos : cache.get(structure)) { double dist = distanceCache.computeIfAbsent(sPos, position2 -> position2.distance(pos)); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawMinDistance.java similarity index 85% rename from core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java rename to core/src/main/java/com/volmit/iris/engine/object/IrisJigsawMinDistance.java index 17cbda4c2..818f4b3dd 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawDistance.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawMinDistance.java @@ -1,7 +1,6 @@ package com.volmit.iris.engine.object; 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; @@ -11,13 +10,13 @@ import lombok.Data; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; -@Snippet("jigsaw-structure-distance") +@Snippet("jigsaw-structure-min-distance") @Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor @Desc("Represents the min distance between jigsaw structure placements") @Data -public class IrisJigsawDistance { +public class IrisJigsawMinDistance { @Required @RegistryListResource(IrisJigsawStructure.class) @Desc("The structure to check against") @@ -25,7 +24,6 @@ public class IrisJigsawDistance { @Required @MinNumber(0) - @MaxNumber(5000) @Desc("The min distance in blocks to a placed structure\nWARNING: The performance impact scales exponentially!") private int distance; } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index 2bb6faa70..16eea76e8 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -49,13 +49,13 @@ public class IrisJigsawStructurePlacement { @Desc("The 1 in X chance rarity") private int rarity = 100; - @ArrayType(type = IrisJigsawDistance.class) - @Desc("List of distances to check for") - private KList distances = new KList<>(); + @ArrayType(type = IrisJigsawMinDistance.class) + @Desc("List of minimum distances to check for") + private KList minDistances = new KList<>(); - public KMap collectDistances() { + public KMap collectMinDistances() { KMap map = new KMap<>(); - for (IrisJigsawDistance d : distances) { + for (IrisJigsawMinDistance d : minDistances) { map.compute(d.getStructure(), (k, v) -> v != null ? Math.min(toChunks(d.getDistance()), v) : toChunks(d.getDistance())); } return map; From 9e6963b6ce3a53875258aa0f4993a3d1a6fedabd Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 23 Apr 2024 11:24:53 +0200 Subject: [PATCH 69/98] A lot of improvements thanks to CrazyDev! --- .../iris/core/commands/CommandIris.java | 19 +- .../iris/core/commands/CommandUpdater.java | 107 ++++++++++ .../iris/core/pregenerator/ChunkUpdater.java | 186 ++++++++++++------ 3 files changed, 237 insertions(+), 75 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/core/commands/CommandUpdater.java diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index c7f204a52..3a6206fc3 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -78,6 +78,7 @@ public class CommandIris implements DecreeExecutor { private CommandWhat what; private CommandEdit edit; private CommandFind find; + private CommandUpdater updater; private CommandDeveloper developer; public static boolean worldCreation = false; String WorldEngine; @@ -319,24 +320,6 @@ 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") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandUpdater.java b/core/src/main/java/com/volmit/iris/core/commands/CommandUpdater.java new file mode 100644 index 000000000..cb1ff6eeb --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandUpdater.java @@ -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 . + */ + +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") + 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(); + } + +} + + diff --git a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java index 0e783d4c7..d89ad3340 100644 --- a/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java +++ b/core/src/main/java/com/volmit/iris/core/pregenerator/ChunkUpdater.java @@ -9,14 +9,11 @@ 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.reflect.V; import com.volmit.iris.util.scheduling.J; import io.papermc.lib.PaperLib; -import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; - import java.io.File; import java.util.ArrayList; @@ -26,10 +23,10 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; public class ChunkUpdater { + private AtomicBoolean paused; private AtomicBoolean cancelled; private KMap lastUse; private final RollingSequence chunksPerSecond; - private final RollingSequence mcaregionsPerSecond; private final AtomicInteger worldheightsize; private final AtomicInteger worldwidthsize; private final AtomicInteger totalChunks; @@ -40,25 +37,26 @@ public class ChunkUpdater { private AtomicInteger chunksUpdated; private AtomicLong startTime; private ExecutorService executor; + private ExecutorService chunkExecutor; private ScheduledExecutorService scheduler; - private final File[] McaFiles; + private CompletableFuture future; + private CountDownLatch latch; + private final Object pauseLock; private final Engine engine; private final World world; public ChunkUpdater(World world) { - File cacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache"); - File chunkCacheDir = new File("plugins" + File.separator + "iris" + File.separator + "cache" + File.separator + "spiral"); this.engine = IrisToolbelt.access(world).getEngine(); - this.chunksPerSecond = new RollingSequence(10); - this.mcaregionsPerSecond = new RollingSequence(10); + this.chunksPerSecond = new RollingSequence(5); this.world = world; this.lastUse = new KMap(); - this.McaFiles = new File(world.getWorldFolder(), "region").listFiles((dir, name) -> name.endsWith(".mca")); 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(Runtime.getRuntime().availableProcessors() - 2); + 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); @@ -66,6 +64,9 @@ public class ChunkUpdater { 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); @@ -80,6 +81,22 @@ public class ChunkUpdater { 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.."); @@ -87,47 +104,89 @@ public class ChunkUpdater { startTime.set(System.currentTimeMillis()); scheduler.scheduleAtFixedRate(() -> { try { - 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; - Iris.info("Updated: " + Form.f(processed) + " of " + Form.f(totalMaxChunks.get()) + " (%.0f%%) " + Form.f(chunksPerSecond.getAverage()) + "/s, ETA: " + Form.duration(eta, 2), percentage); + 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); - for (int i = 0; i < totalMaxChunks.get(); i++) { - executor.submit(this::processNextChunk); - } + 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(); + } + }); - executor.shutdown(); - executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); - scheduler.shutdownNow(); - Iris.info("Processed: " + Form.f(chunksProcessed.get()) + " Chunks"); - Iris.info("Finished Updating: " + Form.f(chunksUpdated.get()) + " Chunks"); } 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 (areAllChunksGenerated(coords[0], coords[1])) { - CompletableFuture chunkFuture = loadChunksIfGenerated(coords[0], coords[1]); - chunkFuture.thenAccept(chunk -> { - Chunk c = world.getChunkAt(coords[0], coords[1]); - engine.updateChunk(c); - chunksUpdated.getAndIncrement(); - }); + if (loadChunksIfGenerated(coords[0], coords[1])) { + Chunk c = world.getChunkAt(coords[0], coords[1]); + engine.updateChunk(c); + chunksUpdated.incrementAndGet(); } chunksProcessed.getAndIncrement(); } - private boolean areAllChunksGenerated(int x, int z) { + 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)) { @@ -135,34 +194,47 @@ public class ChunkUpdater { } } } - return true; - } - private CompletableFuture loadChunksIfGenerated(int x, int z) { - CompletableFuture future = new CompletableFuture<>(); - if (areAllChunksGenerated(x, z)) { - Runnable task = () -> { - try { - for (int dx = -1; dx <= 1; dx++) { - for (int dz = -1; dz <= 1; dz++) { - Chunk c = world.getChunkAt(x + dx, z + dz); - world.loadChunk(c); - lastUse.put(c, M.ms()); - } + AtomicBoolean generated = new AtomicBoolean(true); + KList> 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; } - future.complete(null); - } catch (Exception e) { - future.completeExceptionally(e); - } - }; - Bukkit.getScheduler().runTask(Iris.instance, task); - } else { - future.completeExceptionally(new IllegalStateException("Not all chunks are generated")); + 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()); + })); + } } - return future; + while (!futures.isEmpty()) { + futures.removeIf(Future::isDone); + try { + Thread.sleep(50); + } catch (InterruptedException ignored) {} + } + return generated.get(); } - private void unloadAndSaveAllChunks() { try { J.sfut(() -> { From 178a462a4eeba9e958f2fc76fdc997ffbec7ea42 Mon Sep 17 00:00:00 2001 From: RePixelatedMC Date: Tue, 23 Apr 2024 12:29:19 +0200 Subject: [PATCH 70/98] e --- .../com/volmit/iris/util/nbt/mca/Chunk.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java index fdd0b969b..f74cdcf7f 100644 --- a/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java +++ b/core/src/main/java/com/volmit/iris/util/nbt/mca/Chunk.java @@ -41,6 +41,7 @@ public class Chunk { private int lastMCAUpdate; private CompoundTag data; private int dataVersion; + private int nativeIrisVersion; private long lastUpdate; private long inhabitedTime; private MCABiomeContainer biomes; @@ -83,6 +84,11 @@ public class Chunk { return c; } + public static void injectIrisData(Chunk c) { + World mainWorld = getServer().getWorlds().get(0); + c.data.put("Iris", nativeIrisVersion()); + } + private static CompoundTag defaultLevel() { CompoundTag level = new CompoundTag(); level.putString("Status", "full"); @@ -90,14 +96,19 @@ public class Chunk { return level; } + private static CompoundTag nativeIrisVersion() { + CompoundTag level = new CompoundTag(); + level.putString("Generator", "Iris " + Iris.instance.getDescription().getVersion()); + return level; + } + private void initReferences(long loadFlags) { if (data == null) { throw new NullPointerException("data cannot be null"); } - CompoundTag level; - if ((level = data.getCompoundTag("Level")) == null) { - throw new IllegalArgumentException("data does not contain \"Level\" tag"); - } + + CompoundTag level = data; + World mainWorld = getServer().getWorlds().get(0); dataVersion = data.getInt("DataVersion"); inhabitedTime = level.getLong("InhabitedTime"); From 100e45051408cfa290d477aca343462a9a748acc Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 23 Apr 2024 13:48:47 +0200 Subject: [PATCH 71/98] fix jigsaw piece collision --- .../java/com/volmit/iris/engine/jigsaw/PlannedPiece.java | 3 +++ .../java/com/volmit/iris/engine/jigsaw/PlannedStructure.java | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index d2b0d43ea..08088ac38 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -30,6 +30,7 @@ import com.volmit.iris.util.math.AxisAlignedBB; import com.volmit.iris.util.math.BlockPosition; import com.volmit.iris.util.math.RNG; import lombok.Data; +import lombok.EqualsAndHashCode; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; @@ -50,10 +51,12 @@ public class PlannedPiece { private IrisObject ogObject; private IrisJigsawPiece piece; private IrisObjectRotation rotation; + @EqualsAndHashCode.Exclude private IrisData data; private KList connected; private boolean dead = false; private AxisAlignedBB box; + @EqualsAndHashCode.Exclude private PlannedStructure structure; public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece) { diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 36cdcaa00..dc2bf6b68 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -31,6 +31,7 @@ import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.matter.slices.container.JigsawPieceContainer; import com.volmit.iris.util.matter.slices.container.JigsawStructuresContainer; import lombok.Data; +import lombok.EqualsAndHashCode; import org.bukkit.Axis; import org.bukkit.World; @@ -319,6 +320,10 @@ public class PlannedStructure { public boolean collidesWith(PlannedPiece piece, PlannedPiece ignore) { for (PlannedPiece i : pieces) { + if (i.equals(ignore)) { + continue; + } + if (i.collidesWith(piece)) { return true; } From c1d5ba55cd4ac65bb523dfe42204eefcab9a418c Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 23 Apr 2024 13:49:10 +0200 Subject: [PATCH 72/98] fix null pointer --- .../main/java/com/volmit/iris/engine/object/IrisObject.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index c4306c115..665b60c77 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -279,6 +279,8 @@ public class IrisObject extends IrisRegistrant { public synchronized IrisObject copy() { IrisObject o = new IrisObject(w, h, d); o.setLoadKey(o.getLoadKey()); + o.setLoader(getLoader()); + o.setLoadFile(getLoadFile()); o.setCenter(getCenter().clone()); for (BlockVector i : getBlocks().keySet()) { @@ -898,6 +900,7 @@ public class IrisObject extends IrisRegistrant { } } } catch (Throwable e) { + e.printStackTrace(); Iris.reportError(e); } readLock.unlock(); From 6470b2f4a9875c9bf1ba65f434054fd3d439a6a6 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Tue, 23 Apr 2024 13:49:30 +0200 Subject: [PATCH 73/98] fix another null pointer --- .../java/com/volmit/iris/core/commands/CommandJigsaw.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java index a59aa2a69..edab02cdb 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java @@ -34,6 +34,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; @@ -56,8 +57,9 @@ public class CommandJigsaw implements DecreeExecutor { ) { 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(), failed -> sender().sendMessage(failed == 0 ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place " + failed + " pieces!")); + VolmitSender sender = sender(); + sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2)); + ps.place(world(), failed -> sender.sendMessage(failed == 0 ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place " + failed + " pieces!")); } @Decree(description = "Create a jigsaw piece") From e3e4ecbc5c51b38686731a03356d5bca87bda1b6 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:41:29 +0200 Subject: [PATCH 74/98] Update README.md --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 52dbc784e..df89fcade 100644 --- a/README.md +++ b/README.md @@ -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) From a3dcf031c9934be0865b638d581bfe138fd56d5b Mon Sep 17 00:00:00 2001 From: Brian Neumann-Fopiano Date: Mon, 29 Apr 2024 15:45:41 -0400 Subject: [PATCH 75/98] v+ , and the other v+ lol --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 77c48256c..53fc6212c 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ plugins { id "de.undercouch.download" version "5.0.1" } -version '3.2.4-1.19.2-1.20.4' +version '3.2.6-1.19.2-1.20.4' def specialSourceVersion = '1.11.0' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED From 720417b6c8a1ab3397ef723c1be6a261b15566a1 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 1 May 2024 18:39:42 +0200 Subject: [PATCH 76/98] fix shrinkwrap method --- .../volmit/iris/engine/object/IrisObject.java | 2535 +++++++++-------- 1 file changed, 1268 insertions(+), 1267 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 665b60c77..ea3d115ea 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -1,1267 +1,1268 @@ -/* - * 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 . - */ - -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.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.PlacedObject; -import com.volmit.iris.engine.framework.placer.HeightmapObjectPlacer; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.context.IrisContext; -import com.volmit.iris.util.data.B; -import com.volmit.iris.util.data.IrisBlockData; -import com.volmit.iris.util.format.Form; -import com.volmit.iris.util.interpolation.IrisInterpolation; -import com.volmit.iris.util.json.JSONObject; -import com.volmit.iris.util.math.AxisAlignedBB; -import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.math.RNG; -import com.volmit.iris.util.matter.MatterMarker; -import com.volmit.iris.util.parallel.BurstExecutor; -import com.volmit.iris.util.parallel.MultiBurst; -import com.volmit.iris.util.plugin.VolmitSender; -import com.volmit.iris.util.scheduling.IrisLock; -import com.volmit.iris.util.scheduling.PrecisionStopwatch; -import com.volmit.iris.util.stream.ProceduralStream; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import lombok.experimental.Accessors; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.TileState; -import org.bukkit.block.data.BlockData; -import org.bukkit.block.data.MultipleFacing; -import org.bukkit.block.data.Waterlogged; -import org.bukkit.block.data.type.Leaves; -import org.bukkit.util.BlockVector; -import org.bukkit.util.Vector; - -import java.io.*; -import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; - -@Accessors(chain = true) -@EqualsAndHashCode(callSuper = false) -public class IrisObject extends IrisRegistrant { - protected static final Vector HALF = new Vector(0.5, 0.5, 0.5); - protected static final BlockData AIR = B.get("CAVE_AIR"); - protected static final BlockData VAIR = B.get("VOID_AIR"); - protected static final BlockData VAIR_DEBUG = B.get("COBWEB"); - protected static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")}; - protected transient final IrisLock readLock = new IrisLock("read-conclock"); - @Getter - @Setter - protected transient volatile boolean smartBored = false; - @Getter - @Setter - protected transient IrisLock lock = new IrisLock("Preloadcache"); - @Setter - protected transient AtomicCache aabb = new AtomicCache<>(); - private KMap blocks; - private KMap> states; - @Getter - @Setter - private int w; - @Getter - @Setter - private int d; - @Getter - @Setter - private int h; - @Getter - @Setter - private transient BlockVector center; - - public IrisObject(int w, int h, int d) { - blocks = new KMap<>(); - states = new KMap<>(); - this.w = w; - this.h = h; - this.d = d; - center = new BlockVector(w / 2, h / 2, d / 2); - } - - public IrisObject() { - this(0, 0, 0); - } - - public static BlockVector getCenterForSize(BlockVector size) { - return new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2); - } - - public static AxisAlignedBB getAABBFor(BlockVector size) { - BlockVector center = new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2); - return new AxisAlignedBB(new IrisPosition(new BlockVector(0, 0, 0).subtract(center).toBlockVector()), - new IrisPosition(new BlockVector(size.getX() - 1, size.getY() - 1, size.getZ() - 1).subtract(center).toBlockVector())); - } - - @SuppressWarnings({"resource", "RedundantSuppression"}) - public static BlockVector sampleSize(File file) throws IOException { - FileInputStream in = new FileInputStream(file); - DataInputStream din = new DataInputStream(in); - BlockVector bv = new BlockVector(din.readInt(), din.readInt(), din.readInt()); - Iris.later(din::close); - return bv; - } - - private static List blocksBetweenTwoPoints(Vector loc1, Vector loc2) { - List locations = new ArrayList<>(); - int topBlockX = Math.max(loc1.getBlockX(), loc2.getBlockX()); - int bottomBlockX = Math.min(loc1.getBlockX(), loc2.getBlockX()); - int topBlockY = Math.max(loc1.getBlockY(), loc2.getBlockY()); - int bottomBlockY = Math.min(loc1.getBlockY(), loc2.getBlockY()); - int topBlockZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); - int bottomBlockZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); - - for (int x = bottomBlockX; x <= topBlockX; x++) { - for (int z = bottomBlockZ; z <= topBlockZ; z++) { - for (int y = bottomBlockY; y <= topBlockY; y++) { - locations.add(new BlockVector(x, y, z)); - } - } - } - return locations; - } - - public AxisAlignedBB getAABB() { - return aabb.aquire(() -> getAABBFor(new BlockVector(w, h, d))); - } - - public void ensureSmartBored(boolean debug) { - if (smartBored) { - return; - } - - PrecisionStopwatch p = PrecisionStopwatch.start(); - BlockData vair = debug ? VAIR_DEBUG : VAIR; - lock.lock(); - AtomicInteger applied = new AtomicInteger(); - if (getBlocks().isEmpty()) { - lock.unlock(); - Iris.warn("Cannot Smart Bore " + getLoadKey() + " because it has 0 blocks in it."); - smartBored = true; - return; - } - - BlockVector max = new BlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE); - BlockVector min = new BlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); - - for (BlockVector i : getBlocks().keySet()) { - max.setX(Math.max(i.getX(), max.getX())); - min.setX(Math.min(i.getX(), min.getX())); - max.setY(Math.max(i.getY(), max.getY())); - min.setY(Math.min(i.getY(), min.getY())); - max.setZ(Math.max(i.getZ(), max.getZ())); - min.setZ(Math.min(i.getZ(), min.getZ())); - } - - BurstExecutor burst = MultiBurst.burst.burst(); - - // Smash X - for (int rayY = min.getBlockY(); rayY <= max.getBlockY(); rayY++) { - int finalRayY = rayY; - burst.queue(() -> { - for (int rayZ = min.getBlockZ(); rayZ <= max.getBlockZ(); rayZ++) { - int start = Integer.MAX_VALUE; - int end = Integer.MIN_VALUE; - - for (int ray = min.getBlockX(); ray <= max.getBlockX(); ray++) { - if (getBlocks().containsKey(new BlockVector(ray, finalRayY, rayZ))) { - start = Math.min(ray, start); - end = Math.max(ray, end); - } - } - - if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { - for (int i = start; i <= end; i++) { - BlockVector v = new BlockVector(i, finalRayY, rayZ); - - if (!B.isAir(getBlocks().get(v))) { - getBlocks().computeIfAbsent(v, (vv) -> vair); - applied.getAndIncrement(); - } - } - } - } - }); - } - - // Smash Y - for (int rayX = min.getBlockX(); rayX <= max.getBlockX(); rayX++) { - int finalRayX = rayX; - burst.queue(() -> { - for (int rayZ = min.getBlockZ(); rayZ <= max.getBlockZ(); rayZ++) { - int start = Integer.MAX_VALUE; - int end = Integer.MIN_VALUE; - - for (int ray = min.getBlockY(); ray <= max.getBlockY(); ray++) { - if (getBlocks().containsKey(new BlockVector(finalRayX, ray, rayZ))) { - start = Math.min(ray, start); - end = Math.max(ray, end); - } - } - - if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { - for (int i = start; i <= end; i++) { - BlockVector v = new BlockVector(finalRayX, i, rayZ); - - if (!B.isAir(getBlocks().get(v))) { - getBlocks().computeIfAbsent(v, (vv) -> vair); - applied.getAndIncrement(); - } - } - } - } - }); - } - - // Smash Z - for (int rayX = min.getBlockX(); rayX <= max.getBlockX(); rayX++) { - int finalRayX = rayX; - burst.queue(() -> { - for (int rayY = min.getBlockY(); rayY <= max.getBlockY(); rayY++) { - int start = Integer.MAX_VALUE; - int end = Integer.MIN_VALUE; - - for (int ray = min.getBlockZ(); ray <= max.getBlockZ(); ray++) { - if (getBlocks().containsKey(new BlockVector(finalRayX, rayY, ray))) { - start = Math.min(ray, start); - end = Math.max(ray, end); - } - } - - if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { - for (int i = start; i <= end; i++) { - BlockVector v = new BlockVector(finalRayX, rayY, i); - - if (!B.isAir(getBlocks().get(v))) { - getBlocks().computeIfAbsent(v, (vv) -> vair); - applied.getAndIncrement(); - } - } - } - } - }); - } - - burst.complete(); - smartBored = true; - lock.unlock(); - Iris.debug("Smart Bore: " + getLoadKey() + " in " + Form.duration(p.getMilliseconds(), 2) + " (" + Form.f(applied.get()) + ")"); - } - - public synchronized IrisObject copy() { - IrisObject o = new IrisObject(w, h, d); - o.setLoadKey(o.getLoadKey()); - o.setLoader(getLoader()); - o.setLoadFile(getLoadFile()); - o.setCenter(getCenter().clone()); - - for (BlockVector i : getBlocks().keySet()) { - o.getBlocks().put(i.clone(), Objects.requireNonNull(getBlocks().get(i)).clone()); - } - - for (BlockVector i : getStates().keySet()) { - o.getStates().put(i.clone(), Objects.requireNonNull(getStates().get(i)).clone()); - } - - return o; - } - - public void readLegacy(InputStream in) throws IOException { - DataInputStream din = new DataInputStream(in); - this.w = din.readInt(); - this.h = din.readInt(); - this.d = din.readInt(); - center = new BlockVector(w / 2, h / 2, d / 2); - int s = din.readInt(); - - for (int i = 0; i < s; i++) { - getBlocks().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.get(din.readUTF())); - } - - try { - int size = din.readInt(); - - for (int i = 0; i < size; i++) { - getStates().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din)); - } - } catch (Throwable e) { - Iris.reportError(e); - - } - } - - public void read(InputStream in) throws Throwable { - DataInputStream din = new DataInputStream(in); - this.w = din.readInt(); - this.h = din.readInt(); - this.d = din.readInt(); - if (!din.readUTF().equals("Iris V2 IOB;")) { - return; - } - center = new BlockVector(w / 2, h / 2, d / 2); - int s = din.readShort(); - int i; - KList palette = new KList<>(); - - for (i = 0; i < s; i++) { - palette.add(din.readUTF()); - } - - s = din.readInt(); - - for (i = 0; i < s; i++) { - getBlocks().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.get(palette.get(din.readShort()))); - } - - s = din.readInt(); - - for (i = 0; i < s; i++) { - getStates().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din)); - } - } - - public void write(OutputStream o) throws IOException { - DataOutputStream dos = new DataOutputStream(o); - dos.writeInt(w); - dos.writeInt(h); - dos.writeInt(d); - dos.writeUTF("Iris V2 IOB;"); - KList palette = new KList<>(); - - for (BlockData i : getBlocks().values()) { - palette.addIfMissing(i.getAsString()); - } - - dos.writeShort(palette.size()); - - for (String i : palette) { - dos.writeUTF(i); - } - - dos.writeInt(getBlocks().size()); - - for (BlockVector i : getBlocks().keySet()) { - dos.writeShort(i.getBlockX()); - dos.writeShort(i.getBlockY()); - dos.writeShort(i.getBlockZ()); - dos.writeShort(palette.indexOf(getBlocks().get(i).getAsString())); - } - - dos.writeInt(getStates().size()); - for (BlockVector i : getStates().keySet()) { - dos.writeShort(i.getBlockX()); - dos.writeShort(i.getBlockY()); - dos.writeShort(i.getBlockZ()); - getStates().get(i).toBinary(dos); - } - } - - public void read(File file) throws IOException { - FileInputStream fin = new FileInputStream(file); - try { - read(fin); - fin.close(); - } catch (Throwable e) { - Iris.reportError(e); - fin.close(); - fin = new FileInputStream(file); - readLegacy(fin); - fin.close(); - } - } - - public void write(File file) throws IOException { - if (file == null) { - return; - } - - FileOutputStream out = new FileOutputStream(file); - write(out); - out.close(); - } - - public void shrinkwrap() { - BlockVector min = new BlockVector(); - BlockVector max = new BlockVector(); - - for (BlockVector i : getBlocks().keySet()) { - min.setX(Math.min(min.getX(), i.getX())); - min.setY(Math.min(min.getY(), i.getY())); - min.setZ(Math.min(min.getZ(), i.getZ())); - max.setX(Math.max(max.getX(), i.getX())); - max.setY(Math.max(max.getY(), i.getY())); - max.setZ(Math.max(max.getZ(), i.getZ())); - } - - w = max.getBlockX() - min.getBlockX(); - h = max.getBlockY() - min.getBlockY(); - d = max.getBlockZ() - min.getBlockZ(); - } - - public void clean() { - KMap d = new KMap<>(); - - for (BlockVector i : getBlocks().keySet()) { - d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i))); - } - - KMap> dx = new KMap<>(); - - for (BlockVector i : getBlocks().keySet()) { - d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i))); - } - - for (BlockVector i : getStates().keySet()) { - dx.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getStates().get(i))); - } - - blocks = d; - states = dx; - } - - public BlockVector getSigned(int x, int y, int z) { - if (x >= w || y >= h || z >= d) { - throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d); - } - - return new BlockVector(x, y, z).subtract(center).toBlockVector(); - } - - public void setUnsigned(int x, int y, int z, BlockData block) { - BlockVector v = getSigned(x, y, z); - - if (block == null) { - getBlocks().remove(v); - getStates().remove(v); - } else { - getBlocks().put(v, block); - } - } - - public void setUnsigned(int x, int y, int z, Block block) { - BlockVector v = getSigned(x, y, z); - - if (block == null) { - getBlocks().remove(v); - getStates().remove(v); - } else { - BlockData data = block.getBlockData(); - getBlocks().put(v, data); - TileData state = TileData.getTileState(block); - if (state != null) { - Iris.info("Saved State " + v); - getStates().put(v, state); - } - } - } - - public int place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { - return place(x, -1, z, placer, config, rng, rdata); - } - - public int place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, CarveResult c, IrisData rdata) { - return place(x, -1, z, placer, config, rng, null, c, rdata); - } - - public int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { - return place(x, yv, z, placer, config, rng, null, null, rdata); - } - - public int place(Location loc, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { - return place(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), placer, config, rng, rdata); - } - - public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, BiConsumer listener, CarveResult c, IrisData rdata) { - IObjectPlacer placer = (config.getHeightmap() != null) ? new HeightmapObjectPlacer(oplacer.getEngine() == null ? IrisContext.get().getEngine() : oplacer.getEngine(), rng, x, yv, z, config, oplacer) : oplacer; - - if (rdata != null) { - // Slope condition - if (!config.getSlopeCondition().isDefault() && - !config.getSlopeCondition().isValid(rdata.getEngine().getComplex().getSlopeStream().get(x, z))) { - return -1; - } - -// if (config.getCarvingSupport().supportsSurface()) { -// int y = placer.getHighest(x, z, rdata); -// if (placer.isCarved(x, y, z)) { -// return -1; -// } -// } - - // Rotation calculation - int slopeRotationY = 0; - ProceduralStream heightStream = rdata.getEngine().getComplex().getHeightStream(); - if (config.isRotateTowardsSlope()) { - // Whichever side of the rectangle that bounds the object is lowest is the 'direction' of the slope (simply said). - double hNorth = heightStream.get(x, z + ((float) d) / 2); - double hEast = heightStream.get(x + ((float) w) / 2, z); - double hSouth = heightStream.get(x, z - ((float) d) / 2); - double hWest = heightStream.get(x - ((float) w) / 2, z); - double min = Math.min(Math.min(hNorth, hEast), Math.min(hSouth, hWest)); - if (min == hNorth) { - slopeRotationY = 0; - } else if (min == hEast) { - slopeRotationY = 90; - } else if (min == hSouth) { - slopeRotationY = 180; - } else if (min == hWest) { - slopeRotationY = 270; - } - - double newRotation = config.getRotation().getYAxis().getMin() + slopeRotationY; - if (newRotation == 0) { - config.getRotation().setYAxis(new IrisAxisRotationClamp(false, false, 0, 0, 90)); - config.getRotation().setEnabled(config.getRotation().canRotateX() || config.getRotation().canRotateZ()); - } else { - config.getRotation().setYAxis(new IrisAxisRotationClamp(true, false, newRotation, newRotation, 90)); - config.getRotation().setEnabled(true); - } - } - } - - if (config.isSmartBore()) { - ensureSmartBored(placer.isDebugSmartBore()); - } - - boolean warped = !config.getWarp().isFlat(); - boolean stilting = (config.getMode().equals(ObjectPlaceMode.STILT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT) || - config.getMode() == ObjectPlaceMode.MIN_STILT || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT || - config.getMode() == ObjectPlaceMode.CENTER_STILT); - KMap heightmap = config.getSnow() > 0 ? new KMap<>() : null; - int spinx = rng.imax() / 1000; - int spiny = rng.imax() / 1000; - int spinz = rng.imax() / 1000; - int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY(); - int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY(); - int y = -1; - int xx, zz; - int yrand = config.getTranslate().getYRandom(); - yrand = yrand > 0 ? rng.i(0, yrand) : yrand < 0 ? rng.i(yrand, 0) : yrand; - boolean bail = false; - - if (yv < 0) { - if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT) || config.getMode() == ObjectPlaceMode.CENTER_STILT) { - y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; - } - } else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) { - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); - int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); - int minX = Math.min(x - xLength, x + xLength); - int maxX = Math.max(x - xLength, x + xLength); - int zLength = (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); - int minZ = Math.min(z - zLength, z + zLength); - int maxZ = Math.max(z - zLength, z + zLength); - for (int i = minX; i <= maxX; i++) { - for (int ii = minZ; ii <= maxZ; ii++) { - int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; - } - if (h > y) - y = h; - } - } - } else if (config.getMode().equals(ObjectPlaceMode.FAST_MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT)) { - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); - - int xRadius = (rotatedDimensions.getBlockX() / 2); - int xLength = xRadius + offset.getBlockX(); - int minX = Math.min(x - xLength, x + xLength); - int maxX = Math.max(x - xLength, x + xLength); - int zRadius = (rotatedDimensions.getBlockZ() / 2); - int zLength = zRadius + offset.getBlockZ(); - int minZ = Math.min(z - zLength, z + zLength); - int maxZ = Math.max(z - zLength, z + zLength); - - for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { - for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { - int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; - } - if (h > y) - y = h; - } - } - } else if (config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.MIN_STILT) { - y = rdata.getEngine().getHeight() + 1; - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); - - int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); - int minX = Math.min(x - xLength, x + xLength); - int maxX = Math.max(x - xLength, x + xLength); - int zLength = (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); - int minZ = Math.min(z - zLength, z + zLength); - int maxZ = Math.max(z - zLength, z + zLength); - for (int i = minX; i <= maxX; i++) { - for (int ii = minZ; ii <= maxZ; ii++) { - int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; - } - if (h < y) { - y = h; - } - } - } - } else if (config.getMode().equals(ObjectPlaceMode.FAST_MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT) { - y = rdata.getEngine().getHeight() + 1; - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); - - int xRadius = (rotatedDimensions.getBlockX() / 2); - int xLength = xRadius + offset.getBlockX(); - int minX = Math.min(x - xLength, x + xLength); - int maxX = Math.max(x - xLength, x + xLength); - int zRadius = (rotatedDimensions.getBlockZ() / 2); - int zLength = zRadius + offset.getBlockZ(); - int minZ = Math.min(z - zLength, z + zLength); - int maxZ = Math.max(z - zLength, z + zLength); - - for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { - for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { - int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; - } - if (h < y) { - y = h; - } - } - } - } else if (config.getMode().equals(ObjectPlaceMode.PAINT)) { - y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; - } - } - } else { - y = yv; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; - } - } - - if (yv >= 0 && config.isBottom()) { - y += Math.floorDiv(h, 2); - bail = placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z); - } - - if (bail) { - return -1; - } - - if (yv < 0) { - if (!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) { - return -1; - } - } - - if (c != null && Math.max(0, h + yrand + ty) + 1 >= c.getHeight()) { - return -1; - } - - if (config.isUnderwater() && y + rty + ty >= placer.getFluidHeight()) { - return -1; - } - - if (!config.getClamp().canPlace(y + rty + ty, y - rty + ty)) { - return -1; - } - - if (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty()) { - Engine engine = rdata.getEngine(); - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { - for (int j = y - Math.floorDiv(h, 2) + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) { - for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) { - PlacedObject p = engine.getObjectPlacement(i, j, k); - if (p == null) continue; - IrisObject o = p.getObject(); - if (o == null) continue; - String key = o.getLoadKey(); - if (key != null) { - if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) { - // Iris.debug("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k); - return -1; - } - } - } - } - } - } - - if (config.isBore()) { - BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); - for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { - for (int j = y - Math.floorDiv(h, 2) - config.getBoreExtendMinY() + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) + config.getBoreExtendMaxY() - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) { - for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) { - placer.set(i, j, k, AIR); - } - } - } - } - - int lowest = Integer.MAX_VALUE; - y += yrand; - readLock.lock(); - - KMap markers = null; - - try { - if (config.getMarkers().isNotEmpty() && placer.getEngine() != null) { - markers = new KMap<>(); - for (IrisObjectMarker j : config.getMarkers()) { - IrisMarker marker = getLoader().getMarkerLoader().load(j.getMarker()); - - if (marker == null) { - continue; - } - - int max = j.getMaximumMarkers(); - - for (BlockVector i : getBlocks().k().shuffle()) { - if (max <= 0) { - break; - } - - BlockData data = getBlocks().get(i); - - for (BlockData k : j.getMark(rdata)) { - if (max <= 0) { - break; - } - - if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { - boolean a = !blocks.containsKey(new BlockVector(i.clone().add(new BlockVector(0, 1, 0)))); - boolean fff = !blocks.containsKey(new BlockVector(i.clone().add(new BlockVector(0, 2, 0)))); - - if (!marker.isEmptyAbove() || (a && fff)) { - markers.put(i, j.getMarker()); - max--; - } - } - } - } - } - } - - for (BlockVector g : getBlocks().keySet()) { - BlockData d; - TileData tile = null; - - try { - d = getBlocks().get(g); - tile = getStates().get(g); - } catch (Throwable e) { - Iris.reportError(e); - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (cme)"); - d = AIR; - } - - if (d == null) { - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (null)"); - d = AIR; - } - - BlockVector i = g.clone(); - BlockData data = d.clone(); - i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); - i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); - - if (stilting && i.getBlockY() < lowest && !B.isAir(data)) { - lowest = i.getBlockY(); - } - - if (placer.isPreventingDecay() && (data) instanceof Leaves && !((Leaves) (data)).isPersistent()) { - ((Leaves) data).setPersistent(true); - } - - for (IrisObjectReplace j : config.getEdit()) { - if (rng.chance(j.getChance())) { - for (BlockData k : j.getFind(rdata)) { - if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { - BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); - - if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisBlockData || data instanceof IrisBlockData)) - data = data.merge(newData); - else - data = newData; - - if (newData.getMaterial() == Material.SPAWNER) { - Optional> t = j.getReplace().getTile(rng, x, y, z, rdata); - if (t.isPresent()) { - tile = t.get(); - } - } - } - } - } - } - - data = config.getRotation().rotate(data, spinx, spiny, spinz); - xx = x + (int) Math.round(i.getX()); - - int yy = y + (int) Math.round(i.getY()); - zz = z + (int) Math.round(i.getZ()); - - if (warped) { - xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z, getLoader()); - zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader()); - } - - if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT)) && !B.isVineBlock(data)) { - yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, getLoader(), config.isUnderwater()); - } - - if (heightmap != null) { - Position2 pos = new Position2(xx, zz); - - if (!heightmap.containsKey(pos)) { - heightmap.put(pos, yy); - } - - if (heightmap.get(pos) < yy) { - heightmap.put(pos, yy); - } - } - - if (config.isMeld() && !placer.isSolid(xx, yy, zz)) { - continue; - } - - if ((config.isWaterloggable() || config.isUnderwater()) && yy <= placer.getFluidHeight() && data instanceof Waterlogged) { - // TODO Here - ((Waterlogged) data).setWaterlogged(true); - } - - if (B.isVineBlock(data)) { - MultipleFacing f = (MultipleFacing) data; - for (BlockFace face : f.getAllowedFaces()) { - BlockData facingBlock = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ()); - if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { - f.setFace(face, true); - } - } - } - - if (listener != null) { - listener.accept(new BlockPosition(xx, yy, zz), data); - } - - if (markers != null && markers.containsKey(g)) { - placer.getEngine().getMantle().getMantle().set(xx, yy, zz, new MatterMarker(markers.get(g))); - } - - boolean wouldReplace = B.isSolid(placer.get(xx, yy, zz)) && B.isVineBlock(data); - - if (!data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace) { - placer.set(xx, yy, zz, data); - if (tile != null) { - placer.setTile(xx, yy, zz, tile); - } - } - } - } catch (Throwable e) { - e.printStackTrace(); - Iris.reportError(e); - } - readLock.unlock(); - - if (stilting) { - readLock.lock(); - IrisStiltSettings settings = config.getStiltSettings(); - for (BlockVector g : getBlocks().keySet()) { - BlockData d; - - if (settings == null || settings.getPalette() == null) { - try { - d = getBlocks().get(g); - } catch (Throwable e) { - Iris.reportError(e); - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt cme)"); - d = AIR; - } - - if (d == null) { - Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt null)"); - d = AIR; - } - } else - d = config.getStiltSettings().getPalette().get(rng, x, y, z, rdata); - - - BlockVector i = g.clone(); - i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); - i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); - d = config.getRotation().rotate(d, spinx, spiny, spinz); - - if (i.getBlockY() != lowest) - continue; - - for (IrisObjectReplace j : config.getEdit()) { - if (rng.chance(j.getChance())) { - for (BlockData k : j.getFind(rdata)) { - if (j.isExact() ? k.matches(d) : k.getMaterial().equals(d.getMaterial())) { - BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); - - if (newData.getMaterial() == d.getMaterial()) { - d = d.merge(newData); - } else { - d = newData; - } - } - } - } - } - - if (d == null || B.isAir(d)) - continue; - - xx = x + (int) Math.round(i.getX()); - zz = z + (int) Math.round(i.getZ()); - - if (warped) { - xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z, getLoader()); - zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader()); - } - - int highest = placer.getHighest(xx, zz, getLoader(), true); - - if ((config.isWaterloggable() || config.isUnderwater()) && highest <= placer.getFluidHeight() && d instanceof Waterlogged) - ((Waterlogged) d).setWaterlogged(true); - - if (yv >= 0 && config.isBottom()) - y += Math.floorDiv(h, 2); - - int lowerBound = highest - 1; - if (settings != null) { - lowerBound -= config.getStiltSettings().getOverStilt() - rng.i(0, config.getStiltSettings().getYRand()); - if (settings.getYMax() != 0) - lowerBound -= Math.min(config.getStiltSettings().getYMax() - (lowest + y - highest), 0); - } - for (int j = lowest + y; j > lowerBound; j--) { - if (B.isVineBlock(d)) { - MultipleFacing f = (MultipleFacing) d; - for (BlockFace face : f.getAllowedFaces()) { - BlockData facingBlock = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ()); - if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { - f.setFace(face, true); - } - } - } - placer.set(xx, j, zz, d); - } - - } - - readLock.unlock(); - } - - if (heightmap != null) { - RNG rngx = rng.nextParallelRNG(3468854); - - for (Position2 i : heightmap.k()) { - int vx = i.getX(); - int vy = heightmap.get(i); - int vz = i.getZ(); - - if (config.getSnow() > 0) { - int height = rngx.i(0, (int) (config.getSnow() * 7)); - placer.set(vx, vy + 1, vz, SNOW_LAYERS[Math.max(Math.min(height, 7), 0)]); - } - } - } - - return y; - } - - public IrisObject rotateCopy(IrisObjectRotation rt) { - IrisObject copy = copy(); - copy.rotate(rt, 0, 0, 0); - return copy; - } - - public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) { - KMap d = new KMap<>(); - - for (BlockVector i : getBlocks().keySet()) { - d.put(r.rotate(i.clone(), spinx, spiny, spinz), r.rotate(getBlocks().get(i).clone(), - spinx, spiny, spinz)); - } - - KMap> dx = new KMap<>(); - - for (BlockVector i : getStates().keySet()) { - dx.put(r.rotate(i.clone(), spinx, spiny, spinz), getStates().get(i)); - } - - blocks = d; - states = dx; - } - - public void place(Location at) { - for (BlockVector i : getBlocks().keySet()) { - Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock(); - b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false); - - if (getStates().containsKey(i)) { - Iris.info(Objects.requireNonNull(states.get(i)).toString()); - BlockState st = b.getState(); - Objects.requireNonNull(getStates().get(i)).toBukkitTry(st); - st.update(); - } - } - } - - public void placeCenterY(Location at) { - for (BlockVector i : getBlocks().keySet()) { - Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock(); - b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false); - - if (getStates().containsKey(i)) { - Objects.requireNonNull(getStates().get(i)).toBukkitTry(b.getState()); - } - } - } - - public synchronized KMap getBlocks() { - return blocks; - } - - public synchronized KMap> getStates() { - return states; - } - - public void unplaceCenterY(Location at) { - for (BlockVector i : getBlocks().keySet()) { - at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData(AIR, false); - } - } - - public IrisObject scaled(double scale, IrisObjectPlacementScaleInterpolator interpolation) { - Vector sm1 = new Vector(scale - 1, scale - 1, scale - 1); - scale = Math.max(0.001, Math.min(50, scale)); - if (scale < 1) { - scale = scale - 0.0001; - } - - IrisPosition l1 = getAABB().max(); - IrisPosition l2 = getAABB().min(); - @SuppressWarnings({"unchecked", "rawtypes"}) HashMap placeBlock = new HashMap(); - - Vector center = getCenter(); - if (getH() == 2) { - center = center.setY(center.getBlockY() + 0.5); - } - if (getW() == 2) { - center = center.setX(center.getBlockX() + 0.5); - } - if (getD() == 2) { - center = center.setZ(center.getBlockZ() + 0.5); - } - - IrisObject oo = new IrisObject((int) Math.ceil((w * scale) + (scale * 2)), (int) Math.ceil((h * scale) + (scale * 2)), (int) Math.ceil((d * scale) + (scale * 2))); - - for (Map.Entry entry : blocks.entrySet()) { - BlockData bd = entry.getValue(); - placeBlock.put(entry.getKey().clone().add(HALF).subtract(center) - .multiply(scale).add(sm1).toBlockVector(), bd); - } - - for (Map.Entry entry : placeBlock.entrySet()) { - BlockVector v = entry.getKey(); - if (scale > 1) { - for (BlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) { - oo.getBlocks().put(vec, entry.getValue()); - } - } else { - oo.setUnsigned(v.getBlockX(), v.getBlockY(), v.getBlockZ(), entry.getValue()); - } - } - - if (scale > 1) { - switch (interpolation) { - case TRILINEAR -> oo.trilinear((int) Math.round(scale)); - case TRICUBIC -> oo.tricubic((int) Math.round(scale)); - case TRIHERMITE -> oo.trihermite((int) Math.round(scale)); - } - } - - return oo; - } - - public void trilinear(int rad) { - KMap v = getBlocks().copy(); - KMap b = new KMap<>(); - BlockVector min = getAABB().minbv(); - BlockVector max = getAABB().maxbv(); - - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - - if (data == null || data.getMaterial().isAir()) { - return 0; - } - - return 1; - }) >= 0.5) { - b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); - } else { - b.put(new BlockVector(x, y, z), AIR); - } - } - } - } - - blocks = b; - } - - public void tricubic(int rad) { - KMap v = getBlocks().copy(); - KMap b = new KMap<>(); - BlockVector min = getAABB().minbv(); - BlockVector max = getAABB().maxbv(); - - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - - if (data == null || data.getMaterial().isAir()) { - return 0; - } - - return 1; - }) >= 0.5) { - b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); - } else { - b.put(new BlockVector(x, y, z), AIR); - } - } - } - } - - blocks = b; - } - - public void trihermite(int rad) { - trihermite(rad, 0D, 0D); - } - - public void trihermite(int rad, double tension, double bias) { - KMap v = getBlocks().copy(); - KMap b = new KMap<>(); - BlockVector min = getAABB().minbv(); - BlockVector max = getAABB().maxbv(); - - for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { - for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { - for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { - if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> { - BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); - - if (data == null || data.getMaterial().isAir()) { - return 0; - } - - return 1; - }, tension, bias) >= 0.5) { - b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); - } else { - b.put(new BlockVector(x, y, z), AIR); - } - } - } - } - - blocks = b; - } - - private BlockData nearestBlockData(int x, int y, int z) { - BlockVector vv = new BlockVector(x, y, z); - BlockData r = getBlocks().get(vv); - - if (r != null && !r.getMaterial().isAir()) { - return r; - } - - double d = Double.MAX_VALUE; - - for (Map.Entry entry : blocks.entrySet()) { - BlockData dat = entry.getValue(); - - if (dat.getMaterial().isAir()) { - continue; - } - - double dx = entry.getKey().distanceSquared(vv); - - if (dx < d) { - d = dx; - r = dat; - } - } - - return r; - } - - public int volume() { - return blocks.size(); - } - - @Override - public String getFolderName() { - return "objects"; - } - - @Override - public String getTypeName() { - return "Object"; - } - - @Override - public void scanForErrors(JSONObject p, VolmitSender sender) { - } -} +/* + * 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 . + */ + +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.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.framework.PlacedObject; +import com.volmit.iris.engine.framework.placer.HeightmapObjectPlacer; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.context.IrisContext; +import com.volmit.iris.util.data.B; +import com.volmit.iris.util.data.IrisBlockData; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.interpolation.IrisInterpolation; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.math.AxisAlignedBB; +import com.volmit.iris.util.math.BlockPosition; +import com.volmit.iris.util.math.Position2; +import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.matter.MatterMarker; +import com.volmit.iris.util.parallel.BurstExecutor; +import com.volmit.iris.util.parallel.MultiBurst; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.scheduling.IrisLock; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import com.volmit.iris.util.stream.ProceduralStream; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.TileState; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.MultipleFacing; +import org.bukkit.block.data.Waterlogged; +import org.bukkit.block.data.type.Leaves; +import org.bukkit.util.BlockVector; +import org.bukkit.util.Vector; + +import java.io.*; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; + +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +public class IrisObject extends IrisRegistrant { + protected static final Vector HALF = new Vector(0.5, 0.5, 0.5); + protected static final BlockData AIR = B.get("CAVE_AIR"); + protected static final BlockData VAIR = B.get("VOID_AIR"); + protected static final BlockData VAIR_DEBUG = B.get("COBWEB"); + protected static final BlockData[] SNOW_LAYERS = new BlockData[]{B.get("minecraft:snow[layers=1]"), B.get("minecraft:snow[layers=2]"), B.get("minecraft:snow[layers=3]"), B.get("minecraft:snow[layers=4]"), B.get("minecraft:snow[layers=5]"), B.get("minecraft:snow[layers=6]"), B.get("minecraft:snow[layers=7]"), B.get("minecraft:snow[layers=8]")}; + protected transient final IrisLock readLock = new IrisLock("read-conclock"); + @Getter + @Setter + protected transient volatile boolean smartBored = false; + @Getter + @Setter + protected transient IrisLock lock = new IrisLock("Preloadcache"); + @Setter + protected transient AtomicCache aabb = new AtomicCache<>(); + private KMap blocks; + private KMap> states; + @Getter + @Setter + private int w; + @Getter + @Setter + private int d; + @Getter + @Setter + private int h; + @Getter + @Setter + private transient BlockVector center; + + public IrisObject(int w, int h, int d) { + blocks = new KMap<>(); + states = new KMap<>(); + this.w = w; + this.h = h; + this.d = d; + center = new BlockVector(w / 2, h / 2, d / 2); + } + + public IrisObject() { + this(0, 0, 0); + } + + public static BlockVector getCenterForSize(BlockVector size) { + return new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2); + } + + public static AxisAlignedBB getAABBFor(BlockVector size) { + BlockVector center = new BlockVector(size.getX() / 2, size.getY() / 2, size.getZ() / 2); + return new AxisAlignedBB(new IrisPosition(new BlockVector(0, 0, 0).subtract(center).toBlockVector()), + new IrisPosition(new BlockVector(size.getX() - 1, size.getY() - 1, size.getZ() - 1).subtract(center).toBlockVector())); + } + + @SuppressWarnings({"resource", "RedundantSuppression"}) + public static BlockVector sampleSize(File file) throws IOException { + FileInputStream in = new FileInputStream(file); + DataInputStream din = new DataInputStream(in); + BlockVector bv = new BlockVector(din.readInt(), din.readInt(), din.readInt()); + Iris.later(din::close); + return bv; + } + + private static List blocksBetweenTwoPoints(Vector loc1, Vector loc2) { + List locations = new ArrayList<>(); + int topBlockX = Math.max(loc1.getBlockX(), loc2.getBlockX()); + int bottomBlockX = Math.min(loc1.getBlockX(), loc2.getBlockX()); + int topBlockY = Math.max(loc1.getBlockY(), loc2.getBlockY()); + int bottomBlockY = Math.min(loc1.getBlockY(), loc2.getBlockY()); + int topBlockZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ()); + int bottomBlockZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ()); + + for (int x = bottomBlockX; x <= topBlockX; x++) { + for (int z = bottomBlockZ; z <= topBlockZ; z++) { + for (int y = bottomBlockY; y <= topBlockY; y++) { + locations.add(new BlockVector(x, y, z)); + } + } + } + return locations; + } + + public AxisAlignedBB getAABB() { + return aabb.aquire(() -> getAABBFor(new BlockVector(w, h, d))); + } + + public void ensureSmartBored(boolean debug) { + if (smartBored) { + return; + } + + PrecisionStopwatch p = PrecisionStopwatch.start(); + BlockData vair = debug ? VAIR_DEBUG : VAIR; + lock.lock(); + AtomicInteger applied = new AtomicInteger(); + if (getBlocks().isEmpty()) { + lock.unlock(); + Iris.warn("Cannot Smart Bore " + getLoadKey() + " because it has 0 blocks in it."); + smartBored = true; + return; + } + + BlockVector max = new BlockVector(Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE); + BlockVector min = new BlockVector(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE); + + for (BlockVector i : getBlocks().keySet()) { + max.setX(Math.max(i.getX(), max.getX())); + min.setX(Math.min(i.getX(), min.getX())); + max.setY(Math.max(i.getY(), max.getY())); + min.setY(Math.min(i.getY(), min.getY())); + max.setZ(Math.max(i.getZ(), max.getZ())); + min.setZ(Math.min(i.getZ(), min.getZ())); + } + + BurstExecutor burst = MultiBurst.burst.burst(); + + // Smash X + for (int rayY = min.getBlockY(); rayY <= max.getBlockY(); rayY++) { + int finalRayY = rayY; + burst.queue(() -> { + for (int rayZ = min.getBlockZ(); rayZ <= max.getBlockZ(); rayZ++) { + int start = Integer.MAX_VALUE; + int end = Integer.MIN_VALUE; + + for (int ray = min.getBlockX(); ray <= max.getBlockX(); ray++) { + if (getBlocks().containsKey(new BlockVector(ray, finalRayY, rayZ))) { + start = Math.min(ray, start); + end = Math.max(ray, end); + } + } + + if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { + for (int i = start; i <= end; i++) { + BlockVector v = new BlockVector(i, finalRayY, rayZ); + + if (!B.isAir(getBlocks().get(v))) { + getBlocks().computeIfAbsent(v, (vv) -> vair); + applied.getAndIncrement(); + } + } + } + } + }); + } + + // Smash Y + for (int rayX = min.getBlockX(); rayX <= max.getBlockX(); rayX++) { + int finalRayX = rayX; + burst.queue(() -> { + for (int rayZ = min.getBlockZ(); rayZ <= max.getBlockZ(); rayZ++) { + int start = Integer.MAX_VALUE; + int end = Integer.MIN_VALUE; + + for (int ray = min.getBlockY(); ray <= max.getBlockY(); ray++) { + if (getBlocks().containsKey(new BlockVector(finalRayX, ray, rayZ))) { + start = Math.min(ray, start); + end = Math.max(ray, end); + } + } + + if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { + for (int i = start; i <= end; i++) { + BlockVector v = new BlockVector(finalRayX, i, rayZ); + + if (!B.isAir(getBlocks().get(v))) { + getBlocks().computeIfAbsent(v, (vv) -> vair); + applied.getAndIncrement(); + } + } + } + } + }); + } + + // Smash Z + for (int rayX = min.getBlockX(); rayX <= max.getBlockX(); rayX++) { + int finalRayX = rayX; + burst.queue(() -> { + for (int rayY = min.getBlockY(); rayY <= max.getBlockY(); rayY++) { + int start = Integer.MAX_VALUE; + int end = Integer.MIN_VALUE; + + for (int ray = min.getBlockZ(); ray <= max.getBlockZ(); ray++) { + if (getBlocks().containsKey(new BlockVector(finalRayX, rayY, ray))) { + start = Math.min(ray, start); + end = Math.max(ray, end); + } + } + + if (start != Integer.MAX_VALUE && end != Integer.MIN_VALUE) { + for (int i = start; i <= end; i++) { + BlockVector v = new BlockVector(finalRayX, rayY, i); + + if (!B.isAir(getBlocks().get(v))) { + getBlocks().computeIfAbsent(v, (vv) -> vair); + applied.getAndIncrement(); + } + } + } + } + }); + } + + burst.complete(); + smartBored = true; + lock.unlock(); + Iris.debug("Smart Bore: " + getLoadKey() + " in " + Form.duration(p.getMilliseconds(), 2) + " (" + Form.f(applied.get()) + ")"); + } + + public synchronized IrisObject copy() { + IrisObject o = new IrisObject(w, h, d); + o.setLoadKey(o.getLoadKey()); + o.setLoader(getLoader()); + o.setLoadFile(getLoadFile()); + o.setCenter(getCenter().clone()); + + for (BlockVector i : getBlocks().keySet()) { + o.getBlocks().put(i.clone(), Objects.requireNonNull(getBlocks().get(i)).clone()); + } + + for (BlockVector i : getStates().keySet()) { + o.getStates().put(i.clone(), Objects.requireNonNull(getStates().get(i)).clone()); + } + + return o; + } + + public void readLegacy(InputStream in) throws IOException { + DataInputStream din = new DataInputStream(in); + this.w = din.readInt(); + this.h = din.readInt(); + this.d = din.readInt(); + center = new BlockVector(w / 2, h / 2, d / 2); + int s = din.readInt(); + + for (int i = 0; i < s; i++) { + getBlocks().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.get(din.readUTF())); + } + + try { + int size = din.readInt(); + + for (int i = 0; i < size; i++) { + getStates().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din)); + } + } catch (Throwable e) { + Iris.reportError(e); + + } + } + + public void read(InputStream in) throws Throwable { + DataInputStream din = new DataInputStream(in); + this.w = din.readInt(); + this.h = din.readInt(); + this.d = din.readInt(); + if (!din.readUTF().equals("Iris V2 IOB;")) { + return; + } + center = new BlockVector(w / 2, h / 2, d / 2); + int s = din.readShort(); + int i; + KList palette = new KList<>(); + + for (i = 0; i < s; i++) { + palette.add(din.readUTF()); + } + + s = din.readInt(); + + for (i = 0; i < s; i++) { + getBlocks().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), B.get(palette.get(din.readShort()))); + } + + s = din.readInt(); + + for (i = 0; i < s; i++) { + getStates().put(new BlockVector(din.readShort(), din.readShort(), din.readShort()), TileData.read(din)); + } + } + + public void write(OutputStream o) throws IOException { + DataOutputStream dos = new DataOutputStream(o); + dos.writeInt(w); + dos.writeInt(h); + dos.writeInt(d); + dos.writeUTF("Iris V2 IOB;"); + KList palette = new KList<>(); + + for (BlockData i : getBlocks().values()) { + palette.addIfMissing(i.getAsString()); + } + + dos.writeShort(palette.size()); + + for (String i : palette) { + dos.writeUTF(i); + } + + dos.writeInt(getBlocks().size()); + + for (BlockVector i : getBlocks().keySet()) { + dos.writeShort(i.getBlockX()); + dos.writeShort(i.getBlockY()); + dos.writeShort(i.getBlockZ()); + dos.writeShort(palette.indexOf(getBlocks().get(i).getAsString())); + } + + dos.writeInt(getStates().size()); + for (BlockVector i : getStates().keySet()) { + dos.writeShort(i.getBlockX()); + dos.writeShort(i.getBlockY()); + dos.writeShort(i.getBlockZ()); + getStates().get(i).toBinary(dos); + } + } + + public void read(File file) throws IOException { + FileInputStream fin = new FileInputStream(file); + try { + read(fin); + fin.close(); + } catch (Throwable e) { + Iris.reportError(e); + fin.close(); + fin = new FileInputStream(file); + readLegacy(fin); + fin.close(); + } + } + + public void write(File file) throws IOException { + if (file == null) { + return; + } + + FileOutputStream out = new FileOutputStream(file); + write(out); + out.close(); + } + + public void shrinkwrap() { + BlockVector min = new BlockVector(); + BlockVector max = new BlockVector(); + + for (BlockVector i : getBlocks().keySet()) { + min.setX(Math.min(min.getX(), i.getX())); + min.setY(Math.min(min.getY(), i.getY())); + min.setZ(Math.min(min.getZ(), i.getZ())); + max.setX(Math.max(max.getX(), i.getX())); + max.setY(Math.max(max.getY(), i.getY())); + max.setZ(Math.max(max.getZ(), i.getZ())); + } + + w = max.getBlockX() - min.getBlockX() + (min.getBlockX() <= 0 && max.getBlockX() >= 0 && min.getBlockX() != max.getBlockX() ? 1 : 0); + h = max.getBlockY() - min.getBlockY() + (min.getBlockY() <= 0 && max.getBlockY() >= 0 && min.getBlockY() != max.getBlockY() ? 1 : 0); + d = max.getBlockZ() - min.getBlockZ() + (min.getBlockZ() <= 0 && max.getBlockZ() >= 0 && min.getBlockZ() != max.getBlockZ() ? 1 : 0); + center = new BlockVector(w / 2, h / 2, d / 2); + } + + public void clean() { + KMap d = new KMap<>(); + + for (BlockVector i : getBlocks().keySet()) { + d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i))); + } + + KMap> dx = new KMap<>(); + + for (BlockVector i : getBlocks().keySet()) { + d.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getBlocks().get(i))); + } + + for (BlockVector i : getStates().keySet()) { + dx.put(new BlockVector(i.getBlockX(), i.getBlockY(), i.getBlockZ()), Objects.requireNonNull(getStates().get(i))); + } + + blocks = d; + states = dx; + } + + public BlockVector getSigned(int x, int y, int z) { + if (x >= w || y >= h || z >= d) { + throw new RuntimeException(x + " " + y + " " + z + " exceeds limit of " + w + " " + h + " " + d); + } + + return new BlockVector(x, y, z).subtract(center).toBlockVector(); + } + + public void setUnsigned(int x, int y, int z, BlockData block) { + BlockVector v = getSigned(x, y, z); + + if (block == null) { + getBlocks().remove(v); + getStates().remove(v); + } else { + getBlocks().put(v, block); + } + } + + public void setUnsigned(int x, int y, int z, Block block) { + BlockVector v = getSigned(x, y, z); + + if (block == null) { + getBlocks().remove(v); + getStates().remove(v); + } else { + BlockData data = block.getBlockData(); + getBlocks().put(v, data); + TileData state = TileData.getTileState(block); + if (state != null) { + Iris.info("Saved State " + v); + getStates().put(v, state); + } + } + } + + public int place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { + return place(x, -1, z, placer, config, rng, rdata); + } + + public int place(int x, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, CarveResult c, IrisData rdata) { + return place(x, -1, z, placer, config, rng, null, c, rdata); + } + + public int place(int x, int yv, int z, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { + return place(x, yv, z, placer, config, rng, null, null, rdata); + } + + public int place(Location loc, IObjectPlacer placer, IrisObjectPlacement config, RNG rng, IrisData rdata) { + return place(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), placer, config, rng, rdata); + } + + public int place(int x, int yv, int z, IObjectPlacer oplacer, IrisObjectPlacement config, RNG rng, BiConsumer listener, CarveResult c, IrisData rdata) { + IObjectPlacer placer = (config.getHeightmap() != null) ? new HeightmapObjectPlacer(oplacer.getEngine() == null ? IrisContext.get().getEngine() : oplacer.getEngine(), rng, x, yv, z, config, oplacer) : oplacer; + + if (rdata != null) { + // Slope condition + if (!config.getSlopeCondition().isDefault() && + !config.getSlopeCondition().isValid(rdata.getEngine().getComplex().getSlopeStream().get(x, z))) { + return -1; + } + +// if (config.getCarvingSupport().supportsSurface()) { +// int y = placer.getHighest(x, z, rdata); +// if (placer.isCarved(x, y, z)) { +// return -1; +// } +// } + + // Rotation calculation + int slopeRotationY = 0; + ProceduralStream heightStream = rdata.getEngine().getComplex().getHeightStream(); + if (config.isRotateTowardsSlope()) { + // Whichever side of the rectangle that bounds the object is lowest is the 'direction' of the slope (simply said). + double hNorth = heightStream.get(x, z + ((float) d) / 2); + double hEast = heightStream.get(x + ((float) w) / 2, z); + double hSouth = heightStream.get(x, z - ((float) d) / 2); + double hWest = heightStream.get(x - ((float) w) / 2, z); + double min = Math.min(Math.min(hNorth, hEast), Math.min(hSouth, hWest)); + if (min == hNorth) { + slopeRotationY = 0; + } else if (min == hEast) { + slopeRotationY = 90; + } else if (min == hSouth) { + slopeRotationY = 180; + } else if (min == hWest) { + slopeRotationY = 270; + } + + double newRotation = config.getRotation().getYAxis().getMin() + slopeRotationY; + if (newRotation == 0) { + config.getRotation().setYAxis(new IrisAxisRotationClamp(false, false, 0, 0, 90)); + config.getRotation().setEnabled(config.getRotation().canRotateX() || config.getRotation().canRotateZ()); + } else { + config.getRotation().setYAxis(new IrisAxisRotationClamp(true, false, newRotation, newRotation, 90)); + config.getRotation().setEnabled(true); + } + } + } + + if (config.isSmartBore()) { + ensureSmartBored(placer.isDebugSmartBore()); + } + + boolean warped = !config.getWarp().isFlat(); + boolean stilting = (config.getMode().equals(ObjectPlaceMode.STILT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT) || + config.getMode() == ObjectPlaceMode.MIN_STILT || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT || + config.getMode() == ObjectPlaceMode.CENTER_STILT); + KMap heightmap = config.getSnow() > 0 ? new KMap<>() : null; + int spinx = rng.imax() / 1000; + int spiny = rng.imax() / 1000; + int spinz = rng.imax() / 1000; + int rty = config.getRotation().rotate(new BlockVector(0, getCenter().getBlockY(), 0), spinx, spiny, spinz).getBlockY(); + int ty = config.getTranslate().translate(new BlockVector(0, getCenter().getBlockY(), 0), config.getRotation(), spinx, spiny, spinz).getBlockY(); + int y = -1; + int xx, zz; + int yrand = config.getTranslate().getYRandom(); + yrand = yrand > 0 ? rng.i(0, yrand) : yrand < 0 ? rng.i(yrand, 0) : yrand; + boolean bail = false; + + if (yv < 0) { + if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT) || config.getMode() == ObjectPlaceMode.CENTER_STILT) { + y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty; + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } + } else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) { + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); + int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); + int minX = Math.min(x - xLength, x + xLength); + int maxX = Math.max(x - xLength, x + xLength); + int zLength = (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); + int minZ = Math.min(z - zLength, z + zLength); + int maxZ = Math.max(z - zLength, z + zLength); + for (int i = minX; i <= maxX; i++) { + for (int ii = minZ; ii <= maxZ; ii++) { + int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } + if (h > y) + y = h; + } + } + } else if (config.getMode().equals(ObjectPlaceMode.FAST_MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.FAST_STILT)) { + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); + + int xRadius = (rotatedDimensions.getBlockX() / 2); + int xLength = xRadius + offset.getBlockX(); + int minX = Math.min(x - xLength, x + xLength); + int maxX = Math.max(x - xLength, x + xLength); + int zRadius = (rotatedDimensions.getBlockZ() / 2); + int zLength = zRadius + offset.getBlockZ(); + int minZ = Math.min(z - zLength, z + zLength); + int maxZ = Math.max(z - zLength, z + zLength); + + for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { + for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { + int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } + if (h > y) + y = h; + } + } + } else if (config.getMode().equals(ObjectPlaceMode.MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.MIN_STILT) { + y = rdata.getEngine().getHeight() + 1; + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); + + int xLength = (rotatedDimensions.getBlockX() / 2) + offset.getBlockX(); + int minX = Math.min(x - xLength, x + xLength); + int maxX = Math.max(x - xLength, x + xLength); + int zLength = (rotatedDimensions.getBlockZ() / 2) + offset.getBlockZ(); + int minZ = Math.min(z - zLength, z + zLength); + int maxZ = Math.max(z - zLength, z + zLength); + for (int i = minX; i <= maxX; i++) { + for (int ii = minZ; ii <= maxZ; ii++) { + int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } + if (h < y) { + y = h; + } + } + } + } else if (config.getMode().equals(ObjectPlaceMode.FAST_MIN_HEIGHT) || config.getMode() == ObjectPlaceMode.FAST_MIN_STILT) { + y = rdata.getEngine().getHeight() + 1; + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + BlockVector rotatedDimensions = config.getRotation().rotate(new BlockVector(getW(), getH(), getD()), spinx, spiny, spinz).clone(); + + int xRadius = (rotatedDimensions.getBlockX() / 2); + int xLength = xRadius + offset.getBlockX(); + int minX = Math.min(x - xLength, x + xLength); + int maxX = Math.max(x - xLength, x + xLength); + int zRadius = (rotatedDimensions.getBlockZ() / 2); + int zLength = zRadius + offset.getBlockZ(); + int minZ = Math.min(z - zLength, z + zLength); + int maxZ = Math.max(z - zLength, z + zLength); + + for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { + for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { + int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } + if (h < y) { + y = h; + } + } + } + } else if (config.getMode().equals(ObjectPlaceMode.PAINT)) { + y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty; + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } + } + } else { + y = yv; + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } + } + + if (yv >= 0 && config.isBottom()) { + y += Math.floorDiv(h, 2); + bail = placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z); + } + + if (bail) { + return -1; + } + + if (yv < 0) { + if (!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) { + return -1; + } + } + + if (c != null && Math.max(0, h + yrand + ty) + 1 >= c.getHeight()) { + return -1; + } + + if (config.isUnderwater() && y + rty + ty >= placer.getFluidHeight()) { + return -1; + } + + if (!config.getClamp().canPlace(y + rty + ty, y - rty + ty)) { + return -1; + } + + if (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty()) { + Engine engine = rdata.getEngine(); + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { + for (int j = y - Math.floorDiv(h, 2) + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) { + for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) { + PlacedObject p = engine.getObjectPlacement(i, j, k); + if (p == null) continue; + IrisObject o = p.getObject(); + if (o == null) continue; + String key = o.getLoadKey(); + if (key != null) { + if (config.getForbiddenCollisions().contains(key) && !config.getAllowedCollisions().contains(key)) { + // Iris.debug("%s collides with %s (%s / %s / %s)", getLoadKey(), key, i, j, k); + return -1; + } + } + } + } + } + } + + if (config.isBore()) { + BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); + for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { + for (int j = y - Math.floorDiv(h, 2) - config.getBoreExtendMinY() + (int) offset.getY(); j <= y + Math.floorDiv(h, 2) + config.getBoreExtendMaxY() - (h % 2 == 0 ? 1 : 0) + (int) offset.getY(); j++) { + for (int k = z - Math.floorDiv(d, 2) + (int) offset.getZ(); k <= z + Math.floorDiv(d, 2) - (d % 2 == 0 ? 1 : 0) + (int) offset.getX(); k++) { + placer.set(i, j, k, AIR); + } + } + } + } + + int lowest = Integer.MAX_VALUE; + y += yrand; + readLock.lock(); + + KMap markers = null; + + try { + if (config.getMarkers().isNotEmpty() && placer.getEngine() != null) { + markers = new KMap<>(); + for (IrisObjectMarker j : config.getMarkers()) { + IrisMarker marker = getLoader().getMarkerLoader().load(j.getMarker()); + + if (marker == null) { + continue; + } + + int max = j.getMaximumMarkers(); + + for (BlockVector i : getBlocks().k().shuffle()) { + if (max <= 0) { + break; + } + + BlockData data = getBlocks().get(i); + + for (BlockData k : j.getMark(rdata)) { + if (max <= 0) { + break; + } + + if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { + boolean a = !blocks.containsKey(new BlockVector(i.clone().add(new BlockVector(0, 1, 0)))); + boolean fff = !blocks.containsKey(new BlockVector(i.clone().add(new BlockVector(0, 2, 0)))); + + if (!marker.isEmptyAbove() || (a && fff)) { + markers.put(i, j.getMarker()); + max--; + } + } + } + } + } + } + + for (BlockVector g : getBlocks().keySet()) { + BlockData d; + TileData tile = null; + + try { + d = getBlocks().get(g); + tile = getStates().get(g); + } catch (Throwable e) { + Iris.reportError(e); + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (cme)"); + d = AIR; + } + + if (d == null) { + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (null)"); + d = AIR; + } + + BlockVector i = g.clone(); + BlockData data = d.clone(); + i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); + i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); + + if (stilting && i.getBlockY() < lowest && !B.isAir(data)) { + lowest = i.getBlockY(); + } + + if (placer.isPreventingDecay() && (data) instanceof Leaves && !((Leaves) (data)).isPersistent()) { + ((Leaves) data).setPersistent(true); + } + + for (IrisObjectReplace j : config.getEdit()) { + if (rng.chance(j.getChance())) { + for (BlockData k : j.getFind(rdata)) { + if (j.isExact() ? k.matches(data) : k.getMaterial().equals(data.getMaterial())) { + BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); + + if (newData.getMaterial() == data.getMaterial() && !(newData instanceof IrisBlockData || data instanceof IrisBlockData)) + data = data.merge(newData); + else + data = newData; + + if (newData.getMaterial() == Material.SPAWNER) { + Optional> t = j.getReplace().getTile(rng, x, y, z, rdata); + if (t.isPresent()) { + tile = t.get(); + } + } + } + } + } + } + + data = config.getRotation().rotate(data, spinx, spiny, spinz); + xx = x + (int) Math.round(i.getX()); + + int yy = y + (int) Math.round(i.getY()); + zz = z + (int) Math.round(i.getZ()); + + if (warped) { + xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z, getLoader()); + zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader()); + } + + if (yv < 0 && (config.getMode().equals(ObjectPlaceMode.PAINT)) && !B.isVineBlock(data)) { + yy = (int) Math.round(i.getY()) + Math.floorDiv(h, 2) + placer.getHighest(xx, zz, getLoader(), config.isUnderwater()); + } + + if (heightmap != null) { + Position2 pos = new Position2(xx, zz); + + if (!heightmap.containsKey(pos)) { + heightmap.put(pos, yy); + } + + if (heightmap.get(pos) < yy) { + heightmap.put(pos, yy); + } + } + + if (config.isMeld() && !placer.isSolid(xx, yy, zz)) { + continue; + } + + if ((config.isWaterloggable() || config.isUnderwater()) && yy <= placer.getFluidHeight() && data instanceof Waterlogged) { + // TODO Here + ((Waterlogged) data).setWaterlogged(true); + } + + if (B.isVineBlock(data)) { + MultipleFacing f = (MultipleFacing) data; + for (BlockFace face : f.getAllowedFaces()) { + BlockData facingBlock = placer.get(xx + face.getModX(), yy + face.getModY(), zz + face.getModZ()); + if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { + f.setFace(face, true); + } + } + } + + if (listener != null) { + listener.accept(new BlockPosition(xx, yy, zz), data); + } + + if (markers != null && markers.containsKey(g)) { + placer.getEngine().getMantle().getMantle().set(xx, yy, zz, new MatterMarker(markers.get(g))); + } + + boolean wouldReplace = B.isSolid(placer.get(xx, yy, zz)) && B.isVineBlock(data); + + if (!data.getMaterial().equals(Material.AIR) && !data.getMaterial().equals(Material.CAVE_AIR) && !wouldReplace) { + placer.set(xx, yy, zz, data); + if (tile != null) { + placer.setTile(xx, yy, zz, tile); + } + } + } + } catch (Throwable e) { + e.printStackTrace(); + Iris.reportError(e); + } + readLock.unlock(); + + if (stilting) { + readLock.lock(); + IrisStiltSettings settings = config.getStiltSettings(); + for (BlockVector g : getBlocks().keySet()) { + BlockData d; + + if (settings == null || settings.getPalette() == null) { + try { + d = getBlocks().get(g); + } catch (Throwable e) { + Iris.reportError(e); + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt cme)"); + d = AIR; + } + + if (d == null) { + Iris.warn("Failed to read block node " + g.getBlockX() + "," + g.getBlockY() + "," + g.getBlockZ() + " in object " + getLoadKey() + " (stilt null)"); + d = AIR; + } + } else + d = config.getStiltSettings().getPalette().get(rng, x, y, z, rdata); + + + BlockVector i = g.clone(); + i = config.getRotation().rotate(i.clone(), spinx, spiny, spinz).clone(); + i = config.getTranslate().translate(i.clone(), config.getRotation(), spinx, spiny, spinz).clone(); + d = config.getRotation().rotate(d, spinx, spiny, spinz); + + if (i.getBlockY() != lowest) + continue; + + for (IrisObjectReplace j : config.getEdit()) { + if (rng.chance(j.getChance())) { + for (BlockData k : j.getFind(rdata)) { + if (j.isExact() ? k.matches(d) : k.getMaterial().equals(d.getMaterial())) { + BlockData newData = j.getReplace(rng, i.getX() + x, i.getY() + y, i.getZ() + z, rdata).clone(); + + if (newData.getMaterial() == d.getMaterial()) { + d = d.merge(newData); + } else { + d = newData; + } + } + } + } + } + + if (d == null || B.isAir(d)) + continue; + + xx = x + (int) Math.round(i.getX()); + zz = z + (int) Math.round(i.getZ()); + + if (warped) { + xx += config.warp(rng, i.getX() + x, i.getY() + y, i.getZ() + z, getLoader()); + zz += config.warp(rng, i.getZ() + z, i.getY() + y, i.getX() + x, getLoader()); + } + + int highest = placer.getHighest(xx, zz, getLoader(), true); + + if ((config.isWaterloggable() || config.isUnderwater()) && highest <= placer.getFluidHeight() && d instanceof Waterlogged) + ((Waterlogged) d).setWaterlogged(true); + + if (yv >= 0 && config.isBottom()) + y += Math.floorDiv(h, 2); + + int lowerBound = highest - 1; + if (settings != null) { + lowerBound -= config.getStiltSettings().getOverStilt() - rng.i(0, config.getStiltSettings().getYRand()); + if (settings.getYMax() != 0) + lowerBound -= Math.min(config.getStiltSettings().getYMax() - (lowest + y - highest), 0); + } + for (int j = lowest + y; j > lowerBound; j--) { + if (B.isVineBlock(d)) { + MultipleFacing f = (MultipleFacing) d; + for (BlockFace face : f.getAllowedFaces()) { + BlockData facingBlock = placer.get(xx + face.getModX(), j + face.getModY(), zz + face.getModZ()); + if (B.isSolid(facingBlock) && !B.isVineBlock(facingBlock)) { + f.setFace(face, true); + } + } + } + placer.set(xx, j, zz, d); + } + + } + + readLock.unlock(); + } + + if (heightmap != null) { + RNG rngx = rng.nextParallelRNG(3468854); + + for (Position2 i : heightmap.k()) { + int vx = i.getX(); + int vy = heightmap.get(i); + int vz = i.getZ(); + + if (config.getSnow() > 0) { + int height = rngx.i(0, (int) (config.getSnow() * 7)); + placer.set(vx, vy + 1, vz, SNOW_LAYERS[Math.max(Math.min(height, 7), 0)]); + } + } + } + + return y; + } + + public IrisObject rotateCopy(IrisObjectRotation rt) { + IrisObject copy = copy(); + copy.rotate(rt, 0, 0, 0); + return copy; + } + + public void rotate(IrisObjectRotation r, int spinx, int spiny, int spinz) { + KMap d = new KMap<>(); + + for (BlockVector i : getBlocks().keySet()) { + d.put(r.rotate(i.clone(), spinx, spiny, spinz), r.rotate(getBlocks().get(i).clone(), + spinx, spiny, spinz)); + } + + KMap> dx = new KMap<>(); + + for (BlockVector i : getStates().keySet()) { + dx.put(r.rotate(i.clone(), spinx, spiny, spinz), getStates().get(i)); + } + + blocks = d; + states = dx; + } + + public void place(Location at) { + for (BlockVector i : getBlocks().keySet()) { + Block b = at.clone().add(0, getCenter().getY(), 0).add(i).getBlock(); + b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false); + + if (getStates().containsKey(i)) { + Iris.info(Objects.requireNonNull(states.get(i)).toString()); + BlockState st = b.getState(); + Objects.requireNonNull(getStates().get(i)).toBukkitTry(st); + st.update(); + } + } + } + + public void placeCenterY(Location at) { + for (BlockVector i : getBlocks().keySet()) { + Block b = at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock(); + b.setBlockData(Objects.requireNonNull(getBlocks().get(i)), false); + + if (getStates().containsKey(i)) { + Objects.requireNonNull(getStates().get(i)).toBukkitTry(b.getState()); + } + } + } + + public synchronized KMap getBlocks() { + return blocks; + } + + public synchronized KMap> getStates() { + return states; + } + + public void unplaceCenterY(Location at) { + for (BlockVector i : getBlocks().keySet()) { + at.clone().add(getCenter().getX(), getCenter().getY(), getCenter().getZ()).add(i).getBlock().setBlockData(AIR, false); + } + } + + public IrisObject scaled(double scale, IrisObjectPlacementScaleInterpolator interpolation) { + Vector sm1 = new Vector(scale - 1, scale - 1, scale - 1); + scale = Math.max(0.001, Math.min(50, scale)); + if (scale < 1) { + scale = scale - 0.0001; + } + + IrisPosition l1 = getAABB().max(); + IrisPosition l2 = getAABB().min(); + @SuppressWarnings({"unchecked", "rawtypes"}) HashMap placeBlock = new HashMap(); + + Vector center = getCenter(); + if (getH() == 2) { + center = center.setY(center.getBlockY() + 0.5); + } + if (getW() == 2) { + center = center.setX(center.getBlockX() + 0.5); + } + if (getD() == 2) { + center = center.setZ(center.getBlockZ() + 0.5); + } + + IrisObject oo = new IrisObject((int) Math.ceil((w * scale) + (scale * 2)), (int) Math.ceil((h * scale) + (scale * 2)), (int) Math.ceil((d * scale) + (scale * 2))); + + for (Map.Entry entry : blocks.entrySet()) { + BlockData bd = entry.getValue(); + placeBlock.put(entry.getKey().clone().add(HALF).subtract(center) + .multiply(scale).add(sm1).toBlockVector(), bd); + } + + for (Map.Entry entry : placeBlock.entrySet()) { + BlockVector v = entry.getKey(); + if (scale > 1) { + for (BlockVector vec : blocksBetweenTwoPoints(v.clone().add(center), v.clone().add(center).add(sm1))) { + oo.getBlocks().put(vec, entry.getValue()); + } + } else { + oo.setUnsigned(v.getBlockX(), v.getBlockY(), v.getBlockZ(), entry.getValue()); + } + } + + if (scale > 1) { + switch (interpolation) { + case TRILINEAR -> oo.trilinear((int) Math.round(scale)); + case TRICUBIC -> oo.tricubic((int) Math.round(scale)); + case TRIHERMITE -> oo.trihermite((int) Math.round(scale)); + } + } + + return oo; + } + + public void trilinear(int rad) { + KMap v = getBlocks().copy(); + KMap b = new KMap<>(); + BlockVector min = getAABB().minbv(); + BlockVector max = getAABB().maxbv(); + + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + if (IrisInterpolation.getTrilinear(x, y, z, rad, (xx, yy, zz) -> { + BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + + if (data == null || data.getMaterial().isAir()) { + return 0; + } + + return 1; + }) >= 0.5) { + b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); + } else { + b.put(new BlockVector(x, y, z), AIR); + } + } + } + } + + blocks = b; + } + + public void tricubic(int rad) { + KMap v = getBlocks().copy(); + KMap b = new KMap<>(); + BlockVector min = getAABB().minbv(); + BlockVector max = getAABB().maxbv(); + + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + if (IrisInterpolation.getTricubic(x, y, z, rad, (xx, yy, zz) -> { + BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + + if (data == null || data.getMaterial().isAir()) { + return 0; + } + + return 1; + }) >= 0.5) { + b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); + } else { + b.put(new BlockVector(x, y, z), AIR); + } + } + } + } + + blocks = b; + } + + public void trihermite(int rad) { + trihermite(rad, 0D, 0D); + } + + public void trihermite(int rad, double tension, double bias) { + KMap v = getBlocks().copy(); + KMap b = new KMap<>(); + BlockVector min = getAABB().minbv(); + BlockVector max = getAABB().maxbv(); + + for (int x = min.getBlockX(); x <= max.getBlockX(); x++) { + for (int y = min.getBlockY(); y <= max.getBlockY(); y++) { + for (int z = min.getBlockZ(); z <= max.getBlockZ(); z++) { + if (IrisInterpolation.getTrihermite(x, y, z, rad, (xx, yy, zz) -> { + BlockData data = v.get(new BlockVector((int) xx, (int) yy, (int) zz)); + + if (data == null || data.getMaterial().isAir()) { + return 0; + } + + return 1; + }, tension, bias) >= 0.5) { + b.put(new BlockVector(x, y, z), nearestBlockData(x, y, z)); + } else { + b.put(new BlockVector(x, y, z), AIR); + } + } + } + } + + blocks = b; + } + + private BlockData nearestBlockData(int x, int y, int z) { + BlockVector vv = new BlockVector(x, y, z); + BlockData r = getBlocks().get(vv); + + if (r != null && !r.getMaterial().isAir()) { + return r; + } + + double d = Double.MAX_VALUE; + + for (Map.Entry entry : blocks.entrySet()) { + BlockData dat = entry.getValue(); + + if (dat.getMaterial().isAir()) { + continue; + } + + double dx = entry.getKey().distanceSquared(vv); + + if (dx < d) { + d = dx; + r = dat; + } + } + + return r; + } + + public int volume() { + return blocks.size(); + } + + @Override + public String getFolderName() { + return "objects"; + } + + @Override + public String getTypeName() { + return "Object"; + } + + @Override + public void scanForErrors(JSONObject p, VolmitSender sender) { + } +} From 5b4265783ea9b9b9947d2bca1f47202863611b4c Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 1 May 2024 18:42:23 +0200 Subject: [PATCH 77/98] fix object w/h/d not changing with rotation --- core/src/main/java/com/volmit/iris/engine/object/IrisObject.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index ea3d115ea..0e8b3b907 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -1036,6 +1036,7 @@ public class IrisObject extends IrisRegistrant { blocks = d; states = dx; + shrinkwrap(); } public void place(Location at) { From 40163d25b800496fb1ce860c9efd70c12f57c726 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 1 May 2024 18:44:45 +0200 Subject: [PATCH 78/98] add object shink command for fixing too large/small bounding boxes for objects --- .../volmit/iris/core/commands/CommandObject.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java index ea7f07f7a..15bf87b76 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java @@ -197,6 +197,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()); From c653d852e43368eb3a8dcb970eef01031acabcac Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 1 May 2024 18:46:22 +0200 Subject: [PATCH 79/98] make jigsaw place command use the same method as normal gen --- .../iris/core/commands/CommandJigsaw.java | 2 +- .../iris/engine/jigsaw/PlannedStructure.java | 99 ++++++++++++++++--- 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java index edab02cdb..70e8e2ae3 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java @@ -59,7 +59,7 @@ public class CommandJigsaw implements DecreeExecutor { PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation()), new RNG()); VolmitSender sender = sender(); sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2)); - ps.place(world(), failed -> sender.sendMessage(failed == 0 ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place " + failed + " pieces!")); + ps.place(world(), failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!")); } @Decree(description = "Create a jigsaw piece") diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index dc2bf6b68..18c03bd9b 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -21,6 +21,7 @@ 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.core.tools.IrisToolbelt; import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.object.*; @@ -30,13 +31,17 @@ import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.math.RNG; 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 lombok.EqualsAndHashCode; import org.bukkit.Axis; +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 java.util.concurrent.atomic.AtomicInteger; -import java.util.function.IntConsumer; +import java.util.function.Consumer; @Data public class PlannedStructure { @@ -139,20 +144,86 @@ public class PlannedStructure { 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); - }, null, getData()) != -1; + }, null, getData().getEngine() != null ? getData() : eng.getData()) != -1; } - public void place(World world, IntConsumer consumer) { - AtomicInteger processed = new AtomicInteger(); - AtomicInteger failures = new AtomicInteger(); - for (PlannedPiece i : pieces) { - Iris.sq(() -> { - if (!i.place(world)) failures.incrementAndGet(); - if (processed.incrementAndGet() == pieces.size()) { - consumer.accept(failures.get()); - } - }); + public void place(World world, Consumer consumer) { + var a = IrisToolbelt.access(world); + if (a == null || a.getEngine() == null) { + consumer.accept(null); + return; } + var engine = a.getEngine(); + var engineMantle = engine.getMantle(); + var placer = new IObjectPlacer() { + @Override + public int getHighest(int x, int z, IrisData data) { + return engineMantle.getHighest(x, z, data); + } + + @Override + public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { + return engineMantle.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); + + //Prevent blocks being set in or bellow bedrock + if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return; + + 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 engineMantle.isPreventingDecay(); + } + + @Override + public boolean isCarved(int x, int y, int z) { + return engineMantle.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 engineMantle.isUnderwater(x, z); + } + + @Override + public int getFluidHeight() { + return engineMantle.getFluidHeight(); + } + + @Override + public boolean isDebugSmartBore() { + return engineMantle.isDebugSmartBore(); + } + + @Override + public void setTile(int xx, int yy, int zz, TileData tile) { + BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState(); + tile.toBukkitTry(state); + state.update(); + } + + @Override + public Engine getEngine() { + return engine; + } + }; + J.s(() -> consumer.accept(place(placer, engineMantle.getMantle(), engine))); } private void generateOutwards() { From 93469fb3b45228417bddfe1212a999b1d0d79c92 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 1 May 2024 20:01:10 +0200 Subject: [PATCH 80/98] include translate option into the bounding box of jigsaw pieces --- .../com/volmit/iris/engine/jigsaw/PlannedPiece.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index 08088ac38..cf0ef0dc0 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -97,7 +97,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; } From ace434e7b09dd489019a9fcee1dff72e92de9068 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sat, 4 May 2024 13:21:55 +0200 Subject: [PATCH 81/98] add EcoItems support --- core/build.gradle | 2 + .../iris/core/link/EcoItemsDataProvider.java | 71 +++++++++++++++++++ .../com/volmit/iris/core/link/Identifier.java | 4 ++ .../iris/core/service/ExternalDataSVC.java | 4 ++ 4 files changed, 81 insertions(+) create mode 100644 core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java diff --git a/core/build.gradle b/core/build.gradle index b15995f34..45e48457b 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -35,6 +35,7 @@ compileJava { repositories { maven { url 'https://nexus.phoenixdevt.fr/repository/maven-public/'} + maven { url 'https://repo.auxilor.io/repository/maven-public/' } } /** @@ -66,6 +67,7 @@ dependencies { 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') } diff --git a/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java b/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java new file mode 100644 index 000000000..615256e66 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/link/EcoItemsDataProvider.java @@ -0,0 +1,71 @@ +package com.volmit.iris.core.link; + +import com.volmit.iris.Iris; +import com.volmit.iris.util.collection.KList; +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 itemStack; + private WrappedField 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) throws MissingResourceException { + throw new MissingResourceException("Failed to find BlockData!", blockId.namespace(), blockId.key()); + } + + @Override + public ItemStack getItemStack(Identifier itemId) 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 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; + } +} diff --git a/core/src/main/java/com/volmit/iris/core/link/Identifier.java b/core/src/main/java/com/volmit/iris/core/link/Identifier.java index 4059016d0..3969b174b 100644 --- a/core/src/main/java/com/volmit/iris/core/link/Identifier.java +++ b/core/src/main/java/com/volmit/iris/core/link/Identifier.java @@ -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) { diff --git a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java index 00bc519c1..e70e1c1d4 100644 --- a/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/ExternalDataSVC.java @@ -64,6 +64,10 @@ public class ExternalDataSVC implements IrisService { 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()) { From fec587edad4cebe2535a0ffbf1989935bbfc9d29 Mon Sep 17 00:00:00 2001 From: RePixelatedMC <107539181+RePixelatedMC@users.noreply.github.com> Date: Tue, 7 May 2024 22:42:28 +0200 Subject: [PATCH 82/98] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index df89fcade..fadd56ffe 100644 --- a/README.md +++ b/README.md @@ -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! From 49a65521682ae1831c7783b972eb7f8d11028e35 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 10 May 2024 15:41:42 +0200 Subject: [PATCH 83/98] add forcePlace option to suppress placement checks --- .../volmit/iris/engine/object/IrisObject.java | 68 ++++++++++++------- .../engine/object/IrisObjectPlacement.java | 2 + 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java index 0e8b3b907..cb85b0d66 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObject.java @@ -506,7 +506,7 @@ public class IrisObject extends IrisRegistrant { if (rdata != null) { // Slope condition if (!config.getSlopeCondition().isDefault() && - !config.getSlopeCondition().isValid(rdata.getEngine().getComplex().getSlopeStream().get(x, z))) { + !config.getSlopeCondition().isValid(rdata.getEngine().getComplex().getSlopeStream().get(x, z)) && !config.isForcePlace()) { return -1; } @@ -571,8 +571,10 @@ public class IrisObject extends IrisRegistrant { if (yv < 0) { if (config.getMode().equals(ObjectPlaceMode.CENTER_HEIGHT) || config.getMode() == ObjectPlaceMode.CENTER_STILT) { y = (c != null ? c.getSurface() : placer.getHighest(x, z, getLoader(), config.isUnderwater())) + rty; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; + if (!config.isForcePlace()) { + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } } } else if (config.getMode().equals(ObjectPlaceMode.MAX_HEIGHT) || config.getMode().equals(ObjectPlaceMode.STILT)) { BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); @@ -586,9 +588,11 @@ public class IrisObject extends IrisRegistrant { for (int i = minX; i <= maxX; i++) { for (int ii = minZ; ii <= maxZ; ii++) { int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; + if (!config.isForcePlace()) { + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } } if (h > y) y = h; @@ -610,9 +614,11 @@ public class IrisObject extends IrisRegistrant { for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; + if (!config.isForcePlace()) { + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } } if (h > y) y = h; @@ -632,9 +638,11 @@ public class IrisObject extends IrisRegistrant { for (int i = minX; i <= maxX; i++) { for (int ii = minZ; ii <= maxZ; ii++) { int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; + if (!config.isForcePlace()) { + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } } if (h < y) { y = h; @@ -658,9 +666,11 @@ public class IrisObject extends IrisRegistrant { for (int i = minX; i <= maxX; i += Math.abs(xRadius) + 1) { for (int ii = minZ; ii <= maxZ; ii += Math.abs(zRadius) + 1) { int h = placer.getHighest(i, ii, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { - bail = true; - break; + if (!config.isForcePlace()) { + if (placer.isCarved(i, h, ii) || placer.isCarved(i, h - 1, ii) || placer.isCarved(i, h - 2, ii) || placer.isCarved(i, h - 3, ii)) { + bail = true; + break; + } } if (h < y) { y = h; @@ -669,45 +679,51 @@ public class IrisObject extends IrisRegistrant { } } else if (config.getMode().equals(ObjectPlaceMode.PAINT)) { y = placer.getHighest(x, z, getLoader(), config.isUnderwater()) + rty; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; + if (!config.isForcePlace()) { + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } } } } else { y = yv; - if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { - bail = true; + if (!config.isForcePlace()) { + if (placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z)) { + bail = true; + } } } if (yv >= 0 && config.isBottom()) { y += Math.floorDiv(h, 2); - bail = placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z); + if (!config.isForcePlace()) { + bail = placer.isCarved(x, y, z) || placer.isCarved(x, y - 1, z) || placer.isCarved(x, y - 2, z) || placer.isCarved(x, y - 3, z); + } } - if (bail) { + if (bail && !config.isForcePlace()) { return -1; } if (yv < 0) { - if (!config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) { + if (!config.isForcePlace() && !config.isUnderwater() && !config.isOnwater() && placer.isUnderwater(x, z)) { return -1; } } - if (c != null && Math.max(0, h + yrand + ty) + 1 >= c.getHeight()) { + if (!config.isForcePlace() && c != null && Math.max(0, h + yrand + ty) + 1 >= c.getHeight()) { return -1; } - if (config.isUnderwater() && y + rty + ty >= placer.getFluidHeight()) { + if (!config.isForcePlace() && config.isUnderwater() && y + rty + ty >= placer.getFluidHeight()) { return -1; } - if (!config.getClamp().canPlace(y + rty + ty, y - rty + ty)) { + if (!config.isForcePlace() && !config.getClamp().canPlace(y + rty + ty, y - rty + ty)) { return -1; } - if (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty()) { + if (!config.isForcePlace() && (!config.getAllowedCollisions().isEmpty() || !config.getForbiddenCollisions().isEmpty())) { Engine engine = rdata.getEngine(); BlockVector offset = new BlockVector(config.getTranslate().getX(), config.getTranslate().getY(), config.getTranslate().getZ()); for (int i = x - Math.floorDiv(w, 2) + (int) offset.getX(); i <= x + Math.floorDiv(w, 2) - (w % 2 == 0 ? 1 : 0) + (int) offset.getX(); i++) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java index 813ef8c4a..d03248e87 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectPlacement.java @@ -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 forbiddenCollisions = new KList<>(); + @Desc("Ignore any placement restrictions for this object") + private boolean forcePlace = false; private transient AtomicCache cache = new AtomicCache<>(); public IrisObjectPlacement toPlacement(String... place) { From b70e94dc65648c56a987b89558263194ceabea40 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 10 May 2024 15:43:01 +0200 Subject: [PATCH 84/98] make manual jigsaw place use the same calculations as normal --- .../iris/core/commands/CommandJigsaw.java | 15 ++- .../framework/placer/WorldObjectPlacer.java | 127 ++++++++++++++++++ .../iris/engine/jigsaw/PlannedPiece.java | 112 --------------- .../iris/engine/jigsaw/PlannedStructure.java | 89 +----------- 4 files changed, 141 insertions(+), 202 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java index 70e8e2ae3..710184027 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandJigsaw.java @@ -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; @@ -56,10 +57,16 @@ public class CommandJigsaw implements DecreeExecutor { IrisJigsawStructure structure ) { PrecisionStopwatch p = PrecisionStopwatch.start(); - PlannedStructure ps = new PlannedStructure(structure, new IrisPosition(player().getLocation()), new RNG()); - VolmitSender sender = sender(); - sender.sendMessage(C.GREEN + "Generated " + ps.getPieces().size() + " pieces in " + Form.duration(p.getMilliseconds(), 2)); - ps.place(world(), failed -> sender.sendMessage(failed ? C.GREEN + "Placed the structure!" : C.RED + "Failed to place the structure!")); + 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") diff --git a/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java b/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java new file mode 100644 index 000000000..16968eee5 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/framework/placer/WorldObjectPlacer.java @@ -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 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 tile) { + BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState(); + tile.toBukkitTry(state); + state.update(); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index cf0ef0dc0..862674f8b 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -20,24 +20,11 @@ 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.math.AxisAlignedBB; -import com.volmit.iris.util.math.BlockPosition; -import com.volmit.iris.util.math.RNG; import lombok.Data; import lombok.EqualsAndHashCode; -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 org.bukkit.util.BlockVector; import java.util.ArrayList; @@ -175,103 +162,4 @@ public class PlannedPiece { public boolean isFull() { return connected.size() >= piece.getConnectors().size() || isDead(); } - - public boolean 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 - } - Engine engine = a != null ? a.getEngine() : IrisContext.get().getEngine(); - - getPiece().getPlacementOptions().setTranslate(new IrisObjectTranslate()); - getPiece().getPlacementOptions().getRotation().setEnabled(false); - getPiece().getPlacementOptions().setRotateTowardsSlope(false); - int finalMinY = minY; - RNG rng = getStructure().getRng().nextParallelRNG(37555); - - // TODO: REAL CLASSES!!!!!!! - return getObject().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.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 tile) { - BlockState state = world.getBlockAt(xx, yy, zz).getState(); - tile.toBukkitTry(state); - state.update(); - } - - @Override - public Engine getEngine() { - return engine; - } - }, piece.getPlacementOptions(), rng, getData().getEngine() == null ? engine.getData() : getData()) != -1; - } } diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 18c03bd9b..846ba406a 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -21,9 +21,8 @@ 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.core.tools.IrisToolbelt; -import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.framework.Engine; +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.mantle.Mantle; @@ -34,12 +33,6 @@ 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.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 java.util.function.Consumer; @@ -119,7 +112,6 @@ public class PlannedStructure { 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; @@ -147,83 +139,8 @@ public class PlannedStructure { }, null, getData().getEngine() != null ? getData() : eng.getData()) != -1; } - public void place(World world, Consumer consumer) { - var a = IrisToolbelt.access(world); - if (a == null || a.getEngine() == null) { - consumer.accept(null); - return; - } - var engine = a.getEngine(); - var engineMantle = engine.getMantle(); - var placer = new IObjectPlacer() { - @Override - public int getHighest(int x, int z, IrisData data) { - return engineMantle.getHighest(x, z, data); - } - - @Override - public int getHighest(int x, int z, IrisData data, boolean ignoreFluid) { - return engineMantle.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); - - //Prevent blocks being set in or bellow bedrock - if (y <= world.getMinHeight() || block.getType() == Material.BEDROCK) return; - - 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 engineMantle.isPreventingDecay(); - } - - @Override - public boolean isCarved(int x, int y, int z) { - return engineMantle.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 engineMantle.isUnderwater(x, z); - } - - @Override - public int getFluidHeight() { - return engineMantle.getFluidHeight(); - } - - @Override - public boolean isDebugSmartBore() { - return engineMantle.isDebugSmartBore(); - } - - @Override - public void setTile(int xx, int yy, int zz, TileData tile) { - BlockState state = world.getBlockAt(xx, yy + world.getMinHeight(), zz).getState(); - tile.toBukkitTry(state); - state.update(); - } - - @Override - public Engine getEngine() { - return engine; - } - }; - J.s(() -> consumer.accept(place(placer, engineMantle.getMantle(), engine))); + public void place(WorldObjectPlacer placer, Consumer consumer) { + J.s(() -> consumer.accept(place(placer, placer.getMantle().getMantle(), placer.getEngine()))); } private void generateOutwards() { From 8b5d1d0298902469ae32d56678e40623f8854c9e Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 10 May 2024 15:58:26 +0200 Subject: [PATCH 85/98] rewrite jigsaw placement logic to prevent placements from being too close --- .../components/MantleJigsawComponent.java | 81 ++++++++----------- .../object/IrisJigsawStructurePlacement.java | 61 +++++++++++++- 2 files changed, 93 insertions(+), 49 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index f10ff67c7..b7d8223b7 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -18,7 +18,6 @@ package com.volmit.iris.engine.mantle.components; -import com.volmit.iris.engine.data.cache.Cache; import com.volmit.iris.engine.jigsaw.PlannedStructure; import com.volmit.iris.engine.mantle.EngineMantle; import com.volmit.iris.engine.mantle.IrisMantleComponent; @@ -35,34 +34,31 @@ 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 com.volmit.iris.util.noise.NoiseType; +import org.jetbrains.annotations.Nullable; import java.util.List; public class MantleJigsawComponent extends IrisMantleComponent { + private final CNG cng; public MantleJigsawComponent(EngineMantle engineMantle) { super(engineMantle, MantleFlag.JIGSAW); - } - - private RNG applyNoise(int x, int z) { - long seed = Cache.key(x, z) + getEngineMantle().getEngine().getSeedManager().getJigsaw(); - CNG cng = CNG.signatureFast(new RNG(seed), NoiseType.WHITE, NoiseType.GLOB); - return new RNG((long) (seed * cng.noise(x, z))); + cng = NoiseStyle.STATIC.create(new RNG(jigsaw())); } @Override public void generateLayer(MantleWriter writer, int x, int z, ChunkContext context) { - RNG rng = applyNoise(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) { + 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 poss = getDimension().getStrongholds(seed()); @@ -70,7 +66,7 @@ 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); + place(writer, pos.toIris(), structure, new RNG(seed)); return; } } @@ -80,27 +76,23 @@ public class MantleJigsawComponent extends IrisMantleComponent { KSet cachedRegions = new KSet<>(); KMap> cache = new KMap<>(); KMap distanceCache = new KMap<>(); - boolean placed = placeStructures(writer, rng, x, z, biome.getJigsawStructures(), cachedRegions, cache, distanceCache); + boolean placed = placeStructures(writer, seed, x, z, biome.getJigsawStructures(), cachedRegions, cache, distanceCache); if (!placed) - placed = placeStructures(writer, rng, x, z, region.getJigsawStructures(), cachedRegions, cache, distanceCache); + placed = placeStructures(writer, seed, x, z, region.getJigsawStructures(), cachedRegions, cache, distanceCache); if (!placed) - placeStructures(writer, rng, x, z, getDimension().getJigsawStructures(), cachedRegions, cache, distanceCache); + placeStructures(writer, seed, x, z, getDimension().getJigsawStructures(), cachedRegions, cache, distanceCache); } @ChunkCoordinates - private boolean placeStructures(MantleWriter writer, RNG rng, int x, int z, KList structures, + private boolean placeStructures(MantleWriter writer, long seed, int x, int z, KList structures, KSet cachedRegions, KMap> cache, KMap distanceCache) { - for (IrisJigsawStructurePlacement i : structures) { - if (rng.nextInt(i.getRarity()) == 0) { - if (checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache)) - continue; - IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); - IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); - if (place(writer, position, structure, rng)) - return true; - } - } - return false; + 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); } @ChunkCoordinates @@ -138,7 +130,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { public IrisJigsawStructure guess(int x, int z) { // todo The guess doesnt bring into account that the placer may return -1 // todo doesnt bring skipped placements into account - RNG rng = applyNoise(x, z); + 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); @@ -154,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 structures, long seed, int x, int z) { + return IRare.pick(structures.stream() + .filter(p -> p.shouldPlace(jigsaw(), x, z)) + .toList(), new RNG(seed).nextDouble()); } @BlockCoordinates 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(); + } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index 16eea76e8..f5a10361a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -18,20 +18,23 @@ 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.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 @@ -39,16 +42,33 @@ 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)") + private int salt = 76134; + + @Required + @MinNumber(0) + @Desc("Average distance in chunks between two neighboring generation attempts") + private int spacing = 32; + + @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 = 16; + + @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 minDistances = new KList<>(); @@ -64,4 +84,39 @@ public class IrisJigsawStructurePlacement { private int toChunks(int blocks) { return (int) Math.ceil(blocks / 16d); } + + @ChunkCoordinates + public boolean shouldPlace(long seed, int x, int z) { + 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; + } + + public enum SpreadType { + LINEAR(RNG::i), + 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); + } } From 55c0fa5f320ed5058da76dffed4f9feaf7123570 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Fri, 10 May 2024 15:58:57 +0200 Subject: [PATCH 86/98] add command to sample the distances between structures --- .../iris/core/commands/CommandStudio.java | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index bea1dcd2b..774e760b8 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java @@ -74,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; @@ -332,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> 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 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) From f68d7420e3a95139461bc3236ee6dfbe95a4e14a Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sat, 11 May 2024 12:50:40 +0200 Subject: [PATCH 87/98] woops forgot description for SpreadType --- .../iris/engine/object/IrisJigsawStructurePlacement.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index f5a10361a..ed62db9c0 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -102,8 +102,11 @@ public class IrisJigsawStructurePlacement implements IRare { 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; From 09a0f830137bf67628c8b0264c1ef6653ae02729 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sat, 11 May 2024 12:51:29 +0200 Subject: [PATCH 88/98] add terminating pool overwrite --- .../java/com/volmit/iris/engine/jigsaw/PlannedPiece.java | 2 +- .../com/volmit/iris/engine/jigsaw/PlannedStructure.java | 7 +++++-- .../com/volmit/iris/engine/object/IrisJigsawStructure.java | 4 ++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index 862674f8b..882f29f02 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -160,6 +160,6 @@ public class PlannedPiece { } public boolean isFull() { - return connected.size() >= piece.getConnectors().size() || isDead(); + return connected.size() >= piece.getConnectors().size(); } } diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 846ba406a..594f14c91 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -257,7 +257,8 @@ public class PlannedStructure { private KList getShuffledPiecesFor(IrisJigsawPieceConnector c) { KList p = new KList<>(); - for (String i : c.getPools().shuffleCopy(rng)) { + KList 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); @@ -283,7 +284,9 @@ public class PlannedStructure { } public KList getPiecesWithAvailableConnectors() { - return pieces.copy().removeWhere(PlannedPiece::isFull); + KList available = pieces.copy().removeWhere(PlannedPiece::isFull); + if (!terminating) available.removeIf(PlannedPiece::isDead); + return available; } public int getVolume() { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructure.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructure.java index 8a009364f..9d6d28506 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructure.java @@ -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; From f92234297edad90d49e42e0d1c038340b8c47edf Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 15 May 2024 18:07:12 +0200 Subject: [PATCH 89/98] add 1.20.6 support --- build.gradle | 65 +- core/build.gradle | 2 +- .../iris/core/commands/CommandObject.java | 3 +- .../java/com/volmit/iris/core/nms/INMS.java | 13 +- .../com/volmit/iris/core/nms/INMSBinding.java | 12 +- .../com/volmit/iris/core/service/WandSVC.java | 17 +- .../volmit/iris/core/wand/WandSelection.java | 4 +- .../iris/engine/object/IrisBiomeCustom.java | 7 +- .../iris/engine/object/IrisDimension.java | 7 +- .../volmit/iris/engine/object/IrisEntity.java | 4 +- .../java/com/volmit/iris/util/data/B.java | 6 +- .../volmit/iris/util/data/IrisBlockData.java | 2 +- .../iris/util/inventorygui/UIElement.java | 2 +- .../java/com/volmit/iris/util/misc/E.java | 12 + gradle/wrapper/gradle-wrapper.properties | 2 +- .../core/nms/v1_20_R4/CustomBiomeSource.java | 168 +++++ .../iris/core/nms/v1_20_R4/NMSBinding.java | 592 ++++++++++++++++++ settings.gradle | 1 + 18 files changed, 878 insertions(+), 41 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/util/misc/E.java create mode 100644 nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java create mode 100644 nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java diff --git a/build.gradle b/build.gradle index 53fc6212c..32445122c 100644 --- a/build.gradle +++ b/build.gradle @@ -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) @@ -21,12 +19,12 @@ import java.util.function.Consumer 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.2.6-1.19.2-1.20.4' -def specialSourceVersion = '1.11.0' //[NMS] +def specialSourceVersion = '1.11.4' //[NMS] // ADD YOURSELF AS A NEW LINE IF YOU WANT YOUR OWN BUILD TASK GENERATED // ======================== WINDOWS ============================= @@ -44,6 +42,7 @@ registerCustomOutputTaskUnix('PsychoLT', '/Volumes/PRO-G40/Minecraft/MinecraftDe // ============================================================== def NMS_BINDINGS = Map.of( + "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,11 +50,15 @@ def NMS_BINDINGS = Map.of( "v1_19_R2", "1.19.3-R0.1-SNAPSHOT", "v1_19_R1", "1.19.2-R0.1-SNAPSHOT" ) +def JVM_VERSION = Map.of( + "v1_20_R4", 21, +) NMS_BINDINGS.each { def key = it.key def value = it.value def nms = value.split("-")[0]; project(":nms:${key}") { + apply plugin: 'java' apply plugin: 'java-library' apply plugin: 'de.undercouch.download' @@ -64,9 +67,10 @@ NMS_BINDINGS.each { 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 buildToolsJar = new File(rootProject.layout.buildDirectory.asFile.get(), "tools/BuildTools.jar") + def specialSourceJar = new File(rootProject.layout.buildDirectory.asFile.get(), "tools/SpecialSource.jar") + def buildDir = layout.buildDirectory.asFile.get(); def buildToolsFolder = new File(buildDir, "buildtools") def specialSourceFolder = new File(buildDir, "specialsource") def buildToolsHint = new File(buildDir, "buildtools/craftbukkit-" + nms + ".jar") @@ -81,6 +85,22 @@ NMS_BINDINGS.each { def m2s = m2.getAbsolutePath(); // ======================== Building Mapped Jars ============================= + def targetJavaVersion = JVM_VERSION.getOrDefault(key, 17) + def javaVersion = JavaVersion.toVersion(targetJavaVersion) + def javaLanguageVersion = JavaLanguageVersion.of(targetJavaVersion) + project.java.sourceCompatibility = javaVersion + project.java.targetCompatibility = javaVersion + project.java.toolchain.languageVersion = javaLanguageVersion + def launcher = javaToolchains.launcherFor(java.toolchain).get() + def javaHome = launcher.executablePath.getAsFile().parentFile.parentFile.getAbsolutePath() + + tasks.withType(JavaCompile).configureEach { + options.release.set(targetJavaVersion) + } + + tasks.withType(JavaExec).configureEach { + javaLauncher.set(launcher) + } ext { executeBuildTools = new Runnable() { @@ -98,6 +118,7 @@ NMS_BINDINGS.each { if (!buildToolsHint.exists()) { buildToolsFolder.mkdirs() project.javaexec { + executable = launcher.executablePath classpath = files(buildToolsJar) workingDir = buildToolsFolder args = [ @@ -107,16 +128,14 @@ NMS_BINDINGS.each { "craftbukkit", "--remap" ] + def env = new HashMap(environment) + env.put("JAVA_HOME", javaHome) + environment = env } } } } } - tasks.register("executeBuildTools") { - doLast { - property("executeBuildTools").run(); - } - } tasks.build.doLast { //Download @@ -136,6 +155,7 @@ NMS_BINDINGS.each { //obfuscate javaexec { + executable = launcher.executablePath workingDir = specialSourceFolder classpath = files(specialSourceJar, new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-mojang.jar")) @@ -150,10 +170,14 @@ NMS_BINDINGS.each { m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-mojang.txt", "--reverse", ] + def env = new HashMap(environment) + env.put("JAVA_HOME", javaHome) + environment = env } //remap javaexec { + executable = launcher.executablePath workingDir = specialSourceFolder classpath = files(specialSourceJar, new File(m2s + "/org/spigotmc/spigot/" + value + "/spigot-" + value + "-remapped-obf.jar")) @@ -167,6 +191,9 @@ NMS_BINDINGS.each { "-m", m2s + "/org/spigotmc/minecraft-server/" + value + "/minecraft-server-" + value + "-maps-spigot.csrg" ] + def env = new HashMap(environment) + env.put("JAVA_HOME", javaHome) + environment = env } //copy copy { @@ -181,7 +208,10 @@ NMS_BINDINGS.each { } shadowJar { - NMS_BINDINGS.each {dependsOn(":nms:${it.key}:build")} + NMS_BINDINGS.each { + dependsOn(":nms:${it.key}:build") + from("${project(":nms:${it.key}").layout.buildDirectory.asFile.get()}/libs/${it.key}.jar") + } //minimize() append("plugin.yml") @@ -193,9 +223,6 @@ shadowJar { dependencies { implementation project(':core') - NMS_BINDINGS.each { - implementation project(":nms:${it.key}") - } } configurations.configureEach { @@ -284,8 +311,8 @@ 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) } @@ -308,7 +335,9 @@ NMS_BINDINGS.keySet().forEach { tasks.register("setup-${nms}") { group "iris" dependsOn(":nms:${nms}:clean") - dependsOn(":nms:${nms}:executeBuildTools") + doLast { + project(":nms:${nms}").property("executeBuildTools").run(); + } } } diff --git a/core/build.gradle b/core/build.gradle index 45e48457b..d1c25950d 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -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' diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java index ea7f07f7a..e75e2bb60 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandObject.java @@ -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 skipBlocks = Set.of(Material.GRASS, Material.SNOW, Material.VINE, Material.TORCH, Material.DEAD_BUSH, + private static final Set 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 futureBlockChanges) { diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMS.java b/core/src/main/java/com/volmit/iris/core/nms/INMS.java index dcb5e8dce..85b3778e9 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMS.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMS.java @@ -23,7 +23,13 @@ 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 REVISION = Map.of( + "1.20.5", "v1_20_R4", + "1.20.6", "v1_20_R4" + ); //@done private static final INMSBinding binding = bind(); @@ -37,7 +43,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!"); diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 5f1d114b5..321268174 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -19,9 +19,10 @@ package com.volmit.iris.core.nms; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisEntity; +import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer; @@ -36,7 +37,6 @@ import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.EntitySpawnEvent; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; @@ -112,4 +112,12 @@ public interface INMSBinding { Vector3d getBoundingbox(org.bukkit.entity.EntityType entity); Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason); + + default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) { + return json; + } + + default JSONObject fixDimension(JSONObject json) { + return json; + } } diff --git a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java index 27fc4c87a..e71392c89 100644 --- a/core/src/main/java/com/volmit/iris/core/service/WandSVC.java +++ b/core/src/main/java/com/volmit/iris/core/service/WandSVC.java @@ -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().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().add(locationToString(a), locationToString(b))); is.setItemMeta(im); @@ -311,7 +316,7 @@ 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); @@ -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)); } } } diff --git a/core/src/main/java/com/volmit/iris/core/wand/WandSelection.java b/core/src/main/java/com/volmit/iris/core/wand/WandSelection.java index 94be207d2..e2b99633b 100644 --- a/core/src/main/java/com/volmit/iris/core/wand/WandSelection.java +++ b/core/src/main/java/com/volmit/iris/core/wand/WandSelection.java @@ -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)); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java index 2b7052db4..b79f359ef 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java @@ -19,6 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMS; 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"; @@ -155,7 +158,7 @@ public class IrisBiomeCustom { j.put("spawners", spawners); } - return j.toString(4); + return INMS.get().fixCustomBiome(this, j).toString(4); } private int parseColor(String c) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index aee21600b..4a8eee4ed 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -22,6 +22,7 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; +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.*; @@ -563,7 +564,7 @@ public class IrisDimension extends IrisRegistrant { obj.put("min_y", dimensionHeight.getMin()); obj.put("height", dimensionHeight.getMax() - dimensionHeight.getMin()); obj.put("logical_height", logicalHeight); - return obj.toString(4); + return INMS.get().fixDimension(obj).toString(4); } private String generateDatapackJsonNether() { @@ -571,7 +572,7 @@ public class IrisDimension extends IrisRegistrant { obj.put("min_y", dimensionHeightNether.getMin()); obj.put("height", dimensionHeightNether.getMax() - dimensionHeightNether.getMin()); obj.put("logical_height", logicalHeightNether); - return obj.toString(4); + return INMS.get().fixDimension(obj).toString(4); } private String generateDatapackJsonEnd() { @@ -579,6 +580,6 @@ public class IrisDimension extends IrisRegistrant { obj.put("min_y", dimensionHeightEnd.getMin()); obj.put("height", dimensionHeightEnd.getMax() - dimensionHeightEnd.getMin()); obj.put("logical_height", logicalHeightEnd); - return obj.toString(4); + return INMS.get().fixDimension(obj).toString(4); } } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java index 61de43e69..6f732f449 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisEntity.java @@ -29,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; @@ -65,6 +66,7 @@ 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; @@ -386,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); } diff --git a/core/src/main/java/com/volmit/iris/util/data/B.java b/core/src/main/java/com/volmit/iris/util/data/B.java index 59d150357..d67615151 100644 --- a/core/src/main/java/com/volmit/iris/util/data/B.java +++ b/core/src/main/java/com/volmit/iris/util/data/B.java @@ -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 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, diff --git a/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java index dce36cd17..b5cd4030c 100644 --- a/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java +++ b/core/src/main/java/com/volmit/iris/util/data/IrisBlockData.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @Data -public class IrisBlockData implements BlockData{ +public class IrisBlockData implements BlockData { private final @NonNull BlockData base; private final @NotNull Identifier custom; diff --git a/core/src/main/java/com/volmit/iris/util/inventorygui/UIElement.java b/core/src/main/java/com/volmit/iris/util/inventorygui/UIElement.java index 21344d06f..acadadd37 100644 --- a/core/src/main/java/com/volmit/iris/util/inventorygui/UIElement.java +++ b/core/src/main/java/com/volmit/iris/util/inventorygui/UIElement.java @@ -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); diff --git a/core/src/main/java/com/volmit/iris/util/misc/E.java b/core/src/main/java/com/volmit/iris/util/misc/E.java new file mode 100644 index 000000000..473fa2b17 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/misc/E.java @@ -0,0 +1,12 @@ +package com.volmit.iris.util.misc; + +public class E { + + public static > T getOrDefault(Class enumClass, String name, String fallback) { + try { + return Enum.valueOf(enumClass, name); + } catch (Throwable e) { + return Enum.valueOf(enumClass, fallback); + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897b..48c0a02ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java new file mode 100644 index 000000000..d37284c25 --- /dev/null +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/CustomBiomeSource.java @@ -0,0 +1,168 @@ +package com.volmit.iris.core.nms.v1_20_R4; + +import com.mojang.serialization.MapCodec; +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.IrisBiome; +import com.volmit.iris.engine.object.IrisBiomeCustom; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.math.RNG; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.biome.Biome; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.biome.Climate; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_20_R4.CraftServer; +import org.bukkit.craftbukkit.v1_20_R4.CraftWorld; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +public class CustomBiomeSource extends BiomeSource { + + private final long seed; + private final Engine engine; + private final Registry biomeCustomRegistry; + private final Registry biomeRegistry; + private final AtomicCache registryAccess = new AtomicCache<>(); + private final RNG rng; + private final KMap> customBiomes; + + public CustomBiomeSource(long seed, Engine engine, World world) { + this.engine = engine; + this.seed = seed; + this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null); + this.biomeRegistry = ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())).registry(Registries.BIOME).orElse(null); + this.rng = new RNG(engine.getSeedManager().getBiome()); + this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine); + } + + private static List> getAllBiomes(Registry customRegistry, Registry registry, Engine engine) { + List> b = new ArrayList<>(); + + for (IrisBiome i : engine.getAllBiomes()) { + if (i.isCustom()) { + for (IrisBiomeCustom j : i.getCustomDerivitives()) { + b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry + .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); + } + } else { + b.add(NMSBinding.biomeToBiomeBase(registry, i.getVanillaDerivative())); + } + } + + return b; + } + + private static Object getFor(Class type, Object source) { + Object o = fieldFor(type, source); + + if (o != null) { + return o; + } + + return invokeFor(type, source); + } + + private static Object fieldFor(Class returns, Object in) { + return fieldForClass(returns, in.getClass(), in); + } + + private static Object invokeFor(Class returns, Object in) { + for (Method i : in.getClass().getMethods()) { + if (i.getReturnType().equals(returns)) { + i.setAccessible(true); + try { + Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + return i.invoke(in); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + return null; + } + + @SuppressWarnings("unchecked") + private static T fieldForClass(Class returnType, Class sourceType, Object in) { + for (Field i : sourceType.getDeclaredFields()) { + if (i.getType().equals(returnType)) { + i.setAccessible(true); + try { + Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + return (T) i.get(in); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return null; + } + + @Override + protected Stream> collectPossibleBiomes() { + return getAllBiomes( + ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())) + .registry(Registries.BIOME).orElse(null), + ((CraftWorld) engine.getWorld().realWorld()).getHandle().registryAccess().registry(Registries.BIOME).orElse(null), + engine).stream(); + } + private KMap> fillCustomBiomes(Registry customRegistry, Engine engine) { + KMap> m = new KMap<>(); + + for (IrisBiome i : engine.getAllBiomes()) { + if (i.isCustom()) { + for (IrisBiomeCustom j : i.getCustomDerivitives()) { + ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); + Biome biome = customRegistry.get(resourceLocation); + Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); + if (optionalBiomeKey.isEmpty()) { + Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); + continue; + } + ResourceKey biomeKey = optionalBiomeKey.get(); + Optional> optionalReferenceHolder = customRegistry.getHolder(biomeKey); + if (optionalReferenceHolder.isEmpty()) { + Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName()); + continue; + } + m.put(j.getId(), optionalReferenceHolder.get()); + } + } + } + + return m; + } + + private RegistryAccess registry() { + return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); + } + + @Override + protected MapCodec codec() { + throw new UnsupportedOperationException("Not supported"); + } + + @Override + public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { + int m = (y - engine.getMinHeight()) << 2; + IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2); + if (ib.isCustom()) { + return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId()); + } else { + org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2); + return NMSBinding.biomeToBiomeBase(biomeRegistry, v); + } + } +} \ No newline at end of file diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java new file mode 100644 index 000000000..a43ee5971 --- /dev/null +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -0,0 +1,592 @@ +package com.volmit.iris.core.nms.v1_20_R4; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Vector; +import java.util.concurrent.atomic.AtomicInteger; + +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.json.JSONArray; +import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.component.CustomData; +import net.minecraft.world.level.chunk.status.ChunkStatus; +import org.bukkit.*; +import org.bukkit.block.Biome; +import org.bukkit.block.data.BlockData; +import org.bukkit.craftbukkit.v1_20_R4.CraftChunk; +import org.bukkit.craftbukkit.v1_20_R4.CraftServer; +import org.bukkit.craftbukkit.v1_20_R4.CraftWorld; +import org.bukkit.craftbukkit.v1_20_R4.block.data.CraftBlockData; +import org.bukkit.craftbukkit.v1_20_R4.entity.CraftDolphin; +import org.bukkit.craftbukkit.v1_20_R4.inventory.CraftItemStack; +import org.bukkit.craftbukkit.v1_20_R4.util.CraftNamespacedKey; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Entity; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.generator.ChunkGenerator; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; + +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.volmit.iris.Iris; +import com.volmit.iris.core.nms.INMSBinding; +import com.volmit.iris.engine.data.cache.AtomicCache; +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.hunk.Hunk; +import com.volmit.iris.util.json.JSONObject; +import com.volmit.iris.util.mantle.Mantle; +import com.volmit.iris.util.math.Vector3d; +import com.volmit.iris.util.matter.MatterBiomeInject; +import com.volmit.iris.util.nbt.io.NBTUtil; +import com.volmit.iris.util.nbt.mca.NBTWorld; +import com.volmit.iris.util.nbt.mca.palette.*; +import com.volmit.iris.util.nbt.tag.CompoundTag; + +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.core.RegistryAccess; +import net.minecraft.core.registries.Registries; +import net.minecraft.nbt.NbtIo; +import net.minecraft.nbt.TagParser; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.biome.BiomeSource; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.LevelChunk; +import sun.misc.Unsafe; + +public class NMSBinding implements INMSBinding { + private final KMap baseBiomeCache = new KMap<>(); + private final BlockData AIR = Material.AIR.createBlockData(); + private final AtomicCache> biomeMapCache = new AtomicCache<>(); + private final AtomicCache> registryCache = new AtomicCache<>(); + private final AtomicCache> globalCache = new AtomicCache<>(); + private final AtomicCache registryAccess = new AtomicCache<>(); + private final AtomicCache byIdRef = new AtomicCache<>(); + private Field biomeStorageCache = null; + + private static Object getFor(Class type, Object source) { + Object o = fieldFor(type, source); + + if (o != null) { + return o; + } + + return invokeFor(type, source); + } + + private static Object invokeFor(Class returns, Object in) { + for (Method i : in.getClass().getMethods()) { + if (i.getReturnType().equals(returns)) { + i.setAccessible(true); + try { + Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); + return i.invoke(in); + } catch (Throwable e) { + e.printStackTrace(); + } + } + } + + return null; + } + + private static Object fieldFor(Class returns, Object in) { + return fieldForClass(returns, in.getClass(), in); + } + + @SuppressWarnings("unchecked") + private static T fieldForClass(Class returnType, Class sourceType, Object in) { + for (Field i : sourceType.getDeclaredFields()) { + if (i.getType().equals(returnType)) { + i.setAccessible(true); + try { + Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); + return (T) i.get(in); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + return null; + } + + private static Class getClassType(Class type, int ordinal) { + return type.getDeclaredClasses()[ordinal]; + } + + @Override + public boolean hasTile(Location l) { + return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; + } + + @Override + public CompoundTag serializeTile(Location location) { + BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), true); + + if (e == null) { + return null; + } + + net.minecraft.nbt.CompoundTag tag = e.saveWithFullMetadata(registry()); + return convert(tag); + } + + private CompoundTag convert(net.minecraft.nbt.CompoundTag tag) { + try { + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + DataOutputStream dos = new DataOutputStream(boas); + tag.write(dos); + dos.close(); + return (CompoundTag) NBTUtil.read(new ByteArrayInputStream(boas.toByteArray()), false).getTag(); + } catch (Throwable ex) { + ex.printStackTrace(); + } + + return null; + } + + private net.minecraft.nbt.CompoundTag convert(CompoundTag tag) { + try { + ByteArrayOutputStream boas = new ByteArrayOutputStream(); + NBTUtil.write(tag, boas, false); + DataInputStream din = new DataInputStream(new ByteArrayInputStream(boas.toByteArray())); + net.minecraft.nbt.CompoundTag c = NbtIo.read(din); + din.close(); + return c; + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; + } + + @Override + public void deserializeTile(CompoundTag c, Location pos) { + ((CraftWorld) pos.getWorld()).getHandle().getChunkAt(new BlockPos(pos.getBlockX(), 0, pos.getBlockZ())).setBlockEntityNbt(convert(c)); + } + + @Override + public CompoundTag serializeEntity(Entity location) { + return null;// TODO: + } + + @Override + public Entity deserializeEntity(CompoundTag s, Location newPosition) { + return null;// TODO: + } + + @Override + public boolean supportsCustomHeight() { + return true; + } + + private RegistryAccess registry() { + return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); + } + + private Registry getCustomBiomeRegistry() { + return registry().registry(Registries.BIOME).orElse(null); + } + + private Registry getBlockRegistry() { + return registry().registry(Registries.BLOCK).orElse(null); + } + + @Override + public Object getBiomeBaseFromId(int id) { + return getCustomBiomeRegistry().getHolder(id); + } + + @Override + public int getMinHeight(World world) { + return world.getMinHeight(); + } + + @Override + public boolean supportsCustomBiomes() { + return true; + } + + @Override + public int getTrueBiomeBaseId(Object biomeBase) { + return getCustomBiomeRegistry().getId(((Holder) biomeBase).value()); + } + + @Override + public Object getTrueBiomeBase(Location location) { + return ((CraftWorld) location.getWorld()).getHandle().getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + } + + @Override + public String getTrueBiomeBaseKey(Location location) { + return getKeyForBiomeBase(getTrueBiomeBase(location)); + } + + @Override + public Object getCustomBiomeBaseFor(String mckey) { + return getCustomBiomeRegistry().get(new ResourceLocation(mckey)); + } + + @Override + public Object getCustomBiomeBaseHolderFor(String mckey) { + return getCustomBiomeRegistry().getHolder(getTrueBiomeBaseId(getCustomBiomeRegistry().get(new ResourceLocation(mckey)))).get(); + } + + public int getBiomeBaseIdForKey(String key) { + return getCustomBiomeRegistry().getId(getCustomBiomeRegistry().get(new ResourceLocation(key))); + } + + @Override + public String getKeyForBiomeBase(Object biomeBase) { + return getCustomBiomeRegistry().getKey((net.minecraft.world.level.biome.Biome) biomeBase).getPath(); // something, not something:something + } + + @Override + public Object getBiomeBase(World world, Biome biome) { + return biomeToBiomeBase(((CraftWorld) world).getHandle() + .registryAccess().registry(Registries.BIOME).orElse(null), biome); + } + + @Override + public Object getBiomeBase(Object registry, Biome biome) { + Object v = baseBiomeCache.get(biome); + + if (v != null) { + return v; + } + //noinspection unchecked + v = biomeToBiomeBase((Registry) registry, biome); + if (v == null) { + // Ok so there is this new biome name called "CUSTOM" in Paper's new releases. + // But, this does NOT exist within CraftBukkit which makes it return an error. + // So, we will just return the ID that the plains biome returns instead. + //noinspection unchecked + return biomeToBiomeBase((Registry) registry, Biome.PLAINS); + } + baseBiomeCache.put(biome, v); + return v; + } + + @Override + public KList getBiomes() { + return new KList<>(Biome.values()).qadd(Biome.CHERRY_GROVE).qdel(Biome.CUSTOM); + } + + @Override + public boolean isBukkit() { + return true; + } + + @Override + public int getBiomeId(Biome biome) { + for (World i : Bukkit.getWorlds()) { + if (i.getEnvironment().equals(World.Environment.NORMAL)) { + Registry registry = ((CraftWorld) i).getHandle().registryAccess().registry(Registries.BIOME).orElse(null); + return registry.getId((net.minecraft.world.level.biome.Biome) getBiomeBase(registry, biome)); + } + } + + return biome.ordinal(); + } + + private MCAIdMap getBiomeMapping() { + return biomeMapCache.aquire(() -> new MCAIdMap<>() { + @NotNull + @Override + public Iterator iterator() { + return getCustomBiomeRegistry().iterator(); + } + + @Override + public int getId(net.minecraft.world.level.biome.Biome paramT) { + return getCustomBiomeRegistry().getId(paramT); + } + + @Override + public net.minecraft.world.level.biome.Biome byId(int paramInt) { + return (net.minecraft.world.level.biome.Biome) getBiomeBaseFromId(paramInt); + } + }); + } + + @NotNull + private MCABiomeContainer getBiomeContainerInterface(MCAIdMap biomeMapping, MCAChunkBiomeContainer base) { + return new MCABiomeContainer() { + @Override + public int[] getData() { + return base.writeBiomes(); + } + + @Override + public void setBiome(int x, int y, int z, int id) { + base.setBiome(x, y, z, biomeMapping.byId(id)); + } + + @Override + public int getBiome(int x, int y, int z) { + return biomeMapping.getId(base.getBiome(x, y, z)); + } + }; + } + + @Override + public MCABiomeContainer newBiomeContainer(int min, int max) { + MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max); + return getBiomeContainerInterface(getBiomeMapping(), base); + } + + @Override + public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) { + MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data); + return getBiomeContainerInterface(getBiomeMapping(), base); + } + + @Override + public int countCustomBiomes() { + AtomicInteger a = new AtomicInteger(0); + + getCustomBiomeRegistry().keySet().forEach((i) -> { + if (i.getNamespace().equals("minecraft")) { + return; + } + + a.incrementAndGet(); + Iris.debug("Custom Biome: " + i); + }); + + return a.get(); + } + + public boolean supportsDataPacks() { + return true; + } + + public void setBiomes(int cx, int cz, World world, Hunk biomes) { + LevelChunk c = ((CraftWorld) world).getHandle().getChunk(cx, cz); + biomes.iterateSync((x, y, z, b) -> c.setBiome(x, y, z, (Holder) b)); + c.setUnsaved(true); + } + + @Override + public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { + try { + ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk); + Holder biome = (Holder) somethingVeryDirty; + s.setBiome(x, y, z, biome); + } catch (IllegalAccessException e) { + Iris.reportError(e); + e.printStackTrace(); + } + } + + private Field getFieldForBiomeStorage(Object storage) { + Field f = biomeStorageCache; + + if (f != null) { + return f; + } + try { + f = storage.getClass().getDeclaredField("biome"); + f.setAccessible(true); + return f; + } catch (Throwable e) { + Iris.reportError(e); + e.printStackTrace(); + Iris.error(storage.getClass().getCanonicalName()); + } + + biomeStorageCache = f; + return null; + } + + @Override + public MCAPaletteAccess createPalette() { + MCAIdMapper registry = registryCache.aquireNasty(() -> { + Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId"); + Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT"); + Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId"); + cf.setAccessible(true); + df.setAccessible(true); + bf.setAccessible(true); + net.minecraft.core.IdMapper blockData = Block.BLOCK_STATE_REGISTRY; + int b = bf.getInt(blockData); + Object2IntMap c = (Object2IntMap) cf.get(blockData); + List d = (List) df.get(blockData); + return new MCAIdMapper(c, d, b); + }); + MCAPalette global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState())); + MCAPalettedContainer container = new MCAPalettedContainer<>(global, registry, + i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(), + i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), + ((CraftBlockData) AIR).getState()); + return new MCAWrappedPalettedContainer<>(container, + i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), + i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState()); + } + + @Override + public void injectBiomesFromMantle(Chunk e, Mantle mantle) { + ChunkAccess chunk = ((CraftChunk) e).getHandle(ChunkStatus.FULL); + AtomicInteger c = new AtomicInteger(); + AtomicInteger r = new AtomicInteger(); + mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x, y, z, b) -> { + if (b != null) { + if (b.isCustom()) { + chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get()); + c.getAndIncrement(); + } else { + chunk.setBiome(x, y, z, (Holder) getBiomeBase(e.getWorld(), b.getBiome())); + r.getAndIncrement(); + } + } + }); + } + + public ItemStack applyCustomNbt(ItemStack itemStack, KMap customNbt) throws IllegalArgumentException { + if (customNbt != null && !customNbt.isEmpty()) { + net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(itemStack); + + try { + net.minecraft.nbt.CompoundTag tag = TagParser.parseTag((new JSONObject(customNbt)).toString()); + tag.merge(s.getOrDefault(DataComponents.CUSTOM_DATA, CustomData.EMPTY).getUnsafe()); + s.set(DataComponents.CUSTOM_DATA, CustomData.of(tag)); + } catch (CommandSyntaxException var5) { + throw new IllegalArgumentException(var5); + } + + return CraftItemStack.asBukkitCopy(s); + } else { + return itemStack; + } + } + + public void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos) { + CraftDolphin cd = (CraftDolphin)dolphin; + cd.getHandle().setTreasurePos(new BlockPos(pos.getX(), pos.getY(), pos.getZ())); + cd.getHandle().setGotFish(true); + } + + public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException { + ServerLevel serverLevel = ((CraftWorld)world).getHandle(); + Class clazz = serverLevel.getChunkSource().chunkMap.generator.getClass(); + Field biomeSource = getField(clazz, BiomeSource.class); + biomeSource.setAccessible(true); + Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); + unsafeField.setAccessible(true); + Unsafe unsafe = (Unsafe)unsafeField.get(null); + CustomBiomeSource customBiomeSource = new CustomBiomeSource(seed, engine, world); + unsafe.putObject(biomeSource.get(serverLevel.getChunkSource().chunkMap.generator), unsafe.objectFieldOffset(biomeSource), customBiomeSource); + biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource); + } + + public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { + Field[] fields = EntityType.class.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { + try { + EntityType entityType = (EntityType) field.get(null); + if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { + Vector v1 = new Vector<>(); + v1.add(entityType.getHeight()); + entityType.getDimensions(); + Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); + //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); + return box; + } + } catch (IllegalAccessException e) { + Iris.error("Unable to get entity dimensions!"); + e.printStackTrace(); + } + } + } + return null; + } + + + @Override + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + + @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 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; + } + + private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { + try { + for (Field f : clazz.getDeclaredFields()) { + if (f.getType().equals(fieldType)) + return f; + } + throw new NoSuchFieldException(fieldType.getName()); + } catch (NoSuchFieldException var4) { + Class superClass = clazz.getSuperclass(); + if (superClass == null) { + throw var4; + } else { + return getField(superClass, fieldType); + } + } + } + + public static Holder biomeToBiomeBase(Registry registry, Biome biome) { + return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); + } +} diff --git a/settings.gradle b/settings.gradle index ba41bb67e..c4b3fa275 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,6 +26,7 @@ rootProject.name = 'Iris' include(':core') include( + ':nms:v1_20_R4', ':nms:v1_20_R3', ':nms:v1_20_R2', ':nms:v1_20_R1', From 8345a58f2b9d0fdeb3d493fe7a2f7a6e15e983b1 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Wed, 15 May 2024 18:11:05 +0200 Subject: [PATCH 90/98] change safeguard message --- .../java/com/volmit/iris/core/safeguard/ServerBootSFG.java | 3 ++- .../main/java/com/volmit/iris/core/safeguard/UtilsSFG.java | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java index 754744e41..f26ab913e 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/ServerBootSFG.java @@ -15,6 +15,7 @@ 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; @@ -81,7 +82,7 @@ public class ServerBootSFG { severityHigh++; } - if (getJavaVersion() != 17) { + if (!List.of(17, 21).contains(getJavaVersion())) { isJDK17 = false; joiner.add("Unsupported Java version"); severityMedium++; diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java index 11516c028..679211a56 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java @@ -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()); } } } From 6ddb0b5304826e51fa3ca59f97da2ae695c458db Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 16 May 2024 13:12:11 +0200 Subject: [PATCH 91/98] update gson library --- build.gradle | 2 +- core/src/main/resources/plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 2484924d8..a012fdd3a 100644 --- a/build.gradle +++ b/build.gradle @@ -244,7 +244,7 @@ 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:33.0.0-jre' compileOnly 'bsf:bsf:2.4.0' diff --git a/core/src/main/resources/plugin.yml b/core/src/main/resources/plugin.yml index 83ad85017..a54d30829 100644 --- a/core/src/main/resources/plugin.yml +++ b/core/src/main/resources/plugin.yml @@ -12,7 +12,7 @@ libraries: - commons-io:commons-io:2.13.0 - io.timeandspace:smoothie-map:2.0.2 - com.google.guava:guava:31.0.1-jre - - com.google.code.gson:gson:2.8.9 + - com.google.code.gson:gson:2.10.1 - org.zeroturnaround:zt-zip:1.14 - it.unimi.dsi:fastutil:8.5.6 - org.ow2.asm:asm:9.2 From 44500d6af910fb28f73b96721c690b237e9a46b7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 16 May 2024 13:12:49 +0200 Subject: [PATCH 92/98] fix translation not rotating --- .../com/volmit/iris/engine/object/IrisObjectRotation.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectRotation.java b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectRotation.java index 5b75ef725..6e8eb2a11 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisObjectRotation.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisObjectRotation.java @@ -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; } From fd10c005b0cdadc8b377b09e25a0434ab320aef4 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 16 May 2024 13:15:34 +0200 Subject: [PATCH 93/98] disable warp to prevent x/z offsets --- .../java/com/volmit/iris/engine/jigsaw/PlannedStructure.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 594f14c91..05b199a3a 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -103,6 +103,7 @@ public class PlannedStructure { options = i.getPiece().getPlacementOptions(); options.getRotation().setEnabled(false); options.setRotateTowardsSlope(false); + options.setWarp(new IrisGeneratorStyle(NoiseStyle.FLAT)); } else { options.setMode(i.getPiece().getPlaceMode()); } From 6348442962af4cd8ab9b991df8b6271aa9540982 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Thu, 16 May 2024 13:17:17 +0200 Subject: [PATCH 94/98] add y lock to fix offset when placing objects --- .../iris/engine/jigsaw/PlannedPiece.java | 52 +++++++++++++++++-- .../iris/engine/jigsaw/PlannedStructure.java | 15 +++++- .../object/IrisJigsawPieceConnector.java | 3 ++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java index 882f29f02..5a966e752 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedPiece.java @@ -22,15 +22,17 @@ import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisData; 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.math.AxisAlignedBB; +import lombok.AccessLevel; import lombok.Data; 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; @@ -45,6 +47,12 @@ public class PlannedPiece { private AxisAlignedBB box; @EqualsAndHashCode.Exclude private PlannedStructure structure; + @EqualsAndHashCode.Exclude + @Setter(AccessLevel.NONE) + private ParentConnection parent = null; + @EqualsAndHashCode.Exclude + @Setter(AccessLevel.NONE) + private KMap realPositions; public PlannedPiece(PlannedStructure structure, IrisPosition position, IrisJigsawPiece piece) { this(structure, position, piece, 0, 0, 0); @@ -66,6 +74,7 @@ public class PlannedPiece { this.object.setLoadKey(piece.getObject()); this.ogObject.setLoadKey(piece.getObject()); this.connected = new KList<>(); + this.realPositions = new KMap<>(); } @@ -124,11 +133,21 @@ public class PlannedPiece { return c; } - public boolean connect(IrisJigsawPieceConnector c) { - if (piece.getConnectors().contains(c)) { - return connected.addIfMissing(c); - } + public KList getChildConnectors() { + ParentConnection pc = getParent(); + KList 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,4 +181,27 @@ public class PlannedPiece { public boolean isFull() { return connected.size() >= piece.getConnectors().size(); } + + 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); + } + } + + 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())); + } + } } diff --git a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java index 05b199a3a..77d4157f7 100644 --- a/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java +++ b/core/src/main/java/com/volmit/iris/engine/jigsaw/PlannedStructure.java @@ -126,6 +126,17 @@ public class PlannedStructure { 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)) { @@ -134,6 +145,7 @@ public class PlannedStructure { int id = rng.i(0, Integer.MAX_VALUE); JigsawPieceContainer container = JigsawPieceContainer.toContainer(i.getPiece()); + 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); @@ -248,8 +260,7 @@ public class PlannedStructure { return false; } - piece.connect(pieceConnector); - test.connect(testConnector); + piece.connect(pieceConnector, test, testConnector); pieces.add(test); return true; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPieceConnector.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPieceConnector.java index bc5fce61b..f3afe074a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPieceConnector.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawPieceConnector.java @@ -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() + ")"; } From 52ec80d3844c09ca415df363f89f41cecde6ea00 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sun, 19 May 2024 14:40:19 +0200 Subject: [PATCH 95/98] add datapack upgrade command --- .../volmit/iris/core/ServerConfigurator.java | 9 +++- .../iris/core/commands/CommandIris.java | 11 ++++ .../com/volmit/iris/core/nms/INMSBinding.java | 11 ++-- .../iris/core/nms/datapack/DataVersion.java | 40 ++++++++++++++ .../iris/core/nms/datapack/IDataFixer.java | 11 ++++ .../nms/datapack/v1192/DataFixerV1192.java | 18 +++++++ .../nms/datapack/v1206/DataFixerV1206.java | 54 +++++++++++++++++++ .../volmit/iris/core/safeguard/UtilsSFG.java | 2 +- .../iris/engine/object/IrisBiomeCustom.java | 6 +-- .../iris/engine/object/IrisDimension.java | 32 +++++------ .../decree/handlers/DataVersionHandler.java | 36 +++++++++++++ .../iris/core/nms/v1_20_R4/NMSBinding.java | 52 +++--------------- 12 files changed, 204 insertions(+), 78 deletions(-) create mode 100644 core/src/main/java/com/volmit/iris/core/nms/datapack/DataVersion.java create mode 100644 core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java create mode 100644 core/src/main/java/com/volmit/iris/core/nms/datapack/v1192/DataFixerV1192.java create mode 100644 core/src/main/java/com/volmit/iris/core/nms/datapack/v1206/DataFixerV1206.java create mode 100644 core/src/main/java/com/volmit/iris/util/decree/handlers/DataVersionHandler.java diff --git a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java index cee4cd053..1a760d9d7 100644 --- a/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java +++ b/core/src/main/java/com/volmit/iris/core/ServerConfigurator.java @@ -21,6 +21,8 @@ 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; @@ -91,8 +93,11 @@ 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; @@ -137,7 +142,7 @@ public class ServerConfigurator { Iris.verbose(" Checking Dimension " + dim.getLoadFile().getPath()); for (File dpack : getDatapacksFolder()) { - dim.installDataPack(() -> data, dpack, ultimateMaxHeight, ultimateMinHeight); + dim.installDataPack(fixer, () -> data, dpack, ultimateMaxHeight, ultimateMinHeight); } } } diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index ad77d9268..ae9cc09be 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -20,7 +20,9 @@ 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; @@ -427,6 +429,15 @@ public class CommandIris implements DecreeExecutor { sender().sendMessage(C.GREEN + "Hotloaded settings"); } + @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 = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world") public void updateWorld( @Param(description = "The world to update", contextual = true) diff --git a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index 321268174..da90e6fb2 100644 --- a/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java +++ b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java @@ -18,11 +18,10 @@ package com.volmit.iris.core.nms; +import com.volmit.iris.core.nms.datapack.DataVersion; import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisBiomeCustom; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.mantle.Mantle; import com.volmit.iris.util.math.Vector3d; import com.volmit.iris.util.nbt.mca.palette.MCABiomeContainer; @@ -113,11 +112,7 @@ public interface INMSBinding { Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason); - default JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) { - return json; - } - - default JSONObject fixDimension(JSONObject json) { - return json; + default DataVersion getDataVersion() { + return DataVersion.V1192; } } diff --git a/core/src/main/java/com/volmit/iris/core/nms/datapack/DataVersion.java b/core/src/main/java/com/volmit/iris/core/nms/datapack/DataVersion.java new file mode 100644 index 000000000..7185b693d --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/nms/datapack/DataVersion.java @@ -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 cache = new KMap<>(); + @Getter(AccessLevel.NONE) + private final Supplier constructor; + private final String version; + private final int packFormat; + + DataVersion(String version, int packFormat, Supplier 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]; + } +} diff --git a/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java b/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java new file mode 100644 index 000000000..76a30f6e0 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/nms/datapack/IDataFixer.java @@ -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); +} diff --git a/core/src/main/java/com/volmit/iris/core/nms/datapack/v1192/DataFixerV1192.java b/core/src/main/java/com/volmit/iris/core/nms/datapack/v1192/DataFixerV1192.java new file mode 100644 index 000000000..c6bd59359 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/nms/datapack/v1192/DataFixerV1192.java @@ -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; + } +} diff --git a/core/src/main/java/com/volmit/iris/core/nms/datapack/v1206/DataFixerV1206.java b/core/src/main/java/com/volmit/iris/core/nms/datapack/v1206/DataFixerV1206.java new file mode 100644 index 000000000..48883bfa5 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/nms/datapack/v1206/DataFixerV1206.java @@ -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 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; + } +} diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java index 679211a56..659c02bdd 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java @@ -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"); diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java index b79f359ef..dd3e16af6 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisBiomeCustom.java @@ -19,7 +19,7 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMS; +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; @@ -92,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())); @@ -158,7 +158,7 @@ public class IrisBiomeCustom { j.put("spawners", spawners); } - return INMS.get().fixCustomBiome(this, j).toString(4); + return fixer.fixCustomBiome(this, j).toString(4); } private int parseColor(String c) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java index 4a8eee4ed..d2aa52db2 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisDimension.java @@ -19,16 +19,13 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.loader.IrisData; import com.volmit.iris.core.loader.IrisRegistrant; -import com.volmit.iris.core.nms.INMS; +import com.volmit.iris.core.nms.datapack.IDataFixer; 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.collection.KList; import com.volmit.iris.util.data.DataProvider; -import com.volmit.iris.util.data.Dimension; import com.volmit.iris.util.io.IO; import com.volmit.iris.util.json.JSONObject; import com.volmit.iris.util.math.Position2; @@ -44,7 +41,6 @@ import org.bukkit.Material; import org.bukkit.World.Environment; import org.bukkit.block.data.BlockData; -import java.io.DataInput; import java.io.File; import java.io.IOException; @@ -448,7 +444,7 @@ public class IrisDimension extends IrisRegistrant { return landBiomeStyle; } - public boolean installDataPack(DataProvider data, File datapacks, double ultimateMaxHeight, double ultimateMinHeight) { + public boolean installDataPack(IDataFixer fixer, DataProvider data, File datapacks, double ultimateMaxHeight, double ultimateMinHeight) { boolean write = false; boolean changed = false; @@ -468,7 +464,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(); @@ -481,7 +477,7 @@ public class IrisDimension extends IrisRegistrant { Iris.verbose(" Installing Data Pack Dimension Types: \"minecraft:overworld\", \"minecraft:the_nether\", \"minecraft:the_end\""); dimensionHeight.setMax(ultimateMaxHeight); dimensionHeight.setMin(ultimateMinHeight); - changed = writeDimensionType(changed, datapacks); + changed = writeDimensionType(fixer, changed, datapacks); } if (write) { @@ -520,13 +516,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(); @@ -538,7 +534,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(); @@ -550,7 +546,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(); @@ -559,27 +555,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 INMS.get().fixDimension(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 INMS.get().fixDimension(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 INMS.get().fixDimension(obj).toString(4); + return fixer.fixDimension(obj).toString(4); } } diff --git a/core/src/main/java/com/volmit/iris/util/decree/handlers/DataVersionHandler.java b/core/src/main/java/com/volmit/iris/util/decree/handlers/DataVersionHandler.java new file mode 100644 index 000000000..489590496 --- /dev/null +++ b/core/src/main/java/com/volmit/iris/util/decree/handlers/DataVersionHandler.java @@ -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 { + @Override + public KList 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); + } +} diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index a43ee5971..59f90620b 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -9,14 +9,10 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; -import java.util.Locale; import java.util.Vector; import java.util.concurrent.atomic.AtomicInteger; -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.json.JSONArray; +import com.volmit.iris.core.nms.datapack.DataVersion; import net.minecraft.core.component.DataComponents; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.chunk.status.ChunkStatus; @@ -528,47 +524,6 @@ public class NMSBinding implements INMSBinding { return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); } - @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 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; - } - private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { try { for (Field f : clazz.getDeclaredFields()) { @@ -589,4 +544,9 @@ public class NMSBinding implements INMSBinding { public static Holder biomeToBiomeBase(Registry registry, Biome biome) { return registry.getHolderOrThrow(ResourceKey.create(Registries.BIOME, CraftNamespacedKey.toMinecraft(biome.getKey()))); } + + @Override + public DataVersion getDataVersion() { + return DataVersion.V1205; + } } From aee0806aa8ee9f0201a0283c3fbd5045d5aff3a7 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sun, 19 May 2024 19:10:53 +0200 Subject: [PATCH 96/98] move datapack upgrade command under dev --- .../volmit/iris/core/commands/CommandDeveloper.java | 10 ++++++++++ .../com/volmit/iris/core/commands/CommandIris.java | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java index 4bb6d9e52..9439d29d6 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandDeveloper.java @@ -19,8 +19,10 @@ 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; @@ -155,6 +157,14 @@ public class CommandDeveloper implements DecreeExecutor { } + @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 updater( @Param(description = "Updater for chunks") diff --git a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java index ae9cc09be..5154ea4af 100644 --- a/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java +++ b/core/src/main/java/com/volmit/iris/core/commands/CommandIris.java @@ -429,15 +429,6 @@ public class CommandIris implements DecreeExecutor { sender().sendMessage(C.GREEN + "Hotloaded settings"); } - @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 = "Update the pack of a world (UNSAFE!)", name = "^world", aliases = "update-world") public void updateWorld( @Param(description = "The world to update", contextual = true) From bee19733902387bf693d6a21b3281b085a70d9af Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sat, 25 May 2024 15:34:25 +0200 Subject: [PATCH 97/98] fix salt not being a long --- .../iris/engine/object/IrisJigsawStructurePlacement.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index ed62db9c0..925214203 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -21,6 +21,7 @@ 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; @@ -54,7 +55,9 @@ public class IrisJigsawStructurePlacement implements IRare { @Required @Desc("The salt to use when generating the structure (to differentiate structures)") - private int salt = 76134; + @MinNumber(Long.MIN_VALUE) + @MaxNumber(Long.MAX_VALUE) + private long salt = 0; @Required @MinNumber(0) From c9b26ebaff46a4b73e971e35668d6492bfb62cf6 Mon Sep 17 00:00:00 2001 From: CrazyDev22 Date: Sat, 25 May 2024 15:34:51 +0200 Subject: [PATCH 98/98] add better backwards compat --- .../object/IrisJigsawStructurePlacement.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index 925214203..e816cfa78 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -62,12 +62,12 @@ public class IrisJigsawStructurePlacement implements IRare { @Required @MinNumber(0) @Desc("Average distance in chunks between two neighboring generation attempts") - private int spacing = 32; + 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 = 16; + private int separation = -1; @Desc("The method used to spread the structure") private SpreadType spreadType = SpreadType.TRIANGULAR; @@ -88,8 +88,21 @@ public class IrisJigsawStructurePlacement implements IRare { return (int) Math.ceil(blocks / 16d); } + private void calculateMissing(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 / 20d); + spacing = new RNG(seed).nextInt(separation, separation * 2); + } + } + @ChunkCoordinates public boolean shouldPlace(long seed, int x, int z) { + calculateMissing(seed); if (separation > spacing) { separation = spacing; Iris.warn("JigsawStructurePlacement: separation must be less than or equal to spacing");