Add methods to write IForgeRegistryEntry to ByteBuf (#3806)
This commit is contained in:
parent
d77033b0d0
commit
acdfe97bd6
4 changed files with 122 additions and 3 deletions
|
@ -20,9 +20,19 @@
|
|||
package net.minecraftforge.fml.common.network;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.registry.FMLControlledNamespacedRegistry;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.common.registry.IForgeRegistry;
|
||||
import net.minecraftforge.fml.common.registry.IForgeRegistryEntry;
|
||||
import net.minecraftforge.fml.common.registry.PersistentRegistryManager;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
@ -31,6 +41,9 @@ import com.google.common.base.Throwables;
|
|||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Utilities for interacting with {@link ByteBuf}.
|
||||
|
@ -219,6 +232,109 @@ public class ByteBufUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a registry entry to the stream. The serialized format is not specified and must not be relied upon.
|
||||
* Do not use this to write to a file, it is used for client-server communication only.
|
||||
* @param out the buffer to write to
|
||||
* @param entry the registry entry
|
||||
*/
|
||||
public static <T extends IForgeRegistryEntry<T>> void writeRegistryEntry(@Nonnull ByteBuf out, @Nonnull T entry)
|
||||
{
|
||||
FMLControlledNamespacedRegistry<T> registry = (FMLControlledNamespacedRegistry<T>)GameRegistry.findRegistry(entry.getRegistryType());
|
||||
writeUTF8String(out, PersistentRegistryManager.getRegistryRegistryName(registry).toString());
|
||||
writeVarInt(out, registry.getId(entry), 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a registry entry from the stream. The same format as in {@link #writeRegistryEntry(ByteBuf, IForgeRegistryEntry)} is used.
|
||||
* @param in the buffer to read from
|
||||
* @param registry the registry the entry belongs to
|
||||
* @return the read registry entry
|
||||
*/
|
||||
@Nonnull
|
||||
public static <T extends IForgeRegistryEntry<T>> T readRegistryEntry(@Nonnull ByteBuf in, @Nonnull IForgeRegistry<T> registry)
|
||||
{
|
||||
String registryName = readUTF8String(in);
|
||||
int id = readVarInt(in, 5);
|
||||
ResourceLocation expectedRegistryName = PersistentRegistryManager.getRegistryRegistryName(registry);
|
||||
if (!expectedRegistryName.toString().equals(registryName))
|
||||
{
|
||||
throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName);
|
||||
}
|
||||
T thing = ((FMLControlledNamespacedRegistry<T>)registry).getRaw(id);
|
||||
if (thing == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received.");
|
||||
}
|
||||
return thing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write multiple registry entries from the same registry to the stream. The serialized format may be more compact than using
|
||||
* {@link #writeRegistryEntry(ByteBuf, IForgeRegistryEntry)} multiple times.
|
||||
* @param out the buffer to write to
|
||||
* @param entries the entries to write
|
||||
*/
|
||||
public static <T extends IForgeRegistryEntry<T>> void writeRegistryEntries(@Nonnull ByteBuf out, @Nonnull Collection<T> entries)
|
||||
{
|
||||
writeVarInt(out, entries.size(), 5);
|
||||
|
||||
Iterator<T> it = entries.iterator();
|
||||
if (it.hasNext())
|
||||
{
|
||||
T first = it.next();
|
||||
FMLControlledNamespacedRegistry<T> registry = (FMLControlledNamespacedRegistry<T>)GameRegistry.findRegistry(first.getRegistryType());
|
||||
writeUTF8String(out, PersistentRegistryManager.getRegistryRegistryName(registry).toString());
|
||||
writeVarInt(out, registry.getId(first), 5);
|
||||
while (it.hasNext()) {
|
||||
int id = registry.getId(it.next());
|
||||
if (id == -1) {
|
||||
throw new IllegalArgumentException("Unregistered IForgeRegistryEntry in collection " + entries + ".");
|
||||
}
|
||||
writeVarInt(out, id, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read multiple registry entries from the same registries from the stream. The list of entries must have been written by
|
||||
* {@link #writeRegistryEntries(ByteBuf, Collection)}.
|
||||
* @param in the buffer to read from
|
||||
* @param registry the registry the entries belong to
|
||||
* @return the immutable list of entries
|
||||
*/
|
||||
@Nonnull
|
||||
public static <T extends IForgeRegistryEntry<T>> List<T> readRegistryEntries(@Nonnull ByteBuf in, @Nonnull IForgeRegistry<T> registry)
|
||||
{
|
||||
int size = readVarInt(in, 5);
|
||||
if (size == 0)
|
||||
{
|
||||
return ImmutableList.of();
|
||||
}
|
||||
else
|
||||
{
|
||||
String registryName = readUTF8String(in);
|
||||
ResourceLocation expectedRegistryName = PersistentRegistryManager.getRegistryRegistryName(registry);
|
||||
if (!expectedRegistryName.toString().equals(registryName))
|
||||
{
|
||||
throw new IllegalArgumentException("Registry mismatch: " + registryName + " != " + expectedRegistryName);
|
||||
}
|
||||
|
||||
ImmutableList.Builder<T> b = ImmutableList.builder();
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
int id = readVarInt(in, 5);
|
||||
T thing = ((FMLControlledNamespacedRegistry<T>)registry).getRaw(id);
|
||||
if (thing == null)
|
||||
{
|
||||
throw new IllegalArgumentException("Unknown ID " + id + " for registry " + expectedRegistryName + " received.");
|
||||
}
|
||||
b.add(thing);
|
||||
}
|
||||
return b.build();
|
||||
}
|
||||
}
|
||||
|
||||
public static String getContentDump(ByteBuf buffer)
|
||||
{
|
||||
int currentLength = buffer.readableBytes();
|
||||
|
|
|
@ -59,7 +59,7 @@ public interface IForgeRegistryEntry<V>
|
|||
@Nullable
|
||||
ResourceLocation getRegistryName();
|
||||
|
||||
Class<? super V> getRegistryType();
|
||||
Class<V> getRegistryType();
|
||||
|
||||
// Default implementation, modders who make extra items SHOULD extend this instead of Object.
|
||||
// We have to do this until we get default implementations in Java 8.
|
||||
|
@ -100,6 +100,6 @@ public interface IForgeRegistryEntry<V>
|
|||
}
|
||||
|
||||
@Override
|
||||
public final Class<? super T> getRegistryType() { return token.getRawType(); };
|
||||
public final Class<T> getRegistryType() { return (Class<T>) token.getRawType(); };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -236,6 +236,9 @@ public class PersistentRegistryManager
|
|||
return PersistentRegistry.ACTIVE.getRegistry(registryType);
|
||||
}
|
||||
|
||||
public static ResourceLocation getRegistryRegistryName(IForgeRegistry<?> registry) {
|
||||
return PersistentRegistry.ACTIVE.registries.inverse().get(registry);
|
||||
}
|
||||
|
||||
public static List<String> injectSnapshot(GameDataSnapshot snapshot, boolean injectFrozenData, boolean isLocalWorld)
|
||||
{
|
||||
|
|
|
@ -93,7 +93,7 @@ class CustomRegistryEntry implements ICustomRegistryEntry
|
|||
}
|
||||
|
||||
@Override
|
||||
public Class<? super ICustomRegistryEntry> getRegistryType()
|
||||
public Class<ICustomRegistryEntry> getRegistryType()
|
||||
{
|
||||
return ICustomRegistryEntry.class;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue