Restructure block and item mapping data in world save and network to potentially expand to custom mod ID registry syncing. Tip: ONLY use those functions in GameData that are marked as public API as internal API may change in 1.8.
This commit is contained in:
parent
27ea6bb6fa
commit
10d3062fc6
|
@ -38,7 +38,7 @@ minecraft {
|
|||
installerVersion = "1.4"
|
||||
}
|
||||
|
||||
group = 'net.minecraftforge.fml'
|
||||
group = 'net.minecraftforge'
|
||||
version = getVersionFromGit(getProject())
|
||||
|
||||
jenkins {
|
||||
|
|
|
@ -126,10 +126,8 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
|
||||
private DummyModContainer optifineContainer;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private boolean guiLoaded;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private boolean serverIsRunning;
|
||||
|
||||
private MissingModsException modsMissing;
|
||||
|
@ -148,7 +146,6 @@ public class FMLClientHandler implements IFMLSidedHandler
|
|||
|
||||
private List<IResourcePack> resourcePackList;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private IReloadableResourceManager resourceManager;
|
||||
|
||||
private Map<String, IResourcePack> resourcePackMap;
|
||||
|
|
|
@ -168,7 +168,6 @@ public class GuiModList extends GuiScreen
|
|||
}
|
||||
else
|
||||
{
|
||||
@SuppressWarnings("resource")
|
||||
InputStream logoResource = getClass().getResourceAsStream(logoFile);
|
||||
if (logoResource != null)
|
||||
{
|
||||
|
|
|
@ -24,6 +24,7 @@ import java.util.Set;
|
|||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagIntArray;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
@ -92,66 +93,63 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
|||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
|
||||
{
|
||||
NBTTagCompound fmlData = new NBTTagCompound();
|
||||
NBTTagList list = new NBTTagList();
|
||||
NBTTagList modList = new NBTTagList();
|
||||
for (ModContainer mc : Loader.instance().getActiveModList())
|
||||
{
|
||||
NBTTagCompound mod = new NBTTagCompound();
|
||||
mod.setString("ModId", mc.getModId());
|
||||
mod.setString("ModVersion", mc.getVersion());
|
||||
list.appendTag(mod);
|
||||
modList.appendTag(mod);
|
||||
}
|
||||
fmlData.setTag("ModList", list);
|
||||
// name <-> id mappings
|
||||
NBTTagList dataList = new NBTTagList();
|
||||
FMLLog.fine("Gathering id map for writing to world save %s", info.getWorldName());
|
||||
GameData.GameDataSnapshot dataSnapshot = GameData.buildItemDataList();
|
||||
for (Entry<String, Integer> item : dataSnapshot.idMap.entrySet())
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K",item.getKey());
|
||||
tag.setInteger("V",item.getValue());
|
||||
dataList.appendTag(tag);
|
||||
}
|
||||
fmlData.setTag("ItemData", dataList);
|
||||
// blocked ids
|
||||
fmlData.setIntArray("BlockedItemIds", GameData.getBlockedIds());
|
||||
// block aliases
|
||||
NBTTagList blockAliasList = new NBTTagList();
|
||||
for (Entry<String, String> entry : GameData.getBlockRegistry().getAliases().entrySet())
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", entry.getKey());
|
||||
tag.setString("V", entry.getValue());
|
||||
blockAliasList.appendTag(tag);
|
||||
}
|
||||
fmlData.setTag("BlockAliases", blockAliasList);
|
||||
NBTTagList blockSubstitutionsList = new NBTTagList();
|
||||
for (String entry : dataSnapshot.blockSubstitutions)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", entry);
|
||||
blockSubstitutionsList.appendTag(tag);
|
||||
}
|
||||
fmlData.setTag("BlockSubstitutions", blockSubstitutionsList);
|
||||
// item aliases
|
||||
NBTTagList itemAliasList = new NBTTagList();
|
||||
for (Entry<String, String> entry : GameData.getItemRegistry().getAliases().entrySet())
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", entry.getKey());
|
||||
tag.setString("V", entry.getValue());
|
||||
itemAliasList.appendTag(tag);
|
||||
}
|
||||
fmlData.setTag("ItemAliases", itemAliasList);
|
||||
fmlData.setTag("ModList", modList);
|
||||
|
||||
NBTTagList itemSubstitutionsList = new NBTTagList();
|
||||
for (String entry : dataSnapshot.itemSubstitutions)
|
||||
NBTTagCompound registries = new NBTTagCompound();
|
||||
fmlData.setTag("Registries", registries);
|
||||
FMLLog.fine("Gathering id map for writing to world save %s", info.getWorldName());
|
||||
GameData.GameDataSnapshot dataSnapshot = GameData.takeSnapshot();
|
||||
|
||||
for (Map.Entry<String, GameData.GameDataSnapshot.Entry> e : dataSnapshot.entries.entrySet())
|
||||
{
|
||||
NBTTagCompound data = new NBTTagCompound();
|
||||
registries.setTag(e.getKey(), data);
|
||||
|
||||
NBTTagList ids = new NBTTagList();
|
||||
for (Entry<String, Integer> item : e.getValue().ids.entrySet())
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", item.getKey());
|
||||
tag.setInteger("V", item.getValue());
|
||||
ids.appendTag(tag);
|
||||
}
|
||||
data.setTag("ids", ids);
|
||||
|
||||
NBTTagList aliases = new NBTTagList();
|
||||
for (Entry<String, String> entry : e.getValue().aliases.entrySet())
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", entry.getKey());
|
||||
tag.setString("V", entry.getValue());
|
||||
aliases.appendTag(tag);
|
||||
}
|
||||
data.setTag("aliases", aliases);
|
||||
|
||||
NBTTagList subs = new NBTTagList();
|
||||
for (String entry : e.getValue().substitutions)
|
||||
{
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
tag.setString("K", entry);
|
||||
itemSubstitutionsList.appendTag(tag);
|
||||
subs.appendTag(tag);
|
||||
}
|
||||
data.setTag("substitutions", subs);
|
||||
|
||||
int[] blocked = new int[e.getValue().blocked.size()];
|
||||
int idx = 0;
|
||||
for (Integer i : e.getValue().blocked)
|
||||
{
|
||||
blocked[idx++] = i;
|
||||
}
|
||||
data.setIntArray("blocked", blocked);
|
||||
}
|
||||
fmlData.setTag("ItemSubstitutions", itemSubstitutionsList);
|
||||
return fmlData;
|
||||
}
|
||||
|
||||
|
@ -181,97 +179,143 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
|||
|
||||
List<String> failedElements = null;
|
||||
|
||||
if (tag.hasKey("ModItemData"))
|
||||
if (tag.hasKey("ModItemData")) // Pre 1.7
|
||||
{
|
||||
GameData.GameDataSnapshot snapshot = new GameData.GameDataSnapshot();
|
||||
GameData.GameDataSnapshot.Entry items = new GameData.GameDataSnapshot.Entry();
|
||||
snapshot.entries.put("fml:blocks", new GameData.GameDataSnapshot.Entry());
|
||||
snapshot.entries.put("fml:items", items);
|
||||
|
||||
FMLLog.info("Attempting to convert old world data to new system. This may be trouble!");
|
||||
NBTTagList modList = tag.getTagList("ModItemData", (byte)10);
|
||||
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
||||
for (int i = 0; i < modList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound itemTag = modList.getCompoundTagAt(i);
|
||||
String modId = itemTag.getString("ModId");
|
||||
String itemType = itemTag.getString("ItemType");
|
||||
int itemId = itemTag.getInteger("ItemId");
|
||||
int ordinal = itemTag.getInteger("ordinal");
|
||||
String forcedModId = itemTag.hasKey("ForcedModId") ? itemTag.getString("ForcedModId") : null;
|
||||
String forcedName = itemTag.hasKey("ForcedName") ? itemTag.getString("ForcedName") : null;
|
||||
NBTTagCompound data = modList.getCompoundTagAt(i);
|
||||
String forcedModId = data.hasKey("ForcedModId") ? data.getString("ForcedModId") : null;
|
||||
String forcedName = data.hasKey("ForcedName") ? data.getString("ForcedName") : null;
|
||||
if (forcedName == null)
|
||||
{
|
||||
FMLLog.warning("Found unlabelled item in world save, this may cause problems. The item type %s:%d will not be present", itemType, ordinal);
|
||||
FMLLog.warning("Found unlabelled item in world save, this may cause problems. The item type %s:%d will not be present", data.getString("ItemType"), data.getInteger("ordinal"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// all entries are Items, blocks were only saved through their ItemBlock
|
||||
String itemLabel = String.format("%c%s:%s", '\u0002', forcedModId != null ? forcedModId : modId, forcedName);
|
||||
dataList.put(itemLabel, itemId);
|
||||
String itemLabel = String.format("%s:%s", forcedModId != null ? forcedModId : data.getString("ModId"), forcedName);
|
||||
items.ids.put(itemLabel, data.getInteger("ItemId"));
|
||||
}
|
||||
}
|
||||
failedElements = GameData.injectWorldIDMap(dataList, ImmutableSet.<String>of(), ImmutableSet.<String>of(), true, true);
|
||||
failedElements = GameData.injectSnapshot(snapshot, true, true);
|
||||
|
||||
}
|
||||
else if (tag.hasKey("ItemData"))
|
||||
else if (tag.hasKey("ItemData")) // 1.7
|
||||
{
|
||||
// name <-> id mappings
|
||||
GameData.GameDataSnapshot snapshot = new GameData.GameDataSnapshot();
|
||||
GameData.GameDataSnapshot.Entry blocks = new GameData.GameDataSnapshot.Entry();
|
||||
GameData.GameDataSnapshot.Entry items = new GameData.GameDataSnapshot.Entry();
|
||||
snapshot.entries.put("fml:blocks", blocks);
|
||||
snapshot.entries.put("fml:items", items);
|
||||
|
||||
NBTTagList list = tag.getTagList("ItemData", 10);
|
||||
Map<String,Integer> dataList = Maps.newLinkedHashMap();
|
||||
for (int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||
dataList.put(dataTag.getString("K"), dataTag.getInteger("V"));
|
||||
NBTTagCompound e = list.getCompoundTagAt(i);
|
||||
String name = e.getString("K");
|
||||
|
||||
if (name.charAt(0) == '\u0001')
|
||||
blocks.ids.put(name.substring(1), e.getInteger("V"));
|
||||
else if (name.charAt(0) == '\u0002')
|
||||
items.ids.put(name.substring(1), e.getInteger("V"));
|
||||
}
|
||||
|
||||
Set<Integer> blockedIds = new HashSet<Integer>();
|
||||
|
||||
if (!tag.hasKey("BlockedItemIds")) // no blocked id info -> old 1.7 save
|
||||
{
|
||||
// old early 1.7 save potentially affected by the registry mapping bug
|
||||
// fix the ids the best we can...
|
||||
GameData.fixBrokenIds(dataList, blockedIds);
|
||||
GameData.fixBrokenIds(blocks, items, blockedIds);
|
||||
}
|
||||
|
||||
// blocked ids
|
||||
else
|
||||
{
|
||||
for (int id : tag.getIntArray("BlockedItemIds"))
|
||||
{
|
||||
blockedIds.add(id);
|
||||
}
|
||||
// block aliases
|
||||
Map<String, String> blockAliases = new HashMap<String, String>();
|
||||
}
|
||||
blocks.blocked.addAll(blockedIds);
|
||||
items.blocked.addAll(blockedIds);
|
||||
|
||||
list = tag.getTagList("BlockAliases", 10);
|
||||
for (int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||
blockAliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||
blocks.aliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||
}
|
||||
Set<String> blockSubstitutions = Sets.newHashSet();
|
||||
|
||||
if (tag.hasKey("BlockSubstitutions", 9))
|
||||
{
|
||||
list = tag.getTagList("BlockSubstitutions", 10);
|
||||
for (int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||
blockSubstitutions.add(dataTag.getString("K"));
|
||||
blocks.substitutions.add(dataTag.getString("K"));
|
||||
}
|
||||
}
|
||||
// item aliases
|
||||
Map<String, String> itemAliases = new HashMap<String, String>();
|
||||
|
||||
list = tag.getTagList("ItemAliases", 10);
|
||||
for (int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||
itemAliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||
items.aliases.put(dataTag.getString("K"), dataTag.getString("V"));
|
||||
}
|
||||
|
||||
Set<String> itemSubstitutions = Sets.newHashSet();
|
||||
if (tag.hasKey("ItemSubstitutions", 9))
|
||||
{
|
||||
list = tag.getTagList("ItemSubstitutions", 10);
|
||||
for (int i = 0; i < list.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataTag = list.getCompoundTagAt(i);
|
||||
itemSubstitutions.add(dataTag.getString("K"));
|
||||
items.substitutions.add(dataTag.getString("K"));
|
||||
}
|
||||
}
|
||||
failedElements = GameData.injectWorldIDMap(dataList, blockedIds, blockAliases, itemAliases, blockSubstitutions, itemSubstitutions, true, true);
|
||||
failedElements = GameData.injectSnapshot(snapshot, true, true);
|
||||
}
|
||||
else if (tag.hasKey("Registries")) // 1.8, genericed out the 'registries' list
|
||||
{
|
||||
GameData.GameDataSnapshot snapshot = new GameData.GameDataSnapshot();
|
||||
NBTTagCompound regs = tag.getCompoundTag("Registries");
|
||||
for (String key : (Set<String>)regs.getKeySet())
|
||||
{
|
||||
GameData.GameDataSnapshot.Entry entry = new GameData.GameDataSnapshot.Entry();
|
||||
snapshot.entries.put(key, entry);
|
||||
|
||||
NBTTagList list = regs.getCompoundTag(key).getTagList("ids", 10);
|
||||
for (int x = 0; x < list.tagCount(); x++)
|
||||
{
|
||||
NBTTagCompound e = list.getCompoundTagAt(x);
|
||||
entry.ids.put(e.getString("K"), e.getInteger("V"));
|
||||
}
|
||||
|
||||
list = regs.getCompoundTag(key).getTagList("aliases", 10);
|
||||
for (int x = 0; x < list.tagCount(); x++)
|
||||
{
|
||||
NBTTagCompound e = list.getCompoundTagAt(x);
|
||||
entry.aliases.put(e.getString("K"), e.getString("V"));
|
||||
}
|
||||
|
||||
list = regs.getCompoundTag(key).getTagList("substitutions", 10);
|
||||
for (int x = 0; x < list.tagCount(); x++)
|
||||
{
|
||||
NBTTagCompound e = list.getCompoundTagAt(x);
|
||||
entry.substitutions.add(e.getString("K"));
|
||||
}
|
||||
|
||||
int[] blocked = regs.getCompoundTag(key).getIntArray("blocked");
|
||||
for (int i : blocked)
|
||||
{
|
||||
entry.blocked.add(i);
|
||||
}
|
||||
}
|
||||
failedElements = GameData.injectSnapshot(snapshot, true, true);
|
||||
}
|
||||
|
||||
if (failedElements != null && !failedElements.isEmpty())
|
||||
|
|
|
@ -695,8 +695,6 @@ public class Loader
|
|||
modController.transition(LoaderState.AVAILABLE, false);
|
||||
modController.distributeStateMessage(LoaderState.AVAILABLE);
|
||||
GameData.freezeData();
|
||||
// Dump the custom registry data map, if necessary
|
||||
GameData.dumpRegistry(minecraftDir);
|
||||
FMLLog.info("Forge Mod Loader has successfully loaded %d mod%s", mods.size(), mods.size() == 1 ? "" : "s");
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package net.minecraftforge.fml.common.network.handshake;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
|
@ -85,8 +86,28 @@ enum FMLHandshakeClientState implements IHandshakeState<FMLHandshakeClientState>
|
|||
@Override
|
||||
public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||
{
|
||||
FMLHandshakeMessage.ModIdData modIds = (FMLHandshakeMessage.ModIdData)msg;
|
||||
List<String> locallyMissing = GameData.injectWorldIDMap(modIds.dataList(), modIds.blockSubstitutions(), modIds.itemSubstitutions(), false, false);
|
||||
FMLHandshakeMessage.RegistryData pkt = (FMLHandshakeMessage.RegistryData)msg;
|
||||
GameData.GameDataSnapshot snap = ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).get();
|
||||
if (snap == null)
|
||||
{
|
||||
snap = new GameData.GameDataSnapshot();
|
||||
ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).set(snap);
|
||||
}
|
||||
|
||||
GameData.GameDataSnapshot.Entry entry = new GameData.GameDataSnapshot.Entry();
|
||||
entry.ids.putAll(pkt.getIdMap());
|
||||
entry.substitutions.addAll(pkt.getSubstitutions());
|
||||
snap.entries.put(pkt.getName(), entry);
|
||||
|
||||
if (pkt.hasMore())
|
||||
{
|
||||
FMLLog.fine("Received Mod Registry mapping for %s: %d IDs %d subs", pkt.getName(), entry.ids.size(), entry.substitutions.size());
|
||||
return WAITINGSERVERCOMPLETE;
|
||||
}
|
||||
|
||||
ctx.channel().attr(NetworkDispatcher.FML_GAMEDATA_SNAPSHOT).remove();
|
||||
|
||||
List<String> locallyMissing = GameData.injectSnapshot(snap, false, false);
|
||||
if (!locallyMissing.isEmpty())
|
||||
{
|
||||
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
|
|
|
@ -10,7 +10,7 @@ public class FMLHandshakeCodec extends FMLIndexedMessageToMessageCodec<FMLHandsh
|
|||
addDiscriminator((byte)0, FMLHandshakeMessage.ServerHello.class);
|
||||
addDiscriminator((byte)1, FMLHandshakeMessage.ClientHello.class);
|
||||
addDiscriminator((byte)2, FMLHandshakeMessage.ModList.class);
|
||||
addDiscriminator((byte)3, FMLHandshakeMessage.ModIdData.class);
|
||||
addDiscriminator((byte)3, FMLHandshakeMessage.RegistryData.class);
|
||||
addDiscriminator((byte)-1, FMLHandshakeMessage.HandshakeAck.class);
|
||||
addDiscriminator((byte)-2, FMLHandshakeMessage.HandshakeReset.class);
|
||||
}
|
||||
|
|
|
@ -125,91 +125,91 @@ public abstract class FMLHandshakeMessage {
|
|||
}
|
||||
}
|
||||
|
||||
public static class ModIdData extends FMLHandshakeMessage {
|
||||
public ModIdData()
|
||||
public static class RegistryData extends FMLHandshakeMessage
|
||||
{
|
||||
public RegistryData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ModIdData(GameData.GameDataSnapshot snapshot)
|
||||
public RegistryData(boolean hasMore, String name, GameData.GameDataSnapshot.Entry entry)
|
||||
{
|
||||
this.modIds = snapshot.idMap;
|
||||
this.blockSubstitutions = snapshot.blockSubstitutions;
|
||||
this.itemSubstitutions = snapshot.itemSubstitutions;
|
||||
this.hasMore = hasMore;
|
||||
this.name = name;
|
||||
this.ids = entry.ids;
|
||||
this.substitutions = entry.substitutions;
|
||||
}
|
||||
|
||||
private Map<String,Integer> modIds;
|
||||
private Set<String> blockSubstitutions;
|
||||
private Set<String> itemSubstitutions;
|
||||
private boolean hasMore;
|
||||
private String name;
|
||||
private Map<String,Integer> ids;
|
||||
private Set<String> substitutions;
|
||||
|
||||
@Override
|
||||
public void fromBytes(ByteBuf buffer)
|
||||
{
|
||||
this.hasMore = buffer.readBoolean();
|
||||
this.name = ByteBufUtils.readUTF8String(buffer);
|
||||
|
||||
int length = ByteBufUtils.readVarInt(buffer, 3);
|
||||
modIds = Maps.newHashMap();
|
||||
blockSubstitutions = Sets.newHashSet();
|
||||
itemSubstitutions = Sets.newHashSet();
|
||||
ids = Maps.newHashMap();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
modIds.put(ByteBufUtils.readUTF8String(buffer),ByteBufUtils.readVarInt(buffer, 3));
|
||||
}
|
||||
// we don't have any more data to read
|
||||
if (!buffer.isReadable())
|
||||
{
|
||||
return;
|
||||
ids.put(ByteBufUtils.readUTF8String(buffer), ByteBufUtils.readVarInt(buffer, 3));
|
||||
}
|
||||
|
||||
length = ByteBufUtils.readVarInt(buffer, 3);
|
||||
substitutions = Sets.newHashSet();
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
blockSubstitutions.add(ByteBufUtils.readUTF8String(buffer));
|
||||
}
|
||||
length = ByteBufUtils.readVarInt(buffer, 3);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
itemSubstitutions.add(ByteBufUtils.readUTF8String(buffer));
|
||||
substitutions.add(ByteBufUtils.readUTF8String(buffer));
|
||||
}
|
||||
//if (!buffer.isReadable()) return; // In case we expand
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBytes(ByteBuf buffer)
|
||||
{
|
||||
ByteBufUtils.writeVarInt(buffer, modIds.size(), 3);
|
||||
for (Entry<String, Integer> entry: modIds.entrySet())
|
||||
buffer.writeBoolean(this.hasMore);
|
||||
ByteBufUtils.writeUTF8String(buffer, this.name);
|
||||
|
||||
ByteBufUtils.writeVarInt(buffer, ids.size(), 3);
|
||||
for (Entry<String, Integer> entry: ids.entrySet())
|
||||
{
|
||||
ByteBufUtils.writeUTF8String(buffer, entry.getKey());
|
||||
ByteBufUtils.writeVarInt(buffer, entry.getValue(), 3);
|
||||
}
|
||||
|
||||
ByteBufUtils.writeVarInt(buffer, blockSubstitutions.size(), 3);
|
||||
for (String entry: blockSubstitutions)
|
||||
{
|
||||
ByteBufUtils.writeUTF8String(buffer, entry);
|
||||
}
|
||||
ByteBufUtils.writeVarInt(buffer, blockSubstitutions.size(), 3);
|
||||
|
||||
for (String entry: itemSubstitutions)
|
||||
ByteBufUtils.writeVarInt(buffer, substitutions.size(), 3);
|
||||
for (String entry: substitutions)
|
||||
{
|
||||
ByteBufUtils.writeUTF8String(buffer, entry);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String,Integer> dataList()
|
||||
public Map<String,Integer> getIdMap()
|
||||
{
|
||||
return modIds;
|
||||
return ids;
|
||||
}
|
||||
public Set<String> blockSubstitutions()
|
||||
public Set<String> getSubstitutions()
|
||||
{
|
||||
return blockSubstitutions;
|
||||
return substitutions;
|
||||
}
|
||||
public Set<String> itemSubstitutions()
|
||||
public String getName()
|
||||
{
|
||||
return itemSubstitutions;
|
||||
return this.name;
|
||||
}
|
||||
public boolean hasMore()
|
||||
{
|
||||
return this.hasMore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(Class<? extends Enum<?>> side)
|
||||
{
|
||||
return super.toString(side) + ":"+modIds.size()+" mappings";
|
||||
return super.toString(side) + ":"+ids.size()+" mappings";
|
||||
}
|
||||
}
|
||||
public static class HandshakeAck extends FMLHandshakeMessage {
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
package net.minecraftforge.fml.common.network.handshake;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
import net.minecraftforge.fml.common.Loader;
|
||||
import net.minecraftforge.fml.common.network.NetworkRegistry;
|
||||
|
@ -56,7 +60,13 @@ enum FMLHandshakeServerState implements IHandshakeState<FMLHandshakeServerState>
|
|||
{
|
||||
if (!ctx.channel().attr(NetworkDispatcher.IS_LOCAL).get())
|
||||
{
|
||||
ctx.writeAndFlush(new FMLHandshakeMessage.ModIdData(GameData.buildItemDataList())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
GameData.GameDataSnapshot snapshot = GameData.takeSnapshot();
|
||||
Iterator<Map.Entry<String, GameData.GameDataSnapshot.Entry>> itr = snapshot.entries.entrySet().iterator();
|
||||
while (itr.hasNext())
|
||||
{
|
||||
Entry<String, GameData.GameDataSnapshot.Entry> e = itr.next();
|
||||
ctx.writeAndFlush(new FMLHandshakeMessage.RegistryData(itr.hasNext(), e.getKey(), e.getValue())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
}
|
||||
}
|
||||
ctx.writeAndFlush(new FMLHandshakeMessage.HandshakeAck(ordinal())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
|
||||
NetworkRegistry.INSTANCE.fireNetworkHandshake(ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(), Side.SERVER);
|
||||
|
|
|
@ -41,6 +41,7 @@ import net.minecraftforge.fml.common.network.PacketLoggingHandler;
|
|||
import net.minecraftforge.fml.common.network.internal.FMLMessage;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLNetworkHandler;
|
||||
import net.minecraftforge.fml.common.network.internal.FMLProxyPacket;
|
||||
import net.minecraftforge.fml.common.registry.GameData;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> implements ChannelOutboundHandler {
|
||||
|
@ -74,6 +75,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
|
|||
|
||||
public static final AttributeKey<NetworkDispatcher> FML_DISPATCHER = AttributeKey.valueOf("fml:dispatcher");
|
||||
public static final AttributeKey<Boolean> IS_LOCAL = AttributeKey.valueOf("fml:isLocal");
|
||||
public static final AttributeKey<GameData.GameDataSnapshot> FML_GAMEDATA_SNAPSHOT = AttributeKey.valueOf("fml:gameDataSnapshot");
|
||||
public final NetworkManager manager;
|
||||
private final ServerConfigurationManager scm;
|
||||
private EntityPlayerMP player;
|
||||
|
|
|
@ -29,18 +29,16 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
|
|||
private I optionalDefaultObject;
|
||||
private int maxId;
|
||||
private int minId;
|
||||
private char discriminator;
|
||||
// aliases redirecting legacy names to the actual name, may need recursive application to find the final name.
|
||||
// these need to be registry specific, it's possible to only have a loosely linked item for a block which may get renamed by itself.
|
||||
private final Map<String, String> aliases = new HashMap<String, String>();
|
||||
private BiMap<String, I> persistentSubstitutions;
|
||||
private BiMap<String, I> activeSubstitutions = HashBiMap.create();
|
||||
|
||||
FMLControlledNamespacedRegistry(Object defaultKey, int maxIdValue, int minIdValue, Class<I> type, char discriminator)
|
||||
FMLControlledNamespacedRegistry(Object defaultKey, int maxIdValue, int minIdValue, Class<I> type)
|
||||
{
|
||||
super(defaultKey);
|
||||
this.superType = type;
|
||||
this.discriminator = discriminator;
|
||||
this.optionalDefaultKey = defaultKey;
|
||||
this.maxId = maxIdValue;
|
||||
this.minId = minIdValue;
|
||||
|
@ -98,7 +96,6 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
|
|||
{
|
||||
if (this.superType != registry.superType) throw new IllegalArgumentException("incompatible registry");
|
||||
|
||||
this.discriminator = registry.discriminator;
|
||||
this.optionalDefaultKey = registry.optionalDefaultKey;
|
||||
this.maxId = registry.maxId;
|
||||
this.minId = registry.minId;
|
||||
|
@ -333,13 +330,16 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
|
|||
{
|
||||
for (I thing : this.typeSafeIterable())
|
||||
{
|
||||
idMapping.put(discriminator+getNameForObject(thing).toString(), getId(thing));
|
||||
idMapping.put(getNameForObject(thing).toString(), getId(thing));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getAliases() // for saving
|
||||
public void serializeAliases(Map<String, String> map)
|
||||
{
|
||||
return ImmutableMap.copyOf(aliases);
|
||||
map.putAll(this.aliases);
|
||||
}
|
||||
public void serializeSubstitutions(Set<String> set)
|
||||
{
|
||||
set.addAll(activeSubstitutions.keySet());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -504,11 +504,6 @@ public class FMLControlledNamespacedRegistry<I> extends RegistryNamespacedDefaul
|
|||
getPersistentSubstitutions().put(nameToReplace, replacement);
|
||||
}
|
||||
|
||||
public void serializeSubstitutions(Set<String> blockSubs)
|
||||
{
|
||||
blockSubs.addAll(activeSubstitutions.keySet());
|
||||
}
|
||||
|
||||
private BiMap<String, I> getPersistentSubstitutions()
|
||||
{
|
||||
if (persistentSubstitutions == null)
|
||||
|
|
|
@ -14,6 +14,7 @@ package net.minecraftforge.fml.common.registry;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -63,11 +64,6 @@ public class GameData {
|
|||
static final int MAX_ITEM_ID = 31999;
|
||||
|
||||
private static final GameData mainData = new GameData();
|
||||
|
||||
private static final FMLControlledNamespacedRegistry<Block> blockRegistry = getBlockRegistry();
|
||||
private static final FMLControlledNamespacedRegistry<Item> itemRegistry = getItemRegistry();
|
||||
|
||||
private static Table<String, String, ItemStack> customItemStacks = HashBasedTable.create();
|
||||
private static Map<UniqueIdentifier, ModContainer> customOwners = Maps.newHashMap();
|
||||
private static GameData frozen;
|
||||
|
||||
|
@ -91,43 +87,59 @@ public class GameData {
|
|||
return getMain().iItemRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated no replacement planned
|
||||
*/
|
||||
@Deprecated
|
||||
public static ModContainer findModOwner(String string)
|
||||
/***************************************************
|
||||
* INTERNAL CODE FROM HERE ON DO NOT USE!
|
||||
***************************************************/
|
||||
|
||||
public static class GameDataSnapshot
|
||||
{
|
||||
UniqueIdentifier ui = new UniqueIdentifier(string);
|
||||
if (customOwners.containsKey(ui))
|
||||
public static class Entry
|
||||
{
|
||||
return customOwners.get(ui);
|
||||
}
|
||||
return Loader.instance().getIndexedModList().get(ui.modId);
|
||||
public final Map<String, Integer> ids;
|
||||
public final Set<String> substitutions;
|
||||
public final Map<String, String> aliases;
|
||||
public final Set<Integer> blocked;
|
||||
|
||||
public Entry()
|
||||
{
|
||||
this(new HashMap<String, Integer>(), new HashSet<String>(), new HashMap<String, String>(), new HashSet<Integer>());
|
||||
}
|
||||
|
||||
// internal from here
|
||||
public Entry(Map<String, Integer> ids, Set<String> substitions, Map<String, String> aliases, Set<Integer> blocked)
|
||||
{
|
||||
this.ids = ids;
|
||||
this.substitutions = substitions;
|
||||
this.aliases = aliases;
|
||||
this.blocked = blocked;
|
||||
}
|
||||
|
||||
public static class GameDataSnapshot {
|
||||
public final Map<String,Integer> idMap;
|
||||
public final Set<String> blockSubstitutions;
|
||||
public final Set<String> itemSubstitutions;
|
||||
public GameDataSnapshot(Map<String, Integer> idMap, Set<String> blockSubstitutions, Set<String> itemSubstitutions)
|
||||
public Entry(FMLControlledNamespacedRegistry registry)
|
||||
{
|
||||
this.idMap = idMap;
|
||||
this.blockSubstitutions = blockSubstitutions;
|
||||
this.itemSubstitutions = itemSubstitutions;
|
||||
this.ids = Maps.newHashMap();
|
||||
this.substitutions = Sets.newHashSet();
|
||||
this.aliases = Maps.newHashMap();
|
||||
this.blocked = Sets.newHashSet();
|
||||
|
||||
registry.serializeInto(this.ids);
|
||||
registry.serializeSubstitutions(this.substitutions);
|
||||
registry.serializeAliases(this.aliases);
|
||||
|
||||
if (GameData.getBlockRegistry() == registry ||
|
||||
GameData.getItemRegistry() == registry)
|
||||
{
|
||||
this.blocked.addAll(GameData.getMain().blockedIds);
|
||||
}
|
||||
}
|
||||
public static GameDataSnapshot buildItemDataList()
|
||||
}
|
||||
public final Map<String, Entry> entries = Maps.newHashMap();
|
||||
}
|
||||
|
||||
public static GameDataSnapshot takeSnapshot()
|
||||
{
|
||||
Map<String,Integer> idMapping = Maps.newHashMap();
|
||||
getMain().iBlockRegistry.serializeInto(idMapping);
|
||||
getMain().iItemRegistry.serializeInto(idMapping);
|
||||
Set<String> blockSubs = Sets.newHashSet();
|
||||
getMain().iBlockRegistry.serializeSubstitutions(blockSubs);
|
||||
Set<String> itemSubs = Sets.newHashSet();
|
||||
getMain().iItemRegistry.serializeSubstitutions(itemSubs);
|
||||
return new GameDataSnapshot(idMapping, blockSubs, itemSubs);
|
||||
GameDataSnapshot snap = new GameDataSnapshot();
|
||||
snap.entries.put("fml:blocks", new GameDataSnapshot.Entry(getMain().getBlockRegistry()));
|
||||
snap.entries.put("fml:items", new GameDataSnapshot.Entry(getMain().getItemRegistry()));
|
||||
return snap;
|
||||
}
|
||||
|
||||
public static int[] getBlockedIds()
|
||||
|
@ -144,34 +156,6 @@ public class GameData {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static void dumpRegistry(File minecraftDir)
|
||||
{
|
||||
if (customItemStacks == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (Boolean.valueOf(System.getProperty("fml.dumpRegistry", "false")).booleanValue())
|
||||
{
|
||||
ImmutableListMultimap.Builder<String, String> builder = ImmutableListMultimap.builder();
|
||||
for (String modId : customItemStacks.rowKeySet())
|
||||
{
|
||||
builder.putAll(modId, customItemStacks.row(modId).keySet());
|
||||
}
|
||||
|
||||
File f = new File(minecraftDir, "itemStackRegistry.csv");
|
||||
MapJoiner mapJoiner = Joiner.on("\n").withKeyValueSeparator(",");
|
||||
try
|
||||
{
|
||||
Files.write(mapJoiner.join(builder.build().entries()), f, Charsets.UTF_8);
|
||||
FMLLog.log(Level.INFO, "Dumped item registry data to %s", f.getAbsolutePath());
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
FMLLog.log(Level.ERROR, e, "Failed to write registry data to %s", f.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Item findItem(String modId, String name)
|
||||
{
|
||||
return (Item) getMain().iItemRegistry.getObject(modId + ":" + name);
|
||||
|
@ -183,57 +167,18 @@ public class GameData {
|
|||
return getMain().iBlockRegistry.containsKey(key) ? getMain().iBlockRegistry.getObject(key) : null;
|
||||
}
|
||||
|
||||
static ItemStack findItemStack(String modId, String name)
|
||||
{
|
||||
ItemStack is = customItemStacks.get(modId, name);
|
||||
if (is == null)
|
||||
{
|
||||
Item i = findItem(modId, name);
|
||||
if (i != null)
|
||||
{
|
||||
is = new ItemStack(i, 0 ,0);
|
||||
}
|
||||
}
|
||||
if (is == null)
|
||||
{
|
||||
Block b = findBlock(modId, name);
|
||||
if (b != null)
|
||||
{
|
||||
is = new ItemStack(b, 0, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
static void registerCustomItemStack(String name, ItemStack itemStack)
|
||||
{
|
||||
customItemStacks.put(Loader.instance().activeModContainer().getModId(), name, itemStack);
|
||||
}
|
||||
|
||||
static UniqueIdentifier getUniqueName(Block block)
|
||||
{
|
||||
if (block == null) return null;
|
||||
Object name = getMain().iBlockRegistry.getNameForObject(block);
|
||||
UniqueIdentifier ui = new UniqueIdentifier(name);
|
||||
if (customItemStacks.contains(ui.modId, ui.name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ui;
|
||||
return new UniqueIdentifier(name);
|
||||
}
|
||||
|
||||
static UniqueIdentifier getUniqueName(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
Object name = getMain().iItemRegistry.getNameForObject(item);
|
||||
UniqueIdentifier ui = new UniqueIdentifier(name);
|
||||
if (customItemStacks.contains(ui.modId, ui.name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ui;
|
||||
return new UniqueIdentifier(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -244,57 +189,46 @@ public class GameData {
|
|||
*
|
||||
* @param dataList List containing the IDs to fix
|
||||
*/
|
||||
public static void fixBrokenIds(Map<String, Integer> dataList, Set<Integer> blockedIds)
|
||||
public static void fixBrokenIds(GameDataSnapshot.Entry blocks, GameDataSnapshot.Entry items, Set<Integer> blockedIds)
|
||||
{
|
||||
BitSet availabilityMap = new BitSet(MAX_ITEM_ID + 1);
|
||||
|
||||
// reserve all ids occupied by blocks
|
||||
for (Entry<String, Integer> entry : dataList.entrySet())
|
||||
{
|
||||
String itemName = entry.getKey();
|
||||
String realName = itemName.substring(1);
|
||||
|
||||
if (itemName.charAt(0) == '\u0001') // is a block
|
||||
for (Entry<String, Integer> entry : blocks.ids.entrySet())
|
||||
{
|
||||
availabilityMap.set(entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
Set<Integer> newBlockedIds = new HashSet<Integer>();
|
||||
Set<String> itemsToRemove = new HashSet<String>();
|
||||
Map<String, Integer> itemsToRelocate = new HashMap<String, Integer>();
|
||||
|
||||
// check all ids occupied by items
|
||||
for (Entry<String, Integer> entry : dataList.entrySet())
|
||||
{
|
||||
String itemName = entry.getKey();
|
||||
|
||||
if (itemName.charAt(0) != '\u0001') // is an item
|
||||
for (Entry<String, Integer> entry : items.ids.entrySet())
|
||||
{
|
||||
int oldId = entry.getValue();
|
||||
String realName = itemName.substring(1);
|
||||
String blockName = '\u0001' + realName;
|
||||
Item item = getMain().iItemRegistry.getRaw(realName);
|
||||
String name = entry.getKey();
|
||||
Item item = getMain().iItemRegistry.getRaw(name);
|
||||
boolean blockThisId = false; // block oldId unless it's used by a block
|
||||
|
||||
if (item == null) // item no longer available
|
||||
{
|
||||
// can't fix items without reliably checking if they are ItemBlocks
|
||||
FMLLog.warning("Item %s (old id %d) is no longer available and thus can't be fixed.", realName, oldId);
|
||||
itemsToRemove.add(itemName);
|
||||
FMLLog.warning("Item %s (old id %d) is no longer available and thus can't be fixed.", name, oldId);
|
||||
itemsToRemove.add(name);
|
||||
blockThisId = true;
|
||||
}
|
||||
else if (item instanceof ItemBlock)
|
||||
{
|
||||
if (dataList.containsKey(blockName)) // the item was an ItemBlock before
|
||||
if (blocks.ids.containsKey(name)) // the item was an ItemBlock before
|
||||
{
|
||||
int blockId = dataList.get(blockName);
|
||||
int blockId = blocks.ids.get(name);
|
||||
|
||||
if (blockId != oldId) // mis-located ItemBlock
|
||||
{
|
||||
// relocate to the matching block
|
||||
FMLLog.warning("ItemBlock %s (old id %d) doesn't have the same id as its block (%d).", realName, oldId, blockId);
|
||||
itemsToRelocate.put(entry.getKey(), blockId);
|
||||
FMLLog.warning("ItemBlock %s (old id %d) doesn't have the same id as its block (%d).", name, oldId, blockId);
|
||||
itemsToRelocate.put(name, blockId);
|
||||
blockThisId = true;
|
||||
}
|
||||
else // intact ItemBlock
|
||||
|
@ -305,16 +239,16 @@ public class GameData {
|
|||
else // the item hasn't been an ItemBlock before, but it's now
|
||||
{
|
||||
// can't fix these, drop them
|
||||
FMLLog.warning("Item %s (old id %d) has been migrated to an ItemBlock and can't be fixed.", realName, oldId);
|
||||
itemsToRemove.add(itemName);
|
||||
FMLLog.warning("Item %s (old id %d) has been migrated to an ItemBlock and can't be fixed.", name, oldId);
|
||||
itemsToRemove.add(name);
|
||||
blockThisId = true;
|
||||
}
|
||||
}
|
||||
else if (availabilityMap.get(oldId)) // normal item, id is already occupied
|
||||
{
|
||||
// remove the item mapping
|
||||
FMLLog.warning("Item %s (old id %d) is conflicting with another block/item and can't be fixed.", realName, oldId);
|
||||
itemsToRemove.add(itemName);
|
||||
FMLLog.warning("Item %s (old id %d) is conflicting with another block/item and can't be fixed.", name, oldId);
|
||||
itemsToRemove.add(name);
|
||||
}
|
||||
else // intact Item
|
||||
{
|
||||
|
@ -331,7 +265,6 @@ public class GameData {
|
|||
availabilityMap.set(oldId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemsToRemove.isEmpty() && itemsToRelocate.isEmpty()) return; // nothing to do
|
||||
|
||||
|
@ -350,9 +283,9 @@ public class GameData {
|
|||
// confirm missing mods causing item removal
|
||||
Set<String> modsMissing = new HashSet<String>();
|
||||
|
||||
for (String itemName : itemsToRemove)
|
||||
for (String name : itemsToRemove)
|
||||
{
|
||||
modsMissing.add(itemName.substring(1, itemName.indexOf(':')));
|
||||
modsMissing.add(name.substring(0, name.indexOf(':')));
|
||||
}
|
||||
|
||||
for (Iterator<String> it = modsMissing.iterator(); it.hasNext(); )
|
||||
|
@ -396,32 +329,22 @@ public class GameData {
|
|||
}
|
||||
|
||||
// apply fix
|
||||
for (String itemName : itemsToRemove)
|
||||
for (String name : itemsToRemove)
|
||||
{
|
||||
int id = dataList.remove(itemName);
|
||||
|
||||
FMLLog.warning("Removed Item %s, old id %d.", itemName.substring(1), id);
|
||||
FMLLog.warning("Removed Item %s, old id %d.", name, items.ids.remove(name));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, Integer> entry : itemsToRelocate.entrySet())
|
||||
{
|
||||
String itemName = entry.getKey();
|
||||
int newId = entry.getValue();
|
||||
|
||||
int oldId = dataList.put(itemName, newId);
|
||||
|
||||
FMLLog.warning("Remapped Item %s to id %d, old id %d.", itemName.substring(1), newId, oldId);
|
||||
int oldId = items.ids.put(entry.getKey(), newId);
|
||||
FMLLog.warning("Remapped Item %s to id %d, old id %d.", entry.getKey(), newId, oldId);
|
||||
}
|
||||
|
||||
blockedIds.addAll(newBlockedIds);
|
||||
}
|
||||
|
||||
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, Set<String> blockSubstitutions, Set<String> itemSubstitutions, boolean injectFrozenData, boolean isLocalWorld)
|
||||
{
|
||||
return injectWorldIDMap(dataList, new HashSet<Integer>(), new HashMap<String, String>(), new HashMap<String, String>(), blockSubstitutions, itemSubstitutions, injectFrozenData, isLocalWorld);
|
||||
}
|
||||
|
||||
public static List<String> injectWorldIDMap(Map<String, Integer> dataList, Set<Integer> blockedIds, Map<String, String> blockAliases, Map<String, String> itemAliases, Set<String> blockSubstitutions, Set<String> itemSubstitutions, boolean injectFrozenData, boolean isLocalWorld)
|
||||
public static List<String> injectSnapshot(GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld)
|
||||
{
|
||||
FMLLog.info("Injecting existing block and item data into this %s instance", FMLCommonHandler.instance().getEffectiveSide().isServer() ? "server" : "client");
|
||||
Map<String, Integer[]> remaps = Maps.newHashMap();
|
||||
|
@ -430,28 +353,31 @@ public class GameData {
|
|||
getMain().iBlockRegistry.dump();
|
||||
getMain().iItemRegistry.dump();
|
||||
|
||||
GameDataSnapshot.Entry blocks = snapshot.entries.get("fml:blocks");
|
||||
GameDataSnapshot.Entry items = snapshot.entries.get("fml:items");
|
||||
|
||||
GameData newData = new GameData();
|
||||
|
||||
for (int id : blockedIds)
|
||||
for (int id : blocks.blocked)
|
||||
{
|
||||
newData.block(id);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : blockAliases.entrySet())
|
||||
for (Map.Entry<String, String> entry : blocks.aliases.entrySet())
|
||||
{
|
||||
newData.iBlockRegistry.addAlias(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : itemAliases.entrySet())
|
||||
for (Map.Entry<String, String> entry : items.aliases.entrySet())
|
||||
{
|
||||
newData.iItemRegistry.addAlias(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
for (String entry : blockSubstitutions)
|
||||
for (String entry : blocks.substitutions)
|
||||
{
|
||||
newData.iBlockRegistry.activateSubstitution(entry);
|
||||
}
|
||||
for (String entry : itemSubstitutions)
|
||||
for (String entry : items.substitutions)
|
||||
{
|
||||
newData.iItemRegistry.activateSubstitution(entry);
|
||||
}
|
||||
|
@ -459,14 +385,14 @@ public class GameData {
|
|||
{
|
||||
for (String newBlockSubstitution : getMain().blockSubstitutions.keySet())
|
||||
{
|
||||
if (!blockSubstitutions.contains(newBlockSubstitution))
|
||||
if (!blocks.substitutions.contains(newBlockSubstitution))
|
||||
{
|
||||
newData.iBlockRegistry.activateSubstitution(newBlockSubstitution);
|
||||
}
|
||||
}
|
||||
for (String newItemSubstitution : getMain().itemSubstitutions.keySet())
|
||||
{
|
||||
if (!itemSubstitutions.contains(newItemSubstitution))
|
||||
if (!items.substitutions.contains(newItemSubstitution))
|
||||
{
|
||||
newData.iItemRegistry.activateSubstitution(newItemSubstitution);
|
||||
}
|
||||
|
@ -477,16 +403,12 @@ public class GameData {
|
|||
for (int pass = 0; pass < 2; pass++)
|
||||
{
|
||||
boolean isBlock = (pass == 0);
|
||||
Map<String, Integer> ids = (isBlock ? blocks.ids : items.ids);
|
||||
|
||||
for (Entry<String, Integer> entry : dataList.entrySet())
|
||||
for (Entry<String, Integer> entry : ids.entrySet())
|
||||
{
|
||||
String itemName = entry.getKey();
|
||||
int newId = entry.getValue();
|
||||
|
||||
// names starting with 0x1 are blocks, skip if the type isn't handled by this pass
|
||||
if ((itemName.charAt(0) == '\u0001') != isBlock) continue;
|
||||
|
||||
itemName = itemName.substring(1);
|
||||
int currId = isBlock ? getMain().iBlockRegistry.getId(itemName) : getMain().iItemRegistry.getId(itemName);
|
||||
|
||||
if (currId == -1)
|
||||
|
@ -743,8 +665,8 @@ public class GameData {
|
|||
|
||||
private GameData()
|
||||
{
|
||||
iBlockRegistry = new FMLControlledNamespacedRegistry<Block>(new ResourceLocation("minecraft:air"), MAX_BLOCK_ID, MIN_BLOCK_ID, Block.class,'\u0001');
|
||||
iItemRegistry = new FMLControlledNamespacedRegistry<Item>(null, MAX_ITEM_ID, MIN_ITEM_ID, Item.class,'\u0002');
|
||||
iBlockRegistry = new FMLControlledNamespacedRegistry<Block>(new ResourceLocation("minecraft:air"), MAX_BLOCK_ID, MIN_BLOCK_ID, Block.class);
|
||||
iItemRegistry = new FMLControlledNamespacedRegistry<Item>(null, MAX_ITEM_ID, MIN_ITEM_ID, Item.class);
|
||||
availabilityMap = new BitSet(MAX_ITEM_ID + 1);
|
||||
blockedIds = new HashSet<Integer>();
|
||||
}
|
||||
|
|
|
@ -332,42 +332,6 @@ public class GameRegistry
|
|||
return GameData.findItem(modId, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually register a custom item stack with FML for later tracking. It is automatically scoped with the active modid
|
||||
*
|
||||
* @param name The name to register it under
|
||||
* @param itemStack The itemstack to register
|
||||
*/
|
||||
public static void registerCustomItemStack(String name, ItemStack itemStack)
|
||||
{
|
||||
GameData.registerCustomItemStack(name, itemStack);
|
||||
}
|
||||
/**
|
||||
* Lookup an itemstack based on mod and name. It will create "default" itemstacks from blocks and items if no
|
||||
* explicit itemstack is found.
|
||||
*
|
||||
* If it is built from a block, the metadata is by default the "wildcard" value.
|
||||
*
|
||||
* Custom itemstacks can be dumped from minecraft by setting the system property fml.dumpRegistry to true
|
||||
* (-Dfml.dumpRegistry=true on the command line will work)
|
||||
*
|
||||
* @param modId The modid of the stack owner
|
||||
* @param name The name of the stack
|
||||
* @param stackSize The size of the stack returned
|
||||
* @return The custom itemstack or null if no such itemstack was found
|
||||
*/
|
||||
public static ItemStack findItemStack(String modId, String name, int stackSize)
|
||||
{
|
||||
ItemStack foundStack = GameData.findItemStack(modId, name);
|
||||
if (foundStack != null)
|
||||
{
|
||||
ItemStack is = foundStack.copy();
|
||||
is.stackSize = Math.min(stackSize, is.getMaxStackSize());
|
||||
return is;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static final class UniqueIdentifier
|
||||
{
|
||||
public final String modId;
|
||||
|
|
Loading…
Reference in New Issue