Some more stuffs. ObjectHolder's replacement?
This commit is contained in:
parent
baa9dfe55a
commit
06b16aaa19
47 changed files with 987 additions and 269 deletions
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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 <T> void register(Class<T> type, Capability.IStorage<T> storage, final Class<? extends T> 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 <T> void register(Class<T> type, Capability.IStorage<T> storage, Callable<? extends T> 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<T> cap = new Capability<T>(realName, storage, factory);
|
||||
Capability<T> cap = new Capability<>(realName, storage, factory);
|
||||
providers.put(realName, cap);
|
||||
|
||||
List<Function<Capability<?>, Object>> list = callbacks.get(realName);
|
||||
if (list != null)
|
||||
{
|
||||
for (Function<Capability<?>, Object> func : list)
|
||||
{
|
||||
func.apply(cap);
|
||||
}
|
||||
}
|
||||
callbacks.getOrDefault(realName, Collections.emptyList()).forEach(func -> func.apply(cap));
|
||||
}
|
||||
|
||||
// INTERNAL
|
||||
private IdentityHashMap<String, Capability<?>> providers = Maps.newIdentityHashMap();
|
||||
private IdentityHashMap<String, List<Function<Capability<?>, Object>>> callbacks = Maps.newIdentityHashMap();
|
||||
public void injectCapabilities(ASMDataTable data)
|
||||
private IdentityHashMap<String, Capability<?>> providers = new IdentityHashMap<>();
|
||||
private IdentityHashMap<String, List<Function<Capability<?>, Object>>> callbacks = new IdentityHashMap<>();
|
||||
public void injectCapabilities(List<ModFileScanData> data)
|
||||
{
|
||||
for (ASMDataTable.ASMData entry : data.getAll(CapabilityInject.class.getName()))
|
||||
final List<ModFileScanData.AnnotationData> 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<Function<Capability<?>, Object>> list = callbacks.computeIfAbsent(capabilityName, k -> Lists.newArrayList());
|
||||
List<Function<Capability<?>, Object>> list = callbacks.computeIfAbsent(capabilityName, k -> new ArrayList<>());
|
||||
|
||||
if (entry.getObjectName().indexOf('(') > 0)
|
||||
{
|
||||
list.add(new Function<Capability<?>, 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<Capability<?>, 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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ModAnnotation.EnumHolder> sidesValue = (List<ModAnnotation.EnumHolder>)ad.getAnnotationData().get("value");
|
||||
@SuppressWarnings("unchecked")
|
||||
final List<ModAnnotation.EnumHolder> sidesValue = (List<ModAnnotation.EnumHolder>)ad.getAnnotationData().
|
||||
getOrDefault("value", Arrays.asList(new ModAnnotation.EnumHolder(null, "CLIENT"), new ModAnnotation.EnumHolder(null, "SERVER")));
|
||||
final EnumSet<Side> 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());
|
||||
|
|
44
src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
Normal file
44
src/main/java/net/minecraftforge/fml/DeferredWorkQueue.java
Normal file
|
@ -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<FutureWorkTask<?>> deferredWorkQueue = new ConcurrentLinkedDeque<>();
|
||||
|
||||
public static <T> Future<T> enqueueWork(Callable<T> workToEnqueue) {
|
||||
final FutureWorkTask<T> workTask = new FutureWorkTask<>(workToEnqueue);
|
||||
DeferredWorkQueue.deferredWorkQueue.add(workTask);
|
||||
return workTask;
|
||||
}
|
||||
|
||||
public static class FutureWorkTask<T> extends FutureTask<T>
|
||||
{
|
||||
FutureWorkTask(Callable<T> callable)
|
||||
{
|
||||
super(callable);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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());
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ModFileInfo> modFiles;
|
||||
private final List<ModInfo> sortedList;
|
||||
private final Map<String, ModFileInfo> fileById;
|
||||
private BackgroundScanHandler scanner;
|
||||
private List<ModContainer> mods;
|
||||
private Map<String, ModContainer> indexedMods;
|
||||
private ForkJoinPool modLoadingThreadPool = new ForkJoinPool();
|
||||
private List<ModFileScanData> modFileScanData;
|
||||
|
||||
private ModList(final List<ModFile> modFiles, final List<ModInfo> 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<ModContainer> 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<Object> getModObjectById(String modId)
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Optional<T> getModObjectById(String modId)
|
||||
{
|
||||
return getModContainerById(modId).map(ModContainer::getMod);
|
||||
return getModContainerById(modId).map(ModContainer::getMod).map(o -> (T) o);
|
||||
}
|
||||
|
||||
public Optional<? extends ModContainer> getModContainerById(String modId)
|
||||
|
@ -111,4 +137,24 @@ public class ModList
|
|||
{
|
||||
return this.indexedMods.containsKey(modTarget);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return mods.size();
|
||||
}
|
||||
|
||||
public List<ModFileScanData> 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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Boolean> 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<ModContainer> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ErrorEvent> errorEvents = new ArrayList<>();
|
||||
public static class ErrorEvent {
|
||||
|
||||
}
|
||||
}
|
|
@ -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<Function<ModContainer, ModLifecycleEvent>> modLifecycleEventFunction;
|
||||
|
||||
|
|
241
src/main/java/net/minecraftforge/fml/OptionalMod.java
Normal file
241
src/main/java/net/minecraftforge/fml/OptionalMod.java
Normal file
|
@ -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<T>
|
||||
{
|
||||
private final String modId;
|
||||
private T value;
|
||||
private boolean searched;
|
||||
|
||||
public static <M> OptionalMod<M> of(final String modId) {
|
||||
return new OptionalMod<>(modId);
|
||||
}
|
||||
|
||||
private static OptionalMod<?> EMPTY = new OptionalMod<>(true);
|
||||
private static <T> OptionalMod<T> empty() {
|
||||
@SuppressWarnings("unchecked")
|
||||
OptionalMod<T> t = (OptionalMod<T>) 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().<T>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<? super T> 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<T> filter(Predicate<? super T> 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 <U> 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<U> Optional<U> map(Function<? super T, ? extends U> 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 <U> 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<U> Optional<U> flatMap(Function<? super T, Optional<U>> 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<? extends T> 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 <X> 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 <X extends Throwable> T orElseThrow(Supplier<? extends X> 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);
|
||||
}
|
||||
}
|
247
src/main/java/net/minecraftforge/fml/RegistryObject.java
Normal file
247
src/main/java/net/minecraftforge/fml/RegistryObject.java
Normal file
|
@ -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<T extends IForgeRegistryEntry<? super T>>
|
||||
{
|
||||
private final String name;
|
||||
private final IForgeRegistry<?> owningRegistry;
|
||||
private T value;
|
||||
private boolean searched;
|
||||
|
||||
public static <T extends IForgeRegistryEntry<T>, U extends T> RegistryObject<U> of(final String name, Supplier<Class<T>> registryType) {
|
||||
return new RegistryObject<>(name, registryType);
|
||||
}
|
||||
|
||||
private static RegistryObject<?> EMPTY = new RegistryObject<>();
|
||||
|
||||
private static <T extends IForgeRegistryEntry<? super T>> RegistryObject<T> empty() {
|
||||
@SuppressWarnings("unchecked")
|
||||
RegistryObject<T> t = (RegistryObject<T>) EMPTY;
|
||||
return t;
|
||||
}
|
||||
|
||||
private RegistryObject() {
|
||||
this.searched = true;
|
||||
this.name = "";
|
||||
this.owningRegistry = null;
|
||||
}
|
||||
|
||||
private <V extends IForgeRegistryEntry<V>> RegistryObject(String name, Supplier<Class<V>> registryType)
|
||||
{
|
||||
this.name = name;
|
||||
IForgeRegistry<V> 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<T> 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<? super T> 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<T> filter(Predicate<? super T> 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 <U> 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<U> Optional<U> map(Function<? super T, ? extends U> 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 <U> 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<U> Optional<U> flatMap(Function<? super T, Optional<U>> 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<? extends T> 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 <X> 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 <X extends Throwable> T orElseThrow(Supplier<? extends X> 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);
|
||||
}
|
||||
}
|
|
@ -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<Supplier<Minecraft>, Function<ModContainer, Event>>)c-> mc->new FMLClientInitEvent(c.get(), mc),
|
||||
(Function<Supplier<DedicatedServer>, Function<ModContainer, Event>>)s-> mc->new FMLServerInitEvent(s.get(), mc)),
|
||||
STRIPCHARS((Function<Supplier<Minecraft>, Function<String, String>>)c-> SplashProgress::stripSpecialChars,
|
||||
(Function<Supplier<DedicatedServer>, Function<String, String>>)s-> str->str);
|
||||
|
||||
private static Supplier<Minecraft> client;
|
||||
private static Supplier<DedicatedServer> server;
|
||||
|
|
|
@ -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<Integer, String> lineConsumer) {
|
||||
final List<String> brandings = getBrandings(includeMC, reverse);
|
||||
IntStream.range(0, brandings.size()).boxed().forEachOrdered(idx -> lineConsumer.accept(idx, brandings.get(idx)));
|
||||
}
|
||||
private static final List<String> defaultClientBranding = Stream.of("fml", "forge").collect(Collectors.toList());
|
||||
public static String getClientBranding() {
|
||||
return defaultClientBranding.stream().collect(Collectors.joining(","));
|
||||
|
|
|
@ -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<IResourcePack> 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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;
|
|
@ -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
|
||||
{
|
|
@ -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
|
||||
{
|
|
@ -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
|
|
@ -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
|
||||
{
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -32,26 +32,6 @@ public class RenderingRegistry
|
|||
private static final RenderingRegistry INSTANCE = new RenderingRegistry();
|
||||
|
||||
private Map<Class<? extends Entity>, IRenderFactory<? extends Entity>> entityRenderers = Maps.newHashMap();
|
||||
private Map<Class<? extends Entity>, Render<? extends Entity>> 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<? extends Entity> entityClass, Render<? extends Entity> renderer)
|
||||
{
|
||||
INSTANCE.entityRenderersOld.put(entityClass, renderer);
|
||||
}
|
||||
|
||||
public static void loadEntityRenderers(Map<Class<? extends Entity>, Render<? extends Entity>> 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<Class<? extends Entity> , Render<? extends Entity>> renderMap)
|
||||
public static void loadEntityRenderers(RenderManager manager, Map<Class<? extends Entity>, Render<? extends Entity>> renderMap)
|
||||
{
|
||||
for (Map.Entry<Class<? extends Entity>, IRenderFactory<? extends Entity>> 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 <T extends Entity> void register(RenderManager manager, Map<Class<? extends Entity> , Render<? extends Entity>> renderMap, Class<T> entityClass, IRenderFactory<?> renderFactory)
|
||||
private static <T extends Entity> void register(RenderManager manager, Map<Class<? extends Entity>, Render<? extends Entity>> renderMap, Class<T> entityClass, IRenderFactory<?> renderFactory)
|
||||
{
|
||||
renderMap.put(entityClass, ((IRenderFactory<T>)renderFactory).createRenderFor(manager));
|
||||
}
|
||||
|
|
|
@ -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.<Function<String, String>>get().apply(message);
|
||||
}
|
||||
|
||||
public String getTitle()
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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> 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<ModFileScanData> getFileVisitor();
|
||||
|
||||
void preLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent);
|
||||
void postLifecycleEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent);
|
||||
|
||||
interface IModLanguageLoader {
|
||||
<T> T loadMod(IModInfo info, ClassLoader modClassLoader, ModFileScanData modFileScanResults);
|
||||
}
|
||||
|
|
|
@ -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<IModLanguageProvider> serviceLoader;
|
||||
private final Map<String, ModLanguageWrapper> languageProviderMap = new HashMap<>();
|
||||
|
||||
public void forEach(final Consumer<IModLanguageProvider> consumer)
|
||||
{
|
||||
languageProviders.forEach(consumer);
|
||||
}
|
||||
|
||||
private static class ModLanguageWrapper {
|
||||
private final IModLanguageProvider modLanguageProvider;
|
||||
private final ArtifactVersion version;
|
||||
|
|
|
@ -38,7 +38,8 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Master list of all mods
|
||||
* Master list of all mods <em>in the loading context. This class cannot refer outside the
|
||||
* loading package</em>
|
||||
*/
|
||||
public class LoadingModList
|
||||
{
|
||||
|
@ -47,8 +48,6 @@ public class LoadingModList
|
|||
private final List<ModInfo> sortedList;
|
||||
private final Map<String, ModFileInfo> fileById;
|
||||
private BackgroundScanHandler scanner;
|
||||
private List<ModContainer> mods;
|
||||
private Map<String, ModContainer> indexedMods;
|
||||
|
||||
private LoadingModList(final List<ModFile> modFiles, final List<ModInfo> 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<ModContainer> 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<ModContainer> modContainers)
|
||||
{
|
||||
this.mods = modContainers;
|
||||
this.indexedMods = modContainers.stream().collect(Collectors.toMap(ModContainer::getModId, Function.identity()));
|
||||
}
|
||||
|
||||
public Optional<Object> getModObjectById(String modId)
|
||||
{
|
||||
return getModContainerById(modId).map(ModContainer::getMod);
|
||||
}
|
||||
|
||||
public Optional<? extends ModContainer> getModContainerById(String modId)
|
||||
{
|
||||
return Optional.ofNullable(this.indexedMods.get(modId));
|
||||
}
|
||||
|
||||
public List<ModInfo> getMods()
|
||||
{
|
||||
return this.sortedList;
|
||||
|
|
|
@ -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<V extends IForgeRegistryEntry<V>> implements IForgeRegistryInternal<V>, IForgeRegistryModifiable<V>
|
||||
{
|
||||
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<Integer, V> ids = HashBiMap.create();
|
||||
private final BiMap<ResourceLocation, V> names = HashBiMap.create();
|
||||
|
@ -293,7 +296,7 @@ public class ForgeRegistry<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V> getDelegate(V thing)
|
||||
|
@ -471,8 +470,7 @@ public class ForgeRegistry<V extends IForgeRegistryEntry<V>> implements IForgeRe
|
|||
|
||||
void sync(ResourceLocation name, ForgeRegistry<V> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<ResourceLocation, Integer> ids, Map<ResourceLocation, String> overrides, Map<ResourceLocation, Integer> missing, Map<ResourceLocation, Integer[]> remapped, ForgeRegistry<V> old, ResourceLocation name)
|
||||
|
@ -642,13 +639,13 @@ public class ForgeRegistry<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> implements IForgeRe
|
|||
|
||||
void processMissingEvent(ResourceLocation name, ForgeRegistry<V> pool, List<MissingMappings.Mapping<V>> mappings, Map<ResourceLocation, Integer> missing, Map<ResourceLocation, Integer[]> remaps, Collection<ResourceLocation> defaulted, Collection<ResourceLocation> 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<V> remap : mappings)
|
||||
|
@ -916,19 +911,19 @@ public class ForgeRegistry<V extends IForgeRegistryEntry<V>> 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<V extends IForgeRegistryEntry<V>> 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
|
||||
|
|
|
@ -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<ResourceLocation, ForgeRegistry<?>> 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
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue