mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
A bunch more fixes for FML mods
This commit is contained in:
1 parent
3f803653c4
commit
ae2039c65d
37 files changed
+1050
-788
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
@@ -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="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento exportedEntriesOnly="false" project="FML-Client"/> </runtimeClasspathEntry> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="simpletestmod" type="1"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="FML-Client" type="1"/> "/>
|
||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry path="3" projectName="FML-MockMod" type="1"/> "/>
|
||||
</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";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user