From 1c5b8ecb7b77f1c5a20ffb820942d4a84a000611 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/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 +- .../net/minecraft/client/Minecraft.java.patch | 7 +- .../net/minecraft/item/Item.java.patch | 3 +- 9 files changed, 180 insertions(+), 146 deletions(-) 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 5b747a3b5..08d29c522 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 5ae51ebf5..bc66730ec 100644 --- a/fml/common/cpw/mods/fml/common/FMLDummyContainer.java +++ b/fml/common/cpw/mods/fml/common/FMLDummyContainer.java @@ -27,6 +27,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; @@ -76,7 +77,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; } @@ -107,12 +108,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/network/ModIdMapPacket.java b/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java index 04f0ac8d7..ce433942d 100644 --- a/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModIdMapPacket.java @@ -19,6 +19,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 static cpw.mods.fml.common.network.FMLPacket.Type.MOD_IDMAP; @@ -75,14 +76,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 a81bb5d17..d28a63bbd 100644 --- a/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java +++ b/fml/common/cpw/mods/fml/common/network/ModListResponsePacket.java @@ -23,6 +23,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 @@ -125,7 +126,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 2d2846aac..c34f42b5e 100644 --- a/fml/common/cpw/mods/fml/common/registry/GameRegistry.java +++ b/fml/common/cpw/mods/fml/common/registry/GameRegistry.java @@ -51,7 +51,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(); @@ -301,133 +300,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 bbe156174..c4a2ca88f 100644 --- a/fml/common/cpw/mods/fml/server/FMLServerHandler.java +++ b/fml/common/cpw/mods/fml/server/FMLServerHandler.java @@ -33,6 +33,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; @@ -92,7 +93,7 @@ public class FMLServerHandler implements IFMLSidedHandler { Loader.instance().initializeMods(); LanguageRegistry.reloadLanguageTable(); - GameRegistry.initializeServerGate(1); + GameData.initializeServerGate(1); } @Override diff --git a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 21898e7e7..7863158e0 100644 --- a/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/fml/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -7,6 +7,7 @@ +import cpw.mods.fml.common.FMLCommonHandler; 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 cpw.mods.fml.relauncher.ArgsWrapper; @@ -92,19 +93,19 @@ 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(); + } + diff --git a/fml/patches/minecraft/net/minecraft/item/Item.java.patch b/fml/patches/minecraft/net/minecraft/item/Item.java.patch index b09be1a93..bfd4a7056 100644 --- a/fml/patches/minecraft/net/minecraft/item/Item.java.patch +++ b/fml/patches/minecraft/net/minecraft/item/Item.java.patch @@ -4,6 +4,7 @@ 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; @@ -14,7 +15,7 @@ field_77698_e[256 + p_i3659_1_] = this; + -+ GameRegistry.newItemAdded(this); ++ GameData.newItemAdded(this); } public Item func_77665_c(int p_77665_1_)