diff --git a/client/cpw/mods/fml/client/FMLClientHandler.java b/client/cpw/mods/fml/client/FMLClientHandler.java index eae8a022e7..aef3afd8be 100644 --- a/client/cpw/mods/fml/client/FMLClientHandler.java +++ b/client/cpw/mods/fml/client/FMLClientHandler.java @@ -43,6 +43,8 @@ import javax.imageio.ImageIO; import org.lwjgl.opengl.GL11; +import com.google.common.collect.ImmutableMap; + import net.minecraft.client.Minecraft; import net.minecraft.src.BaseMod; import net.minecraft.src.BiomeGenBase; @@ -81,12 +83,16 @@ import net.minecraft.src.World; import net.minecraft.src.WorldType; import argo.jdom.JdomParser; import argo.jdom.JsonNode; +import cpw.mods.fml.client.registry.KeyBindingRegistry; +import cpw.mods.fml.common.DummyModContainer; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLDummyContainer; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.IFMLSidedHandler; -import cpw.mods.fml.common.IKeyHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.LoaderException; +import cpw.mods.fml.common.LoaderState; +import cpw.mods.fml.common.MetadataCollection; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModMetadata; import cpw.mods.fml.common.ProxyInjector; @@ -147,7 +153,6 @@ public class FMLClientHandler implements IFMLSidedHandler private HashMap> overrideInfo = new HashMap>(); private HashMap blockModelIds = new HashMap(); private HashMap keyBindings = new HashMap(); - private List keyHandlers = new ArrayList(); private HashSet animationSet = new HashSet(); private List addedTextureFX = new ArrayList(); @@ -160,10 +165,12 @@ public class FMLClientHandler implements IFMLSidedHandler * @param minecraftServer */ - private OptifineModContainer optifineContainer; + private DummyModContainer optifineContainer; private boolean guiLoaded; + private boolean serverIsRunning; + public void onPreLoad(Minecraft minecraft) { client = minecraft; @@ -173,27 +180,16 @@ public class FMLClientHandler implements IFMLSidedHandler try { Class optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader()); - optifineContainer = new OptifineModContainer(optifineConfig); + String optifineVersion = (String) optifineConfig.getField("VERSION").get(null); + Map dummyOptifineMeta = ImmutableMap.builder().put("name", "Optifine").put("version", optifineVersion).build(); + ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info")).getMetadataForId("optifine", dummyOptifineMeta); + optifineContainer = new DummyModContainer(optifineMetadata); + FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion()); } catch (Exception e) { - // OPTIFINE not found optifineContainer = null; } - if (optifineContainer != null) - { - ModMetadata optifineMetadata; - try - { - optifineMetadata = readMetadataFrom(Loader.instance().getModClassLoader().getResourceAsStream("optifinemod.info"), optifineContainer); - optifineContainer.setMetadata(optifineMetadata); - } - catch (Exception e) - { - //not available - } - FMLCommonHandler.instance().getFMLLogger().info(String.format("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion())); - } try { Loader.instance().loadMods(); @@ -226,48 +222,27 @@ public class FMLClientHandler implements IFMLSidedHandler haltGame("There was a severe problem during mod loading that has caused the game to fail", le); return; } - for (ModContainer mod : Loader.getModList()) { - mod.gatherRenderers(RenderManager.field_1233_a.getRendererList()); - for (Render r : RenderManager.field_1233_a.getRendererList().values()) { - r.func_4009_a(RenderManager.field_1233_a); - } - } - // Load the key bindings into the settings table - - GameSettings gs = client.field_6304_y; - KeyBinding[] modKeyBindings = harvestKeyBindings(); - KeyBinding[] allKeys = new KeyBinding[gs.field_1564_t.length + modKeyBindings.length]; - System.arraycopy(gs.field_1564_t, 0, allKeys, 0, gs.field_1564_t.length); - System.arraycopy(modKeyBindings, 0, allKeys, gs.field_1564_t.length, modKeyBindings.length); - gs.field_1564_t = allKeys; - gs.func_6519_a(); - + // TODO +// for (ModContainer mod : Loader.getModList()) { +// mod.gatherRenderers(RenderManager.field_1233_a.getRendererList()); +// for (Render r : RenderManager.field_1233_a.getRendererList().values()) { +// r.func_4009_a(RenderManager.field_1233_a); +// } +// } // Mark this as a "first tick" - + KeyBindingRegistry.uploadKeyBindingsToGame(client.field_6304_y); + firstTick = true; } - public KeyBinding[] harvestKeyBindings() { - List allKeys=FMLCommonHandler.instance().gatherKeyBindings(); - KeyBinding[] keys=new KeyBinding[allKeys.size()]; - int i=0; - for (IKeyHandler key : allKeys) { - keys[i++]=(KeyBinding)key.getKeyBinding(); - keyBindings.put((KeyBinding) key.getKeyBinding(), key.getOwningContainer()); - } - keyHandlers = allKeys; - return keys; - } /** * Every tick just before world and other ticks occur */ public void onPreWorldTick() { - if (client.field_6324_e != null) { - // For the client world ticks and game ticks are the same - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLD), client.field_6324_e, client.field_6313_p, client.field_6324_e); - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.GAME,TickType.WORLDGUI), 0.0f, client.field_6313_p, client.field_6324_e); - } + // TODO +// FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLD), client., client.field_6313_p, client.field_6324_e); +// FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.GAME,TickType.WORLDGUI), 0.0f, client.field_6313_p, client.field_6324_e); } /** @@ -275,23 +250,19 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void onPostWorldTick() { -// if (client.field_6324_e != null) { -// // For the client world ticks and game ticks are the same -// FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.WORLD), client.field_6324_e, client.field_6313_p, client.field_6324_e); -// FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.GAME,TickType.WORLDGUI), 0.0f, client.field_6313_p, client.field_6324_e); -// } + // TODO +// FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.WORLD), client.field_6324_e, client.field_6313_p, client.field_6324_e); +// FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.GAME,TickType.WORLDGUI), 0.0f, client.field_6313_p, client.field_6324_e); } public void onWorldLoadTick() { -// if (client.field_6324_e != null) { - if (firstTick) - { - loadTextures(fallbackTexturePack); - firstTick = false; - } - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLDLOAD,TickType.GUILOAD)); -// } + if (firstTick) + { + loadTextures(fallbackTexturePack); + firstTick = false; + } + FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLDLOAD,TickType.GUILOAD)); } public void onRenderTickStart(float partialTickTime) @@ -345,25 +316,6 @@ public class FMLClientHandler implements IFMLSidedHandler FMLCommonHandler.instance().handleWorldGeneration(chunkX, chunkZ, world.func_22138_q(), world, generator, chunkProvider); } - /** - * Is the offered class and instance of BaseMod and therefore a ModLoader - * mod? - */ - public boolean isModLoaderMod(Class clazz) - { - return BaseMod.class.isAssignableFrom(clazz); - } - - /** - * Load the supplied mod class into a mod container - */ - public ModContainer loadBaseModMod(Class clazz, File canonicalFile) - { - @SuppressWarnings("unchecked") - Class bmClazz = (Class) clazz; - return new ModLoaderModContainer(bmClazz, canonicalFile); - } - /** * Called to notify that an item was picked up from the world * @@ -372,13 +324,14 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void notifyItemPickup(EntityItem entityItem, EntityPlayer entityPlayer) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsPickupNotification()) - { - mod.getPickupNotifier().notifyPickup(entityItem, entityPlayer); - } - } + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsPickupNotification()) +// { +// mod.getPickupNotifier().notifyPickup(entityItem, entityPlayer); +// } +// } } /** @@ -396,14 +349,15 @@ public class FMLClientHandler implements IFMLSidedHandler */ public boolean tryDispensingEntity(World world, double x, double y, double z, int p_56784_7_, int p_56784_8_, ItemStack item) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsToDispense() && mod.getDispenseHandler().dispense(x, y, z, p_56784_7_, p_56784_8_, world, item)) - { - return true; - } - } - + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsToDispense() && mod.getDispenseHandler().dispense(x, y, z, p_56784_7_, p_56784_8_, world, item)) +// { +// return true; +// } +// } +// return false; } @@ -452,13 +406,14 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void onItemCrafted(EntityPlayer player, ItemStack craftedItem, IInventory craftingGrid) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsCraftingNotification()) - { - mod.getCraftingHandler().onCrafting(player, craftedItem, craftingGrid); - } - } + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsCraftingNotification()) +// { +// mod.getCraftingHandler().onCrafting(player, craftedItem, craftingGrid); +// } +// } } /** @@ -469,13 +424,14 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void onItemSmelted(EntityPlayer player, ItemStack smeltedItem) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsCraftingNotification()) - { - mod.getCraftingHandler().onSmelting(player, smeltedItem); - } - } + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsCraftingNotification()) +// { +// mod.getCraftingHandler().onSmelting(player, smeltedItem); +// } +// } } /** @@ -488,14 +444,15 @@ public class FMLClientHandler implements IFMLSidedHandler */ public boolean handleChatPacket(Packet3Chat chat) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat)) - { - return true; - } - } - + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat)) +// { +// return true; +// } +// } +// return false; } @@ -509,14 +466,15 @@ public class FMLClientHandler implements IFMLSidedHandler */ public boolean handleChatPacket(Packet3Chat chat, EntityPlayer player) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat, player)) - { - return true; - } - } - + // TODO +// for (ModContainer mod : Loader.getModList()) +// { +// if (mod.wantsNetworkPackets() && mod.getNetworkHandler().onChat(chat, player)) +// { +// return true; +// } +// } +// return false; } @@ -531,9 +489,11 @@ public class FMLClientHandler implements IFMLSidedHandler { networkManager.func_972_a(packet); } - for (ModContainer mod : Loader.getModList()) { - mod.getNetworkHandler().onServerLogin(handler); - } + + // TODO +// for (ModContainer mod : Loader.getModList()) { +// mod.getNetworkHandler().onServerLogin(handler); +// } } /** @@ -549,13 +509,14 @@ public class FMLClientHandler implements IFMLSidedHandler handleServerRegistration(packet); return; } - - ModContainer mod = FMLCommonHandler.instance().getModForChannel(packet.field_44012_a); - - if (mod != null) - { - mod.getNetworkHandler().onPacket250Packet(packet); - } + // TODO + +// ModContainer mod = FMLCommonHandler.instance().getModForChannel(packet.field_44012_a); +// +// if (mod != null) +// { +// mod.getNetworkHandler().onPacket250Packet(packet); +// } } /** @@ -606,13 +567,7 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void announceLogin(EntityPlayer player) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsPlayerTracking()) - { - mod.getPlayerTracker().onPlayerLogin(player); - } - } + // TODO } /** @@ -620,13 +575,7 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void announceLogout(EntityPlayer player) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsPlayerTracking()) - { - mod.getPlayerTracker().onPlayerLogout(player); - } - } + // TODO } /** @@ -634,13 +583,7 @@ public class FMLClientHandler implements IFMLSidedHandler */ public void announceDimensionChange(EntityPlayer player) { - for (ModContainer mod : Loader.getModList()) - { - if (mod.wantsPlayerTracking()) - { - mod.getPlayerTracker().onPlayerChangedDimension(player); - } - } + // TODO } /** @@ -692,7 +635,7 @@ public class FMLClientHandler implements IFMLSidedHandler info.override = overridingTexturePath; info.texture = textureToOverride; list.add(info); - FMLCommonHandler.instance().getFMLLogger().log(Level.FINE, String.format("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride))); + FMLLog.fine("Overriding %s @ %d with %s. %d slots remaining",textureToOverride, location, overridingTexturePath, SpriteHelper.freeSlotCount(textureToOverride)); } /** * @param mod @@ -743,10 +686,10 @@ public class FMLClientHandler implements IFMLSidedHandler * @param keyHandler * @param allowRepeat */ - public void registerKeyHandler(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat) + public void registerModLoaderKeyHandler(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat) { ModLoaderModContainer mlmc=ModLoaderHelper.registerKeyHelper(mod); - mlmc.addKeyHandler(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc)); + KeyBindingRegistry.registerKeyBinding(new ModLoaderKeyBindingHandler(keyHandler, allowRepeat, mlmc)); } /** @@ -830,9 +773,6 @@ public class FMLClientHandler implements IFMLSidedHandler */ private void registerAnimatedTexturesFor(ModContainer mod) { - this.animationCallbackMod=mod; - mod.requestAnimations(); - this.animationCallbackMod=null; } public String getObjectName(Object instance) { @@ -850,56 +790,6 @@ public class FMLClientHandler implements IFMLSidedHandler return objectName; } - /* (non-Javadoc) - * @see cpw.mods.fml.common.IFMLSidedHandler#readMetadataFrom(java.io.InputStream, cpw.mods.fml.common.ModContainer) - */ - @Override - public ModMetadata readMetadataFrom(InputStream input, ModContainer mod) throws Exception - { - JsonNode root=new JdomParser().parse(new InputStreamReader(input)); - List lst=root.getArrayNode(); - JsonNode modinfo = null; - for (JsonNode tmodinfo : lst) { - if (mod.getName().equals(tmodinfo.getStringValue("modid"))) { - modinfo = tmodinfo; - break; - } - } - if (modinfo == null) { - FMLCommonHandler.instance().getFMLLogger().fine(String.format("Unable to process JSON modinfo file for %s", mod.getName())); - return null; - } - ModMetadata meta=new ModMetadata(mod); - try { - meta.name=modinfo.getStringValue("name"); - meta.description=modinfo.getStringValue("description").replace("\r", ""); - meta.version=modinfo.getStringValue("version"); - meta.credits=modinfo.getStringValue("credits"); - List authors=modinfo.getArrayNode("authors"); - StringBuilder sb=new StringBuilder(); - for (int i=0; i screenshots=modinfo.getArrayNode("screenshots"); - meta.screenshots=new String[screenshots.size()]; - for (int i=0; i effects) { ListIterator li = addedTextureFX.listIterator(); @@ -1044,7 +934,6 @@ public class FMLClientHandler implements IFMLSidedHandler public boolean onUpdateTextureEffect(TextureFX effect) { - Logger log = FMLCommonHandler.instance().getFMLLogger(); ITextureFX ifx = (effect instanceof ITextureFX ? ((ITextureFX)effect) : null); if (ifx != null && ifx.getErrored()) @@ -1064,7 +953,7 @@ public class FMLClientHandler implements IFMLSidedHandler } catch (Exception e) { - log.warning(String.format("Texture FX %s has failed to animate. Likely caused by a texture pack change that they did not respond correctly to", name)); + FMLLog.log.warning("Texture FX %s has failed to animate. Likely caused by a texture pack change that they did not respond correctly to", name); if (ifx != null) { ifx.setErrored(true); @@ -1080,7 +969,7 @@ public class FMLClientHandler implements IFMLSidedHandler int target = ((dim.width >> 4) * (dim.height >> 4)) << 2; if (effect.field_1127_a.length != target) { - log.warning(String.format("Detected a texture FX sizing discrepancy in %s (%d, %d)", name, effect.field_1127_a.length, target)); + FMLLog.log.warning("Detected a texture FX sizing discrepancy in %s (%d, %d)", name, effect.field_1127_a.length, target); ifx.setErrored(true); return false; } diff --git a/client/cpw/mods/fml/client/GuiModList.java b/client/cpw/mods/fml/client/GuiModList.java index 3d32c1f633..abe68c490a 100644 --- a/client/cpw/mods/fml/client/GuiModList.java +++ b/client/cpw/mods/fml/client/GuiModList.java @@ -100,7 +100,7 @@ public class GuiModList extends GuiScreen this.func_548_a(this.field_6451_g, "Mod List", this.field_951_c / 2, 16, 0xFFFFFF); int offset = this.listWidth + 20; if (selectedMod != null) { - if (selectedMod.getMetadata() != null) { + if (!selectedMod.getMetadata().autogenerated) { int shifty = 35; if (!selectedMod.getMetadata().logoFile.isEmpty()) { diff --git a/client/cpw/mods/fml/client/ModLoaderKeyBindingHandler.java b/client/cpw/mods/fml/client/ModLoaderKeyBindingHandler.java index a0056723e3..b062413b29 100644 --- a/client/cpw/mods/fml/client/ModLoaderKeyBindingHandler.java +++ b/client/cpw/mods/fml/client/ModLoaderKeyBindingHandler.java @@ -16,84 +16,77 @@ package cpw.mods.fml.client; import java.util.EnumSet; +import net.minecraft.src.KeyBinding; + import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; -import net.minecraft.src.KeyBinding; -import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.IKeyHandler; -import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.client.registry.KeyBindingRegistry; import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.modloader.ModLoaderModContainer; +import cpw.mods.fml.common.registry.TickRegistry; /** * @author cpw * */ -public class ModLoaderKeyBindingHandler implements IKeyHandler +public class ModLoaderKeyBindingHandler extends KeyBindingRegistry.KeyHandler { - - private boolean shouldRepeat; - private KeyBinding keyBinding; - private ModContainer modContainer; - private boolean lastState = false; - private boolean armed; + private ModLoaderModContainer modContainer; + private boolean downArmed; + private boolean upArmed; /** * @param keyHandler * @param allowRepeat * @param modContainer */ - public ModLoaderKeyBindingHandler(KeyBinding keyHandler, boolean allowRepeat, ModContainer modContainer) + public ModLoaderKeyBindingHandler(KeyBinding keyBinding, boolean allowRepeat, ModLoaderModContainer modContainer) { - this.keyBinding=keyHandler; - this.shouldRepeat=allowRepeat; + super(keyBinding, allowRepeat); this.modContainer=modContainer; - FMLCommonHandler.instance().registerTickHandler(this); - } - - @Override - public Object getKeyBinding() - { - return this.keyBinding; - } - - /** - * @return the modContainer - */ - public ModContainer getOwningContainer() - { - return modContainer; } public void onRenderEndTick() { - int keyCode = keyBinding.field_1370_b; - boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode)); - if (state && (!lastState || (lastState && shouldRepeat))) + ((net.minecraft.src.BaseMod)modContainer.getMod()).keyboardEvent(keyBinding); + } + + @Override + public void keyDown(EnumSet type, boolean end, boolean repeats) + { + if (!end) { - modContainer.keyBindEvent(keyBinding); + return; } - lastState = state; - } - - @Override - public void tickStart(EnumSet type, Object... tickData) - { - // NO-OP for ML - } - - @Override - public void tickEnd(EnumSet type, Object... tickData) - { + upArmed = false; if (type.contains(TickType.GUILOAD)|| type.contains(TickType.GAME)) { - armed = true; + downArmed = true; } - if (type.contains(TickType.RENDER) && armed) + if (type.contains(TickType.RENDER) && downArmed) { onRenderEndTick(); - armed = false; + downArmed = false; + } + } + + @Override + public void keyUp(EnumSet type, boolean end) + { + if (!end) + { + return; + } + downArmed = false; + if (type.contains(TickType.GUILOAD)|| type.contains(TickType.GAME)) + { + upArmed = true; + } + if (type.contains(TickType.RENDER) && upArmed) + { + onRenderEndTick(); + upArmed = false; } } @@ -106,6 +99,6 @@ public class ModLoaderKeyBindingHandler implements IKeyHandler @Override public String getLabel() { - return getOwningContainer()+" KB "+keyBinding.field_1371_a; + return modContainer.getModId() +" KB "+keyBinding.field_1371_a; } } diff --git a/client/cpw/mods/fml/client/OptifineModContainer.java b/client/cpw/mods/fml/client/OptifineModContainer.java deleted file mode 100644 index 2908e05d23..0000000000 --- a/client/cpw/mods/fml/client/OptifineModContainer.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * The FML Forge Mod Loader suite. - * Copyright (C) 2012 cpw - * - * 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; either version 2.1 of the License, or any later version. - * - * 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 cpw.mods.fml.client; - -import java.io.File; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import cpw.mods.fml.common.DummyModContainer; -import cpw.mods.fml.common.FMLModContainer; -import cpw.mods.fml.common.IConsoleHandler; -import cpw.mods.fml.common.ICraftingHandler; -import cpw.mods.fml.common.IDispenseHandler; -import cpw.mods.fml.common.IKeyHandler; -import cpw.mods.fml.common.INetworkHandler; -import cpw.mods.fml.common.IPickupNotifier; -import cpw.mods.fml.common.IPlayerTracker; -import cpw.mods.fml.common.IWorldGenerator; -import cpw.mods.fml.common.ModContainer; -import cpw.mods.fml.common.ModMetadata; - -/** - * @author cpw - * - */ -public class OptifineModContainer extends DummyModContainer -{ - private String optifineVersion; - private ModMetadata metadata; - /** - * @param optifineConfig - */ - public OptifineModContainer(Class optifineConfig) - { - super(); - try - { - optifineVersion = (String) optifineConfig.getField("VERSION").get(null); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - - @Override - public String getName() - { - return "Optifine"; - } - @Override - public String getVersion() - { - return optifineVersion; - } - -} diff --git a/client/cpw/mods/fml/client/SpriteHelper.java b/client/cpw/mods/fml/client/SpriteHelper.java index ed95441fe5..896c21e20b 100644 --- a/client/cpw/mods/fml/client/SpriteHelper.java +++ b/client/cpw/mods/fml/client/SpriteHelper.java @@ -16,10 +16,11 @@ package cpw.mods.fml.client; import java.util.BitSet; import java.util.HashMap; +import java.util.logging.Level; import net.minecraft.src.ModLoader; import cpw.mods.fml.common.FMLCommonHandler; -import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.LoaderException; /** @@ -99,7 +100,7 @@ public class SpriteHelper if (slots == null) { Exception ex = new Exception(String.format("Invalid getUniqueSpriteIndex call for texture: %s", path)); - Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex); + FMLLog.log.log(Level.SEVERE, ex, "A critical error has been detected with sprite overrides"); FMLCommonHandler.instance().raiseException(ex,"Invalid request to getUniqueSpriteIndex",true); } @@ -108,7 +109,7 @@ public class SpriteHelper if (ret == -1) { Exception ex = new Exception(String.format("No more sprite indicies left for: %s", path)); - Loader.log.throwing("ModLoader", "getUniqueSpriteIndex", ex); + FMLLog.log.log(Level.SEVERE, ex, "There are no sprite indicies left for %s", path); FMLCommonHandler.instance().raiseException(ex,"No more sprite indicies left", true); } return ret; diff --git a/client/cpw/mods/fml/client/registry/KeyBindingRegistry.java b/client/cpw/mods/fml/client/registry/KeyBindingRegistry.java new file mode 100644 index 0000000000..4c6ccbc673 --- /dev/null +++ b/client/cpw/mods/fml/client/registry/KeyBindingRegistry.java @@ -0,0 +1,92 @@ +package cpw.mods.fml.client.registry; + +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; + +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; + +import com.google.common.collect.Lists; + +import net.minecraft.src.GameSettings; +import net.minecraft.src.KeyBinding; + +import cpw.mods.fml.common.ITickHandler; +import cpw.mods.fml.common.TickType; +import cpw.mods.fml.common.registry.TickRegistry; + +public class KeyBindingRegistry +{ + public static abstract class KeyHandler implements ITickHandler + { + protected KeyBinding keyBinding; + protected boolean keyDown; + protected boolean repeating; + + public KeyHandler(KeyBinding keyBinding, boolean repeating) + { + this.keyBinding = keyBinding; + this.repeating = repeating; + } + + public KeyBinding getKeyBinding() + { + return this.keyBinding; + } + + @Override + public final void tickStart(EnumSet type, Object... tickData) + { + keyTick(type, false); + } + + @Override + public final void tickEnd(EnumSet type, Object... tickData) + { + keyTick(type, true); + } + + private void keyTick(EnumSet type, boolean tickEnd) + { + int keyCode = keyBinding.field_1370_b; + boolean state = (keyCode < 0 ? Mouse.isButtonDown(keyCode + 100) : Keyboard.isKeyDown(keyCode)); + if (state != keyDown || (state && repeating)) + { + if (state) + { + keyDown(type, tickEnd, state!=keyDown); + } + else + { + keyUp(type, tickEnd); + } + keyDown = state; + } + } + + public abstract void keyDown(EnumSet types, boolean tickEnd, boolean isRepeat); + public abstract void keyUp(EnumSet types, boolean tickEnd); + } + + private static List keyHandlers = Lists.newArrayList(); + + public static void registerKeyBinding(KeyHandler handler) { + keyHandlers.add(handler); + } + + public static void uploadKeyBindingsToGame(GameSettings settings) + { + ArrayList harvestedBindings = Lists.newArrayList(); + for (KeyHandler key : keyHandlers) + { + harvestedBindings.add(key.keyBinding); + } + KeyBinding[] modKeyBindings = harvestedBindings.toArray(new KeyBinding[harvestedBindings.size()]); + KeyBinding[] allKeys = new KeyBinding[settings.field_1564_t.length + modKeyBindings.length]; + System.arraycopy(settings.field_1564_t, 0, allKeys, 0, settings.field_1564_t.length); + System.arraycopy(modKeyBindings, 0, allKeys, settings.field_1564_t.length, modKeyBindings.length); + settings.field_1564_t = allKeys; + settings.func_6519_a(); + } +} diff --git a/client/net/minecraft/src/ModLoader.java b/client/net/minecraft/src/ModLoader.java index 1a15c4be8c..d97700d3c7 100644 --- a/client/net/minecraft/src/ModLoader.java +++ b/client/net/minecraft/src/ModLoader.java @@ -567,7 +567,7 @@ public class ModLoader public static void registerKey(BaseMod mod, KeyBinding keyHandler, boolean allowRepeat) { - FMLClientHandler.instance().registerKeyHandler(mod, keyHandler, allowRepeat); + FMLClientHandler.instance().registerModLoaderKeyHandler(mod, keyHandler, allowRepeat); } /** diff --git a/common/cpw/mods/fml/common/FMLCommonHandler.java b/common/cpw/mods/fml/common/FMLCommonHandler.java index ee54ea2f4b..994ffa3f23 100644 --- a/common/cpw/mods/fml/common/FMLCommonHandler.java +++ b/common/cpw/mods/fml/common/FMLCommonHandler.java @@ -26,10 +26,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.PriorityQueue; import java.util.Properties; import java.util.Random; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -39,6 +39,8 @@ import java.util.zip.ZipFile; import java.util.zip.ZipInputStream; import cpw.mods.fml.common.discovery.ContainerType; +import cpw.mods.fml.common.registry.TickRegistry; +import cpw.mods.fml.common.registry.WorldRegistry; /** @@ -84,68 +86,20 @@ public class FMLCommonHandler private Map modLanguageData=new HashMap(); - private PriorityQueue tickHandlers = new PriorityQueue(); - private List scheduledTicks = new ArrayList(); - private Set worldGenerators = new HashSet(); - /** - * We register our delegate here - * @param handler - */ - - private static class TickQueueElement implements Comparable - { - static long tickCounter = 0; - public TickQueueElement(IScheduledTickHandler ticker) - { - this.ticker = ticker; - update(); - } - @Override - public int compareTo(TickQueueElement o) - { - return (int)(next - o.next); - } - - public void update() - { - next = tickCounter + Math.max(ticker.nextTickSpacing(),1); - } - - private long next; - private IScheduledTickHandler ticker; - - public boolean scheduledNow() - { - return tickCounter >= next; - } - } - public void beginLoading(IFMLSidedHandler handler) { sidedDelegate = handler; - getFMLLogger().info("Attempting early MinecraftForge initialization"); + FMLLog.info("Attempting early MinecraftForge initialization"); callForgeMethod("initialize"); - getFMLLogger().info("Completed early MinecraftForge initialization"); + FMLLog.info("Completed early MinecraftForge initialization"); } public void rescheduleTicks() { sidedDelegate.profileStart("modTickScheduling"); - TickQueueElement.tickCounter++; - scheduledTicks.clear(); - while (true) - { - if (tickHandlers.size()==0 || !tickHandlers.peek().scheduledNow()) - { - break; - } - TickQueueElement tickQueueElement = tickHandlers.poll(); - tickQueueElement.update(); - tickHandlers.offer(tickQueueElement); - scheduledTicks.add(tickQueueElement.ticker); - } + TickRegistry.updateTickQueue(scheduledTicks); sidedDelegate.profileEnd(); } public void tickStart(EnumSet ticks, Object ... data) @@ -190,18 +144,6 @@ public class FMLCommonHandler sidedDelegate.profileEnd(); } - public List gatherKeyBindings() { - List allKeys=new ArrayList(); - for (ModContainer mod : Loader.getModList()) - { - allKeys.addAll(mod.getKeys()); - } - for (ModContainer mod : auxilliaryContainers) - { - allKeys.addAll(mod.getKeys()); - } - return allKeys; - } /** * @return the instance */ @@ -322,8 +264,7 @@ public class FMLCommonHandler } catch (UnsupportedEncodingException e) { - Loader.log.warning("Error building registration list"); - Loader.log.throwing("FMLHooks", "getPacketRegistry", e); + FMLLog.log.log(Level.WARNING, e, "Error building registration list"); return new byte[0]; } } @@ -345,7 +286,7 @@ public class FMLCommonHandler */ public Logger getFMLLogger() { - return Loader.log; + return FMLLog.log.getLogger(); } /** @@ -362,27 +303,6 @@ public class FMLCommonHandler return sidedDelegate.getMinecraftLogger(); } - /** - * Is this a modloader mod? - * @param clazz - * @return - */ - public boolean isModLoaderMod(Class clazz) - { - return sidedDelegate.isModLoaderMod(clazz); - } - - /** - * Load the modloader mod - * @param clazz - * @param canonicalPath - * @return - */ - public ModContainer loadBaseModMod(Class clazz, File canonicalFile) - { - return sidedDelegate.loadBaseModMod(clazz, canonicalFile); - } - public File getMinecraftRootDirectory() { return sidedDelegate.getMinecraftRootDirectory(); } @@ -457,12 +377,6 @@ public class FMLCommonHandler public int fuelLookup(int itemId, int itemDamage) { int fv = 0; - - for (ModContainer mod : Loader.getModList()) - { - fv = Math.max(fv, mod.lookupFuelValue(itemId, itemDamage)); - } - return fv; } @@ -573,35 +487,12 @@ public class FMLCommonHandler public void handleWorldGeneration(int chunkX, int chunkZ, long worldSeed, Object... data) { - Random fmlRandom = new Random(worldSeed); - long xSeed = fmlRandom.nextLong() >> 2 + 1L; - long zSeed = fmlRandom.nextLong() >> 2 + 1L; - fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ worldSeed); - - for (IWorldGenerator generator : worldGenerators) - { - generator.generate(fmlRandom, chunkX, chunkZ, data); - } - } - - public void registerTickHandler(ITickHandler handler) - { - registerScheduledTickHandler(new SingleIntervalHandler(handler)); - } - - public void registerScheduledTickHandler(IScheduledTickHandler handler) - { - tickHandlers.add(new TickQueueElement(handler)); - } - - public void registerWorldGenerator(IWorldGenerator generator) - { - worldGenerators.add(generator); + WorldRegistry.generateWorld(chunkX, chunkZ, worldSeed, data); } public void onPostServerTick() { - FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.GAME)); + tickEnd(EnumSet.of(TickType.GAME)); } /** @@ -609,12 +500,12 @@ public class FMLCommonHandler */ public void onPostWorldTick(Object world) { - FMLCommonHandler.instance().tickEnd(EnumSet.of(TickType.WORLD), world); + tickEnd(EnumSet.of(TickType.WORLD), world); } public void onPreServerTick() { - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.GAME)); + tickStart(EnumSet.of(TickType.GAME)); } /** @@ -622,11 +513,11 @@ public class FMLCommonHandler */ public void onPreWorldTick(Object world) { - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLD), world); + tickStart(EnumSet.of(TickType.WORLD), world); } public void onWorldLoadTick() { - FMLCommonHandler.instance().tickStart(EnumSet.of(TickType.WORLDLOAD)); + tickStart(EnumSet.of(TickType.WORLDLOAD)); } } diff --git a/common/cpw/mods/fml/common/FMLLog.java b/common/cpw/mods/fml/common/FMLLog.java new file mode 100644 index 0000000000..1e2d15af05 --- /dev/null +++ b/common/cpw/mods/fml/common/FMLLog.java @@ -0,0 +1,109 @@ +package cpw.mods.fml.common; + +import java.io.File; +import java.util.logging.ConsoleHandler; +import java.util.logging.FileHandler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +public class FMLLog +{ + + /** + * Our special logger for logging issues to. We copy various assets from the + * Minecraft logger to acheive a similar appearance. + */ + public static FMLLog log = new FMLLog(); + + private static File minecraftHome; + private static boolean configured; + private Logger myLog; + + private FMLLog() + { + } + /** + * Configure the FML logger + */ + private static void configureLogging() + { + LogManager.getLogManager().reset(); + Logger globalLogger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); + globalLogger.setLevel(Level.OFF); + + log.myLog = Logger.getLogger("ForgeModLoader"); + FMLLogFormatter formatter = new FMLLogFormatter(); + ConsoleHandler ch = new ConsoleHandler(); + log.myLog.setUseParentHandlers(false); + log.myLog.addHandler(ch); + ch.setFormatter(formatter); + log.myLog.setLevel(Level.ALL); + try + { + File logPath = new File(minecraftHome, "ForgeModLoader-%g.log"); + FileHandler fileHandler = new FileHandler(logPath.getPath(), 0, 3); + fileHandler.setFormatter(new FMLLogFormatter()); + fileHandler.setLevel(Level.ALL); + log.myLog.addHandler(fileHandler); + } + catch (Exception e) + { + } + + // Reset global logging to shut up other logging sources (thanks guava!) + configured = true; + } + + public static void log(Level level, String format, Object... data) + { + if (!configured) + { + configureLogging(); + } + log.myLog.log(level, String.format(format, data)); + } + + public static void log(Level level, Throwable ex, String format, Object... data) + { + if (!configured) + { + configureLogging(); + } + log.myLog.log(level, String.format(format, data), ex); + } + + public static void severe(String format, Object... data) + { + log(Level.SEVERE, format, data); + } + + public static void warning(String format, Object... data) + { + log(Level.WARNING, format, data); + } + + public static void info(String format, Object... data) + { + log(Level.INFO, format, data); + } + + public static void fine(String format, Object... data) + { + log(Level.FINE, format, data); + } + + public static void finer(String format, Object... data) + { + log(Level.FINER, format, data); + } + + public static void finest(String format, Object... data) + { + log(Level.FINEST, format, data); + } + public Logger getLogger() + { + return myLog; + } +} diff --git a/common/cpw/mods/fml/common/FMLModContainer.java b/common/cpw/mods/fml/common/FMLModContainer.java index e9b76efafb..a1121dae86 100644 --- a/common/cpw/mods/fml/common/FMLModContainer.java +++ b/common/cpw/mods/fml/common/FMLModContainer.java @@ -13,18 +13,29 @@ package cpw.mods.fml.common; import java.io.File; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.google.common.base.Throwables; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import cpw.mods.fml.common.LoaderState.ModState; +import cpw.mods.fml.common.Mod.Block; +import cpw.mods.fml.common.Mod.Instance; +import cpw.mods.fml.common.Mod.Metadata; import cpw.mods.fml.common.discovery.ContainerType; import cpw.mods.fml.common.event.FMLConstructionEvent; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; public class FMLModContainer implements ModContainer { @@ -35,13 +46,14 @@ public class FMLModContainer implements ModContainer private String className; private String modId; private Map descriptor; - private boolean enabled; + private boolean enabled = true; private List requirements; private List dependencies; private List dependants; private boolean overridesMetadata; private EventBus eventBus; private LoadController controller; + private Multimap, Object> annotations; public FMLModContainer(String className, File modSource, Map modDescriptor) { @@ -83,7 +95,7 @@ public class FMLModContainer implements ModContainer @Override public void bindMetadata(MetadataCollection mc) { - modMetadata = mc.getMetadataForId(getModId()); + modMetadata = mc.getMetadataForId(getModId(), descriptor); if (descriptor.containsKey("usesMetadata")) { @@ -156,6 +168,7 @@ public class FMLModContainer implements ModContainer { if (this.enabled) { + FMLLog.fine("Enabling mod %s", getModId()); this.eventBus = bus; this.controller = controller; eventBus.register(this); @@ -167,19 +180,128 @@ public class FMLModContainer implements ModContainer } } + private Multimap, Object> gatherAnnotations(Class clazz) throws Exception + { + Multimap,Object> anns = ArrayListMultimap.create(); + + for (Field f : clazz.getDeclaredFields()) + { + for (Annotation a : f.getAnnotations()) + { + f.setAccessible(true); + anns.put(a.annotationType(), f); + } + } + + for (Method m : clazz.getDeclaredMethods()) + { + for (Annotation a : m.getAnnotations()) + { + if (m.getParameterTypes().length==0) + { + m.setAccessible(true); + anns.put(a.annotationType(), m); + } + else + { + FMLLog.severe("The mod type %s appears to have an invalid method annotation %s. This annotation can only apply to zero argument methods", getModId(), a.annotationType().getSimpleName()); + } + } + } + return anns; + } + + private void processFieldAnnotations() throws Exception + { + // Instance annotation + for (Object o : annotations.get(Instance.class)) + { + Field f = (Field) o; + f.set(modInstance, modInstance); + } + + for (Object o : annotations.get(Metadata.class)) + { + Field f = (Field) o; + f.set(modInstance, modMetadata); + } + + for (Object o : annotations.get(Block.class)) + { + Field f = (Field) o; + } + } + @Subscribe - void constructMod(FMLConstructionEvent event) + public void constructMod(FMLConstructionEvent event) { try { ModClassLoader modClassLoader = event.getModClassLoader(); modClassLoader.addFile(source); - modInstance = Class.forName(className, true, modClassLoader).newInstance(); + Class clazz = Class.forName(className, true, modClassLoader); + annotations = gatherAnnotations(clazz); + modInstance = clazz.newInstance(); + processFieldAnnotations(); } - catch (Exception e) + catch (Throwable e) { controller.errorOccurred(this, e); Throwables.propagateIfPossible(e); } } + + @Subscribe + public void preInitMod(FMLPreInitializationEvent event) + { + try + { + for (Object o : annotations.get(Mod.PreInit.class)) + { + Method m = (Method) o; + m.invoke(modInstance); + } + } + catch (Throwable t) + { + controller.errorOccurred(this, t); + Throwables.propagateIfPossible(t); + } + } + + @Subscribe + public void initMod(FMLInitializationEvent event) + { + try + { + for (Object o : annotations.get(Mod.Init.class)) + { + Method m = (Method) o; + m.invoke(modInstance); + } + } + catch (Throwable t) + { + controller.errorOccurred(this, t); + Throwables.propagateIfPossible(t); + } + } + + @Subscribe + public void postInitMod(FMLPostInitializationEvent event) + { + try + { + for (Object o : annotations.get(Mod.PostInit.class)) + { + Method m = (Method) o; + m.invoke(modInstance); + } + } + catch (Throwable t) + { + controller.errorOccurred(this, t); + Throwables.propagateIfPossible(t); + } + } } diff --git a/common/cpw/mods/fml/common/IFMLSidedHandler.java b/common/cpw/mods/fml/common/IFMLSidedHandler.java index 3eda416c36..2e9af52f3b 100644 --- a/common/cpw/mods/fml/common/IFMLSidedHandler.java +++ b/common/cpw/mods/fml/common/IFMLSidedHandler.java @@ -14,13 +14,10 @@ public interface IFMLSidedHandler { Logger getMinecraftLogger(); File getMinecraftRootDirectory(); - boolean isModLoaderMod(Class clazz); - ModContainer loadBaseModMod(Class clazz, File canonicalFile); Object getMinecraftInstance(); String getCurrentLanguage(); Properties getCurrentLanguageTable(); String getObjectName(Object minecraftObject); - ModMetadata readMetadataFrom(InputStream input, ModContainer mod) throws Exception; void profileStart(String profileLabel); void profileEnd(); ModProperty getModLoaderPropertyFor(Field f); diff --git a/common/cpw/mods/fml/common/IKeyHandler.java b/common/cpw/mods/fml/common/IKeyHandler.java deleted file mode 100644 index 5e846fae06..0000000000 --- a/common/cpw/mods/fml/common/IKeyHandler.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * The FML Forge Mod Loader suite. - * Copyright (C) 2012 cpw - * - * 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; either version 2.1 of the License, or any later version. - * - * 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 cpw.mods.fml.common; - -/** - * @author cpw - * - */ -public interface IKeyHandler extends ITickHandler -{ - - Object getKeyBinding(); - - /** - * @return - */ - ModContainer getOwningContainer(); -} diff --git a/common/cpw/mods/fml/common/LoadController.java b/common/cpw/mods/fml/common/LoadController.java index 8b57807341..b43fa553bc 100644 --- a/common/cpw/mods/fml/common/LoadController.java +++ b/common/cpw/mods/fml/common/LoadController.java @@ -1,21 +1,18 @@ package cpw.mods.fml.common; -import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.logging.Level; -import java.util.logging.Logger; import com.google.common.base.Joiner; -import com.google.common.collect.HashMultimap; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; -import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import cpw.mods.fml.common.LoaderState.ModState; -import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLStateEvent; public class LoadController @@ -24,9 +21,8 @@ public class LoadController private EventBus masterChannel; private ImmutableMap eventChannels; private LoaderState state; - private Multimap modStates = HashMultimap.create(); - private Multimap errors = HashMultimap.create(); - private Logger log; + private Multimap modStates = ArrayListMultimap.create(); + private Multimap errors = ArrayListMultimap.create(); private Map modList; public LoadController(Loader loader) @@ -35,7 +31,6 @@ public class LoadController this.modList = loader.getIndexedModList(); this.masterChannel = new EventBus("FMLMainChannel"); this.masterChannel.register(this); - this.log = Loader.log; Builder eventBus = ImmutableMap.builder(); @@ -45,11 +40,13 @@ public class LoadController boolean isActive = mod.registerBus(bus, this); if (isActive) { + FMLLog.fine("Activating mod %s", mod.getModId()); modStates.put(mod.getModId(), ModState.UNLOADED); eventBus.put(mod.getModId(), bus); } else { + FMLLog.warning("Mod %s has been disabled through configuration", mod.getModId()); modStates.put(mod.getModId(), ModState.UNLOADED); modStates.put(mod.getModId(), ModState.DISABLED); } @@ -60,7 +57,7 @@ public class LoadController state = LoaderState.CONSTRUCTING; } - public void runNextPhase(Object... eventData) + public void distributeStateMessage(Object... eventData) { if (state.hasEvent()) { @@ -68,18 +65,33 @@ public class LoadController } } - public void transition() + public void transition(LoaderState desiredState) { + LoaderState oldState = state; state = state.transition(!errors.isEmpty()); + if (state != desiredState) + { + FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState); + StringBuilder sb = new StringBuilder(); + printModStates(sb); + FMLLog.severe(sb.toString()); + FMLLog.severe("The following problems were captured during this phase"); + for (Entry error : errors.entries()) + { + FMLLog.log(Level.SEVERE, error.getValue(), "Caught exception from %s", error.getKey()); + } + + throw new LoaderException(); + } } @Subscribe - void propogateStateMessage(FMLStateEvent stateEvent) + public void propogateStateMessage(FMLStateEvent stateEvent) { for (Map.Entry entry : eventChannels.entrySet()) { entry.getValue().post(stateEvent); - if (errors.isEmpty()) + if (!errors.containsKey(entry.getKey())) { modStates.put(entry.getKey(), stateEvent.getModState()); } @@ -92,17 +104,7 @@ public class LoadController public void errorOccurred(ModContainer modContainer, Throwable exception) { - errors.put(modContainer, exception); - } - - public void log(Level level, String message, Object... rest) - { - log.log(level, String.format(message,rest)); - } - - public void log(Level level, Throwable error, String message, Object... rest) - { - log.log(level, String.format(message,rest), error); + errors.put(modContainer.getModId(), exception); } public void printModStates(StringBuilder ret) diff --git a/common/cpw/mods/fml/common/Loader.java b/common/cpw/mods/fml/common/Loader.java index b3fb7ad9a8..58bcabbbd9 100644 --- a/common/cpw/mods/fml/common/Loader.java +++ b/common/cpw/mods/fml/common/Loader.java @@ -26,10 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; -import java.util.logging.ConsoleHandler; -import java.util.logging.FileHandler; import java.util.logging.Level; -import java.util.logging.Logger; import java.util.regex.Matcher; import com.google.common.base.CharMatcher; @@ -89,12 +86,6 @@ public class Loader * The singleton instance */ private static Loader instance; - /** - * Our special logger for logging issues to. We copy various assets from the - * Minecraft logger to acheive a similar appearance. - */ - public static Logger log = Logger.getLogger("ForgeModLoader"); - /** * Build information for tracking purposes. */ @@ -148,8 +139,6 @@ public class Loader private Loader() { - configureLogging(); - InputStream stream = getClass().getClassLoader().getResourceAsStream("fmlversion.properties"); Properties properties = new Properties(); @@ -161,7 +150,7 @@ public class Loader } catch (IOException ex) { - Loader.log.log(Level.SEVERE, "Could not get FML version information - corrupted installation detected!", ex); + FMLLog.log.log(Level.SEVERE, "Could not get FML version information - corrupted installation detected!", ex); throw new LoaderException(ex); } } @@ -173,44 +162,11 @@ public class Loader mccversion = properties.getProperty("fmlbuild.mcclientversion", "missing"); mcsversion = properties.getProperty("fmlbuild.mcserverversion", "missing"); - log.info(String.format("Forge Mod Loader version %s.%s.%s.%s for Minecraft c:%s, s:%s loading", major, minor, rev, build, mccversion, mcsversion)); + FMLLog.log.info("Forge Mod Loader version %s.%s.%s.%s for Minecraft client:%s, server:%s loading", major, minor, rev, build, mccversion, mcsversion); modClassLoader = new ModClassLoader(getClass().getClassLoader()); } - /** - * Configure the FML logger - */ - private static void configureLogging() - { - FMLLogFormatter formatter = new FMLLogFormatter(); - if (FMLCommonHandler.instance().getMinecraftLogger() != null) - { - Loader.log.setParent(FMLCommonHandler.instance().getMinecraftLogger()); - } - else - { - ConsoleHandler ch = new ConsoleHandler(); - Loader.log.setUseParentHandlers(false); - Loader.log.addHandler(ch); - ch.setFormatter(formatter); - - } - Loader.log.setLevel(Level.ALL); - try - { - File logPath = new File(FMLCommonHandler.instance().getMinecraftRootDirectory().getCanonicalPath(), "ForgeModLoader-%g.log"); - FileHandler fileHandler = new FileHandler(logPath.getPath(), 0, 3); - fileHandler.setFormatter(new FMLLogFormatter()); - fileHandler.setLevel(Level.ALL); - Loader.log.addHandler(fileHandler); - } - catch (Exception e) - { - // Whatever - give up - } - } - /** * Sort the mods into a sorted list, using dependency information from the * containers. The sorting is performed using a {@link TopologicalSort} @@ -218,43 +174,47 @@ public class Loader */ private void sortModList() { - log.fine("Verifying mod requirements are satisfied"); + FMLLog.log.fine("Verifying mod requirements are satisfied"); try { for (ModContainer mod : mods) { if (!namedMods.keySet().containsAll(mod.getRequirements())) { - log.log(Level.SEVERE, String.format("The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), mod.getRequirements())); + FMLLog.log.log(Level.SEVERE, "The mod %s (%s) requires mods %s to be available, one or more are not", mod.getModId(), mod.getName(), mod.getRequirements()); throw new LoaderException(); } } - log.fine("All mod requirements are satisfied"); + FMLLog.log.fine("All mod requirements are satisfied"); ModSorter sorter = new ModSorter(mods, namedMods); try { - log.fine("Sorting mods into an ordered list"); + FMLLog.log.fine("Sorting mods into an ordered list"); mods = sorter.sort(); - log.fine("Mod sorting completed successfully"); + FMLLog.log.fine("Mod sorting completed successfully"); } catch (ModSortingException sortException) { - log.severe("A dependency cycle was detected in the input mod set so an ordering cannot be determined"); - log.severe(String.format("The visited mod list is %s", sortException.getExceptionData().getVisitedNodes())); - log.severe(String.format("The first mod in the cycle is %s", sortException.getExceptionData().getFirstBadNode())); - log.throwing("Loader", "sortModList", sortException); + FMLLog.log.severe("A dependency cycle was detected in the input mod set so an ordering cannot be determined"); + FMLLog.log.severe("The visited mod list is %s", sortException.getExceptionData().getVisitedNodes()); + FMLLog.log.severe("The first mod in the cycle is %s", sortException.getExceptionData().getFirstBadNode()); + FMLLog.log.log(Level.SEVERE, sortException, "The full error"); throw new LoaderException(sortException); } } finally { - log.fine("Mod sorting data:"); + FMLLog.log.fine("Mod sorting data:"); for (ModContainer mod : mods) { - log.fine(String.format("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules())); + FMLLog.log.fine("\t%s(%s): %s (%s)", mod.getModId(), mod.getName(), mod.getSource().getName(), mod.getSortingRules()); + } + if (mods.size()==0) + { + FMLLog.log.fine("No mods found to sort"); } } @@ -284,16 +244,16 @@ public class Loader private void identifyMods() { ModDiscoverer discoverer = new ModDiscoverer(); - log.fine("Attempting to load mods contained in the minecraft jar file and associated classes"); + FMLLog.log.fine("Attempting to load mods contained in the minecraft jar file and associated classes"); discoverer.findClasspathMods(modClassLoader); - log.fine("Minecraft jar mods loaded successfully"); + FMLLog.log.fine("Minecraft jar mods loaded successfully"); - log.info(String.format("Searching %s for mods", canonicalModsDir.getAbsolutePath())); + FMLLog.log.info("Searching %s for mods", canonicalModsDir.getAbsolutePath()); discoverer.findModDirMods(canonicalModsDir); mods = discoverer.identifyMods(); namedMods = Maps.uniqueIndex(mods, new ModIdFunction()); - log.info(String.format("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 0 ? "s" : "")); + FMLLog.log.info("Forge Mod Loader has identified %d mod%s to load", mods.size(), mods.size() != 1 ? "s" : ""); } /** @@ -317,7 +277,7 @@ public class Loader } catch (IOException ioe) { - log.log(Level.SEVERE, + FMLLog.log.log(Level.SEVERE, String.format("Failed to resolve loader directories: mods : %s ; config %s", canonicalModsDir.getAbsolutePath(), configDir.getAbsolutePath()), ioe); throw new LoaderException(ioe); @@ -325,37 +285,37 @@ public class Loader if (!canonicalModsDir.exists()) { - log.log(Level.INFO, String.format("No mod directory found, creating one: %s", canonicalModsPath)); + FMLLog.log.info("No mod directory found, creating one: %s", canonicalModsPath); boolean dirMade = canonicalModsDir.mkdir(); if (!dirMade) { - log.log(Level.SEVERE, String.format("Unable to create the mod directory %s", canonicalModsPath)); + FMLLog.log.severe("Unable to create the mod directory %s", canonicalModsPath); throw new LoaderException(); } - log.log(Level.INFO, "Mod directory created successfully"); + FMLLog.log.info("Mod directory created successfully"); } if (!canonicalConfigDir.exists()) { - log.fine(String.format("No config directory found, creating one: %s", canonicalConfigPath)); + FMLLog.log.fine("No config directory found, creating one: %s", canonicalConfigPath); boolean dirMade = canonicalConfigDir.mkdir(); if (!dirMade) { - log.log(Level.SEVERE, String.format("Unable to create the config directory %s", canonicalConfigPath)); + FMLLog.log.severe("Unable to create the config directory %s", canonicalConfigPath); throw new LoaderException(); } - log.log(Level.INFO, "Config directory created successfully"); + FMLLog.log.info("Config directory created successfully"); } if (!canonicalModsDir.isDirectory()) { - log.log(Level.SEVERE, String.format("Attempting to load mods from %s, which is not a directory", canonicalModsPath)); + FMLLog.log.severe("Attempting to load mods from %s, which is not a directory", canonicalModsPath); throw new LoaderException(); } if (!configDir.isDirectory()) { - log.log(Level.SEVERE, String.format("Attempting to load configuration from %s, which is not a directory", canonicalConfigPath)); + FMLLog.log.severe("Attempting to load configuration from %s, which is not a directory", canonicalConfigPath); throw new LoaderException(); } } @@ -382,38 +342,40 @@ public class Loader sortModList(); mods = ImmutableList.copyOf(mods); modController = new LoadController(this); - modController.runNextPhase(modClassLoader); + modController.distributeStateMessage(modClassLoader); + modController.transition(LoaderState.PREINITIALIZATION); + modController.distributeStateMessage(); + modController.transition(LoaderState.INITIALIZATION); } private void disableRequestedMods() { String disabledModList = System.getProperty("fml.disabledMods", ""); - log.log(Level.FINE, String.format("Received a system property request \'%s\'",disabledModList)); + FMLLog.log.fine("Received a system property request \'%s\'",disabledModList); Map sysPropertyStateList = Splitter.on(CharMatcher.anyOf(";:")) .omitEmptyStrings().trimResults().withKeyValueSeparator("=") .split(disabledModList); - log.log(Level.FINE, String.format("System property request managing the state of %d mods", sysPropertyStateList.size())); + FMLLog.log.fine("System property request managing the state of %d mods", sysPropertyStateList.size()); Map modStates = Maps.newHashMap(); File disabledModFile = new File(canonicalConfigDir, "fmlModState.properties"); Properties disabledModListProperties = new Properties(); if (disabledModFile.exists() && disabledModFile.isFile()) { - log.log(Level.FINE, String.format("Found a mod state file %s", disabledModFile.getName())); + FMLLog.log.fine("Found a mod state file %s", disabledModFile.getName()); try { disabledModListProperties.load(new FileReader(disabledModFile)); - log.log(Level.FINE, String.format("Loaded states for %d mods from file", disabledModListProperties.size())); + FMLLog.log.fine("Loaded states for %d mods from file", disabledModListProperties.size()); } catch (Exception e) { - log.log(Level.INFO, "An error occurred reading the fmlModState.properties file", e); + FMLLog.log.log(Level.INFO, e, "An error occurred reading the fmlModState.properties file"); } - log.log(Level.FINE, String.format("Found a mod state file %s", disabledModFile.getName())); } modStates.putAll(Maps.fromProperties(disabledModListProperties)); modStates.putAll(sysPropertyStateList); - log.log(Level.FINE, String.format("After merging, found state information for %d mods", modStates.size())); + FMLLog.log.fine("After merging, found state information for %d mods", modStates.size()); Map isEnabled = Maps.transformValues(modStates, new Function() { @@ -427,7 +389,7 @@ public class Loader { if (namedMods.containsKey(entry.getKey())) { - log.log(Level.INFO, String.format("Setting mod %s to enabled state %b", entry.getKey(), entry.getValue())); + FMLLog.log.info("Setting mod %s to enabled state %b", entry.getKey(), entry.getValue()); namedMods.get(entry.getKey()).setEnabledState(entry.getValue()); } } @@ -455,8 +417,11 @@ public class Loader public String getCrashInformation() { StringBuilder ret = new StringBuilder(); - Joiner.on('\n').appendTo(ret, FMLCommonHandler.instance().getBrandingStrings(getFMLVersionString())); - modController.printModStates(ret); + Joiner.on('\n').appendTo(ret, FMLCommonHandler.instance().getBrandingStrings("")); + if (modController!=null) + { + modController.printModStates(ret); + } return ret.toString(); } @@ -488,15 +453,15 @@ public class Loader for (String dep : DEPENDENCYSPLITTER.split(dependencyString)) { List depparts = Lists.newArrayList(DEPENDENCYPARTSPLITTER.split(dep)); - String instruction = depparts.get(0); - String target = depparts.get(1); - boolean targetIsAll = target.equals("*"); - // If we don't have two parts to each substring, this is an invalid dependency string if (depparts.size() != 2) { parseFailure=true; continue; } + String instruction = depparts.get(0); + String target = depparts.get(1); + boolean targetIsAll = target.equals("*"); + // If we don't have two parts to each substring, this is an invalid dependency string // If this is a required element, add it to the required list if ("required-before".equals(instruction) || "required-after".equals(instruction)) @@ -531,6 +496,7 @@ public class Loader if (parseFailure) { + FMLLog.log(Level.WARNING, "Unable to parse dependency string %s", dependencyString); throw new LoaderException(); } } @@ -539,4 +505,14 @@ public class Loader { return ImmutableMap.copyOf(namedMods); } + + public void initializeMods() + { + // Mod controller should be in the initialization state here + modController.distributeStateMessage(); + modController.transition(LoaderState.POSTINITIALIZATION); + modController.distributeStateMessage(); + modController.transition(LoaderState.LOADCOMPLETE); + FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size()==1 ? "" : "s"); + } } diff --git a/common/cpw/mods/fml/common/LoaderState.java b/common/cpw/mods/fml/common/LoaderState.java index b7e2741024..addfe779fd 100644 --- a/common/cpw/mods/fml/common/LoaderState.java +++ b/common/cpw/mods/fml/common/LoaderState.java @@ -51,7 +51,7 @@ public enum LoaderState { try { - return eventClass.getConstructor(Object[].class).newInstance(eventData); + return eventClass.getConstructor(Object[].class).newInstance((Object)eventData); } catch (Exception e) { diff --git a/common/cpw/mods/fml/common/MetadataCollection.java b/common/cpw/mods/fml/common/MetadataCollection.java index 589a799f2c..34652c7319 100644 --- a/common/cpw/mods/fml/common/MetadataCollection.java +++ b/common/cpw/mods/fml/common/MetadataCollection.java @@ -19,13 +19,17 @@ import com.google.common.collect.Maps; public class MetadataCollection { - private static Logger log = Loader.log; private static JdomParser parser = new JdomParser(); private Map metadatas = Maps.newHashMap(); private int metadataVersion = 1; public static MetadataCollection from(InputStream inputStream) { + if (inputStream == null) + { + return new MetadataCollection(); + } + InputStreamReader reader = new InputStreamReader(inputStream); try { @@ -69,8 +73,17 @@ public class MetadataCollection } } - public ModMetadata getMetadataForId(String modId) + public ModMetadata getMetadataForId(String modId, Map extraData) { + if (!metadatas.containsKey(modId)) + { + ModMetadata dummy = new ModMetadata(); + dummy.modId = modId; + dummy.name = (String) extraData.get("name"); + dummy.version = (String) extraData.get("version"); + dummy.autogenerated = true; + metadatas.put(modId, dummy); + } return metadatas.get(modId); } diff --git a/common/cpw/mods/fml/common/Mod.java b/common/cpw/mods/fml/common/Mod.java index c94a47ae49..5d03b3d65b 100644 --- a/common/cpw/mods/fml/common/Mod.java +++ b/common/cpw/mods/fml/common/Mod.java @@ -18,6 +18,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import net.minecraft.src.ItemBlock; + /** * The new mod style in FML 1.3 * @@ -55,6 +57,46 @@ public @interface Mod */ boolean useMetadata() default false; + /** + * Mark the designated method as being called at the "pre-initialization" phase + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface PreInit {} + /** + * Mark the designated method as being called at the "initialization" phase + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface Init {} + /** + * Mark the designated method as being called at the "post-initialization" phase + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface PostInit {} + /** + * Populate the annotated field with the mod instance. + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Instance {} + /** + * Populate the annotated field with the mod's metadata. + * @author cpw + * + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Metadata {} /** * Populate the annotated field with an instance of the Block as specified * @author cpw @@ -68,16 +110,11 @@ public @interface Mod * @return */ String name(); - /** - * The class (extending Block) that should be created. - * @return - */ - String typeClass(); /** * The associated ItemBlock subtype for the item (can be null for an ItemBlock) * @return */ - String itemTypeClass() default ""; + Class itemTypeClass() default ItemBlock.class; } /** * Populate the annotated field with an Item @@ -98,12 +135,4 @@ public @interface Mod */ String typeClass(); } - /** - * Populate the annotated field with the mod instance. - * @author cpw - * - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - public @interface Instance {} } diff --git a/common/cpw/mods/fml/common/ModClassLoader.java b/common/cpw/mods/fml/common/ModClassLoader.java index 526f639a2c..0842caac55 100644 --- a/common/cpw/mods/fml/common/ModClassLoader.java +++ b/common/cpw/mods/fml/common/ModClassLoader.java @@ -22,6 +22,9 @@ import java.net.URLClassLoader; import java.util.List; import java.util.logging.Level; +import com.google.common.collect.ImmutableList; + +import cpw.mods.fml.common.discovery.ModCandidate; import cpw.mods.fml.relauncher.FMLEmbeddingRelauncher; import cpw.mods.fml.relauncher.RelaunchClassLoader; @@ -34,6 +37,7 @@ import cpw.mods.fml.relauncher.RelaunchClassLoader; */ public class ModClassLoader extends URLClassLoader { + private static final List STANDARD_LIBRARIES = ImmutableList.of("jinput.jar", "lwjgl.jar", "lwjgl_util.jar", "argo-2.25.jar", "asm-all-4.0.jar", "guava-12.0.jar"); private RelaunchClassLoader mainClassLoader; public ModClassLoader(ClassLoader parent) { @@ -66,8 +70,13 @@ public class ModClassLoader extends URLClassLoader } catch (URISyntaxException e) { - Loader.log.log(Level.SEVERE, "Unable to process our input to locate the minecraft code", e); + FMLLog.log.log(Level.SEVERE, "Unable to process our input to locate the minecraft code", e); throw new LoaderException(e); } } + + public List getDefaultLibraries() + { + return STANDARD_LIBRARIES; + } } diff --git a/common/cpw/mods/fml/common/ModContainerFactory.java b/common/cpw/mods/fml/common/ModContainerFactory.java index 9f1623fef1..74a431c836 100644 --- a/common/cpw/mods/fml/common/ModContainerFactory.java +++ b/common/cpw/mods/fml/common/ModContainerFactory.java @@ -1,6 +1,7 @@ package cpw.mods.fml.common; import java.io.File; +import java.util.regex.Pattern; import org.objectweb.asm.Type; @@ -10,22 +11,26 @@ import cpw.mods.fml.common.modloader.ModLoaderModContainer; public class ModContainerFactory { + private static Pattern modClass = Pattern.compile(".*(\\.|)(mod\\_[^\\s$]+)$"); private static ModContainerFactory INSTANCE = new ModContainerFactory(); public static ModContainerFactory instance() { return INSTANCE; } public ModContainer build(ASMModParser modParser, File modSource) { - if (modParser.getASMSuperType().equals(Type.getType("BaseMod"))) + String className = modParser.getASMType().getClassName(); + if (modParser.isBaseMod() && modClass.matcher(className).find()) { - return new ModLoaderModContainer(modParser.getASMType().getClassName(), modSource); + FMLLog.fine("Identified a BaseMod type mod %s", className); + return new ModLoaderModContainer(className, modSource, modParser.getBaseModProperties()); } for (ModAnnotation ann : modParser.getAnnotations()) { if (ann.getASMType().equals(Type.getType(Mod.class))) { - return new FMLModContainer(modParser.getASMType().getClassName(), modSource, ann.getValues()); + FMLLog.fine("Identified a FMLMod type mod %s", className); + return new FMLModContainer(className, modSource, ann.getValues()); } } diff --git a/common/cpw/mods/fml/common/ModMetadata.java b/common/cpw/mods/fml/common/ModMetadata.java index 877950e3a8..b54eee2dd9 100644 --- a/common/cpw/mods/fml/common/ModMetadata.java +++ b/common/cpw/mods/fml/common/ModMetadata.java @@ -89,6 +89,7 @@ public class ModMetadata public List requiredMods = Lists.newArrayList(); public List dependencies = Lists.newArrayList(); public List dependants = Lists.newArrayList(); + public boolean autogenerated; /** * @param mod2 diff --git a/common/cpw/mods/fml/common/discovery/DirectoryDiscoverer.java b/common/cpw/mods/fml/common/discovery/DirectoryDiscoverer.java index f5743f0520..0be9a89788 100644 --- a/common/cpw/mods/fml/common/discovery/DirectoryDiscoverer.java +++ b/common/cpw/mods/fml/common/discovery/DirectoryDiscoverer.java @@ -2,11 +2,22 @@ package cpw.mods.fml.common.discovery; import java.io.File; import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.util.Arrays; import java.util.List; +import java.util.logging.Logger; import java.util.regex.Matcher; +import com.google.common.base.Throwables; +import com.google.common.collect.Lists; + +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.MetadataCollection; import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.ModContainerFactory; +import cpw.mods.fml.common.discovery.asm.ASMModParser; public class DirectoryDiscoverer implements ITypeDiscoverer { @@ -15,19 +26,36 @@ public class DirectoryDiscoverer implements ITypeDiscoverer @Override public boolean accept(File file) { - return (file.isFile() && modClass.matcher(file.getName()).find()) || file.isDirectory(); + return (file.isFile() && classFile.matcher(file.getName()).find()) || file.isDirectory(); } } @Override public List discover(ModCandidate candidate) + { + List found = Lists.newArrayList(); + FMLLog.log.fine("Examining directory %s for potential mods", candidate.getModContainer().getName()); + exploreFileSystem("", candidate.getModContainer(), found, candidate, null); + return found; + } + + public void exploreFileSystem(String path, File modDir, List harvestedMods, ModCandidate candidate, MetadataCollection mc) { if (path.length() == 0) { - dirRoot = modDir; - + File metadata = new File(modDir, "mcmod.info"); + try + { + FileInputStream fis = new FileInputStream(metadata); + mc = MetadataCollection.from(fis); + fis.close(); + } + catch (Exception e) + { + mc = MetadataCollection.from(null); + } } - boolean foundAModClass = false; + File[] content = modDir.listFiles(new ClassFilter()); // Always sort our content @@ -36,22 +64,37 @@ public class DirectoryDiscoverer implements ITypeDiscoverer { if (file.isDirectory()) { - log.finest(String.format("Recursing into package %s", path + file.getName())); - attemptDirLoad(file, path + file.getName() + ".", sourceType, dirRoot); + FMLLog.log.finest("Recursing into package %s", path + file.getName()); + exploreFileSystem(path + file.getName() + ".", file, harvestedMods, candidate, mc); continue; } - Matcher fname = modClass.matcher(file.getName()); - if (!fname.find()) + Matcher match = classFile.matcher(file.getName()); + + if (match.matches()) { - continue; + ASMModParser modParser = null; + try + { + FileInputStream fis = new FileInputStream(file); + modParser = new ASMModParser(fis); + fis.close(); + } + catch (Exception e) + { + Throwables.propagate(e); + } + + modParser.validate(); + ModContainer container = ModContainerFactory.instance().build(modParser, candidate.getModContainer()); + if (container!=null) + { + harvestedMods.add(container); + container.bindMetadata(mc); + } } - String clazzName = path + fname.group(2); - log.fine(String.format("Candidate mod %s found in directory %s", clazzName, dirRoot.getName())); - candidates.add(new ModCandidate(sourceType, dirRoot, dirRoot, clazzName, sourceType)); - foundAModClass = true; + + } - // TODO Auto-generated method stub - return null; } } diff --git a/common/cpw/mods/fml/common/discovery/ITypeDiscoverer.java b/common/cpw/mods/fml/common/discovery/ITypeDiscoverer.java index d548863711..ef1c622588 100644 --- a/common/cpw/mods/fml/common/discovery/ITypeDiscoverer.java +++ b/common/cpw/mods/fml/common/discovery/ITypeDiscoverer.java @@ -8,7 +8,6 @@ import cpw.mods.fml.common.ModContainer; public interface ITypeDiscoverer { public static Pattern classFile = Pattern.compile("([^\\s$]+).class$"); - public static Pattern modClass = Pattern.compile("(.+/|)(mod\\_[^\\s$]+).class$"); public List discover(ModCandidate candidate); } diff --git a/common/cpw/mods/fml/common/discovery/JarDiscoverer.java b/common/cpw/mods/fml/common/discovery/JarDiscoverer.java index 3300d00366..e3d9cc3de2 100644 --- a/common/cpw/mods/fml/common/discovery/JarDiscoverer.java +++ b/common/cpw/mods/fml/common/discovery/JarDiscoverer.java @@ -9,7 +9,7 @@ import java.util.zip.ZipFile; import com.google.common.collect.Lists; -import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.MetadataCollection; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModContainerFactory; @@ -17,12 +17,11 @@ import cpw.mods.fml.common.discovery.asm.ASMModParser; public class JarDiscoverer implements ITypeDiscoverer { - private static Logger log = Loader.log; @Override public List discover(ModCandidate candidate) { List foundMods = Lists.newArrayList(); - log.fine(String.format("Examining file %s for potential mods", candidate.getModContainer().getName())); + FMLLog.log.fine("Examining file %s for potential mods", candidate.getModContainer().getName()); ZipFile jar = null; try { @@ -32,7 +31,7 @@ public class JarDiscoverer implements ITypeDiscoverer MetadataCollection mc = null; if (modInfo != null) { - log.finer(String.format("Located mcmod.info file in file %s", candidate.getModContainer().getName())); + FMLLog.log.finer("Located mcmod.info file in file %s", candidate.getModContainer().getName()); mc = MetadataCollection.from(jar.getInputStream(modInfo)); } for (ZipEntry ze : Collections.list(jar.entries())) @@ -46,24 +45,14 @@ public class JarDiscoverer implements ITypeDiscoverer if (container!=null) { foundMods.add(container); - if (mc!=null) - { - container.bindMetadata(mc); - } + container.bindMetadata(mc); } } - - match = modClass.matcher(ze.getName()); - - if (match.matches()) - { - log.warning(String.format("Candidate mod %s found in mod file %s but is missing mod information", ze.getName().replace("/","."), candidate.getModContainer().getName())); - } } } catch (Exception e) { - log.warning(String.format("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName())); + FMLLog.log.warning("Zip file %s failed to read properly, it will be ignored", candidate.getModContainer().getName()); } finally { diff --git a/common/cpw/mods/fml/common/discovery/ModDiscoverer.java b/common/cpw/mods/fml/common/discovery/ModDiscoverer.java index 343a1e3389..00c7534da7 100644 --- a/common/cpw/mods/fml/common/discovery/ModDiscoverer.java +++ b/common/cpw/mods/fml/common/discovery/ModDiscoverer.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -24,16 +25,16 @@ import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.Opcodes; +import com.google.common.base.Throwables; import com.google.common.collect.Lists; -import cpw.mods.fml.common.Loader; +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.LoaderException; import cpw.mods.fml.common.ModClassLoader; import cpw.mods.fml.common.ModContainer; public class ModDiscoverer { - private Logger log = Loader.log; - private static Pattern zipJar = Pattern.compile("(.+).(zip|jar)$"); private List candidates = Lists.newArrayList(); @@ -43,7 +44,7 @@ public class ModDiscoverer File[] minecraftSources = modClassLoader.getParentSources(); if (minecraftSources.length == 1 && minecraftSources[0].isFile()) { - log.fine(String.format("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath())); + FMLLog.log.fine("Minecraft is a file at %s, loading", minecraftSources[0].getAbsolutePath()); candidates.add(new ModCandidate(minecraftSources[0], minecraftSources[0], ContainerType.JAR)); } else @@ -52,12 +53,19 @@ public class ModDiscoverer { if (minecraftSources[i].isFile()) { - log.fine(String.format("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath())); - candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true)); + if (modClassLoader.getDefaultLibraries().contains(minecraftSources[i].getName())) + { + FMLLog.log.fine("Skipping known library file %s", minecraftSources[i].getAbsolutePath()); + } + else + { + FMLLog.log.fine("Found a minecraft related file at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath()); + candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.JAR, true)); + } } else if (minecraftSources[i].isDirectory()) { - log.fine(String.format("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath())); + FMLLog.log.fine("Found a minecraft related directory at %s, examining for mod candidates", minecraftSources[i].getAbsolutePath()); candidates.add(new ModCandidate(minecraftSources[i], minecraftSources[i], ContainerType.DIR, true)); } } @@ -75,7 +83,7 @@ public class ModDiscoverer { if (modFile.isDirectory()) { - log.fine(String.format("Found a candidate mod directory %s", modFile.getName())); + FMLLog.log.fine("Found a candidate mod directory %s", modFile.getName()); candidates.add(new ModCandidate(modFile, modFile, ContainerType.DIR)); } else @@ -84,12 +92,12 @@ public class ModDiscoverer if (matcher.matches()) { - log.fine(String.format("Found a candidate zip or jar file %s", matcher.group(0))); + FMLLog.log.fine("Found a candidate zip or jar file %s", matcher.group(0)); candidates.add(new ModCandidate(modFile, modFile, ContainerType.JAR)); } else { - log.fine(String.format("Ignoring unknown file %s in mods directory", modFile.getName())); + FMLLog.log.fine("Ignoring unknown file %s in mods directory", modFile.getName()); } } } @@ -101,8 +109,19 @@ public class ModDiscoverer for (ModCandidate candidate : candidates) { - List mods = candidate.explore(); - modList.addAll(mods); + try + { + List mods = candidate.explore(); + modList.addAll(mods); + } + catch (LoaderException le) + { + FMLLog.log(Level.WARNING, le, "Identified a problem with the mod candidate %s, ignoring this source", candidate.getModContainer()); + } + catch (Throwable t) + { + Throwables.propagate(t); + } } return modList; diff --git a/common/cpw/mods/fml/common/discovery/asm/ASMModParser.java b/common/cpw/mods/fml/common/discovery/asm/ASMModParser.java index 6ce727b1aa..7ff5ee44a2 100644 --- a/common/cpw/mods/fml/common/discovery/asm/ASMModParser.java +++ b/common/cpw/mods/fml/common/discovery/asm/ASMModParser.java @@ -110,4 +110,9 @@ public class ASMModParser { this.baseModProperties = foundProperties; } + + public String getBaseModProperties() + { + return this.baseModProperties; + } } diff --git a/common/cpw/mods/fml/common/event/FMLInitializationEvent.java b/common/cpw/mods/fml/common/event/FMLInitializationEvent.java index f48afc9d18..e59692a6de 100644 --- a/common/cpw/mods/fml/common/event/FMLInitializationEvent.java +++ b/common/cpw/mods/fml/common/event/FMLInitializationEvent.java @@ -5,6 +5,11 @@ import cpw.mods.fml.common.LoaderState.ModState; public class FMLInitializationEvent extends FMLStateEvent { + public FMLInitializationEvent(Object... data) + { + super(data); + } + @Override public ModState getModState() { diff --git a/common/cpw/mods/fml/common/event/FMLPostInitializationEvent.java b/common/cpw/mods/fml/common/event/FMLPostInitializationEvent.java index 04f2578ca7..f60fe1f4e0 100644 --- a/common/cpw/mods/fml/common/event/FMLPostInitializationEvent.java +++ b/common/cpw/mods/fml/common/event/FMLPostInitializationEvent.java @@ -4,6 +4,10 @@ import cpw.mods.fml.common.LoaderState.ModState; public class FMLPostInitializationEvent extends FMLStateEvent { + public FMLPostInitializationEvent(Object... data) + { + super(data); + } @Override public ModState getModState() diff --git a/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java b/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java index 53195dacc6..6e1556a4f7 100644 --- a/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java +++ b/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java @@ -6,7 +6,11 @@ import cpw.mods.fml.common.LoaderState.ModState; public class FMLPreInitializationEvent extends FMLStateEvent { - + public FMLPreInitializationEvent(Object... data) + { + super(data); + } + @Override public ModState getModState() { diff --git a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java index 3d6b478e2d..754e6eeebc 100644 --- a/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java +++ b/common/cpw/mods/fml/common/modloader/ModLoaderModContainer.java @@ -32,15 +32,17 @@ import java.util.Properties; import java.util.logging.Level; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.IConsoleHandler; import cpw.mods.fml.common.ICraftingHandler; import cpw.mods.fml.common.IDispenseHandler; import cpw.mods.fml.common.IFMLSidedHandler; -import cpw.mods.fml.common.IKeyHandler; import cpw.mods.fml.common.INetworkHandler; import cpw.mods.fml.common.IPickupNotifier; import cpw.mods.fml.common.IPlayerTracker; @@ -54,7 +56,11 @@ import cpw.mods.fml.common.LoaderState.ModState; import cpw.mods.fml.common.MetadataCollection; import cpw.mods.fml.common.discovery.ContainerType; import cpw.mods.fml.common.event.FMLConstructionEvent; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.registry.TickRegistry; +import cpw.mods.fml.common.registry.WorldRegistry; import cpw.mods.fml.common.ModContainer; import cpw.mods.fml.common.ModMetadata; import cpw.mods.fml.common.ProxyInjector; @@ -63,13 +69,11 @@ import cpw.mods.fml.common.TickType; public class ModLoaderModContainer implements ModContainer { private static final ProxyInjector NULLPROXY = new ProxyInjector("","","",null); - private Class modClazz; public BaseMod mod; private File modSource; - public ArrayList requirements; - public ArrayList dependencies; - public ArrayList dependants; - private ArrayList keyHandlers; + public ArrayList requirements = Lists.newArrayList(); + public ArrayList dependencies = Lists.newArrayList(); + public ArrayList dependants = Lists.newArrayList(); private ContainerType sourceType; private ModMetadata metadata; private ProxyInjector sidedProxy; @@ -79,13 +83,15 @@ public class ModLoaderModContainer implements ModContainer private String modId; private EventBus bus; private LoadController controller; - private boolean enabled; + private boolean enabled = true; + private String sortingProperties; - public ModLoaderModContainer(String className, File modSource) + public ModLoaderModContainer(String className, File modSource, String sortingProperties) { this.modClazzName = className; this.modSource = modSource; - this.modId = className.contains(".") ? className.substring(className.lastIndexOf('.')) : className; + this.modId = className.contains(".") ? className.substring(className.lastIndexOf('.')+1) : className; + this.sortingProperties = sortingProperties; } /** @@ -98,54 +104,15 @@ public class ModLoaderModContainer implements ModContainer this.gameTickHandler = new BaseModTicker(instance, false); this.guiTickHandler = new BaseModTicker(instance, true); } - - @Subscribe - public void constructMod(FMLConstructionEvent event) - { - try - { - ModClassLoader modClassLoader = event.getModClassLoader(); - modClassLoader.addFile(modSource); - mod = (BaseMod)Class.forName(modClazzName, true, modClassLoader).newInstance(); - } - catch (Exception e) - { - controller.errorOccurred(this, e); - Throwables.propagateIfPossible(e); - } - } - - @Subscribe - public void preInit(FMLPreInitializationEvent event) - { - try - { - EnumSet ticks = EnumSet.noneOf(TickType.class); - this.gameTickHandler = new BaseModTicker(ticks, false); - this.guiTickHandler = new BaseModTicker(ticks.clone(), true); - configureMod(); - mod = modClazz.newInstance(); - this.gameTickHandler.setMod(mod); - this.guiTickHandler.setMod(mod); - FMLCommonHandler.instance().registerTickHandler(this.gameTickHandler); - FMLCommonHandler.instance().registerTickHandler(this.guiTickHandler); - FMLCommonHandler.instance().registerWorldGenerator(this.mod); - } - catch (Exception e) - { - throw new LoaderException(e); - } - } /** * */ - private void configureMod() + private void configureMod(Class modClazz) { IFMLSidedHandler sideHandler = FMLCommonHandler.instance().getSidedDelegate(); File configDir = Loader.instance().getConfigDir(); - String modConfigName = modClazz.getSimpleName(); - File modConfig = new File(configDir, String.format("%s.cfg", modConfigName)); + File modConfig = new File(configDir, String.format("%s.cfg", modClazzName)); Properties props = new Properties(); boolean existingConfigFound = false; @@ -155,15 +122,14 @@ public class ModLoaderModContainer implements ModContainer { try { - Loader.log.fine(String.format("Reading existing configuration file for %s : %s", modConfigName, modConfig.getName())); + FMLLog.log.fine("Reading existing configuration file for %s : %s", modClazzName, modConfig.getName()); FileReader configReader = new FileReader(modConfig); props.load(configReader); configReader.close(); } catch (Exception e) { - Loader.log.severe(String.format("Error occured reading mod configuration file %s", modConfig.getName())); - Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + FMLLog.log.log(Level.SEVERE, e, "Error occured reading mod configuration file %s", modConfig.getName()); throw new LoaderException(e); } existingConfigFound = true; @@ -194,19 +160,18 @@ public class ModLoaderModContainer implements ModContainer { defaultValue = f.get(null); propertyValue = props.getProperty(propertyName, extractValue(defaultValue)); - Object currentValue = parseValue(propertyValue, property, f.getType(), propertyName, modConfigName); - Loader.log.finest(String.format("Configuration for %s.%s found values default: %s, configured: %s, interpreted: %s", modConfigName, propertyName, defaultValue, propertyValue, currentValue)); + Object currentValue = parseValue(propertyValue, property, f.getType(), propertyName, modClazzName); + FMLLog.log.finest("Configuration for %s.%s found values default: %s, configured: %s, interpreted: %s", modClazzName, propertyName, defaultValue, propertyValue, currentValue); if (currentValue != null && !currentValue.equals(defaultValue)) { - Loader.log.finest(String.format("Configuration for %s.%s value set to: %s", modConfigName, propertyName, currentValue)); + FMLLog.log.finest("Configuration for %s.%s value set to: %s", modClazzName, propertyName, currentValue); f.set(null, currentValue); } } catch (Exception e) { - Loader.log.severe(String.format("Invalid configuration found for %s in %s", propertyName, modConfig.getName())); - Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + FMLLog.log.log(Level.SEVERE, e, "Invalid configuration found for %s in %s", propertyName, modConfig.getName()); throw new LoaderException(e); } finally @@ -243,22 +208,22 @@ public class ModLoaderModContainer implements ModContainer { if (!mlPropFound && !existingConfigFound) { - Loader.log.fine(String.format("No MLProp configuration for %s found or required. No file written", modConfigName)); + FMLLog.log.fine("No MLProp configuration for %s found or required. No file written", modClazzName); return; } if (!mlPropFound && existingConfigFound) { File mlPropBackup = new File(modConfig.getParent(),modConfig.getName()+".bak"); - Loader.log.fine(String.format("MLProp configuration file for %s found but not required. Attempting to rename file to %s", modConfigName, mlPropBackup.getName())); + FMLLog.log.fine("MLProp configuration file for %s found but not required. Attempting to rename file to %s", modClazzName, mlPropBackup.getName()); boolean renamed = modConfig.renameTo(mlPropBackup); if (renamed) { - Loader.log.fine(String.format("Unused MLProp configuration file for %s renamed successfully to %s", modConfigName, mlPropBackup.getName())); + FMLLog.log.fine("Unused MLProp configuration file for %s renamed successfully to %s", modClazzName, mlPropBackup.getName()); } else { - Loader.log.fine(String.format("Unused MLProp configuration file for %s renamed UNSUCCESSFULLY to %s", modConfigName, mlPropBackup.getName())); + FMLLog.log.fine("Unused MLProp configuration file for %s renamed UNSUCCESSFULLY to %s", modClazzName, mlPropBackup.getName()); } return; @@ -268,12 +233,11 @@ public class ModLoaderModContainer implements ModContainer FileWriter configWriter = new FileWriter(modConfig); props.store(configWriter, comments.toString()); configWriter.close(); - Loader.log.fine(String.format("Configuration for %s written to %s", modConfigName, modConfig.getName())); + FMLLog.log.fine("Configuration for %s written to %s", modClazzName, modConfig.getName()); } catch (IOException e) { - Loader.log.warning(String.format("Error trying to write the config file %s", modConfig.getName())); - Loader.log.throwing("ModLoaderModContainer", "configureMod", e); + FMLLog.log.log(Level.SEVERE, e, "Error trying to write the config file %s", modConfig.getName()); throw new LoaderException(e); } } @@ -324,7 +288,7 @@ public class ModLoaderModContainer implements ModContainer if (n.doubleValue() < property.min() || n.doubleValue() > property.max()) { - Loader.log.warning(String.format("Configuration for %s.%s found value %s outside acceptable range %s,%s", modConfigName,propertyName, n, property.min(), property.max())); + FMLLog.log.warning("Configuration for %s.%s found value %s outside acceptable range %s,%s", modConfigName,propertyName, n, property.min(), property.max()); return null; } else @@ -354,7 +318,7 @@ public class ModLoaderModContainer implements ModContainer @Override public String getName() { - return mod != null ? mod.getName() : modClazz.getSimpleName(); + return mod != null ? mod.getName() : modId; } @Deprecated @@ -366,16 +330,13 @@ public class ModLoaderModContainer implements ModContainer @Override public String getSortingRules() { - if (mod!=null) { - return mod.getPriorities(); - } else { - return ""; - } + return sortingProperties; } + @Override public boolean matches(Object mod) { - return modClazz.isInstance(mod); + return this.mod == mod; } /** @@ -431,30 +392,7 @@ public class ModLoaderModContainer implements ModContainer public String toString() { - return modClazz.getSimpleName(); - } - - /** - * @param keyHandler - * @param allowRepeat - */ - public void addKeyHandler(IKeyHandler handler) - { - if (keyHandlers==null) { - keyHandlers=new ArrayList(); - } - - Iterator itr = keyHandlers.iterator(); - while(itr.hasNext()) - { - IKeyHandler old = itr.next(); - if (old.getKeyBinding() == handler.getKeyBinding()) - { - itr.remove(); - } - } - - keyHandlers.add(handler); + return modId; } @Override @@ -510,7 +448,9 @@ public class ModLoaderModContainer implements ModContainer @Override public void bindMetadata(MetadataCollection mc) { - this.metadata = mc.getMetadataForId(modId); + Map dummyMetadata = ImmutableMap.builder().put("name", modId).put("version", "").build(); + this.metadata = mc.getMetadataForId(modId, dummyMetadata); + Loader.instance().computeDependencies(sortingProperties, getRequirements(), getDependencies(), getDependants()); } @Override @@ -524,7 +464,7 @@ public class ModLoaderModContainer implements ModContainer { if (this.enabled) { - controller.log(Level.FINE, "Enabling mod %s", getModId()); + FMLLog.fine("Enabling mod %s", getModId()); this.bus = bus; this.controller = controller; bus.register(this); @@ -535,4 +475,74 @@ public class ModLoaderModContainer implements ModContainer return false; } } + + // Lifecycle mod events + + @Subscribe + public void constructMod(FMLConstructionEvent event) + { + try + { + ModClassLoader modClassLoader = event.getModClassLoader(); + modClassLoader.addFile(modSource); + Class modClazz = (Class) Class.forName(modClazzName, true, modClassLoader); + configureMod(modClazz); + mod = (BaseMod)modClazz.newInstance(); + } + catch (Exception e) + { + controller.errorOccurred(this, e); + Throwables.propagateIfPossible(e); + } + } + + @Subscribe + public void preInit(FMLPreInitializationEvent event) + { + try + { + EnumSet ticks = EnumSet.noneOf(TickType.class); + this.gameTickHandler = new BaseModTicker(ticks, false); + this.guiTickHandler = new BaseModTicker(ticks.clone(), true); + this.gameTickHandler.setMod(mod); + this.guiTickHandler.setMod(mod); + TickRegistry.registerTickHandler(this.gameTickHandler); + TickRegistry.registerTickHandler(this.guiTickHandler); + WorldRegistry.registerWorldGenerator(this.mod); + } + catch (Exception e) + { + controller.errorOccurred(this, e); + Throwables.propagateIfPossible(e); + } + } + + + @Subscribe + public void init(FMLInitializationEvent event) + { + try + { + mod.load(); + } + catch (Throwable t) + { + controller.errorOccurred(this, t); + Throwables.propagateIfPossible(t); + } + } + + @Subscribe + public void postInit(FMLPostInitializationEvent event) + { + try + { + mod.modsLoaded(); + } + catch (Throwable t) + { + controller.errorOccurred(this, t); + Throwables.propagateIfPossible(t); + } + } } diff --git a/common/cpw/mods/fml/common/registry/FMLRegistry.java b/common/cpw/mods/fml/common/registry/FMLRegistry.java index 47021b7bb0..b535a8fe4e 100644 --- a/common/cpw/mods/fml/common/registry/FMLRegistry.java +++ b/common/cpw/mods/fml/common/registry/FMLRegistry.java @@ -13,6 +13,7 @@ */ package cpw.mods.fml.common.registry; + import net.minecraft.src.BiomeGenBase; import net.minecraft.src.Block; import net.minecraft.src.Entity; diff --git a/common/cpw/mods/fml/common/registry/TickRegistry.java b/common/cpw/mods/fml/common/registry/TickRegistry.java new file mode 100644 index 0000000000..7e710988cf --- /dev/null +++ b/common/cpw/mods/fml/common/registry/TickRegistry.java @@ -0,0 +1,77 @@ +package cpw.mods.fml.common.registry; + +import java.util.List; +import java.util.PriorityQueue; + +import com.google.common.collect.Queues; + +import cpw.mods.fml.common.IScheduledTickHandler; +import cpw.mods.fml.common.ITickHandler; +import cpw.mods.fml.common.SingleIntervalHandler; + +public class TickRegistry +{ + + /** + * We register our delegate here + * @param handler + */ + + public static class TickQueueElement implements Comparable + { + public static long tickCounter = 0; + public TickQueueElement(IScheduledTickHandler ticker) + { + this.ticker = ticker; + update(); + } + @Override + public int compareTo(TickQueueElement o) + { + return (int)(next - o.next); + } + + public void update() + { + next = tickCounter + Math.max(ticker.nextTickSpacing(),1); + } + + private long next; + public IScheduledTickHandler ticker; + + public boolean scheduledNow() + { + return tickCounter >= next; + } + } + + private static PriorityQueue tickHandlers = Queues.newPriorityQueue(); + + public static void registerScheduledTickHandler(IScheduledTickHandler handler) + { + tickHandlers.add(new TickQueueElement(handler)); + } + + public static void registerTickHandler(ITickHandler handler) + { + registerScheduledTickHandler(new SingleIntervalHandler(handler)); + } + + public static void updateTickQueue(List ticks) + { + ticks.clear(); + TickQueueElement.tickCounter++; + while (true) + { + if (tickHandlers.size()==0 || !tickHandlers.peek().scheduledNow()) + { + break; + } + TickRegistry.TickQueueElement tickQueueElement = tickHandlers.poll(); + tickQueueElement.update(); + tickHandlers.offer(tickQueueElement); + ticks.add(tickQueueElement.ticker); + } + } + +} diff --git a/common/cpw/mods/fml/common/registry/WorldRegistry.java b/common/cpw/mods/fml/common/registry/WorldRegistry.java new file mode 100644 index 0000000000..9ca974d490 --- /dev/null +++ b/common/cpw/mods/fml/common/registry/WorldRegistry.java @@ -0,0 +1,33 @@ +package cpw.mods.fml.common.registry; + +import java.util.HashSet; +import java.util.Random; +import java.util.Set; + +import cpw.mods.fml.common.IWorldGenerator; + +public class WorldRegistry +{ + + private static Set worldGenerators = new HashSet(); + + public static void registerWorldGenerator(IWorldGenerator generator) + { + worldGenerators.add(generator); + } + + public static void generateWorld(int chunkX, int chunkZ, long worldSeed, Object... data) + { + Random fmlRandom = new Random(worldSeed); + long xSeed = fmlRandom.nextLong() >> 2 + 1L; + long zSeed = fmlRandom.nextLong() >> 2 + 1L; + fmlRandom.setSeed((xSeed * chunkX + zSeed * chunkZ) ^ worldSeed); + + for (IWorldGenerator generator : worldGenerators) + { + generator.generate(fmlRandom, chunkX, chunkZ, data); + } + + } + +} diff --git a/common/cpw/mods/fml/relauncher/FMLEmbeddingRelauncher.java b/common/cpw/mods/fml/relauncher/FMLEmbeddingRelauncher.java index ef75a5bffa..78b8a13bce 100644 --- a/common/cpw/mods/fml/relauncher/FMLEmbeddingRelauncher.java +++ b/common/cpw/mods/fml/relauncher/FMLEmbeddingRelauncher.java @@ -47,6 +47,8 @@ public class FMLEmbeddingRelauncher // Now we re-inject the home into the "new" minecraft under our control Class client = ReflectionHelper.getClass(clientLoader, "net.minecraft.client.Minecraft"); ReflectionHelper.setPrivateValue(client, null, minecraftHome, "field_6275_Z", "ap", "minecraftDir"); + Class log = ReflectionHelper.getClass(clientLoader, "cpw.mods.fml.common.FMLLog"); + ReflectionHelper.setPrivateValue(log, null, minecraftHome, "minecraftHome"); try { @@ -54,6 +56,7 @@ public class FMLEmbeddingRelauncher } catch (Exception e) { + e.printStackTrace(); // Hmmm } } diff --git a/eclipse/.metadata/.plugins/org.eclipse.debug.core/.launches/FML-Client.launch b/eclipse/.metadata/.plugins/org.eclipse.debug.core/.launches/FML-Client.launch index 679686aa1b..e5ae582ebb 100644 --- a/eclipse/.metadata/.plugins/org.eclipse.debug.core/.launches/FML-Client.launch +++ b/eclipse/.metadata/.plugins/org.eclipse.debug.core/.launches/FML-Client.launch @@ -17,10 +17,12 @@ + + diff --git a/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockBlock.java b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockBlock.java new file mode 100644 index 0000000000..b6b98f3e64 --- /dev/null +++ b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockBlock.java @@ -0,0 +1,12 @@ +package cpw.mods.mockmod; + +import net.minecraft.src.Block; +import net.minecraft.src.Material; + +public class MockBlock extends Block +{ + public MockBlock(int id) + { + super(id,Material.field_1316_v); + } +} diff --git a/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java index c708357be9..f90a5ed0a3 100644 --- a/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java +++ b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java @@ -1,13 +1,38 @@ package cpw.mods.mockmod; -import com.google.common.eventbus.Subscribe; - +import net.minecraft.src.ItemBlock; import cpw.mods.fml.common.Mod; import cpw.mods.fml.common.Mod.Block; +import cpw.mods.fml.common.Mod.Init; +import cpw.mods.fml.common.Mod.Instance; +import cpw.mods.fml.common.Mod.Metadata; +import cpw.mods.fml.common.ModMetadata; -@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependsOn="noone", useMetadata=true) +@Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="before:mod_testMod", useMetadata=true) public class MockMod { - @Block(typeClass="myclass",itemTypeClass="",name="MyBlock") - private Object myBlock; + public class TestItem extends ItemBlock + { + + public TestItem(int id) + { + super(id); + } + + } + + @Instance + public static MockMod myInstance; + + @Metadata + private ModMetadata meta; + + @Block(name="MyBlock", itemTypeClass=TestItem.class) + private MockBlock myBlock; + + @Init + public void init() + { + System.out.printf("Hello from mockmod init : %s %s\n", myInstance, meta); + } } diff --git a/eclipse/simpletestmod/src/net/minecraft/src/mod_testMod.java b/eclipse/simpletestmod/src/net/minecraft/src/mod_testMod.java index d2189d3826..2b2a1b9941 100644 --- a/eclipse/simpletestmod/src/net/minecraft/src/mod_testMod.java +++ b/eclipse/simpletestmod/src/net/minecraft/src/mod_testMod.java @@ -6,6 +6,7 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.IScheduledTickHandler; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; +import cpw.mods.fml.common.registry.TickRegistry; import net.minecraft.client.Minecraft; public class mod_testMod extends BaseMod { @@ -17,7 +18,8 @@ public class mod_testMod extends BaseMod { @Override public void load() { - ModLoader.setInGameHook(this, true, false); +// if (1==1) throw new RuntimeException(); +// ModLoader.setInGameHook(this, true, false); // ModLoader.setInGUIHook(this, true, false); // FMLCommonHandler.instance().registerTickHandler(this); TickTester t1 = new TickTester(); @@ -26,9 +28,9 @@ public class mod_testMod extends BaseMod { t2.interval=2; TickTester t3 = new TickTester(); t3.interval=3; - FMLCommonHandler.instance().registerScheduledTickHandler(t1); - FMLCommonHandler.instance().registerScheduledTickHandler(t2); - FMLCommonHandler.instance().registerScheduledTickHandler(t3); + TickRegistry.registerScheduledTickHandler(t1); + TickRegistry.registerScheduledTickHandler(t2); + TickRegistry.registerScheduledTickHandler(t3); } @Override @@ -94,6 +96,6 @@ public class mod_testMod extends BaseMod { @Override public String getPriorities() { - return "TESTString"; + return "after:MockMod"; } } \ No newline at end of file