From aee1a3f24d11ba44bf9e1c53c7c1099e42129382 Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 9 Dec 2012 22:24:16 -0500 Subject: [PATCH] Fixing id map generation - should validate correctly now --- .../cpw/mods/fml/client/FMLClientHandler.java | 5 +- .../mods/fml/common/FMLDummyContainer.java | 9 +- .../fml/common/FMLDummyContainer.java.rej | 23 +++ .../fml/common/network/ModIdMapPacket.java | 9 +- .../common/network/ModListResponsePacket.java | 3 +- .../mods/fml/common/registry/GameData.java | 157 ++++++++++++++++++ .../fml/common/registry/GameRegistry.java | 130 --------------- .../cpw/mods/fml/server/FMLServerHandler.java | 3 +- .../common/net/minecraft/src/Item.java.patch | 7 +- .../net/minecraft/client/Minecraft.java.patch | 31 ++-- 10 files changed, 217 insertions(+), 160 deletions(-) create mode 100644 fml/common/cpw/mods/fml/common/FMLDummyContainer.java.rej create mode 100644 fml/common/cpw/mods/fml/common/registry/GameData.java diff --git a/fml/client/cpw/mods/fml/client/FMLClientHandler.java b/fml/client/cpw/mods/fml/client/FMLClientHandler.java index 2225d3ccb..508ae9776 100644 --- a/fml/client/cpw/mods/fml/client/FMLClientHandler.java +++ b/fml/client/cpw/mods/fml/client/FMLClientHandler.java @@ -64,6 +64,7 @@ import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; import cpw.mods.fml.common.network.ModMissingPacket; 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.IEntityAdditionalSpawnData; import cpw.mods.fml.common.registry.IThrowableEntity; @@ -479,13 +480,13 @@ public class FMLClientHandler implements IFMLSidedHandler if (response) { serverShouldBeKilledQuietly = false; - GameRegistry.releaseGate(true); + GameData.releaseGate(true); client.continueWorldLoading(); } else { serverShouldBeKilledQuietly = true; - GameRegistry.releaseGate(false); + GameData.releaseGate(false); // Reset and clear the client state client.func_71403_a((WorldClient)null); client.func_71373_a(null); diff --git a/fml/common/cpw/mods/fml/common/FMLDummyContainer.java b/fml/common/cpw/mods/fml/common/FMLDummyContainer.java index 0aed689c6..88a0857e3 100644 --- a/fml/common/cpw/mods/fml/common/FMLDummyContainer.java +++ b/fml/common/cpw/mods/fml/common/FMLDummyContainer.java @@ -30,6 +30,7 @@ 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; @@ -79,7 +80,7 @@ public class FMLDummyContainer extends DummyModContainer implements WorldAccessC } fmlData.func_74782_a("ModList", list); NBTTagList itemList = new NBTTagList(); - GameRegistry.writeItemData(itemList); + GameData.writeItemData(itemList); fmlData.func_74782_a("ModItemData", itemList); return fmlData; } @@ -110,12 +111,12 @@ public class FMLDummyContainer extends DummyModContainer implements WorldAccessC if (tag.func_74764_b("ModItemData")) { NBTTagList modList = tag.func_74761_m("ModItemData"); - Set worldSaveItems = GameRegistry.buildWorldItemData(modList); - GameRegistry.validateWorldSave(worldSaveItems); + Set worldSaveItems = GameData.buildWorldItemData(modList); + GameData.validateWorldSave(worldSaveItems); } else { - GameRegistry.validateWorldSave(null); + GameData.validateWorldSave(null); } } diff --git a/fml/common/cpw/mods/fml/common/FMLDummyContainer.java.rej b/fml/common/cpw/mods/fml/common/FMLDummyContainer.java.rej new file mode 100644 index 000000000..a2da26985 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/FMLDummyContainer.java.rej @@ -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; + diff --git a/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java b/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java index 566339723..f81cc1f6d 100644 --- a/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java @@ -15,6 +15,7 @@ import com.google.common.primitives.UnsignedBytes; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.common.FMLCommonHandler; 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.ItemData; 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) { byte[] allData = Bytes.concat(partials); - GameRegistry.initializeServerGate(1); + GameData.initializeServerGate(1); try { NBTTagCompound serverList = CompressedStreamTools.func_74792_a(allData); NBTTagList list = serverList.func_74761_m("List"); - Set itemData = GameRegistry.buildWorldItemData(list); - GameRegistry.validateWorldSave(itemData); - MapDifference serverDifference = GameRegistry.gateWorldLoadingForValidation(); + Set itemData = GameData.buildWorldItemData(list); + GameData.validateWorldSave(itemData); + MapDifference serverDifference = GameData.gateWorldLoadingForValidation(); if (serverDifference!=null) { FMLCommonHandler.instance().disconnectIDMismatch(serverDifference, netHandler, network); diff --git a/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java b/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java index 8c5813de9..c11ed4779 100644 --- a/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java @@ -25,6 +25,7 @@ import com.google.common.io.ByteStreams; import cpw.mods.fml.common.FMLLog; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.registry.GameData; import cpw.mods.fml.common.registry.GameRegistry; public class ModListResponsePacket extends FMLPacket @@ -127,7 +128,7 @@ public class ModListResponsePacket extends FMLPacket pkt.field_73628_b = pkt.field_73629_c.length; network.func_74429_a(pkt); NBTTagList itemList = new NBTTagList(); - GameRegistry.writeItemData(itemList); + GameData.writeItemData(itemList); byte[][] registryPackets = FMLPacket.makePacketSet(MOD_IDMAP, itemList); for (int i = 0; i < registryPackets.length; i++) { diff --git a/fml/common/cpw/mods/fml/common/registry/GameData.java b/fml/common/cpw/mods/fml/common/registry/GameData.java new file mode 100644 index 000000000..3ec333a44 --- /dev/null +++ b/fml/common/cpw/mods/fml/common/registry/GameData.java @@ -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 idMap = Maps.newHashMap(); + private static CountDownLatch serverValidationLatch; + private static CountDownLatch clientValidationLatch; + private static MapDifference 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 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 idMapFunction = new Function() { + public Integer apply(ItemData input) { + return input.itemId; + }; + }; + + Map 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 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 buildWorldItemData(NBTTagList modList) + { + Set 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; + } + + + +} diff --git a/fml/common/cpw/mods/fml/common/registry/GameRegistry.java b/fml/common/cpw/mods/fml/common/registry/GameRegistry.java index 620e533b4..2466127bb 100644 --- a/fml/common/cpw/mods/fml/common/registry/GameRegistry.java +++ b/fml/common/cpw/mods/fml/common/registry/GameRegistry.java @@ -52,7 +52,6 @@ import cpw.mods.fml.common.ModContainer; public class GameRegistry { private static Multimap blockRegistry = ArrayListMultimap.create(); - private static Set itemRegistry = Sets.newHashSet(); private static Set worldGenerators = Sets.newHashSet(); private static List fuelHandlers = Lists.newArrayList(); private static List craftingHandlers = Lists.newArrayList(); @@ -302,133 +301,4 @@ public class GameRegistry 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 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 idMapFunction = new Function() { - public Integer apply(ItemData input) { - return input.itemId; - }; - }; - - Map worldMap = Maps.uniqueIndex(worldSaveItems,idMapFunction); - Map 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 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 buildWorldItemData(NBTTagList modList) - { - Set 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 difference; - private static boolean shouldContinue = true; - private static boolean isSaveValid = true; - } diff --git a/fml/common/cpw/mods/fml/server/FMLServerHandler.java b/fml/common/cpw/mods/fml/server/FMLServerHandler.java index 501e6ff3f..06622e69e 100644 --- a/fml/common/cpw/mods/fml/server/FMLServerHandler.java +++ b/fml/common/cpw/mods/fml/server/FMLServerHandler.java @@ -34,6 +34,7 @@ import cpw.mods.fml.common.network.EntitySpawnAdjustmentPacket; import cpw.mods.fml.common.network.EntitySpawnPacket; import cpw.mods.fml.common.network.ModMissingPacket; 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.ItemData; import cpw.mods.fml.common.registry.LanguageRegistry; @@ -93,7 +94,7 @@ public class FMLServerHandler implements IFMLSidedHandler { Loader.instance().initializeMods(); LanguageRegistry.reloadLanguageTable(); - GameRegistry.initializeServerGate(1); + GameData.initializeServerGate(1); } @Override diff --git a/fml/patches/common/net/minecraft/src/Item.java.patch b/fml/patches/common/net/minecraft/src/Item.java.patch index b57a5b1d3..9b6c83690 100644 --- a/fml/patches/common/net/minecraft/src/Item.java.patch +++ b/fml/patches/common/net/minecraft/src/Item.java.patch @@ -1,19 +1,20 @@ --- ../src-base/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.asm.SideOnly; ++import cpw.mods.fml.common.registry.GameData; +import cpw.mods.fml.common.registry.GameRegistry; + import java.util.List; import java.util.Random; -@@ -187,6 +189,7 @@ +@@ -187,6 +190,7 @@ } field_77698_e[256 + p_i3659_1_] = this; -+ GameRegistry.newItemAdded(this); ++ GameData.newItemAdded(this); } public Item func_77665_c(int p_77665_1_) diff --git a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 8a6b8c9ae..bb981e7ea 100644 --- a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -1,16 +1,17 @@ --- ../src-base/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.asm.SideOnly; ++import cpw.mods.fml.common.registry.GameData; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.common.registry.ItemData; + import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; -@@ -15,7 +18,9 @@ +@@ -15,7 +19,9 @@ import java.text.DecimalFormat; import java.util.HashMap; import java.util.List; @@ -20,7 +21,7 @@ import net.minecraft.src.AchievementList; import net.minecraft.src.AnvilSaveConverter; import net.minecraft.src.AxisAlignedBB; -@@ -122,6 +127,7 @@ +@@ -122,6 +128,7 @@ import net.minecraft.src.WorldInfo; import net.minecraft.src.WorldRenderer; import net.minecraft.src.WorldSettings; @@ -28,7 +29,7 @@ import org.lwjgl.LWJGLException; import org.lwjgl.Sys; import org.lwjgl.input.Keyboard; -@@ -134,6 +140,14 @@ +@@ -134,6 +141,14 @@ import org.lwjgl.opengl.GLContext; import org.lwjgl.opengl.PixelFormat; import org.lwjgl.util.glu.GLU; @@ -43,7 +44,7 @@ @SideOnly(Side.CLIENT) public abstract class Minecraft implements Runnable, IPlayerUsage -@@ -316,7 +330,7 @@ +@@ -316,7 +331,7 @@ this.func_71357_I(); 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); @@ -52,7 +53,7 @@ if (this.field_71474_y.field_74363_ab != null) { 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); this.field_71452_i = new EffectRenderer(this.field_71441_e, this.field_71446_o); @@ -61,7 +62,7 @@ try { this.field_71430_V = new ThreadDownloadResources(this.field_71412_D, this); -@@ -389,6 +405,7 @@ +@@ -389,6 +406,7 @@ { this.func_71352_k(); } @@ -69,7 +70,7 @@ } private void func_71357_I() throws LWJGLException -@@ -747,9 +764,11 @@ +@@ -747,9 +765,11 @@ if (!this.field_71454_w) { @@ -81,7 +82,7 @@ } GL11.glFlush(); -@@ -1279,11 +1298,13 @@ +@@ -1279,11 +1299,13 @@ public void func_71407_l() { @@ -95,7 +96,7 @@ this.field_71424_I.func_76320_a("stats"); this.field_71413_E.func_77449_e(); this.field_71424_I.func_76318_c("gui"); -@@ -1739,6 +1760,7 @@ +@@ -1739,6 +1761,7 @@ this.field_71453_ak.func_74428_b(); } @@ -103,21 +104,21 @@ this.field_71424_I.func_76319_b(); 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); -+ 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.func_71256_s(); -+ MapDifference idDifferences = GameRegistry.gateWorldLoadingForValidation(); ++ MapDifference idDifferences = GameData.gateWorldLoadingForValidation(); + if (idDifferences!=null) + { + FMLClientHandler.instance().warnIDMismatch(idDifferences, true); + } + else + { -+ GameRegistry.releaseGate(true); ++ GameData.releaseGate(true); + continueWorldLoading(); + } + @@ -127,7 +128,7 @@ this.field_71455_al = true; 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_) {