From 8482293b40273aba2a60b80cbece2cdfea41aca3 Mon Sep 17 00:00:00 2001 From: cpw Date: Fri, 4 Oct 2019 15:24:15 -0400 Subject: [PATCH] Split server and client side pack locators apart and move them to their respective behavioural components. This should facilitate fixing the server pack data pack ordering, as well as other new features of mod resource packs. Signed-off-by: cpw --- .../fml/client/ClientModLoader.java | 33 +++++++++++++- .../fml/packs/ResourcePackLoader.java | 45 ++++++++----------- .../fml/server/ServerLifecycleHooks.java | 37 ++++++++++++++- 3 files changed, 85 insertions(+), 30 deletions(-) diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 8625a82d2..fa3f3a5fa 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -26,6 +26,7 @@ import net.minecraft.profiler.IProfiler; import net.minecraft.resources.IFutureReloadListener; import net.minecraft.resources.IReloadableResourceManager; import net.minecraft.resources.IResourceManager; +import net.minecraft.resources.ResourcePackInfo; import net.minecraft.resources.ResourcePackList; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -38,13 +39,17 @@ import net.minecraftforge.fml.BrandingControl; import net.minecraftforge.fml.LoadingFailedException; import net.minecraftforge.fml.LogicalSidedProvider; import net.minecraftforge.fml.ModLoader; +import net.minecraftforge.fml.ModLoadingStage; import net.minecraftforge.fml.ModLoadingWarning; import net.minecraftforge.fml.SidedProvider; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.client.gui.LoadingErrorScreen; import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.loading.moddiscovery.ModFile; +import net.minecraftforge.fml.packs.ModFileResourcePack; import net.minecraftforge.fml.packs.ResourcePackLoader; import net.minecraftforge.fml.server.LanguageHook; +import net.minecraftforge.forgespi.language.IModInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -52,11 +57,15 @@ import com.mojang.blaze3d.platform.GlStateManager; import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Supplier; +import static net.minecraftforge.fml.Logging.CORE; import static net.minecraftforge.fml.loading.LogMarkers.LOADING; @OnlyIn(Dist.CLIENT) @@ -77,7 +86,7 @@ public class ClientModLoader LanguageHook.loadForgeAndMCLangs(); earlyLoaderGUI = new EarlyLoaderGUI(minecraft.mainWindow); createRunnableWithCatch(() -> ModLoader.get().gatherAndInitializeMods(earlyLoaderGUI::renderTick)).run(); - ResourcePackLoader.loadResourcePacks(defaultResourcePacks); + ResourcePackLoader.loadResourcePacks(defaultResourcePacks, ClientModLoader::buildPackFinder); mcResourceManager.addReloadListener(ClientModLoader::onreload); mcResourceManager.addReloadListener(BrandingControl.resourceManagerReloadListener()); ModelLoaderRegistry.init(); @@ -163,4 +172,26 @@ public class ClientModLoader { return loading; } + + private static ResourcePackLoader.IPackInfoFinder buildPackFinder(Map modResourcePacks, BiConsumer packSetter) { + return (packList, factory) -> clientPackFinder(modResourcePacks, packSetter, packList, factory); + } + + private static void clientPackFinder(Map modResourcePacks, BiConsumer packSetter, Map packList, ResourcePackInfo.IFactory factory) { + for (Map.Entry e : modResourcePacks.entrySet()) + { + IModInfo mod = e.getKey().getModInfos().get(0); + if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod" + final String name = "mod:" + mod.getModId(); + final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM); + if (packInfo == null) { + // Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong + ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey())); + continue; + } + packSetter.accept(e.getValue(), packInfo); + LOGGER.debug(CORE, "Generating PackInfo named {} for mod file {}", name, e.getKey().getFilePath()); + packList.put(name, packInfo); + } + } } diff --git a/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java b/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java index 724fb89f8..5eca5f7ba 100644 --- a/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java +++ b/src/main/java/net/minecraftforge/fml/packs/ResourcePackLoader.java @@ -19,12 +19,12 @@ package net.minecraftforge.fml.packs; -import static net.minecraftforge.fml.Logging.CORE; import java.util.Map; -import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; @@ -35,16 +35,11 @@ import net.minecraft.resources.IPackFinder; import net.minecraft.resources.ResourcePackInfo; import net.minecraft.resources.ResourcePackList; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoader; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.ModLoadingWarning; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; -import net.minecraftforge.forgespi.language.IModInfo; public class ResourcePackLoader { - private static final Logger LOGGER = LogManager.getLogger(); private static Map modResourcePacks; private static ResourcePackList resourcePackList; @@ -54,36 +49,32 @@ public class ResourcePackLoader map(ModFileInfo::getFile).map(mf->modResourcePacks.get(mf)); } - public static void loadResourcePacks(ResourcePackList resourcePacks) { + public static void loadResourcePacks(ResourcePackList resourcePacks, BiFunction, BiConsumer, IPackInfoFinder> packFinder) { resourcePackList = resourcePacks; modResourcePacks = ModList.get().getModFiles().stream(). filter(mf->!Objects.equals(mf.getModLoader(),"minecraft")). map(mf -> new ModFileResourcePack(mf.getFile())). collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity())); - resourcePacks.addPackFinder(new ModPackFinder()); + resourcePacks.addPackFinder(new LambdaFriendlyPackFinder(packFinder.apply(modResourcePacks, ModFileResourcePack::setPackInfo))); } - private static class ModPackFinder implements IPackFinder - { + public interface IPackInfoFinder { + void addPackInfosToMap(Map packList, ResourcePackInfo.IFactory factory); + } + + // SO GROSS - DON'T @ me bro + @SuppressWarnings("unchecked") + private static class LambdaFriendlyPackFinder implements IPackFinder { + private IPackInfoFinder wrapped; + + private LambdaFriendlyPackFinder(final IPackInfoFinder wrapped) { + this.wrapped = wrapped; + } + @Override public void addPackInfosToMap(Map packList, ResourcePackInfo.IFactory factory) { - for (Entry e : modResourcePacks.entrySet()) - { - IModInfo mod = e.getKey().getModInfos().get(0); - if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod" - final String name = "mod:" + mod.getModId(); - final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM); - if (packInfo == null) { - // Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong - ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey())); - continue; - } - e.getValue().setPackInfo(packInfo); - LOGGER.debug(CORE, "Generating PackInfo named {} for mod file {}", name, e.getKey().getFilePath()); - packList.put(name, packInfo); - } + wrapped.addPackInfosToMap(packList, factory); } - } } diff --git a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java index 5bdcf15e9..23c2fe10a 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java @@ -23,12 +23,16 @@ import net.minecraft.network.ProtocolType; import net.minecraft.network.NetworkManager; import net.minecraft.network.handshake.client.CHandshakePacket; import net.minecraft.network.login.server.SDisconnectLoginPacket; +import net.minecraft.resources.ResourcePackInfo; import net.minecraft.server.MinecraftServer; import net.minecraft.util.text.StringTextComponent; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.LogicalSidedProvider; +import net.minecraftforge.fml.ModLoader; +import net.minecraftforge.fml.ModLoadingStage; +import net.minecraftforge.fml.ModLoadingWarning; import net.minecraftforge.fml.config.ConfigTracker; import net.minecraftforge.fml.config.ModConfig; import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent; @@ -37,20 +41,27 @@ import net.minecraftforge.fml.event.server.FMLServerStartedEvent; import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.loading.FileUtils; +import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.network.ConnectionType; import net.minecraftforge.fml.network.FMLNetworkConstants; import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.network.NetworkRegistry; +import net.minecraftforge.fml.packs.ModFileResourcePack; import net.minecraftforge.fml.packs.ResourcePackLoader; +import net.minecraftforge.forgespi.language.IModInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import java.nio.file.Path; -import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.BiConsumer; + +import static net.minecraftforge.fml.Logging.CORE; public class ServerLifecycleHooks { @@ -66,7 +77,7 @@ public class ServerLifecycleHooks final Path serverConfig = server.getActiveAnvilConverter().getFile(server.getFolderName(), "serverconfig").toPath(); FileUtils.getOrCreateDirectory(serverConfig, "serverconfig"); ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.SERVER, serverConfig); - ResourcePackLoader.loadResourcePacks(currentServer.getResourcePacks()); + ResourcePackLoader.loadResourcePacks(currentServer.getResourcePacks(), ServerLifecycleHooks::buildPackFinder); return !MinecraftForge.EVENT_BUS.post(new FMLServerAboutToStartEvent(server)); } @@ -182,4 +193,26 @@ public class ServerLifecycleHooks System.exit(retVal); } + private static ResourcePackLoader.IPackInfoFinder buildPackFinder(Map modResourcePacks, BiConsumer packSetter) { + return (packList, factory) -> serverPackFinder(modResourcePacks, packSetter, packList, factory); + } + + private static void serverPackFinder(Map modResourcePacks, BiConsumer packSetter, Map packList, ResourcePackInfo.IFactory factory) { + for (Map.Entry e : modResourcePacks.entrySet()) + { + IModInfo mod = e.getKey().getModInfos().get(0); + if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod" + final String name = "mod:" + mod.getModId(); + final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM); + if (packInfo == null) { + // Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong + ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey())); + continue; + } + packSetter.accept(e.getValue(), packInfo); + LOGGER.debug(CORE, "Generating PackInfo named {} for mod file {}", name, e.getKey().getFilePath()); + packList.put(name, packInfo); + } + } + }