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.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();
}
}
}

View File

@ -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<String,Integer> itemList = GameData.buildItemDataList();
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.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<I> extends RegistryNamespaced {
private BiMap<String,Integer> namedIds = HashBiMap.create();
private BiMap<String,Integer> frozenIds;
private Map<String,Integer> transactionalNamedIds;
private BitSet transactionalAvailabilityMap;
private BitSet availabilityMap;
private int maxId;
private int minId;
@ -123,13 +125,32 @@ public class FMLControlledNamespacedRegistry<I> 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<I> 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<I> extends RegistryNamespaced {
{
idMap().beginSwap();
transactionalNamedIds = Maps.newHashMap();
transactionalAvailabilityMap = new BitSet();
}
void reassignMapping(String name, int newId)
@ -197,6 +220,7 @@ public class FMLControlledNamespacedRegistry<I> 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<I> extends RegistryNamespaced {
{
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();
ArrayListMultimap<String,String> missing = ArrayListMultimap.create();
blockRegistry.dump();
itemRegistry.dump();
blockRegistry.beginIdSwap();
itemRegistry.beginIdSwap();
for (Entry<String, Integer> 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<String, Integer> missingBlocks = Maps.newHashMap(blockRegistry.getMissingMappings());
Map<String, Integer> 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;
}