Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
TobyWarren authored Aug 14, 2024
1 parent 218ed61 commit d28aee2
Show file tree
Hide file tree
Showing 11 changed files with 623 additions and 0 deletions.
17 changes: 17 additions & 0 deletions platforms/bukkit/nms/v1_21_R1/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apply(plugin = "io.papermc.paperweight.userdev")

repositories {
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}

dependencies {
api(project(":platforms:bukkit:common"))
paperDevBundle(Versions.Bukkit.paperDevBundle)
implementation("xyz.jpenilla", "reflection-remapper", Versions.Bukkit.reflectionRemapper)
}

tasks {
assemble {
dependsOn("reobfJar")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.dfsek.terra.bukkit.nms.v1_21;

import com.google.common.collect.ImmutableMap;
import net.minecraft.core.Holder;
import net.minecraft.core.Holder.Reference;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.RegistrationInfo;
import net.minecraft.core.WritableRegistry;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.level.biome.Biome;
import org.bukkit.NamespacedKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
import com.dfsek.terra.registry.master.ConfigRegistry;


public class AwfulBukkitHacks {
private static final Logger LOGGER = LoggerFactory.getLogger(AwfulBukkitHacks.class);

private static final Map<ResourceLocation, List<ResourceLocation>> terraBiomeMap = new HashMap<>();

public static void registerBiomes(ConfigRegistry configRegistry) {
try {
LOGGER.info("Hacking biome registry...");
WritableRegistry<Biome> biomeRegistry = (WritableRegistry<Biome>) RegistryFetcher.biomeRegistry();

Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, false);

configRegistry.forEach(pack -> pack.getRegistry(com.dfsek.terra.api.world.biome.Biome.class).forEach((key, biome) -> {
try {
BukkitPlatformBiome platformBiome = (BukkitPlatformBiome) biome.getPlatformBiome();
NamespacedKey vanillaBukkitKey = platformBiome.getHandle().getKey();
ResourceLocation vanillaMinecraftKey = ResourceLocation.fromNamespaceAndPath(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));

ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
ResourceLocation.fromNamespaceAndPath("terra", NMSBiomeInjector.createBiomeID(pack, key))
);

Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, RegistrationInfo.BUILT_IN);
Reflection.REFERENCE.invokeBindValue(holder, platform); // IMPORTANT: bind holder.

platformBiome.getContext().put(new NMSBiomeInfo(delegateKey));

terraBiomeMap.computeIfAbsent(vanillaMinecraftKey, i -> new ArrayList<>()).add(delegateKey.location());

LOGGER.debug("Registered biome: " + delegateKey);
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}));

Reflection.MAPPED_REGISTRY.setFrozen((MappedRegistry<?>) biomeRegistry, true); // freeze registry again :)

LOGGER.info("Doing tag garbage....");
Map<TagKey<Biome>, List<Holder<Biome>>> collect = biomeRegistry
.getTags() // streamKeysAndEntries
.collect(HashMap::new,
(map, pair) ->
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().stream().toList())),
HashMap::putAll);

terraBiomeMap
.forEach((vb, terraBiomes) ->
NMSBiomeInjector.getEntry(biomeRegistry, vb).ifPresentOrElse(
vanilla -> terraBiomes.forEach(
tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb).ifPresentOrElse(
terra -> {
LOGGER.debug("{} (vanilla for {}): {}",
vanilla.unwrapKey().orElseThrow().location(),
terra.unwrapKey().orElseThrow().location(),
vanilla.tags().toList());
vanilla.tags()
.forEach(tag -> collect
.computeIfAbsent(tag, t -> new ArrayList<>())
.add(terra));
},
() -> LOGGER.error("No such biome: {}", tb))),
() -> LOGGER.error("No vanilla biome: {}", vb)));

