diff --git a/fml/jsons/1.7.10-dev.json b/fml/jsons/1.7.10-dev.json index 56c2dd3e9..02ab3de1e 100644 --- a/fml/jsons/1.7.10-dev.json +++ b/fml/jsons/1.7.10-dev.json @@ -126,10 +126,10 @@ "name": "io.netty:netty-all:4.0.10.Final" }, { - "name": "com.google.guava:guava:16.0" + "name": "com.google.guava:guava:17.0" }, { - "name": "org.apache.commons:commons-lang3:3.2.1" + "name": "org.apache.commons:commons-lang3:3.3.2" }, { "name": "commons-io:commons-io:2.4" diff --git a/fml/jsons/1.7.10-rel.json b/fml/jsons/1.7.10-rel.json index b56a8f63c..a13bfc3ff 100644 --- a/fml/jsons/1.7.10-rel.json +++ b/fml/jsons/1.7.10-rel.json @@ -16,8 +16,11 @@ "releaseTime": "1960-01-01T00:00:00-0700", "type": "release", "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker", - "minimumLauncherVersion": 13, - "assets": "1.7.10", + "mainClass": "net.minecraft.launchwrapper.Launch", + "minimumLauncherVersion": 14, + "assets": "@minecraft_version@", + "inheritsFrom": "@minecraft_version@", + "jar": "@minecraft_version@", "libraries": [ { "name": "@artifact@", @@ -108,165 +111,22 @@ "serverreq":true, "clientreq":true }, - { - "name": "net.sf.jopt-simple:jopt-simple:4.5", - "serverreq":true - }, { "name": "lzma:lzma:0.0.1", "serverreq":true }, { - "name": "com.mojang:realms:1.3.5" + "name": "net.sf.jopt-simple:jopt-simple:4.5", + "serverreq":true }, { - "name": "org.apache.commons:commons-compress:1.8.1" + "name": "com.google.guava:guava:17.0", + "serverreq":true }, { - "name": "org.apache.httpcomponents:httpclient:4.3.3" - }, - { - "name": "commons-logging:commons-logging:1.1.3" - }, - { - "name": "org.apache.httpcomponents:httpcore:4.3.2" - }, - { - "name": "java3d:vecmath:1.3.1" - }, - { - "name": "net.sf.trove4j:trove4j:3.0.3" - }, - { - "name": "com.ibm.icu:icu4j-core-mojang:51.2" - }, - { - "name": "com.paulscode:codecjorbis:20101023" - }, - { - "name": "com.paulscode:codecwav:20101023" - }, - { - "name": "com.paulscode:libraryjavasound:20101123" - }, - { - "name": "com.paulscode:librarylwjglopenal:20100824" - }, - { - "name": "com.paulscode:soundsystem:20120107" - }, - { - "name": "io.netty:netty-all:4.0.10.Final" - }, - { - "name": "com.google.guava:guava:16.0" - }, - { - "name": "org.apache.commons:commons-lang3:3.2.1" - }, - { - "name": "commons-io:commons-io:2.4" - }, - { - "name": "commons-codec:commons-codec:1.9" - }, - { - "name": "net.java.jinput:jinput:2.0.5" - }, - { - "name": "net.java.jutils:jutils:1.0.0" - }, - { - "name": "com.google.code.gson:gson:2.2.4" - }, - { - "name": "com.mojang:authlib:1.5.16" - }, - { - "name": "org.apache.logging.log4j:log4j-api:2.0-beta9" - }, - { - "name": "org.apache.logging.log4j:log4j-core:2.0-beta9" - }, - { - "name": "org.lwjgl.lwjgl:lwjgl:2.9.1" - }, - { - "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1" - }, - { - "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1", - "natives": { - "linux": "natives-linux", - "windows": "natives-windows", - "osx": "natives-osx" - }, - "extract": { - "exclude": [ - "META-INF/" - ] - } - }, - { - "name": "net.java.jinput:jinput-platform:2.0.5", - "natives": { - "linux": "natives-linux", - "windows": "natives-windows", - "osx": "natives-osx" - }, - "extract": { - "exclude": [ - "META-INF/" - ] - } - }, - { - "name": "tv.twitch:twitch:5.16" - }, - { - "name": "tv.twitch:twitch-platform:5.16", - "rules": [ - { - "action": "allow" - }, - { - "action": "disallow", - "os": { - "name": "linux" - } - } - ], - "natives": { - "linux": "natives-linux", - "windows": "natives-windows-${arch}", - "osx": "natives-osx" - }, - "extract": { - "exclude": [ - "META-INF/" - ] - } - }, - { - "name": "tv.twitch:twitch-external-platform:4.5", - "rules": [ - { - "action": "allow", - "os": { - "name": "windows" - } - } - ], - "natives": { - "windows": "natives-windows-${arch}" - }, - "extract": { - "exclude": [ - "META-INF/" - ] - } + "name": "org.apache.commons:commons-lang3:3.3.2", + "serverreq":true } - ], - "mainClass": "net.minecraft.launchwrapper.Launch" + ] } } diff --git a/fml/jsons/1.7.10.json b/fml/jsons/1.7.10.json index 020bda29c..595605462 100644 --- a/fml/jsons/1.7.10.json +++ b/fml/jsons/1.7.10.json @@ -74,7 +74,7 @@ "name": "com.google.code.gson:gson:2.2.4" }, { - "name": "com.mojang:authlib:1.5.16" + "name": "com.mojang:authlib:1.5.21" }, { "name": "org.apache.logging.log4j:log4j-api:2.0-beta9" diff --git a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch index da90e830c..d80d88b03 100644 --- a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraft/client/Minecraft.java +++ ../src-work/minecraft/net/minecraft/client/Minecraft.java -@@ -411,7 +411,7 @@ +@@ -410,10 +410,10 @@ this.field_110451_am = new SimpleReloadableResourceManager(this.field_110452_an); this.field_135017_as = new LanguageManager(this.field_110452_an, this.field_71474_y.field_74363_ab); this.field_110451_am.func_110542_a(this.field_135017_as); @@ -8,11 +8,47 @@ + net.minecraftforge.fml.client.FMLClientHandler.instance().beginMinecraftLoading(this, this.field_110449_ao, this.field_110451_am); this.field_71446_o = new TextureManager(this.field_110451_am); this.field_110451_am.func_110542_a(this.field_71446_o); - this.func_180510_a(this.field_71446_o); -@@ -483,12 +483,13 @@ +- this.func_180510_a(this.field_71446_o); ++ net.minecraftforge.fml.client.SplashProgress.drawVanillaScreen(this.field_71446_o); + this.func_175595_al(); + this.field_152350_aA = new SkinManager(this.field_71446_o, new File(this.field_110446_Y, "skins"), this.field_152355_az); + this.field_71469_aa = new AnvilSaveConverter(new File(this.field_71412_D, "saves")); +@@ -449,6 +449,8 @@ + } + }); + this.field_71417_B = new MouseHelper(); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar= net.minecraftforge.fml.common.ProgressManager.push("Rendering Setup", 9); ++ bar.step("GL Setup"); + this.func_71361_d("Pre startup"); + GlStateManager.func_179098_w(); + GlStateManager.func_179103_j(7425); +@@ -462,17 +464,21 @@ + GlStateManager.func_179096_D(); + GlStateManager.func_179128_n(5888); + this.func_71361_d("Startup"); ++ bar.step("Loading Texture Map"); + this.field_147128_au = new TextureMap("textures"); + this.field_147128_au.func_147633_a(this.field_71474_y.field_151442_I); + this.field_71446_o.func_110580_a(TextureMap.field_110575_b, this.field_147128_au); + this.field_71446_o.func_110577_a(TextureMap.field_110575_b); + this.field_147128_au.func_174937_a(false, this.field_71474_y.field_151442_I > 0); ++ bar.step("Loading Model Manager"); + this.field_175617_aL = new ModelManager(this.field_147128_au); + this.field_110451_am.func_110542_a(this.field_175617_aL); ++ bar.step("Loading Item Renderer"); + this.field_175621_X = new RenderItem(this.field_71446_o, this.field_175617_aL); + this.field_175616_W = new RenderManager(this.field_71446_o, this.field_175621_X); + this.field_175620_Y = new ItemRenderer(this); + this.field_110451_am.func_110542_a(this.field_175621_X); ++ bar.step("Loading Entity Renderer"); + this.field_71460_t = new EntityRenderer(this, this.field_110451_am); + this.field_110451_am.func_110542_a(this.field_71460_t); + this.field_175618_aM = new BlockRendererDispatcher(this.field_175617_aL.func_174954_c(), this.field_71474_y); +@@ -482,19 +488,21 @@ this.field_71458_u = new GuiAchievement(this); GlStateManager.func_179083_b(0, 0, this.field_71443_c, this.field_71440_d); this.field_71452_i = new EffectRenderer(this.field_71441_e, this.field_71446_o); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + net.minecraftforge.fml.client.FMLClientHandler.instance().finishMinecraftLoading(); this.func_71361_d("Post startup"); this.field_71456_v = new GuiIngame(this); @@ -24,7 +60,15 @@ } else { -@@ -504,6 +505,7 @@ + this.func_147108_a(new GuiMainMenu()); + } + +- this.field_71446_o.func_147645_c(this.field_152354_ay); ++ net.minecraftforge.fml.client.SplashProgress.clearVanillaResources(field_71446_o, field_152354_ay); + this.field_152354_ay = null; + this.field_71461_s = new LoadingScreenRenderer(this); + +@@ -503,6 +511,7 @@ this.func_71352_k(); } @@ -32,7 +76,7 @@ try { Display.setVSyncEnabled(this.field_71474_y.field_74352_v); -@@ -682,21 +684,23 @@ +@@ -681,21 +690,23 @@ File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt"); Bootstrap.func_179870_a(p_71377_1_.func_71502_e()); @@ -59,7 +103,7 @@ } public boolean func_152349_b() -@@ -1000,7 +1004,7 @@ +@@ -999,7 +1010,7 @@ { while (!this.field_152351_aB.isEmpty()) { @@ -68,7 +112,7 @@ } } -@@ -1035,9 +1039,11 @@ +@@ -1034,9 +1045,11 @@ if (!this.field_71454_w) { @@ -80,7 +124,7 @@ } this.field_71424_I.func_76319_b(); -@@ -1592,6 +1598,8 @@ +@@ -1591,6 +1604,8 @@ --this.field_71467_ac; } @@ -89,7 +133,7 @@ this.field_71424_I.func_76320_a("gui"); if (!this.field_71445_n) -@@ -1745,6 +1753,7 @@ +@@ -1744,6 +1759,7 @@ this.field_71462_r.func_146274_d(); } } @@ -97,7 +141,7 @@ } if (this.field_71429_W > 0) -@@ -1921,6 +1930,7 @@ +@@ -1920,6 +1936,7 @@ } } } @@ -105,7 +149,7 @@ } for (i = 0; i < 9; ++i) -@@ -2121,12 +2131,15 @@ +@@ -2120,12 +2137,15 @@ this.field_71453_ak.func_74428_b(); } @@ -121,7 +165,7 @@ this.func_71403_a((WorldClient)null); System.gc(); ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false); -@@ -2162,6 +2175,12 @@ +@@ -2161,6 +2181,12 @@ while (!this.field_71437_Z.func_71200_ad()) { @@ -134,7 +178,7 @@ String s2 = this.field_71437_Z.func_71195_b_(); if (s2 != null) -@@ -2187,7 +2206,7 @@ +@@ -2186,7 +2212,7 @@ SocketAddress socketaddress = this.field_71437_Z.func_147137_ag().func_151270_a(); NetworkManager networkmanager = NetworkManager.func_150722_a(socketaddress); networkmanager.func_150719_a(new NetHandlerLoginClient(networkmanager, this, (GuiScreen)null)); @@ -143,7 +187,7 @@ networkmanager.func_179290_a(new C00PacketLoginStart(this.func_110432_I().func_148256_e())); this.field_71453_ak = networkmanager; } -@@ -2238,6 +2257,7 @@ +@@ -2237,6 +2263,7 @@ this.func_71351_a((ServerData)null); this.field_71455_al = false; diff --git a/fml/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch b/fml/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch new file mode 100644 index 000000000..7272aef7c --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/client/gui/FontRenderer.java.patch @@ -0,0 +1,126 @@ +--- ../src-base/minecraft/net/minecraft/client/gui/FontRenderer.java ++++ ../src-work/minecraft/net/minecraft/client/gui/FontRenderer.java +@@ -57,7 +57,7 @@ + this.field_111273_g = p_i1035_2_; + this.field_78298_i = p_i1035_3_; + this.field_78293_l = p_i1035_4_; +- p_i1035_3_.func_110577_a(this.field_111273_g); ++ bindTexture(this.field_111273_g); + + for (int i = 0; i < 32; ++i) + { +@@ -105,7 +105,7 @@ + + try + { +- bufferedimage = TextureUtil.func_177053_a(Minecraft.func_71410_x().func_110442_L().func_110536_a(this.field_111273_g).func_110527_b()); ++ bufferedimage = TextureUtil.func_177053_a(getResourceInputStream(this.field_111273_g)); + } + catch (IOException ioexception) + { +@@ -172,7 +172,7 @@ + + try + { +- inputstream = Minecraft.func_71410_x().func_110442_L().func_110536_a(new ResourceLocation("font/glyph_sizes.bin")).func_110527_b(); ++ inputstream = getResourceInputStream(new ResourceLocation("font/glyph_sizes.bin")); + inputstream.read(this.field_78287_e); + } + catch (IOException ioexception) +@@ -195,7 +195,7 @@ + float f = (float)(p_78266_1_ % 16 * 8); + float f1 = (float)(p_78266_1_ / 16 * 8); + float f2 = p_78266_2_ ? 1.0F : 0.0F; +- this.field_78298_i.func_110577_a(this.field_111273_g); ++ bindTexture(this.field_111273_g); + float f3 = (float)this.field_78286_d[p_78266_1_] - 0.01F; + GL11.glBegin(GL11.GL_TRIANGLE_STRIP); + GL11.glTexCoord2f(f / 128.0F, f1 / 128.0F); +@@ -222,7 +222,7 @@ + + private void func_78257_a(int p_78257_1_) + { +- this.field_78298_i.func_110577_a(this.func_111271_a(p_78257_1_)); ++ bindTexture(this.func_111271_a(p_78257_1_)); + } + + protected float func_78277_a(char p_78277_1_, boolean p_78277_2_) +@@ -269,7 +269,7 @@ + + public int func_175065_a(String p_175065_1_, float p_175065_2_, float p_175065_3_, int p_175065_4_, boolean p_175065_5_) + { +- GlStateManager.func_179141_d(); ++ enableAlpha(); + this.func_78265_b(); + int j; + +@@ -341,7 +341,7 @@ + + k = this.field_78285_g[j]; + this.field_78304_r = k; +- GlStateManager.func_179131_c((float)(k >> 16) / 255.0F, (float)(k >> 8 & 255) / 255.0F, (float)(k & 255) / 255.0F, this.field_78305_q); ++ setColor((float)(k >> 16) / 255.0F, (float)(k >> 8 & 255) / 255.0F, (float)(k & 255) / 255.0F, this.field_78305_q); + } + else if (j == 16) + { +@@ -370,7 +370,7 @@ + this.field_78299_w = false; + this.field_78300_v = false; + this.field_78301_u = false; +- GlStateManager.func_179131_c(this.field_78291_n, this.field_78292_o, this.field_78306_p, this.field_78305_q); ++ setColor(this.field_78291_n, this.field_78292_o, this.field_78306_p, this.field_78305_q); + } + + ++i; +@@ -429,6 +429,15 @@ + ++f; + } + ++ doDraw(f); ++ } ++ } ++ } ++ ++ protected void doDraw(float f) ++ { ++ { ++ { + Tessellator tessellator; + WorldRenderer worldrenderer; + +@@ -504,7 +513,7 @@ + this.field_78292_o = (float)(p_180455_4_ >> 8 & 255) / 255.0F; + this.field_78306_p = (float)(p_180455_4_ & 255) / 255.0F; + this.field_78305_q = (float)(p_180455_4_ >> 24 & 255) / 255.0F; +- GlStateManager.func_179131_c(this.field_78291_n, this.field_78292_o, this.field_78306_p, this.field_78305_q); ++ setColor(this.field_78291_n, this.field_78292_o, this.field_78306_p, this.field_78305_q); + this.field_78295_j = p_180455_2_; + this.field_78296_k = p_180455_3_; + this.func_78255_a(p_180455_1_, p_180455_5_); +@@ -842,6 +851,26 @@ + return this.field_78294_m; + } + ++ protected void setColor(float r, float g, float b, float a) ++ { ++ GlStateManager.func_179131_c(r,g,b,a); ++ } ++ ++ protected void enableAlpha() ++ { ++ GlStateManager.func_179141_d(); ++ } ++ ++ protected void bindTexture(ResourceLocation location) ++ { ++ field_78298_i.func_110577_a(location); ++ } ++ ++ protected InputStream getResourceInputStream(ResourceLocation location) throws IOException ++ { ++ return Minecraft.func_71410_x().func_110442_L().func_110536_a(location).func_110527_b(); ++ } ++ + public int func_175064_b(char p_175064_1_) + { + return this.field_78285_g["0123456789abcdef".indexOf(p_175064_1_)]; diff --git a/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch b/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch new file mode 100644 index 000000000..2f6291fc4 --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureMap.java.patch @@ -0,0 +1,91 @@ +--- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureMap.java ++++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureMap.java +@@ -91,6 +91,7 @@ + this.field_94258_i.clear(); + int j = Integer.MAX_VALUE; + int k = 1 << this.field_147636_j; ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar bar = net.minecraftforge.fml.common.ProgressManager.push("Texture stitching", this.field_110574_e.size()); + Iterator iterator = this.field_110574_e.entrySet().iterator(); + + while (iterator.hasNext()) +@@ -99,6 +100,7 @@ + TextureAtlasSprite textureatlassprite = (TextureAtlasSprite)entry.getValue(); + ResourceLocation resourcelocation = new ResourceLocation(textureatlassprite.func_94215_i()); + ResourceLocation resourcelocation1 = this.func_147634_a(resourcelocation, 0); ++ bar.step(resourcelocation1.func_110623_a()); + + try + { +@@ -150,12 +152,14 @@ + } + catch (RuntimeException runtimeexception) + { +- field_147635_d.error("Unable to parse metadata from " + resourcelocation1, runtimeexception); ++ //logger.error("Unable to parse metadata from " + resourcelocation1, runtimeexception); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().trackBrokenTexture(resourcelocation1, runtimeexception.getMessage()); + continue; + } + catch (IOException ioexception1) + { +- field_147635_d.error("Using missing texture, unable to load " + resourcelocation1, ioexception1); ++ //logger.error("Using missing texture, unable to load " + resourcelocation1, ioexception1); ++ net.minecraftforge.fml.client.FMLClientHandler.instance().trackMissingTexture(resourcelocation1); + continue; + } + +@@ -171,6 +175,7 @@ + stitcher.func_110934_a(textureatlassprite); + } + ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + int j1 = Math.min(j, k); + int k1 = MathHelper.func_151239_c(j1); + +@@ -181,10 +186,12 @@ + } + + Iterator iterator1 = this.field_110574_e.values().iterator(); ++ bar = net.minecraftforge.fml.common.ProgressManager.push("Mipmap generation", this.field_110574_e.size()); + + while (iterator1.hasNext()) + { + final TextureAtlasSprite textureatlassprite1 = (TextureAtlasSprite)iterator1.next(); ++ bar.step(textureatlassprite1.func_94215_i()); + + try + { +@@ -225,9 +232,12 @@ + + this.field_94249_f.func_147963_d(this.field_147636_j); + stitcher.func_110934_a(this.field_94249_f); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); ++ bar = net.minecraftforge.fml.common.ProgressManager.push("Texture creation", 3); + + try + { ++ bar.step("Stitching"); + stitcher.func_94305_f(); + } + catch (StitcherException stitcherexception) +@@ -236,11 +246,13 @@ + } + + 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}); ++ bar.step("Allocating GL texture"); + TextureUtil.func_180600_a(this.func_110552_b(), this.field_147636_j, stitcher.func_110935_a(), stitcher.func_110936_b()); + HashMap hashmap = Maps.newHashMap(this.field_110574_e); + Iterator iterator2 = stitcher.func_94309_g().iterator(); + TextureAtlasSprite textureatlassprite2; + ++ bar.step("Uploading GL texture"); + while (iterator2.hasNext()) + { + textureatlassprite2 = (TextureAtlasSprite)iterator2.next(); +@@ -276,6 +288,7 @@ + } + + TextureUtil.func_177055_a(this.field_94254_c.replaceAll("/", "_"), this.func_110552_b(), this.field_147636_j, stitcher.func_110935_a(), stitcher.func_110936_b()); ++ net.minecraftforge.fml.common.ProgressManager.pop(bar); + } + + private ResourceLocation func_147634_a(ResourceLocation p_147634_1_, int p_147634_2_) diff --git a/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch b/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch new file mode 100644 index 000000000..4e5c66c9f --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java ++++ ../src-work/minecraft/net/minecraft/client/renderer/texture/TextureUtil.java +@@ -202,9 +202,11 @@ + + public static void func_180600_a(int p_180600_0_, int p_180600_1_, int p_180600_2_, int p_180600_3_) + { ++ synchronized (net.minecraftforge.fml.client.SplashProgress.class) ++ { + func_147942_a(p_180600_0_); + func_94277_a(p_180600_0_); +- ++ } + if (p_180600_1_ >= 0) + { + GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, p_180600_1_); diff --git a/fml/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch b/fml/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch new file mode 100644 index 000000000..feee903f7 --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/client/resources/AbstractResourcePack.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/client/resources/AbstractResourcePack.java ++++ ../src-work/minecraft/net/minecraft/client/resources/AbstractResourcePack.java +@@ -58,7 +58,7 @@ + + protected void func_110594_c(String p_110594_1_) + { +- field_110598_a.warn("ResourcePack: ignored non-lowercase namespace: %s in %s", new Object[] {p_110594_1_, this.field_110597_b}); ++ field_110598_a.warn("ResourcePack: ignored non-lowercase namespace: {} in {}", new Object[] {p_110594_1_, this.field_110597_b}); + } + + public IMetadataSection func_135058_a(IMetadataSerializer p_135058_1_, String p_135058_2_) throws IOException diff --git a/fml/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch b/fml/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch new file mode 100644 index 000000000..f6bef8704 --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java.patch @@ -0,0 +1,46 @@ +--- ../src-base/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java ++++ ../src-work/minecraft/net/minecraft/client/resources/SimpleReloadableResourceManager.java +@@ -95,6 +95,7 @@ + public void func_110541_a(List p_110541_1_) + { + this.func_110543_a(); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resources", p_110541_1_.size()+1); + field_147967_a.info("Reloading ResourceManager: " + field_130074_a.join(Iterables.transform(p_110541_1_, new Function() + { + private static final String __OBFID = "CL_00001092"; +@@ -112,26 +113,35 @@ + while (iterator.hasNext()) + { + IResourcePack iresourcepack = (IResourcePack)iterator.next(); ++ resReload.step(iresourcepack.func_130077_b()); + this.func_110545_a(iresourcepack); + } + ++ resReload.step("Reloading listeners"); + this.func_110544_b(); ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + + public void func_110542_a(IResourceManagerReloadListener p_110542_1_) + { + this.field_110546_b.add(p_110542_1_); ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Loading Resource", 1); ++ resReload.step(p_110542_1_.getClass()); + p_110542_1_.func_110549_a(this); ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + + private void func_110544_b() + { + Iterator iterator = this.field_110546_b.iterator(); + ++ net.minecraftforge.fml.common.ProgressManager.ProgressBar resReload = net.minecraftforge.fml.common.ProgressManager.push("Reloading", this.field_110546_b.size()); + while (iterator.hasNext()) + { + IResourceManagerReloadListener iresourcemanagerreloadlistener = (IResourceManagerReloadListener)iterator.next(); ++ resReload.step(iresourcemanagerreloadlistener.getClass()); + iresourcemanagerreloadlistener.func_110549_a(this); + } ++ net.minecraftforge.fml.common.ProgressManager.pop(resReload); + } + } diff --git a/fml/patches/minecraft/net/minecraft/server/management/PlayerProfileCache.java.patch b/fml/patches/minecraft/net/minecraft/server/management/PlayerProfileCache.java.patch new file mode 100644 index 000000000..93c276883 --- /dev/null +++ b/fml/patches/minecraft/net/minecraft/server/management/PlayerProfileCache.java.patch @@ -0,0 +1,50 @@ +--- ../src-base/minecraft/net/minecraft/server/management/PlayerProfileCache.java ++++ ../src-work/minecraft/net/minecraft/server/management/PlayerProfileCache.java +@@ -204,26 +204,12 @@ + { + List list = null; + BufferedReader bufferedreader = null; +- label64: + { + try + { + bufferedreader = Files.newReader(this.field_152665_g, Charsets.UTF_8); + list = (List)this.field_152660_b.fromJson(bufferedreader, field_152666_h); +- break label64; +- } +- catch (FileNotFoundException filenotfoundexception) +- { +- ; +- } +- finally +- { +- IOUtils.closeQuietly(bufferedreader); +- } + +- return; +- } +- + if (list != null) + { + this.field_152661_c.clear(); +@@ -242,6 +228,20 @@ + } + } + } ++ } ++ catch (FileNotFoundException filenotfoundexception) ++ { ++ ; ++ } ++ catch (com.google.gson.JsonParseException parsefail) ++ { ++ // No op - the cache can quietly rebuild if it's junk ++ } ++ finally ++ { ++ IOUtils.closeQuietly(bufferedreader); ++ } ++ } + } + + public void func_152658_c() diff --git a/fml/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java b/fml/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java index b680df20e..b270de9be 100644 --- a/fml/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java +++ b/fml/src/main/java/net/minecraftforge/fml/client/FMLClientHandler.java @@ -41,8 +41,11 @@ import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.OldServerPinger; import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.resources.AbstractResourcePack; +import net.minecraft.client.resources.FallbackResourceManager; import net.minecraft.client.resources.IReloadableResourceManager; import net.minecraft.client.resources.IResourcePack; +import net.minecraft.client.resources.SimpleReloadableResourceManager; import net.minecraft.crash.CrashReport; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -69,6 +72,7 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry; import net.minecraftforge.fml.common.DummyModContainer; import net.minecraftforge.fml.common.DuplicateModsFoundException; import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.FMLContainerHolder; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.IFMLSidedHandler; import net.minecraftforge.fml.common.Loader; @@ -89,16 +93,25 @@ import net.minecraftforge.fml.common.toposort.ModSortingException; import net.minecraftforge.fml.relauncher.Side; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.lwjgl.LWJGLUtil; import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; import com.google.common.base.Strings; import com.google.common.base.Throwables; import com.google.common.collect.BiMap; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashBiMap; +import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.Maps; +import com.google.common.collect.SetMultimap; +import com.google.common.collect.Sets; +import com.google.common.collect.Table; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -178,6 +191,8 @@ public class FMLClientHandler implements IFMLSidedHandler @SuppressWarnings("unchecked") public void beginMinecraftLoading(Minecraft minecraft, @SuppressWarnings("rawtypes") List resourcePackList, IReloadableResourceManager resourceManager) { + detectOptifine(); + SplashProgress.start(); client = minecraft; this.resourcePackList = resourcePackList; this.resourceManager = resourceManager; @@ -191,19 +206,6 @@ public class FMLClientHandler implements IFMLSidedHandler FMLCommonHandler.instance().beginLoading(this); try - { - Class optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader()); - String optifineVersion = (String) optifineConfig.getField("VERSION").get(null); - Map dummyOptifineMeta = ImmutableMap.builder().put("name", "Optifine").put("version", optifineVersion).build(); - ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info"),"optifine").getMetadataForId("optifine", dummyOptifineMeta); - optifineContainer = new DummyModContainer(optifineMetadata); - FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion()); - } - catch (Exception e) - { - optifineContainer = null; - } - try { Loader.instance().loadMods(); } @@ -269,9 +271,27 @@ public class FMLClientHandler implements IFMLSidedHandler } } + private void detectOptifine() + { + try + { + Class optifineConfig = Class.forName("Config", false, Loader.instance().getModClassLoader()); + String optifineVersion = (String) optifineConfig.getField("VERSION").get(null); + Map dummyOptifineMeta = ImmutableMap.builder().put("name", "Optifine").put("version", optifineVersion).build(); + ModMetadata optifineMetadata = MetadataCollection.from(getClass().getResourceAsStream("optifinemod.info"),"optifine").getMetadataForId("optifine", dummyOptifineMeta); + optifineContainer = new DummyModContainer(optifineMetadata); + FMLLog.info("Forge Mod Loader has detected optifine %s, enabling compatibility features",optifineContainer.getVersion()); + } + catch (Exception e) + { + optifineContainer = null; + } + } + @Override public void haltGame(String message, Throwable t) { + SplashProgress.finish(); client.displayCrashReport(new CrashReport(message, t)); throw Throwables.propagate(t); } @@ -284,6 +304,7 @@ public class FMLClientHandler implements IFMLSidedHandler { if (modsMissing != null || wrongMC != null || customError!=null || dupesFound!=null || modSorting!=null) { + SplashProgress.finish(); return; } try @@ -294,6 +315,7 @@ public class FMLClientHandler implements IFMLSidedHandler { FMLLog.log(Level.ERROR, custom, "A custom exception was thrown by a mod, the game will now halt"); customError = custom; + SplashProgress.finish(); return; } catch (LoaderException le) @@ -379,7 +401,10 @@ public class FMLClientHandler implements IFMLSidedHandler } else { + Loader.instance().loadingComplete(); + SplashProgress.finish(); } + logMissingTextureErrors(); } /** * Get the server instance @@ -863,4 +888,111 @@ public class FMLClientHandler implements IFMLSidedHandler net instanceof INetHandlerStatusServer) return getServer(); throw new RuntimeException("Unknown INetHandler: " + net); } + + private SetMultimap missingTextures = HashMultimap.create(); + private Set badTextureDomains = Sets.newHashSet(); + private Table> brokenTextures = HashBasedTable.create(); + + public void trackMissingTexture(ResourceLocation resourceLocation) + { + badTextureDomains.add(resourceLocation.getResourceDomain()); + missingTextures.put(resourceLocation.getResourceDomain(),resourceLocation); + } + + public void trackBrokenTexture(ResourceLocation resourceLocation, String error) + { + badTextureDomains.add(resourceLocation.getResourceDomain()); + Set badType = brokenTextures.get(resourceLocation.getResourceDomain(), error); + if (badType == null) + { + badType = Sets.newHashSet(); + brokenTextures.put(resourceLocation.getResourceDomain(), error, badType); + } + badType.add(resourceLocation); + } + + public void logMissingTextureErrors() + { + if (missingTextures.isEmpty() && brokenTextures.isEmpty()) + { + return; + } + Logger logger = LogManager.getLogger("TEXTURE ERRORS"); + logger.error(Strings.repeat("+=", 25)); + logger.error("The following texture errors were found."); + Map resManagers = ObfuscationReflectionHelper.getPrivateValue(SimpleReloadableResourceManager.class, (SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager(), "domainResourceManagers", "field_110548"+"_a"); + for (String resourceDomain : missingTextures.keySet()) + { + Set missing = missingTextures.get(resourceDomain); + logger.error(Strings.repeat("=", 50)); + logger.error(" DOMAIN {}", resourceDomain); + logger.error(Strings.repeat("-", 50)); + logger.error(" domain {} is missing {} texture{}",resourceDomain, missing.size(),missing.size()!=1 ? "s" : ""); + FallbackResourceManager fallbackResourceManager = resManagers.get(resourceDomain); + if (fallbackResourceManager == null) + { + logger.error(" domain {} is missing a resource manager - it is probably a side-effect of automatic texture processing", resourceDomain); + } + else + { + List resPacks = ObfuscationReflectionHelper.getPrivateValue(FallbackResourceManager.class, fallbackResourceManager, "resourcePacks","field_110540"+"_a"); + logger.error(" domain {} has {} location{}:",resourceDomain, resPacks.size(), resPacks.size() != 1 ? "s" :""); + for (IResourcePack resPack : resPacks) + { + if (resPack instanceof FMLContainerHolder) { + FMLContainerHolder containerHolder = (FMLContainerHolder) resPack; + ModContainer fmlContainer = containerHolder.getFMLContainer(); + logger.error(" mod {} resources at {}", fmlContainer.getModId(), fmlContainer.getSource().getPath()); + } + else if (resPack instanceof AbstractResourcePack) + { + AbstractResourcePack resourcePack = (AbstractResourcePack) resPack; + File resPath = ObfuscationReflectionHelper.getPrivateValue(AbstractResourcePack.class, resourcePack, "resourcePackFile","field_110597"+"_b"); + logger.error(" resource pack at path {}",resPath.getPath()); + } + else + { + logger.error(" unknown resourcepack type {} : {}", resPack.getClass().getName(), resPack.getPackName()); + } + } + } + logger.error(Strings.repeat("-", 25)); + logger.error(" The missing resources for domain {} are:",resourceDomain); + for (ResourceLocation rl : missing) + { + logger.error(" {}",rl.getResourcePath()); + } + logger.error(Strings.repeat("-", 25)); + if (!brokenTextures.containsRow(resourceDomain)) + { + logger.error(" No other errors exist for domain {}", resourceDomain); + } + else + { + logger.error(" The following other errors were reported for domain {}:",resourceDomain); + Map> resourceErrs = brokenTextures.row(resourceDomain); + for (String error: resourceErrs.keySet()) + { + logger.error(Strings.repeat("-", 25)); + logger.error(" Problem: {}", error); + for (ResourceLocation rl : resourceErrs.get(error)) + { + logger.error(" {}",rl.getResourcePath()); + } + } + } + logger.error(Strings.repeat("=", 50)); + } + logger.error(Strings.repeat("+=", 25)); + } + + @Override + public void processWindowMessages() + { + // workaround for windows requiring messages being processed on the main thread + if(LWJGLUtil.getPlatform() == LWJGLUtil.PLATFORM_WINDOWS) + { + Display.processMessages(); + } + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java b/fml/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java index 9ea3c43e7..3738a6ef8 100644 --- a/fml/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java +++ b/fml/src/main/java/net/minecraftforge/fml/client/FMLFileResourcePack.java @@ -10,12 +10,13 @@ import org.apache.logging.log4j.Level; import javax.imageio.ImageIO; import net.minecraft.client.resources.FileResourcePack; +import net.minecraftforge.fml.common.FMLContainerHolder; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.ModContainer; import com.google.common.base.Charsets; -public class FMLFileResourcePack extends FileResourcePack { +public class FMLFileResourcePack extends FileResourcePack implements FMLContainerHolder { private ModContainer container; @@ -58,4 +59,10 @@ public class FMLFileResourcePack extends FileResourcePack { { return ImageIO.read(getInputStreamByName(container.getMetadata().logoFile)); } + + @Override + public ModContainer getFMLContainer() + { + return container; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java b/fml/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java index a3e7a2413..c56319728 100644 --- a/fml/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java +++ b/fml/src/main/java/net/minecraftforge/fml/client/FMLFolderResourcePack.java @@ -10,12 +10,13 @@ import org.apache.logging.log4j.Level; import javax.imageio.ImageIO; import net.minecraft.client.resources.FolderResourcePack; +import net.minecraftforge.fml.common.FMLContainerHolder; import net.minecraftforge.fml.common.FMLLog; import net.minecraftforge.fml.common.ModContainer; import com.google.common.base.Charsets; -public class FMLFolderResourcePack extends FolderResourcePack { +public class FMLFolderResourcePack extends FolderResourcePack implements FMLContainerHolder { private ModContainer container; @@ -64,4 +65,10 @@ public class FMLFolderResourcePack extends FolderResourcePack { return ImageIO.read(getInputStreamByName(container.getMetadata().logoFile)); } + @Override + public ModContainer getFMLContainer() + { + return container; + } + } diff --git a/fml/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java b/fml/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java index e632835de..14c53287c 100644 --- a/fml/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java +++ b/fml/src/main/java/net/minecraftforge/fml/client/GuiModsMissing.java @@ -58,6 +58,6 @@ public class GuiModsMissing extends GuiErrorScreen this.drawCenteredString(this.fontRendererObj, String.format("%s : %s", v.getLabel(), v.getRangeString()), this.width / 2, offset, 0xEEEEEE); } offset+=20; - this.drawCenteredString(this.fontRendererObj, "The file 'ForgeModLoader-client-0.log' contains more information", this.width / 2, offset, 0xFFFFFF); + this.drawCenteredString(this.fontRendererObj, "The file 'logs/fml-client-latest.log' contains more information", this.width / 2, offset, 0xFFFFFF); } } diff --git a/fml/src/main/java/net/minecraftforge/fml/client/SplashProgress.java b/fml/src/main/java/net/minecraftforge/fml/client/SplashProgress.java new file mode 100644 index 000000000..c778182d1 --- /dev/null +++ b/fml/src/main/java/net/minecraftforge/fml/client/SplashProgress.java @@ -0,0 +1,740 @@ +package net.minecraftforge.fml.client; + +import static org.lwjgl.opengl.GL11.GL_ALPHA_TEST; +import static org.lwjgl.opengl.GL11.GL_BLEND; +import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; +import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; +import static org.lwjgl.opengl.GL11.GL_GREATER; +import static org.lwjgl.opengl.GL11.GL_LEQUAL; +import static org.lwjgl.opengl.GL11.GL_LIGHTING; +import static org.lwjgl.opengl.GL11.GL_MODELVIEW; +import static org.lwjgl.opengl.GL11.GL_NEAREST; +import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_PROJECTION; +import static org.lwjgl.opengl.GL11.GL_QUADS; +import static org.lwjgl.opengl.GL11.GL_RENDERER; +import static org.lwjgl.opengl.GL11.GL_RGBA; +import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER; +import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER; +import static org.lwjgl.opengl.GL11.GL_VENDOR; +import static org.lwjgl.opengl.GL11.GL_VERSION; +import static org.lwjgl.opengl.GL11.glAlphaFunc; +import static org.lwjgl.opengl.GL11.glBegin; +import static org.lwjgl.opengl.GL11.glBindTexture; +import static org.lwjgl.opengl.GL11.glBlendFunc; +import static org.lwjgl.opengl.GL11.glClear; +import static org.lwjgl.opengl.GL11.glClearColor; +import static org.lwjgl.opengl.GL11.glColor3ub; +import static org.lwjgl.opengl.GL11.glDeleteTextures; +import static org.lwjgl.opengl.GL11.glDepthFunc; +import static org.lwjgl.opengl.GL11.glDisable; +import static org.lwjgl.opengl.GL11.glEnable; +import static org.lwjgl.opengl.GL11.glEnd; +import static org.lwjgl.opengl.GL11.glGenTextures; +import static org.lwjgl.opengl.GL11.glGetString; +import static org.lwjgl.opengl.GL11.glLoadIdentity; +import static org.lwjgl.opengl.GL11.glMatrixMode; +import static org.lwjgl.opengl.GL11.glOrtho; +import static org.lwjgl.opengl.GL11.glPopMatrix; +import static org.lwjgl.opengl.GL11.glPushMatrix; +import static org.lwjgl.opengl.GL11.glRotatef; +import static org.lwjgl.opengl.GL11.glScalef; +import static org.lwjgl.opengl.GL11.glTexCoord2f; +import static org.lwjgl.opengl.GL11.glTexImage2D; +import static org.lwjgl.opengl.GL11.glTexParameteri; +import static org.lwjgl.opengl.GL11.glTexSubImage2D; +import static org.lwjgl.opengl.GL11.glTranslatef; +import static org.lwjgl.opengl.GL11.glVertex2f; +import static org.lwjgl.opengl.GL11.glViewport; +import static org.lwjgl.opengl.GL12.GL_BGRA; +import static org.lwjgl.opengl.GL12.GL_UNSIGNED_INT_8_8_8_8_REV; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.lang.Thread.UncaughtExceptionHandler; +import java.nio.IntBuffer; +import java.util.Iterator; +import java.util.Properties; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.resources.FileResourcePack; +import net.minecraft.client.resources.FolderResourcePack; +import net.minecraft.client.resources.IResourcePack; +import net.minecraft.crash.CrashReport; +import net.minecraft.launchwrapper.Launch; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.FMLLog; +import net.minecraftforge.fml.common.ICrashCallable; +import net.minecraftforge.fml.common.ProgressManager; +import net.minecraftforge.fml.common.ProgressManager.ProgressBar; +import net.minecraftforge.fml.common.asm.FMLSanityChecker; + +import org.apache.commons.io.IOUtils; +import org.apache.logging.log4j.Level; +import org.lwjgl.BufferUtils; +import org.lwjgl.LWJGLException; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.Drawable; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.SharedDrawable; +import org.lwjgl.util.glu.GLU; + +/** + * @deprecated not a stable API, will break, don't use this yet + */ +@Deprecated +public class SplashProgress +{ + private static Drawable d; + private static volatile boolean pause = false; + private static volatile boolean done = false; + private static Thread thread; + private static volatile Throwable threadError; + private static int angle = 0; + private static final Lock lock = new ReentrantLock(true); + private static SplashFontRenderer fontRenderer; + + private static final IResourcePack mcPack = Minecraft.getMinecraft().mcDefaultResourcePack; + private static final IResourcePack fmlPack = createResourcePack(FMLSanityChecker.fmlLocation); + private static IResourcePack miscPack; + + private static Texture fontTexture; + private static Texture logoTexture; + private static Texture forgeTexture; + + private static Properties config; + + private static boolean enabled; + private static boolean rotate; + private static int logoOffset; + private static int backgroundColor; + private static int fontColor; + private static int barBorderColor; + private static int barColor; + private static int barBackgroundColor; + + private static String getString(String name, String def) + { + String value = config.getProperty(name, def); + config.setProperty(name, value); + return value; + } + + private static boolean getBool(String name, boolean def) + { + return Boolean.parseBoolean(getString(name, Boolean.toString(def))); + } + + private static int getInt(String name, int def) + { + return Integer.decode(getString(name, Integer.toString(def))); + } + + private static int getHex(String name, int def) + { + return Integer.decode(getString(name, "0x" + Integer.toString(def, 16).toUpperCase())); + } + + public static void start() + { + File configFile = new File(Minecraft.getMinecraft().mcDataDir, "config/splash.properties"); + FileReader r = null; + config = new Properties(); + try + { + r = new FileReader(configFile); + config.load(r); + } + catch(IOException e) + { + FMLLog.info("Could not load splash.properties, will create a default one"); + } + finally + { + IOUtils.closeQuietly(r); + } + + // Enable if we have the flag, and there's either no optifine, or optifine has added a key to the blackboard ("optifine.ForgeSplashCompatible") + // Optifine authors - add this key to the blackboard if you feel your modifications are now compatible with this code. + enabled = getBool("enabled", true) && ( (!FMLClientHandler.instance().hasOptifine()) || Launch.blackboard.containsKey("optifine.ForgeSplashCompatible")); + rotate = getBool("rotate", false); + logoOffset = getInt("logoOffset", 0); + backgroundColor = getHex("background", 0xFFFFFF); + fontColor = getHex("font", 0x000000); + barBorderColor = getHex("barBorder", 0xC0C0C0); + barColor = getHex("bar", 0xCB3D35); + barBackgroundColor = getHex("barBackground", 0xFFFFFF); + + final ResourceLocation fontLoc = new ResourceLocation(getString("fontTexture", "textures/font/ascii.png")); + final ResourceLocation logoLoc = new ResourceLocation(getString("logoTexture", "textures/gui/title/mojang.png")); + final ResourceLocation forgeLoc = new ResourceLocation(getString("forgeTexture", "fml:textures/gui/forge.gif")); + + File miscPackFile = new File(Minecraft.getMinecraft().mcDataDir, getString("resourcePackPath", "resources")); + + 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"); + } + finally + { + IOUtils.closeQuietly(w); + } + + miscPack = createResourcePack(miscPackFile); + + if(!enabled) return; + // getting debug info out of the way, while we still can + FMLCommonHandler.instance().registerCrashCallable(new ICrashCallable() + { + public String call() throws Exception + { + return "' Vendor: '" + glGetString(GL_VENDOR) + + "' Version: '" + glGetString(GL_VERSION) + + "' Renderer: '" + glGetString(GL_RENDERER) + + "'"; + } + + public String getLabel() + { + return "GL info"; + } + }); + CrashReport report = CrashReport.makeCrashReport(new Throwable(), "Loading screen debug info"); + System.out.println(report.getCompleteReport()); + + try + { + d = new SharedDrawable(Display.getDrawable()); + Display.getDrawable().releaseContext(); + d.makeCurrent(); + } + catch (LWJGLException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + Thread mainThread = Thread.currentThread(); + thread = new Thread(new Runnable() + { + private final int barWidth = 400; + private final int barHeight = 20; + private final int textHeight2 = 20; + private final int barOffset = 55; + + public void run() + { + setGL(); + fontTexture = new Texture(fontLoc); + logoTexture = new Texture(logoLoc); + forgeTexture = new Texture(forgeLoc); + glEnable(GL_TEXTURE_2D); + fontRenderer = new SplashFontRenderer(); + glDisable(GL_TEXTURE_2D); + while(!done) + { + ProgressBar first = null, penult = null, last = null; + Iterator i = ProgressManager.barIterator(); + while(i.hasNext()) + { + if(first == null) first = i.next(); + else + { + penult = last; + last = i.next(); + } + } + + glClear(GL_COLOR_BUFFER_BIT); + + // matrix setup + int w = Display.getWidth(); + int h = Display.getHeight(); + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(320 - w/2, 320 + w/2, 240 + h/2, 240 - h/2, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // mojang logo + setColor(backgroundColor); + glEnable(GL_TEXTURE_2D); + logoTexture.bind(); + glBegin(GL_QUADS); + logoTexture.texCoord(0, 0, 0); + glVertex2f(320 - 256, 240 - 256); + logoTexture.texCoord(0, 0, 1); + glVertex2f(320 - 256, 240 + 256); + logoTexture.texCoord(0, 1, 1); + glVertex2f(320 + 256, 240 + 256); + logoTexture.texCoord(0, 1, 0); + glVertex2f(320 + 256, 240 - 256); + glEnd(); + glDisable(GL_TEXTURE_2D); + + // bars + if(first != null) + { + glPushMatrix(); + glTranslatef(320 - (float)barWidth / 2, 310, 0); + drawBar(first); + if(penult != null) + { + glTranslatef(0, barOffset, 0); + drawBar(penult); + } + if(last != null) + { + glTranslatef(0, barOffset, 0); + drawBar(last); + } + glPopMatrix(); + } + + angle += 1; + + // forge logo + setColor(backgroundColor); + float fw = (float)forgeTexture.getWidth() / 2; + float fh = (float)forgeTexture.getHeight() / 2; + if(rotate) + { + float sh = Math.max(fw, fh); + glTranslatef(320 + w/2 - sh - logoOffset, 240 + h/2 - sh - logoOffset, 0); + glRotatef(angle, 0, 0, 1); + } + else + { + glTranslatef(320 + w/2 - fw - logoOffset, 240 + h/2 - fh - logoOffset, 0); + } + int f = (angle / 10) % forgeTexture.getFrames(); + glEnable(GL_TEXTURE_2D); + forgeTexture.bind(); + glBegin(GL_QUADS); + forgeTexture.texCoord(f, 0, 0); + glVertex2f(-fw, -fh); + forgeTexture.texCoord(f, 0, 1); + glVertex2f(-fw, fh); + forgeTexture.texCoord(f, 1, 1); + glVertex2f(fw, fh); + forgeTexture.texCoord(f, 1, 0); + glVertex2f(fw, -fh); + glEnd(); + glDisable(GL_TEXTURE_2D); + + Display.update(); + if(pause) + { + clearGL(); + setGL(); + } + Display.sync(100); + } + clearGL(); + } + + private void setColor(int color) + { + glColor3ub((byte)((color >> 16) & 0xFF), (byte)((color >> 8) & 0xFF), (byte)(color & 0xFF)); + } + + private void drawBox(int w, int h) + { + glBegin(GL_QUADS); + glVertex2f(0, 0); + glVertex2f(0, h); + glVertex2f(w, h); + glVertex2f(w, 0); + glEnd(); + } + + private void drawBar(ProgressBar b) + { + glPushMatrix(); + // title - message + setColor(fontColor); + glScalef(2, 2, 1); + glEnable(GL_TEXTURE_2D); + fontRenderer.drawString(b.getTitle() + " - " + b.getMessage(), 0, 0, 0x000000); + glDisable(GL_TEXTURE_2D); + glPopMatrix(); + // border + glPushMatrix(); + glTranslatef(0, textHeight2, 0); + setColor(barBorderColor); + drawBox(barWidth, barHeight); + // interior + setColor(barBackgroundColor); + glTranslatef(1, 1, 0); + drawBox(barWidth - 2, barHeight - 2); + // slidy part + setColor(barColor); + drawBox((barWidth - 2) * b.getStep() / b.getSteps(), barHeight - 2); + // progress text + String progress = "" + b.getStep() + "/" + b.getSteps(); + glTranslatef(((float)barWidth - 2) / 2 - fontRenderer.getStringWidth(progress), 2, 0); + setColor(fontColor); + glScalef(2, 2, 1); + glEnable(GL_TEXTURE_2D); + fontRenderer.drawString(progress, 0, 0, 0x000000); + glPopMatrix(); + } + + private void setGL() + { + lock.lock(); + try + { + Display.getDrawable().makeCurrent(); + } + catch (LWJGLException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + glClearColor((float)((backgroundColor >> 16) & 0xFF) / 0xFF, (float)((backgroundColor >> 8) & 0xFF) / 0xFF, (float)(backgroundColor & 0xFF) / 0xFF, 1); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + + private void clearGL() + { + Minecraft mc = Minecraft.getMinecraft(); + mc.displayWidth = Display.getWidth(); + mc.displayHeight = Display.getHeight(); + mc.resize(mc.displayWidth, mc.displayHeight); + glClearColor(1, 1, 1, 1); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, .1f); + try + { + Display.getDrawable().releaseContext(); + } + catch (LWJGLException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + finally + { + lock.unlock(); + } + } + }); + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() + { + public void uncaughtException(Thread t, Throwable e) + { + FMLLog.log(Level.ERROR, e, "Splash thread Exception"); + threadError = e; + } + }); + thread.start(); + checkThreadState(); + } + + private static void checkThreadState() + { + if(thread.getState() == Thread.State.TERMINATED || threadError != null) + { + throw new IllegalStateException("Splash thread", threadError); + } + } + /** + * Call before you need to explicitly modify GL context state during loading. + * Resource loading doesn't usually require this call. + * Call {@link #resume()} when you're done. + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static void pause() + { + if(!enabled) return; + checkThreadState(); + pause = true; + lock.lock(); + try + { + d.releaseContext(); + Display.getDrawable().makeCurrent(); + } + catch (LWJGLException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + /** + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static void resume() + { + if(!enabled) return; + checkThreadState(); + pause = false; + try + { + Display.getDrawable().releaseContext(); + d.makeCurrent(); + } + catch (LWJGLException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + lock.unlock(); + } + + public static void finish() + { + if(!enabled) return; + checkThreadState(); + try + { + done = true; + thread.join(); + d.releaseContext(); + Display.getDrawable().makeCurrent(); + fontTexture.delete(); + logoTexture.delete(); + forgeTexture.delete(); + } + catch (Exception e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private static IResourcePack createResourcePack(File file) + { + if(file.isDirectory()) + { + return new FolderResourcePack(file); + } + else + { + return new FileResourcePack(file); + } + } + + private static final IntBuffer buf = BufferUtils.createIntBuffer(4 * 1024 * 1024); + + private static class Texture + { + private final ResourceLocation location; + private final int name; + private final int width; + private final int height; + private final int frames; + private final int size; + + public Texture(ResourceLocation location) + { + InputStream s = null; + try + { + this.location = location; + s = open(location); + ImageInputStream stream = ImageIO.createImageInputStream(s); + Iterator readers = ImageIO.getImageReaders(stream); + if(!readers.hasNext()) throw new IOException("No suitable reader found for image" + location); + ImageReader reader = readers.next(); + reader.setInput(stream); + frames = reader.getNumImages(true); + BufferedImage[] images = new BufferedImage[frames]; + for(int i = 0; i < frames; i++) + { + images[i] = reader.read(i); + } + reader.dispose(); + int size = 1; + width = images[0].getWidth(); + height = images[0].getHeight(); + while((size / width) * (size / height) < frames) size *= 2; + this.size = size; + glEnable(GL_TEXTURE_2D); + synchronized(SplashProgress.class) + { + name = glGenTextures(); + glBindTexture(GL_TEXTURE_2D, name); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, (IntBuffer)null); + checkGLError("Texture creation"); + for(int i = 0; i * (size / width) < frames; i++) + { + for(int j = 0; i * (size / width) + j < frames && j < size / width; j++) + { + buf.clear(); + BufferedImage image = images[i * (size / width) + j]; + for(int k = 0; k < height; k++) + { + for(int l = 0; l < width; l++) + { + buf.put(image.getRGB(l, k)); + } + } + buf.position(0).limit(width * height); + glTexSubImage2D(GL_TEXTURE_2D, 0, j * width, i * height, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buf); + checkGLError("Texture uploading"); + } + } + glBindTexture(GL_TEXTURE_2D, 0); + glDisable(GL_TEXTURE_2D); + } + catch(IOException e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + finally + { + IOUtils.closeQuietly(s); + } + } + + public ResourceLocation getLocation() + { + return location; + } + + public int getName() + { + return name; + } + + public int getWidth() + { + return width; + } + + public int getHeight() + { + return height; + } + + public int getFrames() + { + return frames; + } + + public int getSize() + { + return size; + } + + public void bind() + { + glBindTexture(GL_TEXTURE_2D, name); + } + + public void delete() + { + glDeleteTextures(name); + } + + public float getU(int frame, float u) + { + return width * (frame % (size / width) + u) / size; + } + + public float getV(int frame, float v) + { + return height * (frame / (size / width) + v) / size; + } + + public void texCoord(int frame, float u, float v) + { + glTexCoord2f(getU(frame, u), getV(frame, v)); + } + } + + private static class SplashFontRenderer extends FontRenderer + { + public SplashFontRenderer() + { + super(Minecraft.getMinecraft().gameSettings, fontTexture.getLocation(), null, false); + super.onResourceManagerReload(null); + } + + @Override + protected void bindTexture(ResourceLocation location) + { + if(location != locationFontTexture) throw new IllegalArgumentException(); + fontTexture.bind(); + } + + @Override + protected InputStream getResourceInputStream(ResourceLocation location) throws IOException + { + return Minecraft.getMinecraft().mcDefaultResourcePack.getInputStream(location); + } + } + + public static void drawVanillaScreen(TextureManager renderEngine) throws LWJGLException + { + if(!enabled) + { + Minecraft.getMinecraft().drawSplashScreen(renderEngine); + } + } + + public static void clearVanillaResources(TextureManager renderEngine, ResourceLocation mojangLogo) + { + if(!enabled) + { + renderEngine.deleteTexture(mojangLogo); + } + } + + public static void checkGLError(String where) + { + int err = GL11.glGetError(); + if (err != 0) + { + throw new IllegalStateException(where + ": " + GLU.gluErrorString(err)); + } + } + + private static InputStream open(ResourceLocation loc) throws IOException + { + if(miscPack.resourceExists(loc)) + { + return miscPack.getInputStream(loc); + } + else if(fmlPack.resourceExists(loc)) + { + return fmlPack.getInputStream(loc); + } + return mcPack.getInputStream(loc); + } +} diff --git a/fml/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java b/fml/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java new file mode 100644 index 000000000..2b85a2dc0 --- /dev/null +++ b/fml/src/main/java/net/minecraftforge/fml/common/ClassNameUtils.java @@ -0,0 +1,10 @@ +package net.minecraftforge.fml.common; + +public class ClassNameUtils +{ + public static String shortName(Class clz) + { + String nm = clz.getName(); + return nm.indexOf('.') > -1 ? nm.substring(nm.lastIndexOf('.')+1) : nm; + } +} diff --git a/fml/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java b/fml/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java index 681086c6f..eabfb0b7a 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/FMLCommonHandler.java @@ -664,6 +664,11 @@ public class FMLCommonHandler return true; } + public void processWindowMessages() + { + if (sidedDelegate == null) return; + sidedDelegate.processWindowMessages(); + } /** * Used to exit from java, with system exit preventions in place. Will be tidy about it and just log a message, diff --git a/fml/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java b/fml/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java new file mode 100644 index 000000000..73f45a912 --- /dev/null +++ b/fml/src/main/java/net/minecraftforge/fml/common/FMLContainerHolder.java @@ -0,0 +1,6 @@ +package net.minecraftforge.fml.common; + +public interface FMLContainerHolder +{ + ModContainer getFMLContainer(); +} diff --git a/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java b/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java index 72b3e6bb5..60ae2c6b2 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/FMLModContainer.java @@ -168,6 +168,8 @@ public class FMLModContainer implements ModContainer List dependants = Lists.newArrayList(); annotationDependencies = (String) descriptor.get("dependencies"); Loader.instance().computeDependencies(annotationDependencies, requirements, dependencies, dependants); + dependants.addAll(Loader.instance().getInjectedBefore(getModId())); + dependencies.addAll(Loader.instance().getInjectedAfter(getModId())); modMetadata.requiredMods = requirements; modMetadata.dependencies = dependencies; modMetadata.dependants = dependants; @@ -518,7 +520,6 @@ public class FMLModContainer implements ModContainer catch (Throwable e) { controller.errorOccurred(this, e); - Throwables.propagateIfPossible(e); } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java b/fml/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java index 0c94391de..cbf851a3c 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/IFMLSidedHandler.java @@ -62,4 +62,6 @@ public interface IFMLSidedHandler void allowLogins(); IThreadListener getWorldThread(INetHandler net); + + void processWindowMessages(); } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/LoadController.java b/fml/src/main/java/net/minecraftforge/fml/common/LoadController.java index 605782be7..47859da9b 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/LoadController.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/LoadController.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map.Entry; import net.minecraftforge.fml.common.LoaderState.ModState; +import net.minecraftforge.fml.common.ProgressManager.ProgressBar; import net.minecraftforge.fml.common.event.FMLEvent; import net.minecraftforge.fml.common.event.FMLLoadEvent; import net.minecraftforge.fml.common.event.FMLModDisabledEvent; @@ -182,10 +183,13 @@ public class LoadController { modObjectList = buildModObjectList(); } + ProgressBar bar = ProgressManager.push(stateEvent.description(), activeModList.size()); for (ModContainer mc : activeModList) { + bar.step(mc.getName()); sendEventToModContainer(stateEvent, mc); } + ProgressManager.pop(bar); } private void sendEventToModContainer(FMLEvent stateEvent, ModContainer mc) @@ -348,4 +352,9 @@ public class LoadController { return accessibleManager.getStackClasses(); } + + LoaderState getState() + { + return state; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/Loader.java b/fml/src/main/java/net/minecraftforge/fml/common/Loader.java index 3e42289f3..b2fea151f 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -28,6 +28,7 @@ import java.util.Set; import net.minecraftforge.fml.common.LoaderState.ModState; import net.minecraftforge.fml.common.ModContainer.Disableable; +import net.minecraftforge.fml.common.ProgressManager.ProgressBar; import net.minecraftforge.fml.common.discovery.ModDiscoverer; import net.minecraftforge.fml.common.event.FMLInterModComms; import net.minecraftforge.fml.common.event.FMLLoadEvent; @@ -46,6 +47,7 @@ import net.minecraftforge.fml.common.toposort.TopologicalSort; import net.minecraftforge.fml.common.toposort.ModSortingException.SortingExceptionData; import net.minecraftforge.fml.common.versioning.ArtifactVersion; import net.minecraftforge.fml.common.versioning.VersionParser; +import net.minecraftforge.fml.relauncher.ModListHelper; import net.minecraftforge.fml.relauncher.Side; import org.apache.logging.log4j.Level; @@ -72,6 +74,10 @@ import com.google.common.collect.Ordering; import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; import com.google.common.collect.TreeMultimap; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; /** * The loader class performs the actual loading of the mod code from disk. @@ -153,6 +159,7 @@ public class Loader private ImmutableMap fmlBrandingProperties; private File forcedModFile; private ModDiscoverer discoverer; + private ProgressBar progressBar; public static Loader instance() { @@ -336,8 +343,9 @@ public class Loader discoverer.findClasspathMods(modClassLoader); FMLLog.fine("Minecraft jar mods loaded successfully"); + FMLLog.getLogger().log(Level.INFO, "Found {} mods from the command line. Injecting into mod discoverer",ModListHelper.additionalMods.size()); FMLLog.info("Searching %s for mods", canonicalModsDir.getAbsolutePath()); - discoverer.findModDirMods(canonicalModsDir); + discoverer.findModDirMods(canonicalModsDir, ModListHelper.additionalMods.values().toArray(new File[0])); File versionSpecificModsDir = new File(canonicalModsDir,mccversion); if (versionSpecificModsDir.isDirectory()) { @@ -447,6 +455,8 @@ public class Loader FMLLog.severe("Attempting to load configuration from %s, which is not a directory", canonicalConfigPath); throw new LoaderException(); } + + readInjectedDependencies(); } public List getModList() @@ -461,6 +471,8 @@ public class Loader */ public void loadMods() { + progressBar = ProgressManager.push("Loading", 7); + progressBar.step("Constructing Mods"); initializeLoader(); mods = Lists.newArrayList(); namedMods = Maps.newHashMap(); @@ -500,6 +512,7 @@ public class Loader { FMLLog.fine("No user mod signature data found"); } + progressBar.step("Initializing mods Phase 1"); modController.transition(LoaderState.PREINITIALIZATION, false); } @@ -514,6 +527,7 @@ public class Loader modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir); ObjectHolderRegistry.INSTANCE.applyObjectHolders(); modController.transition(LoaderState.INITIALIZATION, false); + progressBar.step("Initializing Minecraft Engine"); } private void disableRequestedMods() @@ -688,15 +702,19 @@ public class Loader public void initializeMods() { + progressBar.step("Initializing mods Phase 2"); // Mod controller should be in the initialization state here modController.distributeStateMessage(LoaderState.INITIALIZATION); + progressBar.step("Initializing mods Phase 3"); modController.transition(LoaderState.POSTINITIALIZATION, false); modController.distributeStateMessage(FMLInterModComms.IMCEvent.class); modController.distributeStateMessage(LoaderState.POSTINITIALIZATION); + progressBar.step("Finishing up"); modController.transition(LoaderState.AVAILABLE, false); modController.distributeStateMessage(LoaderState.AVAILABLE); GameData.freezeData(); FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size() == 1 ? "" : "s"); + progressBar.step("Completing Minecraft initialization"); } public ICrashCallable getCallableCrashInformation() @@ -981,4 +999,68 @@ public class Loader FMLLog.log(Level.INFO, e, "An error occurred writing the fml mod states file, your disabled change won't persist"); } } + + public void loadingComplete() + { + ProgressManager.pop(progressBar); + progressBar = null; + } + + private ListMultimap injectedBefore = ArrayListMultimap.create(); + private ListMultimap injectedAfter = ArrayListMultimap.create(); + + private void readInjectedDependencies() + { + File injectedDepFile = new File(getConfigDir(),"injectedDependencies.json"); + if (!injectedDepFile.exists()) + { + FMLLog.getLogger().log(Level.DEBUG, "File {} not found. No dependencies injected", injectedDepFile.getAbsolutePath()); + return; + } + JsonParser parser = new JsonParser(); + JsonElement injectedDeps; + try + { + injectedDeps = parser.parse(new FileReader(injectedDepFile)); + for (JsonElement el : injectedDeps.getAsJsonArray()) + { + JsonObject jo = el.getAsJsonObject(); + String modId = jo.get("modId").getAsString(); + JsonArray deps = jo.get("deps").getAsJsonArray(); + for (JsonElement dep : deps) + { + JsonObject depObj = dep.getAsJsonObject(); + String type = depObj.get("type").getAsString(); + if (type.equals("before")) { + injectedBefore.put(modId, VersionParser.parseVersionReference(depObj.get("target").getAsString())); + } else if (type.equals("after")) { + injectedAfter.put(modId, VersionParser.parseVersionReference(depObj.get("target").getAsString())); + } else { + FMLLog.getLogger().log(Level.ERROR, "Invalid dependency type {}", type); + throw new RuntimeException("Unable to parse type"); + } + } + } + } catch (Exception e) + { + FMLLog.getLogger().log(Level.ERROR, "Unable to parse {} - skipping", injectedDepFile); + FMLLog.getLogger().throwing(Level.ERROR, e); + return; + } + FMLLog.getLogger().log(Level.DEBUG, "Loaded {} injected dependencies on modIds: {}", injectedBefore.size(), injectedBefore.keySet()); + } + + List getInjectedBefore(String modId) + { + return injectedBefore.get(modId); + } + List getInjectedAfter(String modId) + { + return injectedAfter.get(modId); + } + + public final LoaderState getLoaderState() + { + return modController != null ? modController.getState() : LoaderState.NOINIT; + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/ProgressManager.java b/fml/src/main/java/net/minecraftforge/fml/common/ProgressManager.java new file mode 100644 index 000000000..cd4716b82 --- /dev/null +++ b/fml/src/main/java/net/minecraftforge/fml/common/ProgressManager.java @@ -0,0 +1,98 @@ +package net.minecraftforge.fml.common; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import com.google.common.base.Joiner; + +/** + * @deprecated not a stable API, will break, don't use this yet + */ +@Deprecated +public class ProgressManager +{ + private static final List bars = new CopyOnWriteArrayList(); + + /** + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static ProgressBar push(String title, int steps) + { + ProgressBar bar = new ProgressBar(title, steps); + bars.add(bar); + FMLCommonHandler.instance().processWindowMessages(); + return bar; + } + + /** + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static void pop(ProgressBar bar) + { + if(bar.getSteps() != bar.getStep()) throw new IllegalStateException("can't pop unfinished ProgressBar " + bar.getTitle()); + bars.remove(bar); + FMLCommonHandler.instance().processWindowMessages(); + } + + /* + * Internal use only. + */ + public static Iterator barIterator() + { + return bars.iterator(); + } + + /** + * @deprecated not a stable API, will break, don't use this yet + */ + @Deprecated + public static class ProgressBar + { + private final String title; + private final int steps; + private volatile int step = 0; + private volatile String message = ""; + + private ProgressBar(String title, int steps) + { + this.title = title; + this.steps = steps; + } + + public void step(Class classToName, String... extra) + { + step(ClassNameUtils.shortName(classToName)+Joiner.on(' ').join(extra)); + } + + public void step(String message) + { + if(step >= steps) throw new IllegalStateException("too much steps for ProgressBar " + title); + step++; + this.message = message; + FMLCommonHandler.instance().processWindowMessages(); + } + + public String getTitle() + { + return title; + } + + public int getSteps() + { + return steps; + } + + public int getStep() + { + return step; + } + + public String getMessage() + { + return message; + } + } +} diff --git a/fml/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java b/fml/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java index bf1814c8c..105aaa6f3 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/discovery/ModDiscoverer.java @@ -88,9 +88,13 @@ public class ModDiscoverer public void findModDirMods(File modsDir) { - File[] modList = FileListHelper.sortFileList(modsDir, null); - modList = FileListHelper.sortFileList(ObjectArrays.concat(modList, ModListHelper.additionalMods.values().toArray(new File[0]), File.class)); + findModDirMods(modsDir, new File[0]); + } + public void findModDirMods(File modsDir, File[] supplementalModFileCandidates) + { + File[] modList = FileListHelper.sortFileList(modsDir, null); + modList = FileListHelper.sortFileList(ObjectArrays.concat(modList, supplementalModFileCandidates, File.class)); for (File modFile : modList) { // skip loaded coremods diff --git a/fml/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java b/fml/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java index 686fa88d1..943655a87 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/event/FMLEvent.java @@ -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 */ @@ -20,8 +20,12 @@ public class FMLEvent { return getClass().getSimpleName(); } - - public void applyModContainer(ModContainer activeContainer) { - // NO OP - } + public final String description() + { + String cn = getClass().getName(); + return cn.substring(cn.lastIndexOf('.')+4,cn.length()-5); + } + public void applyModContainer(ModContainer activeContainer) { + // NO OP + } } diff --git a/fml/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java b/fml/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java index e02f9f629..2a1b1d100 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/eventhandler/Event.java @@ -3,11 +3,8 @@ package net.minecraftforge.fml.common.eventhandler; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; -import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.Target; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -36,8 +33,6 @@ public class Event private static ListenerList listeners = new ListenerList(); private EventPriority phase = null; - private static final Map, Map, Boolean>> annotationMap = new ConcurrentHashMap, Map, Boolean>>(); - public Event() { setup(); diff --git a/fml/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java b/fml/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java index e96224976..c6c54e1c0 100644 --- a/fml/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java +++ b/fml/src/main/java/net/minecraftforge/fml/common/registry/GameRegistry.java @@ -187,7 +187,7 @@ public class GameRegistry * @param block The block to register * @param itemclass The item type to register with it : null registers a block without associated item. * @param name The mod-unique name to register it as, will get prefixed by your modid. - * @param itemCtorArgs Arguments to pass to the ItemBlock constructor (optional). + * @param itemCtorArgs Arguments to pass (after the required {@code Block} parameter) to the ItemBlock constructor (optional). */ public static Block registerBlock(Block block, Class itemclass, String name, Object... itemCtorArgs) { diff --git a/fml/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java b/fml/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java index 11e2ac225..32ff2c3c2 100644 --- a/fml/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java +++ b/fml/src/main/java/net/minecraftforge/fml/server/FMLServerHandler.java @@ -266,4 +266,10 @@ public class FMLServerHandler implements IFMLSidedHandler // Always the server on the dedicated server, eventually add Per-World if Mojang adds world stuff. return getServer(); } + + @Override + public void processWindowMessages() + { + // NOOP + } } diff --git a/fml/src/main/resources/assets/fml/textures/gui/forge.gif b/fml/src/main/resources/assets/fml/textures/gui/forge.gif new file mode 100644 index 000000000..b316837fb Binary files /dev/null and b/fml/src/main/resources/assets/fml/textures/gui/forge.gif differ diff --git a/fml/src/main/resources/assets/fml/textures/gui/forge.png b/fml/src/main/resources/assets/fml/textures/gui/forge.png new file mode 100644 index 000000000..1be137a39 Binary files /dev/null and b/fml/src/main/resources/assets/fml/textures/gui/forge.png differ diff --git a/fml/src/main/resources/fml_at.cfg b/fml/src/main/resources/fml_at.cfg index 5520baf81..713b94536 100644 --- a/fml/src/main/resources/fml_at.cfg +++ b/fml/src/main/resources/fml_at.cfg @@ -33,6 +33,9 @@ public net.minecraft.entity.passive.EntityVillager field_70960_bC public net.minecraft.client.gui.GuiScreen field_146297_k # minecraft instance - public because gui's outside access it # Minecraft public net.minecraft.client.Minecraft field_71446_o # textureManager +public net.minecraft.client.Minecraft field_110450_ap # mcDefaultResourcePack +public net.minecraft.client.Minecraft func_71370_a(II)V # resize +public net.minecraft.client.Minecraft func_180510_a(Lnet/minecraft/client/renderer/texture/TextureManager;)V # drawSplashScreen ## ItemBlock public net.minecraft.item.ItemBlock field_150939_a ## DedicatedServer @@ -69,4 +72,14 @@ public net.minecraft.entity.passive.EntityVillager$ItemAndEmeraldToItem public net.minecraft.entity.passive.EntityVillager$ListEnchantedBookForEmeralds public net.minecraft.entity.passive.EntityVillager$ListEnchantedItemForEmeralds public net.minecraft.entity.passive.EntityVillager$ListItemForEmeralds -public net.minecraft.entity.passive.EntityVillager$PriceInfo \ No newline at end of file +public net.minecraft.entity.passive.EntityVillager$PriceInfo + +# Font renderer +protected net.minecraft.client.gui.FontRenderer field_78288_b # FONT_HEIGHT +protected net.minecraft.client.gui.FontRenderer field_78286_d # charWidth +protected net.minecraft.client.gui.FontRenderer field_78287_e # glyphWidth +protected net.minecraft.client.gui.FontRenderer field_111273_g # locationFontTexture +protected net.minecraft.client.gui.FontRenderer field_78295_j # posX +protected net.minecraft.client.gui.FontRenderer field_78296_k # posY +protected net.minecraft.client.gui.FontRenderer func_78266_a(IZ)F # renderDefaultChar +protected net.minecraft.client.gui.FontRenderer func_78277_a(CZ)F # renderUnicodeChar