diff --git a/build.gradle b/build.gradle index a08c889bf..2af8b701a 100644 --- a/build.gradle +++ b/build.gradle @@ -61,9 +61,6 @@ def NMS_BINDINGS = Map.of( "v1_20_R3", "1.20.4-R0.1-SNAPSHOT", "v1_20_R2", "1.20.2-R0.1-SNAPSHOT", "v1_20_R1", "1.20.1-R0.1-SNAPSHOT", - "v1_19_R3", "1.19.4-R0.1-SNAPSHOT", - "v1_19_R2", "1.19.3-R0.1-SNAPSHOT", - "v1_19_R1", "1.19.2-R0.1-SNAPSHOT" ) def JVM_VERSION = Map.of() NMS_BINDINGS.each { nms -> @@ -131,7 +128,7 @@ allprojects { annotationProcessor 'org.projectlombok:lombok:1.18.36' // Shaded - implementation 'com.dfsek:Paralithic:0.4.0' + implementation 'com.dfsek:paralithic:0.8.1' implementation 'io.papermc:paperlib:1.0.5' implementation "net.kyori:adventure-text-minimessage:4.17.0" implementation 'net.kyori:adventure-platform-bukkit:4.3.4' 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 49988ca0f..e22ebff27 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 @@ -265,6 +265,17 @@ public class CommandIris implements DecreeExecutor { return; } sender().sendMessage(C.GREEN + "Removing world: " + world.getName()); + + if (!IrisToolbelt.evacuate(world)) { + sender().sendMessage(C.RED + "Failed to evacuate world: " + world.getName()); + return; + } + + if (!Bukkit.unloadWorld(world, false)) { + sender().sendMessage(C.RED + "Failed to unload world: " + world.getName()); + return; + } + try { if (IrisToolbelt.removeWorld(world)) { sender().sendMessage(C.GREEN + "Successfully removed " + world.getName() + " from bukkit.yml"); @@ -277,27 +288,32 @@ public class CommandIris implements DecreeExecutor { } IrisToolbelt.evacuate(world, "Deleting world"); deletingWorld = true; - Bukkit.unloadWorld(world, false); - int retries = 12; - if (delete) { + if (!delete) { + deletingWorld = false; + return; + } + VolmitSender sender = sender(); + J.a(() -> { + int retries = 12; + if (deleteDirectory(world.getWorldFolder())) { - sender().sendMessage(C.GREEN + "Successfully removed world folder"); + sender.sendMessage(C.GREEN + "Successfully removed world folder"); } else { while(true){ if (deleteDirectory(world.getWorldFolder())){ - sender().sendMessage(C.GREEN + "Successfully removed world folder"); + sender.sendMessage(C.GREEN + "Successfully removed world folder"); break; } retries--; if (retries == 0){ - sender().sendMessage(C.RED + "Failed to remove world folder"); + sender.sendMessage(C.RED + "Failed to remove world folder"); break; } J.sleep(3000); } } - } - deletingWorld = false; + deletingWorld = false; + }); } public static boolean deleteDirectory(File dir) { diff --git a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java index c9284681c..cfff91b62 100644 --- a/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java +++ b/core/src/main/java/com/volmit/iris/core/safeguard/UtilsSFG.java @@ -37,7 +37,7 @@ public class UtilsSFG { } if (ServerBootSFG.unsuportedversion) { Iris.safeguard(C.RED + "Server Version"); - Iris.safeguard(C.RED + "- Iris only supports 1.19.2 > 1.21.3"); + Iris.safeguard(C.RED + "- Iris only supports 1.20.1 > 1.21.4"); } if (!ServerBootSFG.passedserversoftware) { Iris.safeguard(C.YELLOW + "Unsupported Server Software"); diff --git a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java index 25e44ca9e..6ba27c542 100644 --- a/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java +++ b/core/src/main/java/com/volmit/iris/engine/mantle/components/MantleJigsawComponent.java @@ -90,8 +90,10 @@ public class MantleJigsawComponent extends IrisMantleComponent { private boolean placeStructures(MantleWriter writer, long seed, int x, int z, KList structures, KSet cachedRegions, KMap> cache, KMap distanceCache) { IrisJigsawStructurePlacement i = pick(structures, seed, x, z); - if (i == null || checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache)) - return false; + try { + if (i == null || checkMinDistances(i.collectMinDistances(), x, z, cachedRegions, cache, distanceCache)) + return false; + } catch (Throwable ignored) {} RNG rng = new RNG(seed); IrisPosition position = new IrisPosition((x << 4) + rng.nextInt(15), 0, (z << 4) + rng.nextInt(15)); IrisJigsawStructure structure = getData().getJigsawStructureLoader().load(i.getStructure()); @@ -159,7 +161,7 @@ public class MantleJigsawComponent extends IrisMantleComponent { @ChunkCoordinates private IrisJigsawStructurePlacement pick(List structures, long seed, int x, int z) { return IRare.pick(structures.stream() - .filter(p -> p.shouldPlace(getDimension().getJigsawStructureDivisor(), jigsaw(), x, z)) + .filter(p -> p.shouldPlace(getData(), getDimension().getJigsawStructureDivisor(), jigsaw(), x, z)) .toList(), new RNG(seed).nextDouble()); } diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisExpression.java b/core/src/main/java/com/volmit/iris/engine/object/IrisExpression.java index 98cb0ed0f..0fbd1c48a 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisExpression.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisExpression.java @@ -24,6 +24,7 @@ import com.dfsek.paralithic.eval.parser.Scope; import com.volmit.iris.Iris; import com.volmit.iris.core.loader.IrisRegistrant; import com.volmit.iris.engine.data.cache.AtomicCache; +import com.volmit.iris.engine.object.IrisExpressionFunction.FunctionContext; import com.volmit.iris.engine.object.annotations.ArrayType; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; @@ -46,12 +47,14 @@ import lombok.experimental.Accessors; @Data @EqualsAndHashCode(callSuper = false) public class IrisExpression extends IrisRegistrant { - private static final Parser parser = new Parser(); - @ArrayType(type = IrisExpressionLoad.class, min = 1) @Desc("Variables to use in this expression") private KList variables = new KList<>(); + @ArrayType(type = IrisExpressionFunction.class, min = 1) + @Desc("Functions to use in this expression") + private KList functions = new KList<>(); + @Required @Desc("The expression. Inherited variables are x, y and z. Avoid using those variable names.") private String expression; @@ -62,6 +65,7 @@ public class IrisExpression extends IrisRegistrant { private Expression expression() { return expressionCache.aquire(() -> { Scope scope = new Scope(); // Create variable scope. This scope can hold both constants and invocation variables. + Parser parser = new Parser(); try { for (IrisExpressionLoad i : variables) { @@ -76,6 +80,12 @@ public class IrisExpression extends IrisRegistrant { Iris.error("Script Variable load error in " + getLoadFile().getPath()); } + for (IrisExpressionFunction f : functions) { + if (!f.isValid()) continue; + f.setData(getLoader()); + parser.registerFunction(f.getName(), f); + } + try { return parser.parse(getExpression(), scope); } catch (Throwable e) { @@ -103,7 +113,7 @@ public class IrisExpression extends IrisRegistrant { g[m++] = z; g[m] = -1; - return expression().evaluate(g); + return expression().evaluate(new FunctionContext(rng), g); } public double evaluate(RNG rng, double x, double y, double z) { @@ -117,7 +127,7 @@ public class IrisExpression extends IrisRegistrant { g[m++] = y; g[m] = z; - return expression().evaluate(g); + return expression().evaluate(new FunctionContext(rng), g); } @Override diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionFunction.java b/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionFunction.java new file mode 100644 index 000000000..d56cbec7c --- /dev/null +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionFunction.java @@ -0,0 +1,101 @@ +package com.volmit.iris.engine.object; + +import com.dfsek.paralithic.functions.dynamic.Context; +import com.dfsek.paralithic.functions.dynamic.DynamicFunction; +import com.dfsek.paralithic.node.Statefulness; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.engine.object.annotations.Desc; +import com.volmit.iris.engine.object.annotations.MinNumber; +import com.volmit.iris.engine.object.annotations.Required; +import com.volmit.iris.engine.object.annotations.Snippet; +import com.volmit.iris.util.collection.KMap; +import com.volmit.iris.util.math.RNG; +import lombok.*; +import lombok.experimental.Accessors; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Snippet("expression-function") +@Accessors(chain = true) +@NoArgsConstructor +@AllArgsConstructor +@Desc("Represents a function to use in your expression. Do not set the name to x, y, or z, also don't duplicate names.") +@Data +@EqualsAndHashCode(callSuper = false) +public class IrisExpressionFunction implements DynamicFunction { + @Required + @Desc("The function to assign this value to. Do not set the name to x, y, or z") + private String name; + + @Desc("If defined, this variable will use a generator style as it's value") + private IrisGeneratorStyle styleValue = null; + + @Desc("If defined, iris will use an internal stream from the engine as it's value") + private IrisEngineStreamType engineStreamValue = null; + + @MinNumber(2) + @Desc("Number of arguments for the function") + private int args = 2; + + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private transient final KMap cache = new KMap<>(); + private transient IrisData data; + + public boolean isValid() { + return styleValue != null || engineStreamValue != null; + } + + @Override + public int getArgNumber() { + if (engineStreamValue != null) return 2; + return Math.max(args, 2); + } + + @NotNull + @Override + public Statefulness statefulness() { + return Statefulness.STATEFUL; + } + + @Override + public double eval(double... doubles) { + return 0; + } + + @Override + public double eval(@Nullable Context raw, double... args) { + return cache.computeIfAbsent((FunctionContext) raw, context -> { + assert context != null; + if (engineStreamValue != null) { + var stream = engineStreamValue.get(data.getEngine()); + return d -> stream.get(d[0], d[1]); + } + + if (styleValue != null) { + return styleValue.createNoCache(context.rng, data)::noise; + } + + return d -> Double.NaN; + }).eval(args); + } + + public record FunctionContext(@NonNull RNG rng) implements Context { + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) return false; + FunctionContext that = (FunctionContext) o; + return rng.getSeed() == that.rng.getSeed(); + } + + @Override + public int hashCode() { + return Long.hashCode(rng.getSeed()); + } + } + + @FunctionalInterface + private interface Provider { + double eval(double... args); + } +} diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionLoad.java b/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionLoad.java index 9a7b8a26a..c539cc3f3 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionLoad.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisExpressionLoad.java @@ -23,12 +23,11 @@ import com.volmit.iris.engine.data.cache.AtomicCache; import com.volmit.iris.engine.object.annotations.Desc; import com.volmit.iris.engine.object.annotations.Required; import com.volmit.iris.engine.object.annotations.Snippet; +import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.math.RNG; +import com.volmit.iris.util.noise.CNG; import com.volmit.iris.util.stream.ProceduralStream; -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import lombok.*; import lombok.experimental.Accessors; @Snippet("expression-load") @@ -57,6 +56,9 @@ public class IrisExpressionLoad { private transient AtomicCache> streamCache = new AtomicCache<>(); private transient AtomicCache valueCache = new AtomicCache<>(); + @Getter(AccessLevel.NONE) + @Setter(AccessLevel.NONE) + private transient final KMap styleCache = new KMap<>(); public double getValue(RNG rng, IrisData data, double x, double z) { if (engineValue != null) { @@ -68,7 +70,8 @@ public class IrisExpressionLoad { } if (styleValue != null) { - return styleValue.create(rng, data).noise(x, z); + return styleCache.computeIfAbsent(rng.getSeed(), k -> styleValue.createNoCache(new RNG(k), data)) + .noise(x, z); } return staticValue; @@ -84,7 +87,8 @@ public class IrisExpressionLoad { } if (styleValue != null) { - return styleValue.create(rng, data).noise(x, y, z); + return styleCache.computeIfAbsent(rng.getSeed(), k -> styleValue.createNoCache(new RNG(k), data)) + .noise(x, y, z); } return staticValue; diff --git a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java index 40603ce85..5f0220321 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java +++ b/core/src/main/java/com/volmit/iris/engine/object/IrisJigsawStructurePlacement.java @@ -19,13 +19,8 @@ package com.volmit.iris.engine.object; import com.volmit.iris.Iris; -import com.volmit.iris.engine.object.annotations.ArrayType; -import com.volmit.iris.engine.object.annotations.Desc; -import com.volmit.iris.engine.object.annotations.MaxNumber; -import com.volmit.iris.engine.object.annotations.MinNumber; -import com.volmit.iris.engine.object.annotations.RegistryListResource; -import com.volmit.iris.engine.object.annotations.Required; -import com.volmit.iris.engine.object.annotations.Snippet; +import com.volmit.iris.core.loader.IrisData; +import com.volmit.iris.engine.object.annotations.*; import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.documentation.ChunkCoordinates; @@ -54,6 +49,7 @@ public class IrisJigsawStructurePlacement implements IRare { private int rarity = 100; @Required + @DependsOn({"spacing", "separation"}) @Desc("The salt to use when generating the structure (to differentiate structures)") @MinNumber(Long.MIN_VALUE) @MaxNumber(Long.MAX_VALUE) @@ -61,16 +57,26 @@ public class IrisJigsawStructurePlacement implements IRare { @Required @MinNumber(0) + @DependsOn({"salt", "separation"}) @Desc("Average distance in chunks between two neighboring generation attempts") private int spacing = -1; @Required @MinNumber(0) + @DependsOn({"salt", "spacing"}) @Desc("Minimum distance in chunks between two neighboring generation attempts\nThe maximum distance of two neighboring generation attempts is 2*spacing - separation") private int separation = -1; @Desc("The method used to spread the structure") - private SpreadType spreadType = SpreadType.TRIANGULAR; + private SpreadType spreadType = SpreadType.LINEAR; + + @DependsOn({"spreadType"}) + @Desc("The noise style to use when spreadType is set to 'NOISE'\nThis ignores the spacing and separation parameters") + private IrisGeneratorStyle style = new IrisGeneratorStyle(); + + @DependsOn({"spreadType", "style"}) + @Desc("Threshold for noise style") + private double threshold = 0.5; @ArrayType(type = IrisJigsawMinDistance.class) @Desc("List of minimum distances to check for") @@ -89,20 +95,29 @@ public class IrisJigsawStructurePlacement implements IRare { } private void calculateMissing(double divisor, long seed) { - seed = seed + hashCode(); + if (salt != 0 && separation > 0 && spacing > 0) + return; + seed *= (long) structure.hashCode() * rarity; if (salt == 0) { - salt = new RNG(seed).nextLong(Integer.MIN_VALUE, Integer.MAX_VALUE); + salt = new RNG(seed).l(Integer.MIN_VALUE, Integer.MAX_VALUE); } if (separation == -1 || spacing == -1) { separation = (int) Math.round(rarity / divisor); - spacing = new RNG(seed).nextInt(separation, separation * 2); + spacing = new RNG(seed).i(separation, separation * 2); } } @ChunkCoordinates - public boolean shouldPlace(double divisor, long seed, int x, int z) { + public boolean shouldPlace(IrisData data, double divisor, long seed, int x, int z) { calculateMissing(divisor, seed); + if (spreadType != SpreadType.NOISE) + return shouldPlaceSpread(seed, x, z); + + return style.create(new RNG(seed + salt), data).noise(x, z) > threshold; + } + + private boolean shouldPlaceSpread(long seed, int x, int z) { if (separation > spacing) { separation = spacing; Iris.warn("JigsawStructurePlacement: separation must be less than or equal to spacing"); @@ -123,7 +138,9 @@ public class IrisJigsawStructurePlacement implements IRare { @Desc("Linear spread") LINEAR(RNG::i), @Desc("Triangular spread") - TRIANGULAR((rng, bound) -> (rng.i(bound) + rng.i(bound)) / 2); + TRIANGULAR((rng, bound) -> (rng.i(bound) + rng.i(bound)) / 2), + @Desc("Noise based spread\nThis ignores the spacing and separation parameters") + NOISE((rng, bound) -> 0); private final SpreadMethod method; SpreadType(SpreadMethod method) { diff --git a/core/src/main/java/com/volmit/iris/engine/object/TileData.java b/core/src/main/java/com/volmit/iris/engine/object/TileData.java index 094c48b00..9c0809545 100644 --- a/core/src/main/java/com/volmit/iris/engine/object/TileData.java +++ b/core/src/main/java/com/volmit/iris/engine/object/TileData.java @@ -35,7 +35,6 @@ import java.io.IOException; @SuppressWarnings("ALL") @Getter -@ToString @EqualsAndHashCode @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -137,4 +136,9 @@ public class TileData implements Cloneable { clone.properties = properties.copy(); //TODO make a deep copy return clone; } + + @Override + public String toString() { + return material.getKey() + gson.toJson(properties); + } } diff --git a/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java b/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java index 0dc17c5ad..b3377ebe8 100644 --- a/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java +++ b/core/src/main/java/com/volmit/iris/util/data/registry/RegistryUtil.java @@ -1,15 +1,18 @@ package com.volmit.iris.util.data.registry; import com.volmit.iris.core.nms.container.Pair; +import com.volmit.iris.engine.data.cache.AtomicCache; import lombok.NonNull; import org.bukkit.Bukkit; import org.bukkit.Keyed; import org.bukkit.NamespacedKey; import org.bukkit.Registry; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -20,6 +23,7 @@ import java.util.stream.Collectors; @SuppressWarnings("unchecked") public class RegistryUtil { + private static final AtomicCache registryLookup = new AtomicCache<>(); private static final Map, Map> KEYED_REGISTRY = new HashMap<>(); private static final Map, Map> ENUM_REGISTRY = new HashMap<>(); private static final Map, Registry> REGISTRY = new HashMap<>(); @@ -43,7 +47,7 @@ public class RegistryUtil { if (keys.length == 0) throw new IllegalArgumentException("Need at least one key"); Registry registry = null; if (Keyed.class.isAssignableFrom(typeClass)) { - registry = Bukkit.getRegistry(typeClass.asSubclass(Keyed.class)); + registry = getRegistry(typeClass.asSubclass(Keyed.class)); } if (registry == null) { registry = REGISTRY.computeIfAbsent(typeClass, t -> Arrays.stream(Registry.class.getDeclaredFields()) @@ -150,4 +154,56 @@ public class RegistryUtil { }; } } + + @Nullable + private static Registry getRegistry(@NotNull Class type) { + RegistryLookup lookup = registryLookup.aquire(() -> { + RegistryLookup bukkit; + try { + bukkit = Bukkit::getRegistry; + } catch (Throwable ignored) { + bukkit = null; + } + return new DefaultRegistryLookup(bukkit); + }); + return lookup.find(type); + } + + private interface RegistryLookup { + @Nullable + Registry find(@NonNull Class type); + } + + private static class DefaultRegistryLookup implements RegistryLookup { + private final RegistryLookup bukkit; + private final Map registries; + + private DefaultRegistryLookup(RegistryLookup bukkit) { + this.bukkit = bukkit; + registries = Arrays.stream(Registry.class.getDeclaredFields()) + .filter(field -> Modifier.isPublic(field.getModifiers()) && Modifier.isStatic(field.getModifiers())) + .filter(field -> Registry.class.isAssignableFrom(field.getType())) + .map(field -> { + var type = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; + try { + return new Pair<>(type, field.get(null)); + } catch (Throwable e) { + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toMap(Pair::getA, Pair::getB, (a, b) -> a)); + } + + @Nullable + @Override + public Registry find(@NonNull Class type) { + if (bukkit == null) return (Registry) registries.get(type); + try { + return bukkit.find(type); + } catch (Throwable e) { + return (Registry) registries.get(type); + } + } + } } diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java deleted file mode 100644 index a24e62d85..000000000 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/CustomBiomeSource.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R1; - -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.engine.object.IrisBiomeCustom; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.math.RNG; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R1.CraftServer; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -public class CustomBiomeSource extends BiomeSource { - private final long seed; - private final Engine engine; - private final Registry biomeCustomRegistry; - private final Registry biomeRegistry; - private final AtomicCache registryAccess = new AtomicCache<>(); - private final RNG rng; - private final KMap> customBiomes; - - public CustomBiomeSource(long seed, Engine engine, World world) { - super(getAllBiomes( - ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())) - .registry(Registry.BIOME_REGISTRY).orElse(null), - ((CraftWorld) world).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null), - engine)); - this.engine = engine; - this.seed = seed; - this.biomeCustomRegistry = registry().registry(Registry.BIOME_REGISTRY).orElse(null); - this.biomeRegistry = ((CraftWorld) world).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null); - this.rng = new RNG(engine.getSeedManager().getBiome()); - this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine); - } - - private static List> getAllBiomes(Registry customRegistry, Registry registry, Engine engine) { - List> b = new ArrayList<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); - } - } else { - b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative())); - } - } - - return b; - } - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - private KMap> fillCustomBiomes(Registry customRegistry, Engine engine) { - KMap> m = new KMap<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); - } - } - } - - return m; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - @Override - protected Codec codec() { - throw new UnsupportedOperationException("Not supported"); - } - - @Override - public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { - int m = (y - engine.getMinHeight()) << 2; - IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2); - if (ib.isCustom()) { - return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId()); - } else { - org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2); - return CraftBlock.biomeToBiomeBase(biomeRegistry, v); - } - } -} \ No newline at end of file diff --git a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/IrisChunkGenerator.java b/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/IrisChunkGenerator.java deleted file mode 100644 index df23a6d05..000000000 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/IrisChunkGenerator.java +++ /dev/null @@ -1,257 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R1; - -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.ResultLocator; -import com.volmit.iris.engine.framework.WrongEngineBroException; -import com.volmit.iris.engine.object.IrisJigsawStructure; -import com.volmit.iris.engine.object.IrisJigsawStructurePlacement; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.mantle.MantleFlag; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.reflect.WrappedField; -import net.minecraft.core.*; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.tags.TagKey; -import net.minecraft.util.random.WeightedRandomList; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.MobSpawnSettings; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.structure.Structure; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.generator.CustomChunkGenerator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; - -public class IrisChunkGenerator extends CustomChunkGenerator { - private static final WrappedField BIOME_SOURCE; - private final ChunkGenerator delegate; - private final Engine engine; - private final KMap, KSet> structures = new KMap<>(); - - public IrisChunkGenerator(ChunkGenerator delegate, long seed, Engine engine, World world) { - super(((CraftWorld) world).getHandle(), edit(delegate, new CustomBiomeSource(seed, engine, world)), null); - this.delegate = delegate; - this.engine = engine; - var dimension = engine.getDimension(); - - KSet placements = new KSet<>(); - addAll(dimension.getJigsawStructures(), placements); - for (var region : dimension.getAllRegions(engine)) { - addAll(region.getJigsawStructures(), placements); - for (var biome : region.getAllBiomes(engine)) - addAll(biome.getJigsawStructures(), placements); - } - var stronghold = dimension.getStronghold(); - if (stronghold != null) - placements.add(engine.getData().getJigsawStructureLoader().load(stronghold)); - placements.removeIf(Objects::isNull); - - var registry = ((CraftWorld) world).getHandle().registryAccess().registry(Registry.STRUCTURE_REGISTRY).orElseThrow(); - for (var s : placements) { - try { - String raw = s.getStructureKey(); - if (raw == null) continue; - boolean tag = raw.startsWith("#"); - if (tag) raw = raw.substring(1); - - var location = new ResourceLocation(raw); - if (!tag) { - structures.computeIfAbsent(ResourceKey.create(Registry.STRUCTURE_REGISTRY, location), k -> new KSet<>()).add(s.getLoadKey()); - continue; - } - - var key = TagKey.create(Registry.STRUCTURE_REGISTRY, location); - var set = registry.getTag(key).orElse(null); - if (set == null) { - Iris.error("Could not find structure tag: " + raw); - continue; - } - for (var holder : set) { - var resourceKey = holder.unwrapKey().orElse(null); - if (resourceKey == null) continue; - structures.computeIfAbsent(resourceKey, k -> new KSet<>()).add(s.getLoadKey()); - } - } catch (Throwable e) { - Iris.error("Failed to load structure: " + s.getLoadKey()); - e.printStackTrace(); - } - } - } - - private void addAll(KList placements, KSet structures) { - if (placements == null) return; - placements.stream() - .map(IrisJigsawStructurePlacement::getStructure) - .map(engine.getData().getJigsawStructureLoader()::load) - .filter(Objects::nonNull) - .forEach(structures::add); - } - - @Override - public @Nullable Pair> findNearestMapStructure(ServerLevel level, HolderSet holders, BlockPos pos, int radius, boolean findUnexplored) { - if (engine.getDimension().isDisableExplorerMaps()) - return null; - - KMap> structures = new KMap<>(); - for (var holder : holders) { - if (holder == null) continue; - var key = holder.unwrapKey().orElse(null); - var set = this.structures.get(key); - if (set == null) continue; - for (var structure : set) { - structures.put(structure, holder); - } - } - if (structures.isEmpty()) - return null; - - var locator = ResultLocator.locateStructure(structures.keySet()) - .then((e, p , s) -> structures.get(s.getLoadKey())); - if (findUnexplored) - locator = locator.then((e, p, s) -> e.getMantle().getMantle().getChunk(p.getX(), p.getZ()).isFlagged(MantleFlag.DISCOVERED) ? null : s); - - try { - var result = locator.find(engine, new Position2(pos.getX() >> 4, pos.getZ() >> 4), radius * 10L, i -> {}, false).get(); - if (result == null) return null; - var blockPos = new BlockPos(result.getBlockX(), 0, result.getBlockZ()); - return Pair.of(blockPos, result.obj()); - } catch (WrongEngineBroException | ExecutionException | InterruptedException e) { - return null; - } - } - - @Override - protected Codec codec() { - return Codec.unit(null); - } - - @Override - public ChunkGenerator getDelegate() { - if (delegate instanceof CustomChunkGenerator chunkGenerator) - return chunkGenerator.getDelegate(); - return delegate; - } - - @Override - public int getMinY() { - return delegate.getMinY(); - } - - @Override - public int getSeaLevel() { - return delegate.getSeaLevel(); - } - - @Override - public void createStructures(RegistryAccess iregistrycustom, RandomState randomstate, StructureManager structuremanager, ChunkAccess ichunkaccess, StructureTemplateManager structuretemplatemanager, long i) { - delegate.createStructures(iregistrycustom, randomstate, structuremanager, ichunkaccess, structuretemplatemanager, i); - } - - @Override - public void buildSurface(WorldGenRegion regionlimitedworldaccess, StructureManager structuremanager, RandomState randomstate, ChunkAccess ichunkaccess) { - delegate.buildSurface(regionlimitedworldaccess, structuremanager, randomstate, ichunkaccess); - } - - @Override - public void applyCarvers(WorldGenRegion regionlimitedworldaccess, long seed, RandomState randomstate, BiomeManager biomemanager, StructureManager structuremanager, ChunkAccess ichunkaccess, GenerationStep.Carving worldgenstage_features) { - delegate.applyCarvers(regionlimitedworldaccess, seed, randomstate, biomemanager, structuremanager, ichunkaccess, worldgenstage_features); - } - - @Override - public CompletableFuture fillFromNoise(Executor executor, Blender blender, RandomState randomstate, StructureManager structuremanager, ChunkAccess ichunkaccess) { - return delegate.fillFromNoise(executor, blender, randomstate, structuremanager, ichunkaccess); - } - - @Override - public int getBaseHeight(int i, int j, Heightmap.Types heightmap_type, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseHeight(i, j, heightmap_type, levelheightaccessor, randomstate); - } - - @Override - public WeightedRandomList getMobsAt(Holder holder, StructureManager structuremanager, MobCategory enumcreaturetype, BlockPos blockposition) { - return delegate.getMobsAt(holder, structuremanager, enumcreaturetype, blockposition); - } - - @Override - public void applyBiomeDecoration(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager) { - delegate.applyBiomeDecoration(generatoraccessseed, ichunkaccess, structuremanager); - } - - @Override - public void addDebugScreenInfo(List list, RandomState randomstate, BlockPos blockposition) { - delegate.addDebugScreenInfo(list, randomstate, blockposition); - } - - @Override - public void spawnOriginalMobs(WorldGenRegion regionlimitedworldaccess) { - delegate.spawnOriginalMobs(regionlimitedworldaccess); - } - - @Override - public int getSpawnHeight(LevelHeightAccessor levelheightaccessor) { - return delegate.getSpawnHeight(levelheightaccessor); - } - - @Override - public int getGenDepth() { - return delegate.getGenDepth(); - } - - @Override - public NoiseColumn getBaseColumn(int i, int j, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseColumn(i, j, levelheightaccessor, randomstate); - } - - static { - Field biomeSource = null; - for (Field field : ChunkGenerator.class.getDeclaredFields()) { - if (!field.getType().equals(BiomeSource.class)) - continue; - biomeSource = field; - break; - } - if (biomeSource == null) - throw new RuntimeException("Could not find biomeSource field in ChunkGenerator!"); - BIOME_SOURCE = new WrappedField<>(ChunkGenerator.class, biomeSource.getName()); - } - - private static ChunkGenerator edit(ChunkGenerator generator, BiomeSource source) { - try { - BIOME_SOURCE.set(generator, source); - if (generator instanceof CustomChunkGenerator custom) - BIOME_SOURCE.set(custom.getDelegate(), source); - - return generator; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} 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 deleted file mode 100644 index 935af6a14..000000000 --- a/nms/v1_19_R1/src/main/java/com/volmit/iris/core/nms/v1_19_R1/NMSBinding.java +++ /dev/null @@ -1,626 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R1; - -import java.awt.Color; -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.Map; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - -import com.mojang.datafixers.util.Pair; -import com.volmit.iris.core.nms.container.BiomeColor; -import com.volmit.iris.util.scheduling.J; -import net.minecraft.nbt.*; -import net.minecraft.nbt.Tag; -import net.minecraft.server.commands.data.BlockDataAccessor; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.EntityBlock; -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.CraftBlockState; -import org.bukkit.craftbukkit.v1_19_R1.block.CraftBlockStates; -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.Contract; -import org.jetbrains.annotations.NotNull; - -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMSBinding; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.json.JSONObject; -import com.volmit.iris.util.mantle.Mantle; -import com.volmit.iris.util.math.Vector3d; -import com.volmit.iris.util.matter.MatterBiomeInject; -import com.volmit.iris.util.nbt.io.NBTUtil; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.nbt.mca.palette.*; -import com.volmit.iris.util.nbt.tag.CompoundTag; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; -import sun.misc.Unsafe; - -public class NMSBinding implements INMSBinding { - private final KMap baseBiomeCache = new KMap<>(); - private final BlockData AIR = Material.AIR.createBlockData(); - private final AtomicCache> biomeMapCache = new AtomicCache<>(); - private final AtomicCache> registryCache = new AtomicCache<>(); - private final AtomicCache> globalCache = new AtomicCache<>(); - private final AtomicCache registryAccess = new AtomicCache<>(); - private final AtomicCache byIdRef = new AtomicCache<>(); - private Field biomeStorageCache = null; - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - private static Class getClassType(Class type, int ordinal) { - return type.getDeclaredClasses()[ordinal]; - } - - @Override - public boolean hasTile(Material material) { - return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material)); - } - - @Override - public boolean hasTile(Location l) { - return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; - } - - @Override - @SuppressWarnings("unchecked") - public KMap serializeTile(Location location) { - BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false); - - if (e == null) { - return null; - } - - net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(); - return (KMap) convertFromTag(tag, 0, 64); - } - - @Contract(value = "null, _, _ -> null", pure = true) - private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) { - if (tag == null || depth > maxDepth) return null; - if (tag instanceof CollectionTag collection) { - KList list = new KList<>(); - - for (Object i : collection) { - if (i instanceof net.minecraft.nbt.Tag t) - list.add(convertFromTag(t, depth + 1, maxDepth)); - else list.add(i); - } - return list; - } - if (tag instanceof net.minecraft.nbt.CompoundTag compound) { - KMap map = new KMap<>(); - - for (String key : compound.getAllKeys()) { - var child = compound.get(key); - if (child == null) continue; - var value = convertFromTag(child, depth + 1, maxDepth); - if (value == null) continue; - map.put(key, value); - } - return map; - } - if (tag instanceof NumericTag numeric) - return numeric.getAsNumber(); - return tag.getAsString(); - } - - @Override - public void deserializeTile(KMap map, Location pos) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64); - var level = ((CraftWorld) pos.getWorld()).getHandle(); - var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); - J.s(() -> merge(level, blockPos, tag)); - } - - private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) { - var blockEntity = level.getBlockEntity(blockPos); - if (blockEntity == null) { - Iris.warn("[NMS] BlockEntity not found at " + blockPos); - var state = level.getBlockState(blockPos); - if (!state.hasBlockEntity()) - return; - - blockEntity = ((EntityBlock) state.getBlock()) - .newBlockEntity(blockPos, state); - } - var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); - } - - private Tag convertToTag(Object object, int depth, int maxDepth) { - if (object == null || depth > maxDepth) return EndTag.INSTANCE; - if (object instanceof Map map) { - var tag = new net.minecraft.nbt.CompoundTag(); - for (var i : map.entrySet()) { - tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof List list) { - var tag = new net.minecraft.nbt.ListTag(); - for (var i : list) { - tag.add(convertToTag(i, depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof Byte number) return ByteTag.valueOf(number); - if (object instanceof Short number) return ShortTag.valueOf(number); - if (object instanceof Integer number) return IntTag.valueOf(number); - if (object instanceof Long number) return LongTag.valueOf(number); - if (object instanceof Float number) return FloatTag.valueOf(number); - if (object instanceof Double number) return DoubleTag.valueOf(number); - if (object instanceof String string) return StringTag.valueOf(string); - return EndTag.INSTANCE; - } - - @Override - public CompoundTag serializeEntity(Entity location) { - return null;// TODO: - } - - @Override - public Entity deserializeEntity(CompoundTag s, Location newPosition) { - return null;// TODO: - } - - @Override - public boolean supportsCustomHeight() { - return true; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - private Registry getCustomBiomeRegistry() { - return registry().registry(Registry.BIOME_REGISTRY).orElse(null); - } - - private Registry getBlockRegistry() { - return registry().registry(Registry.BLOCK_REGISTRY).orElse(null); - } - - @Override - public Object getBiomeBaseFromId(int id) { - return getCustomBiomeRegistry().getHolder(id); - } - - @Override - public int getMinHeight(World world) { - return world.getMinHeight(); - } - - @Override - public boolean supportsCustomBiomes() { - return true; - } - - @Override - public int getTrueBiomeBaseId(Object biomeBase) { - return getCustomBiomeRegistry().getId(((Holder) biomeBase).value()); - } - - @Override - public Object getTrueBiomeBase(Location location) { - return ((CraftWorld) location.getWorld()).getHandle().getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - } - - @Override - public String getTrueBiomeBaseKey(Location location) { - return getKeyForBiomeBase(getTrueBiomeBase(location)); - } - - @Override - public Object getCustomBiomeBaseFor(String mckey) { - return getCustomBiomeRegistry().get(new ResourceLocation(mckey)); - } - - @Override - public Object getCustomBiomeBaseHolderFor(String mckey) { - return getCustomBiomeRegistry().getHolder(getTrueBiomeBaseId(getCustomBiomeRegistry().get(new ResourceLocation(mckey)))).get(); - } - - public int getBiomeBaseIdForKey(String key) { - return getCustomBiomeRegistry().getId(getCustomBiomeRegistry().get(new ResourceLocation(key))); - } - - @Override - public String getKeyForBiomeBase(Object biomeBase) { - return getCustomBiomeRegistry().getKey((net.minecraft.world.level.biome.Biome) biomeBase).getPath(); // something, not something:something - } - - @Override - public Object getBiomeBase(World world, Biome biome) { - return CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle() - .registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null), biome); - } - - @Override - public Object getBiomeBase(Object registry, Biome biome) { - Object v = baseBiomeCache.get(biome); - - if (v != null) { - return v; - } - //noinspection unchecked - v = CraftBlock.biomeToBiomeBase((Registry) registry, biome); - if (v == null) { - // Ok so there is this new biome name called "CUSTOM" in Paper's new releases. - // But, this does NOT exist within CraftBukkit which makes it return an error. - // So, we will just return the ID that the plains biome returns instead. - //noinspection unchecked - return CraftBlock.biomeToBiomeBase((Registry) registry, Biome.PLAINS); - } - baseBiomeCache.put(biome, v); - return v; - } - - @Override - public KList getBiomes() { - return new KList<>(Biome.values()).qdel(Biome.CUSTOM); - } - - @Override - public boolean isBukkit() { - return true; - } - - @Override - public int getBiomeId(Biome biome) { - for (World i : Bukkit.getWorlds()) { - if (i.getEnvironment().equals(World.Environment.NORMAL)) { - Registry registry = ((CraftWorld) i).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null); - return registry.getId((net.minecraft.world.level.biome.Biome) getBiomeBase(registry, biome)); - } - } - - return biome.ordinal(); - } - - private MCAIdMap getBiomeMapping() { - return biomeMapCache.aquire(() -> new MCAIdMap<>() { - @NotNull - @Override - public Iterator iterator() { - return getCustomBiomeRegistry().iterator(); - } - - @Override - public int getId(net.minecraft.world.level.biome.Biome paramT) { - return getCustomBiomeRegistry().getId(paramT); - } - - @Override - public net.minecraft.world.level.biome.Biome byId(int paramInt) { - return (net.minecraft.world.level.biome.Biome) getBiomeBaseFromId(paramInt); - } - }); - } - - @NotNull - private MCABiomeContainer getBiomeContainerInterface(MCAIdMap biomeMapping, MCAChunkBiomeContainer base) { - return new MCABiomeContainer() { - @Override - public int[] getData() { - return base.writeBiomes(); - } - - @Override - public void setBiome(int x, int y, int z, int id) { - base.setBiome(x, y, z, biomeMapping.byId(id)); - } - - @Override - public int getBiome(int x, int y, int z) { - return biomeMapping.getId(base.getBiome(x, y, z)); - } - }; - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public int countCustomBiomes() { - AtomicInteger a = new AtomicInteger(0); - - getCustomBiomeRegistry().keySet().forEach((i) -> { - if (i.getNamespace().equals("minecraft")) { - return; - } - - a.incrementAndGet(); - Iris.debug("Custom Biome: " + i); - }); - - return a.get(); - } - - public boolean supportsDataPacks() { - return true; - } - - public void setBiomes(int cx, int cz, World world, Hunk biomes) { - LevelChunk c = ((CraftWorld) world).getHandle().getChunk(cx, cz); - biomes.iterateSync((x, y, z, b) -> c.setBiome(x, y, z, (Holder) b)); - c.setUnsaved(true); - } - - @Override - public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { - try { - ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk); - Holder biome = (Holder) somethingVeryDirty; - s.setBiome(x, y, z, biome); - } catch (IllegalAccessException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - - private Field getFieldForBiomeStorage(Object storage) { - Field f = biomeStorageCache; - - if (f != null) { - return f; - } - try { - f = storage.getClass().getDeclaredField("biome"); - f.setAccessible(true); - return f; - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error(storage.getClass().getCanonicalName()); - } - - biomeStorageCache = f; - return null; - } - - @Override - public MCAPaletteAccess createPalette() { - MCAIdMapper registry = registryCache.aquireNasty(() -> { - Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId"); - Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT"); - Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId"); - cf.setAccessible(true); - df.setAccessible(true); - bf.setAccessible(true); - net.minecraft.core.IdMapper blockData = Block.BLOCK_STATE_REGISTRY; - int b = bf.getInt(blockData); - Object2IntMap c = (Object2IntMap) cf.get(blockData); - List d = (List) df.get(blockData); - return new MCAIdMapper(c, d, b); - }); - MCAPalette global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState())); - MCAPalettedContainer container = new MCAPalettedContainer<>(global, registry, - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(), - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - ((CraftBlockData) AIR).getState()); - return new MCAWrappedPalettedContainer<>(container, - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState()); - } - - @Override - public void injectBiomesFromMantle(Chunk e, Mantle mantle) { - ChunkAccess chunk = ((CraftChunk) e).getHandle(); - AtomicInteger c = new AtomicInteger(); - AtomicInteger r = new AtomicInteger(); - mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x, y, z, b) -> { - if (b != null) { - if (b.isCustom()) { - chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get()); - c.getAndIncrement(); - } else { - chunk.setBiome(x, y, z, (Holder) getBiomeBase(e.getWorld(), b.getBiome())); - r.getAndIncrement(); - } - } - }); - } - - public ItemStack applyCustomNbt(ItemStack itemStack, KMap customNbt) throws IllegalArgumentException { - if (customNbt != null && !customNbt.isEmpty()) { - net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(itemStack); - - try { - net.minecraft.nbt.CompoundTag tag = TagParser.parseTag((new JSONObject(customNbt)).toString()); - tag.merge(s.getOrCreateTag()); - s.setTag(tag); - } catch (CommandSyntaxException var5) { - throw new IllegalArgumentException(var5); - } - - return CraftItemStack.asBukkitCopy(s); - } else { - return itemStack; - } - } - - public void inject(long seed, Engine engine, World world) { - var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); - } - - public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { - Field[] fields = EntityType.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { - try { - EntityType entityType = (EntityType) field.get(null); - if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { - Vector v1 = new Vector<>(); - v1.add(entityType.getHeight()); - entityType.getDimensions(); - Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); - //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); - return box; - } - } catch (IllegalAccessException e) { - Iris.error("Unable to get entity dimensions!"); - e.printStackTrace(); - } - } - } - return null; - } - - @Override - public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { - return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); - } - - @Override - public Color getBiomeColor(Location location, BiomeColor type) { - LevelReader reader = ((CraftWorld) location.getWorld()).getHandle(); - var holder = reader.getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - var biome = holder.value(); - if (biome == null) throw new IllegalArgumentException("Invalid biome: " + holder.unwrapKey().orElse(null)); - - int rgba = switch (type) { - case FOG -> biome.getFogColor(); - case WATER -> biome.getWaterColor(); - case WATER_FOG -> biome.getWaterFogColor(); - case SKY -> biome.getSkyColor(); - case FOLIAGE -> biome.getFoliageColor(); - case GRASS -> biome.getGrassColor(location.getBlockX(), location.getBlockZ()); - }; - if (rgba == 0) { - if (BiomeColor.FOLIAGE == type && biome.getSpecialEffects().getFoliageColorOverride().isEmpty()) - return null; - if (BiomeColor.GRASS == type && biome.getSpecialEffects().getGrassColorOverride().isEmpty()) - return null; - } - return new Color(rgba, true); - } - - @Override - public KList getStructureKeys() { - KList keys = new KList<>(); - - var registry = registry().registry(Registry.STRUCTURE_REGISTRY).orElse(null); - if (registry == null) return keys; - registry.keySet().stream().map(ResourceLocation::toString).forEach(keys::add); - registry.getTags() - .map(Pair::getFirst) - .map(TagKey::location) - .map(ResourceLocation::toString) - .map(s -> "#" + s) - .forEach(keys::add); - - return keys; - } - - private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { - try { - for (Field f : clazz.getDeclaredFields()) { - if (f.getType().equals(fieldType)) - return f; - } - throw new NoSuchFieldException(fieldType.getName()); - } catch (NoSuchFieldException var4) { - Class superClass = clazz.getSuperclass(); - if (superClass == null) { - throw var4; - } else { - return getField(superClass, fieldType); - } - } - } -} diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java deleted file mode 100644 index 7a82acf42..000000000 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/CustomBiomeSource.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R2; - -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.engine.object.IrisBiomeCustom; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.math.RNG; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R2.CraftServer; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlock; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -public class CustomBiomeSource extends BiomeSource { - - private final long seed; - private final Engine engine; - private final Registry biomeCustomRegistry; - private final Registry biomeRegistry; - private final AtomicCache registryAccess = new AtomicCache<>(); - private final RNG rng; - private final KMap> customBiomes; - - public CustomBiomeSource(long seed, Engine engine, World world) { - super(getAllBiomes( - ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())) - .registry(Registries.BIOME).orElse(null), - ((CraftWorld) world).getHandle().registryAccess().registry(Registries.BIOME).orElse(null), - engine)); - this.engine = engine; - this.seed = seed; - this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null); - this.biomeRegistry = ((CraftWorld) world).getHandle().registryAccess().registry(Registries.BIOME).orElse(null); - this.rng = new RNG(engine.getSeedManager().getBiome()); - this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine); - } - - private static List> getAllBiomes(Registry customRegistry, Registry registry, Engine engine) { - List> b = new ArrayList<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); - } - } else { - b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative())); - } - } - - return b; - } - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - private KMap> fillCustomBiomes(Registry customRegistry, Engine engine) { - KMap> m = new KMap<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - m.put(j.getId(), customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); - } - } - } - - return m; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - @Override - protected Codec codec() { - throw new UnsupportedOperationException("Not supported"); - } - - @Override - public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { - int m = (y - engine.getMinHeight()) << 2; - IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2); - if (ib.isCustom()) { - return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId()); - } else { - org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2); - return CraftBlock.biomeToBiomeBase(biomeRegistry, v); - } - } -} \ No newline at end of file diff --git a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/IrisChunkGenerator.java b/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/IrisChunkGenerator.java deleted file mode 100644 index 92b7b2b32..000000000 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/IrisChunkGenerator.java +++ /dev/null @@ -1,260 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R2; - -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.ResultLocator; -import com.volmit.iris.engine.framework.WrongEngineBroException; -import com.volmit.iris.engine.object.IrisJigsawStructure; -import com.volmit.iris.engine.object.IrisJigsawStructurePlacement; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.mantle.MantleFlag; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.reflect.WrappedField; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.tags.TagKey; -import net.minecraft.util.random.WeightedRandomList; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.MobSpawnSettings; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.structure.Structure; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.generator.CustomChunkGenerator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.*; - -public class IrisChunkGenerator extends CustomChunkGenerator { - private static final WrappedField BIOME_SOURCE; - private final ChunkGenerator delegate; - private final Engine engine; - private final KMap, KSet> structures = new KMap<>(); - - public IrisChunkGenerator(ChunkGenerator delegate, long seed, Engine engine, World world) { - super(((CraftWorld) world).getHandle(), edit(delegate, new CustomBiomeSource(seed, engine, world)), null); - this.delegate = delegate; - this.engine = engine; - var dimension = engine.getDimension(); - - KSet placements = new KSet<>(); - addAll(dimension.getJigsawStructures(), placements); - for (var region : dimension.getAllRegions(engine)) { - addAll(region.getJigsawStructures(), placements); - for (var biome : region.getAllBiomes(engine)) - addAll(biome.getJigsawStructures(), placements); - } - var stronghold = dimension.getStronghold(); - if (stronghold != null) - placements.add(engine.getData().getJigsawStructureLoader().load(stronghold)); - placements.removeIf(Objects::isNull); - - var registry = ((CraftWorld) world).getHandle().registryAccess().registry(Registries.STRUCTURE).orElseThrow(); - for (var s : placements) { - try { - String raw = s.getStructureKey(); - if (raw == null) continue; - boolean tag = raw.startsWith("#"); - if (tag) raw = raw.substring(1); - - var location = new ResourceLocation(raw); - if (!tag) { - structures.computeIfAbsent(ResourceKey.create(Registries.STRUCTURE, location), k -> new KSet<>()).add(s.getLoadKey()); - continue; - } - - var key = TagKey.create(Registries.STRUCTURE, location); - var set = registry.getTag(key).orElse(null); - if (set == null) { - Iris.error("Could not find structure tag: " + raw); - continue; - } - for (var holder : set) { - var resourceKey = holder.unwrapKey().orElse(null); - if (resourceKey == null) continue; - structures.computeIfAbsent(resourceKey, k -> new KSet<>()).add(s.getLoadKey()); - } - } catch (Throwable e) { - Iris.error("Failed to load structure: " + s.getLoadKey()); - e.printStackTrace(); - } - } - } - - private void addAll(KList placements, KSet structures) { - if (placements == null) return; - placements.stream() - .map(IrisJigsawStructurePlacement::getStructure) - .map(engine.getData().getJigsawStructureLoader()::load) - .filter(Objects::nonNull) - .forEach(structures::add); - } - - @Override - public @Nullable Pair> findNearestMapStructure(ServerLevel level, HolderSet holders, BlockPos pos, int radius, boolean findUnexplored) { - if (engine.getDimension().isDisableExplorerMaps()) - return null; - - KMap> structures = new KMap<>(); - for (var holder : holders) { - if (holder == null) continue; - var key = holder.unwrapKey().orElse(null); - var set = this.structures.get(key); - if (set == null) continue; - for (var structure : set) { - structures.put(structure, holder); - } - } - if (structures.isEmpty()) - return null; - - var locator = ResultLocator.locateStructure(structures.keySet()) - .then((e, p , s) -> structures.get(s.getLoadKey())); - if (findUnexplored) - locator = locator.then((e, p, s) -> e.getMantle().getMantle().getChunk(p.getX(), p.getZ()).isFlagged(MantleFlag.DISCOVERED) ? null : s); - - try { - var result = locator.find(engine, new Position2(pos.getX() >> 4, pos.getZ() >> 4), radius * 10L, i -> {}, false).get(); - if (result == null) return null; - var blockPos = new BlockPos(result.getBlockX(), 0, result.getBlockZ()); - return Pair.of(blockPos, result.obj()); - } catch (WrongEngineBroException | ExecutionException | InterruptedException e) { - return null; - } - } - - @Override - protected Codec codec() { - return Codec.unit(null); - } - - @Override - public ChunkGenerator getDelegate() { - if (delegate instanceof CustomChunkGenerator chunkGenerator) - return chunkGenerator.getDelegate(); - return delegate; - } - - @Override - public int getMinY() { - return delegate.getMinY(); - } - - @Override - public int getSeaLevel() { - return delegate.getSeaLevel(); - } - - @Override - public void createStructures(RegistryAccess iregistrycustom, ChunkGeneratorStructureState chunkgeneratorstructurestate, StructureManager structuremanager, ChunkAccess ichunkaccess, StructureTemplateManager structuretemplatemanager) { - delegate.createStructures(iregistrycustom, chunkgeneratorstructurestate, structuremanager, ichunkaccess, structuretemplatemanager); - } - - @Override - public void buildSurface(WorldGenRegion regionlimitedworldaccess, StructureManager structuremanager, RandomState randomstate, ChunkAccess ichunkaccess) { - delegate.buildSurface(regionlimitedworldaccess, structuremanager, randomstate, ichunkaccess); - } - - @Override - public void applyCarvers(WorldGenRegion regionlimitedworldaccess, long seed, RandomState randomstate, BiomeManager biomemanager, StructureManager structuremanager, ChunkAccess ichunkaccess, GenerationStep.Carving worldgenstage_features) { - delegate.applyCarvers(regionlimitedworldaccess, seed, randomstate, biomemanager, structuremanager, ichunkaccess, worldgenstage_features); - } - - @Override - public CompletableFuture fillFromNoise(Executor executor, Blender blender, RandomState randomstate, StructureManager structuremanager, ChunkAccess ichunkaccess) { - return delegate.fillFromNoise(executor, blender, randomstate, structuremanager, ichunkaccess); - } - - @Override - public int getBaseHeight(int i, int j, Heightmap.Types heightmap_type, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseHeight(i, j, heightmap_type, levelheightaccessor, randomstate); - } - - @Override - public WeightedRandomList getMobsAt(Holder holder, StructureManager structuremanager, MobCategory enumcreaturetype, BlockPos blockposition) { - return delegate.getMobsAt(holder, structuremanager, enumcreaturetype, blockposition); - } - - @Override - public void applyBiomeDecoration(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager) { - delegate.applyBiomeDecoration(generatoraccessseed, ichunkaccess, structuremanager); - } - - @Override - public void addDebugScreenInfo(List list, RandomState randomstate, BlockPos blockposition) { - delegate.addDebugScreenInfo(list, randomstate, blockposition); - } - - @Override - public void spawnOriginalMobs(WorldGenRegion regionlimitedworldaccess) { - delegate.spawnOriginalMobs(regionlimitedworldaccess); - } - - @Override - public int getSpawnHeight(LevelHeightAccessor levelheightaccessor) { - return delegate.getSpawnHeight(levelheightaccessor); - } - - @Override - public int getGenDepth() { - return delegate.getGenDepth(); - } - - @Override - public NoiseColumn getBaseColumn(int i, int j, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseColumn(i, j, levelheightaccessor, randomstate); - } - - static { - Field biomeSource = null; - for (Field field : ChunkGenerator.class.getDeclaredFields()) { - if (!field.getType().equals(BiomeSource.class)) - continue; - biomeSource = field; - break; - } - if (biomeSource == null) - throw new RuntimeException("Could not find biomeSource field in ChunkGenerator!"); - BIOME_SOURCE = new WrappedField<>(ChunkGenerator.class, biomeSource.getName()); - } - - private static ChunkGenerator edit(ChunkGenerator generator, BiomeSource source) { - try { - BIOME_SOURCE.set(generator, source); - if (generator instanceof CustomChunkGenerator custom) - BIOME_SOURCE.set(custom.getDelegate(), source); - - return generator; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} 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 deleted file mode 100644 index 5d4c44d70..000000000 --- a/nms/v1_19_R2/src/main/java/com/volmit/iris/core/nms/v1_19_R2/NMSBinding.java +++ /dev/null @@ -1,628 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R2; - -import java.awt.Color; -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.Map; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - -import com.mojang.datafixers.util.Pair; -import com.volmit.iris.core.nms.container.BiomeColor; -import com.volmit.iris.util.scheduling.J; -import net.minecraft.nbt.*; -import net.minecraft.nbt.Tag; -import net.minecraft.server.commands.data.BlockDataAccessor; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.EntityBlock; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.data.BlockData; -import org.bukkit.craftbukkit.v1_19_R2.CraftChunk; -import org.bukkit.craftbukkit.v1_19_R2.CraftServer; -import org.bukkit.craftbukkit.v1_19_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlock; -import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockState; -import org.bukkit.craftbukkit.v1_19_R2.block.CraftBlockStates; -import org.bukkit.craftbukkit.v1_19_R2.block.data.CraftBlockData; -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.event.entity.CreatureSpawnEvent; -import org.bukkit.generator.ChunkGenerator; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; - -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMSBinding; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.json.JSONObject; -import com.volmit.iris.util.mantle.Mantle; -import com.volmit.iris.util.math.Vector3d; -import com.volmit.iris.util.matter.MatterBiomeInject; -import com.volmit.iris.util.nbt.io.NBTUtil; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.nbt.mca.palette.*; -import com.volmit.iris.util.nbt.tag.CompoundTag; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.LevelChunk; -import sun.misc.Unsafe; - -public class NMSBinding implements INMSBinding { - private final KMap baseBiomeCache = new KMap<>(); - private final BlockData AIR = Material.AIR.createBlockData(); - private final AtomicCache> biomeMapCache = new AtomicCache<>(); - private final AtomicCache> registryCache = new AtomicCache<>(); - private final AtomicCache> globalCache = new AtomicCache<>(); - private final AtomicCache registryAccess = new AtomicCache<>(); - private final AtomicCache byIdRef = new AtomicCache<>(); - private Field biomeStorageCache = null; - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - private static Class getClassType(Class type, int ordinal) { - return type.getDeclaredClasses()[ordinal]; - } - - @Override - public boolean hasTile(Material material) { - return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material)); - } - - @Override - public boolean hasTile(Location l) { - return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; - } - - @Override - @SuppressWarnings("unchecked") - public KMap serializeTile(Location location) { - BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false); - - if (e == null) { - return null; - } - - net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(); - return (KMap) convertFromTag(tag, 0, 64); - } - - @Contract(value = "null, _, _ -> null", pure = true) - private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) { - if (tag == null || depth > maxDepth) return null; - if (tag instanceof CollectionTag collection) { - KList list = new KList<>(); - - for (Object i : collection) { - if (i instanceof net.minecraft.nbt.Tag t) - list.add(convertFromTag(t, depth + 1, maxDepth)); - else list.add(i); - } - return list; - } - if (tag instanceof net.minecraft.nbt.CompoundTag compound) { - KMap map = new KMap<>(); - - for (String key : compound.getAllKeys()) { - var child = compound.get(key); - if (child == null) continue; - var value = convertFromTag(child, depth + 1, maxDepth); - if (value == null) continue; - map.put(key, value); - } - return map; - } - if (tag instanceof NumericTag numeric) - return numeric.getAsNumber(); - return tag.getAsString(); - } - - @Override - public void deserializeTile(KMap map, Location pos) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64); - var level = ((CraftWorld) pos.getWorld()).getHandle(); - var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); - J.s(() -> merge(level, blockPos, tag)); - } - - private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) { - var blockEntity = level.getBlockEntity(blockPos); - if (blockEntity == null) { - Iris.warn("[NMS] BlockEntity not found at " + blockPos); - var state = level.getBlockState(blockPos); - if (!state.hasBlockEntity()) - return; - - blockEntity = ((EntityBlock) state.getBlock()) - .newBlockEntity(blockPos, state); - } - var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); - } - - private Tag convertToTag(Object object, int depth, int maxDepth) { - if (object == null || depth > maxDepth) return EndTag.INSTANCE; - if (object instanceof Map map) { - var tag = new net.minecraft.nbt.CompoundTag(); - for (var i : map.entrySet()) { - tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof List list) { - var tag = new net.minecraft.nbt.ListTag(); - for (var i : list) { - tag.add(convertToTag(i, depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof Byte number) return ByteTag.valueOf(number); - if (object instanceof Short number) return ShortTag.valueOf(number); - if (object instanceof Integer number) return IntTag.valueOf(number); - if (object instanceof Long number) return LongTag.valueOf(number); - if (object instanceof Float number) return FloatTag.valueOf(number); - if (object instanceof Double number) return DoubleTag.valueOf(number); - if (object instanceof String string) return StringTag.valueOf(string); - return EndTag.INSTANCE; - } - - @Override - public CompoundTag serializeEntity(Entity location) { - return null;// TODO: - } - - @Override - public Entity deserializeEntity(CompoundTag s, Location newPosition) { - return null;// TODO: - } - - @Override - public boolean supportsCustomHeight() { - return true; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - private Registry getCustomBiomeRegistry() { - return registry().registry(Registries.BIOME).orElse(null); - } - - private Registry getBlockRegistry() { - return registry().registry(Registries.BLOCK).orElse(null); - } - - @Override - public Object getBiomeBaseFromId(int id) { - return getCustomBiomeRegistry().getHolder(id); - } - - @Override - public int getMinHeight(World world) { - return world.getMinHeight(); - } - - @Override - public boolean supportsCustomBiomes() { - return true; - } - - @Override - public int getTrueBiomeBaseId(Object biomeBase) { - return getCustomBiomeRegistry().getId(((Holder) biomeBase).value()); - } - - @Override - public Object getTrueBiomeBase(Location location) { - return ((CraftWorld) location.getWorld()).getHandle().getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - } - - @Override - public String getTrueBiomeBaseKey(Location location) { - return getKeyForBiomeBase(getTrueBiomeBase(location)); - } - - @Override - public Object getCustomBiomeBaseFor(String mckey) { - return getCustomBiomeRegistry().get(new ResourceLocation(mckey)); - } - - @Override - public Object getCustomBiomeBaseHolderFor(String mckey) { - return getCustomBiomeRegistry().getHolder(getTrueBiomeBaseId(getCustomBiomeRegistry().get(new ResourceLocation(mckey)))).get(); - } - - public int getBiomeBaseIdForKey(String key) { - return getCustomBiomeRegistry().getId(getCustomBiomeRegistry().get(new ResourceLocation(key))); - } - - @Override - public String getKeyForBiomeBase(Object biomeBase) { - return getCustomBiomeRegistry().getKey((net.minecraft.world.level.biome.Biome) biomeBase).getPath(); // something, not something:something - } - - @Override - public Object getBiomeBase(World world, Biome biome) { - return CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle() - .registryAccess().registry(Registries.BIOME).orElse(null), biome); - } - - @Override - public Object getBiomeBase(Object registry, Biome biome) { - Object v = baseBiomeCache.get(biome); - - if (v != null) { - return v; - } - //noinspection unchecked - v = CraftBlock.biomeToBiomeBase((Registry) registry, biome); - if (v == null) { - // Ok so there is this new biome name called "CUSTOM" in Paper's new releases. - // But, this does NOT exist within CraftBukkit which makes it return an error. - // So, we will just return the ID that the plains biome returns instead. - //noinspection unchecked - return CraftBlock.biomeToBiomeBase((Registry) registry, Biome.PLAINS); - } - baseBiomeCache.put(biome, v); - return v; - } - - @Override - public KList getBiomes() { - return new KList<>(Biome.values()).qdel(Biome.CUSTOM); - } - - @Override - public boolean isBukkit() { - return true; - } - - @Override - public int getBiomeId(Biome biome) { - for (World i : Bukkit.getWorlds()) { - if (i.getEnvironment().equals(World.Environment.NORMAL)) { - Registry registry = ((CraftWorld) i).getHandle().registryAccess().registry(Registries.BIOME).orElse(null); - return registry.getId((net.minecraft.world.level.biome.Biome) getBiomeBase(registry, biome)); - } - } - - return biome.ordinal(); - } - - private MCAIdMap getBiomeMapping() { - return biomeMapCache.aquire(() -> new MCAIdMap<>() { - @NotNull - @Override - public Iterator iterator() { - return getCustomBiomeRegistry().iterator(); - } - - @Override - public int getId(net.minecraft.world.level.biome.Biome paramT) { - return getCustomBiomeRegistry().getId(paramT); - } - - @Override - public net.minecraft.world.level.biome.Biome byId(int paramInt) { - return (net.minecraft.world.level.biome.Biome) getBiomeBaseFromId(paramInt); - } - }); - } - - @NotNull - private MCABiomeContainer getBiomeContainerInterface(MCAIdMap biomeMapping, MCAChunkBiomeContainer base) { - return new MCABiomeContainer() { - @Override - public int[] getData() { - return base.writeBiomes(); - } - - @Override - public void setBiome(int x, int y, int z, int id) { - base.setBiome(x, y, z, biomeMapping.byId(id)); - } - - @Override - public int getBiome(int x, int y, int z) { - return biomeMapping.getId(base.getBiome(x, y, z)); - } - }; - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public int countCustomBiomes() { - AtomicInteger a = new AtomicInteger(0); - - getCustomBiomeRegistry().keySet().forEach((i) -> { - if (i.getNamespace().equals("minecraft")) { - return; - } - - a.incrementAndGet(); - Iris.debug("Custom Biome: " + i); - }); - - return a.get(); - } - - public boolean supportsDataPacks() { - return true; - } - - public void setBiomes(int cx, int cz, World world, Hunk biomes) { - LevelChunk c = ((CraftWorld) world).getHandle().getChunk(cx, cz); - biomes.iterateSync((x, y, z, b) -> c.setBiome(x, y, z, (Holder) b)); - c.setUnsaved(true); - } - - @Override - public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { - try { - ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk); - Holder biome = (Holder) somethingVeryDirty; - s.setBiome(x, y, z, biome); - } catch (IllegalAccessException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - - private Field getFieldForBiomeStorage(Object storage) { - Field f = biomeStorageCache; - - if (f != null) { - return f; - } - try { - f = storage.getClass().getDeclaredField("biome"); - f.setAccessible(true); - return f; - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error(storage.getClass().getCanonicalName()); - } - - biomeStorageCache = f; - return null; - } - - @Override - public MCAPaletteAccess createPalette() { - MCAIdMapper registry = registryCache.aquireNasty(() -> { - Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId"); - Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT"); - Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId"); - cf.setAccessible(true); - df.setAccessible(true); - bf.setAccessible(true); - net.minecraft.core.IdMapper blockData = Block.BLOCK_STATE_REGISTRY; - int b = bf.getInt(blockData); - Object2IntMap c = (Object2IntMap) cf.get(blockData); - List d = (List) df.get(blockData); - return new MCAIdMapper(c, d, b); - }); - MCAPalette global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState())); - MCAPalettedContainer container = new MCAPalettedContainer<>(global, registry, - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(), - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - ((CraftBlockData) AIR).getState()); - return new MCAWrappedPalettedContainer<>(container, - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState()); - } - - @Override - public void injectBiomesFromMantle(Chunk e, Mantle mantle) { - ChunkAccess chunk = ((CraftChunk) e).getHandle(); - AtomicInteger c = new AtomicInteger(); - AtomicInteger r = new AtomicInteger(); - mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x, y, z, b) -> { - if (b != null) { - if (b.isCustom()) { - chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get()); - c.getAndIncrement(); - } else { - chunk.setBiome(x, y, z, (Holder) getBiomeBase(e.getWorld(), b.getBiome())); - r.getAndIncrement(); - } - } - }); - } - - public ItemStack applyCustomNbt(ItemStack itemStack, KMap customNbt) throws IllegalArgumentException { - if (customNbt != null && !customNbt.isEmpty()) { - net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(itemStack); - - try { - net.minecraft.nbt.CompoundTag tag = TagParser.parseTag((new JSONObject(customNbt)).toString()); - tag.merge(s.getOrCreateTag()); - s.setTag(tag); - } catch (CommandSyntaxException var5) { - throw new IllegalArgumentException(var5); - } - - return CraftItemStack.asBukkitCopy(s); - } else { - return itemStack; - } - } - - public void inject(long seed, Engine engine, World world) { - var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); - } - - - public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { - Field[] fields = EntityType.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { - try { - EntityType entityType = (EntityType) field.get(null); - if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { - Vector v1 = new Vector<>(); - v1.add(entityType.getHeight()); - entityType.getDimensions(); - Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); - //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); - return box; - } - } catch (IllegalAccessException e) { - Iris.error("Unable to get entity dimensions!"); - e.printStackTrace(); - } - } - } - return null; - } - - @Override - public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { - return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); - } - - @Override - public Color getBiomeColor(Location location, BiomeColor type) { - LevelReader reader = ((CraftWorld) location.getWorld()).getHandle(); - var holder = reader.getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - var biome = holder.value(); - if (biome == null) throw new IllegalArgumentException("Invalid biome: " + holder.unwrapKey().orElse(null)); - - int rgba = switch (type) { - case FOG -> biome.getFogColor(); - case WATER -> biome.getWaterColor(); - case WATER_FOG -> biome.getWaterFogColor(); - case SKY -> biome.getSkyColor(); - case FOLIAGE -> biome.getFoliageColor(); - case GRASS -> biome.getGrassColor(location.getBlockX(), location.getBlockZ()); - }; - if (rgba == 0) { - if (BiomeColor.FOLIAGE == type && biome.getSpecialEffects().getFoliageColorOverride().isEmpty()) - return null; - if (BiomeColor.GRASS == type && biome.getSpecialEffects().getGrassColorOverride().isEmpty()) - return null; - } - return new Color(rgba, true); - } - - @Override - public KList getStructureKeys() { - KList keys = new KList<>(); - - var registry = registry().registry(Registries.STRUCTURE).orElse(null); - if (registry == null) return keys; - registry.keySet().stream().map(ResourceLocation::toString).forEach(keys::add); - registry.getTags() - .map(Pair::getFirst) - .map(TagKey::location) - .map(ResourceLocation::toString) - .map(s -> "#" + s) - .forEach(keys::add); - - return keys; - } - - private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { - try { - for (Field f : clazz.getDeclaredFields()) { - if (f.getType().equals(fieldType)) - return f; - } - throw new NoSuchFieldException(fieldType.getName()); - } catch (NoSuchFieldException var4) { - Class superClass = clazz.getSuperclass(); - if (superClass == null) { - throw var4; - } else { - return getField(superClass, fieldType); - } - } - } -} diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java deleted file mode 100644 index f3debbaad..000000000 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/CustomBiomeSource.java +++ /dev/null @@ -1,169 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R3; - -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.object.IrisBiome; -import com.volmit.iris.engine.object.IrisBiomeCustom; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.math.RNG; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.Climate; -import org.bukkit.Bukkit; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R3.CraftServer; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlock; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -public class CustomBiomeSource extends BiomeSource { - - private final long seed; - private final Engine engine; - private final Registry biomeCustomRegistry; - private final Registry biomeRegistry; - private final AtomicCache registryAccess = new AtomicCache<>(); - private final RNG rng; - private final KMap> customBiomes; - - public CustomBiomeSource(long seed, Engine engine, World world) { - this.engine = engine; - this.seed = seed; - this.biomeCustomRegistry = registry().registry(Registries.BIOME).orElse(null); - this.biomeRegistry = ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())).registry(Registries.BIOME).orElse(null); - this.rng = new RNG(engine.getSeedManager().getBiome()); - this.customBiomes = fillCustomBiomes(biomeCustomRegistry, engine); - } - - private static List> getAllBiomes(Registry customRegistry, Registry registry, Engine engine) { - List> b = new ArrayList<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - b.add(customRegistry.getHolder(customRegistry.getResourceKey(customRegistry - .get(new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()))).get()).get()); - } - } else { - b.add(CraftBlock.biomeToBiomeBase(registry, i.getVanillaDerivative())); - } - } - - return b; - } - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected Stream> collectPossibleBiomes() { - return getAllBiomes( - ((RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())) - .registry(Registries.BIOME).orElse(null), - ((CraftWorld) engine.getWorld().realWorld()).getHandle().registryAccess().registry(Registries.BIOME).orElse(null), - engine).stream(); - } - private KMap> fillCustomBiomes(Registry customRegistry, Engine engine) { - KMap> m = new KMap<>(); - - for (IrisBiome i : engine.getAllBiomes()) { - if (i.isCustom()) { - for (IrisBiomeCustom j : i.getCustomDerivitives()) { - ResourceLocation resourceLocation = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId()); - Biome biome = customRegistry.get(resourceLocation); - Optional> optionalBiomeKey = customRegistry.getResourceKey(biome); - if (optionalBiomeKey.isEmpty()) { - Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName()); - continue; - } - ResourceKey biomeKey = optionalBiomeKey.get(); - Optional> optionalReferenceHolder = customRegistry.getHolder(biomeKey); - if (optionalReferenceHolder.isEmpty()) { - Iris.error("Cannot find reference to biome " + biomeKey + " for engine " + engine.getName()); - continue; - } - m.put(j.getId(), optionalReferenceHolder.get()); - } - } - } - - return m; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - @Override - protected Codec codec() { - throw new UnsupportedOperationException("Not supported"); - } - - @Override - public Holder getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) { - int m = (y - engine.getMinHeight()) << 2; - IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x << 2, z << 2); - if (ib.isCustom()) { - return customBiomes.get(ib.getCustomBiome(rng, x << 2, m, z << 2).getId()); - } else { - org.bukkit.block.Biome v = ib.getSkyBiome(rng, x << 2, m, z << 2); - return CraftBlock.biomeToBiomeBase(biomeRegistry, v); - } - } -} \ No newline at end of file diff --git a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/IrisChunkGenerator.java b/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/IrisChunkGenerator.java deleted file mode 100644 index f4f0b4502..000000000 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/IrisChunkGenerator.java +++ /dev/null @@ -1,262 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R3; - -import com.mojang.datafixers.util.Pair; -import com.mojang.serialization.Codec; -import com.volmit.iris.Iris; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.engine.framework.ResultLocator; -import com.volmit.iris.engine.framework.WrongEngineBroException; -import com.volmit.iris.engine.object.IrisJigsawStructure; -import com.volmit.iris.engine.object.IrisJigsawStructurePlacement; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.collection.KSet; -import com.volmit.iris.util.mantle.MantleFlag; -import com.volmit.iris.util.math.Position2; -import com.volmit.iris.util.reflect.WrappedField; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.HolderSet; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.server.level.WorldGenRegion; -import net.minecraft.tags.TagKey; -import net.minecraft.util.random.WeightedRandomList; -import net.minecraft.world.entity.MobCategory; -import net.minecraft.world.level.LevelHeightAccessor; -import net.minecraft.world.level.NoiseColumn; -import net.minecraft.world.level.StructureManager; -import net.minecraft.world.level.WorldGenLevel; -import net.minecraft.world.level.biome.Biome; -import net.minecraft.world.level.biome.BiomeManager; -import net.minecraft.world.level.biome.BiomeSource; -import net.minecraft.world.level.biome.MobSpawnSettings; -import net.minecraft.world.level.chunk.ChunkAccess; -import net.minecraft.world.level.chunk.ChunkGenerator; -import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; -import net.minecraft.world.level.levelgen.GenerationStep; -import net.minecraft.world.level.levelgen.Heightmap; -import net.minecraft.world.level.levelgen.RandomState; -import net.minecraft.world.level.levelgen.blending.Blender; -import net.minecraft.world.level.levelgen.structure.Structure; -import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; -import org.bukkit.World; -import org.bukkit.craftbukkit.v1_19_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R3.generator.CustomChunkGenerator; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Objects; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; - -public class IrisChunkGenerator extends CustomChunkGenerator { - private static final WrappedField BIOME_SOURCE; - private final ChunkGenerator delegate; - private final Engine engine; - private final KMap, KSet> structures = new KMap<>(); - - public IrisChunkGenerator(ChunkGenerator delegate, long seed, Engine engine, World world) { - super(((CraftWorld) world).getHandle(), edit(delegate, new CustomBiomeSource(seed, engine, world)), null); - this.delegate = delegate; - this.engine = engine; - var dimension = engine.getDimension(); - - KSet placements = new KSet<>(); - addAll(dimension.getJigsawStructures(), placements); - for (var region : dimension.getAllRegions(engine)) { - addAll(region.getJigsawStructures(), placements); - for (var biome : region.getAllBiomes(engine)) - addAll(biome.getJigsawStructures(), placements); - } - var stronghold = dimension.getStronghold(); - if (stronghold != null) - placements.add(engine.getData().getJigsawStructureLoader().load(stronghold)); - placements.removeIf(Objects::isNull); - - var registry = ((CraftWorld) world).getHandle().registryAccess().registry(Registries.STRUCTURE).orElseThrow(); - for (var s : placements) { - try { - String raw = s.getStructureKey(); - if (raw == null) continue; - boolean tag = raw.startsWith("#"); - if (tag) raw = raw.substring(1); - - var location = new ResourceLocation(raw); - if (!tag) { - structures.computeIfAbsent(ResourceKey.create(Registries.STRUCTURE, location), k -> new KSet<>()).add(s.getLoadKey()); - continue; - } - - var key = TagKey.create(Registries.STRUCTURE, location); - var set = registry.getTag(key).orElse(null); - if (set == null) { - Iris.error("Could not find structure tag: " + raw); - continue; - } - for (var holder : set) { - var resourceKey = holder.unwrapKey().orElse(null); - if (resourceKey == null) continue; - structures.computeIfAbsent(resourceKey, k -> new KSet<>()).add(s.getLoadKey()); - } - } catch (Throwable e) { - Iris.error("Failed to load structure: " + s.getLoadKey()); - e.printStackTrace(); - } - } - } - - private void addAll(KList placements, KSet structures) { - if (placements == null) return; - placements.stream() - .map(IrisJigsawStructurePlacement::getStructure) - .map(engine.getData().getJigsawStructureLoader()::load) - .filter(Objects::nonNull) - .forEach(structures::add); - } - - @Override - public @Nullable Pair> findNearestMapStructure(ServerLevel level, HolderSet holders, BlockPos pos, int radius, boolean findUnexplored) { - if (engine.getDimension().isDisableExplorerMaps()) - return null; - - KMap> structures = new KMap<>(); - for (var holder : holders) { - if (holder == null) continue; - var key = holder.unwrapKey().orElse(null); - var set = this.structures.get(key); - if (set == null) continue; - for (var structure : set) { - structures.put(structure, holder); - } - } - if (structures.isEmpty()) - return null; - - var locator = ResultLocator.locateStructure(structures.keySet()) - .then((e, p , s) -> structures.get(s.getLoadKey())); - if (findUnexplored) - locator = locator.then((e, p, s) -> e.getMantle().getMantle().getChunk(p.getX(), p.getZ()).isFlagged(MantleFlag.DISCOVERED) ? null : s); - - try { - var result = locator.find(engine, new Position2(pos.getX() >> 4, pos.getZ() >> 4), radius * 10L, i -> {}, false).get(); - if (result == null) return null; - var blockPos = new BlockPos(result.getBlockX(), 0, result.getBlockZ()); - return Pair.of(blockPos, result.obj()); - } catch (WrongEngineBroException | ExecutionException | InterruptedException e) { - return null; - } - } - - @Override - protected Codec codec() { - return Codec.unit(null); - } - - @Override - public ChunkGenerator getDelegate() { - if (delegate instanceof CustomChunkGenerator chunkGenerator) - return chunkGenerator.getDelegate(); - return delegate; - } - - @Override - public int getMinY() { - return delegate.getMinY(); - } - - @Override - public int getSeaLevel() { - return delegate.getSeaLevel(); - } - - @Override - public void createStructures(RegistryAccess iregistrycustom, ChunkGeneratorStructureState chunkgeneratorstructurestate, StructureManager structuremanager, ChunkAccess ichunkaccess, StructureTemplateManager structuretemplatemanager) { - delegate.createStructures(iregistrycustom, chunkgeneratorstructurestate, structuremanager, ichunkaccess, structuretemplatemanager); - } - - @Override - public void buildSurface(WorldGenRegion regionlimitedworldaccess, StructureManager structuremanager, RandomState randomstate, ChunkAccess ichunkaccess) { - delegate.buildSurface(regionlimitedworldaccess, structuremanager, randomstate, ichunkaccess); - } - - @Override - public void applyCarvers(WorldGenRegion regionlimitedworldaccess, long seed, RandomState randomstate, BiomeManager biomemanager, StructureManager structuremanager, ChunkAccess ichunkaccess, GenerationStep.Carving worldgenstage_features) { - delegate.applyCarvers(regionlimitedworldaccess, seed, randomstate, biomemanager, structuremanager, ichunkaccess, worldgenstage_features); - } - - @Override - public CompletableFuture fillFromNoise(Executor executor, Blender blender, RandomState randomstate, StructureManager structuremanager, ChunkAccess ichunkaccess) { - return delegate.fillFromNoise(executor, blender, randomstate, structuremanager, ichunkaccess); - } - - @Override - public int getBaseHeight(int i, int j, Heightmap.Types heightmap_type, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseHeight(i, j, heightmap_type, levelheightaccessor, randomstate); - } - - @Override - public WeightedRandomList getMobsAt(Holder holder, StructureManager structuremanager, MobCategory enumcreaturetype, BlockPos blockposition) { - return delegate.getMobsAt(holder, structuremanager, enumcreaturetype, blockposition); - } - - @Override - public void applyBiomeDecoration(WorldGenLevel generatoraccessseed, ChunkAccess ichunkaccess, StructureManager structuremanager) { - delegate.applyBiomeDecoration(generatoraccessseed, ichunkaccess, structuremanager); - } - - @Override - public void addDebugScreenInfo(List list, RandomState randomstate, BlockPos blockposition) { - delegate.addDebugScreenInfo(list, randomstate, blockposition); - } - - @Override - public void spawnOriginalMobs(WorldGenRegion regionlimitedworldaccess) { - delegate.spawnOriginalMobs(regionlimitedworldaccess); - } - - @Override - public int getSpawnHeight(LevelHeightAccessor levelheightaccessor) { - return delegate.getSpawnHeight(levelheightaccessor); - } - - @Override - public int getGenDepth() { - return delegate.getGenDepth(); - } - - @Override - public NoiseColumn getBaseColumn(int i, int j, LevelHeightAccessor levelheightaccessor, RandomState randomstate) { - return delegate.getBaseColumn(i, j, levelheightaccessor, randomstate); - } - - static { - Field biomeSource = null; - for (Field field : ChunkGenerator.class.getDeclaredFields()) { - if (!field.getType().equals(BiomeSource.class)) - continue; - biomeSource = field; - break; - } - if (biomeSource == null) - throw new RuntimeException("Could not find biomeSource field in ChunkGenerator!"); - BIOME_SOURCE = new WrappedField<>(ChunkGenerator.class, biomeSource.getName()); - } - - private static ChunkGenerator edit(ChunkGenerator generator, BiomeSource source) { - try { - BIOME_SOURCE.set(generator, source); - if (generator instanceof CustomChunkGenerator custom) - BIOME_SOURCE.set(custom.getDelegate(), source); - - return generator; - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} 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 deleted file mode 100644 index 6c151dea8..000000000 --- a/nms/v1_19_R3/src/main/java/com/volmit/iris/core/nms/v1_19_R3/NMSBinding.java +++ /dev/null @@ -1,638 +0,0 @@ -package com.volmit.iris.core.nms.v1_19_R3; - -import java.awt.Color; -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.Map; -import java.util.Vector; -import java.util.concurrent.atomic.AtomicInteger; - -import com.mojang.datafixers.util.Pair; -import com.volmit.iris.core.nms.container.BiomeColor; -import com.volmit.iris.util.scheduling.J; -import net.minecraft.nbt.*; -import net.minecraft.nbt.Tag; -import net.minecraft.server.commands.data.BlockDataAccessor; -import net.minecraft.tags.TagKey; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.EntityBlock; -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.CraftBlockState; -import org.bukkit.craftbukkit.v1_19_R3.block.CraftBlockStates; -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.Contract; -import org.jetbrains.annotations.NotNull; - -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.volmit.iris.Iris; -import com.volmit.iris.core.nms.INMSBinding; -import com.volmit.iris.engine.data.cache.AtomicCache; -import com.volmit.iris.engine.framework.Engine; -import com.volmit.iris.util.collection.KList; -import com.volmit.iris.util.collection.KMap; -import com.volmit.iris.util.hunk.Hunk; -import com.volmit.iris.util.json.JSONObject; -import com.volmit.iris.util.mantle.Mantle; -import com.volmit.iris.util.math.Vector3d; -import com.volmit.iris.util.matter.MatterBiomeInject; -import com.volmit.iris.util.nbt.io.NBTUtil; -import com.volmit.iris.util.nbt.mca.NBTWorld; -import com.volmit.iris.util.nbt.mca.palette.*; -import com.volmit.iris.util.nbt.tag.CompoundTag; - -import it.unimi.dsi.fastutil.objects.Object2IntMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.RegistryAccess; -import net.minecraft.core.registries.Registries; -import net.minecraft.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.ChunkStatus; -import net.minecraft.world.level.chunk.LevelChunk; -import sun.misc.Unsafe; - -public class NMSBinding implements INMSBinding { - private final KMap baseBiomeCache = new KMap<>(); - private final BlockData AIR = Material.AIR.createBlockData(); - private final AtomicCache> biomeMapCache = new AtomicCache<>(); - private final AtomicCache> registryCache = new AtomicCache<>(); - private final AtomicCache> globalCache = new AtomicCache<>(); - private final AtomicCache registryAccess = new AtomicCache<>(); - private final AtomicCache byIdRef = new AtomicCache<>(); - private Field biomeStorageCache = null; - - private static Object getFor(Class type, Object source) { - Object o = fieldFor(type, source); - - if (o != null) { - return o; - } - - return invokeFor(type, source); - } - - private static Object invokeFor(Class returns, Object in) { - for (Method i : in.getClass().getMethods()) { - if (i.getReturnType().equals(returns)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returns.getSimpleName() + " in " + in.getClass().getSimpleName() + "." + i.getName() + "()"); - return i.invoke(in); - } catch (Throwable e) { - e.printStackTrace(); - } - } - } - - return null; - } - - private static Object fieldFor(Class returns, Object in) { - return fieldForClass(returns, in.getClass(), in); - } - - @SuppressWarnings("unchecked") - private static T fieldForClass(Class returnType, Class sourceType, Object in) { - for (Field i : sourceType.getDeclaredFields()) { - if (i.getType().equals(returnType)) { - i.setAccessible(true); - try { - Iris.debug("[NMS] Found " + returnType.getSimpleName() + " in " + sourceType.getSimpleName() + "." + i.getName()); - return (T) i.get(in); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - return null; - } - - private static Class getClassType(Class type, int ordinal) { - return type.getDeclaredClasses()[ordinal]; - } - - @Override - public boolean hasTile(Material material) { - return !CraftBlockState.class.equals(CraftBlockStates.getBlockStateType(material)); - } - - @Override - public boolean hasTile(Location l) { - return ((CraftWorld) l.getWorld()).getHandle().getBlockEntity(new BlockPos(l.getBlockX(), l.getBlockY(), l.getBlockZ()), false) != null; - } - - @Override - @SuppressWarnings("unchecked") - public KMap serializeTile(Location location) { - BlockEntity e = ((CraftWorld) location.getWorld()).getHandle().getBlockEntity(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ()), false); - - if (e == null) { - return null; - } - - net.minecraft.nbt.CompoundTag tag = e.saveWithoutMetadata(); - return (KMap) convertFromTag(tag, 0, 64); - } - - @Contract(value = "null, _, _ -> null", pure = true) - private Object convertFromTag(net.minecraft.nbt.Tag tag, int depth, int maxDepth) { - if (tag == null || depth > maxDepth) return null; - if (tag instanceof CollectionTag collection) { - KList list = new KList<>(); - - for (Object i : collection) { - if (i instanceof net.minecraft.nbt.Tag t) - list.add(convertFromTag(t, depth + 1, maxDepth)); - else list.add(i); - } - return list; - } - if (tag instanceof net.minecraft.nbt.CompoundTag compound) { - KMap map = new KMap<>(); - - for (String key : compound.getAllKeys()) { - var child = compound.get(key); - if (child == null) continue; - var value = convertFromTag(child, depth + 1, maxDepth); - if (value == null) continue; - map.put(key, value); - } - return map; - } - if (tag instanceof NumericTag numeric) - return numeric.getAsNumber(); - return tag.getAsString(); - } - - @Override - public void deserializeTile(KMap map, Location pos) { - net.minecraft.nbt.CompoundTag tag = (net.minecraft.nbt.CompoundTag) convertToTag(map, 0, 64); - var level = ((CraftWorld) pos.getWorld()).getHandle(); - var blockPos = new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()); - J.s(() -> merge(level, blockPos, tag)); - } - - private void merge(ServerLevel level, BlockPos blockPos, net.minecraft.nbt.CompoundTag tag) { - var blockEntity = level.getBlockEntity(blockPos); - if (blockEntity == null) { - Iris.warn("[NMS] BlockEntity not found at " + blockPos); - var state = level.getBlockState(blockPos); - if (!state.hasBlockEntity()) - return; - - blockEntity = ((EntityBlock) state.getBlock()) - .newBlockEntity(blockPos, state); - } - var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); - } - - private Tag convertToTag(Object object, int depth, int maxDepth) { - if (object == null || depth > maxDepth) return EndTag.INSTANCE; - if (object instanceof Map map) { - var tag = new net.minecraft.nbt.CompoundTag(); - for (var i : map.entrySet()) { - tag.put(i.getKey().toString(), convertToTag(i.getValue(), depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof List list) { - var tag = new net.minecraft.nbt.ListTag(); - for (var i : list) { - tag.add(convertToTag(i, depth + 1, maxDepth)); - } - return tag; - } - if (object instanceof Byte number) return ByteTag.valueOf(number); - if (object instanceof Short number) return ShortTag.valueOf(number); - if (object instanceof Integer number) return IntTag.valueOf(number); - if (object instanceof Long number) return LongTag.valueOf(number); - if (object instanceof Float number) return FloatTag.valueOf(number); - if (object instanceof Double number) return DoubleTag.valueOf(number); - if (object instanceof String string) return StringTag.valueOf(string); - return EndTag.INSTANCE; - } - - @Override - public CompoundTag serializeEntity(Entity location) { - return null;// TODO: - } - - @Override - public Entity deserializeEntity(CompoundTag s, Location newPosition) { - return null;// TODO: - } - - @Override - public boolean supportsCustomHeight() { - return true; - } - - private RegistryAccess registry() { - return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer())); - } - - private Registry getCustomBiomeRegistry() { - return registry().registry(Registries.BIOME).orElse(null); - } - - private Registry getBlockRegistry() { - return registry().registry(Registries.BLOCK).orElse(null); - } - - @Override - public Object getBiomeBaseFromId(int id) { - return getCustomBiomeRegistry().getHolder(id); - } - - @Override - public int getMinHeight(World world) { - return world.getMinHeight(); - } - - @Override - public boolean supportsCustomBiomes() { - return true; - } - - @Override - public int getTrueBiomeBaseId(Object biomeBase) { - return getCustomBiomeRegistry().getId(((Holder) biomeBase).value()); - } - - @Override - public Object getTrueBiomeBase(Location location) { - return ((CraftWorld) location.getWorld()).getHandle().getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - } - - @Override - public String getTrueBiomeBaseKey(Location location) { - return getKeyForBiomeBase(getTrueBiomeBase(location)); - } - - @Override - public Object getCustomBiomeBaseFor(String mckey) { - return getCustomBiomeRegistry().get(new ResourceLocation(mckey)); - } - - @Override - public Object getCustomBiomeBaseHolderFor(String mckey) { - return getCustomBiomeRegistry().getHolder(getTrueBiomeBaseId(getCustomBiomeRegistry().get(new ResourceLocation(mckey)))).get(); - } - - public int getBiomeBaseIdForKey(String key) { - return getCustomBiomeRegistry().getId(getCustomBiomeRegistry().get(new ResourceLocation(key))); - } - - @Override - public String getKeyForBiomeBase(Object biomeBase) { - return getCustomBiomeRegistry().getKey((net.minecraft.world.level.biome.Biome) biomeBase).getPath(); // something, not something:something - } - - @Override - public Object getBiomeBase(World world, Biome biome) { - return CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle() - .registryAccess().registry(Registries.BIOME).orElse(null), biome); - } - - @Override - public Object getBiomeBase(Object registry, Biome biome) { - Object v = baseBiomeCache.get(biome); - - if (v != null) { - return v; - } - //noinspection unchecked - v = CraftBlock.biomeToBiomeBase((Registry) registry, biome); - if (v == null) { - // Ok so there is this new biome name called "CUSTOM" in Paper's new releases. - // But, this does NOT exist within CraftBukkit which makes it return an error. - // So, we will just return the ID that the plains biome returns instead. - //noinspection unchecked - return CraftBlock.biomeToBiomeBase((Registry) registry, Biome.PLAINS); - } - baseBiomeCache.put(biome, v); - return v; - } - - - @Override - public KList getBiomes() { - return new KList<>(Biome.values()).qdel(Biome.CHERRY_GROVE).qdel(Biome.CUSTOM); - } - - @Override - public boolean isBukkit() { - return true; - } - - @Override - public int getBiomeId(Biome biome) { - for (World i : Bukkit.getWorlds()) { - if (i.getEnvironment().equals(World.Environment.NORMAL)) { - Registry registry = ((CraftWorld) i).getHandle().registryAccess().registry(Registries.BIOME).orElse(null); - return registry.getId((net.minecraft.world.level.biome.Biome) getBiomeBase(registry, biome)); - } - } - - return biome.ordinal(); - } - - private MCAIdMap getBiomeMapping() { - return biomeMapCache.aquire(() -> new MCAIdMap<>() { - @NotNull - @Override - public Iterator iterator() { - return getCustomBiomeRegistry().iterator(); - } - - @Override - public int getId(net.minecraft.world.level.biome.Biome paramT) { - return getCustomBiomeRegistry().getId(paramT); - } - - @Override - public net.minecraft.world.level.biome.Biome byId(int paramInt) { - return (net.minecraft.world.level.biome.Biome) getBiomeBaseFromId(paramInt); - } - }); - } - - @NotNull - private MCABiomeContainer getBiomeContainerInterface(MCAIdMap biomeMapping, MCAChunkBiomeContainer base) { - return new MCABiomeContainer() { - @Override - public int[] getData() { - return base.writeBiomes(); - } - - @Override - public void setBiome(int x, int y, int z, int id) { - base.setBiome(x, y, z, biomeMapping.byId(id)); - } - - @Override - public int getBiome(int x, int y, int z) { - return biomeMapping.getId(base.getBiome(x, y, z)); - } - }; - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public MCABiomeContainer newBiomeContainer(int min, int max, int[] data) { - MCAChunkBiomeContainer base = new MCAChunkBiomeContainer<>(getBiomeMapping(), min, max, data); - return getBiomeContainerInterface(getBiomeMapping(), base); - } - - @Override - public int countCustomBiomes() { - AtomicInteger a = new AtomicInteger(0); - - getCustomBiomeRegistry().keySet().forEach((i) -> { - if (i.getNamespace().equals("minecraft")) { - return; - } - - a.incrementAndGet(); - Iris.debug("Custom Biome: " + i); - }); - - return a.get(); - } - - public boolean supportsDataPacks() { - return true; - } - - public void setBiomes(int cx, int cz, World world, Hunk biomes) { - LevelChunk c = ((CraftWorld) world).getHandle().getChunk(cx, cz); - biomes.iterateSync((x, y, z, b) -> c.setBiome(x, y, z, (Holder) b)); - c.setUnsaved(true); - } - - @Override - public void forceBiomeInto(int x, int y, int z, Object somethingVeryDirty, ChunkGenerator.BiomeGrid chunk) { - try { - ChunkAccess s = (ChunkAccess) getFieldForBiomeStorage(chunk).get(chunk); - Holder biome = (Holder) somethingVeryDirty; - s.setBiome(x, y, z, biome); - } catch (IllegalAccessException e) { - Iris.reportError(e); - e.printStackTrace(); - } - } - - private Field getFieldForBiomeStorage(Object storage) { - Field f = biomeStorageCache; - - if (f != null) { - return f; - } - try { - f = storage.getClass().getDeclaredField("biome"); - f.setAccessible(true); - return f; - } catch (Throwable e) { - Iris.reportError(e); - e.printStackTrace(); - Iris.error(storage.getClass().getCanonicalName()); - } - - biomeStorageCache = f; - return null; - } - - @Override - public MCAPaletteAccess createPalette() { - MCAIdMapper registry = registryCache.aquireNasty(() -> { - Field cf = net.minecraft.core.IdMapper.class.getDeclaredField("tToId"); - Field df = net.minecraft.core.IdMapper.class.getDeclaredField("idToT"); - Field bf = net.minecraft.core.IdMapper.class.getDeclaredField("nextId"); - cf.setAccessible(true); - df.setAccessible(true); - bf.setAccessible(true); - net.minecraft.core.IdMapper blockData = Block.BLOCK_STATE_REGISTRY; - int b = bf.getInt(blockData); - Object2IntMap c = (Object2IntMap) cf.get(blockData); - List d = (List) df.get(blockData); - return new MCAIdMapper(c, d, b); - }); - MCAPalette global = globalCache.aquireNasty(() -> new MCAGlobalPalette<>(registry, ((CraftBlockData) AIR).getState())); - MCAPalettedContainer container = new MCAPalettedContainer<>(global, registry, - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState(), - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - ((CraftBlockData) AIR).getState()); - return new MCAWrappedPalettedContainer<>(container, - i -> NBTWorld.getCompound(CraftBlockData.fromData(i)), - i -> ((CraftBlockData) NBTWorld.getBlockData(i)).getState()); - } - - @Override - public void injectBiomesFromMantle(Chunk e, Mantle mantle) { - ChunkAccess chunk = ((CraftChunk) e).getHandle(ChunkStatus.FULL); - AtomicInteger c = new AtomicInteger(); - AtomicInteger r = new AtomicInteger(); - mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x, y, z, b) -> { - if (b != null) { - if (b.isCustom()) { - chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get()); - c.getAndIncrement(); - } else { - chunk.setBiome(x, y, z, (Holder) getBiomeBase(e.getWorld(), b.getBiome())); - r.getAndIncrement(); - } - } - }); - } - - public ItemStack applyCustomNbt(ItemStack itemStack, KMap customNbt) throws IllegalArgumentException { - if (customNbt != null && !customNbt.isEmpty()) { - net.minecraft.world.item.ItemStack s = CraftItemStack.asNMSCopy(itemStack); - - try { - net.minecraft.nbt.CompoundTag tag = TagParser.parseTag((new JSONObject(customNbt)).toString()); - tag.merge(s.getOrCreateTag()); - s.setTag(tag); - } catch (CommandSyntaxException var5) { - throw new IllegalArgumentException(var5); - } - - return CraftItemStack.asBukkitCopy(s); - } else { - return itemStack; - } - } - - public void setTreasurePos(Dolphin dolphin, com.volmit.iris.core.nms.container.BlockPos pos) { - CraftDolphin cd = (CraftDolphin)dolphin; - cd.getHandle().setTreasurePos(new BlockPos(pos.getX(), pos.getY(), pos.getZ())); - cd.getHandle().setGotFish(true); - } - - public void inject(long seed, Engine engine, World world) { - var chunkMap = ((CraftWorld)world).getHandle().getChunkSource().chunkMap; - chunkMap.generator = new IrisChunkGenerator(chunkMap.generator, seed, engine, world); - } - - public Vector3d getBoundingbox(org.bukkit.entity.EntityType entity) { - Field[] fields = EntityType.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers()) && field.getType().equals(EntityType.class)) { - try { - EntityType entityType = (EntityType) field.get(null); - if (entityType.getDescriptionId().equals("entity.minecraft." + entity.name().toLowerCase())) { - Vector v1 = new Vector<>(); - v1.add(entityType.getHeight()); - entityType.getDimensions(); - Vector3d box = new Vector3d( entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); - //System.out.println("Entity Type: " + entityType.getDescriptionId() + ", " + "Height: " + height + ", Width: " + width); - return box; - } - } catch (IllegalAccessException e) { - Iris.error("Unable to get entity dimensions!"); - e.printStackTrace(); - } - } - } - return null; - } - - @Override - public Entity spawnEntity(Location location, org.bukkit.entity.EntityType type, CreatureSpawnEvent.SpawnReason reason) { - if (type == org.bukkit.entity.EntityType.CAMEL) { - return null; - } - return ((CraftWorld) location.getWorld()).spawn(location, type.getEntityClass(), null, reason); - } - - @Override - public Color getBiomeColor(Location location, BiomeColor type) { - LevelReader reader = ((CraftWorld) location.getWorld()).getHandle(); - var holder = reader.getBiome(new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ())); - var biome = holder.value(); - if (biome == null) throw new IllegalArgumentException("Invalid biome: " + holder.unwrapKey().orElse(null)); - - int rgba = switch (type) { - case FOG -> biome.getFogColor(); - case WATER -> biome.getWaterColor(); - case WATER_FOG -> biome.getWaterFogColor(); - case SKY -> biome.getSkyColor(); - case FOLIAGE -> biome.getFoliageColor(); - case GRASS -> biome.getGrassColor(location.getBlockX(), location.getBlockZ()); - }; - if (rgba == 0) { - if (BiomeColor.FOLIAGE == type && biome.getSpecialEffects().getFoliageColorOverride().isEmpty()) - return null; - if (BiomeColor.GRASS == type && biome.getSpecialEffects().getGrassColorOverride().isEmpty()) - return null; - } - return new Color(rgba, true); - } - - @Override - public KList getStructureKeys() { - KList keys = new KList<>(); - - var registry = registry().registry(Registries.STRUCTURE).orElse(null); - if (registry == null) return keys; - registry.keySet().stream().map(ResourceLocation::toString).forEach(keys::add); - registry.getTags() - .map(Pair::getFirst) - .map(TagKey::location) - .map(ResourceLocation::toString) - .map(s -> "#" + s) - .forEach(keys::add); - - return keys; - } - - private static Field getField(Class clazz, Class fieldType) throws NoSuchFieldException { - try { - for (Field f : clazz.getDeclaredFields()) { - if (f.getType().equals(fieldType)) - return f; - } - throw new NoSuchFieldException(fieldType.getName()); - } catch (NoSuchFieldException var4) { - Class superClass = clazz.getSuperclass(); - if (superClass == null) { - throw var4; - } else { - return getField(superClass, fieldType); - } - } - } -} 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 d737ec6aa..a9ad26383 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 @@ -214,7 +214,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { 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 c14400975..804f35074 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 @@ -212,7 +212,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { 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 c69d2a66e..59a124514 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 @@ -212,7 +212,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { diff --git a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java index 9933dbbb0..ea7518d6a 100644 --- a/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java +++ b/nms/v1_20_R4/src/main/java/com/volmit/iris/core/nms/v1_20_R4/NMSBinding.java @@ -216,7 +216,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { diff --git a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java index 7f5662d1d..be0a12f5b 100644 --- a/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java +++ b/nms/v1_21_R1/src/main/java/com/volmit/iris/core/nms/v1_21_R1/NMSBinding.java @@ -215,7 +215,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { diff --git a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java index d5b2e82b6..0522d35f9 100644 --- a/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java +++ b/nms/v1_21_R2/src/main/java/com/volmit/iris/core/nms/v1_21_R2/NMSBinding.java @@ -202,7 +202,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { diff --git a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java index bd332251c..7a5ac4f9d 100644 --- a/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java +++ b/nms/v1_21_R3/src/main/java/com/volmit/iris/core/nms/v1_21_R3/NMSBinding.java @@ -201,7 +201,7 @@ public class NMSBinding implements INMSBinding { .newBlockEntity(blockPos, state); } var accessor = new BlockDataAccessor(blockEntity, blockPos); - accessor.setData(tag.merge(accessor.getData())); + accessor.setData(accessor.getData().merge(tag)); } private Tag convertToTag(Object object, int depth, int maxDepth) { diff --git a/settings.gradle b/settings.gradle index 7371bdae6..57ad35b97 100644 --- a/settings.gradle +++ b/settings.gradle @@ -37,7 +37,4 @@ include( ':nms:v1_20_R3', ':nms:v1_20_R2', ':nms:v1_20_R1', - ':nms:v1_19_R3', - ':nms:v1_19_R2', - ':nms:v1_19_R1' ) \ No newline at end of file