Fix handling world reloads when new stuffs are added

This commit is contained in:
Christian 2013-12-26 12:41:49 -05:00
parent f4fc6377b3
commit 2362fdb9d5
4 changed files with 52 additions and 11 deletions

View File

@ -17,9 +17,7 @@ import java.util.Arrays;
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 org.apache.logging.log4j.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
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.GuiScreen; import net.minecraft.client.gui.GuiScreen;
@ -34,12 +32,11 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.launchwrapper.Launch; import net.minecraft.launchwrapper.Launch;
import net.minecraft.network.NetworkManager; import net.minecraft.network.NetworkManager;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.Level;
import com.google.common.base.Throwables; import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
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;
@ -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; 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();
}
} }
} }

View File

@ -96,6 +96,7 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
} }
fmlData.func_74782_a("ModList", list); fmlData.func_74782_a("ModList", list);
NBTTagList dataList = new NBTTagList(); NBTTagList dataList = new NBTTagList();
FMLLog.fine("Gathering id map for writing to world save %s", info.func_76065_j());
Map<String,Integer> itemList = GameData.buildItemDataList(); Map<String,Integer> itemList = GameData.buildItemDataList();
for (Entry<String, Integer> item : itemList.entrySet()) for (Entry<String, Integer> item : itemList.entrySet())
{ {

View File

@ -13,6 +13,7 @@ import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableBiMap; import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
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;
@ -104,6 +105,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
private BiMap<String,Integer> namedIds = HashBiMap.create(); private BiMap<String,Integer> namedIds = HashBiMap.create();
private BiMap<String,Integer> frozenIds; private BiMap<String,Integer> frozenIds;
private Map<String,Integer> transactionalNamedIds; private Map<String,Integer> transactionalNamedIds;
private BitSet transactionalAvailabilityMap;
private BitSet availabilityMap; private BitSet availabilityMap;
private int maxId; private int maxId;
private int minId; private int minId;
@ -123,13 +125,32 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
@Override @Override
public void func_148756_a(int id, String name, Object thing) 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)); add(id, name, superType.cast(thing));
} }
int swap(int id, String name, I thing) int swap(int id, String name, I thing)
{ {
field_82596_a.remove(name); FMLLog.info("Swap : %s %d %s", name, id, thing);
return add(id, name, 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) public int add(int id, String name, I thing)
{ {
@ -154,9 +175,10 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
String prefix = mc.getModId(); String prefix = mc.getModId();
name = prefix + ":"+ name; name = prefix + ":"+ name;
} }
namedIds.put(func_148755_c(name),idToUse); namedIds.forcePut(func_148755_c(name),idToUse);
super.func_148756_a(idToUse, name, thing); super.func_148756_a(idToUse, name, thing);
useSlot(idToUse); useSlot(idToUse);
FMLLog.info("Add : %s %d %s", name, idToUse, thing);
return idToUse; return idToUse;
} }
@ -190,6 +212,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{ {
idMap().beginSwap(); idMap().beginSwap();
transactionalNamedIds = Maps.newHashMap(); transactionalNamedIds = Maps.newHashMap();
transactionalAvailabilityMap = new BitSet();
} }
void reassignMapping(String name, int newId) void reassignMapping(String name, int newId)
@ -197,6 +220,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
Object item = nameMap().get(name); Object item = nameMap().get(name);
idMap().putNew(newId, item); idMap().putNew(newId, item);
transactionalNamedIds.put(name,newId); transactionalNamedIds.put(name,newId);
transactionalAvailabilityMap.set(newId);
} }
void freezeMap() void freezeMap()
@ -282,4 +306,14 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{ {
return namedIds.containsKey(itemName); return namedIds.containsKey(itemName);
} }
void dump()
{
for (Entry<String, Integer> entry : namedIds.entrySet())
{
String name = entry.getKey();
Object thing = idMap().get(entry.getValue().intValue());
FMLLog.info("Registry : %s %d %s", name, entry.getValue(), thing);
}
}
} }

View File

@ -218,6 +218,8 @@ public class GameData {
{ {
Map<String, Integer[]> remaps = Maps.newHashMap(); Map<String, Integer[]> remaps = Maps.newHashMap();
ArrayListMultimap<String,String> missing = ArrayListMultimap.create(); ArrayListMultimap<String,String> missing = ArrayListMultimap.create();
blockRegistry.dump();
itemRegistry.dump();
blockRegistry.beginIdSwap(); blockRegistry.beginIdSwap();
itemRegistry.beginIdSwap(); itemRegistry.beginIdSwap();
for (Entry<String, Integer> entry : dataList.entrySet()) for (Entry<String, Integer> entry : dataList.entrySet())
@ -267,7 +269,7 @@ public class GameData {
if (injectFrozenData) 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<String, Integer> missingBlocks = Maps.newHashMap(blockRegistry.getMissingMappings()); Map<String, Integer> missingBlocks = Maps.newHashMap(blockRegistry.getMissingMappings());
Map<String, Integer> missingItems = Maps.newHashMap(itemRegistry.getMissingMappings()); Map<String, Integer> missingItems = Maps.newHashMap(itemRegistry.getMissingMappings());
@ -276,9 +278,9 @@ public class GameData {
String itemName = item.getKey(); String itemName = item.getKey();
if (missingBlocks.containsKey(itemName)) if (missingBlocks.containsKey(itemName))
{ {
FMLLog.info("Injecting new block/item %s", itemName);
int blockId = blockRegistry.swap(item.getValue(), itemName, blockRegistry.get(itemName)); int blockId = blockRegistry.swap(item.getValue(), itemName, blockRegistry.get(itemName));
itemRegistry.swap(blockId, itemName, itemRegistry.get(itemName)); itemRegistry.swap(blockId, itemName, itemRegistry.get(itemName));
FMLLog.info("Injecting new block/item %s : %d", itemName, blockId);
missingBlocks.remove(itemName); missingBlocks.remove(itemName);
if (Integer.valueOf(blockId) != item.getValue()) if (Integer.valueOf(blockId) != item.getValue())
{ {
@ -307,6 +309,8 @@ public class GameData {
} }
blockRegistry.completeIdSwap(); blockRegistry.completeIdSwap();
itemRegistry.completeIdSwap(); itemRegistry.completeIdSwap();
blockRegistry.dump();
itemRegistry.dump();
Loader.instance().fireRemapEvent(remaps); Loader.instance().fireRemapEvent(remaps);
return true; return true;
} }