From 2141e7489e615cdf363fb10028002a1bb2958905 Mon Sep 17 00:00:00 2001 From: dfsek Date: Sun, 12 Jun 2022 16:12:21 -0700 Subject: [PATCH] add 1.19 NMS module --- platforms/bukkit/build.gradle.kts | 3 + .../bukkit/nms/v1_19_R1/build.gradle.kts | 16 ++ .../bukkit/nms/v1_19_R1/NMSBiomeInfo.java | 10 + .../bukkit/nms/v1_19_R1/NMSBiomeInjector.java | 188 ++++++++++++++ .../bukkit/nms/v1_19_R1/NMSBiomeProvider.java | 54 ++++ .../v1_19_R1/NMSChunkGeneratorDelegate.java | 239 ++++++++++++++++++ .../bukkit/nms/v1_19_R1/NMSInitializer.java | 15 ++ .../nms/v1_19_R1/NMSInjectListener.java | 52 ++++ .../nms/v1_19_R1/NMSWorldProperties.java | 36 +++ .../terra/bukkit/nms/v1_19_R1/Registries.java | 30 +++ 10 files changed, 643 insertions(+) create mode 100644 platforms/bukkit/nms/v1_19_R1/build.gradle.kts create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java create mode 100644 platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java diff --git a/platforms/bukkit/build.gradle.kts b/platforms/bukkit/build.gradle.kts index 97ca84242..94c915197 100644 --- a/platforms/bukkit/build.gradle.kts +++ b/platforms/bukkit/build.gradle.kts @@ -4,6 +4,9 @@ import java.nio.channels.Channels import java.nio.file.Files import java.nio.file.StandardCopyOption +plugins { + id("xyz.jpenilla.run-paper") version "1.0.6" +} val mcVersion = "1.18.2" val testDir = "target/server" diff --git a/platforms/bukkit/nms/v1_19_R1/build.gradle.kts b/platforms/bukkit/nms/v1_19_R1/build.gradle.kts new file mode 100644 index 000000000..868c0a8de --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + id("io.papermc.paperweight.userdev") version "1.3.3" +} + +dependencies { + api(project(":platforms:bukkit:common")) + paperDevBundle("1.19-R0.1-SNAPSHOT") + + compileOnly(group = "org.spigotmc", name = "spigot", version = "1.18.2-R0.1-SNAPSHOT") +} + +tasks { + assemble { + dependsOn(reobfJar) + } +} \ No newline at end of file diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java new file mode 100644 index 000000000..7a6f08424 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInfo.java @@ -0,0 +1,10 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import com.dfsek.terra.api.properties.Properties; + +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.level.biome.BiomeBase; + + +public record NMSBiomeInfo(ResourceKey biomeKey) implements Properties { +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java new file mode 100644 index 000000000..451fc5863 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeInjector.java @@ -0,0 +1,188 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import com.google.common.collect.ImmutableMap; +import com.mojang.serialization.Lifecycle; +import net.minecraft.core.Holder; +import net.minecraft.core.IRegistry; +import net.minecraft.core.IRegistryWritable; +import net.minecraft.core.RegistryMaterials; +import net.minecraft.data.RegistryGeneration; +import net.minecraft.resources.MinecraftKey; +import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.TagKey; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.biome.BiomeFog; +import net.minecraft.world.level.biome.BiomeFog.GrassColor; +import net.minecraft.world.level.biome.BiomeSettingsGeneration; +import net.minecraft.world.level.biome.BiomeSettingsMobs; +import org.bukkit.NamespacedKey; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.world.biome.Biome; +import com.dfsek.terra.bukkit.config.VanillaBiomeProperties; +import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; +import com.dfsek.terra.registry.master.ConfigRegistry; + + +public class NMSBiomeInjector { + private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.class); + private static final Map> terraBiomeMap = new HashMap<>(); + + + public static void registerBiomes(ConfigRegistry configRegistry) { + try { + LOGGER.info("Hacking biome registry..."); + IRegistryWritable biomeRegistry = (IRegistryWritable) Registries.biomeRegistry(); + Field frozen = RegistryMaterials.class.getDeclaredField("bL"); // registry frozen field + frozen.setAccessible(true); + frozen.set(biomeRegistry, false); + + configRegistry.forEach(pack -> pack.getRegistry(Biome.class).forEach((key, biome) -> { + try { + BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome(); + NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey(); + MinecraftKey vanillaMinecraftKey = new MinecraftKey(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey()); + BiomeBase platform = createBiome( + biome, + biomeRegistry.a(vanillaMinecraftKey) // get + ); + + ResourceKey delegateKey = ResourceKey.a(IRegistry.aP, new MinecraftKey("terra", createBiomeID(pack, key))); + + RegistryGeneration.a(RegistryGeneration.i, delegateKey, platform); + biomeRegistry.a(delegateKey, platform, Lifecycle.stable()); + platformBiome.getContext().put(new NMSBiomeInfo(delegateKey)); + + terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.a()); + + LOGGER.debug("Registered biome: " + delegateKey); + } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { + throw new RuntimeException(e); + } + })); + + frozen.set(biomeRegistry, true); // freeze registry again :) + + LOGGER.info("Doing tag garbage...."); + Map, List>> collect = biomeRegistry + .g() // streamKeysAndEntries + .collect(HashMap::new, + (map, pair) -> + map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().a().toList())), + HashMap::putAll); + + terraBiomeMap + .forEach((vb, terraBiomes) -> + getEntry(biomeRegistry, vb) + .ifPresentOrElse( + vanilla -> terraBiomes + .forEach(tb -> getEntry(biomeRegistry, tb) + .ifPresentOrElse( + terra -> { + LOGGER.debug(vanilla.e().orElseThrow().a() + + " (vanilla for " + + terra.e().orElseThrow().a() + + ": " + + vanilla.c().toList()); + + vanilla.c() + .forEach( + tag -> collect + .computeIfAbsent(tag, + t -> new ArrayList<>()) + .add(terra)); + }, + () -> LOGGER.error( + "No such biome: {}", + tb))), + () -> LOGGER.error("No vanilla biome: {}", vb))); + + biomeRegistry.k(); // clearTags + biomeRegistry.a(ImmutableMap.copyOf(collect)); // populateTags + + } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException exception) { + throw new RuntimeException(exception); + } + } + + public static Optional> getEntry(IRegistry registry, MinecraftKey identifier) { + return registry.b(identifier) + .flatMap(registry::c) + .map(registry::c); + } + + private static BiomeBase createBiome(Biome biome, BiomeBase vanilla) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + BiomeBase.a builder = new BiomeBase.a(); // Builder + + Field f = BiomeBase.class.getDeclaredField("l"); // category + f.setAccessible(true); + builder.a((BiomeBase.Geography) f.get(vanilla)) + .a(vanilla.c()); // getPrecipitation + + + Field biomeSettingMobsField = BiomeBase.class.getDeclaredField("k"); // spawn settings + biomeSettingMobsField.setAccessible(true); + BiomeSettingsMobs biomeSettingMobs = (BiomeSettingsMobs) biomeSettingMobsField.get(vanilla); + builder.a(biomeSettingMobs); + + + BiomeSettingsGeneration.a generationBuilder = new BiomeSettingsGeneration.a(); // builder + builder.a(generationBuilder.a()) + .a(vanilla.c()) + .b(vanilla.h()) // precipitation + .a(vanilla.i()); // temp + + + BiomeFog.a effects = new BiomeFog.a(); // Builder + effects.a(GrassColor.a); // magic + + VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class); + + // fog + effects.a(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.f())); + + // water + effects.b(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.k())); + + // water fog + effects.c(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.l())); + + // sky + effects.d(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.a())); + + if(vanillaBiomeProperties.getFoliageColor() == null) { + vanilla.j().e().ifPresent(effects::e); + } else { + // foliage + effects.e(vanillaBiomeProperties.getFoliageColor()); + } + + if(vanillaBiomeProperties.getGrassColor() == null) { + vanilla.j().f().ifPresent(effects::f); + } else { + // grass + effects.f(vanillaBiomeProperties.getGrassColor()); + } + + builder.a(effects.a()); // build() + + return builder.a(); // build() + } + + public static String createBiomeID(ConfigPack pack, com.dfsek.terra.api.registry.key.RegistryKey biomeID) { + return pack.getID() + .toLowerCase() + "/" + biomeID.getNamespace().toLowerCase(Locale.ROOT) + "/" + biomeID.getID().toLowerCase(Locale.ROOT); + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java new file mode 100644 index 000000000..cd689435c --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSBiomeProvider.java @@ -0,0 +1,54 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import com.mojang.serialization.Codec; +import net.minecraft.core.Holder; +import net.minecraft.core.IRegistry; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.biome.Climate.Sampler; +import net.minecraft.world.level.biome.WorldChunkManager; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_18_R2.CraftServer; + +import com.dfsek.terra.api.util.generic.Lazy; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.bukkit.world.BukkitPlatformBiome; + + +public class NMSBiomeProvider extends WorldChunkManager { + private final BiomeProvider delegate; + private final WorldChunkManager vanilla; + private final long seed; + + private static final Lazy> biomeRegistry = Lazy.lazy(() -> { + DedicatedServer dedicatedserver = ((CraftServer) Bukkit.getServer()).getServer(); + return dedicatedserver.aU().b(IRegistry.aP); + }); + + public NMSBiomeProvider(BiomeProvider delegate, WorldChunkManager vanilla, long seed) { + super(delegate.stream().map(biome -> biomeRegistry.value().g(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext().get(NMSBiomeInfo.class).biomeKey()))); + this.delegate = delegate; + this.vanilla = vanilla; + this.seed = seed; + } + + @Override + protected Codec a() { + return WorldChunkManager.a; + } + + @Override + public WorldChunkManager a(long seed) { + return withSeed(seed); + } + + public WorldChunkManager withSeed(long seed) { + return new NMSBiomeProvider(delegate, vanilla, seed); + } + + @Override + public Holder getNoiseBiome(int x, int y, int z, Sampler sampler) { + //return CraftBlock.biomeToBiomeBase(biomeRegistry.value(), ((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed).getPlatformBiome()).getHandle()); + return biomeRegistry.value().g(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed).getPlatformBiome()).getContext().get(NMSBiomeInfo.class).biomeKey()); + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java new file mode 100644 index 000000000..5696f0001 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSChunkGeneratorDelegate.java @@ -0,0 +1,239 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.util.generic.Lazy; +import com.dfsek.terra.api.world.biome.generation.BiomeProvider; +import com.dfsek.terra.api.world.info.WorldProperties; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap; +import net.minecraft.core.BlockPosition; +import net.minecraft.core.Holder; +import net.minecraft.core.IRegistryCustom; +import net.minecraft.core.SectionPosition; +import net.minecraft.server.level.RegionLimitedWorldAccess; +import net.minecraft.world.level.BlockColumn; +import net.minecraft.world.level.ChunkCoordIntPair; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.biome.Climate; +import net.minecraft.world.level.biome.Climate.Sampler; +import net.minecraft.world.level.block.state.IBlockData; +import net.minecraft.world.level.chunk.ChunkGenerator; +import net.minecraft.world.level.chunk.IChunkAccess; +import net.minecraft.world.level.levelgen.ChunkGeneratorAbstract; +import net.minecraft.world.level.levelgen.HeightMap; +import net.minecraft.world.level.levelgen.WorldGenStage; +import net.minecraft.world.level.levelgen.blending.Blender; +import net.minecraft.world.level.levelgen.structure.StructureSet; +import net.minecraft.world.level.levelgen.structure.placement.ConcentricRingsStructurePlacement; +import net.minecraft.world.level.levelgen.structure.placement.StructurePlacement; +import net.minecraft.world.level.levelgen.structure.templatesystem.DefinedStructureManager; +import org.bukkit.craftbukkit.v1_18_R2.block.data.CraftBlockData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import java.util.stream.Collectors; + + +public class NMSChunkGeneratorDelegate extends ChunkGenerator { + private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class); + private final NMSBiomeProvider biomeSource; + private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate; + + private final ChunkGenerator vanilla; + private final ConfigPack pack; + + private final long seed; + + private final Map>> h = new Object2ObjectArrayMap<>(); + private static final Lazy> EMPTY = Lazy.lazy(List::of); + + + public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) { + super(Registries.structureSet(), Optional.empty(), biomeProvider, biomeProvider, seed); + this.delegate = pack.getGeneratorProvider().newInstance(pack); + this.vanilla = vanilla; + this.biomeSource = biomeProvider; + this.pack = pack; + this.seed = seed; + } + + @Override //applyCarvers + public void a(RegionLimitedWorldAccess regionlimitedworldaccess, long var2, BiomeManager var4, StructureManager var5, + IChunkAccess ichunkaccess, WorldGenStage.Features var7) { + // no-op + } + + @Override // getSeaLevel + public int g() { + return vanilla.g(); + } + + @Override //fillFromNoise + public CompletableFuture a(Executor executor, Blender blender, StructureManager structuremanager, + IChunkAccess ichunkaccess) { + return vanilla.a(executor, blender, structuremanager, ichunkaccess); + } + + + @Override //buildSurface. Used to be buildBase + public void a(RegionLimitedWorldAccess regionlimitedworldaccess, StructureManager structuremanager, IChunkAccess ichunkaccess) { + + } + + @Override + protected Codec b() { + return ChunkGeneratorAbstract.a; + } + + @Override // getColumn + public BlockColumn a(int x, int z, LevelHeightAccessor height) { + IBlockData[] array = new IBlockData[height.v_()]; + WorldProperties properties = new NMSWorldProperties(seed, height); + BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); + for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) { + array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider) + .getHandle()).getState(); + } + return new BlockColumn(getMinimumY(), array); + } + + @Override // withSeed + public ChunkGenerator a(long seed) { + return new NMSChunkGeneratorDelegate(vanilla, pack, biomeSource, seed); + } + + //spawnOriginalMobs + public void a(RegionLimitedWorldAccess regionlimitedworldaccess) { + vanilla.a(regionlimitedworldaccess); + } + + // getGenDepth + public int f() { + return vanilla.f(); + } + + // climateSampler + public Sampler d() { + return Climate.a(); + } + + //getMinY + @Override + public int h() { + return vanilla.h(); + } + + @Override // getBaseHeight + public int a(int x, int z, HeightMap.Type heightmap, LevelHeightAccessor height) { + WorldProperties properties = new NMSWorldProperties(seed, height); + int y = properties.getMaxHeight(); + BiomeProvider biomeProvider = pack.getBiomeProvider().caching(properties); + while(y >= getMinimumY() && !heightmap.e().test( + ((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) { + y--; + } + return y; + } + + @Override + public void a(IRegistryCustom iregistrycustom, StructureManager structuremanager, IChunkAccess ichunkaccess, + DefinedStructureManager definedstructuremanager, long i) { + super.a(iregistrycustom, structuremanager, ichunkaccess, definedstructuremanager, i); + } + + @Nullable + @Override + public List a(ConcentricRingsStructurePlacement concentricringsstructureplacement) { + this.i(); + return this.h.getOrDefault(concentricringsstructureplacement, EMPTY).value(); + } + + private volatile boolean rings = false; + + @Override + public synchronized void i() { + if(!this.rings) { + super.i(); + this.populateStrongholdData(); + this.rings = true; + } + } + + private void populateStrongholdData() { + LOGGER.info("Generating safe stronghold data. This may take up to a minute."); + Set> set = this.d.b(); + a().map(h -> h.a()).forEach((holder) -> { // we dont need the spigot crap because it doesnt touch concentric. + StructurePlacement structureplacement = holder.b(); + if(structureplacement instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) { + if(holder.a().stream().anyMatch((structureset_a1) -> structureset_a1.a(set::contains))) { + this.h.put(concentricringsstructureplacement, + Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement))); + } + } + }); + } + + private List generateRingPositions(StructureSet holder, + ConcentricRingsStructurePlacement concentricringsstructureplacement) { + if(concentricringsstructureplacement.d() == 0) { + return List.of(); + } + List list = new ArrayList<>(); + Set> set = holder.a().stream().flatMap((structureset_a) -> (structureset_a.a().a()).a().a()).collect( + Collectors.toSet()); + int i = concentricringsstructureplacement.b(); + int j = concentricringsstructureplacement.d(); + int k = concentricringsstructureplacement.c(); + Random random = new Random(); + random.setSeed(this.j); + double d0 = random.nextDouble() * Math.PI * 2.0; + int l = 0; + int i1 = 0; + + for(int j1 = 0; j1 < j; ++j1) { + double d1 = (double) (4 * i + i * i1 * 6) + (random.nextDouble() - 0.5) * (double) i * 2.5; + int k1 = (int) Math.round(Math.cos(d0) * d1); + int l1 = (int) Math.round(Math.sin(d0) * d1); + int i2 = SectionPosition.a(k1, 8); + int j2 = SectionPosition.a(l1, 8); + Objects.requireNonNull(set); + Pair> pair = this.c.a(i2, 0, j2, 112, set::contains, random, this.d()); + if(pair != null) { + BlockPosition blockposition = pair.getFirst(); + k1 = SectionPosition.a(blockposition.u()); + l1 = SectionPosition.a(blockposition.w()); + } + + list.add(new ChunkCoordIntPair(k1, l1)); + d0 += 6.283185307179586 / (double) k; + ++l; + if(l == k) { + ++i1; + l = 0; + k += 2 * k / (i1 + 1); + k = Math.min(k, j - j1); + d0 += random.nextDouble() * Math.PI * 2.0; + } + } + return list; + + } + + public int getMinimumY() { + return h(); + } + + @Override //addDebugScreenInfo + public void a(List arg0, BlockPosition arg1) { + + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java new file mode 100644 index 000000000..61efc587d --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInitializer.java @@ -0,0 +1,15 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import org.bukkit.Bukkit; + +import com.dfsek.terra.bukkit.PlatformImpl; +import com.dfsek.terra.bukkit.nms.Initializer; + + +public class NMSInitializer implements Initializer { + @Override + public void initialize(PlatformImpl platform) { + NMSBiomeInjector.registerBiomes(platform.getRawConfigRegistry()); + Bukkit.getPluginManager().registerEvents(new NMSInjectListener(), platform.getPlugin()); + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java new file mode 100644 index 000000000..84ca1ffb7 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSInjectListener.java @@ -0,0 +1,52 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import net.minecraft.server.level.WorldServer; +import net.minecraft.world.level.chunk.ChunkGenerator; +import org.bukkit.World; +import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.world.WorldInitEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.locks.ReentrantLock; + +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.bukkit.generator.BukkitChunkGeneratorWrapper; + + +public class NMSInjectListener implements Listener { + private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class); + private static final Set INJECTED = new HashSet<>(); + private static final ReentrantLock INJECT_LOCK = new ReentrantLock(); + + @EventHandler + public void onWorldInit(WorldInitEvent event) { + if (!INJECTED.contains(event.getWorld()) && event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) { + INJECT_LOCK.lock(); + INJECTED.add(event.getWorld()); + LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName()); + CraftWorld craftWorld = (CraftWorld) event.getWorld(); + WorldServer serverWorld = craftWorld.getHandle(); + + ConfigPack pack = bukkitChunkGeneratorWrapper.getPack(); + + ChunkGenerator vanilla = serverWorld.k().g(); + NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), vanilla.e(), craftWorld.getSeed()); + NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed()); + + custom.conf = vanilla.conf; // world config from Spigot + + serverWorld.k().a.u = custom; + + LOGGER.info("Successfully injected into world."); + + serverWorld.k().a.u.i(); // generate stronghold data now + + INJECT_LOCK.unlock(); + } + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java new file mode 100644 index 000000000..c27e7d2c7 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/NMSWorldProperties.java @@ -0,0 +1,36 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import net.minecraft.world.level.LevelHeightAccessor; + +import com.dfsek.terra.api.world.info.WorldProperties; + + +public class NMSWorldProperties implements WorldProperties { + private final long seed; + private final LevelHeightAccessor height; + + public NMSWorldProperties(long seed, LevelHeightAccessor height) { + this.seed = seed; + this.height = height; + } + + @Override + public Object getHandle() { + return height; + } + + @Override + public long getSeed() { + return seed; + } + + @Override + public int getMaxHeight() { + return height.ag(); + } + + @Override + public int getMinHeight() { + return height.u_(); + } +} diff --git a/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java new file mode 100644 index 000000000..e3c2f8566 --- /dev/null +++ b/platforms/bukkit/nms/v1_19_R1/src/main/java/com/dfsek/terra/bukkit/nms/v1_19_R1/Registries.java @@ -0,0 +1,30 @@ +package com.dfsek.terra.bukkit.nms.v1_19_R1; + +import net.minecraft.core.IRegistry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.dedicated.DedicatedServer; +import net.minecraft.world.level.biome.BiomeBase; +import net.minecraft.world.level.levelgen.structure.StructureSet; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_18_R2.CraftServer; + + +public class Registries { + private static IRegistry getRegistry(ResourceKey> key) { + CraftServer craftserver = (CraftServer) Bukkit.getServer(); + DedicatedServer dedicatedserver = craftserver.getServer(); + return dedicatedserver + .aU() // getRegistryManager + .b( // getRegistry + key + ); + } + + public static IRegistry biomeRegistry() { + return getRegistry(IRegistry.aP); + } + + public static IRegistry structureSet() { + return getRegistry(IRegistry.aM); + } +}