From 2362fdb9d5d4626c08dc7845565f7cdd5efe158b Mon Sep 17 00:00:00 2001 From: Christian Date: Thu, 26 Dec 2013 12:41:49 -0500 Subject: [PATCH] Fix handling world reloads when new stuffs are added --- .../cpw/mods/fml/client/FMLClientHandler.java | 14 ++++--- .../cpw/mods/fml/common/FMLContainer.java | 1 + .../FMLControlledNamespacedRegistry.java | 40 +++++++++++++++++-- .../mods/fml/common/registry/GameData.java | 8 +++- 4 files changed, 52 insertions(+), 11 deletions(-) diff --git a/fml/src/main/java/cpw/mods/fml/client/FMLClientHandler.java b/fml/src/main/java/cpw/mods/fml/client/FMLClientHandler.java index d23a3bde4..4da09ce66 100644 --- a/fml/src/main/java/cpw/mods/fml/client/FMLClientHandler.java +++ b/fml/src/main/java/cpw/mods/fml/client/FMLClientHandler.java @@ -17,9 +17,7 @@ import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import org.apache.logging.log4j.Level; import java.util.logging.Logger; - import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityClientPlayerMP; import net.minecraft.client.gui.GuiScreen; @@ -34,12 +32,11 @@ import net.minecraft.entity.player.EntityPlayer; import net.minecraft.launchwrapper.Launch; import net.minecraft.network.NetworkManager; import net.minecraft.server.MinecraftServer; - +import org.apache.logging.log4j.Level; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; - import cpw.mods.fml.client.registry.RenderingRegistry; import cpw.mods.fml.common.DummyModContainer; import cpw.mods.fml.common.DuplicateModsFoundException; @@ -490,8 +487,13 @@ public class FMLClientHandler implements IFMLSidedHandler return this.client.func_147114_u()!=null ? this.client.func_147114_u().func_147298_b() : null; } - public void handleClientWorldClosing(WorldClient field_71441_e) + public void handleClientWorldClosing(WorldClient world) { - GameData.revertToFrozen(); + NetworkManager client = getClientToServerNetworkManager(); + // ONLY revert a non-local connection + if (client != null && !client.func_150731_c()) + { + GameData.revertToFrozen(); + } } } diff --git a/fml/src/main/java/cpw/mods/fml/common/FMLContainer.java b/fml/src/main/java/cpw/mods/fml/common/FMLContainer.java index 29e15e574..221a6f45d 100644 --- a/fml/src/main/java/cpw/mods/fml/common/FMLContainer.java +++ b/fml/src/main/java/cpw/mods/fml/common/FMLContainer.java @@ -96,6 +96,7 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai } fmlData.func_74782_a("ModList", list); NBTTagList dataList = new NBTTagList(); + FMLLog.fine("Gathering id map for writing to world save %s", info.func_76065_j()); Map itemList = GameData.buildItemDataList(); for (Entry item : itemList.entrySet()) { diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java index 83a38b578..8b8d7fb13 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java @@ -13,6 +13,7 @@ import com.google.common.collect.HashBiMap; 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.Loader; import cpw.mods.fml.common.ModContainer; @@ -104,6 +105,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { private BiMap namedIds = HashBiMap.create(); private BiMap frozenIds; private Map transactionalNamedIds; + private BitSet transactionalAvailabilityMap; private BitSet availabilityMap; private int maxId; private int minId; @@ -123,13 +125,32 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { @Override public void func_148756_a(int id, String name, Object thing) { + FMLLog.info("Add : %s %d %s", name, id, thing); add(id, name, superType.cast(thing)); } int swap(int id, String name, I thing) { - field_82596_a.remove(name); - return add(id, name, thing); + FMLLog.info("Swap : %s %d %s", name, id, thing); + BitSet temporary = availabilityMap; + availabilityMap = transactionalAvailabilityMap; + + int idToUse = id; + if (id == 0 || availabilityMap.get(id)) + { + idToUse = availabilityMap.nextClearBit(minId); + } + if (idToUse >= maxId) + { + throw new RuntimeException(String.format("Invalid id %s - not accepted",id)); + } + + namedIds.forcePut(func_148755_c(name),idToUse); + reassignMapping(name, idToUse); + useSlot(idToUse); + availabilityMap = temporary; + FMLLog.info("Swap : %s %d %s", name, idToUse, thing); + return idToUse; } public int add(int id, String name, I thing) { @@ -154,9 +175,10 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { String prefix = mc.getModId(); name = prefix + ":"+ name; } - namedIds.put(func_148755_c(name),idToUse); + namedIds.forcePut(func_148755_c(name),idToUse); super.func_148756_a(idToUse, name, thing); useSlot(idToUse); + FMLLog.info("Add : %s %d %s", name, idToUse, thing); return idToUse; } @@ -190,6 +212,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { idMap().beginSwap(); transactionalNamedIds = Maps.newHashMap(); + transactionalAvailabilityMap = new BitSet(); } void reassignMapping(String name, int newId) @@ -197,6 +220,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { Object item = nameMap().get(name); idMap().putNew(newId, item); transactionalNamedIds.put(name,newId); + transactionalAvailabilityMap.set(newId); } void freezeMap() @@ -282,4 +306,14 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { return namedIds.containsKey(itemName); } + + void dump() + { + for (Entry entry : namedIds.entrySet()) + { + String name = entry.getKey(); + Object thing = idMap().get(entry.getValue().intValue()); + FMLLog.info("Registry : %s %d %s", name, entry.getValue(), thing); + } + } } diff --git a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java index f25b80518..eb2be1412 100644 --- a/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java +++ b/fml/src/main/java/cpw/mods/fml/common/registry/GameData.java @@ -218,6 +218,8 @@ public class GameData { { Map remaps = Maps.newHashMap(); ArrayListMultimap missing = ArrayListMultimap.create(); + blockRegistry.dump(); + itemRegistry.dump(); blockRegistry.beginIdSwap(); itemRegistry.beginIdSwap(); for (Entry entry : dataList.entrySet()) @@ -267,7 +269,7 @@ public class GameData { if (injectFrozenData) { - FMLLog.info("Injecting new block and item data from this server instance"); + FMLLog.info("Injecting new block and item data into this server instance"); Map missingBlocks = Maps.newHashMap(blockRegistry.getMissingMappings()); Map missingItems = Maps.newHashMap(itemRegistry.getMissingMappings()); @@ -276,9 +278,9 @@ public class GameData { String itemName = item.getKey(); if (missingBlocks.containsKey(itemName)) { - FMLLog.info("Injecting new block/item %s", itemName); int blockId = blockRegistry.swap(item.getValue(), itemName, blockRegistry.get(itemName)); itemRegistry.swap(blockId, itemName, itemRegistry.get(itemName)); + FMLLog.info("Injecting new block/item %s : %d", itemName, blockId); missingBlocks.remove(itemName); if (Integer.valueOf(blockId) != item.getValue()) { @@ -307,6 +309,8 @@ public class GameData { } blockRegistry.completeIdSwap(); itemRegistry.completeIdSwap(); + blockRegistry.dump(); + itemRegistry.dump(); Loader.instance().fireRemapEvent(remaps); return true; }