Fixing id map generation - should validate correctly now

This commit is contained in:
Christian 2012-12-09 22:24:16 -05:00
parent bccad16ea6
commit aee1a3f24d
10 changed files with 217 additions and 160 deletions

View file

@ -64,6 +64,7 @@ import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket; import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.network.ModMissingPacket; import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
import cpw.mods.fml.common.registry.IThrowableEntity; import cpw.mods.fml.common.registry.IThrowableEntity;
@ -479,13 +480,13 @@ public class FMLClientHandler implements IFMLSidedHandler
if (response) if (response)
{ {
serverShouldBeKilledQuietly = false; serverShouldBeKilledQuietly = false;
GameRegistry.releaseGate(true); GameData.releaseGate(true);
client.continueWorldLoading(); client.continueWorldLoading();
} }
else else
{ {
serverShouldBeKilledQuietly = true; serverShouldBeKilledQuietly = true;
GameRegistry.releaseGate(false); GameData.releaseGate(false);
// Reset and clear the client state // Reset and clear the client state
client.func_71403_a((WorldClient)null); client.func_71403_a((WorldClient)null);
client.func_71373_a(null); client.func_71373_a(null);

View file

@ -30,6 +30,7 @@ import com.google.common.collect.MapMaker;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus; import com.google.common.eventbus.EventBus;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.ItemData; import cpw.mods.fml.common.registry.ItemData;
@ -79,7 +80,7 @@ public class FMLDummyContainer extends DummyModContainer implements WorldAccessC
} }
fmlData.func_74782_a("ModList", list); fmlData.func_74782_a("ModList", list);
NBTTagList itemList = new NBTTagList(); NBTTagList itemList = new NBTTagList();
GameRegistry.writeItemData(itemList); GameData.writeItemData(itemList);
fmlData.func_74782_a("ModItemData", itemList); fmlData.func_74782_a("ModItemData", itemList);
return fmlData; return fmlData;
} }
@ -110,12 +111,12 @@ public class FMLDummyContainer extends DummyModContainer implements WorldAccessC
if (tag.func_74764_b("ModItemData")) if (tag.func_74764_b("ModItemData"))
{ {
NBTTagList modList = tag.func_74761_m("ModItemData"); NBTTagList modList = tag.func_74761_m("ModItemData");
Set<ItemData> worldSaveItems = GameRegistry.buildWorldItemData(modList); Set<ItemData> worldSaveItems = GameData.buildWorldItemData(modList);
GameRegistry.validateWorldSave(worldSaveItems); GameData.validateWorldSave(worldSaveItems);
} }
else else
{ {
GameRegistry.validateWorldSave(null); GameData.validateWorldSave(null);
} }
} }

View file

@ -0,0 +1,23 @@
--- common/cpw/mods/fml/common/FMLDummyContainer.java
+++ common/cpw/mods/fml/common/FMLDummyContainer.java
@@ -17,16 +17,16 @@
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import net.minecraft.nbt.*;
+import net.minecraft.nbt.NBTBase;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.storage.SaveHandler;
import net.minecraft.world.storage.WorldInfo;
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.Sets;
import com.google.common.eventbus.EventBus;
+import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.ItemData;

View file

