Change Java whitespace handling in .editorconfig (#425)

* Change whitespace handling in .editorconfig

* Reformat code

* fix format error

* Reformat code

---------

Co-authored-by: Zoë Gidiere <duplexsys@protonmail.com>
This commit is contained in:
Astrashh
2023-11-13 11:57:01 +11:00
committed by GitHub
parent a73fda7d04
commit defd775f13
793 changed files with 7579 additions and 7577 deletions
@@ -27,87 +27,87 @@ import com.dfsek.terra.registry.master.ConfigRegistry;
public class AwfulBukkitHacks {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.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>) Registries.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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(
biome,
biomeRegistry.get(vanillaMinecraftKey) // get
);
biome,
biomeRegistry.get(vanillaMinecraftKey) // get
);
ResourceKey<Biome> delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY, new ResourceLocation("terra",
NMSBiomeInjector.createBiomeID(
pack, key)));
NMSBiomeInjector.createBiomeID(
pack, key)));
BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform);
biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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.unwrapKey()
.orElseThrow()
.location() +
" (vanilla for " +
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)));
.forEach((vb, terraBiomes) ->
NMSBiomeInjector.getEntry(biomeRegistry, vb)
.ifPresentOrElse(
vanilla -> terraBiomes
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
.ifPresentOrElse(
terra -> {
LOGGER.debug(
vanilla.unwrapKey()
.orElseThrow()
.location() +
" (vanilla for " +
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(); // clearTags
biomeRegistry.bindTags(ImmutableMap.copyOf(collect)); // populateTags
} catch(SecurityException | IllegalArgumentException exception) {
throw new RuntimeException(exception);
}
@@ -15,63 +15,63 @@ 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)
.map(registry::getOrCreateHolder);
.flatMap(registry::getResourceKey)
.map(registry::getOrCreateHolder);
}
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
builder.biomeCategory(Reflection.BIOME.getBiomeCategory(vanilla))
.precipitation(vanilla.getPrecipitation()) // getPrecipitation
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(vanilla.getGenerationSettings())
.temperature(vanilla.getBaseTemperature())
.downfall(vanilla.getDownfall());
.precipitation(vanilla.getPrecipitation()) // getPrecipitation
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(vanilla.getGenerationSettings())
.temperature(vanilla.getBaseTemperature())
.downfall(vanilla.getDownfall());
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()));
.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 {
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(); // 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);
@@ -17,33 +17,33 @@ public class NMSBiomeProvider extends BiomeSource {
private final BiomeSource vanilla;
private final long seed;
private final Registry<Biome> biomeRegistry = Registries.biomeRegistry();
public NMSBiomeProvider(BiomeProvider delegate, BiomeSource vanilla, long seed) {
super(delegate.stream()
.map(biome -> Registries.biomeRegistry()
.getOrCreateHolder(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
.map(biome -> Registries.biomeRegistry()
.getOrCreateHolder(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
this.delegate = delegate;
this.vanilla = vanilla;
this.seed = seed;
}
@Override
protected Codec<? extends BiomeSource> codec() {
return BiomeSource.CODEC;
}
@Override
public @NotNull BiomeSource withSeed(long seed) {
return new NMSBiomeProvider(delegate, vanilla, seed);
}
@Override
public @NotNull Holder<Biome> getNoiseBiome(int x, int y, int z, @NotNull Sampler sampler) {
return biomeRegistry.getOrCreateHolder(((BukkitPlatformBiome) delegate.getBiome(x << 2, y << 2, z << 2, seed).getPlatformBiome())
.getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
.getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -58,7 +58,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private final long seed;
private final Map<ConcentricRingsStructurePlacement, Lazy<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap<>();
private volatile boolean rings = false;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(Registries.structureSet(), Optional.empty(), biomeProvider, biomeProvider, seed);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -67,42 +67,42 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull BiomeManager biomeAccess,
@NotNull StructureFeatureManager structureAccessor,
@NotNull ChunkAccess chunk, GenerationStep.@NotNull Carving generationStep) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureFeatureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull StructureFeatureManager structureAccessor,
@NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, structureAccessor, chunk);
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureFeatureManager structures, @NotNull ChunkAccess chunk) {
// no-op
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, LevelHeightAccessor height) {
/*
@@ -117,51 +117,51 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
*/
return vanilla.getBaseColumn(x, z, height);
}
@Override // withSeed
public @NotNull ChunkGenerator withSeed(long seed) {
return new NMSChunkGeneratorDelegate(vanilla, pack, biomeSource, seed);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion regionlimitedworldaccess) {
vanilla.spawnOriginalMobs(regionlimitedworldaccess);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull Sampler climateSampler() {
return Climate.empty();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, Heightmap.@NotNull Types heightmap, @NotNull LevelHeightAccessor world) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Nullable
@Override
public List<ChunkPos> getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement concentricringsstructureplacement) {
ensureStructuresGenerated();
return ringPositions.getOrDefault(concentricringsstructureplacement, EMPTY).value();
}
@Override
public synchronized void ensureStructuresGenerated() {
if(!this.rings) {
@@ -170,7 +170,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.rings = true;
}
}
private void populateStrongholdData() {
LOGGER.info("Generating safe stronghold data. This may take up to a minute.");
Set<Holder<Biome>> set = this.runtimeBiomeSource.possibleBiomes();
@@ -179,29 +179,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
if(structureplacement instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) {
if(holder.structures().stream().anyMatch((structureset_a1) -> structureset_a1.generatesInMatchingBiome(set::contains))) {
this.ringPositions.put(concentricringsstructureplacement,
Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement)));
Lazy.lazy(() -> this.generateRingPositions(holder, concentricringsstructureplacement)));
}
}
});
}
private List<ChunkPos> generateRingPositions(StructureSet holder,
ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot
if(concentricringsstructureplacement.count() == 0) {
return List.of();
}
List<ChunkPos> list = new ArrayList<>();
Set<Holder<Biome>> set = holder
.structures()
.stream()
.flatMap((structureset_a) -> structureset_a.structure().value().biomes().stream())
.collect(Collectors.toSet());
.structures()
.stream()
.flatMap((structureset_a) -> structureset_a.structure().value().biomes().stream())
.collect(Collectors.toSet());
int i = concentricringsstructureplacement.distance();
int j = concentricringsstructureplacement.count();
int k = concentricringsstructureplacement.spread();
Random random = new Random();
// Paper start
if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) ==
net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) {
@@ -213,25 +213,25 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double d0 = random.nextDouble() * 3.141592653589793D * 2.0D;
int l = 0;
int i1 = 0;
for(int j1 = 0; j1 < j; ++j1) {
double d1 = (double) (4 * i + i * i1 * 6) + (random.nextDouble() - 0.5D) * (double) i * 2.5D;
int k1 = (int) Math.round(MathUtil.cos(d0) * d1);
int l1 = (int) Math.round(MathUtil.sin(d0) * d1);
int i2 = SectionPos.sectionToBlockCoord(k1, 8);
int j2 = SectionPos.sectionToBlockCoord(l1, 8);
Objects.requireNonNull(set);
Pair<BlockPos, Holder<Biome>> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, set::contains, random,
this.climateSampler());
this.climateSampler());
if(pair != null) {
BlockPos blockposition = pair.getFirst();
k1 = SectionPos.blockToSectionCoord(blockposition.getX());
l1 = SectionPos.blockToSectionCoord(blockposition.getZ());
}
list.add(new ChunkPos(k1, l1));
d0 += 6.283185307179586D / (double) k;
++l;
@@ -243,12 +243,12 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
d0 += random.nextDouble() * 3.141592653589793D * 2.0D;
}
}
return list;
}
@Override
public void addDebugScreenInfo(@NotNull List<String> arg0, @NotNull BlockPos arg1) {
}
}
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,21 +32,21 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), vanilla.getBiomeSource(), craftWorld.getSeed());
NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
custom.conf = vanilla.conf; // world config from Spigot
serverWorld.getChunkSource().chunkMap.generator = custom;
LOGGER.info("Successfully injected into world.");
serverWorld.getChunkSource().chunkMap.generator.ensureStructuresGenerated(); // generate stronghold data now
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -12,24 +12,24 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final BiomeProxy BIOME;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
BIOME = reflectionProxyFactory.reflectionProxy(BiomeProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(Biome.class)
public interface BiomeProxy {
@FieldGetter("biomeCategory")
@@ -14,16 +14,16 @@ public class Registries {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow( // getRegistry
key
);
.registryAccess()
.registryOrThrow( // getRegistry
key
);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registry.BIOME_REGISTRY);
}
public static Registry<StructureSet> structureSet() {
return getRegistry(Registry.STRUCTURE_SET_REGISTRY);
}
@@ -27,88 +27,88 @@ 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>) Registries.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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(
biome,
Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)) // get
);
biome,
Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)) // get
);
ResourceKey<Biome> delegateKey = ResourceKey.create(Registry.BIOME_REGISTRY,
new ResourceLocation("terra",
NMSBiomeInjector.createBiomeID(pack, key)));
new ResourceLocation("terra",
NMSBiomeInjector.createBiomeID(pack, key)));
BuiltinRegistries.register(BuiltinRegistries.BIOME, delegateKey, platform);
biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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.unwrapKey()
.orElseThrow()
.location() +
" (vanilla for " +
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)));
.forEach((vb, terraBiomes) ->
NMSBiomeInjector.getEntry(biomeRegistry, vb)
.ifPresentOrElse(
vanilla -> terraBiomes
.forEach(tb -> NMSBiomeInjector.getEntry(biomeRegistry, tb)
.ifPresentOrElse(
terra -> {
LOGGER.debug(
vanilla.unwrapKey()
.orElseThrow()
.location() +
" (vanilla for " +
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);
}
@@ -15,63 +15,63 @@ 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)
.map(registry::getOrCreateHolderOrThrow);
.flatMap(registry::getResourceKey)
.map(registry::getOrCreateHolderOrThrow);
}
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
.precipitation(vanilla.getPrecipitation())
.downfall(vanilla.getDownfall())
.temperature(vanilla.getBaseTemperature())
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(vanilla.getGenerationSettings());
.precipitation(vanilla.getPrecipitation())
.downfall(vanilla.getDownfall())
.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()));
.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);
@@ -16,27 +16,27 @@ public class NMSBiomeProvider extends BiomeSource {
private final BiomeProvider delegate;
private final long seed;
private final Registry<Biome> biomeRegistry = Registries.biomeRegistry();
public NMSBiomeProvider(BiomeProvider delegate, long seed) {
super(delegate.stream()
.map(biome -> Registries.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
.map(biome -> Registries.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
this.delegate = delegate;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends BiomeSource> codec() {
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());
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -58,14 +58,14 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
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<ConcentricRingsStructurePlacement, Lazy<List<ChunkPos>>> ringPositions = new Object2ObjectArrayMap<>();
private volatile boolean rings = false;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(Registries.structureSet(), Optional.empty(), biomeProvider);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -73,57 +73,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
// no-op
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
@NotNull ChunkAccess chunk) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
vanilla.spawnOriginalMobs(region);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull RandomState noiseConfig,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
}
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) {
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
@@ -138,8 +138,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
@@ -150,29 +150,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
}
}
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
/*
@@ -188,12 +188,12 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
*/
return vanilla.getBaseColumn(x, z, world, noiseConfig);
}
@Override
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
}
@Override
public void ensureStructuresGenerated(@NotNull RandomState noiseConfig) {
if(!this.rings) {
@@ -201,16 +201,16 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.populateStrongholdData(noiseConfig);
this.rings = true;
}
}
@Override
public List<ChunkPos> getRingPositionsFor(@NotNull ConcentricRingsStructurePlacement structurePlacement,
@NotNull RandomState noiseConfig) {
ensureStructuresGenerated(noiseConfig);
return ringPositions.get(structurePlacement).value();
}
private void populateStrongholdData(RandomState noiseConfig) {
LOGGER.info("Generating safe stronghold data. This may take up to a minute.");
Set<Holder<Biome>> set = this.biomeSource.possibleBiomes();
@@ -223,29 +223,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
match = true;
}
}
if(match) {
if(holder.placement() instanceof ConcentricRingsStructurePlacement concentricringsstructureplacement) {
this.ringPositions.put(concentricringsstructureplacement, Lazy.lazy(
() -> this.generateRingPositions(holder, noiseConfig, concentricringsstructureplacement)));
() -> this.generateRingPositions(holder, noiseConfig, concentricringsstructureplacement)));
}
}
});
}
private List<ChunkPos> generateRingPositions(StructureSet holder, RandomState randomstate,
ConcentricRingsStructurePlacement concentricringsstructureplacement) { // Spigot
if(concentricringsstructureplacement.count() == 0) {
return List.of();
}
List<ChunkPos> list = new ArrayList<>();
int i = concentricringsstructureplacement.distance();
int j = concentricringsstructureplacement.count();
int k = concentricringsstructureplacement.spread();
HolderSet<Biome> holderset = concentricringsstructureplacement.preferredBiomes();
RandomSource randomsource = RandomSource.create();
if(this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) ==
net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) {
randomsource.setSeed(this.conf.strongholdSeed);
@@ -255,25 +255,25 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double d0 = randomsource.nextDouble() * 3.141592653589793D * 2.0D;
int l = 0;
int i1 = 0;
for(int j1 = 0; j1 < j; ++j1) {
double d1 = (double) (4 * i + i * i1 * 6) + (randomsource.nextDouble() - 0.5D) * (double) i * 2.5D;
int k1 = (int) Math.round(MathUtil.cos(d0) * d1);
int l1 = (int) Math.round(MathUtil.sin(d0) * d1);
int i2 = SectionPos.sectionToBlockCoord(k1, 8);
int j2 = SectionPos.sectionToBlockCoord(l1, 8);
Objects.requireNonNull(holderset);
Pair<BlockPos, Holder<Biome>> pair = this.biomeSource.findBiomeHorizontal(i2, 0, j2, 112, holderset::contains, randomsource,
randomstate.sampler());
randomstate.sampler());
if(pair != null) {
BlockPos blockposition = pair.getFirst();
k1 = SectionPos.blockToSectionCoord(blockposition.getX());
l1 = SectionPos.blockToSectionCoord(blockposition.getZ());
}
list.add(new ChunkPos(k1, l1));
d0 += 6.283185307179586D / (double) k;
++l;
@@ -285,7 +285,7 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
d0 += randomsource.nextDouble() * 3.141592653589793D * 2.0D;
}
}
return list;
}
}
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,19 +32,19 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
NMSChunkGeneratorDelegate custom = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
custom.conf = vanilla.conf; // world config from Spigot
serverWorld.getChunkSource().chunkMap.generator = custom;
LOGGER.info("Successfully injected into world.");
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -13,24 +13,24 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final StructureManagerProxy STRUCTURE_MANAGER;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(StructureManager.class)
public interface StructureManagerProxy {
@FieldGetter("level")
@@ -14,16 +14,16 @@ public class Registries {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow( // getRegistry
key
);
.registryAccess()
.registryOrThrow( // getRegistry
key
);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registry.BIOME_REGISTRY);
}
public static Registry<StructureSet> structureSet() {
return getRegistry(Registry.STRUCTURE_SET_REGISTRY);
}
@@ -27,72 +27,72 @@ 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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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)));
.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);
}
@@ -15,63 +15,63 @@ 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);
.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
.precipitation(vanilla.getPrecipitation())
.downfall(vanilla.getDownfall())
.temperature(vanilla.getBaseTemperature())
.mobSpawnSettings(vanilla.getMobSettings())
.generationSettings(vanilla.getGenerationSettings());
.precipitation(vanilla.getPrecipitation())
.downfall(vanilla.getDownfall())
.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()));
.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);
@@ -16,27 +16,27 @@ 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(delegate.stream()
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey())));
this.delegate = delegate;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends BiomeSource> codec() {
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());
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -38,12 +38,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
private final ChunkGenerator vanilla;
private final ConfigPack pack;
private final long seed;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(biomeProvider);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -51,57 +51,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
// no-op
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
@NotNull ChunkAccess chunk) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
vanilla.spawnOriginalMobs(region);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull RandomState noiseConfig,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
}
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) {
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
@@ -116,8 +116,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
@@ -128,29 +128,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
}
}
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
/*
@@ -166,9 +166,9 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
*/
return vanilla.getBaseColumn(x, z, world, noiseConfig);
}
@Override
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
}
}
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
LOGGER.info("Successfully injected into world.");
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final StructureManagerProxy STRUCTURE_MANAGER;
public static final ReferenceProxy REFERENCE;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(StructureManager.class)
public interface StructureManagerProxy {
@FieldGetter("level")
LevelAccessor getLevel(StructureManager instance);
}
@Proxies(Holder.Reference.class)
public interface ReferenceProxy {
@MethodName("bindValue")
@@ -14,10 +14,10 @@ public class RegistryFetcher {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow(key);
.registryAccess()
.registryOrThrow(key);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registries.BIOME);
}
@@ -27,72 +27,72 @@ 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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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)));
.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);
}
@@ -15,62 +15,62 @@ 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);
.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());
.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()));
.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);
@@ -18,32 +18,32 @@ 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()));
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey()));
}
@Override
protected @NotNull Codec<? extends BiomeSource> codec() {
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());
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -39,12 +39,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
private final ChunkGenerator vanilla;
private final ConfigPack pack;
private final long seed;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(biomeProvider);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -52,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
// no-op
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
@NotNull ChunkAccess chunk) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
vanilla.spawnOriginalMobs(region);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull RandomState noiseConfig,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
}
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) {
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
@@ -117,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
@@ -129,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
}
}
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
BlockState[] array = new BlockState[world.getHeight()];
@@ -159,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider();
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
.getHandle()).getState();
.getHandle()).getState();
}
return new NoiseColumn(getMinY(), array);
}
@Override
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
}
}
@@ -1,10 +1,10 @@
package com.dfsek.terra.bukkit.nms.v1_19_R3;
import org.bukkit.Bukkit;
import com.dfsek.terra.bukkit.PlatformImpl;
import com.dfsek.terra.bukkit.nms.Initializer;
import org.bukkit.Bukkit;
public class NMSInitializer implements Initializer {
@Override
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
LOGGER.info("Successfully injected into world.");
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final StructureManagerProxy STRUCTURE_MANAGER;
public static final ReferenceProxy REFERENCE;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(StructureManager.class)
public interface StructureManagerProxy {
@FieldGetter("level")
LevelAccessor getLevel(StructureManager instance);
}
@Proxies(Holder.Reference.class)
public interface ReferenceProxy {
@MethodName("bindValue")
@@ -14,10 +14,10 @@ public class RegistryFetcher {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow(key);
.registryAccess()
.registryOrThrow(key);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registries.BIOME);
}
@@ -27,72 +27,72 @@ 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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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)));
.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);
}
@@ -1,10 +1,10 @@
package com.dfsek.terra.bukkit.nms.v1_20_R1;
import com.dfsek.terra.api.properties.Properties;
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 {
}
@@ -15,62 +15,62 @@ 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);
.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());
.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()));
.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);
@@ -18,32 +18,32 @@ 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()));
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey()));
}
@Override
protected @NotNull Codec<? extends BiomeSource> codec() {
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());
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -1,16 +1,13 @@
package com.dfsek.terra.bukkit.nms.v1_20_R1;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
import com.mojang.serialization.Codec;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.world.level.*;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelHeightAccessor;
import net.minecraft.world.level.NoiseColumn;
import net.minecraft.world.level.StructureManager;
import net.minecraft.world.level.WorldGenLevel;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
@@ -31,16 +28,23 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import com.dfsek.terra.api.config.ConfigPack;
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
import com.dfsek.terra.api.world.info.WorldProperties;
import com.dfsek.terra.bukkit.config.PreLoadCompatibilityOptions;
import com.dfsek.terra.bukkit.world.BukkitWorldProperties;
import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
private final ChunkGenerator vanilla;
private final ConfigPack pack;
private final long seed;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(biomeProvider);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -48,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
// no-op
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
@NotNull ChunkAccess chunk) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
vanilla.spawnOriginalMobs(region);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull RandomState noiseConfig,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
}
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) {
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
@@ -113,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
@@ -125,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
}
}
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
BlockState[] array = new BlockState[world.getHeight()];
@@ -155,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider();
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
.getHandle()).getState();
.getHandle()).getState();
}
return new NoiseColumn(getMinY(), array);
}
@Override
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
}
}
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
LOGGER.info("Successfully injected into world.");
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final StructureManagerProxy STRUCTURE_MANAGER;
public static final ReferenceProxy REFERENCE;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(StructureManager.class)
public interface StructureManagerProxy {
@FieldGetter("level")
LevelAccessor getLevel(StructureManager instance);
}
@Proxies(Holder.Reference.class)
public interface ReferenceProxy {
@MethodName("bindValue")
@@ -14,10 +14,10 @@ public class RegistryFetcher {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow(key);
.registryAccess()
.registryOrThrow(key);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registries.BIOME);
}
@@ -27,72 +27,72 @@ 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 = new ResourceLocation(vanillaBukkitKey.getNamespace(), vanillaBukkitKey.getKey());
Biome platform = NMSBiomeInjector.createBiome(biome, Objects.requireNonNull(biomeRegistry.get(vanillaMinecraftKey)));
ResourceKey<Biome> delegateKey = ResourceKey.create(
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Registries.BIOME,
new ResourceLocation("terra", NMSBiomeInjector.createBiomeID(pack, key))
);
Reference<Biome> holder = biomeRegistry.register(delegateKey, platform, Lifecycle.stable());
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);
.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)));
.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);
}
@@ -15,62 +15,62 @@ 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);
.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());
.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()));
.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);
@@ -18,32 +18,32 @@ 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()));
.map(biome -> RegistryFetcher.biomeRegistry()
.getHolderOrThrow(((BukkitPlatformBiome) biome.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey()));
}
@Override
protected @NotNull Codec<? extends BiomeSource> codec() {
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());
.getPlatformBiome()).getContext()
.get(NMSBiomeInfo.class)
.biomeKey());
}
}
@@ -39,12 +39,12 @@ import com.dfsek.terra.bukkit.world.block.data.BukkitBlockState;
public class NMSChunkGeneratorDelegate extends ChunkGenerator {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSChunkGeneratorDelegate.class);
private final com.dfsek.terra.api.world.chunk.generation.ChunkGenerator delegate;
private final ChunkGenerator vanilla;
private final ConfigPack pack;
private final long seed;
public NMSChunkGeneratorDelegate(ChunkGenerator vanilla, ConfigPack pack, NMSBiomeProvider biomeProvider, long seed) {
super(biomeProvider);
this.delegate = pack.getGeneratorProvider().newInstance(pack);
@@ -52,57 +52,57 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
this.pack = pack;
this.seed = seed;
}
@Override
protected @NotNull Codec<? extends ChunkGenerator> codec() {
return ChunkGenerator.CODEC;
}
@Override
public void applyCarvers(@NotNull WorldGenRegion chunkRegion, long seed, @NotNull RandomState noiseConfig, @NotNull BiomeManager world,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk, @NotNull Carving carverStep) {
// no-op
}
@Override
public void buildSurface(@NotNull WorldGenRegion region, @NotNull StructureManager structures, @NotNull RandomState noiseConfig,
@NotNull ChunkAccess chunk) {
// no-op
}
@Override
public void applyBiomeDecoration(@NotNull WorldGenLevel world, @NotNull ChunkAccess chunk,
@NotNull StructureManager structureAccessor) {
vanilla.applyBiomeDecoration(world, chunk, structureAccessor);
}
@Override
public void spawnOriginalMobs(@NotNull WorldGenRegion region) {
vanilla.spawnOriginalMobs(region);
}
@Override
public int getGenDepth() {
return vanilla.getGenDepth();
}
@Override
public @NotNull CompletableFuture<ChunkAccess> fillFromNoise(@NotNull Executor executor, @NotNull Blender blender,
@NotNull RandomState noiseConfig,
@NotNull StructureManager structureAccessor, @NotNull ChunkAccess chunk) {
return vanilla.fillFromNoise(executor, blender, noiseConfig, structureAccessor, chunk)
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
.thenApply(c -> {
LevelAccessor level = Reflection.STRUCTURE_MANAGER.getLevel(structureAccessor);
BiomeProvider biomeProvider = pack.getBiomeProvider();
PreLoadCompatibilityOptions compatibilityOptions = pack.getContext().get(PreLoadCompatibilityOptions.class);
if(compatibilityOptions.isBeard()) {
beard(structureAccessor, chunk, new BukkitWorldProperties(level.getMinecraftWorld().getWorld()),
biomeProvider, compatibilityOptions);
}
return c;
});
}
private void beard(StructureManager structureAccessor, ChunkAccess chunk, WorldProperties world, BiomeProvider biomeProvider,
PreLoadCompatibilityOptions compatibilityOptions) {
Beardifier structureWeightSampler = Beardifier.forStructuresInChunk(structureAccessor, chunk.getPos());
@@ -117,8 +117,8 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
double noise = structureWeightSampler.compute(new SinglePointContext(x + xi, y, z + zi));
if(noise > threshold) {
chunk.setBlockState(new BlockPos(x, y, z), ((CraftBlockData) ((BukkitBlockState) delegate
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
.getPalette(x + xi, y, z + zi, world, biomeProvider)
.get(depth, x + xi, y, z + zi, world.getSeed())).getHandle()).getState(), false);
depth++;
} else if(noise < airThreshold) {
chunk.setBlockState(new BlockPos(x, y, z), Blocks.AIR.defaultBlockState(), false);
@@ -129,29 +129,29 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
}
}
}
@Override
public int getSeaLevel() {
return vanilla.getSeaLevel();
}
@Override
public int getMinY() {
return vanilla.getMinY();
}
@Override
public int getBaseHeight(int x, int z, @NotNull Types heightmap, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
WorldProperties properties = new NMSWorldProperties(seed, world);
int y = properties.getMaxHeight();
BiomeProvider biomeProvider = pack.getBiomeProvider();
while(y >= getMinY() && !heightmap.isOpaque().test(
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
((CraftBlockData) delegate.getBlock(properties, x, y - 1, z, biomeProvider).getHandle()).getState())) {
y--;
}
return y;
}
@Override
public @NotNull NoiseColumn getBaseColumn(int x, int z, @NotNull LevelHeightAccessor world, @NotNull RandomState noiseConfig) {
BlockState[] array = new BlockState[world.getHeight()];
@@ -159,13 +159,13 @@ public class NMSChunkGeneratorDelegate extends ChunkGenerator {
BiomeProvider biomeProvider = pack.getBiomeProvider();
for(int y = properties.getMaxHeight() - 1; y >= properties.getMinHeight(); y--) {
array[y - properties.getMinHeight()] = ((CraftBlockData) delegate.getBlock(properties, x, y, z, biomeProvider)
.getHandle()).getState();
.getHandle()).getState();
}
return new NoiseColumn(getMinY(), array);
}
@Override
public void addDebugScreenInfo(@NotNull List<String> text, @NotNull RandomState noiseConfig, @NotNull BlockPos pos) {
}
}
@@ -22,7 +22,7 @@ public class NMSInjectListener implements Listener {
private static final Logger LOGGER = LoggerFactory.getLogger(NMSInjectListener.class);
private static final Set<World> INJECTED = new HashSet<>();
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
@EventHandler
public void onWorldInit(WorldInitEvent event) {
if(!INJECTED.contains(event.getWorld()) &&
@@ -32,16 +32,16 @@ public class NMSInjectListener implements Listener {
LOGGER.info("Preparing to take over the world: {}", event.getWorld().getName());
CraftWorld craftWorld = (CraftWorld) event.getWorld();
ServerLevel serverWorld = craftWorld.getHandle();
ConfigPack pack = bukkitChunkGeneratorWrapper.getPack();
ChunkGenerator vanilla = serverWorld.getChunkSource().getGenerator();
NMSBiomeProvider provider = new NMSBiomeProvider(pack.getBiomeProvider(), craftWorld.getSeed());
serverWorld.getChunkSource().chunkMap.generator = new NMSChunkGeneratorDelegate(vanilla, pack, provider, craftWorld.getSeed());
LOGGER.info("Successfully injected into world.");
INJECT_LOCK.unlock();
}
}
@@ -8,27 +8,27 @@ 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.getMaxBuildHeight();
}
@Override
public int getMinHeight() {
return height.getMinBuildHeight();
@@ -16,34 +16,34 @@ import xyz.jpenilla.reflectionremapper.proxy.annotation.Proxies;
public class Reflection {
public static final MappedRegistryProxy MAPPED_REGISTRY;
public static final StructureManagerProxy STRUCTURE_MANAGER;
public static final ReferenceProxy REFERENCE;
static {
ReflectionRemapper reflectionRemapper = ReflectionRemapper.forReobfMappingsInPaperJar();
ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper,
Reflection.class.getClassLoader());
Reflection.class.getClassLoader());
MAPPED_REGISTRY = reflectionProxyFactory.reflectionProxy(MappedRegistryProxy.class);
STRUCTURE_MANAGER = reflectionProxyFactory.reflectionProxy(StructureManagerProxy.class);
REFERENCE = reflectionProxyFactory.reflectionProxy(ReferenceProxy.class);
}
@Proxies(MappedRegistry.class)
public interface MappedRegistryProxy {
@FieldSetter("frozen")
void setFrozen(MappedRegistry<?> instance, boolean frozen);
}
@Proxies(StructureManager.class)
public interface StructureManagerProxy {
@FieldGetter("level")
LevelAccessor getLevel(StructureManager instance);
}
@Proxies(Holder.Reference.class)
public interface ReferenceProxy {
@MethodName("bindValue")
@@ -14,10 +14,10 @@ public class RegistryFetcher {
CraftServer craftserver = (CraftServer) Bukkit.getServer();
DedicatedServer dedicatedserver = craftserver.getServer();
return dedicatedserver
.registryAccess()
.registryOrThrow(key);
.registryAccess()
.registryOrThrow(key);
}
public static Registry<Biome> biomeRegistry() {
return getRegistry(Registries.BIOME);
}