Compare commits

...
41 Commits
Author SHA1 Message Date
mezz 9274e4fe43 Fix log4j configuration 2017-06-07 22:15:18 -07:00
LexManos c6aa04325e Fix dispensers equipping armor on players in the wrong slot Closes #1649 2015-12-09 21:03:02 -08:00
cpw 6243d2ca4c Merge pull request #2192 from MinecraftModArchive/1.7.10
Fuel Handling Fix
2015-11-15 17:28:54 -05:00
Scott Killen d159876385 Add an event hook to allow overriding of fuels recognized by vanilla fuel handling. 2015-11-15 17:12:52 -05:00
Lex Manos 8edca3ed86 Fixed skulls not placing on fences like vanilla {Vanilla is buggy -.-} Closes #2185 2015-11-13 15:17:50 -08:00
cpw aa8eaf2b28 Fix firing the remap event. It always fires now, and additionally fires when the registry reverts to frozen.
Most mods refer to the gameregistry for ids they care about, so this shouldn't affect anything significantly,
but if your mod was dependent on their being content in the remap event, and only acting on that content,
empty content means it's "reverted to frozen" state - the state at the start of the game.
2015-11-10 16:40:27 -05:00
cpw c474da04b3 Two more corner cases in the oredictionary. Should work for all cases now. 2015-11-09 15:20:53 -05:00
cpw a92f2a263b OreDictionary will warn if there's an invalid ore being registered now, rather than just
using -1 and doing weird things with the list as a result.
2015-10-29 12:46:12 -04:00
cpw 945d3887d2 Fix substitutions for recipes and oredict recipes. Should mean that substitutions start working properly. 2015-10-29 08:46:23 -04:00
LexManos 605457deec Merge pull request #2103 from olee/patch-1
Fix possible crash in EventBus
2015-09-27 14:41:29 -07:00
Björn Zeutzheim ac5c7124de Fix possible crash in EventBus
There is currently no way to check if an event handler has been registered or not.
But when trying to unregister a not-registered event handler, Minecraft crashes with a NullPointerException.
This is a simple fix to prevent such crashes.
2015-08-31 03:39:33 +09:00
cpw c308a47124 Cherry pick some changes from 1.8 for inner class discovery, also fix the negativecache. Closes #1872 2015-07-18 12:47:31 -04:00
cpw 0f456b4684 Be a little bit more helpful when the ObjectHolder misses. Should help figure out what is going in in #2006 2015-07-09 17:05:20 -04:00
cpw 8636eb1883 Wake up the FluidRegistry before any mods start loading. Should stop mods claiming to own water or lava (depending on who accessed
FluidRegistry first)
2015-07-09 16:53:31 -04:00
cpw 50677ad87a Actually rebuild the fluidNames each rebuild, don't just try and force changes in. Should fix #1973 2015-07-09 16:40:51 -04:00
cpw 204cb16bc4 ObjectHolder works great, but it should be a lot less spammy about failed lookups. They're usually mod options. 2015-06-25 14:41:45 -04:00
cpw 2c24c7618a Mods that are extracted to the mods dir by unzipping or whatever will now cause the game to crash. Too much info is in the META-INF now,
and more will be being added. Extracting to the mods dir just completely breaks that.
2015-06-20 14:47:55 -04:00
Lex Manos 7041fbc27e Time each bar in the loading screen and print it to the log, useful information to see where most time is spent in loading. 2015-06-18 22:18:27 -07:00
Lex Manos e519278888 Add TextureManager to loading screen. 2015-06-18 22:17:21 -07:00
Lex Manos 4235ca36ea Make TextureMap for items and blocks skip the first pass of loading/stitching textures.
Should decrease loading times for large packs.
May cause issues with some mods so use -Dfml.skipFirstTextureLoad=false to disable.
2015-06-18 20:13:31 -07:00
Lex Manos 6527792d06 Add the stitching allocation stage to loading screen. 2015-06-18 20:13:17 -07:00
Lex Manos 716dfdae47 Create config folder in SplashProgress if it does not exist. 2015-06-18 20:11:23 -07:00
Lex Manos e7724c13cc Fixed Wavefront Object Importer reading files with integer values. Closes #1651, #1654 2015-06-17 15:48:22 -07:00
Lex Manos c50adf2433 Include the thread state in the potential error handleing for SplashProgress. 2015-06-16 15:26:00 -07:00
Lex Manos 64263a9f8e Throw more descriptive errors when mods attempt to register invalid global entity IDs. 2015-06-14 17:06:00 -07:00
Lex Manos b3a1548cfa Cleanup mod state dump to be easier to read by displaying the states in abreviation and placing them before the mod info. 2015-06-09 23:06:06 -07:00
Lex Manos b94c2799ab Cleanup mod signature data table. Easily seperating those mods with signatures vs those with none. 2015-06-09 22:25:13 -07:00
Lex Manos d4f6e9e419 Quiet CrashReport class pre-loading debug, no flag to re-enable. 2015-06-09 21:37:33 -07:00
Lex Manos 847c0246cd Quiet FMLControlledNamespacedRegistry debug spam by default. Reenable using -Dfml.debugRegistryEntries=true. 2015-06-09 21:33:52 -07:00
Lex Manos b985384fab Quiet ClassPatchManager debug spam by default. Reenable using -Dfml.debugClassPatchManager=true. 2015-06-09 21:31:18 -07:00
Lex Manos 851f9c1da6 Cleanup some spammy output. 2015-06-09 21:20:53 -07:00
Lex Manos 9ef7b13442 Bump version for new RB. 2015-06-09 15:06:42 -07:00
cpw 63f2300794 Fix up the client/server fluid race condition that could cause the game to bail when an SSP game connects.
There's still a teeny gap, but it's MUCH less prominent than it was before.
2015-06-03 19:26:53 -04:00
cpw f8cb411df1 So we can't print a lot of unicode in the splash screen, so restrict to a hard subset we know we CAN print, closes #1910 2015-06-02 07:24:26 -04:00
Lex Manos e6eeb03108 Finish loading screen before going fullscreen. Closes MinecraftForge/FML#662
(cherry picked from commit 19d7e16fa6)

Conflicts:
	fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch
2015-06-01 17:15:06 -04:00
Lex Manos f088b1b460 Attempt to disable the new splash screen if there are errors detected finishing up. Print a slightly more helpful error message.
(cherry picked from commit e3211eec04)

Conflicts:
	fml/src/main/java/cpw/mods/fml/client/SplashProgress.java
2015-06-01 17:09:28 -04:00
cpw bd6630810f Add in an ItemStackHolder - a way to inject ItemStacks without having to have complex lookup code everywhere.
Example: https://gist.github.com/cpw/9af398451a20459ac263
2015-05-30 14:07:54 -04:00
cpw 06398fa259 Clean up transformers a bit. Can't use COMPUTE_FRAMES even though it's required - the game refuses to even
run if I do. Note for j8: when we force Java8 classes, all coremods will need a thorough overhaul - the
current way we do things is not sustainable when Java8 becomes the universal norm.
2015-05-17 10:35:56 -04:00
cpw 3bbf5c04a6 Strip control codes in progress bar messages. They cause crashes sometimes. 2015-05-17 10:15:44 -04:00
cpw 686db5e5eb Hardcode the FML version in-game as a specific value. 2015-05-16 13:43:35 -04:00
cpw 5fe653cf82 Attempt to fix the slow loading problem. Instead of forcing the main thread to wait around
on every call to processWindowMessages, we will simply skip it, if the mutex is already
claimed by the display thread. This should fix slow loading issues seen by some with
the new loading screen.
2015-05-16 12:55:15 -04:00
52 changed files with 899 additions and 149 deletions

No files matched your search

