mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-03 06:16:10 +00:00
fix deadlock
This commit is contained in:
@@ -1,18 +1,10 @@
|
||||
package com.dfsek.terra.bukkit.nms;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
|
||||
import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.HolderSet.Named;
|
||||
import net.minecraft.core.IRegistry;
|
||||
import net.minecraft.core.IRegistryWritable;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.RegistryMaterials;
|
||||
import net.minecraft.data.RegistryGeneration;
|
||||
import net.minecraft.resources.MinecraftKey;
|
||||
@@ -39,27 +31,39 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.dfsek.terra.api.config.ConfigPack;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.bukkit.config.VanillaBiomeProperties;
|
||||
import com.dfsek.terra.bukkit.world.BukkitPlatformBiome;
|
||||
import com.dfsek.terra.registry.master.ConfigRegistry;
|
||||
|
||||
|
||||
public class NMSBiomeInjector {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.class);
|
||||
private static final Map<MinecraftKey, List<MinecraftKey>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
public static IRegistryWritable<BiomeBase> getBiomeRegistry() {
|
||||
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||
|
||||
IRegistryWritable<BiomeBase> biomeRegistry = (IRegistryWritable<BiomeBase>) dedicatedserver
|
||||
|
||||
return (IRegistryWritable<BiomeBase>) dedicatedserver
|
||||
.aU() // getRegistryManager
|
||||
.b( // getRegistry
|
||||
IRegistry.aP // biome registry key
|
||||
);
|
||||
}
|
||||
|
||||
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||
|
||||
|
||||
try {
|
||||
LOGGER.info("Hacking biome registry...");
|
||||
IRegistryWritable<BiomeBase> biomeRegistry = getBiomeRegistry();
|
||||
Field frozen = RegistryMaterials.class.getDeclaredField("bL"); // registry frozen field
|
||||
frozen.setAccessible(true);
|
||||
frozen.set(biomeRegistry, false);
|
||||
|
||||
Map<MinecraftKey, List<MinecraftKey>> terraBiomeMap = new HashMap<>();
|
||||
|
||||
|
||||
configRegistry.forEach(pack -> pack.getRegistry(Biome.class).forEach((key, biome) -> {
|
||||
try {
|
||||
@@ -87,57 +91,61 @@ public class NMSBiomeInjector {
|
||||
|
||||
frozen.set(biomeRegistry, true); // freeze registry again :)
|
||||
|
||||
/*
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
Map<TagKey<BiomeBase>, List<Holder<BiomeBase>>> collect = biomeRegistry
|
||||
.g() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().a().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(vanilla -> terraBiomes
|
||||
.forEach(tb ->
|
||||
getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.e()
|
||||
.orElseThrow()
|
||||
.a() +
|
||||
" (vanilla for " +
|
||||
terra.e()
|
||||
.orElseThrow()
|
||||
.a() +
|
||||
": " +
|
||||
vanilla.c()
|
||||
.toList());
|
||||
|
||||
vanilla.c()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.k(); // clearTags
|
||||
biomeRegistry.a(ImmutableMap.copyOf(collect)); // populateTags
|
||||
|
||||
*/
|
||||
|
||||
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
public static void injectTags() {
|
||||
LOGGER.info("Doing tag garbage....");
|
||||
IRegistryWritable<BiomeBase> biomeRegistry = getBiomeRegistry();
|
||||
Map<TagKey<BiomeBase>, List<Holder<BiomeBase>>> collect = biomeRegistry
|
||||
.g() // streamKeysAndEntries
|
||||
.collect(HashMap::new,
|
||||
(map, pair) ->
|
||||
map.put(pair.getFirst(), new ArrayList<>(pair.getSecond().a().toList())),
|
||||
HashMap::putAll);
|
||||
|
||||
terraBiomeMap
|
||||
.forEach((vb, terraBiomes) ->
|
||||
getEntry(biomeRegistry, vb)
|
||||
.ifPresentOrElse(vanilla -> terraBiomes
|
||||
.forEach(tb ->
|
||||
getEntry(biomeRegistry, tb)
|
||||
.ifPresentOrElse(
|
||||
terra -> {
|
||||
LOGGER.debug(
|
||||
vanilla.e()
|
||||
.orElseThrow()
|
||||
.a() +
|
||||
" (vanilla for " +
|
||||
terra.e()
|
||||
.orElseThrow()
|
||||
.a() +
|
||||
": " +
|
||||
vanilla.c()
|
||||
.toList());
|
||||
|
||||
vanilla.c()
|
||||
.forEach(
|
||||
tag -> collect
|
||||
.computeIfAbsent(
|
||||
tag,
|
||||
t -> new ArrayList<>())
|
||||
.add(terra));
|
||||
},
|
||||
() -> LOGGER.error(
|
||||
"No such biome: {}",
|
||||
tb))),
|
||||
() -> LOGGER.error("No vanilla biome: {}", vb)));
|
||||
|
||||
biomeRegistry.k(); // clearTags
|
||||
biomeRegistry.a(ImmutableMap.copyOf(collect)); // populateTags
|
||||
|
||||
}
|
||||
|
||||
public static <T> Optional<Holder<T>> getEntry(IRegistry<T> registry, MinecraftKey identifier) {
|
||||
return registry.b(identifier)
|
||||
.flatMap(registry::c)
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -23,6 +24,8 @@ public class NMSInjectListener implements Listener {
|
||||
private static final Set<World> INJECTED = new HashSet<>();
|
||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||
|
||||
private volatile boolean tags = false;
|
||||
|
||||
@EventHandler
|
||||
public void onWorldInit(WorldInitEvent event) {
|
||||
if (!INJECTED.contains(event.getWorld()) && event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) {
|
||||
@@ -47,4 +50,13 @@ public class NMSInjectListener implements Listener {
|
||||
INJECT_LOCK.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onWorldLoad(WorldLoadEvent load) {
|
||||
if(!tags) {
|
||||
System.out.println("Injecting tags late to prevent deadlock. Thank you Bukkit.");
|
||||
tags = true;
|
||||
NMSBiomeInjector.injectTags();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user