mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-12-23 09:09:15 +00:00
Dirrrrrrrrrrrrty
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package com.volmit.iris.core.nms.v19_2;
|
||||
|
||||
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<Biome> biomeCustomRegistry;
|
||||
private final Registry<Biome> biomeRegistry;
|
||||
private final AtomicCache<RegistryAccess> registryAccess = new AtomicCache<>();
|
||||
private final RNG rng;
|
||||
private final KMap<String, Holder<Biome>> 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 KMap<String, Holder<Biome>> fillCustomBiomes(Registry<Biome> customRegistry, Engine engine) {
|
||||
KMap<String, Holder<Biome>> 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 static List<Holder<Biome>> getAllBiomes(Registry<Biome> customRegistry, Registry<Biome> registry, Engine engine) {
|
||||
List<Holder<Biome>> 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 RegistryAccess registry() {
|
||||
return registryAccess.aquire(() -> (RegistryAccess) getFor(RegistryAccess.Frozen.class, ((CraftServer) Bukkit.getServer()).getHandle().getServer()));
|
||||
}
|
||||
|
||||
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> T fieldForClass(Class<T> 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 Codec<? extends BiomeSource> codec() {
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Holder<Biome> getNoiseBiome(int x, int y, int z, Climate.Sampler sampler) {
|
||||
IrisBiome ib = engine.getComplex().getTrueBiomeStream().get(x, z);
|
||||
if(ib.isCustom()) {
|
||||
return customBiomes.get(ib.getCustomBiome(rng, x, 0, z).getId());
|
||||
} else {
|
||||
org.bukkit.block.Biome v = ib.getSkyBiome(rng, x, 0, z);
|
||||
return CraftBlock.biomeToBiomeBase(biomeRegistry, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,23 +164,7 @@ public class NMSBinding19_2 implements INMSBinding {
|
||||
|
||||
@Override
|
||||
public Object getBiomeBaseFromId(int id) {
|
||||
try {
|
||||
return byIdRef.aquire(() -> {
|
||||
for(Method i : IdMap.class.getDeclaredMethods()) {
|
||||
if(i.getParameterCount() == 1 && i.getParameterTypes()[0].equals(int.class)) {
|
||||
Iris.info("[NMS] Found byId method in " + IdMap.class.getSimpleName() + "." + i.getName() + "(int) => " + Biome.class.getSimpleName());
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
Iris.error("Cannot find byId method!");
|
||||
return null;
|
||||
}).invoke(getCustomBiomeRegistry(), id);
|
||||
} catch(IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
return getCustomBiomeRegistry().getHolder(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,7 +212,8 @@ public class NMSBinding19_2 implements INMSBinding {
|
||||
|
||||
@Override
|
||||
public Object getBiomeBase(World world, Biome biome) {
|
||||
return getBiomeBase(((CraftWorld) world).getHandle().registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null), biome);
|
||||
return org.bukkit.craftbukkit.v1_19_R1.block.CraftBlock.biomeToBiomeBase(((CraftWorld) world).getHandle()
|
||||
.registryAccess().registry(Registry.BIOME_REGISTRY).orElse(null), biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -412,7 +397,7 @@ public class NMSBinding19_2 implements INMSBinding {
|
||||
mantle.iterateChunk(e.getX(), e.getZ(), MatterBiomeInject.class, (x,y,z,b) -> {
|
||||
if(b != null) {
|
||||
if(b.isCustom()) {
|
||||
chunk.setBiome(x, y, z, (Holder<net.minecraft.world.level.biome.Biome>) getBiomeBaseFromId(b.getBiomeId()));
|
||||
chunk.setBiome(x, y, z, getCustomBiomeRegistry().getHolder(b.getBiomeId()).get());
|
||||
c.getAndIncrement();
|
||||
}
|
||||
|
||||
@@ -422,8 +407,6 @@ public class NMSBinding19_2 implements INMSBinding {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Iris.info("Injected " + c.get() + " custom biomes and " + r.get() + " vanilla biomes into chunk " + e.getX() + "," + e.getZ());
|
||||
}
|
||||
|
||||
private static Object getFor(Class<?> type, Object source) {
|
||||
|
||||
@@ -480,7 +480,7 @@ public class IrisWorldManager extends EngineAssignedWorldManager {
|
||||
getEngine().cleanupMantleChunk(e.getX(), e.getZ());
|
||||
|
||||
if(generated) {
|
||||
INMS.get().injectBiomesFromMantle(e, getMantle());
|
||||
//INMS.get().injectBiomesFromMantle(e, getMantle());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,7 @@
|
||||
|
||||
package com.volmit.iris.engine.actuator;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.nms.INMS;
|
||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||
import com.volmit.iris.engine.framework.Engine;
|
||||
import com.volmit.iris.engine.framework.EngineAssignedActuator;
|
||||
import com.volmit.iris.engine.object.IrisBiome;
|
||||
@@ -28,17 +26,12 @@ import com.volmit.iris.engine.object.IrisBiomeCustom;
|
||||
import com.volmit.iris.util.context.ChunkContext;
|
||||
import com.volmit.iris.util.documentation.BlockCoordinates;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkHolder;
|
||||
import com.volmit.iris.util.hunk.view.BiomeGridHunkView;
|
||||
import com.volmit.iris.util.math.RNG;
|
||||
import com.volmit.iris.util.matter.MatterBiomeInject;
|
||||
import com.volmit.iris.util.matter.slices.BiomeInjectMatter;
|
||||
import com.volmit.iris.util.parallel.BurstExecutor;
|
||||
import com.volmit.iris.util.scheduling.ChronoLatch;
|
||||
import com.volmit.iris.util.scheduling.PrecisionStopwatch;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
private final RNG rng;
|
||||
@@ -52,8 +45,7 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
@BlockCoordinates
|
||||
@Override
|
||||
public void onActuate(int x, int z, Hunk<Biome> h, boolean multicore, ChunkContext context) {
|
||||
try
|
||||
{
|
||||
try {
|
||||
PrecisionStopwatch p = PrecisionStopwatch.start();
|
||||
|
||||
int m = 0;
|
||||
@@ -61,7 +53,6 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
IrisBiome ib;
|
||||
for(int zf = 0; zf < h.getDepth(); zf++) {
|
||||
ib = context.getBiome().get(xf, zf);
|
||||
int maxHeight = (int) (getComplex().getFluidHeight() + ib.getMaxWithObjectHeight(getData()));
|
||||
MatterBiomeInject matter = null;
|
||||
|
||||
if(ib.isCustom()) {
|
||||
@@ -72,21 +63,13 @@ public class IrisBiomeActuator extends EngineAssignedActuator<Biome> {
|
||||
matter = BiomeInjectMatter.get(v);
|
||||
}
|
||||
|
||||
for(int i = 0; i < maxHeight; i++) {
|
||||
getEngine().getMantle().getMantle().set(x, i, z, matter);
|
||||
m++;
|
||||
}
|
||||
|
||||
getEngine().getMantle().getMantle().set(x + xf, 0, z + zf, matter);
|
||||
m++;
|
||||
}
|
||||
}
|
||||
|
||||
getEngine().getMetrics().getBiome().put(p.getMilliseconds());
|
||||
Iris.info("Biome Actuator: " + p.getMilliseconds() + "ms");
|
||||
Iris.info("Mantle: " + m + " blocks");
|
||||
}
|
||||
|
||||
catch(Throwable e)
|
||||
{
|
||||
} catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ public class ModeOverworld extends IrisEngineMode implements EngineMode {
|
||||
EngineStage sPerfection = (x, z, k, p, m, c) -> perfection.modify(x, z, k, m, c);
|
||||
|
||||
registerStage(burst(
|
||||
sBiome,
|
||||
sGenMatter,
|
||||
sTerrain
|
||||
));
|
||||
|
||||
@@ -20,6 +20,7 @@ package com.volmit.iris.engine.platform;
|
||||
|
||||
import com.volmit.iris.Iris;
|
||||
import com.volmit.iris.core.loader.IrisData;
|
||||
import com.volmit.iris.core.nms.v19_2.CustomBiomeSource;
|
||||
import com.volmit.iris.core.service.StudioSVC;
|
||||
import com.volmit.iris.engine.IrisEngine;
|
||||
import com.volmit.iris.engine.data.chunk.TerrainChunk;
|
||||
@@ -44,6 +45,10 @@ import com.volmit.iris.util.stream.utility.ProfiledStream;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.ServerLevelAccessor;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.HeightMap;
|
||||
@@ -51,16 +56,26 @@ import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftServer;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.generator.CustomChunkGenerator;
|
||||
import org.bukkit.craftbukkit.v1_19_R1.generator.InternalChunkGenerator;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.generator.BiomeProvider;
|
||||
import org.bukkit.generator.BlockPopulator;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
import org.bukkit.generator.WorldInfo;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Semaphore;
|
||||
@@ -71,7 +86,7 @@ import java.util.function.Consumer;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator {
|
||||
public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChunkGenerator, Listener {
|
||||
private static final int LOAD_LOCKS = Runtime.getRuntime().availableProcessors() * 4;
|
||||
private final Semaphore loadLock;
|
||||
private final IrisWorld world;
|
||||
@@ -102,6 +117,43 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
this.dataLocation = dataLocation;
|
||||
this.dimensionKey = dimensionKey;
|
||||
this.folder = new ReactiveFolder(dataLocation, (_a, _b, _c) -> hotload());
|
||||
Bukkit.getServer().getPluginManager().registerEvents(this, Iris.instance);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
try {
|
||||
ServerLevel serverLevel = ((CraftWorld)event.getWorld()).getHandle();
|
||||
Engine engine = getEngine(event.getWorld());
|
||||
Class<?> clazz = serverLevel.getChunkSource().chunkMap.generator.getClass();
|
||||
Field biomeSource = getField(clazz, "c");
|
||||
biomeSource.setAccessible(true);
|
||||
Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
unsafeField.setAccessible(true);
|
||||
Unsafe unsafe = (Unsafe) unsafeField.get(null);
|
||||
CustomBiomeSource customBiomeSource = new CustomBiomeSource(event.getWorld().getSeed(), engine, event.getWorld());
|
||||
unsafe.putObject(biomeSource.get(serverLevel.getChunkSource().chunkMap.generator), unsafe.objectFieldOffset(biomeSource), customBiomeSource);
|
||||
biomeSource.set(serverLevel.getChunkSource().chunkMap.generator, customBiomeSource);
|
||||
Iris.info("Injected Iris Biome Source into " + event.getWorld().getName());
|
||||
}
|
||||
|
||||
catch(Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static Field getField(Class clazz, String fieldName)
|
||||
throws NoSuchFieldException {
|
||||
try {
|
||||
return clazz.getDeclaredField(fieldName);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Class superClass = clazz.getSuperclass();
|
||||
if (superClass == null) {
|
||||
throw e;
|
||||
} else {
|
||||
return getField(superClass, fieldName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupEngine() {
|
||||
@@ -236,7 +288,6 @@ public class BukkitChunkGenerator extends ChunkGenerator implements PlatformChun
|
||||
|
||||
lock.unlock();
|
||||
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user