+1 -1
View File
@@ -8,7 +8,7 @@
"assets": "1.7.10",
"libraries": [
{
"name": "net.minecraft:launchwrapper:1.11"
"name": "net.minecraft:launchwrapper:1.12"
},
{
"name": "com.google.code.findbugs:jsr305:1.3.9",
+1 -1
View File
@@ -27,7 +27,7 @@
"url": "http://files.minecraftforge.net/maven/"
},
{
"name": "net.minecraft:launchwrapper:1.11",
"name": "net.minecraft:launchwrapper:1.12",
"serverreq":true
},
{
@@ -64,7 +64,7 @@
this.field_110451_am.func_110542_a(this.field_71464_q);
this.field_110451_am.func_110542_a(new GrassColorReloadListener());
this.field_110451_am.func_110542_a(new FoliageColorReloadListener());
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar= cpw.mods.fml.common.ProgressManager.push("Rendering Setup", 9);
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar= cpw.mods.fml.common.ProgressManager.push("Rendering Setup", 9, true);
+ bar.step("Loading Render Manager");
RenderManager.field_78727_a.field_78721_f = new ItemRenderer(this);
+ bar.step("Loading Entity Renderer");
@@ -79,21 +79,23 @@
this.field_71417_B = new MouseHelper();
this.func_71361_d("Pre startup");
GL11.glEnable(GL11.GL_TEXTURE_2D);
@@ -524,27 +535,35 @@
@@ -524,30 +535,39 @@
GL11.glLoadIdentity();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
this.func_71361_d("Startup");
+ bar.step("Render Global instance");
this.field_71438_f = new RenderGlobal(this);
- this.field_147128_au = new TextureMap(0, "textures/blocks");
+ bar.step("Building Blocks Texture");
this.field_147128_au = new TextureMap(0, "textures/blocks");
+ this.field_147128_au = new TextureMap(0, "textures/blocks", true);
+ bar.step("Anisotropy and Mipmaps");
this.field_147128_au.func_147632_b(this.field_71474_y.field_151443_J);
this.field_147128_au.func_147633_a(this.field_71474_y.field_151442_I);
+ bar.step("Loading Blocks Texture");
this.field_71446_o.func_130088_a(TextureMap.field_110575_b, this.field_147128_au);
- this.field_71446_o.func_130088_a(TextureMap.field_110576_c, new TextureMap(1, "textures/items"));
+ bar.step("Loading Items Texture");
this.field_71446_o.func_130088_a(TextureMap.field_110576_c, new TextureMap(1, "textures/items"));
+ this.field_71446_o.func_130088_a(TextureMap.field_110576_c, new TextureMap(1, "textures/items", true));
+ bar.step("Viewport");
GL11.glViewport(0, 0, this.field_71443_c, this.field_71440_d);
this.field_71452_i = new EffectRenderer(this.field_71441_e, this.field_71446_o);
@@ -117,14 +119,10 @@
this.field_152354_ay = null;
this.field_71461_s = new LoadingScreenRenderer(this);
@@ -553,6 +572,7 @@
this.func_71352_k();
}
+ FMLClientHandler.instance().onInitializationComplete();
try
if (this.field_71474_y.field_74353_u && !this.field_71431_Q)
{
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
this.func_71352_k();
@@ -970,9 +990,11 @@
if (!this.field_71454_w)
@@ -0,0 +1,26 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/texture/Stitcher.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/texture/Stitcher.java
@@ -60,6 +60,7 @@
public void func_94305_f()
{
Stitcher.Holder[] aholder = (Stitcher.Holder[])this.field_94319_a.toArray(new Stitcher.Holder[this.field_94319_a.size()]);
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Texture stitching", aholder.length);
Arrays.sort(aholder);
Stitcher.Holder[] aholder1 = aholder;
int i = aholder.length;
@@ -67,6 +68,7 @@
for (int j = 0; j < i; ++j)
{
Stitcher.Holder holder = aholder1[j];
+ bar.step(holder.func_98150_a().func_94215_i());
if (!this.func_94310_b(holder))
{
@@ -80,6 +82,7 @@
this.field_94318_c = MathHelper.func_151236_b(this.field_94318_c);
this.field_94315_d = MathHelper.func_151236_b(this.field_94315_d);
}
+ cpw.mods.fml.common.ProgressManager.pop(bar);
}
public List func_94309_g()
@@ -0,0 +1,18 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureManager.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureManager.java
@@ -162,12 +162,15 @@
public void func_110549_a(IResourceManager p_110549_1_)
{
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Reloading Texture Manager", this.field_110585_a.keySet().size(), true);
Iterator iterator = this.field_110585_a.entrySet().iterator();
while (iterator.hasNext())
{
Entry entry = (Entry)iterator.next();
+ bar.step(entry.getKey().toString());
this.func_110579_a((ResourceLocation)entry.getKey(), (ITextureObject)entry.getValue());
}
+ cpw.mods.fml.common.ProgressManager.pop(bar);
}
}
@@ -1,14 +1,44 @@
--- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureMap.java
+++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureMap.java
@@ -96,6 +96,7 @@
@@ -35,6 +35,7 @@
@SideOnly(Side.CLIENT)
public class TextureMap extends AbstractTexture implements ITickableTextureObject, IIconRegister
{
+ private static final boolean ENABLE_SKIP = Boolean.parseBoolean(System.getProperty("fml.skipFirstTextureLoad", "true"));
private static final Logger field_147635_d = LogManager.getLogger();
public static final ResourceLocation field_110575_b = new ResourceLocation("textures/atlas/blocks.png");
public static final ResourceLocation field_110576_c = new ResourceLocation("textures/atlas/items.png");
@@ -47,12 +48,18 @@
private int field_147637_k = 1;
private final TextureAtlasSprite field_94249_f = new TextureAtlasSprite("missingno");
private static final String __OBFID = "CL_00001058";
+ private boolean skipFirst = false;
public TextureMap(int p_i1281_1_, String p_i1281_2_)
{
+ this(p_i1281_1_, p_i1281_2_, false);
+ }
+ public TextureMap(int p_i1281_1_, String p_i1281_2_, boolean skipFirst)
+ {
this.field_94255_a = p_i1281_1_;
this.field_94254_c = p_i1281_2_;
this.func_110573_f();
+ this.skipFirst = skipFirst && ENABLE_SKIP;
}
private void func_110569_e()
@@ -96,15 +103,17 @@
this.field_94252_e.clear();
this.field_94258_i.clear();
int j = Integer.MAX_VALUE;
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Texture stitching", this.field_110574_e.size());
+ cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Texture Loading", skipFirst ? 0 : this.field_110574_e.size());
Iterator iterator = this.field_110574_e.entrySet().iterator();
TextureAtlasSprite textureatlassprite;
@@ -105,6 +106,7 @@
- while (iterator.hasNext())
+ while (!skipFirst && iterator.hasNext())
{
Entry entry = (Entry)iterator.next();
ResourceLocation resourcelocation = new ResourceLocation((String)entry.getKey());
textureatlassprite = (TextureAtlasSprite)entry.getValue();
ResourceLocation resourcelocation1 = this.func_147634_a(resourcelocation, 0);
@@ -16,7 +46,7 @@
try
{
@@ -156,12 +158,14 @@
@@ -156,12 +165,14 @@
}
catch (RuntimeException runtimeexception)
{
@@ -33,7 +63,7 @@
continue;
}
@@ -169,6 +173,7 @@
@@ -169,6 +180,7 @@
stitcher.func_110934_a(textureatlassprite);
}
@@ -41,24 +71,26 @@
int i1 = MathHelper.func_151239_c(j);
if (i1 < this.field_147636_j)
@@ -178,10 +183,12 @@
@@ -178,10 +190,12 @@
}
Iterator iterator1 = this.field_110574_e.values().iterator();
+ bar = cpw.mods.fml.common.ProgressManager.push("Mipmap generation", this.field_110574_e.size());
+ bar = cpw.mods.fml.common.ProgressManager.push("Mipmap generation", skipFirst ? 0 : this.field_110574_e.size());
while (iterator1.hasNext())
- while (iterator1.hasNext())
+ while (!skipFirst && iterator1.hasNext())
{
final TextureAtlasSprite textureatlassprite1 = (TextureAtlasSprite)iterator1.next();
+ bar.step(textureatlassprite1.func_94215_i());
try
{
@@ -222,9 +229,12 @@
@@ -222,9 +236,13 @@
this.field_94249_f.func_147963_d(this.field_147636_j);
stitcher.func_110934_a(this.field_94249_f);
+ cpw.mods.fml.common.ProgressManager.pop(bar);
+ skipFirst = false;
+ bar = cpw.mods.fml.common.ProgressManager.push("Texture creation", 3);
try
@@ -67,7 +99,7 @@
stitcher.func_94305_f();
}
catch (StitcherException stitcherexception)
@@ -233,10 +243,12 @@
@@ -233,10 +251,12 @@
}
field_147635_d.info("Created: {}x{} {}-atlas", new Object[] {Integer.valueOf(stitcher.func_110935_a()), Integer.valueOf(stitcher.func_110936_b()), this.field_94254_c});
@@ -80,7 +112,7 @@
while (iterator2.hasNext())
{
textureatlassprite = (TextureAtlasSprite)iterator2.next();
@@ -274,6 +286,7 @@
@@ -274,6 +294,7 @@
textureatlassprite = (TextureAtlasSprite)iterator2.next();
textureatlassprite.func_94217_a(this.field_94249_f);
}
@@ -4,7 +4,7 @@
public void func_110541_a(List p_110541_1_)
{
this.func_110543_a();
+ cpw.mods.fml.common.ProgressManager.ProgressBar resReload = cpw.mods.fml.common.ProgressManager.push("Loading Resources", p_110541_1_.size()+1);
+ cpw.mods.fml.common.ProgressManager.ProgressBar resReload = cpw.mods.fml.common.ProgressManager.push("Loading Resources", p_110541_1_.size()+1, true);
field_147967_a.info("Reloading ResourceManager: " + field_130074_a.join(Iterables.transform(p_110541_1_, new Function()
{
private static final String __OBFID = "CL_00001092";
@@ -58,6 +58,7 @@ import net.minecraft.network.NetworkManager;
import net.minecraft.network.ServerStatusResponse;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.StringUtils;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.storage.SaveFormatOld;
@@ -68,6 +69,7 @@ import org.lwjgl.LWJGLUtil;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.Display;
import com.google.common.base.CharMatcher;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.BiMap;
@@ -1003,9 +1005,19 @@ public class FMLClientHandler implements IFMLSidedHandler
public void processWindowMessages()
{
// workaround for windows requiring messages being processed on the main thread
if(LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_WINDOWS)
{
Display.processMessages();
}
if (LWJGLUtil.getPlatform() != LWJGLUtil.PLATFORM_WINDOWS) return;
// If we can't grab the mutex, the update call is blocked, probably in native code, just skip it and carry on
// We'll get another go next time
if (!SplashProgress.mutex.tryAcquire()) return;
Display.processMessages();
SplashProgress.mutex.release();
}
// From FontRenderer.renderCharAtPos
private static final String ALLOWED_CHARS = "\u00c0\u00c1\u00c2\u00c8\u00ca\u00cb\u00cd\u00d3\u00d4\u00d5\u00da\u00df\u00e3\u00f5\u011f\u0130\u0131\u0152\u0153\u015e\u015f\u0174\u0175\u017e\u0207\u0000\u0000\u0000\u0000\u0000\u0000\u0000 !\"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\u0000\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f8\u00a3\u00d8\u00d7\u0192\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u00ae\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb\u2591\u2592\u2593\u2502\u2524\u2561\u2562\u2556\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510\u2514\u2534\u252c\u251c\u2500\u253c\u255e\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567\u2568\u2564\u2565\u2559\u2558\u2552\u2553\u256b\u256a\u2518\u250c\u2588\u2584\u258c\u2590\u2580\u03b1\u03b2\u0393\u03c0\u03a3\u03c3\u03bc\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u2205\u2208\u2229\u2261\u00b1\u2265\u2264\u2320\u2321\u00f7\u2248\u00b0\u2219\u00b7\u221a\u207f\u00b2\u25a0\u0000";
@Override
public String stripSpecialChars(String message)
{
// We can't handle many unicode points in the splash renderer
return CharMatcher.anyOf(ALLOWED_CHARS).retainFrom(StringUtils.stripControlCodes(message));
}
}
@@ -9,10 +9,13 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.lang.Thread.UncaughtExceptionHandler;
import java.nio.IntBuffer;
import java.util.Iterator;
import java.util.Properties;
import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -40,6 +43,7 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.SharedDrawable;
import org.lwjgl.util.glu.GLU;
import cpw.mods.fml.common.EnhancedRuntimeException;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ICrashCallable;
@@ -81,6 +85,7 @@ public class SplashProgress
private static int barBorderColor;
private static int barColor;
private static int barBackgroundColor;
static final Semaphore mutex = new Semaphore(1);
private static String getString(String name, String def)
{
@@ -174,7 +179,12 @@ public class SplashProgress
return "GL info";
}
});
CrashReport report = CrashReport.makeCrashReport(new Throwable(), "Loading screen debug info");
CrashReport report = CrashReport.makeCrashReport(new Throwable()
{
@Override public String getMessage(){ return "This is just a prompt for computer specs to be printed. THIS IS NOT A ERROR"; }
@Override public void printStackTrace(final PrintWriter s){ s.println(getMessage()); }
@Override public void printStackTrace(final PrintStream s) { s.println(getMessage()); }
}, "Loading screen debug info");
System.out.println(report.getCompleteReport());
try
@@ -270,8 +280,8 @@ public class SplashProgress
// forge logo
setColor(backgroundColor);
float fw = (float)forgeTexture.getWidth() / 2;
float fh = (float)forgeTexture.getHeight() / 2;
float fw = (float)forgeTexture.getWidth() / 2 / 2;
float fh = (float)forgeTexture.getHeight() / 2 / 2;
if(rotate)
{
float sh = Math.max(fw, fh);
@@ -297,7 +307,16 @@ public class SplashProgress
glEnd();
glDisable(GL_TEXTURE_2D);
// We use mutex to indicate safely to the main thread that we're taking the display global lock
// So the main thread can skip processing messages while we're updating.
// There are system setups where this call can pause for a while, because the GL implementation
// is trying to impose a framerate or other thing is occurring. Without the mutex, the main
// thread would delay waiting for the same global display lock
mutex.acquireUninterruptibly();
Display.update();
// As soon as we're done, we release the mutex. The other thread can now ping the processmessages
// call as often as it wants until we get get back here again
mutex.release();
if(pause)
{
clearGL();
@@ -344,7 +363,7 @@ public class SplashProgress
drawBox(barWidth - 2, barHeight - 2);
// slidy part
setColor(barColor);
drawBox((barWidth - 2) * b.getStep() / b.getSteps(), barHeight - 2);
drawBox((barWidth - 2) * (b.getStep() + 1) / (b.getSteps() + 1), barHeight - 2); // Step can sometimes be 0.
// progress text
String progress = "" + b.getStep() + "/" + b.getSteps();
glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0);
@@ -469,9 +488,9 @@ public class SplashProgress
public static void finish()
{
if(!enabled) return;
checkThreadState();
try
{
checkThreadState();
done = true;
thread.join();
d.releaseContext();
@@ -483,10 +502,66 @@ public class SplashProgress
catch (Exception e)
{
e.printStackTrace();
throw new RuntimeException(e);
if (disableSplash())
{
throw new EnhancedRuntimeException(e)
{
@Override
protected void printStackTrace(WrappedPrintStream stream)
{
stream.println("SplashProgress has detected a error loading Minecraft.");
stream.println("This can sometimes be caused by bad video drivers.");
stream.println("We have automatically disabeled the new Splash Screen in config/splash.properties.");
stream.println("Try reloading minecraft before reporting any errors.");
}
};
}
else
{
throw new EnhancedRuntimeException(e)
{
@Override
protected void printStackTrace(WrappedPrintStream stream)
{
stream.println("SplashProgress has detected a error loading Minecraft.");
stream.println("This can sometimes be caused by bad video drivers.");
stream.println("Please try disabeling the new Splash Screen in config/splash.properties.");
stream.println("After doing so, try reloading minecraft before reporting any errors.");
}
};
}
}
}
private static boolean disableSplash()
{
File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties");
File parent = configFile.getParentFile();
if (!parent.exists())
parent.mkdirs();
FileReader r = null;
enabled = false;
config.setProperty("enabled", "false");
FileWriter w = null;
try
{
w = new FileWriter(configFile);
config.store(w, "Splash screen properties");
}
catch(IOException e)
{
FMLLog.log(Level.ERROR, e, "Could not save the splash.properties file");
return false;
}
finally
{
IOUtils.closeQuietly(w);
}
return true;
}
private static IResourcePack createResourcePack(File file)
{
if(file.isDirectory())
@@ -691,4 +766,4 @@ public class SplashProgress
}
return mcPack.getInputStream(loc);
}
}
}
@@ -44,7 +44,7 @@ public abstract class EnhancedRuntimeException extends RuntimeException
this.printStackTrace(new WrappedPrintStream()
{
@Override
void println(String line)
public void println(String line)
{
buf.append(line).append('\n');
}
@@ -60,7 +60,7 @@ public abstract class EnhancedRuntimeException extends RuntimeException
printStackTrace(new WrappedPrintStream()
{
@Override
void println(String line)
public void println(String line)
{
s.println(line);
}
@@ -72,7 +72,7 @@ public abstract class EnhancedRuntimeException extends RuntimeException
printStackTrace(new WrappedPrintStream()
{
@Override
void println(String line)
public void println(String line)
{
s.println(line);
}
@@ -84,6 +84,6 @@ public abstract class EnhancedRuntimeException extends RuntimeException
public static abstract class WrappedPrintStream
{
abstract void println(String line);
public abstract void println(String line);
}
}
@@ -632,4 +632,9 @@ public class FMLCommonHandler
Runtime.getRuntime().exit(exitCode);
}
}
public String stripSpecialChars(String message)
{
return sidedDelegate != null ? sidedDelegate.stripSpecialChars(message) : message;
}
}
@@ -63,4 +63,6 @@ public interface IFMLSidedHandler
void allowLogins();
void processWindowMessages();
String stripSpecialChars(String message);
}
@@ -183,7 +183,7 @@ public class LoadController
{
modObjectList = buildModObjectList();
}
ProgressBar bar = ProgressManager.push(stateEvent.description(), activeModList.size());
ProgressBar bar = ProgressManager.push(stateEvent.description(), activeModList.size(), true);
for (ModContainer mc : activeModList)
{
bar.step(mc.getName());
@@ -266,10 +266,17 @@ public class LoadController
public void printModStates(StringBuilder ret)
{
ret.append("\n\tStates:");
for (ModState state : ModState.values())
ret.append(" '").append(state.getMarker()).append("' = ").append(state.toString());
for (ModContainer mc : loader.getModList())
{
ret.append("\n\t").append(mc.getModId()).append("{").append(mc.getVersion()).append("} [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
Joiner.on("->"). appendTo(ret, modStates.get(mc.getModId()));
ret.append("\n\t");
for (ModState state : modStates.get(mc.getModId()))
ret.append(state.getMarker());
ret.append("\t").append(mc.getModId()).append("{").append(mc.getVersion()).append("} [").append(mc.getName()).append("] (").append(mc.getSource().getName()).append(") ");
}
}
@@ -19,6 +19,7 @@ import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -75,6 +76,7 @@ import cpw.mods.fml.common.functions.ArtifactVersionNameFunction;
import cpw.mods.fml.common.functions.ModIdFunction;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry.Type;
import cpw.mods.fml.common.registry.ItemStackHolderInjector;
import cpw.mods.fml.common.registry.ObjectHolderRegistry;
import cpw.mods.fml.common.toposort.ModSorter;
import cpw.mods.fml.common.toposort.ModSortingException;
@@ -509,10 +511,30 @@ public class Loader
}
modController.transition(LoaderState.CONSTRUCTING, false);
modController.distributeStateMessage(LoaderState.CONSTRUCTING, modClassLoader, discoverer.getASMTable(), reverseDependencies);
List<ModContainer> mods = Lists.newArrayList();
mods.addAll(getActiveModList());
Collections.sort(mods, new Comparator<ModContainer>()
{
@Override
public int compare(ModContainer o1, ModContainer o2)
{
return o1.getModId().compareTo(o2.getModId());
}
});
FMLLog.fine("Mod signature data");
FMLLog.fine(" \tValid Signatures:");
for (ModContainer mod : getActiveModList())
{
FMLLog.fine("\t%s(%s:%s): %s (%s)", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName(), CertificateHelper.getFingerprint(mod.getSigningCertificate()));
if (mod.getSigningCertificate() != null)
FMLLog.fine("\t\t(%s) %s\t(%s\t%s)\t%s", CertificateHelper.getFingerprint(mod.getSigningCertificate()), mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName());
}
FMLLog.fine(" \tMissing Signatures:");
for (ModContainer mod : getActiveModList())
{
if (mod.getSigningCertificate() == null)
FMLLog.fine("\t\t%s\t(%s\t%s)\t%s", mod.getModId(), mod.getName(), mod.getVersion(), mod.getSource().getName());
}
if (getActiveModList().isEmpty())
{
@@ -530,8 +552,10 @@ public class Loader
return;
}
ObjectHolderRegistry.INSTANCE.findObjectHolders(discoverer.getASMTable());
ItemStackHolderInjector.INSTANCE.findHolders(discoverer.getASMTable());
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir);
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
ItemStackHolderInjector.INSTANCE.inject();
modController.transition(LoaderState.INITIALIZATION, false);
progressBar.step("Initializing Minecraft Engine");
}
@@ -620,7 +644,7 @@ public class Loader
public String getFMLVersionString()
{
return String.format("%s.%s.%s.%s", major, minor, rev, build);
return "7.10.99.99";
}
public ClassLoader getModClassLoader()
@@ -714,6 +738,7 @@ public class Loader
progressBar.step("Initializing mods Phase 3");
modController.transition(LoaderState.POSTINITIALIZATION, false);
modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
ItemStackHolderInjector.INSTANCE.inject();
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
progressBar.step("Finishing up");
modController.transition(LoaderState.AVAILABLE, false);
@@ -956,14 +981,7 @@ public class Loader
public void fireRemapEvent(Map<String, Integer[]> remaps)
{
if (remaps.isEmpty())
{
FMLLog.finer("Skipping remap event - no remaps occured");
}
else
{
modController.propogateStateMessage(new FMLModIdMappingEvent(remaps));
}
modController.propogateStateMessage(new FMLModIdMappingEvent(remaps));
}
public void runtimeDisableMod(String modId)
@@ -95,21 +95,23 @@ public enum LoaderState
}
public enum ModState
{
UNLOADED("Unloaded"),
LOADED("Loaded"),
CONSTRUCTED("Constructed"),
PREINITIALIZED("Pre-initialized"),
INITIALIZED("Initialized"),
POSTINITIALIZED("Post-initialized"),
AVAILABLE("Available"),
DISABLED("Disabled"),
ERRORED("Errored");
UNLOADED ("Unloaded", "U"),
LOADED ("Loaded", "L"),
CONSTRUCTED ("Constructed", "C"),
PREINITIALIZED ("Pre-initialized", "H"),
INITIALIZED ("Initialized", "I"),
POSTINITIALIZED("Post-initialized", "J"),
AVAILABLE ("Available", "A"),
DISABLED ("Disabled", "D"),
ERRORED ("Errored", "E");
private String label;
private String marker;
private ModState(String label)
private ModState(String label, String marker)
{
this.label = label;
this.marker = marker;
}
@Override
@@ -117,5 +119,10 @@ public enum LoaderState
{
return this.label;
}
public String getMarker()
{
return this.marker;
}
}
}
@@ -12,8 +12,12 @@
package cpw.mods.fml.common;
import java.security.cert.Certificate;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.common.versioning.VersionRange;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
import cpw.mods.fml.relauncher.Side;
public class MinecraftDummyContainer extends DummyModContainer
{
@@ -33,4 +37,20 @@ public class MinecraftDummyContainer extends DummyModContainer
{
return staticRange;
}
@Override
public Certificate getSigningCertificate()
{
if (FMLLaunchHandler.side() != Side.CLIENT)
return null;
try
{
Class<?> cbr = Class.forName("net.minecraft.client.ClientBrandRetriever", false, getClass().getClassLoader());
Certificate[] certificates = cbr.getProtectionDomain().getCodeSource().getCertificates();
return certificates != null ? certificates[0] : null;
}
catch (Exception e){} // Errors don't matter just return null.
return null;
}
}
@@ -19,9 +19,21 @@ public class ProgressManager
*/
@Deprecated
public static ProgressBar push(String title, int steps)
{
return push(title, steps, false);
}
/**
* @deprecated not a stable API, will break, don't use this yet
*/
@Deprecated
public static ProgressBar push(String title, int steps, boolean timeEachStep)
{
ProgressBar bar = new ProgressBar(title, steps);
bars.add(bar);
if (timeEachStep)
{
bar.timeEachStep();
}
FMLCommonHandler.instance().processWindowMessages();
return bar;
}
@@ -34,6 +46,16 @@ public class ProgressManager
{
if(bar.getSteps() != bar.getStep()) throw new IllegalStateException("can't pop unfinished ProgressBar " + bar.getTitle());
bars.remove(bar);
if (bar.getSteps() != 0)
{
long newTime = System.nanoTime();
if (bar.timeEachStep)
FMLLog.fine("Bar Step: %s - %s took %.3fs", bar.getTitle(), bar.getMessage(), ((float)(newTime - bar.lastTime) / 1000000 / 1000));
if (bar.getSteps() == 1)
FMLLog.fine("Bar Finished: %s - %s took %.3fs", bar.getTitle(), bar.getMessage(), ((float)(newTime - bar.startTime) / 1000000 / 1000));
else
FMLLog.fine("Bar Finished: %s took %.3fs", bar.getTitle(), ((float)(newTime - bar.startTime) / 1000000 / 1000));
}
FMLCommonHandler.instance().processWindowMessages();
}
@@ -55,6 +77,9 @@ public class ProgressManager
private final int steps;
private volatile int step = 0;
private volatile String message = "";
private boolean timeEachStep = false;
private long startTime = System.nanoTime();
private long lastTime = startTime;
private ProgressBar(String title, int steps)
{
@@ -70,8 +95,14 @@ public class ProgressManager
public void step(String message)
{
if(step >= steps) throw new IllegalStateException("too much steps for ProgressBar " + title);
if (timeEachStep && step != 0)
{
long newTime = System.nanoTime();
FMLLog.fine("Bar Step: %s - %s took %.3fs", getTitle(), getMessage(), ((float)(newTime - lastTime) / 1000000 / 1000));
lastTime = newTime;
}
step++;
this.message = message;
this.message = FMLCommonHandler.instance().stripSpecialChars(message);
FMLCommonHandler.instance().processWindowMessages();
}
@@ -94,5 +125,10 @@ public class ProgressManager
{
return message;
}
public void timeEachStep()
{
this.timeEachStep = true;
}
}
}
}
@@ -118,7 +118,7 @@ public class AccessTransformer implements IClassTransformer
rulesResource = Resources.getResource(rulesFile);
}
processATFile(Resources.asCharSource(rulesResource, Charsets.UTF_8));
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s\n", modifiers.size(), rulesFile);
FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer config file %s", modifiers.size(), rulesFile);
}
protected void processATFile(CharSource rulesResource) throws IOException
{
@@ -65,7 +65,7 @@ public class EventSubscriptionTransformer implements IClassTransformer
{
if (buildEvents(classNode))
{
ClassWriter cw = new ClassWriter(COMPUTE_MAXS | COMPUTE_FRAMES);
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
classNode.accept(cw);
return cw.toByteArray();
}
@@ -100,7 +100,7 @@ public class MarkerTransformer implements IClassTransformer
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (bytes == null) { return null; }
if (bytes == null) { return null; }
if (!markers.containsKey(name)) { return bytes; }
ClassNode classNode = new ClassNode();
@@ -25,7 +25,7 @@ import cpw.mods.fml.relauncher.FMLRelaunchLog;
public class ModAPITransformer implements IClassTransformer {
private static final boolean logDebugInfo = Boolean.valueOf(System.getProperty("fml.debugAPITransformer", "true"));
private static final boolean logDebugInfo = Boolean.valueOf(System.getProperty("fml.debugAPITransformer", "false"));
private ListMultimap<String, ASMData> optionals;
@Override
@@ -35,7 +35,7 @@ public class SideTransformer implements IClassTransformer
@Override
public byte[] transform(String name, String transformedName, byte[] bytes)
{
if (bytes == null) { return null; }
if (bytes == null) { return null; }
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(bytes);
@@ -38,7 +38,7 @@ public class DirectoryDiscoverer implements ITypeDiscoverer
@Override
public boolean accept(File file)
{
return (file.isFile() && classFile.matcher(file.getName()).find()) || file.isDirectory();
return (file.isFile() && classFile.matcher(file.getName()).matches()) || file.isDirectory();
}
}
@@ -5,7 +5,7 @@
* are made available under the terms of the GNU Lesser Public License v2.1
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
*
* Contributors:
* cpw - implementation
*/
@@ -19,7 +19,8 @@ import cpw.mods.fml.common.ModContainer;
public interface ITypeDiscoverer
{
public static Pattern classFile = Pattern.compile("([^\\s$]+).class$");
// main class part, followed by an optional $ and an "inner class" part. $ cannot be last, otherwise scala breaks
public static Pattern classFile = Pattern.compile("[^\\s\\$]+(\\$[^\\s]+)?\\.class$");
public List<ModContainer> discover(ModCandidate candidate, ASMDataTable table);
}
@@ -80,7 +80,7 @@ public class ModCandidate
public void addClassEntry(String name)
{
String className = name.substring(0, name.lastIndexOf('.')); // strip the .class
foundClasses.add(className.replace('.', '/'));
foundClasses.add(className);
className = className.replace('/','.');
int pkgIdx = className.lastIndexOf('.');
if (pkgIdx > -1)
@@ -121,6 +121,8 @@ public class EventBus implements IEventExceptionHandler
public void unregister(Object object)
{
ArrayList<IEventListener> list = listeners.remove(object);
if (list == null)
return;
for (IEventListener listener : list)
{
ListenerList.unregisterAll(busID, listener);
@@ -38,6 +38,7 @@ public class ClassPatchManager {
public static final ClassPatchManager INSTANCE = new ClassPatchManager();
public static final boolean dumpPatched = Boolean.parseBoolean(System.getProperty("fml.dumpPatchedClasses", "false"));
public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugClassPatchManager", "false"));
private GDiffPatcher patcher = new GDiffPatcher();
private ListMultimap<String, ClassPatch> patches;
@@ -75,7 +76,8 @@ public class ClassPatchManager {
return inputData;
}
boolean ignoredError = false;
FMLRelaunchLog.fine("Runtime patching class %s (input size %d), found %d patch%s", mappedName, (inputData == null ? 0 : inputData.length), list.size(), list.size()!=1 ? "es" : "");
if (DEBUG)
FMLRelaunchLog.fine("Runtime patching class %s (input size %d), found %d patch%s", mappedName, (inputData == null ? 0 : inputData.length), list.size(), list.size()!=1 ? "es" : "");
for (ClassPatch patch: list)
{
if (!patch.targetClassName.equals(mappedName) && !patch.sourceClassName.equals(name))
@@ -122,7 +124,7 @@ public class ClassPatchManager {
}
}
}
if (!ignoredError)
if (!ignoredError && DEBUG)
{
FMLRelaunchLog.fine("Successfully applied runtime patches for %s (new size %d)", mappedName, inputData.length);
}
@@ -194,13 +196,15 @@ public class ClassPatchManager {
}
} while (true);
FMLRelaunchLog.fine("Read %d binary patches", patches.size());
FMLRelaunchLog.fine("Patch list :\n\t%s", Joiner.on("\t\n").join(patches.asMap().entrySet()));
if (DEBUG)
FMLRelaunchLog.fine("Patch list :\n\t%s", Joiner.on("\t\n").join(patches.asMap().entrySet()));
patchedClasses.clear();
}
private ClassPatch readPatch(JarEntry patchEntry, JarInputStream jis)
{
FMLRelaunchLog.finer("Reading patch data from %s", patchEntry.getName());
if (DEBUG)
FMLRelaunchLog.finer("Reading patch data from %s", patchEntry.getName());
ByteArrayDataInput input;
try
{
@@ -9,7 +9,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.Level;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.RegistryNamespaced;
@@ -21,8 +24,10 @@ import com.google.common.collect.Iterators;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.functions.GenericIterableFactory;
import cpw.mods.fml.common.registry.RegistryDelegate.Delegate;
public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
public static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("fml.debugRegistryEntries", "false"));
private final Class<I> superType;
private String optionalDefaultName;
private I optionalDefaultObject;
@@ -50,9 +55,10 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{
int id = getId(obj);
String name = getNameForObject(obj);
boolean isSubstituted = activeSubstitutions.containsKey(name);
// id lookup failed -> obj is not in the obj<->id map
if (id < 0) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s, doesn't yield an id.", type, obj, name));
if (!isSubstituted && id < 0) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s, doesn't yield an id.", type, obj, name));
// id is too high
if (id > maxId) throw new IllegalStateException(String.format("Registry entry for %s %s, name %s uses the too large id %d.", type, obj, name));
// name lookup failed -> obj is not in the obj<->name map
@@ -61,12 +67,14 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
if (name.isEmpty()) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, yields an empty name.", type, obj, id));
// non-prefixed name
if (name.indexOf(':') == -1) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, has the non-prefixed name %s.", type, obj, id, name));
// the rest of the tests don't really work for substituted items or blocks
if (isSubstituted) continue;
// id -> obj lookup is inconsistent
if (getRaw(id) != obj) throw new IllegalStateException(String.format("Registry entry for id %d, name %s, doesn't yield the expected %s %s.", id, name, type, obj));
// name -> obj lookup is inconsistent
if (!(activeSubstitutions.containsKey(name) || activeSubstitutions.containsValue(name)) && getRaw(name) != obj ) throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, type, obj));
if (getRaw(name) != obj) throw new IllegalStateException(String.format("Registry entry for name %s, id %d, doesn't yield the expected %s %s.", name, id, type, obj));
// name -> id lookup is inconsistent
if (!(activeSubstitutions.containsKey(name) || activeSubstitutions.containsValue(name)) && getId(name) != id) throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id));
if (getId(name) != id) throw new IllegalStateException(String.format("Registry entry for name %s doesn't yield the expected id %d.", name, id));
// id isn't marked as unavailable
if (!availabilityMap.get(id)) throw new IllegalStateException(String.format("Registry entry for %s %s, id %d, name %s, marked as empty.", type, obj, id, name));
// entry is blocked, thus should be empty
@@ -104,7 +112,8 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
for (I thing : registry.typeSafeIterable())
{
addObjectRaw(registry.getId(thing), registry.getNameForObject(thing), thing);
int id = registry.getId(thing);
addObjectRaw(id, registry.getNameForObject(thing), thing);
}
this.activeSubstitutions.putAll(registry.activeSubstitutions);
}
@@ -238,9 +247,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
* @return
*/
@SuppressWarnings("unchecked")
private I cast(Object obj)
private I cast(Object obj)
{
return (I)(obj);
return (I)(obj);
}
/**
* Get the object identified by the specified name.
@@ -396,14 +405,16 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
}
addObjectRaw(idToUse, name, thing);
FMLLog.finer("Registry add: %s %d %s (req. id %d)", name, idToUse, thing, id);
if (DEBUG)
FMLLog.finer("Registry add: %s %d %s (req. id %d)", name, idToUse, thing, id);
return idToUse;
}
void addAlias(String from, String to)
{
aliases.put(from, to);
FMLLog.finer("Registry alias: %s -> %s", from, to);
if (DEBUG)
FMLLog.finer("Registry alias: %s -> %s", from, to);
}
Map<String,Integer> getEntriesNotIn(FMLControlledNamespacedRegistry<I> registry)
@@ -426,6 +437,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
void dump()
{
if (!DEBUG)
return;
List<Integer> ids = new ArrayList<Integer>();
for (I thing : this.typeSafeIterable())
@@ -439,7 +453,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
for (int id : ids)
{
I thing = getRaw(id);
FMLLog.finer("Registry: %s %d %s", getNameForObject(thing), id, thing);
FMLLog.finer("Registry: %d %s %s", id, getNameForObject(thing), thing);
}
}
@@ -469,6 +483,19 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{
if (getPersistentSubstitutions().containsKey(nameToReplace))
{
I original = getRaw(nameToReplace);
if (superType == Item.class) {
Item sub = (Item) getPersistentSubstitutions().get(nameToReplace);
if (original == null) {
// When we're activated from the server side, we need to set the delegate on the original instance to
// point to us. Go to the "default state" registry to get it
original = (I)GameData.getItemRegistry().getRaw(nameToReplace);
}
FMLLog.log(Level.DEBUG, "Replacing %s with %s (name %s)", original, sub, nameToReplace);
Delegate<Item> delegate = (Delegate<Item>)((Item)original).delegate;
delegate.changeReference(sub);
((Delegate<Item>)sub.delegate).setName(nameToReplace);
}
activeSubstitutions.put(nameToReplace, getPersistentSubstitutions().get(nameToReplace));
}
}
@@ -496,6 +523,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
FMLLog.severe("The substitute %s for %s is registered into the game independently. This won't work", replacement.getClass().getName(), nameToReplace);
throw new IllegalArgumentException("The object substitution is already registered. This won't work");
}
FMLLog.log(Level.DEBUG, "Adding substitution %s with %s (name %s)", original, replacement, nameToReplace);
getPersistentSubstitutions().put(nameToReplace, replacement);
}
@@ -523,4 +551,13 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{
return Iterators.concat(super.iterator(),getPersistentSubstitutions().values().iterator());
}
// ONLY CALLED ON ITEM registry
void resetSubstitutionDelegates()
{
for (I item: typeSafeIterable()) {
Delegate<Item> delegate = (Delegate<Item>)((Item)item).delegate;
delegate.changeReference((Item)item);
}
}
}
@@ -39,6 +39,7 @@ import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -439,6 +440,7 @@ public class GameData {
getMain().iBlockRegistry.dump();
getMain().iItemRegistry.dump();
getMain().iItemRegistry.resetSubstitutionDelegates();
GameData newData = new GameData();
for (int id : blockedIds)
@@ -734,6 +736,8 @@ public class GameData {
getMain().set(frozen);
}
// the id mapping has reverted, fire remap events for those that care about id changes
Loader.instance().fireRemapEvent(ImmutableMap.<String,Integer[]>of());
// the id mapping has reverted, ensure we sync up the object holders
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
}
@@ -834,7 +838,8 @@ public class GameData {
}
else // ItemBlock after its Block
{
FMLLog.fine("Found matching Block %s for ItemBlock %s at id %d, original id requested: %d", block, item, id, idHint);
if (FMLControlledNamespacedRegistry.DEBUG)
FMLLog.fine("Found matching Block %s for ItemBlock %s at id %d, original id requested: %d", block, item, id, idHint);
freeSlot(id, item); // temporarily free the slot occupied by the Block for the item registration
}
@@ -32,6 +32,10 @@ import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.FurnaceRecipes;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.JsonToNBT;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTException;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraft.world.chunk.IChunkProvider;
@@ -39,6 +43,8 @@ import net.minecraft.world.chunk.IChunkProvider;
import org.apache.logging.log4j.Level;
import com.google.common.base.Objects;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
@@ -476,4 +482,70 @@ public class GameRegistry
*/
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ItemStackHolder
{
/**
* The registry name of the item being looked up.
* @return The registry name
*/
public String value();
/**
* The metadata or damage value for the itemstack, defaults to 0.
* @return the metadata value
*/
public int meta() default 0;
/**
* The string serialized nbt value for the itemstack. Defaults to empty for no nbt.
*
* @return a nbt string
*/
public String nbt() default "";
}
/**
* Makes an {@link ItemStack} based on the itemName reference, with supplied meta, stackSize and nbt, if possible
*
* Will return null if the item doesn't exist (because it's not from a loaded mod for example)
* Will throw a {@link RuntimeException} if the nbtString is invalid for use in an {@link ItemStack}
*
* @param itemName a registry name reference
* @param meta the meta
* @param stackSize the stack size
* @param nbtString an nbt stack as a string, will be processed by {@link JsonToNBT}
* @return a new itemstack
*/
public static ItemStack makeItemStack(String itemName, int meta, int stackSize, String nbtString)
{
if (itemName == null) throw new IllegalArgumentException("The itemName cannot be null");
Item item = GameData.getItemRegistry().getObject(itemName);
if (item == null) {
FMLLog.getLogger().log(Level.TRACE, "Unable to find item with name {}", itemName);
return null;
}
ItemStack is = new ItemStack(item,1,meta);
if (!Strings.isNullOrEmpty(nbtString)) {
NBTBase nbttag = null;
try
{
nbttag = JsonToNBT.func_150315_a(nbtString);
} catch (NBTException e)
{
FMLLog.getLogger().log(Level.WARN, "Encountered an exception parsing ItemStack NBT string {}", nbtString, e);
throw Throwables.propagate(e);
}
if (!(nbttag instanceof NBTTagCompound)) {
FMLLog.getLogger().log(Level.WARN, "Unexpected NBT string - multiple values {}", nbtString);
throw new RuntimeException("Invalid NBT JSON");
} else {
is.setTagCompound((NBTTagCompound) nbttag);
}
}
return is;
}
}
@@ -0,0 +1,80 @@
package cpw.mods.fml.common.registry;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.logging.log4j.Level;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.discovery.ASMDataTable;
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
public enum ItemStackHolderInjector
{
INSTANCE;
private List<ItemStackHolderRef> itemStackHolders = Lists.newArrayList();
public void inject() {
FMLLog.getLogger().log(Level.INFO, "Injecting itemstacks");
for (ItemStackHolderRef ishr: itemStackHolders) {
ishr.apply();
}
FMLLog.getLogger().log(Level.INFO, "Itemstack injection complete");
}
public void findHolders(ASMDataTable table) {
FMLLog.info("Identifying ItemStackHolder annotations");
Set<ASMData> allItemStackHolders = table.getAll(GameRegistry.ItemStackHolder.class.getName());
Map<String, Class<?>> classCache = Maps.newHashMap();
for (ASMData data : allItemStackHolders)
{
String className = data.getClassName();
String annotationTarget = data.getObjectName();
String value = (String) data.getAnnotationInfo().get("value");
int meta = data.getAnnotationInfo().containsKey("meta") ? (Integer) data.getAnnotationInfo().get("meta") : 0;
String nbt = data.getAnnotationInfo().containsKey("nbt") ? (String) data.getAnnotationInfo().get("nbt") : "";
addHolder(classCache, className, annotationTarget, value, meta, nbt);
}
FMLLog.info("Found %d ItemStackHolder annotations", allItemStackHolders.size());
}
private void addHolder(Map<String, Class<?>> classCache, String className, String annotationTarget, String value, Integer meta, String nbt)
{
Class<?> clazz;
if (classCache.containsKey(className))
{
clazz = classCache.get(className);
}
else
{
try
{
clazz = Class.forName(className, true, getClass().getClassLoader());
classCache.put(className, clazz);
}
catch (Exception ex)
{
// unpossible?
throw Throwables.propagate(ex);
}
}
try
{
Field f = clazz.getField(annotationTarget);
itemStackHolders.add(new ItemStackHolderRef(f, value, meta, nbt));
}
catch (Exception ex)
{
// unpossible?
throw Throwables.propagate(ex);
}
}
}
@@ -0,0 +1,84 @@
package cpw.mods.fml.common.registry;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.minecraft.item.ItemStack;
import org.apache.logging.log4j.Level;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameRegistry.ItemStackHolder;
/**
* Internal class used in tracking {@link ItemStackHolder} references
*
* @author cpw
*
*/
class ItemStackHolderRef {
private Field field;
private String itemName;
private int meta;
private String serializednbt;
ItemStackHolderRef(Field field, String itemName, int meta, String serializednbt)
{
this.field = field;
this.itemName = itemName;
this.meta = meta;
this.serializednbt = serializednbt;
makeWritable(field);
}
private static Field modifiersField;
private static Object reflectionFactory;
private static Method newFieldAccessor;
private static Method fieldAccessorSet;
private static void makeWritable(Field f)
{
try
{
if (modifiersField == null)
{
Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory");
reflectionFactory = getReflectionFactory.invoke(null);
newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", Field.class, boolean.class);
fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", Object.class, Object.class);
modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
}
modifiersField.setInt(f, f.getModifiers() & ~Modifier.FINAL);
} catch (Exception e)
{
throw Throwables.propagate(e);
}
}
public void apply()
{
ItemStack is;
try
{
is = GameRegistry.makeItemStack(itemName, meta, 1, serializednbt);
} catch (RuntimeException e)
{
FMLLog.getLogger().log(Level.ERROR, "Caught exception processing itemstack {},{},{} in annotation at {}.{}", itemName, meta, serializednbt,field.getClass().getName(),field.getName());
throw e;
}
try
{
Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, field, false);
fieldAccessorSet.invoke(fieldAccessor, null, is);
}
catch (Exception e)
{
FMLLog.getLogger().log(Level.WARN, "Unable to set {} with value {},{},{}", this.field, this.itemName, this.meta, this.serializednbt);
}
}
}
@@ -20,6 +20,7 @@ import java.io.InputStreamReader;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
@@ -35,6 +36,8 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.StringTranslate;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
@@ -273,13 +276,15 @@ public class LanguageRegistry
private void searchZipForLanguages(File source, Side side) throws IOException
{
ZipFile zf = new ZipFile(source);
List<String> added = Lists.newArrayList();
for (ZipEntry ze : Collections.list(zf.entries()))
{
Matcher matcher = assetENUSLang.matcher(ze.getName());
if (matcher.matches())
{
String lang = matcher.group(2);
FMLLog.fine("Injecting found translation data for lang %s in zip file %s at %s into language system", lang, source.getName(), ze.getName());
//FMLLog.fine("Injecting found translation data for lang %s in zip file %s at %s into language system", lang, source.getName(), ze.getName());
added.add(lang);
LanguageRegistry.instance().injectLanguage(lang, StringTranslate.parseLangFile(zf.getInputStream(ze)));
// Ensure en_US is available to StringTranslate on the server
if ("en_US".equals(lang) && side == Side.SERVER)
@@ -288,6 +293,8 @@ public class LanguageRegistry
}
}
}
if (added.size() > 0)
FMLLog.fine("Found translations in %s [%s]", source.getName(), Joiner.on(", ").join(added));
zf.close();
}
@@ -61,7 +61,7 @@ class ObjectHolderRef {
if (this.injectedObject == null || !isValid())
{
throw new IllegalStateException("The ObjectHolder annotation cannot apply to a field that is not an Item or Block");
throw new IllegalStateException(String.format("The ObjectHolder annotation cannot apply to a field that is not an Item or Block (found : %s at %s.%s)", field.getType().getName(), field.getClass().getName(), field.getName()));
}
makeWritable(field);
}
@@ -116,7 +116,7 @@ class ObjectHolderRef {
if (thing == null)
{
FMLLog.warning("Unable to lookup %s for %s. Is there something wrong with the registry?", injectedObject, field);
FMLLog.getLogger().log(Level.DEBUG, "Unable to lookup {} for {}. This means the object wasn't registered. It's likely just mod options.", injectedObject, field);
return;
}
try
@@ -13,24 +13,30 @@
package cpw.mods.fml.relauncher;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import net.minecraft.launchwrapper.ITweaker;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.launchwrapper.LaunchClassLoader;
import org.apache.logging.log4j.Level;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
@@ -38,6 +44,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.ObjectArrays;
import com.google.common.primitives.Ints;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.asm.transformers.ModAccessTransformer;
import cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker;
@@ -243,6 +250,42 @@ public class CoreModManager {
FMLRelaunchLog.severe("Problem file : %s", f.getName());
}
}
FileFilter derpdirfilter = new FileFilter() {
@Override
public boolean accept(File pathname)
{
return pathname.isDirectory() && new File(pathname,"META-INF").isDirectory();
}
};
File[] derpdirlist = coreMods.listFiles(derpdirfilter);
if (derpdirlist != null && derpdirlist.length > 0)
{
FMLRelaunchLog.log.getLogger().log(Level.FATAL, "There appear to be jars extracted into the mods directory. This is VERY BAD and will almost NEVER WORK WELL");
FMLRelaunchLog.log.getLogger().log(Level.FATAL, "You should place original jars only in the mods directory. NEVER extract them to the mods directory.");
FMLRelaunchLog.log.getLogger().log(Level.FATAL, "The directories below appear to be extracted jar files. Fix this before you continue.");
for (File f : derpdirlist)
{
FMLRelaunchLog.log.getLogger().log(Level.FATAL, "Directory {} contains {}", f.getName(), Arrays.asList(new File(f,"META-INF").list()));
}
RuntimeException re = new RuntimeException("Extracted mod jars found, loading will NOT continue");
// We're generating a crash report for the launcher to show to the user here
try
{
Class<?> crashreportclass = classLoader.loadClass("b");
Object crashreport = crashreportclass.getMethod("a", Throwable.class, String.class).invoke(null, re, "FML has discovered extracted jar files in the mods directory.\nThis breaks mod loading functionality completely.\nRemove the directories and replace with the jar files originally provided.");
File crashreportfile = new File(new File(coreMods.getParentFile(),"crash-reports"),String.format("fml-crash-%1$tY-%1$tm-%1$td_%1$tT.txt",Calendar.getInstance()));
crashreportclass.getMethod("a",File.class).invoke(crashreport, crashreportfile);
System.out.println("#@!@# FML has crashed the game deliberately. Crash report saved to: #@!@# " + crashreportfile.getAbsolutePath());
} catch (Exception e)
{
e.printStackTrace();
// NOOP - hopefully
}
throw re;
}
File[] coreModList = coreMods.listFiles(ff);
File versionedModDir = new File(coreMods, FMLInjectionData.mccversion);
if (versionedModDir.isDirectory())
@@ -259,7 +259,7 @@ public class FMLServerHandler implements IFMLSidedHandler
{
return DedicatedServer.allowPlayerLogins;
}
@Override
public void allowLogins() {
DedicatedServer.allowPlayerLogins = true;
@@ -270,4 +270,10 @@ public class FMLServerHandler implements IFMLSidedHandler
{
// NOOP
}
@Override
public String stripSpecialChars(String message)
{
return message;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@
<Console name="SysOut" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %msg%n" />
</Console>
<Queue name="ServerGuiConsole">
<Queue name="ServerGuiConsole" ignoreExceptions="true">
<PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level] [%logger]: %msg%n" />
</Queue>
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
@@ -56,7 +56,7 @@
if (p_147108_1_ instanceof GuiMainMenu)
{
this.field_71474_y.field_74330_P = false;
@@ -1352,7 +1357,7 @@
@@ -1353,7 +1358,7 @@
if (this.field_71439_g.func_82246_f(i, j, k))
{
@@ -65,7 +65,7 @@
this.field_71439_g.func_71038_i();
}
}
@@ -1433,11 +1438,12 @@
@@ -1434,11 +1439,12 @@
int j = this.field_71476_x.field_72312_c;
int k = this.field_71476_x.field_72309_d;
@@ -80,7 +80,7 @@
{
flag = false;
this.field_71439_g.func_71038_i();
@@ -1464,7 +1470,8 @@
@@ -1465,7 +1471,8 @@
{
ItemStack itemstack1 = this.field_71439_g.field_71071_by.func_70448_g();
@@ -90,7 +90,7 @@
{
this.field_71460_t.field_78516_c.func_78445_c();
}
@@ -1676,6 +1683,8 @@
@@ -1677,6 +1684,8 @@
while (Mouse.next())
{
@@ -99,7 +99,7 @@
j = Mouse.getEventButton();
KeyBinding.func_74510_a(j - 100, Mouse.getEventButtonState());
@@ -2138,6 +2147,11 @@
@@ -2139,6 +2148,11 @@
public void func_71353_a(WorldClient p_71353_1_, String p_71353_2_)
{
@@ -111,7 +111,7 @@
if (p_71353_1_ == null)
{
NetHandlerPlayClient nethandlerplayclient = this.func_147114_u();
@@ -2150,6 +2164,18 @@
@@ -2151,6 +2165,18 @@
if (this.field_71437_Z != null)
{
this.field_71437_Z.func_71263_m();
@@ -130,7 +130,7 @@
}
this.field_71437_Z = null;
@@ -2298,113 +2324,10 @@
@@ -2299,113 +2325,10 @@
if (this.field_71476_x != null)
{
boolean flag = this.field_71439_g.field_71075_bZ.field_75098_d;
@@ -246,7 +246,7 @@
if (flag)
{
j = this.field_71439_g.field_71069_bz.field_75151_b.size() - 9 + this.field_71439_g.field_71071_by.field_70461_c;
@@ -2670,8 +2593,15 @@
@@ -2671,8 +2594,15 @@
p_70001_1_.func_152767_b("gl_max_texture_size", Integer.valueOf(func_71369_N()));
}
@@ -262,7 +262,7 @@
for (int i = 16384; i > 0; i >>= 1)
{
GL11.glTexImage2D(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_RGBA, i, i, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null);
@@ -2679,6 +2609,7 @@
@@ -2680,6 +2610,7 @@
if (j != 0)
{
@@ -32,7 +32,19 @@
}
public void func_147279_a(S0BPacketAnimation p_147279_1_)
@@ -1127,6 +1134,10 @@
@@ -735,6 +742,11 @@
float f = (float)(p_147281_1_.func_149028_l() * 360) / 256.0F;
float f1 = (float)(p_147281_1_.func_149030_m() * 360) / 256.0F;
EntityLivingBase entitylivingbase = (EntityLivingBase)EntityList.func_75616_a(p_147281_1_.func_149025_e(), this.field_147299_f.field_71441_e);
+ if (entitylivingbase == null)
+ {
+ cpw.mods.fml.common.FMLLog.info("Server attempted to spawn an unknown entity using ID: {0} at ({1}, {2}, {3}) Skipping!", p_147281_1_.func_149025_e(), d0, d1, d2);
+ return;
+ }
entitylivingbase.field_70118_ct = p_147281_1_.func_149023_f();
entitylivingbase.field_70117_cu = p_147281_1_.func_149034_g();
entitylivingbase.field_70116_cv = p_147281_1_.func_149029_h();
@@ -1127,6 +1139,10 @@
{
tileentity.func_145839_a(p_147273_1_.func_148857_g());
}
@@ -8,7 +8,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -91,11 +92,14 @@
@@ -98,11 +99,14 @@
public void func_110571_b(IResourceManager p_110571_1_)
{
@@ -20,10 +20,10 @@
this.field_94258_i.clear();
int j = Integer.MAX_VALUE;
+ ForgeHooksClient.onTextureStitchedPre(this);
cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Texture stitching", this.field_110574_e.size());
cpw.mods.fml.common.ProgressManager.ProgressBar bar = cpw.mods.fml.common.ProgressManager.push("Texture Loading", skipFirst ? 0 : this.field_110574_e.size());
Iterator iterator = this.field_110574_e.entrySet().iterator();
TextureAtlasSprite textureatlassprite;
@@ -108,6 +112,16 @@
@@ -115,6 +119,16 @@
ResourceLocation resourcelocation1 = this.func_147634_a(resourcelocation, 0);
bar.step(resourcelocation1.func_110623_a());
@@ -40,7 +40,7 @@
try
{
IResource iresource = p_110571_1_.func_110536_a(resourcelocation1);
@@ -286,6 +300,7 @@
@@ -294,6 +308,7 @@
textureatlassprite = (TextureAtlasSprite)iterator2.next();
textureatlassprite.func_94217_a(this.field_94249_f);
}
@@ -48,7 +48,7 @@
cpw.mods.fml.common.ProgressManager.pop(bar);
}
@@ -360,7 +375,7 @@
@@ -368,7 +383,7 @@
{
throw new IllegalArgumentException("Name cannot be null!");
}
@@ -57,7 +57,7 @@
{
Object object = (TextureAtlasSprite)this.field_110574_e.get(p_94245_1_);
@@ -416,4 +431,37 @@
@@ -424,4 +439,37 @@
{
this.field_147637_k = p_147632_1_;
}
@@ -0,0 +1,10 @@
--- ../src-base/minecraft/net/minecraft/entity/EntityList.java
+++ ../src-work/minecraft/net/minecraft/entity/EntityList.java
@@ -84,6 +84,7 @@
public static void func_75618_a(Class p_75618_0_, String p_75618_1_, int p_75618_2_)
{
+ if (p_75618_2_ < 0 || p_75618_2_ > 255) throw new IllegalArgumentException("Attempted to register a entity with invalid ID: " + p_75618_2_ + " Name: " + p_75618_1_ + " Class: " + p_75618_0_);
if (field_75625_b.containsKey(p_75618_1_))
{
throw new IllegalArgumentException("ID is already registered: " + p_75618_1_);
@@ -1,5 +1,14 @@
--- ../src-base/minecraft/net/minecraft/item/ItemArmor.java
+++ ../src-work/minecraft/net/minecraft/item/ItemArmor.java
@@ -40,7 +40,7 @@
if (list.size() > 0)
{
EntityLivingBase entitylivingbase = (EntityLivingBase)list.get(0);
- int l = entitylivingbase instanceof EntityPlayer ? 1 : 0;
+ int l = 0;// Forge: We fix the indexes. Mojang Stop hard coding this!
int i1 = EntityLiving.func_82159_b(p_82487_2_);
ItemStack itemstack1 = p_82487_2_.func_77946_l();
itemstack1.field_77994_a = 1;
@@ -221,7 +221,7 @@
if (itemstack1 == null)
@@ -14,7 +14,7 @@
return false;
}
- else if (!p_77648_3_.func_147439_a(p_77648_4_, p_77648_5_, p_77648_6_).func_149688_o().func_76220_a())
+ else if (!p_77648_3_.isSideSolid(p_77648_4_, p_77648_5_, p_77648_6_, net.minecraftforge.common.util.ForgeDirection.getOrientation(p_77648_7_)))
+ else if (!p_77648_3_.func_147439_a(p_77648_4_, p_77648_5_, p_77648_6_).func_149688_o().func_76220_a() && !p_77648_3_.isSideSolid(p_77648_4_, p_77648_5_, p_77648_6_, net.minecraftforge.common.util.ForgeDirection.getOrientation(p_77648_7_)))
{
return false;
}
@@ -32,3 +32,13 @@
}
--this.field_145957_n[0].field_77994_a;
@@ -301,6 +304,9 @@
}
else
{
+ int moddedBurnTime = net.minecraftforge.event.ForgeEventFactory.getFuelBurnTime(p_145952_0_);
+ if (moddedBurnTime >= 0) return moddedBurnTime;
+
Item item = p_145952_0_.func_77973_b();
if (item instanceof ItemBlock && Block.func_149634_a(item) != Blocks.field_150350_a)
@@ -26,9 +26,9 @@ import cpw.mods.fml.relauncher.SideOnly;
*/
public class WavefrontObject implements IModelCustom
{
private static Pattern vertexPattern = Pattern.compile("(v( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(v( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern vertexNormalPattern = Pattern.compile("(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *\\n)|(vn( (\\-){0,1}\\d+\\.\\d+){3,4} *$)");
private static Pattern textureCoordinatePattern = Pattern.compile("(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *\\n)|(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *$)");
private static Pattern vertexPattern = Pattern.compile("(v( (\\-){0,1}\\d+(\\.\\d+)?){3,4} *\\n)|(v( (\\-){0,1}\\d+(\\.\\d+)?){3,4} *$)");
private static Pattern vertexNormalPattern = Pattern.compile("(vn( (\\-){0,1}\\d+(\\.\\d+)?){3,4} *\\n)|(vn( (\\-){0,1}\\d+(\\.\\d+)?){3,4} *$)");
private static Pattern textureCoordinatePattern = Pattern.compile("(vt( (\\-){0,1}\\d+\\.\\d+){2,3} *\\n)|(vt( (\\-){0,1}\\d+(\\.\\d+)?){2,3} *$)");
private static Pattern face_V_VT_VN_Pattern = Pattern.compile("(f( \\d+/\\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+/\\d+){3,4} *$)");
private static Pattern face_V_VT_Pattern = Pattern.compile("(f( \\d+/\\d+){3,4} *\\n)|(f( \\d+/\\d+){3,4} *$)");
private static Pattern face_V_VN_Pattern = Pattern.compile("(f( \\d+//\\d+){3,4} *\\n)|(f( \\d+//\\d+){3,4} *$)");
@@ -49,7 +49,7 @@ public class WavefrontObject implements IModelCustom
public WavefrontObject(ResourceLocation resource) throws ModelFormatException
{
this.fileName = resource.toString();
try
{
IResource res = Minecraft.getMinecraft().getResourceManager().getResource(resource);
@@ -60,7 +60,7 @@ public class WavefrontObject implements IModelCustom
throw new ModelFormatException("IO Exception reading model format", e);
}
}
public WavefrontObject(String filename, InputStream inputStream) throws ModelFormatException
{
this.fileName = filename;
@@ -12,6 +12,7 @@ import static net.minecraftforge.common.ForgeVersion.revisionVersion;
import static net.minecraftforge.common.config.Configuration.CATEGORY_GENERAL;
import java.io.File;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -381,4 +382,13 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC
"net.minecraftforge.transformers"
);
}
@Override
public Certificate getSigningCertificate()
{
Certificate[] certificates = getClass().getProtectionDomain().getCodeSource().getCertificates();
return certificates != null ? certificates[0] : null;
}
}
@@ -23,7 +23,7 @@ public class ForgeVersion
//This number is incremented every minecraft release, never reset
public static final int minorVersion = 13;
//This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version
public static final int revisionVersion = 3;
public static final int revisionVersion = 4;
//This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code.
public static final int buildVersion = 0;
@@ -12,6 +12,7 @@ import cpw.mods.fml.relauncher.Side;
import net.minecraft.crash.CrashReport;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.ForgeHooks.SeedEntry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.oredict.OreDictionary;
public class MinecraftForge
@@ -140,22 +141,24 @@ public class MinecraftForge
else
handlers = ObjectArrays.concat(handlers, server, String.class);
FMLLog.info("Preloading CrashReport classes", ForgeVersion.getVersion());
//FMLLog.info("Preloading CrashReport classes", ForgeVersion.getVersion());
for (String s : handlers)
{
FMLLog.info("\t" + s);
//FMLLog.info("\t" + s);
try
{
Class cls = Class.forName(s, false, MinecraftForge.class.getClassLoader());
if (cls != null && !Callable.class.isAssignableFrom(cls))
{
FMLLog.info("\t% s is not a instance of callable!", s);
//FMLLog.info("\t% s is not a instance of callable!", s);
}
}
catch (Exception e){}
}
UsernameCache.load();
// Load before all the mods, so MC owns the MC fluids
FluidRegistry.validateFluidRegistry();
}
@@ -135,6 +135,13 @@ public class ForgeEventFactory
return event.list;
}
public static int getFuelBurnTime(ItemStack fuel)
{
FuelBurnTimeEvent event = new FuelBurnTimeEvent(fuel);
MinecraftForge.EVENT_BUS.post(event);
return event.getResult() == Result.DEFAULT ? -1 : event.burnTime;
}
public static int getMaxSpawnPackSize(EntityLiving entity)
{
LivingPackSizeEvent maxCanSpawnEvent = new LivingPackSizeEvent(entity);
@@ -0,0 +1,32 @@
package net.minecraftforge.event;
import net.minecraft.item.ItemStack;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.common.eventhandler.Event.HasResult;
/**
* FuelBurnTimeEvent is fired whenever a furnace needs the burn time of a fuel. <br>
* Normally, a registered {@link cpw.mods.fml.common.IFuelHandler} is preferred, but
* this is useful in the rare situation where IFuelHandler is not effective.<br>
* <br>
* {@link Result#DEFAULT} allows the normal fuel handling code to proceed.
* {@link Result#ALLOW} or {@link Result#DENY} uses the value of {@link #burnTime}
* for the given {@link fuel}, bypassing both vanilla and IFuelHandler determinations.
* <br>
* {@link #fuel} contains the potential fuel.<br>
* {@link #burnTime} the results if set by an event handler.<br>
* <br>
* This event are fired on the {@link MinecraftForge#EVENT_BUS}.
**/
@HasResult
@Deprecated //Remove in 1.8
public class FuelBurnTimeEvent extends Event
{
public final ItemStack fuel;
public int burnTime;
public FuelBurnTimeEvent(ItemStack fuel)
{
this.fuel = fuel;
}
}
@@ -79,25 +79,21 @@ public abstract class FluidRegistry
public static void initFluidIDs(BiMap<Fluid, Integer> newfluidIDs, Set<String> defaultNames)
{
maxID = newfluidIDs.size();
fluidIDs.clear();
fluidIDs.putAll(newfluidIDs);
fluidNames.clear();
for (Entry<Fluid, Integer> e : fluidIDs.entrySet()) {
fluidNames.put(e.getValue(), e.getKey().getName());
}
loadFluidDefaults(defaultNames);
loadFluidDefaults(newfluidIDs, defaultNames);
}
/**
* Called by forge to load default fluid IDs from the world or from server -> client for syncing
* DO NOT call this and expect useful behaviour.
* @param newfluidIDs
*/
private static void loadFluidDefaults(Set<String> defaultNames)
private static void loadFluidDefaults(BiMap<Fluid, Integer> localFluidIDs, Set<String> defaultNames)
{
// If there's an empty set of default names, use the defaults as defined locally
if (defaultNames.isEmpty()) {
defaultNames.addAll(defaultFluidName.values());
}
BiMap<String, Fluid> localFluids = HashBiMap.create(fluids);
for (String defaultName : defaultNames)
{
Fluid fluid = masterFluidReference.get(defaultName);
@@ -112,10 +108,17 @@ public abstract class FluidRegistry
FMLLog.getLogger().log(Level.ERROR, "The fluid {} specified as default is not present - it will be reverted to default {}", defaultName, localDefault);
}
FMLLog.getLogger().log(Level.DEBUG, "The fluid {} has been selected as the default fluid for {}", defaultName, fluid.getName());
Fluid oldFluid = fluids.put(fluid.getName(), fluid);
Integer id = fluidIDs.remove(oldFluid);
fluidIDs.put(fluid, id);
Fluid oldFluid = localFluids.put(fluid.getName(), fluid);
Integer id = localFluidIDs.remove(oldFluid);
localFluidIDs.put(fluid, id);
}
BiMap<Integer, String> localFluidNames = HashBiMap.create();
for (Entry<Fluid, Integer> e : localFluidIDs.entrySet()) {
localFluidNames.put(e.getValue(), e.getKey().getName());
}
fluidIDs = localFluidIDs;
fluids = localFluids;
fluidNames = localFluidNames;
fluidBlocks = null;
for (FluidDelegate fd : delegates.values())
{
@@ -188,17 +191,17 @@ public abstract class FluidRegistry
public static Fluid getFluid(int fluidID)
{
return fluidIDs.inverse().get(fluidID);
return fluidIDs.inverse().get(fluidID);
}
public static int getFluidID(Fluid fluid)
{
return fluidIDs.get(fluid);
return fluidIDs.get(fluid);
}
public static int getFluidID(String fluidName)
{
return fluidIDs.get(getFluid(fluidName));
return fluidIDs.get(getFluid(fluidName));
}
@Deprecated //Remove in 1.8.3
@@ -312,7 +315,7 @@ public abstract class FluidRegistry
{
FMLLog.getLogger().log(Level.DEBUG, "World is missing persistent fluid defaults - using local defaults");
}
loadFluidDefaults(defaults);
loadFluidDefaults(HashBiMap.create(fluidIDs), defaults);
}
public static void writeDefaultFluidList(NBTTagCompound forgeData)
@@ -1,6 +1,7 @@
package net.minecraftforge.oredict;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -13,6 +14,8 @@ import java.util.RandomAccess;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.logging.log4j.Level;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
@@ -28,7 +31,9 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.eventhandler.Event;
import cpw.mods.fml.common.registry.GameData;
public class OreDictionary
{
@@ -297,7 +302,20 @@ public class OreDictionary
{
if (stack == null || stack.getItem() == null) return -1;
int id = Item.getIdFromItem(stack.getItem());
// HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet
// IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about.
// APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game.
String registryName = stack.getItem().delegate.name();
int id;
if (registryName == null)
{
FMLLog.log(Level.DEBUG, "Attempted to find the oreIDs for an unregistered object (%s). This won't work very well.", stack);
return -1;
}
else
{
id = GameData.getItemRegistry().getId(registryName);
}
List<Integer> ids = stackToId.get(id); //Try the wildcard first
if (ids == null || ids.size() == 0)
{
@@ -319,7 +337,20 @@ public class OreDictionary
Set<Integer> set = new HashSet<Integer>();
int id = Item.getIdFromItem(stack.getItem());
// HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet
// IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about.
// APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game.
String registryName = stack.getItem().delegate.name();
int id;
if (registryName == null)
{
FMLLog.log(Level.DEBUG, "Attempted to find the oreIDs for an unregistered object (%s). This won't work very well.", stack);
return new int[0];
}
else
{
id = GameData.getItemRegistry().getId(registryName);
}
List<Integer> ids = stackToId.get(id);
if (ids != null) set.addAll(ids);
ids = stackToId.get(id | ((stack.getItemDamage() + 1) << 16));
@@ -350,39 +381,39 @@ public class OreDictionary
/**
* Retrieves the List of items that are registered to this ore type at this instant.
* If the flag is TRUE, then it will create the list as empty if it did not exist.
*
*
* This option should be used by modders who are doing blanket scans in postInit.
* It greatly reduces clutter in the OreDictionary is the responsible and proper
* way to use the dictionary in a large number of cases.
*
*
* The other function above is utilized in OreRecipe and is required for the
* operation of that code.
*
*
* @param name The ore name, directly calls getOreID if the flag is TRUE
* @param alwaysCreateEntry Flag - should a new entry be created if empty
* @return An arraylist containing ItemStacks registered for this ore
*/
public static List<ItemStack> getOres(String name, boolean alwaysCreateEntry)
{
if (alwaysCreateEntry) {
return getOres(getOreID(name));
}
return nameToId.get(name) != null ? getOres(getOreID(name)) : EMPTY_LIST;
if (alwaysCreateEntry) {
return getOres(getOreID(name));
}
return nameToId.get(name) != null ? getOres(getOreID(name)) : EMPTY_LIST;
}
/**
* Returns whether or not an oreName exists in the dictionary.
* This function can be used to safely query the Ore Dictionary without
* adding needless clutter to the underlying map structure.
*
*
* Please use this when possible and appropriate.
*
*
* @param name The ore name
* @return Whether or not that name is in the Ore Dictionary.
*/
public static boolean doesOreNameExist(String name)
{
return nameToId.get(name) != null;
return nameToId.get(name) != null;
}
/**
@@ -488,12 +519,27 @@ public class OreDictionary
if (name == null || name.isEmpty() || "Unknown".equals(name)) return; //prevent bad IDs.
if (ore == null || ore.getItem() == null)
{
FMLLog.bigWarning("Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.", name);
return; //prevent bad ItemStacks.
FMLLog.bigWarning("Invalid registration attempt for an Ore Dictionary item with name %s has occurred. The registration has been denied to prevent crashes. The mod responsible for the registration needs to correct this.", name);
return; //prevent bad ItemStacks.
}
int oreID = getOreID(name);
int hash = Item.getIdFromItem(ore.getItem());
// HACK: use the registry name's ID. It is unique and it knows about substitutions. Fallback to a -1 value (what Item.getIDForItem would have returned) in the case where the registry is not aware of the item yet
// IT should be noted that -1 will fail the gate further down, if an entry already exists with value -1 for this name. This is what is broken and being warned about.
// APPARENTLY it's quite common to do this. OreDictionary should be considered alongside Recipes - you can't make them properly until you've registered with the game.
String registryName = ore.getItem().delegate.name();
int hash;
if (registryName == null)
{
FMLLog.bigWarning("A broken ore dictionary registration with name %s has occurred. It adds an item (type: %s) which is currently unknown to the game registry. This dictionary item can only support a single value when"
+ " registered with ores like this, and NO I am not going to turn this spam off. Just register your ore dictionary entries after the GameRegistry.\n"
+ "TO USERS: YES this is a BUG in the mod "+Loader.instance().activeModContainer().getName()+" report it to them!", name, ore.getItem().getClass());
hash = -1;
}
else
{
hash = GameData.getItemRegistry().getId(registryName);
}
if (ore.getItemDamage() != WILDCARD_VALUE)
{
hash |= ((ore.getItemDamage() + 1) << 16); // +1 so 0 is significant
@@ -537,7 +583,18 @@ public class OreDictionary
if (ores == null) continue;
for (ItemStack ore : ores)
{
int hash = Item.getIdFromItem(ore.getItem());
// HACK: use the registry name's ID. It is unique and it knows about substitutions
String name = ore.getItem().delegate.name();
int hash;
if (name == null)
{
FMLLog.log(Level.DEBUG, "Defaulting unregistered ore dictionary entry for ore dictionary %s: type %s to -1", getOreName(id), ore.getItem().getClass());
hash = -1;
}
else
{
hash = GameData.getItemRegistry().getId(name);
}
if (ore.getItemDamage() != WILDCARD_VALUE)
{
hash |= ((ore.getItemDamage() + 1) << 16); // +1 so meta 0 is significant