mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-14 01:04:24 +00:00
More network stuff, partially done id syncing.
This commit is contained in:
1 parent
f5c38e2359
commit
9c96a0a10a
15 files changed
+507
-253
No files matched your search
@@ -16,6 +16,7 @@ import java.io.File;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
@@ -25,10 +26,14 @@ import net.minecraft.world.storage.SaveHandler;
|
||||
import net.minecraft.world.storage.WorldInfo;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.client.FMLFileResourcePack;
|
||||
import cpw.mods.fml.client.FMLFolderResourcePack;
|
||||
import cpw.mods.fml.common.asm.FMLSanityChecker;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.network.NetworkCheckHandler;
|
||||
import cpw.mods.fml.common.network.NetworkModHolder;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
@@ -60,9 +65,21 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller)
|
||||
{
|
||||
bus.register(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void modConstruction(FMLConstructionEvent evt)
|
||||
{
|
||||
NetworkRegistry.INSTANCE.register(this, this.getClass(), null, evt.getASMHarvestedData());
|
||||
}
|
||||
|
||||
@NetworkCheckHandler
|
||||
public boolean checkModLists(Map<String,String> modList, Side side)
|
||||
{
|
||||
return Loader.instance().checkRemoteModList(modList,side);
|
||||
}
|
||||
@Override
|
||||
public NBTTagCompound getDataForWriting(SaveHandler handler, WorldInfo info)
|
||||
{
|
||||
@@ -76,8 +93,7 @@ public class FMLContainer extends DummyModContainer implements WorldAccessContai
|
||||
list.func_74742_a(mod);
|
||||
}
|
||||
fmlData.func_74782_a("ModList", list);
|
||||
NBTTagList itemList = new NBTTagList();
|
||||
GameData.writeItemData(itemList);
|
||||
NBTTagCompound nbt = GameData.buildItemDataList();
|
||||
fmlData.func_74782_a("ModItemData", itemList);
|
||||
return fmlData;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
@@ -40,6 +41,7 @@ import com.google.common.collect.Multisets;
|
||||
import com.google.common.collect.Ordering;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Sets.SetView;
|
||||
import com.google.common.collect.TreeMultimap;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
@@ -56,6 +58,7 @@ import cpw.mods.fml.common.toposort.TopologicalSort;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
import cpw.mods.fml.relauncher.FMLRelaunchLog;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* The loader class performs the actual loading of the mod code from disk.
|
||||
@@ -817,4 +820,24 @@ public class Loader
|
||||
{
|
||||
return getIndexedModList().get(modId).getCustomModProperties();
|
||||
}
|
||||
|
||||
boolean checkRemoteModList(Map<String, String> modList, Side side)
|
||||
{
|
||||
Set<String> remoteModIds = modList.keySet();
|
||||
Set<String> localModIds = namedMods.keySet();
|
||||
|
||||
Set<String> difference = Sets.newLinkedHashSet(Sets.difference(localModIds, remoteModIds));
|
||||
for (Iterator<String> iterator = difference.iterator(); iterator.hasNext();)
|
||||
{
|
||||
String missingRemotely = iterator.next();
|
||||
ModState modState = modController.getModState(namedMods.get(missingRemotely));
|
||||
if (modState == ModState.DISABLED)
|
||||
{
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
FMLLog.info("Attempting connection with missing mods %s at %s", difference, side);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
package cpw.mods.fml.common.network;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface NetworkCheckHandler
|
||||
{
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.SetMultimap;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
@@ -34,11 +36,18 @@ public class NetworkModHolder
|
||||
public abstract boolean check(Map<String,String> remoteVersions, Side side);
|
||||
}
|
||||
|
||||
private class IgnoredChecker extends NetworkChecker {
|
||||
@Override
|
||||
public boolean check(Map<String, String> remoteVersions, Side side)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private class DefaultNetworkChecker extends NetworkChecker {
|
||||
@Override
|
||||
public boolean check(Map<String,String> remoteVersions, Side side)
|
||||
{
|
||||
return acceptVersion(remoteVersions.get(container.getModId()));
|
||||
return remoteVersions.containsKey(container.getModId()) ? acceptVersion(remoteVersions.get(container.getModId())) : false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -78,7 +87,16 @@ public class NetworkModHolder
|
||||
public NetworkModHolder(ModContainer container, Class<?> modClass, String acceptableVersionRange, ASMDataTable table)
|
||||
{
|
||||
this(container);
|
||||
Set<ASMData> versionCheckHandlers = table.getAnnotationsFor(container).get(NetworkCheckHandler.class.getName());
|
||||
SetMultimap<String, ASMData> annotationTable = table.getAnnotationsFor(container);
|
||||
Set<ASMData> versionCheckHandlers;
|
||||
if (annotationTable != null)
|
||||
{
|
||||
versionCheckHandlers = annotationTable.get(NetworkCheckHandler.class.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
versionCheckHandlers = ImmutableSet.of();
|
||||
}
|
||||
String networkCheckHandlerMethod = null;
|
||||
for (ASMData vch : versionCheckHandlers)
|
||||
{
|
||||
@@ -89,6 +107,24 @@ public class NetworkModHolder
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (versionCheckHandlers.isEmpty())
|
||||
{
|
||||
for (Method m : modClass.getMethods())
|
||||
{
|
||||
if (m.isAnnotationPresent(NetworkCheckHandler.class))
|
||||
{
|
||||
if (m.getParameterTypes().length == 2 && m.getParameterTypes()[0].equals(Map.class) && m.getParameterTypes()[1].equals(Side.class))
|
||||
{
|
||||
this.checkHandler = m;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.severe("Found unexpected method signature for annotation NetworkCheckHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (networkCheckHandlerMethod != null)
|
||||
{
|
||||
try
|
||||
@@ -104,22 +140,23 @@ public class NetworkModHolder
|
||||
FMLLog.log(Level.WARNING, e, "The declared version check handler method %s on network mod id %s is not accessible", networkCheckHandlerMethod, container.getModId());
|
||||
}
|
||||
}
|
||||
if (this.checkHandler == null)
|
||||
if (this.checkHandler != null)
|
||||
{
|
||||
String versionBounds = acceptableVersionRange;
|
||||
if (!Strings.isNullOrEmpty(versionBounds))
|
||||
this.checker = new MethodNetworkChecker();
|
||||
} else if (!Strings.isNullOrEmpty(acceptableVersionRange) && !acceptableVersionRange.equals('*'))
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
this.acceptableRange = VersionRange.createFromVersionSpec(versionBounds);
|
||||
}
|
||||
catch (InvalidVersionSpecificationException e)
|
||||
{
|
||||
FMLLog.log(Level.WARNING, e, "Invalid bounded range %s specified for network mod id %s", versionBounds, container.getModId());
|
||||
}
|
||||
this.acceptableRange = VersionRange.createFromVersionSpec(acceptableVersionRange);
|
||||
}
|
||||
catch (InvalidVersionSpecificationException e)
|
||||
{
|
||||
FMLLog.log(Level.WARNING, e, "Invalid bounded range %s specified for network mod id %s", acceptableVersionRange, container.getModId());
|
||||
}
|
||||
this.checker = new DefaultNetworkChecker();
|
||||
} else {
|
||||
this.checker = new IgnoredChecker();
|
||||
}
|
||||
|
||||
FMLLog.finest("Testing mod %s to verify it accepts its own version in a remote connection", container.getModId());
|
||||
boolean acceptsSelf = acceptVersion(container.getVersion());
|
||||
if (!acceptsSelf)
|
||||
@@ -130,8 +167,6 @@ public class NetworkModHolder
|
||||
{
|
||||
FMLLog.finest("The mod %s accepts its own version (%s)", container.getModId(), container.getVersion());
|
||||
}
|
||||
|
||||
this.checker = checkHandler == null ? new DefaultNetworkChecker() : new MethodNetworkChecker();
|
||||
}
|
||||
|
||||
public boolean acceptVersion(String version)
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
|
||||
@@ -59,6 +60,7 @@ public enum NetworkRegistry
|
||||
public static final AttributeKey<Side> CHANNEL_SOURCE = new AttributeKey<Side>("fml:channelSource");
|
||||
public static final AttributeKey<OutboundTarget> FML_MESSAGETARGET = new AttributeKey<OutboundTarget>("fml:outboundTarget");
|
||||
public static final AttributeKey<Object> FML_MESSAGETARGETARGS = new AttributeKey<Object>("fml:outboundTargetArgs");
|
||||
public static final AttributeKey<ModContainer> MOD_CONTAINER = new AttributeKey<ModContainer>("fml:modContainer");
|
||||
|
||||
public static final byte FML_PROTOCOL = 1;
|
||||
|
||||
@@ -204,10 +206,15 @@ public enum NetworkRegistry
|
||||
|
||||
static class FMLEmbeddedChannel extends EmbeddedChannel {
|
||||
public FMLEmbeddedChannel(String channelName, Side source, ChannelHandler... handlers)
|
||||
{
|
||||
this(Loader.instance().activeModContainer(), channelName, source, handlers);
|
||||
}
|
||||
public FMLEmbeddedChannel(ModContainer container, String channelName, Side source, ChannelHandler... handlers)
|
||||
{
|
||||
super(handlers);
|
||||
this.attr(FML_CHANNEL).set(channelName);
|
||||
this.attr(CHANNEL_SOURCE).set(source);
|
||||
this.attr(MOD_CONTAINER).setIfAbsent(container);
|
||||
this.pipeline().addFirst(new FMLOutboundHandler());
|
||||
}
|
||||
}
|
||||
@@ -255,6 +262,23 @@ public enum NetworkRegistry
|
||||
return result;
|
||||
}
|
||||
|
||||
public EnumMap<Side,EmbeddedChannel> newChannel(ModContainer container, String name, ChannelHandler... handlers)
|
||||
{
|
||||
if (channels.containsKey(name) || name.startsWith("MC|") || name.startsWith("\u0001") || (name.startsWith("FML") && !("FML".equals(container.getModId()))))
|
||||
{
|
||||
throw new RuntimeException("That channel is already registered");
|
||||
}
|
||||
EnumMap<Side,EmbeddedChannel> result = Maps.newEnumMap(Side.class);
|
||||
|
||||
for (Side side : Side.values())
|
||||
{
|
||||
FMLEmbeddedChannel channel = new FMLEmbeddedChannel(container, name, side, handlers);
|
||||
channels.get(side).put(name,channel);
|
||||
result.put(side, channel);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public EmbeddedChannel getChannel(String name, Side source)
|
||||
{
|
||||
return channels.get(source).get(name);
|
||||
|
||||
@@ -276,14 +276,6 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback from the networkmanager
|
||||
* @param fmlProxyPacket
|
||||
*/
|
||||
public void dispatch(FMLProxyPacket fmlProxyPacket)
|
||||
{
|
||||
}
|
||||
|
||||
public void sendProxy(FMLProxyPacket msg)
|
||||
{
|
||||
if (side == Side.CLIENT)
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
package cpw.mods.fml.common.registry;
|
||||
|
||||
import gnu.trove.map.hash.TIntIntHashMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
import com.google.common.collect.MapDifference;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
import net.minecraft.util.ObjectIntIdentityMap;
|
||||
import net.minecraft.util.RegistryNamespaced;
|
||||
|
||||
public class FMLControlledNamespacedRegistry<I> extends RegistryNamespaced {
|
||||
public class FMLObjectIntIdentityMap extends ObjectIntIdentityMap {
|
||||
private TIntIntHashMap oldMap;
|
||||
private TIntIntHashMap newMap;
|
||||
private ArrayList<Integer> oldIndex;
|
||||
private ArrayList<Integer> newIndex;
|
||||
|
||||
public FMLObjectIntIdentityMap()
|
||||
{
|
||||
}
|
||||
|
||||
boolean containsID(int id)
|
||||
{
|
||||
return func_148744_b(id);
|
||||
}
|
||||
|
||||
Object get(int id)
|
||||
{
|
||||
return func_148745_a(id);
|
||||
}
|
||||
|
||||
int get(Object obj)
|
||||
{
|
||||
return func_148747_b(obj);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
void beginSwap()
|
||||
{
|
||||
oldMap = field_148749_a;
|
||||
newMap = new TIntIntHashMap(256, 0.5F, -1, -1);
|
||||
oldIndex = (ArrayList<Integer>) field_148748_b;
|
||||
newIndex = new ArrayList<Integer>(oldIndex.size());
|
||||
}
|
||||
|
||||
void completeSwap()
|
||||
{
|
||||
field_148749_a = newMap;
|
||||
field_148748_b = newIndex;
|
||||
oldIndex = newIndex = null;
|
||||
oldMap = newMap = null;
|
||||
}
|
||||
|
||||
void putNew(int id, Object item)
|
||||
{
|
||||
field_148749_a = newMap;
|
||||
field_148748_b = newIndex;
|
||||
super.func_148746_a(item, id);
|
||||
field_148749_a = oldMap;
|
||||
field_148748_b = oldIndex;
|
||||
}
|
||||
}
|
||||
|
||||
private final Class<I> superType;
|
||||
private String optionalDefaultName;
|
||||
private I optionalDefaultObject;
|
||||
|
||||
private BiMap<String,Integer> namedIds = HashBiMap.create();
|
||||
private BitSet availabilityMap;
|
||||
private int maxId;
|
||||
private int minId;
|
||||
|
||||
public FMLControlledNamespacedRegistry(String optionalDefault, int maxIdValue, int minIdValue, Class<I> type)
|
||||
{
|
||||
this.superType = type;
|
||||
this.optionalDefaultName = optionalDefault;
|
||||
this.availabilityMap = new BitSet(maxIdValue);
|
||||
this.maxId = maxIdValue;
|
||||
this.minId = minIdValue;
|
||||
this.field_148759_a = new FMLObjectIntIdentityMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void func_148756_a(int id, String name, Object thing)
|
||||
{
|
||||
add(id, name, superType.cast(thing));
|
||||
}
|
||||
|
||||
public void add(int id, String name, I thing)
|
||||
{
|
||||
if (name.equals(optionalDefaultName))
|
||||
{
|
||||
this.optionalDefaultObject = thing;
|
||||
}
|
||||
|
||||
int idToUse = id;
|
||||
if (availabilityMap.get(id))
|
||||
{
|
||||
idToUse = availabilityMap.nextClearBit(minId);
|
||||
}
|
||||
if (idToUse >= maxId)
|
||||
{
|
||||
throw new RuntimeException(String.format("Invalid id %s - not accepted",id));
|
||||
}
|
||||
namedIds.put(name,idToUse);
|
||||
|
||||
ModContainer mc = Loader.instance().activeModContainer();
|
||||
String prefix = mc.getModId();
|
||||
name = prefix + ":"+ name;
|
||||
super.func_148756_a(idToUse, name, thing);
|
||||
}
|
||||
|
||||
@Override
|
||||
public I func_82594_a(String name)
|
||||
{
|
||||
I object = superType.cast(super.func_82594_a(name));
|
||||
return object == null ? this.optionalDefaultObject : object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public I func_148754_a(int id)
|
||||
{
|
||||
I object = superType.cast(super.func_148754_a(id));
|
||||
return object == null ? this.optionalDefaultObject : object;
|
||||
}
|
||||
|
||||
|
||||
void injectIdMapping(BiMap<String,Integer> values)
|
||||
{
|
||||
MapDifference<String, Integer> difference = Maps.difference(values, namedIds);
|
||||
for (Entry<String, Integer> missing : difference.entriesOnlyOnLeft().entrySet())
|
||||
{
|
||||
String name = missing.getKey();
|
||||
Integer id = missing.getValue();
|
||||
String[] parts = name.split(":");
|
||||
ModContainer modContainer = GameData.findModOwner(parts[0]);
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
BiMap<String,Object> nameMap = (BiMap<String,Object>) field_82596_a;
|
||||
FMLObjectIntIdentityMap idMap = (FMLObjectIntIdentityMap) field_148759_a;
|
||||
idMap.beginSwap();
|
||||
for (Entry<String, Integer> entry : values.entrySet())
|
||||
{
|
||||
String name = entry.getKey();
|
||||
Integer id = entry.getValue();
|
||||
Object item = nameMap.get(name);
|
||||
idMap.putNew(id, item);
|
||||
}
|
||||
|
||||
idMap.completeSwap();
|
||||
}
|
||||
|
||||
public I get(int id)
|
||||
{
|
||||
return func_148754_a(id);
|
||||
}
|
||||
|
||||
public I get(String name)
|
||||
{
|
||||
return func_82594_a(name);
|
||||
}
|
||||
|
||||
public int getId(I thing)
|
||||
{
|
||||
return func_148757_b(thing);
|
||||
}
|
||||
public void serializeInto(Map<String, Integer> idMapping)
|
||||
{
|
||||
for (Entry<String, Integer> id: namedIds.entrySet())
|
||||
{
|
||||
idMapping.put(id.getKey(), id.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,48 +53,10 @@ import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
|
||||
|
||||
public class GameData {
|
||||
private static Map<Integer, ItemData> idMap = Maps.newHashMap();
|
||||
private static CountDownLatch serverValidationLatch;
|
||||
private static CountDownLatch clientValidationLatch;
|
||||
private static MapDifference<Integer, ItemData> difference;
|
||||
private static boolean shouldContinue = true;
|
||||
private static boolean isSaveValid = true;
|
||||
private static ImmutableTable<String, String, Integer> modObjectTable;
|
||||
private static Table<String, String, ItemStack> customItemStacks = HashBasedTable.create();
|
||||
private static Map<String,String> ignoredMods;
|
||||
private static boolean validated;
|
||||
|
||||
private static boolean isModIgnoredForIdValidation(String modId)
|
||||
{
|
||||
if (ignoredMods == null)
|
||||
{
|
||||
File f = new File(Loader.instance().getConfigDir(),"fmlIDChecking.properties");
|
||||
if (f.exists())
|
||||
{
|
||||
Properties p = new Properties();
|
||||
try
|
||||
{
|
||||
p.load(new FileInputStream(f));
|
||||
ignoredMods = Maps.fromProperties(p);
|
||||
if (ignoredMods.size()>0)
|
||||
{
|
||||
FMLLog.log("fml.ItemTracker", Level.WARNING, "Using non-empty ignored mods configuration file %s", ignoredMods.keySet());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Throwables.propagateIfPossible(e);
|
||||
FMLLog.log("fml.ItemTracker", Level.SEVERE, e, "Failed to read ignored ID checker mods properties file");
|
||||
ignoredMods = ImmutableMap.<String, String>of();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ignoredMods = ImmutableMap.<String, String>of();
|
||||
}
|
||||
}
|
||||
return ignoredMods.containsKey(modId);
|
||||
}
|
||||
public static final FMLControlledNamespacedRegistry<Block> blockRegistry = new FMLControlledNamespacedRegistry<Block>("air", 4095, 0, Block.class);
|
||||
public static final FMLControlledNamespacedRegistry<Item> itemRegistry = new FMLControlledNamespacedRegistry<Item>(null, 32000, 4096, Item.class);
|
||||
|
||||
public static void newItemAdded(Item item)
|
||||
{
|
||||
@@ -193,47 +155,12 @@ public class GameData {
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeItemData(NBTTagList itemList)
|
||||
public static Map<String,Integer> buildItemDataList()
|
||||
{
|
||||
for (ItemData dat : idMap.values())
|
||||
{
|
||||
itemList.func_74742_a(dat.toNBT());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the server gate
|
||||
* @param gateCount the countdown amount. If it's 2 we're on the client and the client and server
|
||||
* will wait at the latch. 1 is a server and the server will proceed
|
||||
*/
|
||||
public static void initializeServerGate(int gateCount)
|
||||
{
|
||||
serverValidationLatch = new CountDownLatch(gateCount - 1);
|
||||
clientValidationLatch = new CountDownLatch(gateCount - 1);
|
||||
}
|
||||
|
||||
public static MapDifference<Integer, ItemData> gateWorldLoadingForValidation()
|
||||
{
|
||||
try
|
||||
{
|
||||
serverValidationLatch.await();
|
||||
if (!isSaveValid)
|
||||
{
|
||||
return difference;
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
difference = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static void releaseGate(boolean carryOn)
|
||||
{
|
||||
shouldContinue = carryOn;
|
||||
clientValidationLatch.countDown();
|
||||
Map<String,Integer> idMapping = Maps.newHashMap();
|
||||
blockRegistry.serializeInto(idMapping);
|
||||
itemRegistry.serializeInto(idMapping);
|
||||
return idMapping;
|
||||
}
|
||||
|
||||
public static Set<ItemData> buildWorldItemData(NBTTagList modList)
|
||||
@@ -241,71 +168,21 @@ public class GameData {
|
||||
Set<ItemData> worldSaveItems = Sets.newHashSet();
|
||||
for (int i = 0; i < modList.func_74745_c(); i++)
|
||||
{
|
||||
NBTTagCompound mod = (NBTTagCompound) modList.func_74743_b(i);
|
||||
NBTTagCompound mod = modList.func_150305_b(i);
|
||||
ItemData dat = new ItemData(mod);
|
||||
worldSaveItems.add(dat);
|
||||
}
|
||||
return worldSaveItems;
|
||||
}
|
||||
|
||||
static void setName(Item item, String name, String modId)
|
||||
{
|
||||
int id = item.field_77779_bT;
|
||||
ItemData itemData = idMap.get(id);
|
||||
itemData.setName(name,modId);
|
||||
}
|
||||
|
||||
public static void buildModObjectTable()
|
||||
{
|
||||
if (modObjectTable != null)
|
||||
{
|
||||
throw new IllegalStateException("Illegal call to buildModObjectTable!");
|
||||
}
|
||||
|
||||
Map<Integer, Cell<String, String, Integer>> map = Maps.transformValues(idMap, new Function<ItemData,Cell<String,String,Integer>>() {
|
||||
public Cell<String,String,Integer> apply(ItemData data)
|
||||
{
|
||||
if ("Minecraft".equals(data.getModId()) || !data.isOveridden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Tables.immutableCell(data.getModId(), data.getItemType(), data.getItemId());
|
||||
}
|
||||
});
|
||||
|
||||
Builder<String, String, Integer> tBuilder = ImmutableTable.builder();
|
||||
for (Cell<String, String, Integer> c : map.values())
|
||||
{
|
||||
if (c!=null)
|
||||
{
|
||||
tBuilder.put(c);
|
||||
}
|
||||
}
|
||||
modObjectTable = tBuilder.build();
|
||||
}
|
||||
static Item findItem(String modId, String name)
|
||||
{
|
||||
if (modObjectTable == null || !modObjectTable.contains(modId, name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Item.field_77698_e[modObjectTable.get(modId, name)];
|
||||
return (Item) itemRegistry.func_82594_a(modId + ":" + name);
|
||||
}
|
||||
|
||||
static Block findBlock(String modId, String name)
|
||||
{
|
||||
if (modObjectTable == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer blockId = modObjectTable.get(modId, name);
|
||||
if (blockId == null || blockId >= Block.field_71973_m.length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return Block.field_71973_m[blockId];
|
||||
return (Block) blockRegistry.func_82594_a(modId+":"+name);
|
||||
}
|
||||
|
||||
static ItemStack findItemStack(String modId, String name)
|
||||
@@ -366,25 +243,27 @@ public class GameData {
|
||||
static UniqueIdentifier getUniqueName(Block block)
|
||||
{
|
||||
if (block == null) return null;
|
||||
ItemData itemData = idMap.get(block.field_71990_ca);
|
||||
if (itemData == null || !itemData.isOveridden() || customItemStacks.contains(itemData.getModId(), itemData.getItemType()))
|
||||
String name = blockRegistry.func_148750_c(block);
|
||||
UniqueIdentifier ui = new UniqueIdentifier(name);
|
||||
if (customItemStacks.contains(ui.modId, ui.name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UniqueIdentifier(itemData.getModId(), itemData.getItemType());
|
||||
return ui;
|
||||
}
|
||||
|
||||
static UniqueIdentifier getUniqueName(Item item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
ItemData itemData = idMap.get(item.field_77779_bT);
|
||||
if (itemData == null || !itemData.isOveridden() || customItemStacks.contains(itemData.getModId(), itemData.getItemType()))
|
||||
String name = itemRegistry.func_148750_c(item);
|
||||
UniqueIdentifier ui = new UniqueIdentifier(name);
|
||||
if (customItemStacks.contains(ui.modId, ui.name))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new UniqueIdentifier(itemData.getModId(), itemData.getItemType());
|
||||
return ui;
|
||||
}
|
||||
|
||||
public static void validateRegistry()
|
||||
@@ -406,4 +285,40 @@ public class GameData {
|
||||
}
|
||||
*/ validated = true;
|
||||
}
|
||||
private static Map<UniqueIdentifier, ModContainer> customOwners = Maps.newHashMap();
|
||||
static Block registerBlockAndItem(Item item, Block block, String name, String modId)
|
||||
{
|
||||
|
||||
}
|
||||
static Item registerItem(Item item, String name, String modId)
|
||||
{
|
||||
ModContainer mc = Loader.instance().activeModContainer();
|
||||
if (modId != null)
|
||||
{
|
||||
customOwners.put(new UniqueIdentifier(modId, name), mc);
|
||||
}
|
||||
itemRegistry.add(0, name, item);
|
||||
int itemId = itemRegistry.getId(item);
|
||||
blockRegistry.clearItem(itemId);
|
||||
return item;
|
||||
}
|
||||
static Block registerBlock(Block block, String name, String modId)
|
||||
{
|
||||
ModContainer mc = Loader.instance().activeModContainer();
|
||||
if (modId != null)
|
||||
{
|
||||
customOwners.put(new UniqueIdentifier(modId, name), mc);
|
||||
}
|
||||
blockRegistry.func_148756_a(0, name, block);
|
||||
return block;
|
||||
}
|
||||
public static ModContainer findModOwner(String string)
|
||||
{
|
||||
UniqueIdentifier ui = new UniqueIdentifier(string);
|
||||
if (customOwners.containsKey(ui))
|
||||
{
|
||||
return customOwners.get(ui);
|
||||
}
|
||||
return Loader.instance().getIndexedModList().get(ui.modId);
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import net.minecraft.world.WorldType;
|
||||
import net.minecraft.world.biome.BiomeGenBase;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
@@ -54,12 +55,10 @@ import cpw.mods.fml.common.ObfuscationReflectionHelper;
|
||||
|
||||
public class GameRegistry
|
||||
{
|
||||
private static Multimap<ModContainer, BlockProxy> blockRegistry = ArrayListMultimap.create();
|
||||
private static Set<IWorldGenerator> worldGenerators = Sets.newHashSet();
|
||||
private static List<IFuelHandler> fuelHandlers = Lists.newArrayList();
|
||||
private static List<ICraftingHandler> craftingHandlers = Lists.newArrayList();
|
||||
private static List<IPickupNotifier> pickupHandlers = Lists.newArrayList();
|
||||
private static List<IPlayerTracker> playerTrackers = Lists.newArrayList();
|
||||
|
||||
/**
|
||||
* Register a world generator - something that inserts new block types into the world
|
||||
@@ -114,19 +113,19 @@ public class GameRegistry
|
||||
* @param modId An optional modId that will "own" this block - generally used by multi-mod systems
|
||||
* where one mod should "own" all the blocks of all the mods, null defaults to the active mod
|
||||
*/
|
||||
public static void registerItem(net.minecraft.item.Item item, String name, String modId)
|
||||
public static Item registerItem(Item item, String name, String modId)
|
||||
{
|
||||
GameData.setName(item, name, modId);
|
||||
return GameData.registerItem(item, name, modId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a block with the specified mod specific name : overrides the standard type based name
|
||||
* Register a block with the specified mod specific name
|
||||
* @param block The block to register
|
||||
* @param name The mod-unique name to register it as
|
||||
*/
|
||||
public static void registerBlock(net.minecraft.block.Block block, String name)
|
||||
public static Block registerBlock(Block block, String name)
|
||||
{
|
||||
registerBlock(block, ItemBlock.class, name);
|
||||
return registerBlock(block, ItemBlock.class, name);
|
||||
}
|
||||
/**
|
||||
* Register a block with the world, with the specified item class and block name
|
||||
@@ -134,9 +133,9 @@ public class GameRegistry
|
||||
* @param itemclass The item type to register with it
|
||||
* @param name The mod-unique name to register it with
|
||||
*/
|
||||
public static void registerBlock(net.minecraft.block.Block block, Class<? extends ItemBlock> itemclass, String name)
|
||||
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name)
|
||||
{
|
||||
registerBlock(block, itemclass, name, null);
|
||||
return registerBlock(block, itemclass, name, null);
|
||||
}
|
||||
/**
|
||||
* Register a block with the world, with the specified item class, block name and owning modId
|
||||
@@ -145,7 +144,7 @@ public class GameRegistry
|
||||
* @param name The mod-unique name to register it with
|
||||
* @param modId The modId that will own the block name. null defaults to the active modId
|
||||
*/
|
||||
public static void registerBlock(net.minecraft.block.Block block, Class<? extends ItemBlock> itemclass, String name, String modId)
|
||||
public static Block registerBlock(Block block, Class<? extends ItemBlock> itemclass, String name, String modId)
|
||||
{
|
||||
if (Loader.instance().isInState(LoaderState.CONSTRUCTING))
|
||||
{
|
||||
@@ -155,16 +154,17 @@ public class GameRegistry
|
||||
{
|
||||
assert block != null : "registerBlock: block cannot be null";
|
||||
assert itemclass != null : "registerBlock: itemclass cannot be null";
|
||||
Constructor<? extends ItemBlock> itemCtor = itemclass.getConstructor(net.minecraft.block.Block.class);
|
||||
Constructor<? extends ItemBlock> itemCtor = itemclass.getConstructor(Block.class);
|
||||
Item i = itemCtor.newInstance(block);
|
||||
GameData.registerBlock(block, name, modId);
|
||||
GameRegistry.registerItem(i, name, modId);
|
||||
return block;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.SEVERE, e, "Caught an exception during block registration");
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
blockRegistry.put(Loader.instance().activeModContainer(), (BlockProxy) block);
|
||||
}
|
||||
|
||||
public static void addRecipe(ItemStack output, Object... params)
|
||||
@@ -347,7 +347,7 @@ public class GameRegistry
|
||||
* @param name The name of the block itself
|
||||
* @return The block or null if not found
|
||||
*/
|
||||
public static net.minecraft.block.Block findBlock(String modId, String name)
|
||||
public static Block findBlock(String modId, String name)
|
||||
{
|
||||
return GameData.findBlock(modId, name);
|
||||
}
|
||||
@@ -358,7 +358,7 @@ public class GameRegistry
|
||||
* @param name The name of the item itself
|
||||
* @return The item or null if not found
|
||||
*/
|
||||
public static net.minecraft.item.Item findItem(String modId, String name)
|
||||
public static Item findItem(String modId, String name)
|
||||
{
|
||||
return GameData.findItem(modId, name);
|
||||
}
|
||||
@@ -408,6 +408,22 @@ public class GameRegistry
|
||||
this.modId = modId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public UniqueIdentifier(String string)
|
||||
{
|
||||
String[] parts = string.split(":");
|
||||
this.modId = parts[0];
|
||||
this.name = parts[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null) return false;
|
||||
if (obj.getClass() != this.getClass()) return false;
|
||||
final UniqueIdentifier other = (UniqueIdentifier) obj;
|
||||
return Objects.equal(modId, other.modId) && Objects.equal(name, other.name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +437,7 @@ public class GameRegistry
|
||||
* @param block to lookup
|
||||
* @return a {@link UniqueIdentifier} for the block or null
|
||||
*/
|
||||
public static UniqueIdentifier findUniqueIdentifierFor(net.minecraft.block.Block block)
|
||||
public static UniqueIdentifier findUniqueIdentifierFor(Block block)
|
||||
{
|
||||
return GameData.getUniqueName(block);
|
||||
}
|
||||
@@ -436,7 +452,7 @@ public class GameRegistry
|
||||
* @param item to lookup
|
||||
* @return a {@link UniqueIdentifier} for the item or null
|
||||
*/
|
||||
public static UniqueIdentifier findUniqueIdentifierFor(net.minecraft.item.Item item)
|
||||
public static UniqueIdentifier findUniqueIdentifierFor(Item item)
|
||||
{
|
||||
return GameData.getUniqueName(item);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user