diff --git a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java b/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java index 2563dda6d..0b30f0b55 100644 --- a/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java +++ b/src/main/java/net/minecraftforge/client/event/ModelRegistryEvent.java @@ -20,11 +20,10 @@ package net.minecraftforge.client.event; import net.minecraftforge.eventbus.api.Event; -import net.minecraftforge.fml.common.eventhandler.IContextSetter; /** * Fired when the {@link net.minecraftforge.client.model.ModelLoader} is ready to receive registrations */ -public class ModelRegistryEvent extends Event implements IContextSetter +public class ModelRegistryEvent extends Event { } diff --git a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java b/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java index de791c42f..441a2e883 100644 --- a/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java +++ b/src/main/java/net/minecraftforge/common/capabilities/CapabilityManager.java @@ -22,50 +22,30 @@ package net.minecraftforge.common.capabilities; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.IdentityHashMap; import java.util.List; +import java.util.Objects; import java.util.concurrent.Callable; +import net.minecraftforge.fml.language.ModFileScanData; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.objectweb.asm.Type; import java.util.function.Function; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import java.util.stream.Collectors; import net.minecraftforge.common.util.EnumHelper; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.discovery.ASMDataTable; + +import static net.minecraftforge.fml.Logging.CAPABILITIES; public enum CapabilityManager { INSTANCE; - - /** - * Registers a capability to be consumed by others. - * APIs who define the capability should call this. - * To retrieve the Capability instance, use the @CapabilityInject annotation. - * - * @param type The Interface to be registered - * @param storage A default implementation of the storage handler. - * @param implementation A default implementation of the interface. - * @deprecated Use the overload that takes a factory instead of a class. - * You can easily do this by passing a constructor reference - * (MyImpl::new instead of MyImpl.class). TODO remove in 1.13. - */ - @Deprecated - public void register(Class type, Capability.IStorage storage, final Class implementation) - { - Preconditions.checkArgument(implementation != null, "Attempted to register a capability with no default implementation"); - register(type, storage, () -> - { - try { - return implementation.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new RuntimeException(e); - } - }); - } + private static final Logger LOGGER = LogManager.getLogger("FML"); /** * Registers a capability to be consumed by others. @@ -78,103 +58,95 @@ public enum CapabilityManager */ public void register(Class type, Capability.IStorage storage, Callable factory) { - Preconditions.checkArgument(type != null, "Attempted to register a capability with invalid type"); - Preconditions.checkArgument(storage != null, "Attempted to register a capability with no storage implementation"); - Preconditions.checkArgument(factory != null, "Attempted to register a capability with no default implementation factory"); + Objects.requireNonNull(type,"Attempted to register a capability with invalid type"); + Objects.requireNonNull(storage,"Attempted to register a capability with no storage implementation"); + Objects.requireNonNull(factory,"Attempted to register a capability with no default implementation factory"); String realName = type.getName().intern(); - Preconditions.checkState(!providers.containsKey(realName), "Can not register a capability implementation multiple times: %s", realName); + if (providers.containsKey(realName)) { + LOGGER.error(CAPABILITIES, "Cannot register capability implementation multiple times : {}", realName); + throw new IllegalArgumentException("Cannot register a capability implementation multiple times : "+ realName); + } - Capability cap = new Capability(realName, storage, factory); + Capability cap = new Capability<>(realName, storage, factory); providers.put(realName, cap); - List, Object>> list = callbacks.get(realName); - if (list != null) - { - for (Function, Object> func : list) - { - func.apply(cap); - } - } + callbacks.getOrDefault(realName, Collections.emptyList()).forEach(func -> func.apply(cap)); } // INTERNAL - private IdentityHashMap> providers = Maps.newIdentityHashMap(); - private IdentityHashMap, Object>>> callbacks = Maps.newIdentityHashMap(); - public void injectCapabilities(ASMDataTable data) + private IdentityHashMap> providers = new IdentityHashMap<>(); + private IdentityHashMap, Object>>> callbacks = new IdentityHashMap<>(); + public void injectCapabilities(List data) { - for (ASMDataTable.ASMData entry : data.getAll(CapabilityInject.class.getName())) + final List capabilities = data.stream().map(ModFileScanData::getAnnotations).flatMap(Collection::stream). + filter(a -> Objects.equals(a.getClassType(), Type.getType(CapabilityInject.class))). + collect(Collectors.toList()); + capabilities.forEach(this::attachCapabilityToMethod); + } + + private void attachCapabilityToMethod(ModFileScanData.AnnotationData entry) + { + final String targetClass = entry.getClassType().getClassName(); + final String targetName = entry.getMemberName(); + Type type = (Type)entry.getAnnotationData().get("value"); + if (type == null) { - final String targetClass = entry.getClassName(); - final String targetName = entry.getObjectName(); - Type type = (Type)entry.getAnnotationInfo().get("value"); - if (type == null) - { - FMLLog.log.warn("Unable to inject capability at {}.{} (Invalid Annotation)", targetClass, targetName); - continue; - } - final String capabilityName = type.getInternalName().replace('/', '.').intern(); + LOGGER.warn(CAPABILITIES,"Unable to inject capability at {}.{} (Invalid Annotation)", targetClass, targetName); + return; + } + final String capabilityName = type.getInternalName().replace('/', '.').intern(); - List, Object>> list = callbacks.computeIfAbsent(capabilityName, k -> Lists.newArrayList()); + List, Object>> list = callbacks.computeIfAbsent(capabilityName, k -> new ArrayList<>()); - if (entry.getObjectName().indexOf('(') > 0) - { - list.add(new Function, Object>() + if (entry.getMemberName().indexOf('(') > 0) + { + list.add(input -> { + try { - @Override - public Object apply(Capability input) + for (Method mtd : Class.forName(targetClass).getDeclaredMethods()) { - try + if (targetName.equals(mtd.getName() + Type.getMethodDescriptor(mtd))) { - for (Method mtd : Class.forName(targetClass).getDeclaredMethods()) + if ((mtd.getModifiers() & Modifier.STATIC) != Modifier.STATIC) { - if (targetName.equals(mtd.getName() + Type.getMethodDescriptor(mtd))) - { - if ((mtd.getModifiers() & Modifier.STATIC) != Modifier.STATIC) - { - FMLLog.log.warn("Unable to inject capability {} at {}.{} (Non-Static)", capabilityName, targetClass, targetName); - return null; - } - - mtd.setAccessible(true); - mtd.invoke(null, input); - return null; - } - } - FMLLog.log.warn("Unable to inject capability {} at {}.{} (Method Not Found)", capabilityName, targetClass, targetName); - } - catch (Exception e) - { - FMLLog.log.warn("Unable to inject capability {} at {}.{}", capabilityName, targetClass, targetName, e); - } - return null; - } - }); - } - else - { - list.add(new Function, Object>() - { - @Override - public Object apply(Capability input) - { - try - { - Field field = Class.forName(targetClass).getDeclaredField(targetName); - if ((field.getModifiers() & Modifier.STATIC) != Modifier.STATIC) - { - FMLLog.log.warn("Unable to inject capability {} at {}.{} (Non-Static)", capabilityName, targetClass, targetName); + LOGGER.warn(CAPABILITIES,"Unable to inject capability {} at {}.{} (Non-Static)", capabilityName, targetClass, targetName); return null; } - EnumHelper.setFailsafeFieldValue(field, null, input); - } - catch (Exception e) - { - FMLLog.log.warn("Unable to inject capability {} at {}.{}", capabilityName, targetClass, targetName, e); + + mtd.setAccessible(true); + mtd.invoke(null, input); + return null; } + } + LOGGER.warn(CAPABILITIES,"Unable to inject capability {} at {}.{} (Method Not Found)", capabilityName, targetClass, targetName); + } + catch (Exception e) + { + LOGGER.warn(CAPABILITIES,"Unable to inject capability {} at {}.{}", capabilityName, targetClass, targetName, e); + } + return null; + }); + } + else + { + list.add(input -> { + try + { + Field field = Class.forName(targetClass).getDeclaredField(targetName); + if ((field.getModifiers() & Modifier.STATIC) != Modifier.STATIC) + { + LOGGER.warn(CAPABILITIES,"Unable to inject capability {} at {}.{} (Non-Static)", capabilityName, targetClass, targetName); return null; } - }); - } + // TODO Remove enumhelper here + EnumHelper.setFailsafeFieldValue(field, null, input); + } + catch (Exception e) + { + LOGGER.warn(CAPABILITIES,"Unable to inject capability {} at {}.{}", capabilityName, targetClass, targetName, e); + } + return null; + }); } } } diff --git a/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java b/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java index 5e44b02e3..44c691cf0 100644 --- a/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java +++ b/src/main/java/net/minecraftforge/fml/AutomaticEventSubscriber.java @@ -30,6 +30,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.objectweb.asm.Type; +import java.util.Arrays; import java.util.EnumSet; import java.util.List; import java.util.Objects; @@ -52,7 +53,9 @@ public class AutomaticEventSubscriber collect(Collectors.toList()); ebsTargets.forEach(ad -> { - final List sidesValue = (List)ad.getAnnotationData().get("value"); + @SuppressWarnings("unchecked") + final List sidesValue = (List)ad.getAnnotationData(). + getOrDefault("value", Arrays.asList(new ModAnnotation.EnumHolder(null, "CLIENT"), new ModAnnotation.EnumHolder(null, "SERVER"))); final EnumSet sides = sidesValue.stream().map(eh -> Side.valueOf(eh.getValue())). collect(Collectors.toCollection(() -> EnumSet.noneOf(Side.class))); final String modId = (String)ad.getAnnotationData().getOrDefault("modId", mod.getModId()); diff --git a/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java b/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java new file mode 100644 index 000000000..468b4b16b --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java @@ -0,0 +1,44 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml; + +import java.util.concurrent.Callable; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; + +public class DeferredWorkQueue +{ + public static ConcurrentLinkedDeque> deferredWorkQueue = new ConcurrentLinkedDeque<>(); + + public static Future enqueueWork(Callable workToEnqueue) { + final FutureWorkTask workTask = new FutureWorkTask<>(workToEnqueue); + DeferredWorkQueue.deferredWorkQueue.add(workTask); + return workTask; + } + + public static class FutureWorkTask extends FutureTask + { + FutureWorkTask(Callable callable) + { + super(callable); + } + } +} diff --git a/src/main/java/net/minecraftforge/fml/language/ExtensionPoint.java b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java similarity index 96% rename from src/main/java/net/minecraftforge/fml/language/ExtensionPoint.java rename to src/main/java/net/minecraftforge/fml/ExtensionPoint.java index 02246d01a..c6d554d64 100644 --- a/src/main/java/net/minecraftforge/fml/language/ExtensionPoint.java +++ b/src/main/java/net/minecraftforge/fml/ExtensionPoint.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.language; +package net.minecraftforge.fml; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; diff --git a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java index e140013f1..e79be46f2 100644 --- a/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java +++ b/src/main/java/net/minecraftforge/fml/LifecycleEventProvider.java @@ -19,7 +19,6 @@ package net.minecraftforge.fml; -import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.fml.common.event.ModLifecycleEvent; import net.minecraftforge.fml.javafmlmod.FMLModContainer; @@ -27,8 +26,12 @@ import java.util.function.Supplier; public enum LifecycleEventProvider { - LOAD(()->new LifecycleEvent(ModLoadingStage.BEGIN)), - CONSTRUCT(()->new LifecycleEvent(ModLoadingStage.CONSTRUCT)); + CONSTRUCT(()->new LifecycleEvent(ModLoadingStage.CONSTRUCT)), + PREINIT(()->new LifecycleEvent(ModLoadingStage.PREINIT)), + SIDEDINIT(()->new LifecycleEvent(ModLoadingStage.SIDEDINIT)), + INIT(()->new LifecycleEvent(ModLoadingStage.INIT)), + POSTINIT(()->new LifecycleEvent(ModLoadingStage.POSTINIT)), + COMPLETE(()->new LifecycleEvent(ModLoadingStage.COMPLETE)); public void dispatch() { ModList.get().dispatchLifeCycleEvent(this.event.get()); diff --git a/src/main/java/net/minecraftforge/fml/Logging.java b/src/main/java/net/minecraftforge/fml/Logging.java index 3c835d361..c180face5 100644 --- a/src/main/java/net/minecraftforge/fml/Logging.java +++ b/src/main/java/net/minecraftforge/fml/Logging.java @@ -35,5 +35,6 @@ public class Logging public static final Marker LOADING = MarkerManager.getMarker("LOADING"); public static final Marker SCAN = MarkerManager.getMarker("SCAN"); public static final Marker SPLASH = MarkerManager.getMarker("SPLASH"); + public static final Marker CAPABILITIES = MarkerManager.getMarker("CAPABILITIES"); public static final Marker MODELLOADING = MarkerManager.getMarker("MODELLOADING"); } diff --git a/src/main/java/net/minecraftforge/fml/ModContainer.java b/src/main/java/net/minecraftforge/fml/ModContainer.java index 88c601767..979a5155d 100644 --- a/src/main/java/net/minecraftforge/fml/ModContainer.java +++ b/src/main/java/net/minecraftforge/fml/ModContainer.java @@ -19,7 +19,6 @@ package net.minecraftforge.fml; -import net.minecraftforge.fml.language.ExtensionPoint; import net.minecraftforge.fml.language.IModInfo; import java.util.ArrayList; @@ -59,7 +58,7 @@ public abstract class ModContainer this.modInfo = info; this.triggerMap = new HashMap<>(); this.modLoadingError = new ArrayList<>(); - this.modLoadingStage = ModLoadingStage.BEGIN; + this.modLoadingStage = ModLoadingStage.CONSTRUCT; } /** @@ -101,6 +100,7 @@ public abstract class ModContainer } catch (RuntimeException e) { + modLoadingError.add(e); modLoadingStage = ModLoadingStage.ERROR; } } diff --git a/src/main/java/net/minecraftforge/fml/ModList.java b/src/main/java/net/minecraftforge/fml/ModList.java index 89eadb512..4451b7237 100644 --- a/src/main/java/net/minecraftforge/fml/ModList.java +++ b/src/main/java/net/minecraftforge/fml/ModList.java @@ -20,31 +20,45 @@ package net.minecraftforge.fml; import com.google.common.collect.Streams; +import net.minecraftforge.fml.javafmlmod.ModLoadingContext; +import net.minecraftforge.fml.language.ModFileScanData; import net.minecraftforge.fml.loading.DefaultModInfos; +import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.moddiscovery.BackgroundScanHandler; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import net.minecraftforge.fml.loading.moddiscovery.ModInfo; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.FutureTask; import java.util.function.Function; import java.util.stream.Collectors; +import static net.minecraftforge.fml.Logging.LOADING; + /** - * Master list of all mods + * Master list of all mods - game-side version. This is classloaded in the game scope and + * can dispatch game level events as a result. */ public class ModList { + private static Logger LOGGER = LogManager.getLogger("FML"); private static ModList INSTANCE; private final List modFiles; private final List sortedList; private final Map fileById; - private BackgroundScanHandler scanner; private List mods; private Map indexedMods; + private ForkJoinPool modLoadingThreadPool = new ForkJoinPool(); + private List modFileScanData; private ModList(final List modFiles, final List sortedList) { @@ -79,10 +93,21 @@ public class ModList } public void dispatchLifeCycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { - this.mods.parallelStream().forEach(m->m.transitionState(lifecycleEvent)); + FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.preLifecycleEvent(lifecycleEvent)); + DeferredWorkQueue.deferredWorkQueue.clear(); + try + { + modLoadingThreadPool.submit(()->this.mods.parallelStream().forEach(m->m.transitionState(lifecycleEvent))).get(); + } + catch (InterruptedException | ExecutionException e) + { + LOGGER.error(LOADING, "Encountered an exception during parallel processing", e); + } + DeferredWorkQueue.deferredWorkQueue.forEach(FutureTask::run); + FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.postLifecycleEvent(lifecycleEvent)); final List erroredContainers = this.mods.stream().filter(m -> m.getCurrentState() == ModLoadingStage.ERROR).collect(Collectors.toList()); if (!erroredContainers.isEmpty()) { - throw new RuntimeException("Errored containers found!"); + throw new RuntimeException("Errored containers found!", erroredContainers.get(0).modLoadingError.get(0)); } } @@ -92,9 +117,10 @@ public class ModList this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity())); } - public Optional getModObjectById(String modId) + @SuppressWarnings("unchecked") + public Optional getModObjectById(String modId) { - return getModContainerById(modId).map(ModContainer::getMod); + return getModContainerById(modId).map(ModContainer::getMod).map(o -> (T) o); } public Optional getModContainerById(String modId) @@ -111,4 +137,24 @@ public class ModList { return this.indexedMods.containsKey(modTarget); } + + public int size() + { + return mods.size(); + } + + public List getAllScanData() + { + if (modFileScanData == null) + { + modFileScanData = this.sortedList.stream(). + map(ModInfo::getOwningFile). + filter(Objects::nonNull). + map(ModFileInfo::getFile). + map(ModFile::getScanResult). + collect(Collectors.toList()); + } + return modFileScanData; + + } } diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 5cbdd2491..58efba084 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -19,17 +19,24 @@ package net.minecraftforge.fml; +import net.minecraftforge.api.Side; +import net.minecraftforge.client.event.ModelRegistryEvent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.fml.language.IModInfo; import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.LoadingModList; import net.minecraftforge.fml.loading.moddiscovery.ModFile; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; +import net.minecraftforge.registries.GameData; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.Collection; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Callable; import java.util.function.Function; import java.util.stream.Collectors; @@ -55,15 +62,24 @@ public class ModLoader return INSTANCE == null ? INSTANCE = new ModLoader() : INSTANCE; } + private static Callable fireClientEvents() + { + return ()->MinecraftForge.EVENT_BUS.post(new ModelRegistryEvent()); + } + public void loadMods() { final ModList modList = ModList.of(loadingModList.getModFiles().stream().map(ModFileInfo::getFile).collect(Collectors.toList()), loadingModList.getMods()); modList.setLoadedMods(loadingModList.getModFiles().stream(). map(ModFileInfo::getFile). map(mf -> buildMods(mf, modClassLoader)). flatMap(Collection::stream).collect(Collectors.toList())); - - LifecycleEventProvider.LOAD.dispatch(); LifecycleEventProvider.CONSTRUCT.dispatch(); + GameData.fireCreateRegistryEvents(); + CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData()); + LifecycleEventProvider.PREINIT.dispatch(); + GameData.fireRegistryEvents(rl -> !Objects.equals(rl, GameData.RECIPES)); + SidedExecutor.runOn(Side.CLIENT, ModLoader::fireClientEvents); + LifecycleEventProvider.SIDEDINIT.dispatch(); } private List buildMods(final ModFile modFile, final ModLoadingClassLoader modClassLoader) @@ -76,4 +92,10 @@ public class ModLoader } + public void finishMods() + { + LifecycleEventProvider.INIT.dispatch(); + LifecycleEventProvider.POSTINIT.dispatch(); + LifecycleEventProvider.COMPLETE.dispatch(); + } } diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingException.java b/src/main/java/net/minecraftforge/fml/ModLoadingException.java new file mode 100644 index 000000000..4bd4ee725 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/ModLoadingException.java @@ -0,0 +1,34 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml; + +import java.util.ArrayList; +import java.util.List; + +/** + * Accumulates errors during loading for compact handling + */ +public class ModLoadingException extends RuntimeException +{ + private List errorEvents = new ArrayList<>(); + public static class ErrorEvent { + + } +} diff --git a/src/main/java/net/minecraftforge/fml/ModLoadingStage.java b/src/main/java/net/minecraftforge/fml/ModLoadingStage.java index 0b4c4f37d..9bc0fff0c 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoadingStage.java +++ b/src/main/java/net/minecraftforge/fml/ModLoadingStage.java @@ -31,12 +31,13 @@ import java.util.function.Supplier; public enum ModLoadingStage { ERROR(null), - BEGIN(null), - CONSTRUCT(()->FMLPreInitializationEvent::new), - PREINIT(()->FMLInitializationEvent::new), - INIT(()->FMLPostInitializationEvent::new), - POSTINIT(()->FMLLoadCompleteEvent::new), - COMPLETE(null); + CONSTRUCT(null), + PREINIT(()->FMLPreInitializationEvent::new), + SIDEDINIT(SidedProvider.SIDEDINIT::get), + INIT(()->FMLInitializationEvent::new), + POSTINIT(()->FMLPostInitializationEvent::new), + COMPLETE(()->FMLLoadCompleteEvent::new), + DONE(null); private final Supplier> modLifecycleEventFunction; diff --git a/src/main/java/net/minecraftforge/fml/OptionalMod.java b/src/main/java/net/minecraftforge/fml/OptionalMod.java new file mode 100644 index 000000000..d3724b4a3 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/OptionalMod.java @@ -0,0 +1,241 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml; + +import java.util.NoSuchElementException; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; + +public final class OptionalMod +{ + private final String modId; + private T value; + private boolean searched; + + public static OptionalMod of(final String modId) { + return new OptionalMod<>(modId); + } + + private static OptionalMod EMPTY = new OptionalMod<>(true); + private static OptionalMod empty() { + @SuppressWarnings("unchecked") + OptionalMod t = (OptionalMod) EMPTY; + return t; + } + + private OptionalMod(boolean searched) { + this.searched = searched; + this.modId = ""; + } + + private OptionalMod(String modId) + { + this.modId = modId; + } + + private T getValue() + { + if (!searched) { + this.value = ModList.get().getModObjectById(this.modId).orElse(null); + searched = true; + } + return this.value; + } + + /** + * If a mod is present in this {@code OptionalMod}, returns the value, + * otherwise throws {@code NoSuchElementException}. + * + * @return the modobject held by this {@code OptionalMod} + * @throws NoSuchElementException if there is no modobject present + * + * @see Optional#isPresent() + */ + public T get() { + if (getValue() == null) { + throw new NoSuchElementException("No value present"); + } + return getValue(); + } + + public String getModId() { + return this.modId; + } + + /** + * Return {@code true} if there is a mod object present, otherwise {@code false}. + * + * @return {@code true} if there is a mod object present, otherwise {@code false} + */ + public boolean isPresent() { + return getValue() != null; + } + + /** + * If a mod object is present, invoke the specified consumer with the object, + * otherwise do nothing. + * + * @param consumer block to be executed if a mod object is present + * @throws NullPointerException if mod object is present and {@code consumer} is + * null + */ + public void ifPresent(Consumer consumer) { + if (getValue() != null) + consumer.accept(getValue()); + } + + /** + * If a mod object is present, and the mod object matches the given predicate, + * return an {@code OptionalMod} describing the value, otherwise return an + * empty {@code OptionalMod}. + * + * @param predicate a predicate to apply to the mod object, if present + * @return an {@code OptionalMod} describing the value of this {@code OptionalMod} + * if a mod object is present and the mod object matches the given predicate, + * otherwise an empty {@code OptionalMod} + * @throws NullPointerException if the predicate is null + */ + public OptionalMod filter(Predicate predicate) { + Objects.requireNonNull(predicate); + if (!isPresent()) + return this; + else + return predicate.test(getValue()) ? this : empty(); + } + + /** + * If a mod object is present, apply the provided mapping function to it, + * and if the result is non-null, return an {@code Optional} describing the + * result. Otherwise return an empty {@code Optional}. + * + * @apiNote This method supports post-processing on optional values, without + * the need to explicitly check for a return status. + * + * @param The type of the result of the mapping function + * @param mapper a mapping function to apply to the mod object, if present + * @return an {@code Optional} describing the result of applying a mapping + * function to the mod object of this {@code OptionalMod}, if a mod object is present, + * otherwise an empty {@code Optional} + * @throws NullPointerException if the mapping function is null + */ + public Optional map(Function mapper) { + Objects.requireNonNull(mapper); + if (!isPresent()) + return Optional.empty(); + else { + return Optional.ofNullable(mapper.apply(getValue())); + } + } + + /** + * If a value is present, apply the provided {@code Optional}-bearing + * mapping function to it, return that result, otherwise return an empty + * {@code Optional}. This method is similar to {@link #map(Function)}, + * but the provided mapper is one whose result is already an {@code Optional}, + * and if invoked, {@code flatMap} does not wrap it with an additional + * {@code Optional}. + * + * @param The type parameter to the {@code Optional} returned by + * @param mapper a mapping function to apply to the mod object, if present + * the mapping function + * @return the result of applying an {@code Optional}-bearing mapping + * function to the value of this {@code Optional}, if a value is present, + * otherwise an empty {@code Optional} + * @throws NullPointerException if the mapping function is null or returns + * a null result + */ + public Optional flatMap(Function> mapper) { + Objects.requireNonNull(mapper); + if (!isPresent()) + return Optional.empty(); + else { + return Objects.requireNonNull(mapper.apply(getValue())); + } + } + + /** + * Return the mod object if present, otherwise return {@code other}. + * + * @param other the mod object to be returned if there is no mod object present, may + * be null + * @return the mod object, if present, otherwise {@code other} + */ + public T orElse(T other) { + return getValue() != null ? getValue() : other; + } + + /** + * Return the mod object if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code Supplier} whose result is returned if no mod object + * is present + * @return the mod object if present otherwise the result of {@code other.get()} + * @throws NullPointerException if mod object is not present and {@code other} is + * null + */ + public T orElseGet(Supplier other) { + return getValue() != null ? getValue() : other.get(); + } + + /** + * Return the contained mod object, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present mod object + * @throws X if there is no mod object present + * @throws NullPointerException if no mod object is present and + * {@code exceptionSupplier} is null + */ + public T orElseThrow(Supplier exceptionSupplier) throws X { + if (getValue() != null) { + return getValue(); + } else { + throw exceptionSupplier.get(); + } + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (obj instanceof OptionalMod) { + return Objects.equals(((OptionalMod)obj).modId, modId); + } + return false; + } + + @Override + public int hashCode() + { + return Objects.hashCode(modId); + } +} diff --git a/src/main/java/net/minecraftforge/fml/RegistryObject.java b/src/main/java/net/minecraftforge/fml/RegistryObject.java new file mode 100644 index 000000000..5a9fab30d --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/RegistryObject.java @@ -0,0 +1,247 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml; + +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.registries.ForgeRegistry; +import net.minecraftforge.registries.IForgeRegistry; +import net.minecraftforge.registries.IForgeRegistryEntry; +import net.minecraftforge.registries.RegistryManager; + +import java.util.Objects; +import java.util.Optional; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public final class RegistryObject> +{ + private final String name; + private final IForgeRegistry owningRegistry; + private T value; + private boolean searched; + + public static , U extends T> RegistryObject of(final String name, Supplier> registryType) { + return new RegistryObject<>(name, registryType); + } + + private static RegistryObject EMPTY = new RegistryObject<>(); + + private static > RegistryObject empty() { + @SuppressWarnings("unchecked") + RegistryObject t = (RegistryObject) EMPTY; + return t; + } + + private RegistryObject() { + this.searched = true; + this.name = ""; + this.owningRegistry = null; + } + + private > RegistryObject(String name, Supplier> registryType) + { + this.name = name; + IForgeRegistry registry; + try { + registry = RegistryManager.ACTIVE.getRegistry(registryType.get()); + } catch (Throwable t) { + registry = null; + } + this.owningRegistry = registry; + } + + private T getValue() + { + if (!searched) { + if (this.owningRegistry != null) { + //noinspection unchecked + this.value = (T)this.owningRegistry.getValue(new ResourceLocation(this.name)); + } + searched = true; + } + return this.value; + } + + public String getName() { + return this.name; + } + + public Stream stream() { + return isPresent() ? Stream.of(getValue()) : Stream.of(); + } + /** + * Return {@code true} if there is a mod object present, otherwise {@code false}. + * + * @return {@code true} if there is a mod object present, otherwise {@code false} + */ + public boolean isPresent() { + return getValue() != null; + } + + /** + * If a mod object is present, invoke the specified consumer with the object, + * otherwise do nothing. + * + * @param consumer block to be executed if a mod object is present + * @throws NullPointerException if mod object is present and {@code consumer} is + * null + */ + public void ifPresent(Consumer consumer) { + if (getValue() != null) + consumer.accept(getValue()); + } + + /** + * If a mod object is present, and the mod object matches the given predicate, + * return an {@code RegistryObject} describing the value, otherwise return an + * empty {@code RegistryObject}. + * + * @param predicate a predicate to apply to the mod object, if present + * @return an {@code RegistryObject} describing the value of this {@code RegistryObject} + * if a mod object is present and the mod object matches the given predicate, + * otherwise an empty {@code RegistryObject} + * @throws NullPointerException if the predicate is null + */ + public RegistryObject filter(Predicate predicate) { + Objects.requireNonNull(predicate); + if (!isPresent()) + return this; + else + return predicate.test(getValue()) ? this : empty(); + } + + /** + * If a mod object is present, apply the provided mapping function to it, + * and if the result is non-null, return an {@code Optional} describing the + * result. Otherwise return an empty {@code Optional}. + * + * @apiNote This method supports post-processing on optional values, without + * the need to explicitly check for a return status. + * + * @param The type of the result of the mapping function + * @param mapper a mapping function to apply to the mod object, if present + * @return an {@code Optional} describing the result of applying a mapping + * function to the mod object of this {@code RegistryObject}, if a mod object is present, + * otherwise an empty {@code Optional} + * @throws NullPointerException if the mapping function is null + */ + public Optional map(Function mapper) { + Objects.requireNonNull(mapper); + if (!isPresent()) + return Optional.empty(); + else { + return Optional.ofNullable(mapper.apply(getValue())); + } + } + + /** + * If a value is present, apply the provided {@code Optional}-bearing + * mapping function to it, return that result, otherwise return an empty + * {@code Optional}. This method is similar to {@link #map(Function)}, + * but the provided mapper is one whose result is already an {@code Optional}, + * and if invoked, {@code flatMap} does not wrap it with an additional + * {@code Optional}. + * + * @param The type parameter to the {@code Optional} returned by + * @param mapper a mapping function to apply to the mod object, if present + * the mapping function + * @return the result of applying an {@code Optional}-bearing mapping + * function to the value of this {@code Optional}, if a value is present, + * otherwise an empty {@code Optional} + * @throws NullPointerException if the mapping function is null or returns + * a null result + */ + public Optional flatMap(Function> mapper) { + Objects.requireNonNull(mapper); + if (!isPresent()) + return Optional.empty(); + else { + return Objects.requireNonNull(mapper.apply(getValue())); + } + } + + /** + * Return the mod object if present, otherwise return {@code other}. + * + * @param other the mod object to be returned if there is no mod object present, may + * be null + * @return the mod object, if present, otherwise {@code other} + */ + public T orElse(T other) { + return getValue() != null ? getValue() : other; + } + + /** + * Return the mod object if present, otherwise invoke {@code other} and return + * the result of that invocation. + * + * @param other a {@code Supplier} whose result is returned if no mod object + * is present + * @return the mod object if present otherwise the result of {@code other.get()} + * @throws NullPointerException if mod object is not present and {@code other} is + * null + */ + public T orElseGet(Supplier other) { + return getValue() != null ? getValue() : other.get(); + } + + /** + * Return the contained mod object, if present, otherwise throw an exception + * to be created by the provided supplier. + * + * @apiNote A method reference to the exception constructor with an empty + * argument list can be used as the supplier. For example, + * {@code IllegalStateException::new} + * + * @param Type of the exception to be thrown + * @param exceptionSupplier The supplier which will return the exception to + * be thrown + * @return the present mod object + * @throws X if there is no mod object present + * @throws NullPointerException if no mod object is present and + * {@code exceptionSupplier} is null + */ + public T orElseThrow(Supplier exceptionSupplier) throws X { + if (getValue() != null) { + return getValue(); + } else { + throw exceptionSupplier.get(); + } + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) return true; + if (obj instanceof RegistryObject) { + return Objects.equals(((RegistryObject)obj).name, name); + } + return false; + } + + @Override + public int hashCode() + { + return Objects.hashCode(name); + } +} diff --git a/src/main/java/net/minecraftforge/fml/SidedProvider.java b/src/main/java/net/minecraftforge/fml/SidedProvider.java index ab78ba7e1..0952517d9 100644 --- a/src/main/java/net/minecraftforge/fml/SidedProvider.java +++ b/src/main/java/net/minecraftforge/fml/SidedProvider.java @@ -22,14 +22,23 @@ package net.minecraftforge.fml; import net.minecraft.client.Minecraft; import net.minecraft.server.dedicated.DedicatedServer; import net.minecraftforge.api.Side; +import net.minecraftforge.eventbus.api.Event; +import net.minecraftforge.fml.client.SplashProgress; +import net.minecraftforge.fml.common.event.FMLClientInitEvent; +import net.minecraftforge.fml.common.event.FMLServerInitEvent; import net.minecraftforge.fml.loading.FMLEnvironment; +import sun.plugin.security.StripClassFile; import java.util.function.Function; import java.util.function.Supplier; public enum SidedProvider { - DATAFIXER(c->c.get().getDataFixer(), s->s.get().getDataFixer()); + DATAFIXER(c->c.get().getDataFixer(), s->s.get().getDataFixer()), + SIDEDINIT((Function, Function>)c-> mc->new FMLClientInitEvent(c.get(), mc), + (Function, Function>)s-> mc->new FMLServerInitEvent(s.get(), mc)), + STRIPCHARS((Function, Function>)c-> SplashProgress::stripSpecialChars, + (Function, Function>)s-> str->str); private static Supplier client; private static Supplier server; diff --git a/src/main/java/net/minecraftforge/fml/client/BrandingControl.java b/src/main/java/net/minecraftforge/fml/client/BrandingControl.java index ed8f11c06..3efb7d580 100644 --- a/src/main/java/net/minecraftforge/fml/client/BrandingControl.java +++ b/src/main/java/net/minecraftforge/fml/client/BrandingControl.java @@ -22,10 +22,13 @@ package net.minecraftforge.fml.client; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.fml.ModList; import java.text.MessageFormat; import java.util.List; +import java.util.function.BiConsumer; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; public class BrandingControl @@ -41,7 +44,7 @@ public class BrandingControl brd.add("Minecraft " + ForgeVersion.mcVersion); brd.add("MCP " + ForgeVersion.mcpVersion); brd.add("Forge " + ForgeVersion.getVersion()); - int tModCount = 2; + int tModCount = ModList.get().size(); brd.add(MessageFormat.format("{0,choice,0#No mods|1#1 mod|1<{0} mods} loaded", tModCount)); brandings = brd.build(); @@ -59,6 +62,10 @@ public class BrandingControl } } + public static void forEachLine(boolean includeMC, boolean reverse, BiConsumer lineConsumer) { + final List brandings = getBrandings(includeMC, reverse); + IntStream.range(0, brandings.size()).boxed().forEachOrdered(idx -> lineConsumer.accept(idx, brandings.get(idx))); + } private static final List defaultClientBranding = Stream.of("fml", "forge").collect(Collectors.toList()); public static String getClientBranding() { return defaultClientBranding.stream().collect(Collectors.joining(",")); diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 7030dcf34..bb186a92d 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -25,16 +25,24 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.resources.IReloadableResourceManager; import net.minecraft.client.resources.IResourcePack; import net.minecraft.client.resources.data.MetadataSerializer; +import net.minecraftforge.api.Side; +import net.minecraftforge.api.SideOnly; import net.minecraftforge.fml.SidedProvider; import net.minecraftforge.fml.VersionChecker; import net.minecraftforge.fml.ModLoader; +import net.minecraftforge.fml.client.gui.GuiNotification; +import net.minecraftforge.fml.client.registry.RenderingRegistry; import org.lwjgl.input.Mouse; import java.io.IOException; import java.util.List; +@SideOnly(Side.CLIENT) public class ClientModLoader { + private static boolean loading; + private static Minecraft mc; + /** * Mod loading entrypoint for the client * @param minecraft @@ -44,6 +52,8 @@ public class ClientModLoader */ public static void begin(final Minecraft minecraft, final List defaultResourcePacks, final IReloadableResourceManager mcResourceManager, MetadataSerializer metadataSerializer_) { + loading = true; + ClientModLoader.mc = minecraft; SidedProvider.setClient(()->minecraft); SplashProgress.start(); ModLoader.get().loadMods(); @@ -52,6 +62,9 @@ public class ClientModLoader public static void end() { + ModLoader.get().finishMods(); + loading = false; + mc.gameSettings.loadOptions(); SplashProgress.finish(); } @@ -91,4 +104,9 @@ public class ClientModLoader { return false; } + + public static boolean isLoading() + { + return loading; + } } diff --git a/src/main/java/net/minecraftforge/fml/client/ConfigGuiHandler.java b/src/main/java/net/minecraftforge/fml/client/ConfigGuiHandler.java index f6fb16dca..b630f162e 100644 --- a/src/main/java/net/minecraftforge/fml/client/ConfigGuiHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/ConfigGuiHandler.java @@ -22,7 +22,7 @@ package net.minecraftforge.fml.client; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiScreen; import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.language.ExtensionPoint; +import net.minecraftforge.fml.ExtensionPoint; import net.minecraftforge.fml.loading.moddiscovery.ModInfo; import java.util.Optional; diff --git a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index 373574688..0cb8a7ec8 100644 --- a/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -89,7 +89,18 @@ import net.minecraftforge.client.resource.SelectiveReloadStateHandler; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.ConfigManager; import net.minecraftforge.common.util.CompoundDataFixer; +import net.minecraftforge.fml.client.gui.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.client.gui.GuiAccessDenied; +import net.minecraftforge.fml.client.gui.GuiConfirmation; +import net.minecraftforge.fml.client.gui.GuiCustomModLoadingErrorScreen; +import net.minecraftforge.fml.client.gui.GuiDupesFound; import net.minecraftforge.fml.client.gui.GuiModList; +import net.minecraftforge.fml.client.gui.GuiModsMissing; +import net.minecraftforge.fml.client.gui.GuiMultipleModsErrored; +import net.minecraftforge.fml.client.gui.GuiNotification; +import net.minecraftforge.fml.client.gui.GuiOldSaveLoadConfirm; +import net.minecraftforge.fml.client.gui.GuiSortingProblem; +import net.minecraftforge.fml.client.gui.GuiWrongMinecraft; import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.DuplicateModsFoundException; @@ -166,8 +177,6 @@ public class FMLClientHandler implements IFMLSidedHandler */ private Minecraft client; - private DummyModContainer optifineContainer; - private boolean loading = true; @Nullable diff --git a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/src/main/java/net/minecraftforge/fml/client/SplashProgress.java index f70a4e64e..0ec64ff74 100644 --- a/src/main/java/net/minecraftforge/fml/client/SplashProgress.java +++ b/src/main/java/net/minecraftforge/fml/client/SplashProgress.java @@ -49,6 +49,7 @@ import javax.imageio.ImageIO; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; +import com.google.common.base.CharMatcher; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.GlStateManager; @@ -744,6 +745,17 @@ public class SplashProgress private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024); + // From FontRenderer.renderCharAtPos + private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000"; + private static final CharMatcher DISALLOWED_CHAR_MATCHER = CharMatcher.anyOf(ALLOWED_CHARS).negate(); + + public static String stripSpecialChars(String message) + { + // We can't handle many unicode points in the splash renderer + return DISALLOWED_CHAR_MATCHER.removeFrom(net.minecraft.util.StringUtils.stripControlCodes(message)); + } + + @SuppressWarnings("unused") private static class Texture { diff --git a/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java b/src/main/java/net/minecraftforge/fml/client/gui/CustomModLoadingErrorDisplayException.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java rename to src/main/java/net/minecraftforge/fml/client/gui/CustomModLoadingErrorDisplayException.java index f0960b654..820d6f2d6 100644 --- a/src/main/java/net/minecraftforge/fml/client/CustomModLoadingErrorDisplayException.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/CustomModLoadingErrorDisplayException.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiErrorScreen; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiAccessDenied.java similarity index 95% rename from src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiAccessDenied.java index 55b82a7ec..a0a585ae9 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiAccessDenied.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiAccessDenied.java @@ -17,12 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.multiplayer.ServerData; import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.FMLClientHandler; public class GuiAccessDenied extends GuiScreen { diff --git a/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiBackupFailed.java similarity index 95% rename from src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiBackupFailed.java index 8dc43d281..9129b8853 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiBackupFailed.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiBackupFailed.java @@ -17,12 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import java.io.File; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.FMLClientHandler; public class GuiBackupFailed extends GuiScreen { diff --git a/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiConfirmation.java similarity index 94% rename from src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiConfirmation.java index 361639d3d..196685b49 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiConfirmation.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiConfirmation.java @@ -17,11 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiOptionButton; import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.StartupQuery; public class GuiConfirmation extends GuiNotification diff --git a/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiCustomModLoadingErrorScreen.java similarity index 97% rename from src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiCustomModLoadingErrorScreen.java index 6d3cf9bed..1cabab0f9 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiCustomModLoadingErrorScreen.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiCustomModLoadingErrorScreen.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; public class GuiCustomModLoadingErrorScreen extends GuiErrorBase { diff --git a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiDupesFound.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiDupesFound.java index 4a26f5108..9370b8456 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiDupesFound.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiDupesFound.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraftforge.fml.common.DuplicateModsFoundException; import net.minecraftforge.fml.ModContainer; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiErrorBase.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiErrorBase.java index c806ed7d2..3c1b9ede3 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiErrorBase.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiErrorBase.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiErrorScreen; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissing.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissing.java index 0e96cc82d..d8f7864e7 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissing.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import java.util.List; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissingForServer.java similarity index 96% rename from src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissingForServer.java index 152c2c869..63447e0d3 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModsMissingForServer.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiModsMissingForServer.java @@ -17,13 +17,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import java.util.List; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.MissingModsException; import net.minecraftforge.fml.common.versioning.ArtifactVersion; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiMultipleModsErrored.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiMultipleModsErrored.java index 333c901af..794924a7a 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiMultipleModsErrored.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiMultipleModsErrored.java @@ -17,14 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.resources.I18n; import net.minecraft.util.text.TextFormatting; -import net.minecraftforge.fml.client.gui.GuiScrollingList; import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.MissingModsException; import net.minecraftforge.fml.common.ModContainer; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiNotification.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiNotification.java similarity index 96% rename from src/main/java/net/minecraftforge/fml/client/GuiNotification.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiNotification.java index 753539a78..201ae7643 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiNotification.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiNotification.java @@ -17,11 +17,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.I18n; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.StartupQuery; public class GuiNotification extends GuiScreen diff --git a/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiOldSaveLoadConfirm.java similarity index 97% rename from src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiOldSaveLoadConfirm.java index 5f2850c40..ea45e7ee4 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiOldSaveLoadConfirm.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiOldSaveLoadConfirm.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import java.io.File; import java.io.IOException; @@ -26,6 +26,7 @@ import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiYesNo; import net.minecraft.client.gui.GuiYesNoCallback; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.StartupQuery; import net.minecraftforge.fml.common.ZipperUtil; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiSortingProblem.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiSortingProblem.java index b9cbf904b..4292ef735 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiSortingProblem.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiSortingProblem.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.gui.GuiScreen; import net.minecraftforge.fml.ModContainer; diff --git a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java b/src/main/java/net/minecraftforge/fml/client/gui/GuiWrongMinecraft.java similarity index 98% rename from src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java rename to src/main/java/net/minecraftforge/fml/client/gui/GuiWrongMinecraft.java index dacbf4200..4ebf849b0 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiWrongMinecraft.java +++ b/src/main/java/net/minecraftforge/fml/client/gui/GuiWrongMinecraft.java @@ -17,7 +17,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -package net.minecraftforge.fml.client; +package net.minecraftforge.fml.client.gui; import net.minecraft.client.resources.I18n; import net.minecraft.util.text.TextFormatting; diff --git a/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java b/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java index c6584ee22..34bdf5ada 100644 --- a/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java +++ b/src/main/java/net/minecraftforge/fml/client/registry/RenderingRegistry.java @@ -32,26 +32,6 @@ public class RenderingRegistry private static final RenderingRegistry INSTANCE = new RenderingRegistry(); private Map, IRenderFactory> entityRenderers = Maps.newHashMap(); - private Map, Render> entityRenderersOld = Maps.newHashMap(); - - /** - * Register an entity rendering handler. This will, after mod initialization, be inserted into the main - * render map for entities. - * Call this during Initialization phase. - * - * @deprecated use the factory version during Preinitialization. - * TODO Will be removed in 1.11. - */ - @Deprecated - public static void registerEntityRenderingHandler(Class entityClass, Render renderer) - { - INSTANCE.entityRenderersOld.put(entityClass, renderer); - } - - public static void loadEntityRenderers(Map, Render> entityRenderMap) - { - entityRenderMap.putAll(INSTANCE.entityRenderersOld); - } /** * Register an entity rendering handler. This will, after mod initialization, be inserted into the main @@ -63,16 +43,13 @@ public class RenderingRegistry INSTANCE.entityRenderers.put(entityClass, renderFactory); } - public static void loadEntityRenderers(RenderManager manager, Map , Render> renderMap) + public static void loadEntityRenderers(RenderManager manager, Map, Render> renderMap) { - for (Map.Entry, IRenderFactory> entry : INSTANCE.entityRenderers.entrySet()) - { - register(manager, renderMap, entry.getKey(), entry.getValue()); - } + INSTANCE.entityRenderers.forEach((key, value) -> register(manager, renderMap, key, value)); } @SuppressWarnings("unchecked") - private static void register(RenderManager manager, Map , Render> renderMap, Class entityClass, IRenderFactory renderFactory) + private static void register(RenderManager manager, Map, Render> renderMap, Class entityClass, IRenderFactory renderFactory) { renderMap.put(entityClass, ((IRenderFactory)renderFactory).createRenderFor(manager)); } diff --git a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java b/src/main/java/net/minecraftforge/fml/common/ProgressManager.java index c3b56a00c..2eee4f52a 100644 --- a/src/main/java/net/minecraftforge/fml/common/ProgressManager.java +++ b/src/main/java/net/minecraftforge/fml/common/ProgressManager.java @@ -19,18 +19,18 @@ package net.minecraftforge.fml.common; +import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Function; +import java.util.stream.Collectors; -import com.google.common.base.Joiner; import net.minecraftforge.api.Side; import net.minecraftforge.fml.SidedExecutor; +import net.minecraftforge.fml.SidedProvider; import net.minecraftforge.fml.client.SplashProgress; import org.apache.logging.log4j.message.MessageFormatMessage; -import org.apache.logging.log4j.message.StringFormattedMessage; -import org.lwjgl.LWJGLUtil; -import org.lwjgl.opengl.Display; import static net.minecraftforge.fml.Logging.SPLASH; import static net.minecraftforge.fml.Logging.fmlLog; @@ -121,7 +121,7 @@ public class ProgressManager public void step(Class classToName, String... extra) { - step(ClassNameUtils.shortName(classToName)+Joiner.on(' ').join(extra)); + step(ClassNameUtils.shortName(classToName)+ Arrays.stream(extra).collect(Collectors.joining(" "))); } public void step(String message) @@ -133,9 +133,8 @@ public class ProgressManager fmlLog.debug(SPLASH,new MessageFormatMessage("Bar Step: {0} - {1} took {2,number,0.000}ms", getTitle(), getMessage(), (newTime - lastTime) / 1.0e6)); lastTime = newTime; } - step++; - this.message = FMLCommonHandler.instance().stripSpecialChars(message); - FMLCommonHandler.instance().processWindowMessages(); + step += 1; + this.message = SidedProvider.STRIPCHARS.>get().apply(message); } public String getTitle() diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLClientInitEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLClientInitEvent.java new file mode 100644 index 000000000..4ec66f31d --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLClientInitEvent.java @@ -0,0 +1,31 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.common.event; + +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.ModContainer; + +public class FMLClientInitEvent extends ModLifecycleEvent +{ + public FMLClientInitEvent(Minecraft mc, ModContainer container) + { + super(container); + } +} diff --git a/src/main/java/net/minecraftforge/fml/common/event/FMLServerInitEvent.java b/src/main/java/net/minecraftforge/fml/common/event/FMLServerInitEvent.java new file mode 100644 index 000000000..1b94a3572 --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/event/FMLServerInitEvent.java @@ -0,0 +1,31 @@ +/* + * Minecraft Forge + * Copyright (c) 2018. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.common.event; + +import net.minecraft.server.MinecraftServer; +import net.minecraftforge.fml.ModContainer; + +public class FMLServerInitEvent extends ModLifecycleEvent +{ + public FMLServerInitEvent(MinecraftServer server, ModContainer container) + { + super(container); + } +} diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java index ca3703cfb..38b789b7d 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLJavaModLanguageProvider.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.javafmlmod; +import net.minecraftforge.fml.DeferredWorkQueue; +import net.minecraftforge.fml.LifecycleEventProvider; import net.minecraftforge.fml.language.IModLanguageProvider; import net.minecraftforge.fml.language.IModInfo; import net.minecraftforge.fml.language.ModFileScanData; @@ -29,6 +31,7 @@ import org.objectweb.asm.Type; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Map; +import java.util.concurrent.FutureTask; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.Collectors; @@ -59,6 +62,9 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider @Override public T loadMod(final IModInfo info, final ClassLoader modClassLoader, final ModFileScanData modFileScanResults) { + // This language class is loaded in the system level classloader - before the game even starts + // So we must treat container construction as an arms length operation, and load the container + // in the classloader of the game - the context classloader is appropriate here. try { final Constructor constructor = Class.forName("net.minecraftforge.fml.javafmlmod.FMLModContainer", true, Thread.currentThread().getContextClassLoader()). @@ -92,4 +98,14 @@ public class FMLJavaModLanguageProvider implements IModLanguageProvider scanResult.addLanguageLoader(modTargetMap); }; } + + @Override + public void preLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) + { + } + + @Override + public void postLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) + { + } } diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index 452771d44..28098c574 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -49,9 +49,12 @@ public class FMLModContainer extends ModContainer { super(info); this.scanResults = modFileScanResults; - triggerMap.put(ModLoadingStage.BEGIN, dummy().andThen(this::beforeEvent).andThen(this::constructMod).andThen(this::afterEvent)); - triggerMap.put(ModLoadingStage.CONSTRUCT, dummy().andThen(this::beforeEvent).andThen(this::preinitMod).andThen(this::fireEvent).andThen(this::afterEvent)); - triggerMap.put(ModLoadingStage.PREINIT, dummy().andThen(this::beforeEvent).andThen(this::initMod).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.CONSTRUCT, dummy().andThen(this::beforeEvent).andThen(this::constructMod).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.PREINIT, dummy().andThen(this::beforeEvent).andThen(this::preinitMod).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.SIDEDINIT, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.INIT, dummy().andThen(this::beforeEvent).andThen(this::initMod).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.POSTINIT, dummy().andThen(this::beforeEvent).andThen(this::fireEvent).andThen(this::afterEvent)); + triggerMap.put(ModLoadingStage.COMPLETE, dummy().andThen(this::beforeEvent).andThen(this::completeLoading).andThen(this::fireEvent).andThen(this::afterEvent)); this.eventBus = IEventBus.create(this::onEventFailed); try @@ -66,6 +69,11 @@ public class FMLModContainer extends ModContainer } } + private void completeLoading(LifecycleEventProvider.LifecycleEvent lifecycleEvent) + { + + } + private void initMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java b/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java index b5601fcee..fc7bd98db 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/ModLoadingContext.java @@ -20,8 +20,11 @@ package net.minecraftforge.fml.javafmlmod; import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.fml.language.ExtensionPoint; +import net.minecraftforge.fml.DeferredWorkQueue; +import net.minecraftforge.fml.ExtensionPoint; +import java.util.concurrent.Callable; +import java.util.concurrent.Future; import java.util.function.Supplier; public class ModLoadingContext diff --git a/src/main/java/net/minecraftforge/fml/language/IModLanguageProvider.java b/src/main/java/net/minecraftforge/fml/language/IModLanguageProvider.java index fea28b157..57af038ca 100644 --- a/src/main/java/net/minecraftforge/fml/language/IModLanguageProvider.java +++ b/src/main/java/net/minecraftforge/fml/language/IModLanguageProvider.java @@ -19,6 +19,8 @@ package net.minecraftforge.fml.language; +import net.minecraftforge.fml.LifecycleEventProvider; + import java.util.function.Consumer; /** @@ -33,6 +35,9 @@ public interface IModLanguageProvider Consumer getFileVisitor(); + void preLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent); + void postLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent); + interface IModLanguageLoader { T loadMod(IModInfo info, ClassLoader modClassLoader, ModFileScanData modFileScanResults); } diff --git a/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java b/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java index 652a1878f..e134f13be 100644 --- a/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java +++ b/src/main/java/net/minecraftforge/fml/loading/LanguageLoadingProvider.java @@ -32,6 +32,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ServiceLoader; +import java.util.function.Consumer; import java.util.stream.Stream; import static net.minecraftforge.fml.Logging.CORE; @@ -43,6 +44,11 @@ public class LanguageLoadingProvider private final ServiceLoader serviceLoader; private final Map languageProviderMap = new HashMap<>(); + public void forEach(final Consumer consumer) + { + languageProviders.forEach(consumer); + } + private static class ModLanguageWrapper { private final IModLanguageProvider modLanguageProvider; private final ArtifactVersion version; diff --git a/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java b/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java index 877d31fd0..2b156b773 100644 --- a/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java +++ b/src/main/java/net/minecraftforge/fml/loading/LoadingModList.java @@ -38,7 +38,8 @@ import java.util.function.Function; import java.util.stream.Collectors; /** - * Master list of all mods + * Master list of all mods in the loading context. This class cannot refer outside the + * loading package */ public class LoadingModList { @@ -47,8 +48,6 @@ public class LoadingModList private final List sortedList; private final Map fileById; private BackgroundScanHandler scanner; - private List mods; - private Map indexedMods; private LoadingModList(final List modFiles, final List sortedList) { @@ -106,30 +105,6 @@ public class LoadingModList return this.fileById.get(modid); } - public void dispatchLifeCycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) { - this.mods.parallelStream().forEach(m->m.transitionState(lifecycleEvent)); - final List erroredContainers = this.mods.stream().filter(m -> m.getCurrentState() == ModLoadingStage.ERROR).collect(Collectors.toList()); - if (!erroredContainers.isEmpty()) { - throw new RuntimeException("Errored containers found!"); - } - } - - public void setLoadedMods(final List modContainers) - { - this.mods = modContainers; - this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity())); - } - - public Optional getModObjectById(String modId) - { - return getModContainerById(modId).map(ModContainer::getMod); - } - - public Optional getModContainerById(String modId) - { - return Optional.ofNullable(this.indexedMods.get(modId)); - } - public List getMods() { return this.sortedList; diff --git a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java index 9b6353f4c..56829baca 100644 --- a/src/main/java/net/minecraftforge/registries/ForgeRegistry.java +++ b/src/main/java/net/minecraftforge/registries/ForgeRegistry.java @@ -51,12 +51,15 @@ import net.minecraft.nbt.NBTTagString; import net.minecraft.util.ResourceLocation; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.RegistryEvent.MissingMappings; -import net.minecraftforge.fml.common.FMLLog; -import net.minecraftforge.fml.common.InjectedModContainer; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.Marker; +import org.apache.logging.log4j.MarkerManager; public class ForgeRegistry> implements IForgeRegistryInternal, IForgeRegistryModifiable { - public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugRegistryEntries", "false")); + public static Marker REGISTRIES = MarkerManager.getMarker("REGISTRIES"); + private static Logger LOGGER = LogManager.getLogger("FML"); private final RegistryManager stage; private final BiMap ids = HashBiMap.create(); private final BiMap names = HashBiMap.create(); @@ -293,7 +296,7 @@ public class ForgeRegistry> implements IForgeRe V oldEntry = getRaw(key); if (oldEntry == value) // already registered, return prev registration's id { - FMLLog.bigWarning("Registry {}: The object {} has been registered twice for the same name {}.", this.superType.getSimpleName(), value, key); + LOGGER.warn(REGISTRIES,"Registry {}: The object {} has been registered twice for the same name {}.", this.superType.getSimpleName(), value, key); return this.getID(value); } if (oldEntry != null) // duplicate name @@ -302,8 +305,7 @@ public class ForgeRegistry> implements IForgeRe throw new IllegalArgumentException(String.format("The name %s has been registered twice, for %s and %s.", key, getRaw(key), value)); if (owner == null) throw new IllegalStateException(String.format("Could not determine owner for the override on %s. Value: %s", key, value)); - if (DEBUG) - FMLLog.log.debug("Registry {} Override: {} {} -> {}", this.superType.getSimpleName(), key, oldEntry, value); + LOGGER.debug(REGISTRIES,"Registry {} Override: {} {} -> {}", this.superType.getSimpleName(), key, oldEntry, value); idToUse = this.getID(oldEntry); } @@ -345,11 +347,10 @@ public class ForgeRegistry> implements IForgeRe if (this.add != null) this.add.onAdd(this, this.stage, idToUse, value, oldEntry); - if (this.dummies.remove(key) && DEBUG) - FMLLog.log.debug("Registry {} Dummy Remove: {}", this.superType.getSimpleName(), key); + if (this.dummies.remove(key)) + LOGGER.debug(REGISTRIES,"Registry {} Dummy Remove: {}", this.superType.getSimpleName(), key); - if (DEBUG) - FMLLog.log.trace("Registry {} add: {} {} {} (req. id {})", this.superType.getSimpleName(), key, idToUse, value, id); + LOGGER.trace(REGISTRIES,"Registry {} add: {} {} {} (req. id {})", this.superType.getSimpleName(), key, idToUse, value, id); return idToUse; } @@ -377,8 +378,7 @@ public class ForgeRegistry> implements IForgeRe if (this.isLocked()) throw new IllegalStateException(String.format("Attempted to register the alias %s -> %s to late", from, to)); this.aliases.put(from, to); - if (DEBUG) - FMLLog.log.trace("Registry {} alias: {} -> {}", this.superType.getSimpleName(), from, to); + LOGGER.trace(REGISTRIES,"Registry {} alias: {} -> {}", this.superType.getSimpleName(), from, to); } void addDummy(ResourceLocation key) @@ -386,8 +386,7 @@ public class ForgeRegistry> implements IForgeRe if (this.isLocked()) throw new IllegalStateException(String.format("Attempted to register the dummy %s to late", key)); this.dummies.add(key); - if (DEBUG) - FMLLog.log.trace("Registry {} dummy: {}", this.superType.getSimpleName(), key); + LOGGER.trace(REGISTRIES,"Registry {} dummy: {}", this.superType.getSimpleName(), key); } private RegistryDelegate getDelegate(V thing) @@ -471,8 +470,7 @@ public class ForgeRegistry> implements IForgeRe void sync(ResourceLocation name, ForgeRegistry from) { - if (DEBUG) - FMLLog.log.debug("Registry {} Sync: {} -> {}", this.superType.getSimpleName(), this.stage.getName(), from.stage.getName()); + LOGGER.debug(REGISTRIES,"Registry {} Sync: {} -> {}", this.superType.getSimpleName(), this.stage.getName(), from.stage.getName()); if (this == from) throw new IllegalArgumentException("WTF We are the same!?!?!"); if (from.superType != this.superType) @@ -509,7 +507,7 @@ public class ForgeRegistry> implements IForgeRe int realId = add(id, entry.getValue()); if (id != realId && id != -1) { - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), id, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), id, realId); errored = true; } } @@ -521,14 +519,14 @@ public class ForgeRegistry> implements IForgeRe OverrideOwner owner = from.owners.inverse().get(value); if (owner == null) { - FMLLog.log.warn("Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.superType.getSimpleName(), entry.getKey(), value); + LOGGER.warn(REGISTRIES,"Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.superType.getSimpleName(), entry.getKey(), value); errored = true; continue; } int realId = add(id, value, owner.owner); if (id != realId && id != -1) { - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), id, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), id, realId); errored = true; } } @@ -582,8 +580,7 @@ public class ForgeRegistry> implements IForgeRe if (id == null) throw new IllegalStateException("Removed a entry that did not have an associated id: " + key + " " + value.toString() + " This should never happen unless hackery!"); - if (DEBUG) - FMLLog.log.trace("Registry {} remove: {} {}", this.superType.getSimpleName(), key, id); + LOGGER.trace(REGISTRIES,"Registry {} remove: {} {}", this.superType.getSimpleName(), key, id); } return value; @@ -627,8 +624,8 @@ public class ForgeRegistry> implements IForgeRe Collections.sort(ids); - FMLLog.log.trace("Registry Name : {}", name); - ids.forEach(id -> FMLLog.log.trace(" Registry: {} {} {}", id, getKey(getValue(id)), getValue(id))); + LOGGER.trace(REGISTRIES, "Registry Name : {}", name); + ids.forEach(id -> LOGGER.trace(REGISTRIES," Registry: {} {} {}", id, getKey(getValue(id)), getValue(id))); } public void loadIds(Map ids, Map overrides, Map missing, Map remapped, ForgeRegistry old, ResourceLocation name) @@ -642,13 +639,13 @@ public class ForgeRegistry> implements IForgeRe if (currId == -1) { - FMLLog.log.info("Registry {}: Found a missing id from the world {}", this.superType.getSimpleName(), itemName); + LOGGER.info(REGISTRIES,"Registry {}: Found a missing id from the world {}", this.superType.getSimpleName(), itemName); missing.put(itemName, newId); continue; // no block/item -> nothing to add } else if (currId != newId) { - FMLLog.log.debug("Registry {}: Fixed {} id mismatch {}: {} (init) -> {} (map).", this.superType.getSimpleName(), name, itemName, currId, newId); + LOGGER.debug(REGISTRIES,"Registry {}: Fixed {} id mismatch {}: {} (init) -> {} (map).", this.superType.getSimpleName(), name, itemName, currId, newId); remapped.put(itemName, new Integer[] {currId, newId}); } @@ -674,7 +671,7 @@ public class ForgeRegistry> implements IForgeRe OverrideOwner owner = old.owners.inverse().get(value); if (owner == null) { - FMLLog.log.warn("Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.superType.getSimpleName(), entry.getKey(), value); + LOGGER.warn(REGISTRIES,"Registry {}: Override did not have an associated owner object. Name: {} Value: {}", this.superType.getSimpleName(), entry.getKey(), value); continue; } @@ -683,12 +680,12 @@ public class ForgeRegistry> implements IForgeRe int realId = add(newId, value, owner.owner); if (newId != realId) - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); } int realId = add(newId, obj, primaryName == null ? itemName.getResourceDomain() : primaryName); if (realId != newId) - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); ovs.remove(itemName); } @@ -702,16 +699,16 @@ public class ForgeRegistry> implements IForgeRe V _new = this.owners.get(new OverrideOwner(owner, itemName)); if (_new == null) { - FMLLog.log.warn("Registry {}: Skipping override for {}, Unknown owner {}", this.superType.getSimpleName(), itemName, owner); + LOGGER.warn(REGISTRIES,"Registry {}: Skipping override for {}, Unknown owner {}", this.superType.getSimpleName(), itemName, owner); continue; } - FMLLog.log.info("Registry {}: Activating override {} for {}", this.superType.getSimpleName(), owner, itemName); + LOGGER.info(REGISTRIES,"Registry {}: Activating override {} for {}", this.superType.getSimpleName(), owner, itemName); int newId = this.getID(itemName); int realId = this.add(newId, _new, owner); if (newId != realId) - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), entry.getKey(), newId, realId); } } } @@ -722,8 +719,7 @@ public class ForgeRegistry> implements IForgeRe return false; V dummy = this.dummyFactory.createDummy(key); - if (DEBUG) - FMLLog.log.debug("Registry Dummy Add: {} {} -> {}", key, id, dummy); + LOGGER.debug(REGISTRIES,"Registry Dummy Add: {} {} -> {}", key, id, dummy); //It was blocked before so we need to unset the blocking map this.availabilityMap.clear(id); @@ -740,15 +736,14 @@ public class ForgeRegistry> implements IForgeRe throw new IllegalStateException("Removed a entry that did not have an associated id: " + key + " " + value.toString() + " This should never happen unless hackery!"); if (oldid != id) - FMLLog.log.debug("Registry {}: Dummy ID mismatch {} {} -> {}", this.superType.getSimpleName(), key, oldid, id); + LOGGER.debug(REGISTRIES,"Registry {}: Dummy ID mismatch {} {} -> {}", this.superType.getSimpleName(), key, oldid, id); - if (DEBUG) - FMLLog.log.debug("Registry {} remove: {} {}", this.superType.getSimpleName(), key, oldid); + LOGGER.debug(REGISTRIES,"Registry {} remove: {} {}", this.superType.getSimpleName(), key, oldid); } int realId = this.add(id, dummy); if (realId != id) - FMLLog.log.warn("Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), key, id, realId); + LOGGER.warn(REGISTRIES,"Registry {}: Object did not get ID it asked for. Name: {} Expected: {} Got: {}", this.superType.getSimpleName(), key, id, realId); this.dummies.add(key); return true; @@ -773,8 +768,8 @@ public class ForgeRegistry> implements IForgeRe { V obj = this.names.get(key); OverrideOwner owner = this.owners.inverse().get(obj); - if (owner == null && DEBUG) - FMLLog.log.debug("Registry {} {}: Invalid override {} {}", this.superType.getSimpleName(), this.stage.getName(), key, obj); + if (owner == null) + LOGGER.debug(REGISTRIES,"Registry {} {}: Invalid override {} {}", this.superType.getSimpleName(), this.stage.getName(), key, obj); ret.put(key, owner.owner); } return ret; @@ -904,7 +899,7 @@ public class ForgeRegistry> implements IForgeRe void processMissingEvent(ResourceLocation name, ForgeRegistry pool, List> mappings, Map missing, Map remaps, Collection defaulted, Collection failed, boolean injectNetworkDummies) { - FMLLog.log.debug("Processing missing event for {}:", name); + LOGGER.debug(REGISTRIES,"Processing missing event for {}:", name); int ignored = 0; for (MissingMappings.Mapping remap : mappings) @@ -916,19 +911,19 @@ public class ForgeRegistry> implements IForgeRe // entry re-mapped, finish the registration with the new name/object, but the old id int currId = getID(remap.getTarget()); ResourceLocation newName = pool.getKey(remap.getTarget()); - FMLLog.log.debug(" Remapping {} -> {}.", remap.key, newName); + LOGGER.debug(REGISTRIES," Remapping {} -> {}.", remap.key, newName); missing.remove(remap.key); //I don't think this will work, but I dont think it ever worked.. the item is already in the map with a different id... we want to fix that.. int realId = this.add(remap.id, remap.getTarget()); if (realId != remap.id) - FMLLog.log.warn("Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", newName, this.getRegistrySuperType(), remap.id, realId); + LOGGER.warn(REGISTRIES,"Registered object did not get ID it asked for. Name: {} Type: {} Expected: {} Got: {}", newName, this.getRegistrySuperType(), remap.id, realId); this.addAlias(remap.key, newName); if (currId != realId) { - FMLLog.log.info(" Fixed id mismatch {}: {} (init) -> {} (map).", newName, currId, realId); + LOGGER.info(REGISTRIES,"Fixed id mismatch {}: {} (init) -> {} (map).", newName, currId, realId); remaps.put(newName, new Integer[] {currId, realId}); } } @@ -945,24 +940,24 @@ public class ForgeRegistry> implements IForgeRe } else if (action == MissingMappings.Action.IGNORE) { - FMLLog.log.debug(" Ignoring {}", remap.key); + LOGGER.debug(REGISTRIES,"Ignoring {}", remap.key); ignored++; } else if (action == MissingMappings.Action.FAIL) { - FMLLog.log.debug(" Failing {}!", remap.key); + LOGGER.debug(REGISTRIES,"Failing {}!", remap.key); failed.add(remap.key); } else if (action == MissingMappings.Action.WARN) { - FMLLog.log.warn(" {} may cause world breakage!", remap.key); + LOGGER.warn(REGISTRIES,"{} may cause world breakage!", remap.key); } this.block(remap.id); } } if (failed.isEmpty() && ignored > 0) - FMLLog.log.debug("There were {} missing mappings that have been ignored", ignored); + LOGGER.debug(REGISTRIES,"There were {} missing mappings that have been ignored", ignored); } private static class OverrideOwner diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 03d6b5fd7..f406f01ad 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -83,6 +83,8 @@ import javax.annotation.Nullable; import org.apache.commons.lang3.Validate; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import static net.minecraftforge.fml.Logging.fmlLog; @@ -116,6 +118,7 @@ public class GameData private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid"); + private static final Logger LOGGER = LogManager.getLogger("FML"); private static boolean hasInit = false; private static final boolean DISABLE_VANILLA_REGISTRIES = Boolean.parseBoolean(System.getProperty("forge.disableVanillaGameData", "false")); // Use for unit tests/debugging private static final BiConsumer> LOCK_VANILLA = (name, reg) -> reg.slaves.values().stream().filter(o -> o instanceof ILockableRegistry).forEach(o -> ((ILockableRegistry)o).lock()); @@ -563,8 +566,7 @@ public class GameData } else if (isLocalWorld) { - if (ForgeRegistry.DEBUG) - FMLLog.log.debug("Registry {}: Resuscitating dummy entry {}", key, dummy); + LOGGER.debug("Registry {}: Resuscitating dummy entry {}", key, dummy); } else { @@ -751,12 +753,10 @@ public class GameData if (filter.test(BLOCKS)) { MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(BLOCKS).getRegisterEvent(BLOCKS)); - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any blocks } if (filter.test(ITEMS)) { MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(ITEMS).getRegisterEvent(ITEMS)); - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any items } for (ResourceLocation rl : keys) { @@ -764,7 +764,6 @@ public class GameData if (rl == BLOCKS || rl == ITEMS) continue; MinecraftForge.EVENT_BUS.post(RegistryManager.ACTIVE.getRegistry(rl).getRegisterEvent(rl)); } - ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject everything else /* diff --git a/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java b/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java index 125f08a60..334b7cea8 100644 --- a/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java +++ b/src/test/java/net/minecraftforge/debug/mod/ClientLoadingExceptionTest.java @@ -25,7 +25,7 @@ import net.minecraft.item.Item; import net.minecraftforge.client.event.ModelBakeEvent; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; +import net.minecraftforge.fml.client.gui.CustomModLoadingErrorDisplayException; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent;