/* * Minecraft Forge * Copyright (c) 2016-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; import com.google.common.base.Strings; import com.google.common.collect.SetMultimap; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.common.discovery.ASMDataTable; import net.minecraftforge.fml.common.discovery.ASMDataTable.ASMData; import net.minecraftforge.fml.loading.moddiscovery.ModAnnotation; import net.minecraftforge.fml.relauncher.Side; import java.util.EnumSet; import java.util.List; import java.util.Set; /** * Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber} * annotations and passes the class instances to the {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS} */ public class AutomaticEventSubscriber { private static final EnumSet DEFAULT = EnumSet.allOf(Side.class); public static void inject(ModContainer mod, ASMDataTable data, Side side) { FMLLog.log.debug("Attempting to inject @EventBusSubscriber classes into the eventbus for {}", mod.getModId()); SetMultimap modData = data.getAnnotationsFor(mod); Set mods = modData.get(Mod.class.getName()); Set targets = modData.get(Mod.EventBusSubscriber.class.getName()); ClassLoader mcl = Loader.instance().getModClassLoader(); for (ASMDataTable.ASMData targ : targets) { try { //noinspection unchecked @SuppressWarnings("unchecked") List sidesEnum = (List)targ.getAnnotationInfo().get("value"); EnumSet sides = DEFAULT; if (sidesEnum != null) { sides = EnumSet.noneOf(Side.class); for (ModAnnotation.EnumHolder h: sidesEnum) { sides.add(Side.valueOf(h.getValue())); } } if (sides == DEFAULT || sides.contains(side)) { //FMLLog.log.debug("Found @EventBusSubscriber class {}", targ.getClassName()); String amodid = (String)targ.getAnnotationInfo().get("modid"); if (Strings.isNullOrEmpty(amodid)) { amodid = ASMDataTable.getOwnerModID(mods, targ); if (Strings.isNullOrEmpty(amodid)) { FMLLog.bigWarning("Could not determine owning mod for @EventBusSubscriber on {} for mod {}", targ.getClassName(), mod.getModId()); continue; } } if (!mod.getModId().equals(amodid)) { FMLLog.log.debug("Skipping @EventBusSubscriber injection for {} since it is not for mod {}", targ.getClassName(), mod.getModId()); continue; //We're not injecting this guy } FMLLog.log.debug("Registering @EventBusSubscriber for {} for mod {}", targ.getClassName(), mod.getModId()); Class subscriptionTarget = Class.forName(targ.getClassName(), false, mcl); MinecraftForge.EVENT_BUS.register(subscriptionTarget); FMLLog.log.debug("Injected @EventBusSubscriber class {}", targ.getClassName()); } } catch (Throwable e) { FMLLog.log.error("An error occurred trying to load an EventBusSubscriber {} for modid {}", targ.getClassName(), mod.getModId(), e); throw new LoaderException(e); } } } }