@ -15,6 +15,7 @@ import com.google.common.primitives.UnsignedBytes;
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.FMLLog; import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.ItemData; import cpw.mods.fml.common.registry.ItemData;
import net.minecraft.src.CompressedStreamTools; import net.minecraft.src.CompressedStreamTools;
@ -77,14 +78,14 @@ public class ModIdMapPacket extends FMLPacket {
public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName) public void execute(INetworkManager network, FMLNetworkHandler handler, NetHandler netHandler, String userName)
{ {
byte[] allData = Bytes.concat(partials); byte[] allData = Bytes.concat(partials);
GameRegistry.initializeServerGate(1); GameData.initializeServerGate(1);
try try
{ {
NBTTagCompound serverList = CompressedStreamTools.func_74792_a(allData); NBTTagCompound serverList = CompressedStreamTools.func_74792_a(allData);
NBTTagList list = serverList.func_74761_m("List"); NBTTagList list = serverList.func_74761_m("List");
Set<ItemData> itemData = GameRegistry.buildWorldItemData(list); Set<ItemData> itemData = GameData.buildWorldItemData(list);
GameRegistry.validateWorldSave(itemData); GameData.validateWorldSave(itemData);
MapDifference<Integer, ItemData> serverDifference = GameRegistry.gateWorldLoadingForValidation(); MapDifference<Integer, ItemData> serverDifference = GameData.gateWorldLoadingForValidation();
if (serverDifference!=null) if (serverDifference!=null)
{ {
FMLCommonHandler.instance().disconnectIDMismatch(serverDifference, netHandler, network); FMLCommonHandler.instance().disconnectIDMismatch(serverDifference, netHandler, network);

View file

@ -25,6 +25,7 @@ import com.google.common.io.ByteStreams;
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;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
public class ModListResponsePacket extends FMLPacket public class ModListResponsePacket extends FMLPacket
@ -127,7 +128,7 @@ public class ModListResponsePacket extends FMLPacket
pkt.field_73628_b = pkt.field_73629_c.length; pkt.field_73628_b = pkt.field_73629_c.length;
network.func_74429_a(pkt); network.func_74429_a(pkt);
NBTTagList itemList = new NBTTagList(); NBTTagList itemList = new NBTTagList();
GameRegistry.writeItemData(itemList); GameData.writeItemData(itemList);
byte[][] registryPackets = FMLPacket.makePacketSet(MOD_IDMAP, itemList); byte[][] registryPackets = FMLPacket.makePacketSet(MOD_IDMAP, itemList);
for (int i = 0; i < registryPackets.length; i++) for (int i = 0; i < registryPackets.length; i++)
{ {

View file

@ -0,0 +1,157 @@
package cpw.mods.fml.common.registry;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import net.minecraft.src.Item;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.NBTTagList;
import com.google.common.base.Function;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.ModContainer;
public class GameData {
private static Map<Integer, ItemData> idMap = Maps.newHashMap();
private static CountDownLatch serverValidationLatch;
private static CountDownLatch clientValidationLatch;
private static MapDifference<Integer, ItemData> difference;
private static boolean shouldContinue = true;
private static boolean isSaveValid = true;
public static void newItemAdded(Item item)
{
ModContainer mc = Loader.instance().activeModContainer();
if (mc == null)
{
mc = Loader.instance().getMinecraftModContainer();
if (Loader.instance().hasReachedState(LoaderState.AVAILABLE))
{
FMLLog.severe("It appears something has tried to allocate an Item outside of the initialization phase of Minecraft, this could be very bad for your network connectivity.");
}
}
String itemType = item.getClass().getName();
ItemData itemData = new ItemData(item, mc);
if (idMap.containsKey(item.field_77779_bT))
{
ItemData id = idMap.get(item.field_77779_bT);
FMLLog.warning("[ItemTracker] The mod %s is attempting to overwrite existing item at %d (%s from %s) with %s", mc.getModId(), id.itemId, id.itemType, id.modId, itemType);
}
idMap.put(item.field_77779_bT, itemData);
FMLLog.fine("[ItemTracker] Adding item %s(%d) owned by %s", item.getClass().getName(), item.field_77779_bT, mc.getModId());
}
public static void validateWorldSave(Set<ItemData> worldSaveItems)
{
isSaveValid = true;
shouldContinue = true;
// allow ourselves to continue if there's no saved data
if (worldSaveItems == null)
{
serverValidationLatch.countDown();
try
{
clientValidationLatch.await();
}
catch (InterruptedException e)
{
}
return;
}
Function<? super ItemData, Integer> idMapFunction = new Function<ItemData, Integer>() {
public Integer apply(ItemData input) {
return input.itemId;
};
};
Map<Integer,ItemData> worldMap = Maps.uniqueIndex(worldSaveItems,idMapFunction);
difference = Maps.difference(worldMap, idMap);
if (!difference.entriesDiffering().isEmpty() || !difference.entriesOnlyOnLeft().isEmpty())
{
isSaveValid = false;
serverValidationLatch.countDown();
}
else
{
isSaveValid = true;
serverValidationLatch.countDown();
}
try
{
clientValidationLatch.await();
if (!shouldContinue)
{
throw new RuntimeException("This server instance is going to stop abnormally because of a fatal ID mismatch");
}
}
catch (InterruptedException e)
{
}
}
public static void writeItemData(NBTTagList itemList)
{
for (ItemData dat : idMap.values())
{
itemList.func_74742_a(dat.toNBT());
}
}
/**
* Initialize the server gate
* @param gateCount the countdown amount. If it's 2 we're on the client and the client and server
* will wait at the latch. 1 is a server and the server will proceed
*/
public static void initializeServerGate(int gateCount)
{
serverValidationLatch = new CountDownLatch(gateCount - 1);
clientValidationLatch = new CountDownLatch(gateCount - 1);
}
public static MapDifference<Integer, ItemData> gateWorldLoadingForValidation()
{
try
{
serverValidationLatch.await();
if (!isSaveValid)
{
return difference;
}
}
catch (InterruptedException e)
{
}
difference = null;
return null;
}
public static void releaseGate(boolean carryOn)
{
shouldContinue = carryOn;
clientValidationLatch.countDown();
}
public static Set<ItemData> buildWorldItemData(NBTTagList modList)
{
Set<ItemData> worldSaveItems = Sets.newHashSet();
for (int i = 0; i < modList.func_74745_c(); i++)
{
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
ItemData dat = new ItemData(mod);
worldSaveItems.add(dat);
}
return worldSaveItems;
}
}

View file

@ -52,7 +52,6 @@ import cpw.mods.fml.common.ModContainer;
public class GameRegistry public class GameRegistry
{ {
private static Multimap<ModContainer, BlockProxy> blockRegistry = ArrayListMultimap.create(); private static Multimap<ModContainer, BlockProxy> blockRegistry = ArrayListMultimap.create();
private static Set<ItemData> itemRegistry = Sets.newHashSet();
private static Set<IWorldGenerator> worldGenerators = Sets.newHashSet(); private static Set<IWorldGenerator> worldGenerators = Sets.newHashSet();
private static List<IFuelHandler> fuelHandlers = Lists.newArrayList(); private static List<IFuelHandler> fuelHandlers = Lists.newArrayList();
private static List<ICraftingHandler> craftingHandlers = Lists.newArrayList(); private static List<ICraftingHandler> craftingHandlers = Lists.newArrayList();
@ -302,133 +301,4 @@ public class GameRegistry
tracker.onPlayerRespawn(player); tracker.onPlayerRespawn(player);
} }
public static void newItemAdded(Item item)
{
ModContainer mc = Loader.instance().activeModContainer();
if (mc == null)
{
mc = Loader.instance().getMinecraftModContainer();
if (Loader.instance().hasReachedState(LoaderState.AVAILABLE))
{
FMLLog.severe("It appears something has tried to allocate an Item outside of the initialization phase of Minecraft, this could be very bad for your network connectivity.");
}
}
String itemType = item.getClass().getName();
itemRegistry.add(new ItemData(item, mc));
System.out.printf("Adding item %s(%d) owned by %s\n", item.getClass().getName(), item.field_77779_bT, mc);
}
public static void validateWorldSave(Set<ItemData> worldSaveItems)
{
isSaveValid = true;
shouldContinue = true;
// allow ourselves to continue if there's no saved data
if (worldSaveItems == null)
{
serverValidationLatch.countDown();
try
{
clientValidationLatch.await();
}
catch (InterruptedException e)
{
}
return;
}
Function<? super ItemData, Integer> idMapFunction = new Function<ItemData, Integer>() {
public Integer apply(ItemData input) {
return input.itemId;
};
};
Map<Integer,ItemData> worldMap = Maps.uniqueIndex(worldSaveItems,idMapFunction);
Map<Integer,ItemData> gameMap = Maps.uniqueIndex(itemRegistry, idMapFunction);
difference = Maps.difference(worldMap, gameMap);
if (!difference.entriesDiffering().isEmpty() || !difference.entriesOnlyOnLeft().isEmpty())
{
isSaveValid = false;
serverValidationLatch.countDown();
}
else
{
isSaveValid = true;
serverValidationLatch.countDown();
}
try
{
clientValidationLatch.await();
if (!shouldContinue)
{
throw new RuntimeException("This server instance is going to stop abnormally because of a fatal ID mismatch");
}
}
catch (InterruptedException e)
{
}
}
public static void writeItemData(NBTTagList itemList)
{
for (ItemData dat : itemRegistry)
{
itemList.func_74742_a(dat.toNBT());
}
}
/**
* Initialize the server gate
* @param gateCount the countdown amount. If it's 2 we're on the client and the client and server
* will wait at the latch. 1 is a server and the server will proceed
*/
public static void initializeServerGate(int gateCount)
{
serverValidationLatch = new CountDownLatch(gateCount - 1);
clientValidationLatch = new CountDownLatch(gateCount - 1);
}
public static MapDifference<Integer, ItemData> gateWorldLoadingForValidation()
{
try
{
serverValidationLatch.await();
if (!isSaveValid)
{
return difference;
}
}
catch (InterruptedException e)
{
}
difference = null;
return null;
}
public static void releaseGate(boolean carryOn)
{
shouldContinue = carryOn;
clientValidationLatch.countDown();
}
public static Set<ItemData> buildWorldItemData(NBTTagList modList)
{
Set<ItemData> worldSaveItems = Sets.newHashSet();
for (int i = 0; i < modList.func_74745_c(); i++)
{
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
ItemData dat = new ItemData(mod);
worldSaveItems.add(dat);
}
return worldSaveItems;
}
private static CountDownLatch serverValidationLatch;
private static CountDownLatch clientValidationLatch;
private static MapDifference<Integer, ItemData> difference;
private static boolean shouldContinue = true;
private static boolean isSaveValid = true;
} }

View file

@ -34,6 +34,7 @@ import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket;
import cpw.mods.fml.common.network.EntitySpawnPacket; import cpw.mods.fml.common.network.EntitySpawnPacket;
import cpw.mods.fml.common.network.ModMissingPacket; import cpw.mods.fml.common.network.ModMissingPacket;
import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
import cpw.mods.fml.common.registry.GameData;
import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.ItemData; import cpw.mods.fml.common.registry.ItemData;
import cpw.mods.fml.common.registry.LanguageRegistry; import cpw.mods.fml.common.registry.LanguageRegistry;
@ -93,7 +94,7 @@ public class FMLServerHandler implements IFMLSidedHandler
{ {
Loader.instance().initializeMods(); Loader.instance().initializeMods();
LanguageRegistry.reloadLanguageTable(); LanguageRegistry.reloadLanguageTable();
GameRegistry.initializeServerGate(1); GameData.initializeServerGate(1);
} }
@Override @Override

View file

@ -1,19 +1,20 @@
--- ../src-base/common/net/minecraft/src/Item.java --- ../src-base/common/net/minecraft/src/Item.java
+++ ../src-work/common/net/minecraft/src/Item.java +++ ../src-work/common/net/minecraft/src/Item.java
@@ -2,6 +2,8 @@ @@ -2,6 +2,9 @@
import cpw.mods.fml.common.Side; import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly; import cpw.mods.fml.common.asm.SideOnly;
+import cpw.mods.fml.common.registry.GameData;
+import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.common.registry.GameRegistry;
+ +
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -187,6 +189,7 @@ @@ -187,6 +190,7 @@
} }
field_77698_e[256 + p_i3659_1_] = this; field_77698_e[256 + p_i3659_1_] = this;
+ GameRegistry.newItemAdded(this); + GameData.newItemAdded(this);
} }
public Item func_77665_c(int p_77665_1_) public Item func_77665_c(int p_77665_1_)

View file

@ -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
@@ -2,6 +2,9 @@ @@ -2,6 +2,10 @@
import cpw.mods.fml.common.Side; import cpw.mods.fml.common.Side;
import cpw.mods.fml.common.asm.SideOnly; import cpw.mods.fml.common.asm.SideOnly;
+import cpw.mods.fml.common.registry.GameData;
+import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.common.registry.ItemData; +import cpw.mods.fml.common.registry.ItemData;
+ +
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Canvas; import java.awt.Canvas;
import java.awt.Color; import java.awt.Color;
@@ -15,7 +18,9 @@ @@ -15,7 +19,9 @@
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -20,7 +21,7 @@
import net.minecraft.src.AchievementList; import net.minecraft.src.AchievementList;
import net.minecraft.src.AnvilSaveConverter; import net.minecraft.src.AnvilSaveConverter;
import net.minecraft.src.AxisAlignedBB; import net.minecraft.src.AxisAlignedBB;
@@ -122,6 +127,7 @@ @@ -122,6 +128,7 @@
import net.minecraft.src.WorldInfo; import net.minecraft.src.WorldInfo;
import net.minecraft.src.WorldRenderer; import net.minecraft.src.WorldRenderer;
import net.minecraft.src.WorldSettings; import net.minecraft.src.WorldSettings;
@ -28,7 +29,7 @@
import org.lwjgl.LWJGLException; import org.lwjgl.LWJGLException;
import org.lwjgl.Sys; import org.lwjgl.Sys;
import org.lwjgl.input.Keyboard; import org.lwjgl.input.Keyboard;
@@ -134,6 +140,14 @@ @@ -134,6 +141,14 @@
import org.lwjgl.opengl.GLContext; import org.lwjgl.opengl.GLContext;
import org.lwjgl.opengl.PixelFormat; import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.glu.GLU; import org.lwjgl.util.glu.GLU;
@ -43,7 +44,7 @@
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
public abstract class Minecraft implements Runnable, IPlayerUsage public abstract class Minecraft implements Runnable, IPlayerUsage
@@ -316,7 +330,7 @@ @@ -316,7 +331,7 @@
this.func_71357_I(); this.func_71357_I();
this.field_71466_p = new FontRenderer(this.field_71474_y, "/font/default.png", this.field_71446_o, false); this.field_71466_p = new FontRenderer(this.field_71474_y, "/font/default.png", this.field_71446_o, false);
this.field_71464_q = new FontRenderer(this.field_71474_y, "/font/alternate.png", this.field_71446_o, false); this.field_71464_q = new FontRenderer(this.field_71474_y, "/font/alternate.png", this.field_71446_o, false);
@ -52,7 +53,7 @@
if (this.field_71474_y.field_74363_ab != null) if (this.field_71474_y.field_74363_ab != null)
{ {
StringTranslate.func_74808_a().func_74810_a(this.field_71474_y.field_74363_ab); StringTranslate.func_74808_a().func_74810_a(this.field_71474_y.field_74363_ab);
@@ -361,6 +375,8 @@ @@ -361,6 +376,8 @@
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);
@ -61,7 +62,7 @@
try try
{ {
this.field_71430_V = new ThreadDownloadResources(this.field_71412_D, this); this.field_71430_V = new ThreadDownloadResources(this.field_71412_D, this);
@@ -389,6 +405,7 @@ @@ -389,6 +406,7 @@
{ {
this.func_71352_k(); this.func_71352_k();
} }
@ -69,7 +70,7 @@
} }
private void func_71357_I() throws LWJGLException private void func_71357_I() throws LWJGLException
@@ -747,9 +764,11 @@ @@ -747,9 +765,11 @@
if (!this.field_71454_w) if (!this.field_71454_w)
{ {
@ -81,7 +82,7 @@
} }
GL11.glFlush(); GL11.glFlush();
@@ -1279,11 +1298,13 @@ @@ -1279,11 +1299,13 @@
public void func_71407_l() public void func_71407_l()
{ {
@ -95,7 +96,7 @@
this.field_71424_I.func_76320_a("stats"); this.field_71424_I.func_76320_a("stats");
this.field_71413_E.func_77449_e(); this.field_71413_E.func_77449_e();
this.field_71424_I.func_76318_c("gui"); this.field_71424_I.func_76318_c("gui");
@@ -1739,6 +1760,7 @@ @@ -1739,6 +1761,7 @@
this.field_71453_ak.func_74428_b(); this.field_71453_ak.func_74428_b();
} }
@ -103,21 +104,21 @@
this.field_71424_I.func_76319_b(); this.field_71424_I.func_76319_b();
this.field_71423_H = func_71386_F(); this.field_71423_H = func_71386_F();
} }
@@ -1777,8 +1799,23 @@ @@ -1777,8 +1800,23 @@
} }
this.field_71413_E.func_77450_a(StatList.field_75936_f, 1); this.field_71413_E.func_77450_a(StatList.field_75936_f, 1);
+ GameRegistry.initializeServerGate(2); + GameData.initializeServerGate(2);
this.field_71437_Z = new IntegratedServer(this, p_71371_1_, p_71371_2_, p_71371_3_); this.field_71437_Z = new IntegratedServer(this, p_71371_1_, p_71371_2_, p_71371_3_);
this.field_71437_Z.func_71256_s(); this.field_71437_Z.func_71256_s();
+ MapDifference<Integer, ItemData> idDifferences = GameRegistry.gateWorldLoadingForValidation(); + MapDifference<Integer, ItemData> idDifferences = GameData.gateWorldLoadingForValidation();
+ if (idDifferences!=null) + if (idDifferences!=null)
+ { + {
+ FMLClientHandler.instance().warnIDMismatch(idDifferences, true); + FMLClientHandler.instance().warnIDMismatch(idDifferences, true);
+ } + }
+ else + else
+ { + {
+ GameRegistry.releaseGate(true); + GameData.releaseGate(true);
+ continueWorldLoading(); + continueWorldLoading();
+ } + }
+ +
@ -127,7 +128,7 @@
this.field_71455_al = true; this.field_71455_al = true;
this.field_71461_s.func_73720_a(StatCollector.func_74838_a("menu.loadingLevel")); this.field_71461_s.func_73720_a(StatCollector.func_74838_a("menu.loadingLevel"));
@@ -1993,6 +2030,12 @@ @@ -1993,6 +2031,12 @@
public static void main(String[] p_main_0_) public static void main(String[] p_main_0_)
{ {