From 3e76dfba34aaba4397fc3fb2bd28e0d1f0abe3e4 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 18 Dec 2013 11:15:03 -0500 Subject: [PATCH] More tweaking on id stuffs at worldload --- .../cpw/mods/fml/common/FMLContainer.java | 6 ++- src/main/java/cpw/mods/fml/common/Loader.java | 5 ++- .../common/event/FMLMissingMappingsEvent.java | 22 +++++++--- .../handshake/FMLHandshakeClientState.java | 7 +++- .../FMLControlledNamespacedRegistry.java | 15 +++++++ .../mods/fml/common/registry/GameData.java | 41 ++++++++++++++++--- 6 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/main/java/cpw/mods/fml/common/FMLContainer.java b/src/main/java/cpw/mods/fml/common/FMLContainer.java index 448b0defec..d39c2f2543 100644 --- a/src/main/java/cpw/mods/fml/common/FMLContainer.java +++ b/src/main/java/cpw/mods/fml/common/FMLContainer.java @@ -146,7 +146,11 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai NBTTagCompound dataTag = list.func_150305_b(i); 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"); + } } } diff --git a/src/main/java/cpw/mods/fml/common/Loader.java b/src/main/java/cpw/mods/fml/common/Loader.java index d92efa0b13..ab208de379 100644 --- a/src/main/java/cpw/mods/fml/common/Loader.java +++ b/src/main/java/cpw/mods/fml/common/Loader.java @@ -842,7 +842,7 @@ public class Loader return true; } - public void fireMissingMappingEvent(ArrayListMultimap missing) + public boolean fireMissingMappingEvent(ArrayListMultimap missing) { if (!missing.isEmpty()) { @@ -861,8 +861,9 @@ public class Loader FMLLog.severe("There are unidentified mappings in this world - it cannot be loaded"); throw new RuntimeException("Mod IDs are missing"); } - GameData.processIdRematches(remaps); + return GameData.processIdRematches(remaps); } + return true; } public void fireRemapEvent(Map remaps) { diff --git a/src/main/java/cpw/mods/fml/common/event/FMLMissingMappingsEvent.java b/src/main/java/cpw/mods/fml/common/event/FMLMissingMappingsEvent.java index 5634c5f3d0..d1bafb9015 100644 --- a/src/main/java/cpw/mods/fml/common/event/FMLMissingMappingsEvent.java +++ b/src/main/java/cpw/mods/fml/common/event/FMLMissingMappingsEvent.java @@ -17,26 +17,38 @@ import cpw.mods.fml.common.ModContainer; */ public class FMLMissingMappingsEvent extends FMLEvent { public static enum Type { BLOCK, ITEM } + + /** + * Actions you can take with this missing mapping. + *
    + *
  • {@link #IGNORE} means this missing mapping will be ignored. + *
  • {@link #WARN} means this missing mapping will generate a warning. + *
+ * @author cpw + * + */ + public static enum Action { IGNORE, WARN } public static class MissingMapping { public final Type type; public final String name; - private String remapTarget; + private Action action; private List remaps; public MissingMapping(String name, List remaps) { this.type = name.charAt(0) == '\u0001' ? Type.BLOCK : Type.ITEM; this.name = name; 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); } - public String getRemapTarget() + public Action getAction() { - return this.remapTarget; + return this.action; } } private ListMultimap missing; diff --git a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java index 8fb571c50c..9079525113 100644 --- a/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java +++ b/src/main/java/cpw/mods/fml/common/network/handshake/FMLHandshakeClientState.java @@ -74,7 +74,12 @@ enum FMLHandshakeClientState implements IHandshakeState public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage 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()); return COMPLETE; } diff --git a/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java b/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java index 51f7c045e1..9a28cf2dd8 100644 --- a/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java +++ b/src/main/java/cpw/mods/fml/common/registry/FMLControlledNamespacedRegistry.java @@ -62,6 +62,14 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { 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) { field_148749_a = newMap; @@ -75,6 +83,7 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { { return Ints.asList(field_148749_a.keys()); } + } private final Class superType; @@ -181,6 +190,12 @@ public class FMLControlledNamespacedRegistry extends RegistryNamespaced { transactionalNamedIds = null; } + void revertSwap() + { + idMap().revertSwap(); + transactionalNamedIds = null; + } + public I get(int id) { return func_148754_a(id); diff --git a/src/main/java/cpw/mods/fml/common/registry/GameData.java b/src/main/java/cpw/mods/fml/common/registry/GameData.java index a3d5ef90e8..4d63bea631 100644 --- a/src/main/java/cpw/mods/fml/common/registry/GameData.java +++ b/src/main/java/cpw/mods/fml/common/registry/GameData.java @@ -27,8 +27,10 @@ import net.minecraft.item.ItemStack; import com.google.common.base.Charsets; import com.google.common.base.Joiner; import com.google.common.base.Joiner.MapJoiner; +import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableListMultimap; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Table; 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.Loader; 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.registry.GameRegistry.UniqueIdentifier; @@ -211,10 +214,10 @@ public class GameData { } } - public static void injectWorldIDMap(Map dataList) + public static boolean injectWorldIDMap(Map dataList) { Map remaps = Maps.newHashMap(); - Map missing = Maps.newHashMap(); + ArrayListMultimap missing = ArrayListMultimap.create(); blockRegistry.beginIdSwap(); itemRegistry.beginIdSwap(); for (Entry entry : dataList.entrySet()) @@ -254,17 +257,45 @@ public class GameData { itemRegistry.reassignMapping(itemName, newId); } } + boolean successfullyLoaded = Loader.instance().fireMissingMappingEvent(missing); + if (!successfullyLoaded) + { + blockRegistry.revertSwap(); + itemRegistry.revertSwap(); + return false; + } blockRegistry.completeIdSwap(); itemRegistry.completeIdSwap(); Loader.instance().fireRemapEvent(remaps); + return true; } - public static void processIdRematches(List remaps) + public static boolean processIdRematches(List remaps) { + List ignored = Lists.newArrayList(); + List warned = Lists.newArrayList(); + for (MissingMapping remap : remaps) { - // what to do here - remap.getRemapTarget(); + FMLMissingMappingsEvent.Action action = remap.getAction(); + 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; } }