001 package cpw.mods.fml.common.event; 002 003 import java.util.List; 004 005 import net.minecraft.item.ItemStack; 006 import net.minecraft.nbt.NBTTagCompound; 007 008 import com.google.common.base.Function; 009 import com.google.common.base.Functions; 010 import com.google.common.base.Predicate; 011 import com.google.common.base.Predicates; 012 import com.google.common.collect.ArrayListMultimap; 013 import com.google.common.collect.FluentIterable; 014 import com.google.common.collect.ImmutableList; 015 import com.google.common.collect.ImmutableListMultimap; 016 import com.google.common.collect.Maps; 017 import com.google.common.collect.Multimaps; 018 019 import cpw.mods.fml.common.FMLCommonHandler; 020 import cpw.mods.fml.common.Loader; 021 import cpw.mods.fml.common.LoaderState; 022 import cpw.mods.fml.common.ModContainer; 023 import cpw.mods.fml.common.Mod.Init; 024 import cpw.mods.fml.common.Mod.PostInit; 025 026 /** 027 * Simple intermod communications to receive simple messages directed at you 028 * from other mods 029 * 030 * @author cpw 031 * 032 */ 033 public class FMLInterModComms { 034 private static final ImmutableList<IMCMessage> emptyIMCList = ImmutableList.<IMCMessage>of(); 035 private static ArrayListMultimap<String, IMCMessage> modMessages = ArrayListMultimap.create(); 036 037 /** 038 * Subscribe to this event to receive your messages (they are sent between 039 * {@link Init} and {@link PostInit}) 040 * 041 * @author cpw 042 * 043 */ 044 public static class IMCEvent extends FMLEvent { 045 @Override 046 public void applyModContainer(ModContainer activeContainer) 047 { 048 currentList = ImmutableList.copyOf(modMessages.removeAll(activeContainer.getModId())); 049 } 050 051 private ImmutableList<IMCMessage> currentList; 052 053 public ImmutableList<IMCMessage> getMessages() 054 { 055 return currentList; 056 } 057 } 058 059 /** 060 * You will receive an instance of this for each message sent 061 * 062 * @author cpw 063 * 064 */ 065 public static final class IMCMessage { 066 /** 067 * This is the modid of the mod that sent you the message 068 */ 069 private String sender; 070 /** 071 * This field, and {@link #value} are both at the mod's discretion 072 */ 073 public final String key; 074 /** 075 * This field, and {@link #key} are both at the mod's discretion 076 */ 077 private Object value; 078 079 private IMCMessage(String key, Object value) 080 { 081 this.key = key; 082 this.value = value; 083 } 084 085 @Override 086 public String toString() 087 { 088 return sender; 089 } 090 091 public String getSender() 092 { 093 return this.sender; 094 } 095 096 void setSender(ModContainer activeModContainer) 097 { 098 this.sender = activeModContainer.getModId(); 099 } 100 101 public String getStringValue() 102 { 103 return (String) value; 104 } 105 106 public NBTTagCompound getNBTValue() 107 { 108 return (NBTTagCompound) value; 109 } 110 111 public ItemStack getItemStackValue() 112 { 113 return (ItemStack) value; 114 } 115 } 116 117 public static boolean sendMessage(String modId, String key, NBTTagCompound value) 118 { 119 return enqueueStartupMessage(modId, new IMCMessage(key, value)); 120 } 121 public static boolean sendMessage(String modId, String key, ItemStack value) 122 { 123 return enqueueStartupMessage(modId, new IMCMessage(key, value)); 124 } 125 public static boolean sendMessage(String modId, String key, String value) 126 { 127 return enqueueStartupMessage(modId, new IMCMessage(key, value)); 128 } 129 130 public static void sendRuntimeMessage(Object sourceMod, String modId, String key, NBTTagCompound value) 131 { 132 enqueueMessage(sourceMod, modId, new IMCMessage(key, value)); 133 } 134 135 public static void sendRuntimeMessage(Object sourceMod, String modId, String key, ItemStack value) 136 { 137 enqueueMessage(sourceMod, modId, new IMCMessage(key, value)); 138 } 139 140 public static void sendRuntimeMessage(Object sourceMod, String modId, String key, String value) 141 { 142 enqueueMessage(sourceMod, modId, new IMCMessage(key, value)); 143 } 144 145 private static boolean enqueueStartupMessage(String modTarget, IMCMessage message) 146 { 147 if (Loader.instance().activeModContainer() == null) 148 { 149 return false; 150 } 151 enqueueMessage(Loader.instance().activeModContainer(), modTarget, message); 152 return Loader.isModLoaded(modTarget) && !Loader.instance().hasReachedState(LoaderState.POSTINITIALIZATION); 153 154 } 155 private static void enqueueMessage(Object sourceMod, String modTarget, IMCMessage message) 156 { 157 ModContainer mc = FMLCommonHandler.instance().findContainerFor(sourceMod); 158 if (mc != null && Loader.isModLoaded(modTarget)) 159 { 160 message.setSender(mc); 161 modMessages.put(modTarget, message); 162 } 163 } 164 165 public static ImmutableList<IMCMessage> fetchRuntimeMessages(Object forMod) 166 { 167 ModContainer mc = FMLCommonHandler.instance().findContainerFor(forMod); 168 if (mc != null) 169 { 170 return ImmutableList.copyOf(modMessages.removeAll(mc)); 171 } 172 else 173 { 174 return emptyIMCList; 175 } 176 } 177 }