Merge pull request #400 from sfPlayer1/master
Fix various registry issues
This commit is contained in:
commit
ede8bb6e61
27 changed files with 1897 additions and 772 deletions
|
@ -12,7 +12,7 @@
|
||||||
public class Block
|
public class Block
|
||||||
{
|
{
|
||||||
- public static final RegistryNamespaced field_149771_c = new RegistryNamespacedDefaultedByKey("air");
|
- public static final RegistryNamespaced field_149771_c = new RegistryNamespacedDefaultedByKey("air");
|
||||||
+ public static final RegistryNamespaced field_149771_c = GameData.blockRegistry;
|
+ public static final RegistryNamespaced field_149771_c = GameData.getBlockRegistry();
|
||||||
private CreativeTabs field_149772_a;
|
private CreativeTabs field_149772_a;
|
||||||
protected String field_149768_d;
|
protected String field_149768_d;
|
||||||
public static final Block.SoundType field_149769_e = new Block.SoundType("stone", 1.0F, 1.0F);
|
public static final Block.SoundType field_149769_e = new Block.SoundType("stone", 1.0F, 1.0F);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
--- ../src-base/minecraft/net/minecraft/client/LoadingScreenRenderer.java
|
||||||
|
+++ ../src-work/minecraft/net/minecraft/client/LoadingScreenRenderer.java
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
package net.minecraft.client;
|
||||||
|
|
||||||
|
+import cpw.mods.fml.client.FMLClientHandler;
|
||||||
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
|
import net.minecraft.client.gui.Gui;
|
||||||
|
@@ -147,6 +148,8 @@
|
||||||
|
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!FMLClientHandler.instance().handleLoadingScreen(scaledresolution))
|
||||||
|
+ {
|
||||||
|
Tessellator tessellator = Tessellator.field_78398_a;
|
||||||
|
this.field_73725_b.func_110434_K().func_110577_a(Gui.field_110325_k);
|
||||||
|
float f = 32.0F;
|
||||||
|
@@ -184,6 +187,7 @@
|
||||||
|
OpenGlHelper.func_148821_a(770, 771, 1, 0);
|
||||||
|
this.field_73725_b.field_71466_p.func_78261_a(this.field_73726_c, (l - this.field_73725_b.field_71466_p.func_78256_a(this.field_73726_c)) / 2, i1 / 2 - 4 - 16, 16777215);
|
||||||
|
this.field_73725_b.field_71466_p.func_78261_a(this.field_73727_a, (l - this.field_73725_b.field_71466_p.func_78256_a(this.field_73727_a)) / 2, i1 / 2 - 4 + 8, 16777215);
|
||||||
|
+ }
|
||||||
|
this.field_146588_g.func_147609_e();
|
||||||
|
|
||||||
|
if (OpenGlHelper.func_148822_b())
|
|
@ -1,16 +1,17 @@
|
||||||
--- ../src-base/minecraft/net/minecraft/client/Minecraft.java
|
--- ../src-base/minecraft/net/minecraft/client/Minecraft.java
|
||||||
+++ ../src-work/minecraft/net/minecraft/client/Minecraft.java
|
+++ ../src-work/minecraft/net/minecraft/client/Minecraft.java
|
||||||
@@ -1,6 +1,9 @@
|
@@ -1,6 +1,10 @@
|
||||||
package net.minecraft.client;
|
package net.minecraft.client;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
+
|
+
|
||||||
+import cpw.mods.fml.client.FMLClientHandler;
|
+import cpw.mods.fml.client.FMLClientHandler;
|
||||||
+import cpw.mods.fml.common.FMLCommonHandler;
|
+import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
|
+import cpw.mods.fml.common.StartupQuery;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
import io.netty.util.concurrent.GenericFutureListener;
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
@@ -146,6 +149,8 @@
|
@@ -146,6 +150,8 @@
|
||||||
import org.lwjgl.opengl.PixelFormat;
|
import org.lwjgl.opengl.PixelFormat;
|
||||||
import org.lwjgl.util.glu.GLU;
|
import org.lwjgl.util.glu.GLU;
|
||||||
|
|
||||||
|
@ -19,21 +20,7 @@
|
||||||
@SideOnly(Side.CLIENT)
|
@SideOnly(Side.CLIENT)
|
||||||
public class Minecraft implements IPlayerUsage
|
public class Minecraft implements IPlayerUsage
|
||||||
{
|
{
|
||||||
@@ -323,8 +328,11 @@
|
@@ -448,7 +454,7 @@
|
||||||
|
|
||||||
public void func_71404_a(CrashReport p_71404_1_)
|
|
||||||
{
|
|
||||||
- this.field_71434_R = true;
|
|
||||||
- this.field_71433_S = p_71404_1_;
|
|
||||||
+ if (!FMLClientHandler.instance().handlingCrash(p_71404_1_))
|
|
||||||
+ {
|
|
||||||
+ this.field_71434_R = true;
|
|
||||||
+ this.field_71433_S = p_71404_1_;
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
public void func_71377_b(CrashReport p_71377_1_)
|
|
||||||
@@ -448,7 +456,7 @@
|
|
||||||
this.field_110451_am = new SimpleReloadableResourceManager(this.field_110452_an);
|
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_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);
|
this.field_110451_am.func_110542_a(this.field_135017_as);
|
||||||
|
@ -42,7 +29,7 @@
|
||||||
this.field_71446_o = new TextureManager(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.field_110451_am.func_110542_a(this.field_71446_o);
|
||||||
this.field_147127_av = new SoundHandler(this.field_110451_am, this.field_71474_y);
|
this.field_147127_av = new SoundHandler(this.field_110451_am, this.field_71474_y);
|
||||||
@@ -508,12 +516,13 @@
|
@@ -508,12 +514,13 @@
|
||||||
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"));
|
||||||
GL11.glViewport(0, 0, this.field_71443_c, this.field_71440_d);
|
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);
|
this.field_71452_i = new EffectRenderer(this.field_71441_e, this.field_71446_o);
|
||||||
|
@ -57,7 +44,7 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -527,6 +536,7 @@
|
@@ -527,6 +534,7 @@
|
||||||
this.func_71352_k();
|
this.func_71352_k();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +52,7 @@
|
||||||
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
|
Display.setVSyncEnabled(this.field_71474_y.field_74352_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -916,9 +926,11 @@
|
@@ -916,9 +924,11 @@
|
||||||
|
|
||||||
if (!this.field_71454_w)
|
if (!this.field_71454_w)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +64,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
GL11.glFlush();
|
GL11.glFlush();
|
||||||
@@ -1496,6 +1508,8 @@
|
@@ -1496,6 +1506,8 @@
|
||||||
--this.field_71467_ac;
|
--this.field_71467_ac;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +73,7 @@
|
||||||
this.field_71424_I.func_76320_a("gui");
|
this.field_71424_I.func_76320_a("gui");
|
||||||
|
|
||||||
if (!this.field_71445_n)
|
if (!this.field_71445_n)
|
||||||
@@ -1646,6 +1660,7 @@
|
@@ -1646,6 +1658,7 @@
|
||||||
this.field_71462_r.func_146274_d();
|
this.field_71462_r.func_146274_d();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +81,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.field_71429_W > 0)
|
if (this.field_71429_W > 0)
|
||||||
@@ -1787,6 +1802,7 @@
|
@@ -1787,6 +1800,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +89,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1978,12 +1994,15 @@
|
@@ -1978,12 +1992,15 @@
|
||||||
this.field_71453_ak.func_74428_b();
|
this.field_71453_ak.func_74428_b();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +105,20 @@
|
||||||
this.func_71403_a((WorldClient)null);
|
this.func_71403_a((WorldClient)null);
|
||||||
System.gc();
|
System.gc();
|
||||||
ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false);
|
ISaveHandler isavehandler = this.field_71469_aa.func_75804_a(p_71371_1_, false);
|
||||||
@@ -2094,6 +2113,7 @@
|
@@ -2019,6 +2036,12 @@
|
||||||
|
|
||||||
|
while (!this.field_71437_Z.func_71200_ad())
|
||||||
|
{
|
||||||
|
+ if (!StartupQuery.check())
|
||||||
|
+ {
|
||||||
|
+ func_71403_a(null);
|
||||||
|
+ func_147108_a(null);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
String s2 = this.field_71437_Z.func_71195_b_();
|
||||||
|
|
||||||
|
if (s2 != null)
|
||||||
|
@@ -2094,6 +2117,7 @@
|
||||||
this.field_110448_aq.func_148529_f();
|
this.field_110448_aq.func_148529_f();
|
||||||
this.func_71351_a((ServerData)null);
|
this.func_71351_a((ServerData)null);
|
||||||
this.field_71455_al = false;
|
this.field_71455_al = false;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
public class Item
|
public class Item
|
||||||
{
|
{
|
||||||
- public static final RegistryNamespaced field_150901_e = new RegistryNamespaced();
|
- public static final RegistryNamespaced field_150901_e = new RegistryNamespaced();
|
||||||
+ public static final RegistryNamespaced field_150901_e = GameData.itemRegistry;
|
+ public static final RegistryNamespaced field_150901_e = GameData.getItemRegistry();
|
||||||
protected static final UUID field_111210_e = UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF");
|
protected static final UUID field_111210_e = UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF");
|
||||||
private CreativeTabs field_77701_a;
|
private CreativeTabs field_77701_a;
|
||||||
protected static Random field_77697_d = new Random();
|
protected static Random field_77697_d = new Random();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java
|
--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java
|
||||||
+++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java
|
+++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java
|
||||||
@@ -4,6 +4,10 @@
|
@@ -4,6 +4,11 @@
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||||
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
|
||||||
|
@ -8,10 +8,20 @@
|
||||||
+import cpw.mods.fml.common.FMLCommonHandler;
|
+import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
+import cpw.mods.fml.common.Loader;
|
+import cpw.mods.fml.common.Loader;
|
||||||
+import cpw.mods.fml.common.LoaderState;
|
+import cpw.mods.fml.common.LoaderState;
|
||||||
|
+import cpw.mods.fml.common.StartupQuery;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import cpw.mods.fml.relauncher.SideOnly;
|
import cpw.mods.fml.relauncher.SideOnly;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
@@ -381,6 +385,7 @@
|
@@ -333,7 +338,7 @@
|
||||||
|
|
||||||
|
public void func_71260_j()
|
||||||
|
{
|
||||||
|
- if (!this.field_71290_O)
|
||||||
|
+ if (!this.field_71290_O && Loader.instance().hasReachedState(LoaderState.SERVER_STARTED))
|
||||||
|
{
|
||||||
|
field_147145_h.info("Stopping server");
|
||||||
|
|
||||||
|
@@ -381,6 +386,7 @@
|
||||||
{
|
{
|
||||||
if (this.func_71197_b())
|
if (this.func_71197_b())
|
||||||
{
|
{
|
||||||
|
@ -19,7 +29,7 @@
|
||||||
long i = func_130071_aq();
|
long i = func_130071_aq();
|
||||||
long l = 0L;
|
long l = 0L;
|
||||||
this.field_147147_p.func_151315_a(new ChatComponentText(this.field_71286_C));
|
this.field_147147_p.func_151315_a(new ChatComponentText(this.field_71286_C));
|
||||||
@@ -425,6 +430,7 @@
|
@@ -425,12 +431,17 @@
|
||||||
Thread.sleep(1L);
|
Thread.sleep(1L);
|
||||||
this.field_71296_Q = true;
|
this.field_71296_Q = true;
|
||||||
}
|
}
|
||||||
|
@ -27,18 +37,17 @@
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -462,7 +468,10 @@
|
this.func_71228_a((CrashReport)null);
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
+ if (Loader.instance().hasReachedState(LoaderState.SERVER_STARTED))
|
|
||||||
+ {
|
|
||||||
this.func_71260_j();
|
|
||||||
+ }
|
|
||||||
this.field_71316_v = true;
|
|
||||||
}
|
}
|
||||||
catch (Throwable throwable)
|
}
|
||||||
@@ -471,6 +480,8 @@
|
+ catch (StartupQuery.AbortedException e)
|
||||||
|
+ {
|
||||||
|
+ // ignore silently
|
||||||
|
+ }
|
||||||
|
catch (Throwable throwable1)
|
||||||
|
{
|
||||||
|
field_147145_h.error("Encountered an unexpected exception", throwable1);
|
||||||
|
@@ -471,6 +482,8 @@
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -47,7 +56,7 @@
|
||||||
this.func_71240_o();
|
this.func_71240_o();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,6 +524,7 @@
|
@@ -513,6 +526,7 @@
|
||||||
{
|
{
|
||||||
long i = System.nanoTime();
|
long i = System.nanoTime();
|
||||||
AxisAlignedBB.func_72332_a().func_72298_a();
|
AxisAlignedBB.func_72332_a().func_72298_a();
|
||||||
|
@ -55,7 +64,7 @@
|
||||||
++this.field_71315_w;
|
++this.field_71315_w;
|
||||||
|
|
||||||
if (this.field_71295_T)
|
if (this.field_71295_T)
|
||||||
@@ -566,6 +578,7 @@
|
@@ -566,6 +580,7 @@
|
||||||
|
|
||||||
this.field_71304_b.func_76319_b();
|
this.field_71304_b.func_76319_b();
|
||||||
this.field_71304_b.func_76319_b();
|
this.field_71304_b.func_76319_b();
|
||||||
|
@ -63,7 +72,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public void func_71190_q()
|
public void func_71190_q()
|
||||||
@@ -593,6 +606,7 @@
|
@@ -593,6 +608,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.field_71304_b.func_76320_a("tick");
|
this.field_71304_b.func_76320_a("tick");
|
||||||
|
@ -71,7 +80,7 @@
|
||||||
CrashReport crashreport;
|
CrashReport crashreport;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -617,6 +631,7 @@
|
@@ -617,6 +633,7 @@
|
||||||
throw new ReportedException(crashreport);
|
throw new ReportedException(crashreport);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +88,15 @@
|
||||||
this.field_71304_b.func_76319_b();
|
this.field_71304_b.func_76319_b();
|
||||||
this.field_71304_b.func_76320_a("tracker");
|
this.field_71304_b.func_76320_a("tracker");
|
||||||
worldserver.func_73039_n().func_72788_a();
|
worldserver.func_73039_n().func_72788_a();
|
||||||
@@ -695,7 +710,7 @@
|
@@ -648,6 +665,7 @@
|
||||||
|
|
||||||
|
public void func_71256_s()
|
||||||
|
{
|
||||||
|
+ StartupQuery.reset();
|
||||||
|
(new Thread("Server thread")
|
||||||
|
{
|
||||||
|
private static final String __OBFID = "CL_00001418";
|
||||||
|
@@ -695,7 +713,7 @@
|
||||||
|
|
||||||
public String getServerModName()
|
public String getServerModName()
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,11 +6,11 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
+
|
+
|
||||||
+import cpw.mods.fml.common.FMLCommonHandler;
|
+import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
+import cpw.mods.fml.common.registry.GameRegistryException;
|
+import cpw.mods.fml.common.StartupQuery;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.nbt.CompressedStreamTools;
|
import net.minecraft.nbt.CompressedStreamTools;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
@@ -107,14 +110,22 @@
|
@@ -107,20 +110,29 @@
|
||||||
NBTTagCompound nbttagcompound;
|
NBTTagCompound nbttagcompound;
|
||||||
NBTTagCompound nbttagcompound1;
|
NBTTagCompound nbttagcompound1;
|
||||||
|
|
||||||
|
@ -27,14 +27,21 @@
|
||||||
+ FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
+ FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
||||||
+ return worldInfo;
|
+ return worldInfo;
|
||||||
}
|
}
|
||||||
+ catch (GameRegistryException gre)
|
+ catch (StartupQuery.AbortedException e)
|
||||||
+ {
|
+ {
|
||||||
+ throw gre;
|
+ throw e;
|
||||||
+ }
|
+ }
|
||||||
catch (Exception exception1)
|
catch (Exception exception1)
|
||||||
{
|
{
|
||||||
exception1.printStackTrace();
|
exception1.printStackTrace();
|
||||||
@@ -129,8 +140,14 @@
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ FMLCommonHandler.instance().confirmBackupLevelDatUse(this);
|
||||||
|
file1 = new File(this.field_75770_b, "level.dat_old");
|
||||||
|
|
||||||
|
if (file1.exists())
|
||||||
|
@@ -129,8 +141,14 @@
|
||||||
{
|
{
|
||||||
nbttagcompound = CompressedStreamTools.func_74796_a(new FileInputStream(file1));
|
nbttagcompound = CompressedStreamTools.func_74796_a(new FileInputStream(file1));
|
||||||
nbttagcompound1 = nbttagcompound.func_74775_l("Data");
|
nbttagcompound1 = nbttagcompound.func_74775_l("Data");
|
||||||
|
@ -43,14 +50,14 @@
|
||||||
+ FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
+ FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound);
|
||||||
+ return worldInfo;
|
+ return worldInfo;
|
||||||
}
|
}
|
||||||
+ catch (GameRegistryException gre)
|
+ catch (StartupQuery.AbortedException e)
|
||||||
+ {
|
+ {
|
||||||
+ throw gre;
|
+ throw e;
|
||||||
+ }
|
+ }
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
@@ -146,6 +163,8 @@
|
@@ -146,6 +164,8 @@
|
||||||
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
|
NBTTagCompound nbttagcompound2 = new NBTTagCompound();
|
||||||
nbttagcompound2.func_74782_a("Data", nbttagcompound1);
|
nbttagcompound2.func_74782_a("Data", nbttagcompound1);
|
||||||
|
|
||||||
|
@ -59,7 +66,7 @@
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File file1 = new File(this.field_75770_b, "level.dat_new");
|
File file1 = new File(this.field_75770_b, "level.dat_new");
|
||||||
@@ -184,6 +203,8 @@
|
@@ -184,6 +204,8 @@
|
||||||
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
NBTTagCompound nbttagcompound1 = new NBTTagCompound();
|
||||||
nbttagcompound1.func_74782_a("Data", nbttagcompound);
|
nbttagcompound1.func_74782_a("Data", nbttagcompound);
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.entity.EntityClientPlayerMP;
|
import net.minecraft.client.entity.EntityClientPlayerMP;
|
||||||
import net.minecraft.client.gui.Gui;
|
import net.minecraft.client.gui.Gui;
|
||||||
|
@ -32,6 +31,7 @@ import net.minecraft.client.gui.GuiIngameMenu;
|
||||||
import net.minecraft.client.gui.GuiMainMenu;
|
import net.minecraft.client.gui.GuiMainMenu;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
import net.minecraft.client.gui.GuiSelectWorld;
|
import net.minecraft.client.gui.GuiSelectWorld;
|
||||||
|
import net.minecraft.client.gui.ScaledResolution;
|
||||||
import net.minecraft.client.gui.ServerListEntryNormal;
|
import net.minecraft.client.gui.ServerListEntryNormal;
|
||||||
import net.minecraft.client.multiplayer.GuiConnecting;
|
import net.minecraft.client.multiplayer.GuiConnecting;
|
||||||
import net.minecraft.client.multiplayer.ServerData;
|
import net.minecraft.client.multiplayer.ServerData;
|
||||||
|
@ -55,7 +55,11 @@ import net.minecraft.network.ServerStatusResponse;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.WorldSettings;
|
import net.minecraft.world.WorldSettings;
|
||||||
|
import net.minecraft.world.storage.SaveFormatOld;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
import org.lwjgl.input.Mouse;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.base.Throwables;
|
import com.google.common.base.Throwables;
|
||||||
import com.google.common.collect.BiMap;
|
import com.google.common.collect.BiMap;
|
||||||
|
@ -67,11 +71,11 @@ import com.google.common.collect.Maps;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
|
||||||
import cpw.mods.fml.client.registry.RenderingRegistry;
|
import cpw.mods.fml.client.registry.RenderingRegistry;
|
||||||
import cpw.mods.fml.common.DummyModContainer;
|
import cpw.mods.fml.common.DummyModContainer;
|
||||||
import cpw.mods.fml.common.DuplicateModsFoundException;
|
import cpw.mods.fml.common.DuplicateModsFoundException;
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
import cpw.mods.fml.common.FMLContainer;
|
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.IFMLSidedHandler;
|
import cpw.mods.fml.common.IFMLSidedHandler;
|
||||||
import cpw.mods.fml.common.Loader;
|
import cpw.mods.fml.common.Loader;
|
||||||
|
@ -81,14 +85,11 @@ import cpw.mods.fml.common.MissingModsException;
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
import cpw.mods.fml.common.ModMetadata;
|
import cpw.mods.fml.common.ModMetadata;
|
||||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||||
import cpw.mods.fml.common.WorldAccessContainer;
|
import cpw.mods.fml.common.StartupQuery;
|
||||||
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
import cpw.mods.fml.common.WrongMinecraftVersionException;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent.Action;
|
|
||||||
import cpw.mods.fml.common.eventhandler.EventBus;
|
import cpw.mods.fml.common.eventhandler.EventBus;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.GameRegistryException;
|
|
||||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
@ -424,6 +425,53 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
client.displayGuiScreen(gui);
|
client.displayGuiScreen(gui);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryUser(StartupQuery query) throws InterruptedException
|
||||||
|
{
|
||||||
|
if (query.getResult() == null)
|
||||||
|
{
|
||||||
|
client.displayGuiScreen(new GuiNotification(query));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
client.displayGuiScreen(new GuiConfirmation(query));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.isSynchronous())
|
||||||
|
{
|
||||||
|
while (client.currentScreen instanceof GuiNotification)
|
||||||
|
{
|
||||||
|
if (Thread.interrupted()) throw new InterruptedException();
|
||||||
|
|
||||||
|
client.loadingScreen.resetProgresAndWorkingMessage("");
|
||||||
|
|
||||||
|
Thread.sleep(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
client.loadingScreen.resetProgresAndWorkingMessage(""); // make sure the blank screen is being drawn at the end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean handleLoadingScreen(ScaledResolution scaledResolution)
|
||||||
|
{
|
||||||
|
if (client.currentScreen instanceof GuiNotification)
|
||||||
|
{
|
||||||
|
int width = scaledResolution.getScaledWidth();
|
||||||
|
int height = scaledResolution.getScaledHeight();
|
||||||
|
int mouseX = Mouse.getX() * width / client.displayWidth;
|
||||||
|
int mouseZ = height - Mouse.getY() * height / client.displayHeight - 1;
|
||||||
|
|
||||||
|
client.currentScreen.drawScreen(mouseX, mouseZ, 0);
|
||||||
|
client.currentScreen.handleInput();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public WorldClient getWorldClient()
|
public WorldClient getWorldClient()
|
||||||
{
|
{
|
||||||
return client.theWorld;
|
return client.theWorld;
|
||||||
|
@ -447,6 +495,12 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
// NOOP
|
// NOOP
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getSavesDirectory()
|
||||||
|
{
|
||||||
|
return ((SaveFormatOld) client.getSaveLoader()).savesDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MinecraftServer getServer()
|
public MinecraftServer getServer()
|
||||||
{
|
{
|
||||||
|
@ -595,41 +649,16 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
showGuiScreen(new GuiOldSaveLoadConfirm(dirName, saveName, selectWorldGUI));
|
showGuiScreen(new GuiOldSaveLoadConfirm(dirName, saveName, selectWorldGUI));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
|
|
||||||
launchIntegratedServerCallback(dirName, saveName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CountDownLatch gameReleaseLatch;
|
|
||||||
private Thread clientWaiter;
|
|
||||||
private GameRegistryException gre;
|
|
||||||
|
|
||||||
public void launchIntegratedServerCallback(String dirName, String saveName)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.interrupted();
|
|
||||||
gameReleaseLatch = new CountDownLatch(1);
|
|
||||||
clientWaiter = Thread.currentThread();
|
|
||||||
client.launchIntegratedServer(dirName, saveName, (WorldSettings)null);
|
client.launchIntegratedServer(dirName, saveName, (WorldSettings)null);
|
||||||
System.out.printf("POKEE %b\n", Thread.currentThread().isInterrupted());
|
|
||||||
gameReleaseLatch.await();
|
|
||||||
}
|
}
|
||||||
catch (InterruptedException ie)
|
catch (StartupQuery.AbortedException e)
|
||||||
{
|
{
|
||||||
Thread.interrupted();
|
// ignore
|
||||||
throw gre;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (GameRegistryException gre)
|
|
||||||
{
|
|
||||||
client.loadWorld(null);
|
|
||||||
showGuiScreen(new GuiModItemsMissing(gre.getItems(), gre.getMessage()));
|
|
||||||
}
|
|
||||||
Thread.interrupted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showInGameModOptions(GuiIngameMenu guiIngameMenu)
|
public void showInGameModOptions(GuiIngameMenu guiIngameMenu)
|
||||||
|
@ -813,70 +842,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefaultMissingAction(FMLMissingMappingsEvent.Action action)
|
|
||||||
{
|
|
||||||
this.defaultMissingAction = action;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Action defaultMissingAction = FMLMissingMappingsEvent.Action.FAIL;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Action getDefaultMissingAction()
|
|
||||||
{
|
|
||||||
return defaultMissingAction;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void serverLoadedSuccessfully()
|
|
||||||
{
|
|
||||||
if (gameReleaseLatch!=null)
|
|
||||||
{
|
|
||||||
gameReleaseLatch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failedServerLoading(RuntimeException ex, WorldAccessContainer wac)
|
|
||||||
{
|
|
||||||
if (wac instanceof FMLContainer && ex instanceof GameRegistryException)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
gre = (GameRegistryException) ex;
|
|
||||||
Executors.newSingleThreadExecutor().submit(new Callable<Void>()
|
|
||||||
{
|
|
||||||
// This needs to happen in a separate thread so that the server can "crash"
|
|
||||||
// The three pokes are for the client - it's in a sleep loop, and needs to get
|
|
||||||
// out of it
|
|
||||||
@Override
|
|
||||||
public Void call() throws Exception
|
|
||||||
{
|
|
||||||
System.err.println("POKE");
|
|
||||||
clientWaiter.interrupt();
|
|
||||||
Thread.sleep(50);
|
|
||||||
System.err.println("POKE");
|
|
||||||
clientWaiter.interrupt();
|
|
||||||
Thread.sleep(50);
|
|
||||||
System.err.println("POKE");
|
|
||||||
clientWaiter.interrupt();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Throwable t)
|
|
||||||
{
|
|
||||||
FMLLog.log(Level.ERROR, t, "stuff");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean handlingCrash(CrashReport report)
|
|
||||||
{
|
|
||||||
return report.getCrashCause() instanceof GameRegistryException;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldAllowPlayerLogins()
|
public boolean shouldAllowPlayerLogins()
|
||||||
{
|
{
|
||||||
|
|
33
fml/src/main/java/cpw/mods/fml/client/GuiConfirmation.java
Normal file
33
fml/src/main/java/cpw/mods/fml/client/GuiConfirmation.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiOptionButton;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import cpw.mods.fml.common.StartupQuery;
|
||||||
|
|
||||||
|
public class GuiConfirmation extends GuiNotification
|
||||||
|
{
|
||||||
|
public GuiConfirmation(StartupQuery query)
|
||||||
|
{
|
||||||
|
super(query);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void initGui()
|
||||||
|
{
|
||||||
|
this.buttonList.add(new GuiOptionButton(0, this.width / 2 - 155, this.height - 38, I18n.format("gui.yes")));
|
||||||
|
this.buttonList.add(new GuiOptionButton(1, this.width / 2 - 155 + 160, this.height - 38, I18n.format("gui.no")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void actionPerformed(GuiButton button)
|
||||||
|
{
|
||||||
|
if (button.enabled && (button.id == 0 || button.id == 1))
|
||||||
|
{
|
||||||
|
FMLClientHandler.instance().showGuiScreen(null);
|
||||||
|
query.setResult(button.id == 0);
|
||||||
|
query.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
* Forge Mod Loader
|
|
||||||
* Copyright (c) 2012-2013 cpw.
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
package cpw.mods.fml.client;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import net.minecraft.client.gui.GuiButton;
|
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
|
||||||
import net.minecraft.client.resources.I18n;
|
|
||||||
|
|
||||||
public class GuiModItemsMissing extends GuiScreen
|
|
||||||
{
|
|
||||||
private List<String> missingItems;
|
|
||||||
private String message;
|
|
||||||
|
|
||||||
public GuiModItemsMissing(List<String> items, String message)
|
|
||||||
{
|
|
||||||
this.missingItems = items;
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void initGui()
|
|
||||||
{
|
|
||||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 75, this.height - 38, I18n.format("gui.done")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void actionPerformed(GuiButton p_73875_1_)
|
|
||||||
{
|
|
||||||
if (p_73875_1_.enabled && p_73875_1_.id == 1)
|
|
||||||
{
|
|
||||||
FMLClientHandler.instance().showGuiScreen(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
|
||||||
{
|
|
||||||
this.drawDefaultBackground();
|
|
||||||
int offset = 85;
|
|
||||||
this.drawCenteredString(this.fontRendererObj, "Forge Mod Loader could load this save", this.width / 2, offset, 0xFFFFFF);
|
|
||||||
offset += 10;
|
|
||||||
this.drawCenteredString(this.fontRendererObj, String.format("There are %d unassigned blocks and items in this save", missingItems.size()), this.width / 2, offset, 0xFFFFFF);
|
|
||||||
offset += 10;
|
|
||||||
this.drawCenteredString(this.fontRendererObj, "You will not be able to load until they are present again", this.width / 2, offset, 0xFFFFFF);
|
|
||||||
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
|
|
||||||
}
|
|
||||||
}
|
|
62
fml/src/main/java/cpw/mods/fml/client/GuiNotification.java
Normal file
62
fml/src/main/java/cpw/mods/fml/client/GuiNotification.java
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
package cpw.mods.fml.client;
|
||||||
|
|
||||||
|
import net.minecraft.client.gui.GuiButton;
|
||||||
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
|
import cpw.mods.fml.common.StartupQuery;
|
||||||
|
|
||||||
|
public class GuiNotification extends GuiScreen
|
||||||
|
{
|
||||||
|
public GuiNotification(StartupQuery query)
|
||||||
|
{
|
||||||
|
this.query = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void initGui()
|
||||||
|
{
|
||||||
|
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height - 38, I18n.format("gui.done")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void actionPerformed(GuiButton button)
|
||||||
|
{
|
||||||
|
if (button.enabled && button.id == 0)
|
||||||
|
{
|
||||||
|
FMLClientHandler.instance().showGuiScreen(null);
|
||||||
|
query.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_)
|
||||||
|
{
|
||||||
|
this.drawDefaultBackground();
|
||||||
|
|
||||||
|
String[] lines = query.getText().split("\n");
|
||||||
|
|
||||||
|
int spaceAvailable = this.height - 38 - 20;
|
||||||
|
int spaceRequired = Math.min(spaceAvailable, 10 + 10 * lines.length);
|
||||||
|
|
||||||
|
int offset = 10 + (spaceAvailable - spaceRequired) / 2; // vertically centered
|
||||||
|
|
||||||
|
for (String line : lines)
|
||||||
|
{
|
||||||
|
if (offset >= spaceAvailable)
|
||||||
|
{
|
||||||
|
this.drawCenteredString(this.fontRendererObj, "...", this.width / 2, offset, 0xFFFFFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!line.isEmpty()) this.drawCenteredString(this.fontRendererObj, line, this.width / 2, offset, 0xFFFFFF);
|
||||||
|
offset += 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.drawScreen(p_73863_1_, p_73863_2_, p_73863_3_);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final StartupQuery query;
|
||||||
|
}
|
|
@ -2,14 +2,19 @@ package cpw.mods.fml.client;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import net.minecraft.client.gui.GuiButton;
|
import net.minecraft.client.gui.GuiButton;
|
||||||
import net.minecraft.client.gui.GuiLabel;
|
import net.minecraft.client.gui.GuiLabel;
|
||||||
import net.minecraft.client.gui.GuiScreen;
|
import net.minecraft.client.gui.GuiScreen;
|
||||||
import net.minecraft.client.gui.GuiSelectWorld;
|
import net.minecraft.client.gui.GuiSelectWorld;
|
||||||
import net.minecraft.client.gui.GuiYesNo;
|
import net.minecraft.client.gui.GuiYesNo;
|
||||||
|
import net.minecraft.world.WorldSettings;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||||
|
import cpw.mods.fml.common.StartupQuery;
|
||||||
import cpw.mods.fml.common.ZipperUtil;
|
import cpw.mods.fml.common.ZipperUtil;
|
||||||
|
|
||||||
public class GuiOldSaveLoadConfirm extends GuiYesNo {
|
public class GuiOldSaveLoadConfirm extends GuiYesNo {
|
||||||
|
@ -65,9 +70,15 @@ public class GuiOldSaveLoadConfirm extends GuiYesNo {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FMLClientHandler.instance().showGuiScreen(null);
|
FMLClientHandler.instance().showGuiScreen(null);
|
||||||
FMLClientHandler.instance().launchIntegratedServerCallback(dirName, saveName);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
mc.launchIntegratedServer(dirName, saveName, (WorldSettings)null);
|
||||||
|
}
|
||||||
|
catch (StartupQuery.AbortedException e)
|
||||||
|
{
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common;
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.minecraft.crash.CrashReport;
|
import net.minecraft.crash.CrashReport;
|
||||||
import net.minecraft.crash.CrashReportCategory;
|
import net.minecraft.crash.CrashReportCategory;
|
||||||
import net.minecraft.entity.item.EntityItem;
|
import net.minecraft.entity.item.EntityItem;
|
||||||
|
@ -29,8 +32,10 @@ import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.storage.SaveHandler;
|
import net.minecraft.world.storage.SaveHandler;
|
||||||
import net.minecraft.world.storage.WorldInfo;
|
import net.minecraft.world.storage.WorldInfo;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -39,7 +44,7 @@ import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.MapMaker;
|
import com.google.common.collect.MapMaker;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
|
||||||
import cpw.mods.fml.common.eventhandler.EventBus;
|
import cpw.mods.fml.common.eventhandler.EventBus;
|
||||||
import cpw.mods.fml.common.gameevent.InputEvent;
|
import cpw.mods.fml.common.gameevent.InputEvent;
|
||||||
import cpw.mods.fml.common.gameevent.PlayerEvent;
|
import cpw.mods.fml.common.gameevent.PlayerEvent;
|
||||||
|
@ -79,6 +84,7 @@ public class FMLCommonHandler
|
||||||
private List<String> brandingsNoMC;
|
private List<String> brandingsNoMC;
|
||||||
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
|
private List<ICrashCallable> crashCallables = Lists.newArrayList(Loader.instance().getCallableCrashInformation());
|
||||||
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
|
private Set<SaveHandler> handlerSet = Sets.newSetFromMap(new MapMaker().weakKeys().<SaveHandler,Boolean>makeMap());
|
||||||
|
private WeakReference<SaveHandler> handlerToCheck;
|
||||||
private EventBus eventBus = new EventBus();
|
private EventBus eventBus = new EventBus();
|
||||||
/**
|
/**
|
||||||
* The FML event bus. Subscribe here for FML related events
|
* The FML event bus. Subscribe here for FML related events
|
||||||
|
@ -266,7 +272,6 @@ public class FMLCommonHandler
|
||||||
|
|
||||||
public boolean handleServerStarting(MinecraftServer server)
|
public boolean handleServerStarting(MinecraftServer server)
|
||||||
{
|
{
|
||||||
sidedDelegate.serverLoadedSuccessfully();
|
|
||||||
return Loader.instance().serverStarting(server);
|
return Loader.instance().serverStarting(server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +285,10 @@ public class FMLCommonHandler
|
||||||
Loader.instance().serverStopping();
|
Loader.instance().serverStopping();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getSavesDirectory() {
|
||||||
|
return sidedDelegate.getSavesDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
public MinecraftServer getMinecraftServerInstance()
|
public MinecraftServer getMinecraftServerInstance()
|
||||||
{
|
{
|
||||||
return sidedDelegate.getServer();
|
return sidedDelegate.getServer();
|
||||||
|
@ -290,6 +299,11 @@ public class FMLCommonHandler
|
||||||
sidedDelegate.showGuiScreen(clientGuiElement);
|
sidedDelegate.showGuiScreen(clientGuiElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void queryUser(StartupQuery query) throws InterruptedException
|
||||||
|
{
|
||||||
|
sidedDelegate.queryUser(query);
|
||||||
|
}
|
||||||
|
|
||||||
public void onServerStart(MinecraftServer dedicatedServer)
|
public void onServerStart(MinecraftServer dedicatedServer)
|
||||||
{
|
{
|
||||||
FMLServerHandler.instance();
|
FMLServerHandler.instance();
|
||||||
|
@ -372,6 +386,7 @@ public class FMLCommonHandler
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
handlerSet.add(handler);
|
handlerSet.add(handler);
|
||||||
|
handlerToCheck = new WeakReference<SaveHandler>(handler); // for confirmBackupLevelDatUse
|
||||||
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
Map<String,NBTBase> additionalProperties = Maps.newHashMap();
|
||||||
worldInfo.setAdditionalProperties(additionalProperties);
|
worldInfo.setAdditionalProperties(additionalProperties);
|
||||||
for (ModContainer mc : Loader.instance().getModList())
|
for (ModContainer mc : Loader.instance().getModList())
|
||||||
|
@ -381,20 +396,29 @@ public class FMLCommonHandler
|
||||||
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
|
WorldAccessContainer wac = ((InjectedModContainer)mc).getWrappedWorldAccessContainer();
|
||||||
if (wac != null)
|
if (wac != null)
|
||||||
{
|
{
|
||||||
try
|
wac.readData(handler, worldInfo, additionalProperties, tagCompound.getCompoundTag(mc.getModId()));
|
||||||
{
|
|
||||||
wac.readData(handler, worldInfo, additionalProperties, tagCompound.getCompoundTag(mc.getModId()));
|
|
||||||
}
|
|
||||||
catch (RuntimeException ex)
|
|
||||||
{
|
|
||||||
sidedDelegate.failedServerLoading(ex, wac);
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void confirmBackupLevelDatUse(SaveHandler handler)
|
||||||
|
{
|
||||||
|
if (handlerToCheck == null || handlerToCheck.get() != handler) {
|
||||||
|
// only run if the save has been initially loaded
|
||||||
|
handlerToCheck = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String text = "Forge Mod Loader detected that the backup level.dat is being used.\n\n" +
|
||||||
|
"This may happen due to a bug or corruption, continuing can damage\n" +
|
||||||
|
"your world beyond repair or lose data / progress.\n\n" +
|
||||||
|
"It's recommended to create a world backup before continuing.";
|
||||||
|
|
||||||
|
boolean confirmed = StartupQuery.confirm(text);
|
||||||
|
if (!confirmed) StartupQuery.abort();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean shouldServerBeKilledQuietly()
|
public boolean shouldServerBeKilledQuietly()
|
||||||
{
|
{
|
||||||
if (sidedDelegate == null)
|
if (sidedDelegate == null)
|
||||||
|
@ -514,11 +538,6 @@ public class FMLCommonHandler
|
||||||
sidedDelegate.fireNetRegistrationEvent(bus(), manager, channelSet, channel, side);
|
sidedDelegate.fireNetRegistrationEvent(bus(), manager, channelSet, channel, side);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FMLMissingMappingsEvent.Action getDefaultMissingAction()
|
|
||||||
{
|
|
||||||
return sidedDelegate.getDefaultMissingAction();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean shouldAllowPlayerLogins()
|
public boolean shouldAllowPlayerLogins()
|
||||||
{
|
{
|
||||||
return sidedDelegate.shouldAllowPlayerLogins();
|
return sidedDelegate.shouldAllowPlayerLogins();
|
||||||
|
|
|
@ -15,19 +15,26 @@ package cpw.mods.fml.common;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.nbt.NBTBase;
|
import net.minecraft.nbt.NBTBase;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.nbt.NBTTagList;
|
import net.minecraft.nbt.NBTTagList;
|
||||||
import net.minecraft.world.storage.SaveHandler;
|
import net.minecraft.world.storage.SaveHandler;
|
||||||
import net.minecraft.world.storage.WorldInfo;
|
import net.minecraft.world.storage.WorldInfo;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.eventbus.EventBus;
|
import com.google.common.eventbus.EventBus;
|
||||||
import com.google.common.eventbus.Subscribe;
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
import cpw.mods.fml.client.FMLFileResourcePack;
|
import cpw.mods.fml.client.FMLFileResourcePack;
|
||||||
import cpw.mods.fml.client.FMLFolderResourcePack;
|
import cpw.mods.fml.client.FMLFolderResourcePack;
|
||||||
import cpw.mods.fml.common.asm.FMLSanityChecker;
|
import cpw.mods.fml.common.asm.FMLSanityChecker;
|
||||||
|
@ -36,7 +43,6 @@ import cpw.mods.fml.common.network.NetworkCheckHandler;
|
||||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
import cpw.mods.fml.common.network.internal.FMLNetworkHandler;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.GameRegistryException;
|
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -95,6 +101,7 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
list.appendTag(mod);
|
list.appendTag(mod);
|
||||||
}
|
}
|
||||||
fmlData.setTag("ModList", list);
|
fmlData.setTag("ModList", list);
|
||||||
|
// name <-> id mappings
|
||||||
NBTTagList dataList = new NBTTagList();
|
NBTTagList dataList = new NBTTagList();
|
||||||
FMLLog.fine("Gathering id map for writing to world save %s", info.getWorldName());
|
FMLLog.fine("Gathering id map for writing to world save %s", info.getWorldName());
|
||||||
Map<String,Integer> itemList = GameData.buildItemDataList();
|
Map<String,Integer> itemList = GameData.buildItemDataList();
|
||||||
|
@ -106,6 +113,29 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
dataList.appendTag(tag);
|
dataList.appendTag(tag);
|
||||||
}
|
}
|
||||||
fmlData.setTag("ItemData", dataList);
|
fmlData.setTag("ItemData", dataList);
|
||||||
|
// blocked ids
|
||||||
|
fmlData.setIntArray("BlockedItemIds", GameData.getBlockedIds());
|
||||||
|
// block aliases
|
||||||
|
NBTTagList blockAliasList = new NBTTagList();
|
||||||
|
for (Entry<String, String> entry : GameData.getBlockRegistry().getAliases().entrySet())
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tag.setString("K", entry.getKey());
|
||||||
|
tag.setString("V", entry.getValue());
|
||||||
|
blockAliasList.appendTag(tag);
|
||||||
|
}
|
||||||
|
fmlData.setTag("BlockAliases", blockAliasList);
|
||||||
|
// item aliases
|
||||||
|
NBTTagList itemAliasList = new NBTTagList();
|
||||||
|
for (Entry<String, String> entry : GameData.getItemRegistry().getAliases().entrySet())
|
||||||
|
{
|
||||||
|
NBTTagCompound tag = new NBTTagCompound();
|
||||||
|
tag.setString("K", entry.getKey());
|
||||||
|
tag.setString("V", entry.getValue());
|
||||||
|
itemAliasList.appendTag(tag);
|
||||||
|
}
|
||||||
|
fmlData.setTag("ItemAliases", itemAliasList);
|
||||||
|
|
||||||
return fmlData;
|
return fmlData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +162,9 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> failedElements = null;
|
||||||
|
|
||||||
if (tag.hasKey("ModItemData"))
|
if (tag.hasKey("ModItemData"))
|
||||||
{
|
{
|
||||||
FMLLog.info("Attempting to convert old world data to new system. This may be trouble!");
|
FMLLog.info("Attempting to convert old world data to new system. This may be trouble!");
|
||||||
|
@ -172,26 +205,65 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||||
dataList.put(itemLabel, itemId);
|
dataList.put(itemLabel, itemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> failedElements = GameData.injectWorldIDMap(dataList, true, true);
|
failedElements = GameData.injectWorldIDMap(dataList, true, true);
|
||||||
if (!failedElements.isEmpty())
|
|
||||||
{
|
|
||||||
throw new GameRegistryException("Failed to load the world - there are fatal block and item id issues", failedElements);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (tag.hasKey("ItemData"))
|
else if (tag.hasKey("ItemData"))
|
||||||
{
|
{
|
||||||
NBTTagList list = tag.getTagList("ItemData", (byte)10);
|
// name <-> id mappings
|
||||||
|
NBTTagList list = tag.getTagList("ItemData", 10);
|
||||||
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
||||||
for (int i = 0; i < list.tagCount(); i++)
|
for (int i = 0; i < list.tagCount(); i++)
|
||||||
{
|
{
|
||||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||||
dataList.put(dataTag.getString("K"), dataTag.getInteger("V"));
|
dataList.put(dataTag.getString("K"), dataTag.getInteger("V"));
|
||||||
}
|
}
|
||||||
List<String> failedElements = GameData.injectWorldIDMap(dataList, true, true);
|
|
||||||
if (!failedElements.isEmpty())
|
Set<Integer> blockedIds = new HashSet<Integer>();
|
||||||
|
|
||||||
|
if (!tag.hasKey("BlockedItemIds")) // no blocked id info -> old 1.7 save
|
||||||
{
|
{
|
||||||
throw new GameRegistryException("Failed to load the world - there are fatal block and item id issues", failedElements);
|
// old early 1.7 save potentially affected by the registry mapping bug
|
||||||
|
// fix the ids the best we can...
|
||||||
|
GameData.fixBrokenIds(dataList, blockedIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// blocked ids
|
||||||
|
for (int id : tag.getIntArray("BlockedItemIds"))
|
||||||
|
{
|
||||||
|
blockedIds.add(id);
|
||||||
|
}
|
||||||
|
// block aliases
|
||||||
|
Map<String, String> blockAliases = new HashMap<String, String>();
|
||||||
|
list = tag.getTagList("BlockAliases", 10);
|
||||||
|
for (int i = 0; i < list.tagCount(); i++)
|
||||||
|
{
|
||||||
|
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||||
|
blockAliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||||
|
}
|
||||||
|
// item aliases
|
||||||
|
Map<String, String> itemAliases = new HashMap<String, String>();
|
||||||
|
list = tag.getTagList("ItemAliases", 10);
|
||||||
|
for (int i = 0; i < list.tagCount(); i++)
|
||||||
|
{
|
||||||
|
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||||
|
itemAliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||||
|
}
|
||||||
|
|
||||||
|
failedElements = GameData.injectWorldIDMap(dataList, blockedIds, blockAliases, itemAliases, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failedElements != null && !failedElements.isEmpty())
|
||||||
|
{
|
||||||
|
String text = "Forge Mod Loader could not load this save.\n\n" +
|
||||||
|
"There are "+failedElements.size()+" unassigned blocks and items in this save.\n" +
|
||||||
|
"You will not be able to load until they are present again.\n\n" +
|
||||||
|
"Missing Blocks/Items:\n";
|
||||||
|
|
||||||
|
for (String s : failedElements) text += s + "\n";
|
||||||
|
|
||||||
|
StartupQuery.notify(text);
|
||||||
|
StartupQuery.abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,13 @@ public class FMLLog
|
||||||
log(Level.ERROR, format, data);
|
log(Level.ERROR, format, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void bigWarning(String format, Object... data)
|
||||||
|
{
|
||||||
|
log(Level.WARN, "****************************************");
|
||||||
|
log(Level.WARN, "* "+format, data);
|
||||||
|
log(Level.WARN, "****************************************");
|
||||||
|
}
|
||||||
|
|
||||||
public static void warning(String format, Object... data)
|
public static void warning(String format, Object... data)
|
||||||
{
|
{
|
||||||
log(Level.WARN, format, data);
|
log(Level.WARN, format, data);
|
||||||
|
|
|
@ -12,13 +12,13 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common;
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import net.minecraft.network.INetHandler;
|
import net.minecraft.network.INetHandler;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
|
||||||
import cpw.mods.fml.common.eventhandler.EventBus;
|
import cpw.mods.fml.common.eventhandler.EventBus;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
|
@ -32,10 +32,14 @@ public interface IFMLSidedHandler
|
||||||
|
|
||||||
void showGuiScreen(Object clientGuiElement);
|
void showGuiScreen(Object clientGuiElement);
|
||||||
|
|
||||||
|
void queryUser(StartupQuery query) throws InterruptedException;
|
||||||
|
|
||||||
void beginServerLoading(MinecraftServer server);
|
void beginServerLoading(MinecraftServer server);
|
||||||
|
|
||||||
void finishServerLoading();
|
void finishServerLoading();
|
||||||
|
|
||||||
|
File getSavesDirectory();
|
||||||
|
|
||||||
MinecraftServer getServer();
|
MinecraftServer getServer();
|
||||||
|
|
||||||
boolean shouldServerShouldBeKilledQuietly();
|
boolean shouldServerShouldBeKilledQuietly();
|
||||||
|
@ -56,11 +60,5 @@ public interface IFMLSidedHandler
|
||||||
|
|
||||||
void fireNetRegistrationEvent(EventBus bus, NetworkManager manager, Set<String> channelSet, String channel, Side side);
|
void fireNetRegistrationEvent(EventBus bus, NetworkManager manager, Set<String> channelSet, String channel, Side side);
|
||||||
|
|
||||||
FMLMissingMappingsEvent.Action getDefaultMissingAction();
|
|
||||||
|
|
||||||
void serverLoadedSuccessfully();
|
|
||||||
|
|
||||||
void failedServerLoading(RuntimeException ex, WorldAccessContainer wac);
|
|
||||||
|
|
||||||
boolean shouldAllowPlayerLogins();
|
boolean shouldAllowPlayerLogins();
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,7 +130,7 @@ public class LoadController
|
||||||
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
|
FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
printModStates(sb);
|
printModStates(sb);
|
||||||
FMLLog.severe(sb.toString());
|
FMLLog.severe("%s", sb.toString());
|
||||||
if (errors.size()>0)
|
if (errors.size()>0)
|
||||||
{
|
{
|
||||||
FMLLog.severe("The following problems were captured during this phase");
|
FMLLog.severe("The following problems were captured during this phase");
|
||||||
|
|
|
@ -17,13 +17,17 @@ import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import com.google.common.base.CharMatcher;
|
import com.google.common.base.CharMatcher;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
@ -45,6 +49,7 @@ import com.google.common.collect.Ordering;
|
||||||
import com.google.common.collect.SetMultimap;
|
import com.google.common.collect.SetMultimap;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
import com.google.common.collect.TreeMultimap;
|
import com.google.common.collect.TreeMultimap;
|
||||||
|
|
||||||
import cpw.mods.fml.common.LoaderState.ModState;
|
import cpw.mods.fml.common.LoaderState.ModState;
|
||||||
import cpw.mods.fml.common.ModContainer.Disableable;
|
import cpw.mods.fml.common.ModContainer.Disableable;
|
||||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||||
|
@ -56,6 +61,7 @@ import cpw.mods.fml.common.event.FMLModIdMappingEvent;
|
||||||
import cpw.mods.fml.common.functions.ArtifactVersionNameFunction;
|
import cpw.mods.fml.common.functions.ArtifactVersionNameFunction;
|
||||||
import cpw.mods.fml.common.functions.ModIdFunction;
|
import cpw.mods.fml.common.functions.ModIdFunction;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
|
import cpw.mods.fml.common.registry.GameRegistry.Type;
|
||||||
import cpw.mods.fml.common.toposort.ModSorter;
|
import cpw.mods.fml.common.toposort.ModSorter;
|
||||||
import cpw.mods.fml.common.toposort.ModSortingException;
|
import cpw.mods.fml.common.toposort.ModSortingException;
|
||||||
import cpw.mods.fml.common.toposort.ModSortingException.SortingExceptionData;
|
import cpw.mods.fml.common.toposort.ModSortingException.SortingExceptionData;
|
||||||
|
@ -453,7 +459,6 @@ public class Loader
|
||||||
{
|
{
|
||||||
initializeLoader();
|
initializeLoader();
|
||||||
mods = Lists.newArrayList();
|
mods = Lists.newArrayList();
|
||||||
GameData.fixupRegistries();
|
|
||||||
namedMods = Maps.newHashMap();
|
namedMods = Maps.newHashMap();
|
||||||
modController = new LoadController(this);
|
modController = new LoadController(this);
|
||||||
modController.transition(LoaderState.LOADING, false);
|
modController.transition(LoaderState.LOADING, false);
|
||||||
|
@ -493,7 +498,6 @@ public class Loader
|
||||||
}
|
}
|
||||||
modController.transition(LoaderState.PREINITIALIZATION, false);
|
modController.transition(LoaderState.PREINITIALIZATION, false);
|
||||||
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, disc.getASMTable(), canonicalConfigDir);
|
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, disc.getASMTable(), canonicalConfigDir);
|
||||||
GameData.freezeData();
|
|
||||||
modController.transition(LoaderState.INITIALIZATION, false);
|
modController.transition(LoaderState.INITIALIZATION, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -676,6 +680,7 @@ public class Loader
|
||||||
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
|
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
|
||||||
modController.transition(LoaderState.AVAILABLE, false);
|
modController.transition(LoaderState.AVAILABLE, false);
|
||||||
modController.distributeStateMessage(LoaderState.AVAILABLE);
|
modController.distributeStateMessage(LoaderState.AVAILABLE);
|
||||||
|
GameData.freezeData();
|
||||||
// Dump the custom registry data map, if necessary
|
// Dump the custom registry data map, if necessary
|
||||||
GameData.dumpRegistry(minecraftDir);
|
GameData.dumpRegistry(minecraftDir);
|
||||||
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size() == 1 ? "" : "s");
|
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size() == 1 ? "" : "s");
|
||||||
|
@ -842,41 +847,74 @@ public class Loader
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> fireMissingMappingEvent(ArrayListMultimap<String,String> missing, boolean isLocalWorld)
|
/**
|
||||||
|
* Fire a FMLMissingMappingsEvent to let mods determine how blocks/items defined in the world
|
||||||
|
* save, but missing from the runtime, are to be handled.
|
||||||
|
*
|
||||||
|
* @param missing Map containing missing names with their associated id, blocks need to come before items for remapping.
|
||||||
|
* @param isLocalWorld Whether this is executing for a world load (local/server) or a client.
|
||||||
|
* @param gameData GameData instance where the new map's config is to be loaded into.
|
||||||
|
* @return List with the mapping results.
|
||||||
|
*/
|
||||||
|
public List<String> fireMissingMappingEvent(LinkedHashMap<String, Integer> missing, boolean isLocalWorld, GameData gameData, Map<String, Integer[]> remaps)
|
||||||
{
|
{
|
||||||
if (!missing.isEmpty())
|
if (missing.isEmpty()) // nothing to do
|
||||||
{
|
{
|
||||||
FMLLog.fine("There are %d mappings missing - attempting a mod remap", missing.size());
|
return ImmutableList.of();
|
||||||
ArrayListMultimap<String,MissingMapping> missingMappings = ArrayListMultimap.create();
|
}
|
||||||
List<MissingMapping> remaps = Lists.newArrayList();
|
|
||||||
for (Map.Entry<String, String> mapping : missing.entries())
|
FMLLog.fine("There are %d mappings missing - attempting a mod remap", missing.size());
|
||||||
|
ArrayListMultimap<String, MissingMapping> missingMappings = ArrayListMultimap.create();
|
||||||
|
|
||||||
|
for (Map.Entry<String, Integer> mapping : missing.entrySet())
|
||||||
|
{
|
||||||
|
int id = mapping.getValue();
|
||||||
|
MissingMapping m = new MissingMapping(mapping.getKey(), id);
|
||||||
|
missingMappings.put(m.name.substring(0, m.name.indexOf(':')), m);
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings);
|
||||||
|
modController.propogateStateMessage(missingEvent);
|
||||||
|
|
||||||
|
if (isLocalWorld) // local world, warn about entries still being set to the default action
|
||||||
|
{
|
||||||
|
boolean didWarn = false;
|
||||||
|
|
||||||
|
for (MissingMapping mapping : missingMappings.values())
|
||||||
{
|
{
|
||||||
MissingMapping m = new MissingMapping(mapping.getValue(), remaps);
|
if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT)
|
||||||
missingMappings.put(mapping.getKey(), m);
|
|
||||||
}
|
|
||||||
FMLMissingMappingsEvent missingEvent = new FMLMissingMappingsEvent(missingMappings);
|
|
||||||
modController.propogateStateMessage(missingEvent);
|
|
||||||
if (!missingMappings.isEmpty() && isLocalWorld)
|
|
||||||
{
|
|
||||||
FMLLog.severe("There are unidentified mappings in this world - we are going to attempt to process anyway");
|
|
||||||
for (java.util.Map.Entry<String, MissingMapping> missed : missingMappings.entries())
|
|
||||||
{
|
{
|
||||||
remaps.add(missed.getValue());
|
if (!didWarn)
|
||||||
|
{
|
||||||
|
FMLLog.severe("There are unidentified mappings in this world - we are going to attempt to process anyway");
|
||||||
|
didWarn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLLog.severe("Unidentified %s: %s, id %d", mapping.type == Type.BLOCK ? "block" : "item", mapping.name, mapping.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!missingMappings.isEmpty() && !isLocalWorld)
|
}
|
||||||
|
else // remote world, fail on entries with the default action
|
||||||
|
{
|
||||||
|
List<String> missedMapping = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (MissingMapping mapping : missingMappings.values())
|
||||||
{
|
{
|
||||||
List<String> missedMapping = Lists.newArrayList();
|
if (mapping.getAction() == FMLMissingMappingsEvent.Action.DEFAULT)
|
||||||
for (java.util.Map.Entry<String, MissingMapping> missed : missingMappings.entries())
|
|
||||||
{
|
{
|
||||||
missedMapping.add(missed.getKey()+ ":" + missed.getValue().name);
|
missedMapping.add(mapping.name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!missedMapping.isEmpty())
|
||||||
|
{
|
||||||
return ImmutableList.copyOf(missedMapping);
|
return ImmutableList.copyOf(missedMapping);
|
||||||
}
|
}
|
||||||
return GameData.processIdRematches(remaps, isLocalWorld);
|
|
||||||
}
|
}
|
||||||
return ImmutableList.of();
|
|
||||||
|
return GameData.processIdRematches(missingMappings.values(), isLocalWorld, gameData, remaps);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fireRemapEvent(Map<String, Integer[]> remaps)
|
public void fireRemapEvent(Map<String, Integer[]> remaps)
|
||||||
{
|
{
|
||||||
if (remaps.isEmpty())
|
if (remaps.isEmpty())
|
||||||
|
|
160
fml/src/main/java/cpw/mods/fml/common/StartupQuery.java
Normal file
160
fml/src/main/java/cpw/mods/fml/common/StartupQuery.java
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
package cpw.mods.fml.common;
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
|
||||||
|
public class StartupQuery {
|
||||||
|
// internal class/functionality, do not use
|
||||||
|
|
||||||
|
public static boolean confirm(String text)
|
||||||
|
{
|
||||||
|
StartupQuery query = new StartupQuery(text, new AtomicBoolean());
|
||||||
|
query.execute();
|
||||||
|
return query.getResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void notify(String text)
|
||||||
|
{
|
||||||
|
StartupQuery query = new StartupQuery(text, null);
|
||||||
|
query.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void abort()
|
||||||
|
{
|
||||||
|
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||||
|
if (server != null) server.initiateShutdown();
|
||||||
|
|
||||||
|
aborted = true; // to abort loading and go back to the main menu
|
||||||
|
throw new AbortedException(); // to halt the server
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void reset()
|
||||||
|
{
|
||||||
|
pending = null;
|
||||||
|
aborted = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean check()
|
||||||
|
{
|
||||||
|
if (pending != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FMLCommonHandler.instance().queryUser(pending);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
FMLLog.warning("query interrupted");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
pending = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !aborted;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static volatile StartupQuery pending;
|
||||||
|
private static volatile boolean aborted = false;
|
||||||
|
|
||||||
|
|
||||||
|
private StartupQuery(String text, AtomicBoolean result)
|
||||||
|
{
|
||||||
|
this.text = text;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean getResult()
|
||||||
|
{
|
||||||
|
return result == null ? null : result.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResult(boolean result)
|
||||||
|
{
|
||||||
|
this.result.set(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText()
|
||||||
|
{
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSynchronous()
|
||||||
|
{
|
||||||
|
return synchronous;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finish()
|
||||||
|
{
|
||||||
|
signal.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void execute()
|
||||||
|
{
|
||||||
|
String prop = System.getProperty("fml.queryResult");
|
||||||
|
|
||||||
|
if (result != null && prop != null)
|
||||||
|
{
|
||||||
|
FMLLog.info("Using fml.queryResult %s to answer the following query:\n%s", prop, text);
|
||||||
|
|
||||||
|
if (prop.equalsIgnoreCase("confirm"))
|
||||||
|
{
|
||||||
|
setResult(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (prop.equalsIgnoreCase("cancel"))
|
||||||
|
{
|
||||||
|
setResult(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLLog.warning("Invalid value for fml.queryResult: %s, expected confirm or cancel", prop);
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronous = false;
|
||||||
|
pending = this; // let the other thread start the query
|
||||||
|
|
||||||
|
// from the integrated server thread: the client will eventually check pending and execute the query
|
||||||
|
// from the client thread: synchronous execution
|
||||||
|
// dedicated server: command handling in mc is synchronous, execute the server-side query directly
|
||||||
|
if (FMLCommonHandler.instance().getSide().isServer() ||
|
||||||
|
FMLCommonHandler.instance().getEffectiveSide().isClient())
|
||||||
|
{
|
||||||
|
synchronous = true;
|
||||||
|
check();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
signal.await();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
FMLLog.warning("query interrupted");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
private AtomicBoolean result;
|
||||||
|
private CountDownLatch signal = new CountDownLatch(1);
|
||||||
|
private volatile boolean synchronous;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exception not being caught by the crash report generation logic.
|
||||||
|
*/
|
||||||
|
public static class AbortedException extends RuntimeException
|
||||||
|
{
|
||||||
|
private static final long serialVersionUID = -5933665223696833921L;
|
||||||
|
|
||||||
|
private AbortedException()
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,8 +10,13 @@ import java.util.Deque;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipOutputStream;
|
import java.util.zip.ZipOutputStream;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.Level;
|
||||||
|
|
||||||
import com.google.common.io.Files;
|
import com.google.common.io.Files;
|
||||||
|
|
||||||
|
import cpw.mods.fml.client.FMLClientHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copied from http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure
|
* Copied from http://stackoverflow.com/questions/1399126/java-util-zip-recreating-directory-structure
|
||||||
* because the code looked very tidy and neat. Thanks, McDowell!
|
* because the code looked very tidy and neat. Thanks, McDowell!
|
||||||
|
@ -55,4 +60,39 @@ public class ZipperUtil {
|
||||||
res.close();
|
res.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void backupWorld() throws IOException
|
||||||
|
{
|
||||||
|
String dirName = FMLCommonHandler.instance().getMinecraftServerInstance().getFolderName();
|
||||||
|
String saveName;
|
||||||
|
|
||||||
|
if (FMLCommonHandler.instance().getSide().isClient())
|
||||||
|
{
|
||||||
|
saveName = FMLCommonHandler.instance().getMinecraftServerInstance().getWorldName();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
saveName = dirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
backupWorld(dirName, saveName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void backupWorld(String dirName, String saveName) throws IOException
|
||||||
|
{
|
||||||
|
File dstFolder = FMLCommonHandler.instance().getSavesDirectory();
|
||||||
|
File zip = new File(dstFolder, String.format("%s-%2$tY%2$tm%2$td-%2$tH%2$tM%2$tS.zip", saveName, System.currentTimeMillis()));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ZipperUtil.zip(new File(dstFolder, dirName), zip);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
FMLLog.log(Level.WARN, e, "World backup failed.");
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLLog.info("World backup created at %s.", zip.getCanonicalPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,23 @@ package cpw.mods.fml.common.event;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.GameRegistry;
|
import cpw.mods.fml.common.registry.GameRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This event is fired if a world is loaded that has block and item mappings referring the mod that are not
|
* This event is fired if a world is loaded that has block and item mappings referring the mod that are not
|
||||||
* in existence.
|
* in existence.
|
||||||
* These can be remapped to other existing objects, or simply discarded.
|
* These can be remapped to other existing objects, or simply discarded.
|
||||||
|
* Use get() and getAll() to process this event.
|
||||||
*
|
*
|
||||||
* @author cpw
|
* @author cpw, Player
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FMLMissingMappingsEvent extends FMLEvent {
|
public class FMLMissingMappingsEvent extends FMLEvent {
|
||||||
|
@ -28,56 +32,143 @@ public class FMLMissingMappingsEvent extends FMLEvent {
|
||||||
* @author cpw
|
* @author cpw
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public static enum Action { IGNORE, WARN, FAIL }
|
public static enum Action { DEFAULT, IGNORE, WARN, FAIL, REMAP }
|
||||||
public static class MissingMapping {
|
public static class MissingMapping {
|
||||||
public final GameRegistry.Type type;
|
public final GameRegistry.Type type;
|
||||||
public final String name;
|
public final String name;
|
||||||
private Action action;
|
public final int id;
|
||||||
private List<MissingMapping> remaps;
|
private Action action = Action.DEFAULT;
|
||||||
public MissingMapping(String name, List<MissingMapping> remaps)
|
private Object target;
|
||||||
|
|
||||||
|
public MissingMapping(String name, int id)
|
||||||
{
|
{
|
||||||
this.type = name.charAt(0) == '\u0001' ? GameRegistry.Type.BLOCK : GameRegistry.Type.ITEM;
|
this.type = name.charAt(0) == '\u0001' ? GameRegistry.Type.BLOCK : GameRegistry.Type.ITEM;
|
||||||
this.name = name;
|
this.name = name.substring(1);
|
||||||
this.remaps = remaps;
|
this.id = id;
|
||||||
this.action = FMLCommonHandler.instance().getDefaultMissingAction();
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated use ignore(), warn(), fail() or remap() instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setAction(Action target)
|
public void setAction(Action target)
|
||||||
{
|
{
|
||||||
|
if (target == Action.DEFAULT || target == Action.REMAP) throw new IllegalArgumentException();
|
||||||
|
|
||||||
this.action = target;
|
this.action = target;
|
||||||
remaps.add(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore the missing item.
|
||||||
|
*/
|
||||||
|
public void ignore()
|
||||||
|
{
|
||||||
|
action = Action.IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Warn the user about the missing item.
|
||||||
|
*/
|
||||||
|
public void warn()
|
||||||
|
{
|
||||||
|
action = Action.WARN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent the world from loading due to the missing item.
|
||||||
|
*/
|
||||||
|
public void fail()
|
||||||
|
{
|
||||||
|
action = Action.FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap the missing item to the specified Block.
|
||||||
|
*
|
||||||
|
* Use this if you have renamed a Block, don't forget to handle the ItemBlock.
|
||||||
|
* Existing references using the old name will point to the new one.
|
||||||
|
*
|
||||||
|
* @param target Block to remap to.
|
||||||
|
*/
|
||||||
|
public void remap(Block target)
|
||||||
|
{
|
||||||
|
if (type != GameRegistry.Type.BLOCK) throw new IllegalArgumentException("Can't remap an item to a block.");
|
||||||
|
if (target == null) throw new NullPointerException("remap target is null");
|
||||||
|
if (GameData.getBlockRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified block %s hasn't been registered at startup.", target));
|
||||||
|
|
||||||
|
action = Action.REMAP;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap the missing item to the specified Item.
|
||||||
|
*
|
||||||
|
* Use this if you have renamed an Item.
|
||||||
|
* Existing references using the old name will point to the new one.
|
||||||
|
*
|
||||||
|
* @param target Item to remap to.
|
||||||
|
*/
|
||||||
|
public void remap(Item target)
|
||||||
|
{
|
||||||
|
if (type != GameRegistry.Type.ITEM) throw new IllegalArgumentException("Can't remap a block to an item.");
|
||||||
|
if (target == null) throw new NullPointerException("remap target is null");
|
||||||
|
if (GameData.getItemRegistry().getId(target) < 0) throw new IllegalArgumentException(String.format("The specified item %s hasn't been registered at startup.", target));
|
||||||
|
|
||||||
|
action = Action.REMAP;
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
|
||||||
public Action getAction()
|
public Action getAction()
|
||||||
{
|
{
|
||||||
return this.action;
|
return this.action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object getTarget()
|
||||||
|
{
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private ListMultimap<String,MissingMapping> missing;
|
private ListMultimap<String,MissingMapping> missing;
|
||||||
private ModContainer activeContainer;
|
private ModContainer activeContainer;
|
||||||
private List<MissingMapping> currentList;
|
|
||||||
|
|
||||||
public FMLMissingMappingsEvent(ListMultimap<String,MissingMapping> missingMappings)
|
public FMLMissingMappingsEvent(ListMultimap<String,MissingMapping> missingMappings)
|
||||||
{
|
{
|
||||||
this.missing = missingMappings;
|
this.missing = missingMappings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyModContainer(ModContainer activeContainer)
|
public void applyModContainer(ModContainer activeContainer)
|
||||||
{
|
{
|
||||||
super.applyModContainer(activeContainer);
|
super.applyModContainer(activeContainer);
|
||||||
this.activeContainer = activeContainer;
|
this.activeContainer = activeContainer;
|
||||||
this.currentList = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of missing mappings for the active mod.
|
* Get the list of missing mappings for the active mod.
|
||||||
* @return
|
*
|
||||||
|
* Process the list entries by calling ignore(), warn(), fail() or remap() on each entry.
|
||||||
|
*
|
||||||
|
* @return list of missing mappings
|
||||||
*/
|
*/
|
||||||
public List<MissingMapping> get()
|
public List<MissingMapping> get()
|
||||||
{
|
{
|
||||||
if (currentList == null)
|
return ImmutableList.copyOf(missing.get(activeContainer.getModId()));
|
||||||
{
|
}
|
||||||
currentList = ImmutableList.copyOf(missing.removeAll(activeContainer.getModId()));
|
|
||||||
}
|
/**
|
||||||
return currentList;
|
* Get the list of missing mappings for all mods.
|
||||||
|
*
|
||||||
|
* Only use this if you need to handle mod id changes, e.g. if you renamed your mod or
|
||||||
|
* split/merge into/from multiple mods.
|
||||||
|
*
|
||||||
|
* Process the list entries by calling ignore(), warn(), fail() or remap() on each entry you
|
||||||
|
* want to handle.
|
||||||
|
*
|
||||||
|
* @return list of missing mappings
|
||||||
|
*/
|
||||||
|
public List<MissingMapping> getAll()
|
||||||
|
{
|
||||||
|
return ImmutableList.copyOf(missing.values());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,6 @@ public class EntitySpawnHandler extends SimpleChannelInboundHandler<FMLMessage.E
|
||||||
|
|
||||||
private void spawnEntity(FMLMessage.EntitySpawnMessage spawnMsg)
|
private void spawnEntity(FMLMessage.EntitySpawnMessage spawnMsg)
|
||||||
{
|
{
|
||||||
System.out.println("Spawning entity on client");
|
|
||||||
ModContainer mc = Loader.instance().getIndexedModList().get(spawnMsg.modId);
|
ModContainer mc = Loader.instance().getIndexedModList().get(spawnMsg.modId);
|
||||||
EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, spawnMsg.modEntityTypeId);
|
EntityRegistration er = EntityRegistry.instance().lookupModSpawn(mc, spawnMsg.modEntityTypeId);
|
||||||
WorldClient wc = FMLClientHandler.instance().getWorldClient();
|
WorldClient wc = FMLClientHandler.instance().getWorldClient();
|
||||||
|
@ -116,7 +115,6 @@ public class EntitySpawnHandler extends SimpleChannelInboundHandler<FMLMessage.E
|
||||||
((IEntityAdditionalSpawnData) entity).readSpawnData(spawnMsg.dataStream);
|
((IEntityAdditionalSpawnData) entity).readSpawnData(spawnMsg.dataStream);
|
||||||
}
|
}
|
||||||
wc.addEntityToWorld(spawnMsg.entityId, entity);
|
wc.addEntityToWorld(spawnMsg.entityId, entity);
|
||||||
System.out.println("Entity spawned on client");
|
|
||||||
} catch (Exception e)
|
} catch (Exception e)
|
||||||
{
|
{
|
||||||
FMLLog.log(Level.ERROR, e, "A severe problem occurred during the spawning of an entity");
|
FMLLog.log(Level.ERROR, e, "A severe problem occurred during the spawning of an entity");
|
||||||
|
|
|
@ -1,159 +1,284 @@
|
||||||
package cpw.mods.fml.common.registry;
|
package cpw.mods.fml.common.registry;
|
||||||
|
|
||||||
import gnu.trove.map.hash.TIntIntHashMap;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import net.minecraft.util.ObjectIntIdentityMap;
|
import net.minecraft.util.ObjectIntIdentityMap;
|
||||||
import net.minecraft.util.RegistryNamespaced;
|
import net.minecraft.util.RegistryNamespaced;
|
||||||
import com.google.common.collect.BiMap;
|
|
||||||
import com.google.common.collect.HashBiMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableBiMap;
|
|
||||||
import com.google.common.collect.Maps;
|
|
||||||
import com.google.common.primitives.Ints;
|
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.Loader;
|
import cpw.mods.fml.common.Loader;
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
|
|
||||||
public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
static class FMLObjectIntIdentityMap extends ObjectIntIdentityMap {
|
|
||||||
private TIntIntHashMap frozenMap;
|
|
||||||
private TIntIntHashMap oldMap;
|
|
||||||
private TIntIntHashMap newMap;
|
|
||||||
private ArrayList<Integer> frozenIndex;
|
|
||||||
private ArrayList<Integer> oldIndex;
|
|
||||||
private ArrayList<Integer> newIndex;
|
|
||||||
|
|
||||||
public FMLObjectIntIdentityMap()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean containsID(int id)
|
|
||||||
{
|
|
||||||
return func_148744_b(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object get(int id)
|
|
||||||
{
|
|
||||||
return func_148745_a(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
int get(Object obj)
|
|
||||||
{
|
|
||||||
return func_148747_b(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
void beginSwap()
|
|
||||||
{
|
|
||||||
oldMap = field_148749_a;
|
|
||||||
newMap = new TIntIntHashMap(256, 0.5F, -1, -1);
|
|
||||||
oldIndex = (ArrayList<Integer>) field_148748_b;
|
|
||||||
newIndex = new ArrayList<Integer>(oldIndex.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
void freezeMap()
|
|
||||||
{
|
|
||||||
frozenMap = new TIntIntHashMap(field_148749_a);
|
|
||||||
frozenIndex = new ArrayList<Integer>(field_148748_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void revertToFrozen()
|
|
||||||
{
|
|
||||||
field_148749_a = frozenMap;
|
|
||||||
field_148748_b = frozenIndex;
|
|
||||||
}
|
|
||||||
void completeSwap()
|
|
||||||
{
|
|
||||||
field_148749_a = newMap;
|
|
||||||
field_148748_b = newIndex;
|
|
||||||
oldIndex = newIndex = null;
|
|
||||||
oldMap = newMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void revertSwap()
|
|
||||||
{
|
|
||||||
field_148749_a = oldMap;
|
|
||||||
field_148748_b = oldIndex;
|
|
||||||
oldIndex = newIndex = null;
|
|
||||||
oldMap = newMap = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void putNew(int id, Object item)
|
|
||||||
{
|
|
||||||
field_148749_a = newMap;
|
|
||||||
field_148748_b = newIndex;
|
|
||||||
super.func_148746_a(item, id);
|
|
||||||
field_148749_a = oldMap;
|
|
||||||
field_148748_b = oldIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Integer> usedIds()
|
|
||||||
{
|
|
||||||
return Ints.asList(field_148749_a.keys());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Class<I> superType;
|
private final Class<I> superType;
|
||||||
private String optionalDefaultName;
|
private String optionalDefaultName;
|
||||||
private I optionalDefaultObject;
|
private I optionalDefaultObject;
|
||||||
|
private int maxId;
|
||||||
private BiMap<String,Integer> namedIds = HashBiMap.create();
|
|
||||||
private BiMap<String,Integer> frozenIds;
|
|
||||||
private Map<String,Integer> transactionalNamedIds;
|
|
||||||
private BitSet transactionalAvailabilityMap;
|
|
||||||
private BitSet availabilityMap;
|
|
||||||
int maxId;
|
|
||||||
private int minId;
|
private int minId;
|
||||||
private char discriminator;
|
private char discriminator;
|
||||||
|
// aliases redirecting legacy names to the actual name, may need recursive application to find the final name.
|
||||||
|
// these need to be registry specific, it's possible to only have a loosely linked item for a block which may get renamed by itself.
|
||||||
|
private final Map<String, String> aliases = new HashMap<String, String>();
|
||||||
|
|
||||||
public FMLControlledNamespacedRegistry(String optionalDefault, int maxIdValue, int minIdValue, Class<I> type, char discriminator)
|
FMLControlledNamespacedRegistry(String optionalDefault, int maxIdValue, int minIdValue, Class<I> type, char discriminator)
|
||||||
{
|
{
|
||||||
this.superType = type;
|
this.superType = type;
|
||||||
this.discriminator = discriminator;
|
this.discriminator = discriminator;
|
||||||
this.optionalDefaultName = optionalDefault;
|
this.optionalDefaultName = optionalDefault;
|
||||||
this.availabilityMap = new BitSet(maxIdValue);
|
|
||||||
this.maxId = maxIdValue;
|
this.maxId = maxIdValue;
|
||||||
this.minId = minIdValue;
|
this.minId = minIdValue;
|
||||||
this.underlyingIntegerMap = new FMLObjectIntIdentityMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
void set(FMLControlledNamespacedRegistry<I> registry)
|
||||||
|
{
|
||||||
|
if (this.superType != registry.superType) throw new IllegalArgumentException("incompatible registry");
|
||||||
|
|
||||||
|
this.discriminator = registry.discriminator;
|
||||||
|
this.optionalDefaultName = registry.optionalDefaultName;
|
||||||
|
this.maxId = registry.maxId;
|
||||||
|
this.minId = registry.minId;
|
||||||
|
this.aliases.clear();
|
||||||
|
this.aliases.putAll(registry.aliases);
|
||||||
|
underlyingIntegerMap = new ObjectIntIdentityMap();
|
||||||
|
registryObjects.clear();
|
||||||
|
|
||||||
|
for (I thing : (Iterable<I>) registry)
|
||||||
|
{
|
||||||
|
addObjectRaw(registry.getId(thing), registry.getNameForObject(thing), thing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public api
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an object to the registry, trying to use the specified id.
|
||||||
|
*
|
||||||
|
* @deprecated register through {@link GameRegistry} instead.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@Deprecated
|
||||||
public void addObject(int id, String name, Object thing)
|
public void addObject(int id, String name, Object thing)
|
||||||
{
|
{
|
||||||
FMLLog.finer("Add : %s %d %s", name, id, thing);
|
GameData.getMain().register(thing, name, id);
|
||||||
add(id, name, superType.cast(thing));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int swap(int id, String name, I thing)
|
/**
|
||||||
|
* DANGEROUS! EVIL! DO NOT USE!
|
||||||
|
*
|
||||||
|
* @deprecated register through {@link GameRegistry} instead.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public void putObject(Object objName, Object obj)
|
||||||
{
|
{
|
||||||
FMLLog.fine("Swap : %s %d %s", name, id, thing);
|
String name = (String) objName;
|
||||||
BitSet temporary = availabilityMap;
|
I thing = (I) obj;
|
||||||
availabilityMap = transactionalAvailabilityMap;
|
|
||||||
|
|
||||||
int idToUse = id;
|
if (name == null) throw new NullPointerException("Can't use a null-name for the registry.");
|
||||||
if (id == 0 || availabilityMap.get(id))
|
if (name.isEmpty()) throw new IllegalArgumentException("Can't use an empty name for the registry.");
|
||||||
{
|
if (thing == null) throw new NullPointerException("Can't add null-object to the registry.");
|
||||||
idToUse = availabilityMap.nextClearBit(minId);
|
|
||||||
}
|
|
||||||
if (idToUse >= maxId)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(String.format("Invalid id %s - not accepted",id));
|
|
||||||
}
|
|
||||||
|
|
||||||
namedIds.forcePut(ensureNamespaced(name),idToUse);
|
String existingName = getNameForObject(thing);
|
||||||
reassignMapping(name, idToUse);
|
|
||||||
useSlot(idToUse);
|
if (existingName == null)
|
||||||
availabilityMap = temporary;
|
{
|
||||||
FMLLog.fine("Swap : %s %d %s", name, idToUse, thing);
|
FMLLog.bigWarning("Ignoring putObject(%s, %s), not resolvable", name, thing);
|
||||||
return idToUse;
|
}
|
||||||
|
else if (existingName.equals(name))
|
||||||
|
{
|
||||||
|
FMLLog.bigWarning("Ignoring putObject(%s, %s), already added", name, thing);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FMLLog.bigWarning("Ignoring putObject(%s, %s), adding alias to %s instead", name, thing, existingName);
|
||||||
|
addAlias(name, existingName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public int add(int id, String name, I thing)
|
|
||||||
|
/**
|
||||||
|
* Fetch the object identified by the specified name or the default object.
|
||||||
|
*
|
||||||
|
* For blocks the default object is the air block, for items it's null.
|
||||||
|
*
|
||||||
|
* @param name Unique name identifying the object.
|
||||||
|
* @return Registered object of the default object if it wasn't found-
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public I getObject(String name)
|
||||||
{
|
{
|
||||||
|
I object = getRaw(name);
|
||||||
|
return object == null ? this.optionalDefaultObject : object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch the object identified by the specified id or the default object.
|
||||||
|
*
|
||||||
|
* For blocks the default object is the air block, for items it's null.
|
||||||
|
*
|
||||||
|
* @param id ID identifying the object.
|
||||||
|
* @return Registered object of the default object if it wasn't found-
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public I getObjectById(int id)
|
||||||
|
{
|
||||||
|
I object = getRaw(id);
|
||||||
|
return object == null ? this.optionalDefaultObject : object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use getObjectById instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public I get(int id)
|
||||||
|
{
|
||||||
|
return getObjectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use getObject instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public I get(String name)
|
||||||
|
{
|
||||||
|
return getObject(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id for the specified object.
|
||||||
|
*
|
||||||
|
* Don't hold onto the id across the world, it's being dynamically re-mapped as needed.
|
||||||
|
*
|
||||||
|
* Usually the name should be used instead of the id, if using the Block/Item object itself is
|
||||||
|
* not suitable for the task.
|
||||||
|
*
|
||||||
|
* @param thing Block/Item object.
|
||||||
|
* @return Block/Item id or -1 if it wasn't found.
|
||||||
|
*/
|
||||||
|
public int getId(I thing)
|
||||||
|
{
|
||||||
|
return getIDForObject(thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified id.
|
||||||
|
*
|
||||||
|
* @param id Block/Item id.
|
||||||
|
* @return Block/Item object or null if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I getRaw(int id)
|
||||||
|
{
|
||||||
|
return superType.cast(super.getObjectById(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object identified by the specified name.
|
||||||
|
*
|
||||||
|
* @param name Block/Item name.
|
||||||
|
* @return Block/Item object or null if it wasn't found.
|
||||||
|
*/
|
||||||
|
public I getRaw(String name)
|
||||||
|
{
|
||||||
|
I ret = superType.cast(super.getObject(name));
|
||||||
|
|
||||||
|
if (ret == null) // no match, try aliases recursively
|
||||||
|
{
|
||||||
|
name = aliases.get(name);
|
||||||
|
|
||||||
|
if (name != null) return getRaw(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the registry has an entry for the specified name.
|
||||||
|
*
|
||||||
|
* Aliased names will be resolved as well.
|
||||||
|
*
|
||||||
|
* @param name Object name to check.
|
||||||
|
* @return true if a matching entry was found.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(String name)
|
||||||
|
{
|
||||||
|
boolean ret = super.containsKey(name);
|
||||||
|
|
||||||
|
if (!ret) // no match, try aliases recursively
|
||||||
|
{
|
||||||
|
name = aliases.get(name);
|
||||||
|
|
||||||
|
if (name != null) return containsKey(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the id for the specified object.
|
||||||
|
*
|
||||||
|
* Don't hold onto the id across the world, it's being dynamically re-mapped as needed.
|
||||||
|
*
|
||||||
|
* Usually the name should be used instead of the id, if using the Block/Item object itself is
|
||||||
|
* not suitable for the task.
|
||||||
|
*
|
||||||
|
* @param itemName Block/Item registry name.
|
||||||
|
* @return Block/Item id or -1 if it wasn't found.
|
||||||
|
*/
|
||||||
|
public int getId(String itemName)
|
||||||
|
{
|
||||||
|
I obj = getRaw(itemName);
|
||||||
|
if (obj == null) return -1;
|
||||||
|
|
||||||
|
return getId(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use containsKey instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public boolean contains(String itemName)
|
||||||
|
{
|
||||||
|
return containsKey(itemName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void serializeInto(Map<String, Integer> idMapping) // for saving
|
||||||
|
{
|
||||||
|
for (I thing : (Iterable<I>) this)
|
||||||
|
{
|
||||||
|
idMapping.put(discriminator+getNameForObject(thing), getId(thing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getAliases() // for saving
|
||||||
|
{
|
||||||
|
return ImmutableMap.copyOf(aliases);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the specified object to the registry.
|
||||||
|
*
|
||||||
|
* @param id ID to use if available, auto-assigned otherwise.
|
||||||
|
* @param name Name to use, prefixed by the mod id.
|
||||||
|
* @param thing Object to add.
|
||||||
|
* @param availabilityMap Map marking available IDs for auto assignment.
|
||||||
|
* @return ID eventually allocated.
|
||||||
|
*/
|
||||||
|
int add(int id, String name, I thing, BitSet availabilityMap)
|
||||||
|
{
|
||||||
|
if (name == null) throw new NullPointerException("Can't use a null-name for the registry.");
|
||||||
|
if (name.isEmpty()) throw new IllegalArgumentException("Can't use an empty name for the registry.");
|
||||||
|
if (thing == null) throw new NullPointerException("Can't add null-object to the registry.");
|
||||||
if (name.equals(optionalDefaultName))
|
if (name.equals(optionalDefaultName))
|
||||||
{
|
{
|
||||||
this.optionalDefaultObject = thing;
|
this.optionalDefaultObject = thing;
|
||||||
|
@ -164,9 +289,9 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
{
|
{
|
||||||
idToUse = availabilityMap.nextClearBit(minId);
|
idToUse = availabilityMap.nextClearBit(minId);
|
||||||
}
|
}
|
||||||
if (idToUse >= maxId)
|
if (idToUse > maxId)
|
||||||
{
|
{
|
||||||
throw new RuntimeException(String.format("Invalid id %s - not accepted",id));
|
throw new RuntimeException(String.format("Invalid id %d - maximum id range exceeded.", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
ModContainer mc = Loader.instance().activeModContainer();
|
ModContainer mc = Loader.instance().activeModContainer();
|
||||||
|
@ -175,150 +300,79 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||||
String prefix = mc.getModId();
|
String prefix = mc.getModId();
|
||||||
name = prefix + ":"+ name;
|
name = prefix + ":"+ name;
|
||||||
}
|
}
|
||||||
namedIds.forcePut(ensureNamespaced(name),idToUse);
|
|
||||||
super.addObject(idToUse, name, thing);
|
if (getRaw(name) == thing) // already registered, return prev registration's id
|
||||||
useSlot(idToUse);
|
{
|
||||||
FMLLog.finer("Add : %s %d %s", name, idToUse, thing);
|
FMLLog.bigWarning("The object %s has been registered twice for the same name %s.", thing, name);
|
||||||
|
return getId(thing);
|
||||||
|
}
|
||||||
|
if (getRaw(name) != null) // duplicate name, will crash later due to the BiMap
|
||||||
|
{
|
||||||
|
FMLLog.bigWarning("The name %s has been registered twice, for %s and %s.", name, getRaw(name), thing);
|
||||||
|
}
|
||||||
|
if (getId(thing) >= 0) // duplicate object, will crash later due to the BiMap
|
||||||
|
{
|
||||||
|
FMLLog.bigWarning("The object %s has been registered twice, using the names %s and %s.", thing, getNameForObject(thing), name);
|
||||||
|
}
|
||||||
|
if (GameData.isFrozen(this))
|
||||||
|
{
|
||||||
|
FMLLog.bigWarning("The object %s (name %s) is being added too late.", thing, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
addObjectRaw(idToUse, name, thing);
|
||||||
|
|
||||||
|
FMLLog.finer("Registry add: %s %d %s", name, idToUse, thing);
|
||||||
return idToUse;
|
return idToUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void addAlias(String from, String to)
|
||||||
public I getObject(String name)
|
|
||||||
{
|
{
|
||||||
I object = superType.cast(super.getObject(name));
|
aliases.put(from, to);
|
||||||
return object == null ? this.optionalDefaultObject : object;
|
FMLLog.finer("Registry alias: %s -> %s", from, to);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public I getObjectById(int id)
|
|
||||||
{
|
|
||||||
I object = superType.cast(super.getObjectById(id));
|
|
||||||
return object == null ? this.optionalDefaultObject : object;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private FMLObjectIntIdentityMap idMap()
|
|
||||||
{
|
|
||||||
return (FMLObjectIntIdentityMap) underlyingIntegerMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private BiMap<String,I> nameMap()
|
Map<String,Integer> getEntriesNotIn(FMLControlledNamespacedRegistry<I> registry)
|
||||||
{
|
{
|
||||||
return (BiMap<String,I>) registryObjects;
|
Map<String,Integer> ret = new HashMap<String, Integer>();
|
||||||
}
|
|
||||||
|
|
||||||
void beginIdSwap()
|
for (I thing : (Iterable<I>) this)
|
||||||
{
|
|
||||||
idMap().beginSwap();
|
|
||||||
transactionalNamedIds = Maps.newHashMap();
|
|
||||||
transactionalAvailabilityMap = new BitSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
void reassignMapping(String name, int newId)
|
|
||||||
{
|
|
||||||
Object item = nameMap().get(name);
|
|
||||||
idMap().putNew(newId, item);
|
|
||||||
transactionalNamedIds.put(name,newId);
|
|
||||||
transactionalAvailabilityMap.set(newId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void freezeMap()
|
|
||||||
{
|
|
||||||
if (frozenIds == null)
|
|
||||||
{
|
{
|
||||||
frozenIds = ImmutableBiMap.copyOf(namedIds);
|
if (!registry.field_148758_b.containsKey(thing)) ret.put(getNameForObject(thing), getId(thing));
|
||||||
idMap().freezeMap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void revertToFrozen()
|
@SuppressWarnings("unchecked")
|
||||||
{
|
|
||||||
namedIds = HashBiMap.create(frozenIds);
|
|
||||||
idMap().revertToFrozen();
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String,Integer> getMissingMappings()
|
|
||||||
{
|
|
||||||
return Maps.difference(frozenIds, transactionalNamedIds).entriesOnlyOnLeft();
|
|
||||||
}
|
|
||||||
void completeIdSwap()
|
|
||||||
{
|
|
||||||
idMap().completeSwap();
|
|
||||||
namedIds.clear();
|
|
||||||
namedIds.putAll(transactionalNamedIds);
|
|
||||||
transactionalNamedIds = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
void revertSwap()
|
|
||||||
{
|
|
||||||
idMap().revertSwap();
|
|
||||||
transactionalNamedIds = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public I get(int id)
|
|
||||||
{
|
|
||||||
return getObjectById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public I get(String name)
|
|
||||||
{
|
|
||||||
return getObject(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(I thing)
|
|
||||||
{
|
|
||||||
return getIDForObject(thing);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void serializeInto(Map<String, Integer> idMapping)
|
|
||||||
{
|
|
||||||
for (Entry<String, Integer> id: namedIds.entrySet())
|
|
||||||
{
|
|
||||||
idMapping.put(discriminator+id.getKey(), id.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void useSlot(int id)
|
|
||||||
{
|
|
||||||
if (id >= maxId) return;
|
|
||||||
availabilityMap.set(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Integer> usedIds()
|
|
||||||
{
|
|
||||||
return ((FMLObjectIntIdentityMap)underlyingIntegerMap).usedIds();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId(String itemName)
|
|
||||||
{
|
|
||||||
if (namedIds.containsKey(itemName))
|
|
||||||
{
|
|
||||||
return namedIds.get(itemName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean contains(String itemName)
|
|
||||||
{
|
|
||||||
return namedIds.containsKey(itemName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dump()
|
void dump()
|
||||||
{
|
{
|
||||||
for (Entry<String, Integer> entry : namedIds.entrySet())
|
List<Integer> ids = new ArrayList<Integer>();
|
||||||
|
|
||||||
|
for (I thing : (Iterable<I>) this)
|
||||||
{
|
{
|
||||||
String name = entry.getKey();
|
ids.add(getId(thing));
|
||||||
Object thing = idMap().get(entry.getValue().intValue());
|
}
|
||||||
FMLLog.finer("Registry : %s %d %s", name, entry.getValue(), thing);
|
|
||||||
|
// sort by id
|
||||||
|
Collections.sort(ids);
|
||||||
|
|
||||||
|
for (int id : ids)
|
||||||
|
{
|
||||||
|
I thing = getRaw(id);
|
||||||
|
FMLLog.finer("Registry: %s %d %s", getNameForObject(thing), id, thing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BitSet slots()
|
/**
|
||||||
|
* Version of addObject not using the API restricting overrides.
|
||||||
|
*/
|
||||||
|
private void addObjectRaw(int id, String name, I thing)
|
||||||
{
|
{
|
||||||
return (BitSet) availabilityMap.clone();
|
if (name == null) throw new NullPointerException();
|
||||||
|
if (thing == null) throw new NullPointerException();
|
||||||
|
|
||||||
|
underlyingIntegerMap.func_148746_a(thing, id); // obj <-> id
|
||||||
|
super.putObject(ensureNamespaced(name), thing); // name <-> obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -136,7 +136,7 @@ public class GameRegistry
|
||||||
*/
|
*/
|
||||||
public static Item registerItem(Item item, String name, String modId)
|
public static Item registerItem(Item item, String name, String modId)
|
||||||
{
|
{
|
||||||
GameData.registerItem(item, name, modId);
|
GameData.getMain().registerItem(item, name, modId);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,13 +192,11 @@ public class GameRegistry
|
||||||
Constructor<? extends ItemBlock> itemCtor = itemclass.getConstructor(ctorArgClasses);
|
Constructor<? extends ItemBlock> itemCtor = itemclass.getConstructor(ctorArgClasses);
|
||||||
i = itemCtor.newInstance(ObjectArrays.concat(block, itemCtorArgs));
|
i = itemCtor.newInstance(ObjectArrays.concat(block, itemCtorArgs));
|
||||||
}
|
}
|
||||||
|
// block registration has to happen first
|
||||||
|
GameData.getMain().registerBlock(block, name, modId);
|
||||||
if (i != null)
|
if (i != null)
|
||||||
{
|
{
|
||||||
GameData.registerBlockAndItem(i, block, name, modId);
|
GameData.getMain().registerItem(i, name, modId);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GameData.registerBlock(block, name, modId);
|
|
||||||
}
|
}
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package cpw.mods.fml.common.registry;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class GameRegistryException extends RuntimeException {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private List<String> items;
|
|
||||||
|
|
||||||
public GameRegistryException(String message, List<String> items)
|
|
||||||
{
|
|
||||||
super(message);
|
|
||||||
this.items = items;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getItems()
|
|
||||||
{
|
|
||||||
return this.items;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,20 +12,27 @@
|
||||||
*/
|
*/
|
||||||
package cpw.mods.fml.server;
|
package cpw.mods.fml.server;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import net.minecraft.command.ServerCommand;
|
||||||
import net.minecraft.network.INetHandler;
|
import net.minecraft.network.INetHandler;
|
||||||
import net.minecraft.network.NetHandlerPlayServer;
|
import net.minecraft.network.NetHandlerPlayServer;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.dedicated.DedicatedServer;
|
import net.minecraft.server.dedicated.DedicatedServer;
|
||||||
|
import net.minecraft.world.storage.SaveFormatOld;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.IFMLSidedHandler;
|
import cpw.mods.fml.common.IFMLSidedHandler;
|
||||||
import cpw.mods.fml.common.Loader;
|
import cpw.mods.fml.common.Loader;
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
import cpw.mods.fml.common.WorldAccessContainer;
|
import cpw.mods.fml.common.StartupQuery;
|
||||||
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
|
|
||||||
import cpw.mods.fml.common.eventhandler.EventBus;
|
import cpw.mods.fml.common.eventhandler.EventBus;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
import cpw.mods.fml.common.network.FMLNetworkEvent;
|
||||||
import cpw.mods.fml.common.registry.LanguageRegistry;
|
import cpw.mods.fml.common.registry.LanguageRegistry;
|
||||||
|
@ -94,6 +101,12 @@ public class FMLServerHandler implements IFMLSidedHandler
|
||||||
throw new RuntimeException(message, exception);
|
throw new RuntimeException(message, exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File getSavesDirectory()
|
||||||
|
{
|
||||||
|
return ((SaveFormatOld) server.getActiveAnvilConverter()).savesDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the server instance
|
* Get the server instance
|
||||||
*/
|
*/
|
||||||
|
@ -134,6 +147,67 @@ public class FMLServerHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void queryUser(StartupQuery query) throws InterruptedException
|
||||||
|
{
|
||||||
|
if (query.getResult() == null)
|
||||||
|
{
|
||||||
|
FMLLog.warning("%s", query.getText());
|
||||||
|
query.finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
String text = query.getText() +
|
||||||
|
"\n\nRun the command /fml confirm or or /fml cancel to proceed." +
|
||||||
|
"\nAlternatively start the server with -Dfml.queryResult=confirm or -Dfml.queryResult=cancel to preselect the answer.";
|
||||||
|
FMLLog.warning("%s", text);
|
||||||
|
|
||||||
|
if (!query.isSynchronous()) return; // no-op until mc does commands in another thread (if ever)
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
|
||||||
|
while (!done && server.isServerRunning())
|
||||||
|
{
|
||||||
|
if (Thread.interrupted()) throw new InterruptedException();
|
||||||
|
|
||||||
|
DedicatedServer dedServer = (DedicatedServer) server;
|
||||||
|
|
||||||
|
// rudimentary command processing, check for fml confirm/cancel and stop commands
|
||||||
|
synchronized (dedServer.pendingCommandList)
|
||||||
|
{
|
||||||
|
for (Iterator<ServerCommand> it = dedServer.pendingCommandList.iterator(); it.hasNext(); )
|
||||||
|
{
|
||||||
|
String cmd = it.next().command.trim().toLowerCase();
|
||||||
|
|
||||||
|
if (cmd.equals("/fml confirm"))
|
||||||
|
{
|
||||||
|
FMLLog.info("confirmed");
|
||||||
|
query.setResult(true);
|
||||||
|
done = true;
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
else if (cmd.equals("/fml cancel"))
|
||||||
|
{
|
||||||
|
FMLLog.info("cancelled");
|
||||||
|
query.setResult(false);
|
||||||
|
done = true;
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
else if (cmd.equals("/stop"))
|
||||||
|
{
|
||||||
|
StartupQuery.abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(10L);
|
||||||
|
}
|
||||||
|
|
||||||
|
query.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldServerShouldBeKilledQuietly()
|
public boolean shouldServerShouldBeKilledQuietly()
|
||||||
{
|
{
|
||||||
|
@ -182,21 +256,7 @@ public class FMLServerHandler implements IFMLSidedHandler
|
||||||
{
|
{
|
||||||
bus.post(new FMLNetworkEvent.CustomPacketRegistrationEvent<NetHandlerPlayServer>(manager, channelSet, channel, side, NetHandlerPlayServer.class));
|
bus.post(new FMLNetworkEvent.CustomPacketRegistrationEvent<NetHandlerPlayServer>(manager, channelSet, channel, side, NetHandlerPlayServer.class));
|
||||||
}
|
}
|
||||||
@Override
|
|
||||||
public FMLMissingMappingsEvent.Action getDefaultMissingAction()
|
|
||||||
{
|
|
||||||
return FMLMissingMappingsEvent.Action.valueOf(System.getProperty("fml.missingBlockAction", "FAIL"));
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void serverLoadedSuccessfully()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void failedServerLoading(RuntimeException ex, WorldAccessContainer wac)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldAllowPlayerLogins()
|
public boolean shouldAllowPlayerLogins()
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,6 +74,12 @@ public net.minecraft.client.gui.GuiScreen field_146297_k # minecraft instance -
|
||||||
# Minecraft
|
# Minecraft
|
||||||
#public atv.D #FD:Minecraft/field_71425_J #running
|
#public atv.D #FD:Minecraft/field_71425_J #running
|
||||||
public net.minecraft.client.Minecraft field_71446_o # textureManager
|
public net.minecraft.client.Minecraft field_71446_o # textureManager
|
||||||
|
## ItemBlock
|
||||||
|
public net.minecraft.item.ItemBlock field_150939_a
|
||||||
|
## DedicatedServer
|
||||||
|
public net.minecraft.server.dedicated.DedicatedServer field_71341_l # pendingCommandList
|
||||||
|
## SaveFormatOld
|
||||||
|
public net.minecraft.world.storage.SaveFormatOld field_75808_a # savesDirectory
|
||||||
|
|
||||||
protected net.minecraft.util.ObjectIntIdentityMap field_148749_a # internal map
|
protected net.minecraft.util.ObjectIntIdentityMap field_148749_a # internal map
|
||||||
protected net.minecraft.util.ObjectIntIdentityMap field_148748_b # internal index list
|
protected net.minecraft.util.ObjectIntIdentityMap field_148748_b # internal index list
|
||||||
|
|
Loading…
Reference in a new issue