2018-06-11 01:12:46 +00:00
|
|
|
/*
|
|
|
|
* 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.javafmlmod;
|
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
import net.minecraftforge.eventbus.EventBusErrorMessage;
|
|
|
|
import net.minecraftforge.eventbus.api.Event;
|
|
|
|
import net.minecraftforge.eventbus.api.IEventBus;
|
|
|
|
import net.minecraftforge.eventbus.api.IEventListener;
|
2018-06-11 01:12:46 +00:00
|
|
|
import net.minecraftforge.fml.LifecycleEventProvider;
|
2018-06-15 19:03:35 +00:00
|
|
|
import net.minecraftforge.fml.common.event.ModLifecycleEvent;
|
|
|
|
import net.minecraftforge.fml.AutomaticEventSubscriber;
|
|
|
|
import net.minecraftforge.fml.ModLoadingStage;
|
|
|
|
import net.minecraftforge.fml.ModContainer;
|
2018-06-11 01:36:50 +00:00
|
|
|
import net.minecraftforge.fml.language.IModInfo;
|
|
|
|
import net.minecraftforge.fml.language.ModFileScanData;
|
2018-06-11 01:12:46 +00:00
|
|
|
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
import java.util.function.Consumer;
|
2018-06-11 01:12:46 +00:00
|
|
|
|
|
|
|
import static net.minecraftforge.fml.Logging.LOADING;
|
|
|
|
|
|
|
|
public class FMLModContainer extends ModContainer
|
|
|
|
{
|
|
|
|
private static final Logger LOGGER = LogManager.getLogger("FML");
|
2018-06-11 01:36:50 +00:00
|
|
|
private final ModFileScanData scanResults;
|
2018-06-15 19:03:35 +00:00
|
|
|
private final IEventBus eventBus;
|
2018-06-11 01:12:46 +00:00
|
|
|
private Object modInstance;
|
|
|
|
private final Class<?> modClass;
|
|
|
|
|
2018-06-11 01:36:50 +00:00
|
|
|
public FMLModContainer(IModInfo info, String className, ClassLoader modClassLoader, ModFileScanData modFileScanResults)
|
2018-06-11 01:12:46 +00:00
|
|
|
{
|
|
|
|
super(info);
|
2018-06-11 01:36:50 +00:00
|
|
|
this.scanResults = modFileScanResults;
|
2018-06-19 18:04:05 +00:00
|
|
|
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));
|
2018-06-15 19:03:35 +00:00
|
|
|
this.eventBus = IEventBus.create(this::onEventFailed);
|
2018-06-11 01:12:46 +00:00
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
modClass = Class.forName(className, true, modClassLoader);
|
|
|
|
LOGGER.error(LOADING,"Loaded modclass {} with {}", modClass.getName(), modClass.getClassLoader());
|
|
|
|
}
|
2018-06-15 19:03:35 +00:00
|
|
|
catch (Throwable e)
|
2018-06-11 01:12:46 +00:00
|
|
|
{
|
|
|
|
LOGGER.error(LOADING, "Failed to load class {}", className, e);
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-19 18:04:05 +00:00
|
|
|
private void completeLoading(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
private void initMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
2018-06-11 01:12:46 +00:00
|
|
|
{
|
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private Consumer<LifecycleEventProvider.LifecycleEvent> dummy() { return (s) -> {}; }
|
|
|
|
|
|
|
|
private void onEventFailed(IEventBus iEventBus, Event event, IEventListener[] iEventListeners, int i, Throwable throwable)
|
|
|
|
{
|
|
|
|
LOGGER.error(new EventBusErrorMessage(event, i, iEventListeners, throwable));
|
|
|
|
}
|
2018-06-11 01:12:46 +00:00
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
private void beforeEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
|
|
|
ModLoadingContext.get().activeContainer = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void fireEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
|
|
|
final ModLifecycleEvent event = lifecycleEvent.buildModEvent(this);
|
|
|
|
LOGGER.debug(LOADING, "Firing event {} for modid {}", event, this.getModId());
|
|
|
|
try
|
|
|
|
{
|
|
|
|
eventBus.post(event);
|
|
|
|
LOGGER.debug(LOADING, "Fired event {} for modid {}", event, this.getModId());
|
|
|
|
}
|
|
|
|
catch (Throwable e)
|
|
|
|
{
|
|
|
|
LOGGER.error(LOADING,"Caught exception during event {} dispatch for modid {}", event, this.getModId(), e);
|
|
|
|
modLoadingStage = ModLoadingStage.ERROR;
|
|
|
|
modLoadingError.add(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void afterEvent(LifecycleEventProvider.LifecycleEvent lifecycleEvent) {
|
|
|
|
ModLoadingContext.get().activeContainer = null;
|
|
|
|
if (getCurrentState() == ModLoadingStage.ERROR) {
|
|
|
|
LOGGER.error(LOADING,"An error occurred while dispatching event {} to {}", lifecycleEvent.fromStage(), getModId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void preinitMod(LifecycleEventProvider.LifecycleEvent lifecycleEvent)
|
|
|
|
{
|
|
|
|
AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader());
|
2018-06-11 01:12:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void constructMod(LifecycleEventProvider.LifecycleEvent event)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
LOGGER.debug(LOADING, "Loading mod instance {} of type {}", getModId(), modClass.getName());
|
|
|
|
this.modInstance = modClass.newInstance();
|
|
|
|
LOGGER.debug(LOADING, "Loaded mod instance {} of type {}", getModId(), modClass.getName());
|
|
|
|
}
|
2018-06-15 19:03:35 +00:00
|
|
|
catch (Throwable e)
|
2018-06-11 01:12:46 +00:00
|
|
|
{
|
2018-06-15 19:03:35 +00:00
|
|
|
LOGGER.error(LOADING,"Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.getName(), e);
|
|
|
|
modLoadingStage = ModLoadingStage.ERROR;
|
|
|
|
modLoadingError.add(e);
|
2018-06-11 01:12:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean matches(Object mod)
|
|
|
|
{
|
|
|
|
return mod == modInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Object getMod()
|
|
|
|
{
|
|
|
|
return modInstance;
|
|
|
|
}
|
|
|
|
|
2018-06-15 19:03:35 +00:00
|
|
|
public IEventBus getEventBus()
|
2018-06-11 13:56:44 +00:00
|
|
|
{
|
2018-06-15 19:03:35 +00:00
|
|
|
return this.eventBus;
|
2018-06-11 13:56:44 +00:00
|
|
|
}
|
2018-06-11 01:12:46 +00:00
|
|
|
}
|