mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-17 14:21:08 +00:00
fix deadlock
This commit is contained in:
@@ -1,18 +1,10 @@
|
|||||||
package com.dfsek.terra.bukkit.nms;
|
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.google.common.collect.ImmutableMap;
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.HolderSet.Named;
|
|
||||||
import net.minecraft.core.IRegistry;
|
import net.minecraft.core.IRegistry;
|
||||||
import net.minecraft.core.IRegistryWritable;
|
import net.minecraft.core.IRegistryWritable;
|
||||||
import net.minecraft.core.Registry;
|
|
||||||
import net.minecraft.core.RegistryMaterials;
|
import net.minecraft.core.RegistryMaterials;
|
||||||
import net.minecraft.data.RegistryGeneration;
|
import net.minecraft.data.RegistryGeneration;
|
||||||
import net.minecraft.resources.MinecraftKey;
|
import net.minecraft.resources.MinecraftKey;
|
||||||
@@ -39,27 +31,39 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
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 {
|
public class NMSBiomeInjector {
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(NMSBiomeInjector.class);
|
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();
|
CraftServer craftserver = (CraftServer) Bukkit.getServer();
|
||||||
DedicatedServer dedicatedserver = craftserver.getServer();
|
DedicatedServer dedicatedserver = craftserver.getServer();
|
||||||
|
|
||||||
IRegistryWritable<BiomeBase> biomeRegistry = (IRegistryWritable<BiomeBase>) dedicatedserver
|
return (IRegistryWritable<BiomeBase>) dedicatedserver
|
||||||
.aU() // getRegistryManager
|
.aU() // getRegistryManager
|
||||||
.b( // getRegistry
|
.b( // getRegistry
|
||||||
IRegistry.aP // biome registry key
|
IRegistry.aP // biome registry key
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerBiomes(ConfigRegistry configRegistry) {
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LOGGER.info("Hacking biome registry...");
|
LOGGER.info("Hacking biome registry...");
|
||||||
|
IRegistryWritable<BiomeBase> biomeRegistry = getBiomeRegistry();
|
||||||
Field frozen = RegistryMaterials.class.getDeclaredField("bL"); // registry frozen field
|
Field frozen = RegistryMaterials.class.getDeclaredField("bL"); // registry frozen field
|
||||||
frozen.setAccessible(true);
|
frozen.setAccessible(true);
|
||||||
frozen.set(biomeRegistry, false);
|
frozen.set(biomeRegistry, false);
|
||||||
|
|
||||||
Map<MinecraftKey, List<MinecraftKey>> terraBiomeMap = new HashMap<>();
|
|
||||||
|
|
||||||
configRegistry.forEach(pack -> pack.getRegistry(Biome.class).forEach((key, biome) -> {
|
configRegistry.forEach(pack -> pack.getRegistry(Biome.class).forEach((key, biome) -> {
|
||||||
try {
|
try {
|
||||||
@@ -87,57 +91,61 @@ public class NMSBiomeInjector {
|
|||||||
|
|
||||||
frozen.set(biomeRegistry, true); // freeze registry again :)
|
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) {
|
} catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException exception) {
|
||||||
throw new RuntimeException(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) {
|
public static <T> Optional<Holder<T>> getEntry(IRegistry<T> registry, MinecraftKey identifier) {
|
||||||
return registry.b(identifier)
|
return registry.b(identifier)
|
||||||
.flatMap(registry::c)
|
.flatMap(registry::c)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import org.bukkit.craftbukkit.v1_18_R2.CraftWorld;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.WorldInitEvent;
|
import org.bukkit.event.world.WorldInitEvent;
|
||||||
|
import org.bukkit.event.world.WorldLoadEvent;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@@ -23,6 +24,8 @@ public class NMSInjectListener implements Listener {
|
|||||||
private static final Set<World> INJECTED = new HashSet<>();
|
private static final Set<World> INJECTED = new HashSet<>();
|
||||||
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
private static final ReentrantLock INJECT_LOCK = new ReentrantLock();
|
||||||
|
|
||||||
|
private volatile boolean tags = false;
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onWorldInit(WorldInitEvent event) {
|
public void onWorldInit(WorldInitEvent event) {
|
||||||
if (!INJECTED.contains(event.getWorld()) && event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) {
|
if (!INJECTED.contains(event.getWorld()) && event.getWorld().getGenerator() instanceof BukkitChunkGeneratorWrapper bukkitChunkGeneratorWrapper) {
|
||||||
@@ -47,4 +50,13 @@ public class NMSInjectListener implements Listener {
|
|||||||
INJECT_LOCK.unlock();
|
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