diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/DynamicRegistryPrefixes.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/DynamicRegistryPrefixes.java deleted file mode 100644 index b600f5f9..00000000 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/DynamicRegistryPrefixes.java +++ /dev/null @@ -1,10 +0,0 @@ -package dev.su5ed.sinytra.connector.mod.compat; - -import net.fabricmc.fabric.impl.registry.sync.DynamicRegistriesImpl; -import net.minecraft.resources.ResourceKey; - -public class DynamicRegistryPrefixes { - public static boolean isRegisteredFabricDynamicRegistry(ResourceKey key) { - return DynamicRegistriesImpl.FABRIC_DYNAMIC_REGISTRY_KEYS.stream().anyMatch(key::equals); - } -} diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/RegistryUtil.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/RegistryUtil.java new file mode 100644 index 00000000..77667a3f --- /dev/null +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/compat/RegistryUtil.java @@ -0,0 +1,57 @@ +package dev.su5ed.sinytra.connector.mod.compat; + +import com.google.common.collect.BiMap; +import com.mojang.datafixers.util.Pair; +import com.mojang.logging.LogUtils; +import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader; +import net.fabricmc.fabric.impl.registry.sync.DynamicRegistriesImpl; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.fml.loading.FMLLoader; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import org.slf4j.Logger; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck; + +public class RegistryUtil { + private static final VarHandle REGISTRY_NAMES = uncheck(() -> MethodHandles.privateLookupIn(ForgeRegistry.class, MethodHandles.lookup()).findVarHandle(ForgeRegistry.class, "names", BiMap.class)); + private static final ResourceLocation PARTICLE_TYPE_REGISTRY = ForgeRegistries.Keys.PARTICLE_TYPES.location(); + private static final Logger LOGGER = LogUtils.getLogger(); + + public static boolean isRegisteredFabricDynamicRegistry(ResourceKey key) { + return DynamicRegistriesImpl.FABRIC_DYNAMIC_REGISTRY_KEYS.stream().anyMatch(key::equals); + } + + public static void retainFabricClientEntries(ResourceLocation name, ForgeRegistry from, IForgeRegistry to) { + if (FMLLoader.getDist().isClient() && name.equals(PARTICLE_TYPE_REGISTRY)) { + List> list = new ArrayList<>(); + + for (Map.Entry, V> entry : to.getEntries()) { + ResourceLocation location = entry.getKey().location(); + if (!from.containsKey(location) && ConnectorEarlyLoader.isConnectorMod(location.getNamespace())) { + list.add(Pair.of(location, entry.getValue())); + } + } + + if (!list.isEmpty()) { + LOGGER.info("Connector found {} items to retain in registry {}", list.size(), name); + } + + for (Pair pair : list) { + RegistryUtil.getNames(from).put(pair.getFirst(), pair.getSecond()); + } + } + } + + private static BiMap getNames(ForgeRegistry registry) { + return (BiMap) uncheck(() -> REGISTRY_NAMES.get(registry)); + } +} diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/ClientForgeRegistryMixin.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/ClientForgeRegistryMixin.java new file mode 100644 index 00000000..f5b4d0a2 --- /dev/null +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/ClientForgeRegistryMixin.java @@ -0,0 +1,19 @@ +package dev.su5ed.sinytra.connector.mod.mixin.registries; + +import dev.su5ed.sinytra.connector.mod.compat.RegistryUtil; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(ForgeRegistry.class) +public abstract class ClientForgeRegistryMixin implements IForgeRegistry { + + @Inject(method = "sync", at = @At(value = "INVOKE", target = "Lcom/google/common/collect/BiMap;clear()V", ordinal = 0), remap = false) + private void retainFabricClientEntries(ResourceLocation name, ForgeRegistry from, CallbackInfo ci) { + RegistryUtil.retainFabricClientEntries(name, from, this); + } +} diff --git a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/RegistryDataLoaderMixin.java b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/RegistryDataLoaderMixin.java index 66a4f06d..4f44316d 100644 --- a/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/RegistryDataLoaderMixin.java +++ b/src/mod/java/dev/su5ed/sinytra/connector/mod/mixin/registries/RegistryDataLoaderMixin.java @@ -1,7 +1,7 @@ package dev.su5ed.sinytra.connector.mod.mixin.registries; import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader; -import dev.su5ed.sinytra.connector.mod.compat.DynamicRegistryPrefixes; +import dev.su5ed.sinytra.connector.mod.compat.RegistryUtil; import net.minecraft.core.Registry; import net.minecraft.resources.FileToIdConverter; import net.minecraft.resources.RegistryDataLoader; @@ -73,7 +73,7 @@ private static String modifyRegistryDirPath(ResourceLocation location, RegistryO private static boolean connector$shouldOmitPrefix(ResourceLocation location, ResourceKey> registryKey, ResourceManager manager) { String modid = location.getNamespace(); // Fabric mod registries added directly to RegistryDataLoader.WORLDGEN_REGISTRIES should not be prefixed - if (ConnectorEarlyLoader.isConnectorMod(modid) && ModList.get().isLoaded("fabric_registry_sync_v0") && !DynamicRegistryPrefixes.isRegisteredFabricDynamicRegistry(registryKey)) { + if (ConnectorEarlyLoader.isConnectorMod(modid) && ModList.get().isLoaded("fabric_registry_sync_v0") && !RegistryUtil.isRegisteredFabricDynamicRegistry(registryKey)) { return true; } // Check if the registry has been registered diff --git a/src/mod/resources/connectormod.mixins.json b/src/mod/resources/connectormod.mixins.json index eff365f0..4e39c8bd 100644 --- a/src/mod/resources/connectormod.mixins.json +++ b/src/mod/resources/connectormod.mixins.json @@ -43,7 +43,8 @@ "recipebook.RecipeBookCategoriesAccessor", "recipebook.RecipeBookCategoriesMixin", "recipebook.RecipeBookManagerMixin", - "registries.MinecraftMixin" + "registries.MinecraftMixin", + "registries.ClientForgeRegistryMixin" ], "server": [ "boot.ServerMainMixin",