biomeRegistry.resetTags();
biomeRegistry.bindTags(ImmutableMap.copyOf(collect));

} catch(SecurityException | IllegalArgumentException exception) {
throw new RuntimeException(exception);
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.dfsek.terra.bukkit.nms.v1_21;

import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.biome.Biome;

import com.dfsek.terra.api.properties.Properties;


public record NMSBiomeInfo(ResourceKey<Biome> biomeKey) implements Properties {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.dfsek.terra.bukkit.nms.v1_21;

import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSpecialEffects;

import java.util.Locale;
import java.util.Objects;
import java.util.Optional;

import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;


public class NMSBiomeInjector {

public static <T> Optional<Holder<T>> getEntry(Registry<T> registry, ResourceLocation identifier) {
return registry.getOptional(identifier)
.flatMap(registry::getResourceKey)
.flatMap(registry::getHolder);
}

public static Biome createBiome(com.dfsek.terra.api.world.biome.Biome biome, Biome vanilla)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Biome.BiomeBuilder builder = new Biome.BiomeBuilder();

builder
.downfall(vanilla.climateSettings.downfall())
.temperature(vanilla.getBaseTemperature())
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(vanilla.getGenerationSettings());


BiomeSpecialEffects.Builder effects = new BiomeSpecialEffects.Builder();

effects.grassColorModifier(vanilla.getSpecialEffects().getGrassColorModifier());

VanillaBiomeProperties vanillaBiomeProperties = biome.getContext().get(VanillaBiomeProperties.class);

effects.fogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getFogColor(), vanilla.getFogColor()))

.waterColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterColor(), vanilla.getWaterColor()))

.waterFogColor(Objects.requireNonNullElse(vanillaBiomeProperties.getWaterFogColor(), vanilla.getWaterFogColor()))

.skyColor(Objects.requireNonNullElse(vanillaBiomeProperties.getSkyColor(), vanilla.getSkyColor()));

if(vanillaBiomeProperties.getFoliageColor() == null) {
vanilla.getSpecialEffects().getFoliageColorOverride().ifPresent(effects::foliageColorOverride);
} else {
effects.foliageColorOverride(vanillaBiomeProperties.getFoliageColor());
}

if(vanillaBiomeProperties.getGrassColor() == null) {
vanilla.getSpecialEffects().getGrassColorOverride().ifPresent(effects::grassColorOverride);
} else {
// grass
effects.grassColorOverride(vanillaBiomeProperties.getGrassColor());
}

vanilla.getAmbientLoop().ifPresent(effects::ambientLoopSound);
vanilla.getAmbientAdditions().ifPresent(effects::ambientAdditionsSound);
vanilla.getAmbientMood().ifPresent(effects::ambientMoodSound);
vanilla.getBackgroundMusic().ifPresent(effects::backgroundMusic);
vanilla.getAmbientParticle().ifPresent(effects::ambientParticle);

builder.specialEffects(effects.build());

return builder.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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.dfsek.terra.bukkit.nms.v1_21;

import com.mojang.serialization.MapCodec;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeSource;
import net.minecraft.world.level.biome.Climate.Sampler;
import org.jetbrains.annotations.NotNull;

import java.util.stream.Stream;

import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;


public class NMSBiomeProvider extends BiomeSource {
private final BiomeProvider delegate;
private final long seed;
private final Registry<Biome> biomeRegistry = RegistryFetcher.biomeRegistry();

public NMSBiomeProvider(BiomeProvider delegate, long seed) {
super();
this.delegate = delegate;
this.seed = seed;
}

@Override
protected Stream<Holder<Biome>> collectPossibleBiomes() {
return delegate.stream()
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey()));
}

@Override
protected @NotNull MapCodec<? extends BiomeSource> codec() {
return MapCodec.assumeMapUnsafe(BiomeSource.CODEC);
// return MapCodec.unit(null);
// BuiltInRegistries.BIOME_SOURCE.byNameCodec().dispatchMap(this::codec, Function.identity());
// BuiltInRegistries.BIOME_SOURCE.byNameCodec().dispatchStable(BiomeSource::codec, Function.identity());
// return BiomeSource.CODEC;
}

@Override
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
return biomeRegistry.getHolderOrThrow(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed)
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
Loading

0 comments on commit d28aee2

Please sign in to comment.