More tweaking on id stuffs at worldload

This commit is contained in:
Christian 2013-12-18 11:15:03 -05:00
parent f6f746ceca
commit 8b621292e3
6 changed files with 82 additions and 14 deletions

View file

@ -146,7 +146,11 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
NBTTagCompound dataTag = list.func_150305_b(i); NBTTagCompound dataTag = list.func_150305_b(i);
dataList.put(dataTag.func_74779_i("K"), dataTag.func_74762_e("V")); dataList.put(dataTag.func_74779_i("K"), dataTag.func_74762_e("V"));
} }
GameData.injectWorldIDMap(dataList); boolean successfullyInjected = GameData.injectWorldIDMap(dataList);
if (!successfullyInjected)
{
throw new RuntimeException("Failed to load the world - there are fatal block and item id issues");
}
} }
} }

View file

@ -842,7 +842,7 @@ public class Loader
return true; return true;
} }
public void fireMissingMappingEvent(ArrayListMultimap<String,String> missing) public boolean fireMissingMappingEvent(ArrayListMultimap<String,String> missing)
{ {
if (!missing.isEmpty()) if (!missing.isEmpty())
{ {
@ -861,8 +861,9 @@ public class Loader
FMLLog.severe("There are unidentified mappings in this world - it cannot be loaded"); FMLLog.severe("There are unidentified mappings in this world - it cannot be loaded");
throw new RuntimeException("Mod IDs are missing"); throw new RuntimeException("Mod IDs are missing");
} }
GameData.processIdRematches(remaps); return GameData.processIdRematches(remaps);
} }
return true;
} }
public void fireRemapEvent(Map<String, Integer[]> remaps) public void fireRemapEvent(Map<String, Integer[]> remaps)
{ {

View file

@ -17,26 +17,38 @@ import cpw.mods.fml.common.ModContainer;
*/ */
public class FMLMissingMappingsEvent extends FMLEvent { public class FMLMissingMappingsEvent extends FMLEvent {
public static enum Type { BLOCK, ITEM } public static enum Type { BLOCK, ITEM }
/**
* Actions you can take with this missing mapping.
* <ul>
* <li>{@link #IGNORE} means this missing mapping will be ignored.
* <li>{@link #WARN} means this missing mapping will generate a warning.
* </ul>
* @author cpw
*
*/
public static enum Action { IGNORE, WARN }
public static class MissingMapping { public static class MissingMapping {
public final Type type; public final Type type;
public final String name; public final String name;
private String remapTarget; private Action action;
private List<MissingMapping> remaps; private List<MissingMapping> remaps;
public MissingMapping(String name, List<MissingMapping> remaps) public MissingMapping(String name, List<MissingMapping> remaps)
{ {
this.type = name.charAt(0) == '\u0001' ? Type.BLOCK : Type.ITEM; this.type = name.charAt(0) == '\u0001' ? Type.BLOCK : Type.ITEM;
this.name = name; this.name = name;
this.remaps = remaps; this.remaps = remaps;
this.action = Action.WARN;
} }
public void remapTo(String target) public void setAction(Action target)
{ {
this.remapTarget = target; this.action = target;
remaps.add(this); remaps.add(this);
} }
public String getRemapTarget() public Action getAction()
{ {
return this.remapTarget; return this.action;
} }
} }
private ListMultimap<String,MissingMapping> missing; private ListMultimap<String,MissingMapping> missing;

View file

@ -74,7 +74,12 @@ enum FMLHandshakeClientState implements IHandshakeState<FMLHandshakeClientState>
public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg) public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
{ {
FMLHandshakeMessage.ModIdData modIds = (FMLHandshakeMessage.ModIdData)msg; FMLHandshakeMessage.ModIdData modIds = (FMLHandshakeMessage.ModIdData)msg;
GameData.injectWorldIDMap(modIds.dataList()); if (!GameData.injectWorldIDMap(modIds.dataList()))
{
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.rejectHandshake("Fatally missing blocks and items");
return ERROR;
}
ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck()); ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck());
return COMPLETE; return COMPLETE;
} }

View file

@ -62,6 +62,14 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
oldMap = newMap = null; oldMap = newMap = null;
} }
void revertSwap()
{
field_148749_a = oldMap;
field_148748_b = oldIndex;
oldIndex = newIndex = null;
oldMap = newMap = null;
}
void putNew(int id, Object item) void putNew(int id, Object item)
{ {
field_148749_a = newMap; field_148749_a = newMap;
@ -75,6 +83,7 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
{ {
return Ints.asList(field_148749_a.keys()); return Ints.asList(field_148749_a.keys());
} }
} }
private final Class<I> superType; private final Class<I> superType;
@ -181,6 +190,12 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
transactionalNamedIds = null; transactionalNamedIds = null;
} }
void revertSwap()
{
idMap().revertSwap();
transactionalNamedIds = null;
}
public I get(int id) public I get(int id)
{ {
return func_148754_a(id); return func_148754_a(id);

View file

@ -27,8 +27,10 @@ import net.minecraft.item.ItemStack;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.google.common.base.Joiner.MapJoiner; import com.google.common.base.Joiner.MapJoiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.HashBasedTable; import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableListMultimap; import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Table; import com.google.common.collect.Table;
import com.google.common.io.Files; import com.google.common.io.Files;
@ -36,6 +38,7 @@ import com.google.common.io.Files;
import cpw.mods.fml.common.FMLLog; 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;
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
import cpw.mods.fml.common.event.FMLMissingMappingsEvent.MissingMapping; import cpw.mods.fml.common.event.FMLMissingMappingsEvent.MissingMapping;
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier; import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
@ -211,10 +214,10 @@ public class GameData {
} }
} }
public static void injectWorldIDMap(Map<String, Integer> dataList) public static boolean injectWorldIDMap(Map<String, Integer> dataList)
{ {
Map<String, Integer[]> remaps = Maps.newHashMap(); Map<String, Integer[]> remaps = Maps.newHashMap();
Map<String,String> missing = Maps.newHashMap(); ArrayListMultimap<String,String> missing = ArrayListMultimap.create();
blockRegistry.beginIdSwap(); blockRegistry.beginIdSwap();
itemRegistry.beginIdSwap(); itemRegistry.beginIdSwap();
for (Entry<String, Integer> entry : dataList.entrySet()) for (Entry<String, Integer> entry : dataList.entrySet())
@ -254,17 +257,45 @@ public class GameData {
itemRegistry.reassignMapping(itemName, newId); itemRegistry.reassignMapping(itemName, newId);
} }
} }
boolean successfullyLoaded = Loader.instance().fireMissingMappingEvent(missing);
if (!successfullyLoaded)
{
blockRegistry.revertSwap();
itemRegistry.revertSwap();
return false;
}
blockRegistry.completeIdSwap(); blockRegistry.completeIdSwap();
itemRegistry.completeIdSwap(); itemRegistry.completeIdSwap();
Loader.instance().fireRemapEvent(remaps); Loader.instance().fireRemapEvent(remaps);
return true;
} }
public static void processIdRematches(List<MissingMapping> remaps) public static boolean processIdRematches(List<MissingMapping> remaps)
{ {
List<String> ignored = Lists.newArrayList();
List<String> warned = Lists.newArrayList();
for (MissingMapping remap : remaps) for (MissingMapping remap : remaps)
{ {
// what to do here FMLMissingMappingsEvent.Action action = remap.getAction();
remap.getRemapTarget(); if (action == FMLMissingMappingsEvent.Action.IGNORE)
{
ignored.add(remap.name);
} }
else
{
warned.add(remap.name);
}
}
if (!warned.isEmpty())
{
FMLLog.severe("This world contains block and item mappings that may cause world breakage");
return false;
}
else if (!ignored.isEmpty())
{
FMLLog.fine("There were %d missing mappings that have been ignored", ignored.size());
}
return true;
} }
} }