A bunch more fixes for FML mods

This commit is contained in:
Christian committed 2012-07-23 16:33:17 -02:30
1 parent 3f803653c4
commit ae2039c65d
37 files changed
+1050 -788

No files matched your search

+108 -219
View File
@@ -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<String, ArrayList<OverrideInfo>> overrideInfo = new HashMap<String, ArrayList<OverrideInfo>>();
private HashMap<Integer, BlockRenderInfo> blockModelIds = new HashMap<Integer, BlockRenderInfo>();
private HashMap<KeyBinding, ModContainer> keyBindings = new HashMap<KeyBinding, ModContainer>();
private List<IKeyHandler> keyHandlers = new ArrayList<IKeyHandler>();
private HashSet<OverrideInfo> animationSet = new HashSet<OverrideInfo>();
private List<TextureFX> addedTextureFX = new ArrayList<TextureFX>();
@@ -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<String,Object> dummyOptifineMeta = ImmutableMap.<String,Object>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<IKeyHandler> 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<? extends BaseMod> bmClazz = (Class<? extends BaseMod>) 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<JsonNode> 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<JsonNode> authors=modinfo.getArrayNode("authors");
StringBuilder sb=new StringBuilder();
for (int i=0; i<authors.size(); i++) {
meta.authorList.add(((JsonNode)authors.get(i)).getText());
}
meta.logoFile=modinfo.getStringValue("logoFile");
meta.url=modinfo.getStringValue("url");
meta.updateUrl=modinfo.getStringValue("updateUrl");
meta.parent=modinfo.getStringValue("parent");
List<JsonNode> screenshots=modinfo.getArrayNode("screenshots");
meta.screenshots=new String[screenshots.size()];
for (int i=0; i<screenshots.size(); i++) {
meta.screenshots[i]=((JsonNode)screenshots.get(i)).getText();
}
} catch (Exception e) {
FMLCommonHandler.instance().getFMLLogger().log(Level.FINE, String.format("An error occured reading the info file for %s",mod.getName()), e);
if (Item.class.getPackage() != null) //Print the error if we are in MCP so mod devs see it
{
System.out.println(String.format("An error occured reading the info file for %s",mod.getName()));
e.printStackTrace();
}
}
return meta;
}
public void pruneOldTextureFX(TexturePackBase var1, List<TextureFX> effects)
{
ListIterator<TextureFX> 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;
}
+1 -1
View File
@@ -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())
{
@@ -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<TickType> type, boolean end, boolean repeats)
{
if (!end)
{
modContainer.keyBindEvent(keyBinding);
return;
}
lastState = state;
}
@Override
public void tickStart(EnumSet<TickType> type, Object... tickData)
{
// NO-OP for ML
}
@Override
public void tickEnd(EnumSet<TickType> 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<TickType> 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;
}
}
@@ -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;
}
}
+4 -3
View File
@@ -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;
@@ -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<TickType> type, Object... tickData)
{
keyTick(type, false);
}
@Override
public final void tickEnd(EnumSet<TickType> type, Object... tickData)
{
keyTick(type, true);
}
private void keyTick(EnumSet<TickType> 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<TickType> types, boolean tickEnd, boolean isRepeat);
public abstract void keyUp(EnumSet<TickType> types, boolean tickEnd);
}
private static List<KeyHandler> keyHandlers = Lists.newArrayList();
public static void registerKeyBinding(KeyHandler handler) {
keyHandlers.add(handler);
}
public static void uploadKeyBindingsToGame(GameSettings settings)
{
ArrayList<KeyBinding> 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();
}
}
+1 -1
View File
@@ -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);
}
/**
+14 -123
View File
@@ -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<String,Properties> modLanguageData=new HashMap<String,Properties>();
private PriorityQueue<TickQueueElement> tickHandlers = new PriorityQueue<TickQueueElement>();
private List<IScheduledTickHandler> scheduledTicks = new ArrayList<IScheduledTickHandler>();
private Set<IWorldGenerator> worldGenerators = new HashSet<IWorldGenerator>();
/**
* We register our delegate here
* @param handler
*/
private static class TickQueueElement implements Comparable<TickQueueElement>
{
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<TickType> ticks, Object ... data)
@@ -190,18 +144,6 @@ public class FMLCommonHandler
sidedDelegate.profileEnd();
}
public List<IKeyHandler> gatherKeyBindings() {
List<IKeyHandler> allKeys=new ArrayList<IKeyHandler>();
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));
}
}
+109
View File
@@ -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;
}
}
+127 -5
View File
@@ -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<String, Object> descriptor;
private boolean enabled;
private boolean enabled = true;
private List<String> requirements;
private List<String> dependencies;
private List<String> dependants;
private boolean overridesMetadata;
private EventBus eventBus;
private LoadController controller;
private Multimap<Class<? extends Annotation>, Object> annotations;
public FMLModContainer(String className, File modSource, Map<String,Object> 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<Class<? extends Annotation>, Object> gatherAnnotations(Class<?> clazz) throws Exception
{
Multimap<Class<? extends Annotation>,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);
}
}
}
@@ -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);
@@ -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();
}
+26 -24
View File
@@ -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<String,EventBus> eventChannels;
private LoaderState state;
private Multimap<String, ModState> modStates = HashMultimap.create();
private Multimap<ModContainer, Throwable> errors = HashMultimap.create();
private Logger log;
private Multimap<String, ModState> modStates = ArrayListMultimap.create();
private Multimap<String, Throwable> errors = ArrayListMultimap.create();
private Map<String, ModContainer> 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<String, EventBus> 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<String, Throwable> 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<String,EventBus> 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)
+61 -85
View File
@@ -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<String, String> 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<String, String> 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<String, Boolean> isEnabled = Maps.transformValues(modStates, new Function<String, Boolean>()
{
@@ -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<String> 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");
}
}
+1 -1
View File
@@ -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)
{
@@ -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<String, ModMetadata> 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<String, Object> 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);
}
+43 -14
View File
@@ -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 {}
}
+10 -1
View File
@@ -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<String> 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<String> getDefaultLibraries()
{
return STANDARD_LIBRARIES;
}
}
@@ -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());
}
}
@@ -89,6 +89,7 @@ public class ModMetadata
public List<String> requiredMods = Lists.newArrayList();
public List<String> dependencies = Lists.newArrayList();
public List<String> dependants = Lists.newArrayList();
public boolean autogenerated;
/**
* @param mod2
@@ -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<ModContainer> discover(ModCandidate candidate)
{
List<ModContainer> 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<ModContainer> 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;
}
}
@@ -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<ModContainer> discover(ModCandidate candidate);
}
@@ -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<ModContainer> discover(ModCandidate candidate)
{
List<ModContainer> 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
{
@@ -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<ModCandidate> 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<ModContainer> mods = candidate.explore();
modList.addAll(mods);
try
{
List<ModContainer> 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;
@@ -110,4 +110,9 @@ public class ASMModParser
{
this.baseModProperties = foundProperties;
}
public String getBaseModProperties()
{
return this.baseModProperties;
}
}
@@ -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()
{
@@ -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()
@@ -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()
{
@@ -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 <? extends BaseMod > modClazz;
public BaseMod mod;
private File modSource;
public ArrayList<String> requirements;
public ArrayList<String> dependencies;
public ArrayList<String> dependants;
private ArrayList<IKeyHandler> keyHandlers;
public ArrayList<String> requirements = Lists.newArrayList();
public ArrayList<String> dependencies = Lists.newArrayList();
public ArrayList<String> 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<TickType> 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<? extends BaseMod> 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<IKeyHandler>();
}
Iterator<IKeyHandler> 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<String, Object> dummyMetadata = ImmutableMap.<String,Object>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<? extends BaseMod> modClazz = (Class<? extends BaseMod>) 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<TickType> 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);
}
}
}
@@ -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;
@@ -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<TickQueueElement>
{
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<TickQueueElement> 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<IScheduledTickHandler> 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);
}
}
}
@@ -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<IWorldGenerator> worldGenerators = new HashSet<IWorldGenerator>();
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);
}
}
}
@@ -47,6 +47,8 @@ public class FMLEmbeddingRelauncher
// Now we re-inject the home into the "new" minecraft under our control
Class<? super Object> client = ReflectionHelper.getClass(clientLoader, "net.minecraft.client.Minecraft");
ReflectionHelper.setPrivateValue(client, null, minecraftHome, "field_6275_Z", "ap", "minecraftDir");
Class<? super Object> 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
}
}
@@ -17,10 +17,12 @@
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry id=&quot;org.eclipse.jdt.launching.classpathentry.defaultClasspath&quot;&gt;&#10;&lt;memento exportedEntriesOnly=&quot;false&quot; project=&quot;FML-Client&quot;/&gt;&#10;&lt;/runtimeClasspathEntry&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;simpletestmod&quot; type=&quot;1&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;FML-Client&quot; type=&quot;1&quot;/&gt;&#10;"/>
<listEntry value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#10;&lt;runtimeClasspathEntry path=&quot;3&quot; projectName=&quot;FML-MockMod&quot; type=&quot;1&quot;/&gt;&#10;"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="Start"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="FML-Client"/>
<booleanAttribute key="org.eclipse.jdt.launching.STOP_IN_MAIN" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xincgc -Xmx1024M -Xms1024M"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc:FML-Client/jars}"/>
<booleanAttribute key="org.eclipse.tptp.platform.jvmti.client.ATTR_EXEC_AUTO_POLLING" value="true"/>
@@ -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);
}
}
@@ -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);
}
}
@@ -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";
}
}