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 <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2019-10-04 15:24:15 -04:00
parent dc5a06aab4
commit 8482293b40
No known key found for this signature in database
GPG Key ID: 8EB3DF749553B1B7
3 changed files with 85 additions and 30 deletions

View File

@ -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 <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter) {
return (packList, factory) -> clientPackFinder(modResourcePacks, packSetter, packList, factory);
}
private static <T extends ResourcePackInfo> void clientPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<T> factory) {
for (Map.Entry<ModFile, ModFileResourcePack> 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);
}
}
}

View File

@ -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<ModFile, ModFileResourcePack> modResourcePacks;
private static ResourcePackList<?> resourcePackList;
@ -54,36 +49,32 @@ public class ResourcePackLoader
map(ModFileInfo::getFile).map(mf->modResourcePacks.get(mf));
}
public static <T extends ResourcePackInfo> void loadResourcePacks(ResourcePackList<T> resourcePacks) {
public static <T extends ResourcePackInfo> void loadResourcePacks(ResourcePackList<T> resourcePacks, BiFunction<Map<ModFile, ModFileResourcePack>, BiConsumer<ModFileResourcePack, T>, 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<T extends ResourcePackInfo> {
void addPackInfosToMap(Map<String, T> packList, ResourcePackInfo.IFactory<T> 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 <T extends ResourcePackInfo> void addPackInfosToMap(Map<String, T> packList, ResourcePackInfo.IFactory<T> factory)
{
for (Entry<ModFile, ModFileResourcePack> 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);
}
}
}

View File

@ -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 <T extends ResourcePackInfo> ResourcePackLoader.IPackInfoFinder<T> buildPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter) {
return (packList, factory) -> serverPackFinder(modResourcePacks, packSetter, packList, factory);
}
private static <T extends ResourcePackInfo> void serverPackFinder(Map<ModFile, ModFileResourcePack> modResourcePacks, BiConsumer<ModFileResourcePack, T> packSetter, Map<String, T> packList, ResourcePackInfo.IFactory<T> factory) {
for (Map.Entry<ModFile, ModFileResourcePack> 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);
}
}
}