mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-04-22 16:09:16 +00:00
replace datapack system with a dynamic one
This commit is contained in:
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R1;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -11,6 +12,7 @@ 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.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
@@ -25,6 +27,7 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomBiomeSource extends BiomeSource {
|
||||
private final long seed;
|
||||
@@ -118,8 +121,28 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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());
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
ResourceKey<Biome> biomeKey = optionalBiomeKey.get();
|
||||
Optional<Holder<Biome>> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
@@ -587,51 +584,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registry.BIOME_REGISTRY, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registry.BIOME_REGISTRY, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R2;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -12,6 +13,7 @@ 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;
|
||||
@@ -26,6 +28,7 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class CustomBiomeSource extends BiomeSource {
|
||||
|
||||
@@ -120,8 +123,28 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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());
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
ResourceKey<Biome> biomeKey = optionalBiomeKey.get();
|
||||
Optional<Holder.Reference<Biome>> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
@@ -589,51 +586,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_19_R3;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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);
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
|
||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
@@ -593,51 +590,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R1;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -125,8 +126,16 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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);
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
|
||||
@@ -12,12 +12,12 @@ import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMSBinding;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.collection.KList;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.json.JSONObject;
|
||||
import com.volmit.iris.util.mantle.Mantle;
|
||||
import com.volmit.iris.util.math.Vector3d;
|
||||
@@ -47,7 +47,6 @@ import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.RandomSequences;
|
||||
import net.minecraft.world.entity.EntityDimensions;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
@@ -73,9 +72,7 @@ import org.bukkit.craftbukkit.v1_20_R1.entity.CraftDolphin;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -87,12 +84,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -580,51 +574,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R2;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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);
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
|
||||
@@ -5,12 +5,9 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -26,9 +23,9 @@ import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
@@ -590,51 +587,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R3;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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);
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
|
||||
@@ -66,6 +66,14 @@ public class Headless implements IHeadless, LevelHeightAccessor {
|
||||
};
|
||||
queueLooper.setName("Region Save Looper");
|
||||
queueLooper.start();
|
||||
|
||||
var dimKey = engine.getDimension().getLoadKey();
|
||||
for (var biome : engine.getAllBiomes()) {
|
||||
if (!biome.isCustom()) continue;
|
||||
for (var custom : biome.getCustomDerivitives()) {
|
||||
binding.registerBiome(dimKey, custom, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
@@ -23,16 +21,9 @@ import com.mojang.serialization.JsonOps;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import com.volmit.iris.core.nms.IHeadless;
|
||||
import com.volmit.iris.core.nms.v1_20_R3.mca.ChunkSerializer;
|
||||
import com.volmit.iris.core.nms.v1_20_R3.mca.MCATerrainChunk;
|
||||
import com.volmit.iris.core.nms.v1_20_R3.mca.RegionFileStorage;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.documentation.RegionCoordinates;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
|
||||
import com.volmit.iris.util.hunk.view.ChunkDataHunkHolder;
|
||||
import com.volmit.iris.util.io.IO;
|
||||
import com.volmit.iris.util.parallel.MultiBurst;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
@@ -601,51 +592,10 @@ public class NMSBinding implements INMSBinding {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDatapack(File folder, boolean replace) {
|
||||
var data = new File(folder, "iris/data");
|
||||
if (!data.exists() || !data.isDirectory()) return false;
|
||||
FilenameFilter jsonFilter = (dir, name) -> new File(dir, name).isFile() && name.toLowerCase().endsWith(".json");
|
||||
|
||||
var files = data.listFiles((dir, name) -> new File(dir, name).isDirectory());
|
||||
if (files == null) return false;
|
||||
for (File file : files) {
|
||||
var biome = new File(file, "worldgen/biome");
|
||||
if (!biome.exists()) continue;
|
||||
var biomeFiles = biome.listFiles(jsonFilter);
|
||||
if (biomeFiles == null) continue;
|
||||
for (File biomeFile : biomeFiles) {
|
||||
String json = null;
|
||||
int tries = 10;
|
||||
while (json == null && tries-- > 0) {
|
||||
try {
|
||||
json = IO.readAll(biomeFile);
|
||||
} catch (IOException e) {
|
||||
Iris.error("Failed to read biome " + file.getName() + ":" + biomeFile.getName() + " tries left: " + tries);
|
||||
if (tries == 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException ignored) {}
|
||||
}
|
||||
}
|
||||
if (json == null) continue;
|
||||
|
||||
try {
|
||||
var value = decode(net.minecraft.world.level.biome.Biome.CODEC, json).map(Holder::value).orElse(null);
|
||||
register(Registries.BIOME, from(file.getName(), biomeFile), value, replace);
|
||||
} catch (Throwable e) {
|
||||
Iris.error("Failed to register biome " + file.getName() + ":" + biomeFile.getName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private ResourceLocation from(String namespace, File file) {
|
||||
var name = file.getName();
|
||||
return new ResourceLocation(namespace, name.substring(0, name.lastIndexOf('.')));
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.volmit.iris.core.nms.v1_20_R4;
|
||||
|
||||
import com.mojang.serialization.MapCodec;
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.cache.AtomicCache;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -124,8 +125,16 @@ public class CustomBiomeSource extends BiomeSource {
|
||||
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);
|
||||
ResourceLocation location = new ResourceLocation(engine.getDimension().getLoadKey() + ":" + j.getId());
|
||||
Biome biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
INMS.get().registerBiome(location.getNamespace(), j, false);
|
||||
biome = customRegistry.get(location);
|
||||
if (biome == null) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Optional<ResourceKey<Biome>> optionalBiomeKey = customRegistry.getResourceKey(biome);
|
||||
if (optionalBiomeKey.isEmpty()) {
|
||||
Iris.error("Cannot find biome for IrisBiomeCustom " + j.getId() + " from engine " + engine.getName());
|
||||
|
||||
@@ -4,18 +4,47 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
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.Optional;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import com.volmit.iris.core.nms.datapack.DataVersion;
|
||||
import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.engine.object.IrisDimension;
|
||||
import com.volmit.iris.util.format.C;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.asm.Advice;
|
||||
import net.bytebuddy.dynamic.loading.ClassReloadingStrategy;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.RegistrationInfo;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.RandomSequences;
|
||||
import net.minecraft.world.item.component.CustomData;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
import net.minecraft.world.level.storage.LevelStorageSource;
|
||||
import net.minecraft.world.level.storage.PrimaryLevelData;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
@@ -29,6 +58,7 @@ import org.bukkit.craftbukkit.v1_20_R4.util.CraftNamespacedKey;
|
||||
import org.bukkit.entity.Dolphin;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -549,4 +579,189 @@ public class NMSBinding implements INMSBinding {
|
||||
public DataVersion getDataVersion() {
|
||||
return DataVersion.V1205;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerDimension(String name, IrisDimension dimension) {
|
||||
var registry = registry(Registries.DIMENSION_TYPE);
|
||||
var baseLocation = switch (dimension.getEnvironment()) {
|
||||
case NORMAL -> new ResourceLocation("minecraft", "overworld");
|
||||
case NETHER -> new ResourceLocation("minecraft", "the_nether");
|
||||
case THE_END -> new ResourceLocation("minecraft", "the_end");
|
||||
case CUSTOM -> throw new IllegalArgumentException("Cannot register custom dimension");
|
||||
};
|
||||
var base = registry.getHolder(ResourceKey.create(Registries.DIMENSION_TYPE, baseLocation)).orElse(null);
|
||||
if (base == null) return false;
|
||||
var json = encode(DimensionType.CODEC, base).orElse(null);
|
||||
if (json == null) return false;
|
||||
var object = json.getAsJsonObject();
|
||||
var height = dimension.getDimensionHeight();
|
||||
object.addProperty("min_y", height.getMin());
|
||||
object.addProperty("height", height.getMax() - height.getMin());
|
||||
object.addProperty("logical_height", dimension.getLogicalHeight());
|
||||
var value = decode(DimensionType.CODEC, object.toString()).map(Holder::value).orElse(null);
|
||||
if (value == null) return false;
|
||||
return register(Registries.DIMENSION_TYPE, new ResourceLocation("iris", name), value, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBiome(String dimensionId, IrisBiomeCustom biome, boolean replace) {
|
||||
var biomeBase = decode(net.minecraft.world.level.biome.Biome.CODEC, biome.generateJson()).map(Holder::value).orElse(null);
|
||||
if (biomeBase == null) return false;
|
||||
return register(Registries.BIOME, new ResourceLocation(dimensionId, biome.getId()), biomeBase, replace);
|
||||
}
|
||||
|
||||
private <T> Optional<T> decode(Codec<T> codec, String json) {
|
||||
return codec.decode(JsonOps.INSTANCE, GsonHelper.parse(json)).result().map(Pair::getFirst);
|
||||
}
|
||||
|
||||
private <T> Optional<JsonElement> encode(Codec<T> codec, T value) {
|
||||
return codec.encode(value, JsonOps.INSTANCE, new JsonObject()).result();
|
||||
}
|
||||
|
||||
private <T> boolean register(ResourceKey<Registry<T>> registryKey, ResourceLocation location, T value, boolean replace) {
|
||||
Preconditions.checkArgument(registryKey != null, "The registry cannot be null!");
|
||||
Preconditions.checkArgument(location != null, "The location cannot be null!");
|
||||
Preconditions.checkArgument(value != null, "The value cannot be null!");
|
||||
var registry = registry(registryKey);
|
||||
var key = ResourceKey.create(registryKey, location);
|
||||
try {
|
||||
if (registry.containsKey(key)) {
|
||||
if (!replace) return false;
|
||||
return replace(registryKey, location, value);
|
||||
}
|
||||
Field field = getField(MappedRegistry.class, boolean.class);
|
||||
field.setAccessible(true);
|
||||
boolean frozen = field.getBoolean(registry);
|
||||
field.setBoolean(registry, false);
|
||||
Field valueField = getField(Holder.Reference.class, "T");
|
||||
valueField.setAccessible(true);
|
||||
|
||||
try {
|
||||
var holder = registry.register(key, value, RegistrationInfo.BUILT_IN);
|
||||
if (frozen) valueField.set(holder, value);
|
||||
return true;
|
||||
} finally {
|
||||
field.setBoolean(registry, frozen);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> boolean replace(ResourceKey<Registry<T>> registryKey, ResourceLocation location, T value) {
|
||||
Preconditions.checkArgument(registryKey != null, "The registryKey cannot be null!");
|
||||
Preconditions.checkArgument(location != null, "The location cannot be null!");
|
||||
Preconditions.checkArgument(value != null, "The value cannot be null!");
|
||||
var registry = registry(registryKey);
|
||||
var key = ResourceKey.create(registryKey, location);
|
||||
try {
|
||||
var holder = registry.getHolder(key).orElse(null);
|
||||
if (holder == null) return false;
|
||||
var oldValue = holder.value();
|
||||
Field valueField = getField(Holder.Reference.class, "T");
|
||||
valueField.setAccessible(true);
|
||||
Field toIdField = getField(MappedRegistry.class, buildType(Reference2IntMap.class, "T"));
|
||||
toIdField.setAccessible(true);
|
||||
Field byValueField = getField(MappedRegistry.class, buildType(Map.class, "T", buildType(Holder.Reference.class, "T")));
|
||||
byValueField.setAccessible(true);
|
||||
var toId = (Reference2IntMap<T>) toIdField.get(registry);
|
||||
var byValue = (Map<T, Holder.Reference<T>>) byValueField.get(registry);
|
||||
|
||||
valueField.set(holder, value);
|
||||
toId.put(value, toId.removeInt(oldValue));
|
||||
byValue.put(value, byValue.remove(oldValue));
|
||||
return true;
|
||||
} catch (Throwable e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> MappedRegistry<T> registry(ResourceKey<Registry<T>> registryKey) {
|
||||
var rawRegistry = registry().registry(registryKey).orElse(null);
|
||||
if (!(rawRegistry instanceof MappedRegistry<T> registry))
|
||||
throw new IllegalStateException("The Registry is not a mapped Registry!");
|
||||
return registry;
|
||||
}
|
||||
|
||||
private static String buildType(Class<?> clazz, String... parameterTypes) {
|
||||
if (parameterTypes.length == 0) return clazz.getName();
|
||||
var builder = new StringBuilder(clazz.getName())
|
||||
.append("<");
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
builder.append(parameterTypes[i]).append(parameterTypes.length - 1 == i ? ">" : ", ");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static Field getField(Class<?> clazz, String type) throws NoSuchFieldException {
|
||||
try {
|
||||
for (Field f : clazz.getDeclaredFields()) {
|
||||
if (f.getGenericType().getTypeName().equals(type))
|
||||
return f;
|
||||
}
|
||||
throw new NoSuchFieldException(type);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Class<?> superClass = clazz.getSuperclass();
|
||||
if (superClass == null) throw e;
|
||||
return getField(superClass, type);
|
||||
}
|
||||
}
|
||||
|
||||
public void injectBukkit() {
|
||||
try {
|
||||
Iris.info("Injecting Bukkit");
|
||||
new ByteBuddy()
|
||||
.redefine(WorldCreator.class)
|
||||
.visit(Advice.to(WorldCreatorAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(String.class))))
|
||||
.make()
|
||||
.load(WorldCreator.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
|
||||
new ByteBuddy()
|
||||
.redefine(ServerLevel.class)
|
||||
.visit(Advice.to(ServerLevelAdvice.class).on(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(MinecraftServer.class, Executor.class, LevelStorageSource.LevelStorageAccess.class,
|
||||
PrimaryLevelData.class, ResourceKey.class, LevelStem.class, ChunkProgressListener.class, boolean.class, long.class,
|
||||
List.class, boolean.class, RandomSequences.class, World.Environment.class, ChunkGenerator.class, BiomeProvider.class))))
|
||||
.make()
|
||||
.load(ServerLevel.class.getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
|
||||
Iris.info("Injected Bukkit Successfully!");
|
||||
} catch (Exception e) {
|
||||
Iris.info(C.RED + "Failed to Inject Bukkit!");
|
||||
e.printStackTrace();
|
||||
Iris.reportError(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class ServerLevelAdvice {
|
||||
@Advice.OnMethodEnter
|
||||
static void enter(@Advice.Argument(0) MinecraftServer server, @Advice.Argument(2) LevelStorageSource.LevelStorageAccess access, @Advice.Argument(4) ResourceKey<Level> key, @Advice.Argument(value = 5, readOnly = false) LevelStem levelStem) {
|
||||
File iris = new File(access.levelDirectory.path().toFile(), "iris");
|
||||
if (!iris.exists() && !key.location().getPath().startsWith("iris/")) return;
|
||||
ResourceKey<DimensionType> typeKey = ResourceKey.create(Registries.DIMENSION_TYPE, new ResourceLocation("iris", key.location().getPath()));
|
||||
RegistryAccess registryAccess = server.registryAccess();
|
||||
Registry<DimensionType> registry = registryAccess.registry(Registries.DIMENSION_TYPE).orElse(null);
|
||||
if (registry == null) throw new IllegalStateException("Unable to find registry for dimension type " + typeKey);
|
||||
Holder<DimensionType> holder = registry.getHolder(typeKey).orElse(null);
|
||||
if (holder == null) throw new IllegalStateException("Unable to find dimension type " + typeKey);
|
||||
levelStem = new LevelStem(holder, levelStem.generator());
|
||||
}
|
||||
}
|
||||
|
||||
private static class WorldCreatorAdvice {
|
||||
@Advice.OnMethodEnter
|
||||
static void enter(@Advice.Argument(0) String name) {
|
||||
File isIrisWorld = new File(name, "iris");
|
||||
boolean isFromIris = false;
|
||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
||||
for (StackTraceElement stack : stackTrace) {
|
||||
if (stack.getClassName().contains("Iris")) {
|
||||
isFromIris = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isFromIris) {
|
||||
Preconditions.checkArgument(!isIrisWorld.exists(), "Only Iris can load Iris Worlds!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user