diff --git a/build.gradle b/build.gradle index 8fc97007b..f03557fdf 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/1.20.4 - 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' @@ -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/Iris.java b/core/src/main/java/com/volmit/iris/Iris.java index 03e1fa249..e32c8239d 100644 --- a/core/src/main/java/com/volmit/iris/Iris.java +++ b/core/src/main/java/com/volmit/iris/Iris.java @@ -368,6 +368,13 @@ public class Iris extends VolmitPlugin implements Listener { return Integer.parseInt(version); } + public static String getJava() { + String javaRuntimeName = System.getProperty("java.vm.name"); + String javaRuntimeVendor = System.getProperty("java.vendor"); + String javaRuntimeVersion = System.getProperty("java.vm.version"); + return String.format("%s %s (build %s)", javaRuntimeName, javaRuntimeVendor, javaRuntimeVersion); + } + public static void reportErrorChunk(int x, int z, Throwable e, String extra) { if (IrisSettings.get().getGeneral().isDebug()) { File f = instance.getDataFile("debug", "chunk-errors", "chunk." + x + "." + z + ".txt"); @@ -806,6 +813,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.."); @@ -844,7 +852,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 898b99fca..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 @@ -20,9 +20,18 @@ 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.IrisPackBenchmarking; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.mantle.components.MantleObjectComponent; +import com.volmit.iris.engine.object.IrisBiome; +import com.volmit.iris.engine.object.IrisCave; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.engine.object.IrisEntity; +import com.volmit.iris.util.data.Dimension; import com.volmit.iris.util.decree.DecreeExecutor; import com.volmit.iris.util.decree.DecreeOrigin; import com.volmit.iris.util.decree.annotations.Decree; @@ -31,16 +40,25 @@ 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; import net.jpountz.lz4.LZ4FrameOutputStream; import org.apache.commons.lang.RandomStringUtils; import org.bukkit.Bukkit; +import org.bukkit.Chunk; +import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.EntityType; import java.io.*; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.zip.GZIPInputStream; @@ -51,36 +69,133 @@ 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(); - - Iris.info("-------------------------"); - Iris.info(C.DARK_PURPLE + "Engine Status"); - Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit()); - Iris.info(C.DARK_PURPLE + "Tectonic Loaded Plates: " + C.LIGHT_PURPLE + engine.getMantle().getLoadedRegionCount()); - Iris.info(C.DARK_PURPLE + "Tectonic Plates: " + C.LIGHT_PURPLE + engine.getMantle().getNotClearedLoadedRegions()); - Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + engine.getMantle().getToUnload()); - Iris.info(C.DARK_PURPLE + "Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration((long) engine.getMantle().getTectonicDuration())); - Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize())); - Iris.info(C.DARK_PURPLE + "LastUse Size: " + C.LIGHT_PURPLE + Form.mem(lastUseSize)); - Iris.info("-------------------------"); - } else { - Iris.info(C.RED + "Engine is null!"); + for (World world : IrisWorlds) { + Engine engine = IrisToolbelt.access(world).getEngine(); + TotalQueuedTectonicPlates += (int) engine.getMantle().getToUnload(); + TotalNotQueuedTectonicPlates += (int) engine.getMantle().getNotQueuedLoadedRegions(); + TotalTectonicPlates += engine.getMantle().getLoadedRegionCount(); + if (highestUnloadDuration <= (long) engine.getMantle().getTectonicDuration()) { + highestUnloadDuration = (long) engine.getMantle().getTectonicDuration(); + } + if (lowestUnloadDuration >= (long) engine.getMantle().getTectonicDuration()) { + lowestUnloadDuration = (long) engine.getMantle().getTectonicDuration(); + } + for (Chunk chunk : world.getLoadedChunks()) { + if (chunk.isLoaded()) { + TotalLoadedChunks++; + } + } } + Iris.info("-------------------------"); + Iris.info(C.DARK_PURPLE + "Engine Status"); + Iris.info(C.DARK_PURPLE + "Total Loaded Chunks: " + C.LIGHT_PURPLE + TotalLoadedChunks); + Iris.info(C.DARK_PURPLE + "Tectonic Limit: " + C.LIGHT_PURPLE + IrisEngineSVC.getTectonicLimit()); + Iris.info(C.DARK_PURPLE + "Tectonic Total Plates: " + C.LIGHT_PURPLE + TotalTectonicPlates); + Iris.info(C.DARK_PURPLE + "Tectonic Active Plates: " + C.LIGHT_PURPLE + TotalNotQueuedTectonicPlates); + Iris.info(C.DARK_PURPLE + "Tectonic ToUnload: " + C.LIGHT_PURPLE + TotalQueuedTectonicPlates); + Iris.info(C.DARK_PURPLE + "Lowest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(lowestUnloadDuration)); + Iris.info(C.DARK_PURPLE + "Highest Tectonic Unload Duration: " + C.LIGHT_PURPLE + Form.duration(highestUnloadDuration)); + Iris.info(C.DARK_PURPLE + "Cache Size: " + C.LIGHT_PURPLE + Form.f(IrisData.cacheSize())); + Iris.info("-------------------------"); } - @Decree(description = "Test", origin = DecreeOrigin.BOTH) - public void test() { - Iris.info("Test Developer CMD Executed"); + + @Decree(description = "Test") + public void benchmarkMantle( + @Param(description = "The world to bench", aliases = {"world"}) + World world + ) throws IOException, ClassNotFoundException { + Engine engine = IrisToolbelt.access(world).getEngine(); + int maxHeight = engine.getTarget().getHeight(); + File folder = new File(Bukkit.getWorldContainer(), world.getName()); + int c = 0; + //MCAUtil.read() + + File tectonicplates = new File(folder, "mantle"); + for (File i : Objects.requireNonNull(tectonicplates.listFiles())) { + TectonicPlate.read(maxHeight, i); + c++; + Iris.info("Loaded count: " + c ); + + } + + } + + @Decree(description = "Test") + public void packBenchmark( + @Param(description = "The pack to bench", aliases = {"pack"}) + IrisDimension dimension + ) { + Iris.info("test"); + IrisPackBenchmarking benchmark = new IrisPackBenchmarking(dimension, 1); + + } + + @Decree(description = "test") + public void test() throws NoSuchFieldException, IllegalAccessException { + IrisEngineSVC.instance.engineStatus(); + + } + + @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 the compression algorithms") 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 191169158..bf7b05b48 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; @@ -74,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; @@ -216,6 +216,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/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/commands/CommandStudio.java b/core/src/main/java/com/volmit/iris/core/commands/CommandStudio.java index 621915632..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 @@ -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.*; @@ -229,9 +230,9 @@ public class CommandStudio implements DecreeExecutor { @Decree(description = "Convert objects in the \"convert\" folder") public void convert() { Iris.service(ConversionSVC.class).check(sender()); + //IrisConverter.convertSchematics(sender()); } - @Decree(description = "Execute a script", aliases = "run", origin = DecreeOrigin.PLAYER) public void execute( @Param(description = "The script to run") 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/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/nms/INMSBinding.java b/core/src/main/java/com/volmit/iris/core/nms/INMSBinding.java index a57ac3653..5f1d114b5 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,11 @@ 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; @@ -106,5 +108,8 @@ public interface INMSBinding { void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos); void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException; + + Vector3d getBoundingbox(org.bukkit.entity.EntityType entity); + Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason); } 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 b799345c3..e99478753 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; @@ -87,6 +88,10 @@ public class NMSBinding1X implements INMSBinding { } + public Vector3d getBoundingbox() { + return null; + } + @Override public Entity spawnEntity(Location location, EntityType type, CreatureSpawnEvent.SpawnReason reason) { return location.getWorld().spawnEntity(location, type); @@ -210,6 +215,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/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 95275a759..56ee44b05 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,9 @@ package com.volmit.iris.core.pregenerator; import com.volmit.iris.Iris; +import com.volmit.iris.core.pack.IrisPack; import com.volmit.iris.core.tools.IrisPackBenchmarking; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KSet; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; @@ -30,15 +32,12 @@ import com.volmit.iris.util.math.RollingSequence; import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.J; import com.volmit.iris.util.scheduling.Looper; -import lombok.Getter; -import lombok.Setter; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; -import static com.volmit.iris.core.tools.IrisPackBenchmarking.benchmark; public class IrisPregenerator { private final PregenTask task; @@ -50,6 +49,7 @@ public class IrisPregenerator { private final RollingSequence chunksPerSecond; private final RollingSequence chunksPerMinute; private final RollingSequence regionsPerMinute; + private final KList chunksPerSecondHistory; private static AtomicInteger generated; private final AtomicInteger generatedLast; private final AtomicInteger generatedLastMinute; @@ -62,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); @@ -80,6 +78,7 @@ public class IrisPregenerator { chunksPerSecond = new RollingSequence(10); chunksPerMinute = new RollingSequence(10); regionsPerMinute = new RollingSequence(10); + chunksPerSecondHistory = new KList<>(); generated = new AtomicInteger(0); generatedLast = new AtomicInteger(0); generatedLastMinute = new AtomicInteger(0); @@ -93,6 +92,7 @@ public class IrisPregenerator { int secondGenerated = generated.get() - generatedLast.get(); generatedLast.set(generated.get()); chunksPerSecond.put(secondGenerated); + chunksPerSecondHistory.add(secondGenerated); if (minuteLatch.flip()) { int minuteGenerated = generated.get() - generatedLastMinute.get(); @@ -100,8 +100,6 @@ public class IrisPregenerator { chunksPerMinute.put(minuteGenerated); regionsPerMinute.put((double) minuteGenerated / 1024D); } - long_generatedChunks = generated.get(); - long_totalChunks = totalChunks.get(); listener.onTick(chunksPerSecond.getAverage(), chunksPerMinute.getAverage(), regionsPerMinute.getAverage(), @@ -112,10 +110,10 @@ public class IrisPregenerator { if (cl.flip()) { double percentage = ((double) generated.get() / (double) totalChunks.get()) * 100; - if(benchmark) { - Iris.info(C.GREEN +"Benchmark: " + C.WHITE + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage); + if (!IrisPackBenchmarking.benchmarkInProgress) { + Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); } else { - Iris.info("Pregen: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration((double) eta, 2), percentage); + Iris.info("Benchmarking: " + Form.f(generated.get()) + " of " + Form.f(totalChunks.get()) + " (%.0f%%) " + Form.f((int) chunksPerSecond.getAverage()) + "/s ETA: " + Form.duration(eta, 2), percentage); } } return 1000; @@ -128,17 +126,10 @@ public class IrisPregenerator { // If yes, use smooth function (which gets more accurate over time since its less sensitive to outliers) ((totalChunks.get() - generated.get()) * ((double) (M.ms() - startTime.get()) / (double) generated.get())) : // If no, use quick function (which is less accurate over time but responds better to the initial delay) - ((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000 // + ((totalChunks.get() - generated.get()) / chunksPerSecond.getAverage()) * 1000 ); } - public static long getLongGeneratedChunks() { - return long_generatedChunks; - } - public static long getLongTotalChunks() { - return long_totalChunks; - } - public void close() { shutdown.set(true); @@ -151,6 +142,11 @@ public class IrisPregenerator { task.iterateRegions((x, z) -> visitRegion(x, z, true)); task.iterateRegions((x, z) -> visitRegion(x, z, false)); shutdown(); + if (!IrisPackBenchmarking.benchmarkInProgress) { + Iris.info(C.IRIS + "Pregen stopped."); + } else { + IrisPackBenchmarking.instance.finishedBenchmark(chunksPerSecondHistory); + } } private void checkRegions() { 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 6f3f79535..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,35 +1,76 @@ package com.volmit.iris.core.service; import com.volmit.iris.Iris; +import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.engine.framework.Engine; import com.volmit.iris.engine.platform.PlatformChunkGenerator; +import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.format.C; import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.mantle.TectonicPlate; import com.volmit.iris.util.misc.getHardware; import com.volmit.iris.util.plugin.IrisService; +import com.volmit.iris.util.scheduling.ChronoLatch; import com.volmit.iris.util.scheduling.Looper; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; import org.bukkit.Bukkit; import org.bukkit.World; +import org.bukkit.event.EventHandler; +import org.bukkit.event.server.PluginDisableEvent; +import org.bukkit.event.server.ServerLoadEvent; +import org.bukkit.event.world.WorldLoadEvent; +import org.bukkit.event.world.WorldUnloadEvent; +import org.checkerframework.checker.units.qual.A; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Supplier; public class IrisEngineSVC implements IrisService { + public static IrisEngineSVC instance; + public boolean isServerShuttingDown = false; + public boolean isServerLoaded = false; private static final AtomicInteger tectonicLimit = new AtomicInteger(30); - private final ReentrantLock lastUseLock = new ReentrantLock(); - private final KMap lastUse = new KMap<>(); + private ReentrantLock lastUseLock; + private KMap lastUse; + private List IrisWorlds; private Looper cacheTicker; private Looper trimTicker; private Looper unloadTicker; + private Looper updateTicker; + private PrecisionStopwatch trimAlive; + private PrecisionStopwatch unloadAlive; + public PrecisionStopwatch trimActiveAlive; + public PrecisionStopwatch unloadActiveAlive; + private AtomicInteger TotalTectonicPlates; + private AtomicInteger TotalQueuedTectonicPlates; + private AtomicInteger TotalNotQueuedTectonicPlates; + private AtomicBoolean IsUnloadAlive; + private AtomicBoolean IsTrimAlive; + ChronoLatch cl; + public List corruptedIrisWorlds = new ArrayList<>(); @Override public void onEnable() { + this.cl = new ChronoLatch(5000); + lastUse = new KMap<>(); + lastUseLock = new ReentrantLock(); + IrisWorlds = new ArrayList<>(); + IsUnloadAlive = new AtomicBoolean(true); + IsTrimAlive = new AtomicBoolean(true); + trimActiveAlive = new PrecisionStopwatch(); + unloadActiveAlive = new PrecisionStopwatch(); + trimAlive = new PrecisionStopwatch(); + unloadAlive = new PrecisionStopwatch(); + TotalTectonicPlates = new AtomicInteger(); + TotalQueuedTectonicPlates = new AtomicInteger(); + TotalNotQueuedTectonicPlates = new AtomicInteger(); tectonicLimit.set(2); long t = getHardware.getProcessMemory(); while (t > 200) { @@ -37,15 +78,70 @@ 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(); + 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(); } + 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(); + } + + @EventHandler + public void onServerBoot(ServerLoadEvent event) { + isServerLoaded = true; + } + + @EventHandler + public void onPluginDisable(PluginDisableEvent event) { + if (event.getPlugin().equals(Iris.instance)) { + isServerShuttingDown = true; + } + } + + public void updateWorlds() { + for (World world : Bukkit.getWorlds()) { + try { + if (IrisToolbelt.access(world).getEngine() != null) { + IrisWorlds.add(world); + } + } catch (Exception e) { + // no + } + } + } + private void setup() { cacheTicker = new Looper() { @Override @@ -57,7 +153,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 +163,55 @@ 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 = 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; + } + return 1000; + } + }; + 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."); + e.printStackTrace(); return -1; } @@ -136,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(); @@ -145,6 +290,8 @@ public class IrisEngineSVC implements IrisService { } } } catch (Throwable e) { + Iris.info(C.RED + "EngineSVC: Failed to create supplier."); + e.printStackTrace(); Iris.reportError(e); } return null; 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/IrisConverter.java b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java new file mode 100644 index 000000000..fb4d344eb --- /dev/null +++ b/core/src/main/java/com/volmit/iris/core/tools/IrisConverter.java @@ -0,0 +1,395 @@ +package com.volmit.iris.core.tools; + +import com.volmit.iris.Iris; +import com.volmit.iris.engine.object.*; +import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; +import com.volmit.iris.util.nbt.io.NBTUtil; +import com.volmit.iris.util.nbt.io.NamedTag; +import com.volmit.iris.util.nbt.tag.*; +import com.volmit.iris.util.plugin.VolmitSender; +import com.volmit.iris.util.reflect.V; +import com.volmit.iris.util.scheduling.J; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; +import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.util.Vector; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicInteger; + +public class IrisConverter { + public static void convertSchematics(VolmitSender sender) { + File folder = Iris.instance.getDataFolder("convert"); + + FilenameFilter filter = (dir, name) -> name.endsWith(".schem"); + File[] fileList = folder.listFiles(filter); + ExecutorService executorService = Executors.newFixedThreadPool(1); + executorService.submit(() -> { + for (File schem : fileList) { + try { + PrecisionStopwatch p = new PrecisionStopwatch(); + boolean largeObject = false; + NamedTag tag = null; + try { + tag = NBTUtil.read(schem); + } catch (IOException e) { + Iris.info(C.RED + "Failed to read: " + schem.getName()); + throw new RuntimeException(e); + } + CompoundTag compound = (CompoundTag) tag.getTag(); + + if (compound.containsKey("Palette") && compound.containsKey("Width") && compound.containsKey("Height") && compound.containsKey("Length")) { + int objW = ((ShortTag) compound.get("Width")).getValue(); + int objH = ((ShortTag) compound.get("Height")).getValue(); + int objD = ((ShortTag) compound.get("Length")).getValue(); + int mv = objW * objH * objD; + AtomicInteger v = new AtomicInteger(0); + AtomicInteger fv = new AtomicInteger(0); + if (mv > 500_000) { + largeObject = true; + Iris.info(C.GRAY + "Converting.. "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob")); + Iris.info(C.GRAY + "- It may take a while"); + if (sender.isPlayer()) { + J.a(() -> { +// while (v.get() != mv) { +// double pr = ((double) v.get() / (double ) mv); +// sender.sendProgress(pr, "Converting"); +// J.sleep(16); +// } + }); + } + } + + CompoundTag paletteTag = (CompoundTag) compound.get("Palette"); + Map blockmap = new HashMap<>(paletteTag.size(), 0.9f); + 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[] 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 bd = blockmap.get((int) originalBlockArray[v.get()]); + if (!bd.getMaterial().isAir()) { + object.setUnsigned(w, h, d, bd); + } + v.getAndAdd(1); + } + } + } + + + try { + object.write(new File(folder, schem.getName().replace(".schem", ".iob"))); + } catch (IOException e) { + Iris.info(C.RED + "Failed to save: " + schem.getName()); + throw new RuntimeException(e); + } + if (sender.isPlayer()) { + if (largeObject) { + sender.sendMessage(C.IRIS + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis())); + } else { + sender.sendMessage(C.IRIS + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob")); + } + } + if (largeObject) { + Iris.info(C.GRAY + "Converted "+ schem.getName() + " -> " + schem.getName().replace(".schem", ".iob") + " in " + Form.duration(p.getMillis())); + } else { + Iris.info(C.GRAY + "Converted " + schem.getName() + " -> " + schem.getName().replace(".schem", ".iob")); + } + // schem.delete(); + } + } catch (Exception e) { + Iris.info(C.RED + "Failed to convert: " + schem.getName()); + if (sender.isPlayer()) { + sender.sendMessage(C.RED + "Failed to convert: " + schem.getName()); + } + e.printStackTrace(); + Iris.reportError(e); + } + } + }); + } + + public static boolean isNewPointFurther(int[] originalPoint, int[] oldPoint, int[] newPoint) { + int oX = oldPoint[1]; + int oY = oldPoint[2]; + int oZ = oldPoint[3]; + + int nX = newPoint[1]; + int nY = newPoint[2]; + int nZ = newPoint[3]; + + int orX = originalPoint[1]; + int orY = originalPoint[2]; + int orZ = originalPoint[3]; + + double oldDistance = Math.sqrt(Math.pow(oX - orX, 2) + Math.pow(oY - orY, 2) + Math.pow(oZ - orZ, 2)); + double newDistance = Math.sqrt(Math.pow(nX - orX, 2) + Math.pow(nY - orY, 2) + Math.pow(nZ - orZ, 2)); + + if (newDistance > oldDistance) { + return true; + } + return false; + } + + public static int[] getCoordinates(int pos, int obX, int obY, int obZ) { + int z = 0; + int[] coords = new int[4]; + for (int h = 0; h < obY; h++) { + for (int d = 0; d < obZ; d++) { + for (int w = 0; w < obX; w++) { + if (z == pos) { + coords[1] = w; + coords[2] = h; + coords[3] = d; + return coords; + } + z++; + } + } + } + return null; + } + + public static int getCorrectY(Map 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..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,169 +2,200 @@ package com.volmit.iris.core.tools; import com.volmit.iris.Iris; -import com.volmit.iris.core.pregenerator.IrisPregenerator; -import com.volmit.iris.core.pregenerator.LazyPregenerator; import com.volmit.iris.core.pregenerator.PregenTask; +import com.volmit.iris.engine.framework.Engine; +import com.volmit.iris.engine.object.IrisDimension; +import com.volmit.iris.util.collection.KList; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.exceptions.IrisException; -import com.volmit.iris.util.format.C; +import com.volmit.iris.util.format.Form; import com.volmit.iris.util.math.Position2; import com.volmit.iris.util.scheduling.J; -import org.apache.commons.io.FileUtils; +import com.volmit.iris.util.scheduling.PrecisionStopwatch; +import lombok.Getter; import org.bukkit.Bukkit; import java.io.File; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; - -import static com.volmit.iris.core.commands.CommandIris.BenchDimension; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.time.Clock; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.concurrent.*; public class IrisPackBenchmarking { - public static boolean loaded = false; - public static boolean benchmark = false; - static boolean cancelled = false; - static boolean pregenInProgress = false; - static long startTime; - static long totalChunks; - static long generatedChunks; - static double elapsedTimeNs; + @Getter + public static IrisPackBenchmarking instance; + public static boolean benchmarkInProgress = false; + private IrisDimension IrisDimension; + private int radius; + private boolean finished = false; + PrecisionStopwatch stopwatch; - public static void runBenchmark() { - // IrisPackBenchmarking IrisPackBenchmarking = new IrisPackBenchmarking(); - benchmark = true; - Iris.info(C.BLUE + "Benchmarking Dimension: " + C.AQUA + BenchDimension); - //progress(); - CompletableFuture future = CompletableFuture.runAsync(() -> { - Iris.info(C.GOLD + "Setting everything up.."); - try { - String BenchmarkFolder = "\\Benchmark"; - File folder = new File(BenchmarkFolder); - if (folder.exists() && folder.isDirectory()) { - FileUtils.deleteDirectory(folder); - Iris.debug("Deleted old Benchmark"); - } else { - Iris.info(C.GOLD + "Old Benchmark not found!"); - if(folder.exists()){ - Iris.info(C.RED + "FAILED To remove old Benchmark!"); - //cancelled = true; + public IrisPackBenchmarking(IrisDimension dimension, int r) { + instance = this; + this.IrisDimension = dimension; + this.radius = r; + runBenchmark(); + } - } + private void runBenchmark() { + this.stopwatch = new PrecisionStopwatch(); + ExecutorService service = Executors.newSingleThreadExecutor(); + service.submit(() -> { + Iris.info("Setting up benchmark environment "); + benchmarkInProgress = true; + File file = new File("benchmark"); + if (file.exists()) { + deleteDirectory(file.toPath()); + } + createBenchmark(); + while (!IrisToolbelt.isIrisWorld(Bukkit.getWorld("benchmark"))) { + J.sleep(1000); + Iris.debug("Iris PackBenchmark: Waiting..."); + } + Iris.info("Starting Benchmark!"); + stopwatch.begin(); + startBenchmark(); + }); + + } + + public boolean getBenchmarkInProgress() { + return benchmarkInProgress; + } + + public void finishedBenchmark(KList 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); } - } catch (Exception e) { - throw new RuntimeException(); + writer.write("- " + metrics); + writer.write("Benchmark: " + LocalDateTime.now(Clock.systemDefaultZone()) + "\n"); + writer.write("- Total time: " + time + "\n"); + writer.write("- Average CPS: " + calculateAverage(cps) + "\n"); + writer.write(" - Median CPS: " + calculateMedian(cps) + "\n"); + writer.write(" - Highest CPS: " + findHighest(cps) + "\n"); + writer.write(" - Lowest CPS: " + findLowest(cps) + "\n"); + writer.write("-----------------\n"); + Iris.info("Finished generating a report!"); + } catch (IOException e) { + Iris.error("An error occurred writing to the file."); + e.printStackTrace(); } - }).thenRun(() -> { - Iris.info(C.GOLD + "Creating Benchmark Environment"); - createBenchmark(); - - }).thenRun(() -> { - Iris.info( C.BLUE + "Benchmark Started!"); - boolean done = false; - startBenchmarkTimer(); - startBenchmark(); - basicScheduler(); - }).thenRun(() -> { - - }); - // cancelled = future.cancel(true); - try { - future.get(); - } catch (InterruptedException | ExecutionException e) { + Bukkit.getServer().unloadWorld("benchmark", true); + stopwatch.end(); + } catch (Exception e) { + Iris.error("Something has gone wrong!"); e.printStackTrace(); } } - - private static void results(){ - double averageCps = calculateAverageCPS(); - Iris.info("Benchmark Dimension: " + BenchDimension); - Iris.info("Speeds"); - Iris.info("- Average CPS: " + roundToTwoDecimalPlaces(averageCps)); - Iris.info("Duration: " + roundToTwoDecimalPlaces(elapsedTimeNs)); - - } - private static void basicScheduler() { - while (true) { - totalChunks = IrisPregenerator.getLongTotalChunks(); - generatedChunks = IrisPregenerator.getLongGeneratedChunks(); - if(totalChunks > 0) { - if (generatedChunks >= totalChunks) { - Iris.info("Benchmark Completed!"); - elapsedTimeNs = stopBenchmarkTimer(); - results(); - break; - } - } - //J.sleep(100); test - } - } - static void createBenchmark(){ + private void createBenchmark(){ try { IrisToolbelt.createWorld() - .dimension(BenchDimension) - .name("Benchmark") + .dimension(IrisDimension.getName()) + .name("benchmark") .seed(1337) .studio(false) + .benchmark(true) .create(); } catch (IrisException e) { throw new RuntimeException(e); } } - static void startBenchmark(){ + + private void startBenchmark(){ int x = 0; int z = 0; IrisToolbelt.pregenerate(PregenTask .builder() + .gui(false) .center(new Position2(x, z)) .width(5) .height(5) - .build(), Bukkit.getWorld("Benchmark") + .build(), Bukkit.getWorld("benchmark") ); } - static void startLazyBenchmark(){ - int x = 0; - int z = 0; - LazyPregenerator.LazyPregenJob pregenJob = LazyPregenerator.LazyPregenJob.builder() - //.world("Benchmark") - .healingPosition(0) - .healing(false) - .chunksPerMinute(3200) - .radiusBlocks(5000) - .position(0) - .build(); - LazyPregenerator pregenerator = new LazyPregenerator(pregenJob, new File("plugins/Iris/lazygen.json")); - pregenerator.start(); - } - public static double calculateAverageCPS() { - double elapsedTimeSec = elapsedTimeNs / 1_000_000_000.0; // Convert to seconds - return generatedChunks / elapsedTimeSec; - } - - private static void startBenchmarkTimer() { - startTime = System.nanoTime(); - } - - private static double stopBenchmarkTimer() { - long endTime = System.nanoTime(); - return (endTime - startTime) / 1_000_000_000.0; - } - - public static void deleteDirectory(File dir) { - File[] files = dir.listFiles(); - if(files != null) { - for(File file: files) { - if(file.isDirectory()) { - deleteDirectory(file); - } else { - file.delete(); - } - } + private double calculateAverage(KList list) { + double sum = 0; + for (int num : list) { + sum += num; } - dir.delete(); + return sum / list.size(); } - private static double roundToTwoDecimalPlaces(double value) { - return Double.parseDouble(String.format("%.2f", value)); + + private double calculateMedian(KList 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/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..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; @@ -298,7 +299,7 @@ public interface EngineMantle extends IObjectPlacer { default long getToUnload(){ return getMantle().getToUnload().size(); } - default long getNotClearedLoadedRegions(){ + default long getNotQueuedLoadedRegions(){ return getMantle().getLoadedRegions().size() - getMantle().getToUnload().size(); } default double getTectonicDuration(){ 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 17dd4623d..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 @@ -82,13 +82,17 @@ public class IrisCavePlacer implements IRare { } if (y == -1) { - int h = (int) caveStartHeight.get(rng, x, z, data); - int ma = breakSurface ? h : (int) (engine.getComplex().getHeightStream().get(x, z) - 9); - y = Math.min(h, ma); + if(!breakSurface) { + int eH = engine.getHeight(x, z); + if (caveStartHeight.getMax() > eH) { + caveStartHeight.setMax(eH); + } + } + y = (int) caveStartHeight.get(rng, x, z, data); } try { - cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), waterHint); + cave.generate(mantle, rng, engine, x + rng.nextInt(15), y, z + rng.nextInt(15), waterHint); } catch (Throwable e) { e.printStackTrace(); fail.set(true); 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/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(); } 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 7c00035a6..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; @@ -10,11 +39,13 @@ 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; @@ -24,43 +55,15 @@ 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; 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.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -486,8 +489,31 @@ 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; + } + @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 87b3f478c..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 @@ -1,36 +1,17 @@ package com.volmit.iris.core.nms.v1_19_R2; -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.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.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -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 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; @@ -43,22 +24,46 @@ 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; -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.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; +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.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<>(); @@ -485,8 +490,32 @@ 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; + } + @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 5c328cddc..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; @@ -10,11 +39,13 @@ 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; @@ -25,6 +56,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; @@ -32,36 +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.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -488,10 +492,32 @@ 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; + } @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 e87bc5699..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 @@ -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; @@ -47,6 +49,7 @@ import org.bukkit.entity.Dolphin; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.entity.EntityType; import org.bukkit.generator.ChunkGenerator; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; @@ -58,8 +61,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 { @@ -476,6 +481,34 @@ 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; + } + + @Override + public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { + return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); + } + public void inject(long seed, Engine engine, World world) throws NoSuchFieldException, IllegalAccessException { ServerLevel serverLevel = ((CraftWorld)world).getHandle(); Class clazz = serverLevel.getChunkSource().chunkMap.generator.getClass(); @@ -489,12 +522,6 @@ 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 91baf4efa..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; @@ -10,11 +39,13 @@ 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; @@ -26,6 +57,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; @@ -33,36 +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.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -488,8 +492,31 @@ 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; + } + @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 5e6c63702..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,5 +1,34 @@ 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; @@ -10,11 +39,13 @@ 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; @@ -26,6 +57,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; @@ -33,36 +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.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.util.Iterator; -import java.util.List; -import java.util.concurrent.atomic.AtomicInteger; - public class NMSBinding implements INMSBinding { private final KMap baseBiomeCache = new KMap<>(); private final BlockData AIR = Material.AIR.createBlockData(); @@ -488,9 +492,32 @@ 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; + } + @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); }