A network design I like. It uses the netty embedded channel to allow mods to build channel pipelines on top of
custom payload packets.
This commit is contained in:
parent
fadff73489
commit
1c44a6c181
35 changed files with 825 additions and 203 deletions
|
@ -16,7 +16,6 @@ import java.io.File;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import net.minecraft.nbt.NBTBase;
|
import net.minecraft.nbt.NBTBase;
|
||||||
|
@ -30,16 +29,17 @@ import com.google.common.eventbus.EventBus;
|
||||||
import cpw.mods.fml.client.FMLFileResourcePack;
|
import cpw.mods.fml.client.FMLFileResourcePack;
|
||||||
import cpw.mods.fml.client.FMLFolderResourcePack;
|
import cpw.mods.fml.client.FMLFolderResourcePack;
|
||||||
import cpw.mods.fml.common.asm.FMLSanityChecker;
|
import cpw.mods.fml.common.asm.FMLSanityChecker;
|
||||||
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.ItemData;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author cpw
|
* @author cpw
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class FMLDummyContainer extends DummyModContainer implements WorldAccessContainer
|
public class FMLContainer extends DummyModContainer implements WorldAccessContainer
|
||||||
{
|
{
|
||||||
public FMLDummyContainer()
|
public FMLContainer()
|
||||||
{
|
{
|
||||||
super(new ModMetadata());
|
super(new ModMetadata());
|
||||||
ModMetadata meta = getMetadata();
|
ModMetadata meta = getMetadata();
|
||||||
|
@ -130,6 +130,7 @@ public class FMLDummyContainer extends DummyModContainer implements WorldAccessC
|
||||||
{
|
{
|
||||||
return FMLSanityChecker.fmlLocation;
|
return FMLSanityChecker.fmlLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getCustomResourcePackClass()
|
public Class<?> getCustomResourcePackClass()
|
||||||
{
|
{
|
|
@ -0,0 +1,62 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public class ByteBufUtils {
|
||||||
|
public static int varIntByteCount(int toCount)
|
||||||
|
{
|
||||||
|
return (toCount & -128) == 0 ? 1 : ((toCount & -16384) == 0 ? 2 : ((toCount & -2097152) == 0 ? 3 : ((toCount & -268435456) == 0 ? 4 : 5)));
|
||||||
|
}
|
||||||
|
public static int readVarInt(ByteBuf buf, int maxSize)
|
||||||
|
{
|
||||||
|
Validate.isTrue(maxSize < 6 && maxSize > 0, "Varint length is between 1 and 5, not %d", maxSize);
|
||||||
|
int i = 0;
|
||||||
|
int j = 0;
|
||||||
|
byte b0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
b0 = buf.readByte();
|
||||||
|
i |= (b0 & 127) << j++ * 7;
|
||||||
|
|
||||||
|
if (j > maxSize)
|
||||||
|
{
|
||||||
|
throw new RuntimeException("VarInt too big");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((b0 & 128) == 128);
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeVarInt(ByteBuf to, int toWrite, int maxSize)
|
||||||
|
{
|
||||||
|
Validate.isTrue(varIntByteCount(toWrite) < maxSize, "Integer is too big for %d bytes", maxSize);
|
||||||
|
while ((toWrite & -128) != 0)
|
||||||
|
{
|
||||||
|
to.writeByte(toWrite & 127 | 128);
|
||||||
|
toWrite >>>= 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
to.writeByte(toWrite);
|
||||||
|
}
|
||||||
|
public static String readUTF8String(ByteBuf from)
|
||||||
|
{
|
||||||
|
int len = readVarInt(from,2);
|
||||||
|
String str = from.toString(from.readerIndex(), len, Charsets.UTF_8);
|
||||||
|
from.readerIndex(from.readerIndex() + len);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void writeUTF8String(ByteBuf to, String string)
|
||||||
|
{
|
||||||
|
byte[] utf8Bytes = string.getBytes(Charsets.UTF_8);
|
||||||
|
Validate.isTrue(varIntByteCount(utf8Bytes.length) < 3, "The string is too long for this encoding.");
|
||||||
|
writeVarInt(to, utf8Bytes.length, 2);
|
||||||
|
to.writeBytes(utf8Bytes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.NetworkSide.ClientSide;
|
||||||
|
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle packets <em>from</em> the server at the client.
|
||||||
|
*
|
||||||
|
* @author cpw
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ClientSidePacketHandler implements IPacketHandler<ClientSide> {
|
||||||
|
@Override
|
||||||
|
public ClientSide side()
|
||||||
|
{
|
||||||
|
return NetworkSide.CLIENT;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Handle the custompayload packet
|
||||||
|
* @param packet
|
||||||
|
*/
|
||||||
|
public abstract void handleCustomPayload(S3FPacketCustomPayload packet);
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import gnu.trove.map.hash.TByteObjectHashMap;
|
||||||
|
import gnu.trove.map.hash.TObjectByteHashMap;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageCodec;
|
||||||
|
|
||||||
|
public abstract class FMLIndexedMessageToMessageCodec<A> extends MessageToMessageCodec<FMLProxyPacket, A> {
|
||||||
|
private TByteObjectHashMap<Class<? extends A>> discriminators = new TByteObjectHashMap<Class<? extends A>>();
|
||||||
|
private TObjectByteHashMap<Class<? extends A>> types = new TObjectByteHashMap<Class<? extends A>>();
|
||||||
|
|
||||||
|
public FMLIndexedMessageToMessageCodec<A> addDiscriminator(byte discriminator, Class<? extends A> type)
|
||||||
|
{
|
||||||
|
discriminators.put(discriminator, type);
|
||||||
|
types.put(type, discriminator);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void encodeInto(ChannelHandlerContext ctx, A msg, ByteBuf target) throws Exception;
|
||||||
|
@Override
|
||||||
|
protected final void encode(ChannelHandlerContext ctx, A msg, List<Object> out) throws Exception
|
||||||
|
{
|
||||||
|
ByteBuf buffer = Unpooled.buffer();
|
||||||
|
@SuppressWarnings("unchecked") // Stupid unnecessary cast I can't seem to kill
|
||||||
|
Class<? extends A> clazz = (Class<? extends A>) msg.getClass();
|
||||||
|
byte discriminator = types.get(clazz);
|
||||||
|
buffer.writeByte(discriminator);
|
||||||
|
encodeInto(ctx, msg, buffer);
|
||||||
|
FMLProxyPacket proxy = new FMLProxyPacket(buffer, ctx.channel().attr(NetworkRegistry.FML_CHANNEL).get());
|
||||||
|
out.add(proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf source, A msg);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception
|
||||||
|
{
|
||||||
|
ByteBuf payload = msg.payload();
|
||||||
|
byte discriminator = payload.readByte();
|
||||||
|
Class<? extends A> clazz = discriminators.get(discriminator);
|
||||||
|
A newMsg = clazz.newInstance();
|
||||||
|
decodeInto(ctx, payload.slice(), newMsg);
|
||||||
|
out.add(newMsg);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network;
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
package cpw.mods.fml.common.network;
|
|
||||||
|
|
||||||
import net.minecraft.network.INetHandler;
|
|
||||||
import net.minecraft.network.NetworkManager;
|
|
||||||
|
|
||||||
public class FMLPacketHandlerFactory implements IPacketHandlerFactory {
|
|
||||||
private static final String[] CHANNEL = new String[] { "FML" };
|
|
||||||
@Override
|
|
||||||
public String[] channels()
|
|
||||||
{
|
|
||||||
return CHANNEL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IClientSidePacketHandler makeClientPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler clientPlayHandler, String channel)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public IServerSidePacketHandler makeServerPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler serverPlayHandler)
|
|
||||||
{
|
|
||||||
// TODO Auto-generated method stub
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import net.minecraft.network.INetHandler;
|
||||||
|
import net.minecraft.network.Packet;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||||
|
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||||
|
|
||||||
|
public class FMLProxyPacket extends Packet {
|
||||||
|
final String channel;
|
||||||
|
private final ByteBuf payload;
|
||||||
|
private INetHandler netHandler;
|
||||||
|
|
||||||
|
private FMLProxyPacket(byte[] payload, String channel)
|
||||||
|
{
|
||||||
|
this(Unpooled.wrappedBuffer(payload), channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FMLProxyPacket(S3FPacketCustomPayload original)
|
||||||
|
{
|
||||||
|
this(original.func_149168_d(), original.func_149169_c());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FMLProxyPacket(C17PacketCustomPayload original)
|
||||||
|
{
|
||||||
|
this(original.func_149558_e(), original.func_149559_c());
|
||||||
|
}
|
||||||
|
|
||||||
|
public FMLProxyPacket(ByteBuf payload, String channel)
|
||||||
|
{
|
||||||
|
this.channel = channel;
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void func_148837_a(PacketBuffer packetbuffer) throws IOException
|
||||||
|
{
|
||||||
|
// NOOP - we are not built this way
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void func_148840_b(PacketBuffer packetbuffer) throws IOException
|
||||||
|
{
|
||||||
|
// NOOP - we are not built this way
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void func_148833_a(INetHandler inethandler)
|
||||||
|
{
|
||||||
|
this.netHandler = inethandler;
|
||||||
|
EmbeddedChannel internalChannel = NetworkRegistry.INSTANCE.getChannel(this.channel);
|
||||||
|
if (internalChannel != null)
|
||||||
|
{
|
||||||
|
internalChannel.writeInbound(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteBuf payload()
|
||||||
|
{
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet toC17Packet()
|
||||||
|
{
|
||||||
|
return new C17PacketCustomPayload(channel, payload.array());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Packet toS3FPacket()
|
||||||
|
{
|
||||||
|
return new S3FPacketCustomPayload(channel, payload.array());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +0,0 @@
|
||||||
package cpw.mods.fml.common.network;
|
|
||||||
|
|
||||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle packets <em>from</em> the server at the client.
|
|
||||||
*
|
|
||||||
* @author cpw
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface IClientSidePacketHandler extends IPacketHandler {
|
|
||||||
/**
|
|
||||||
* Handle the custompayload packet
|
|
||||||
* @param packet
|
|
||||||
*/
|
|
||||||
public void handleCustomPayload(S3FPacketCustomPayload packet);
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public interface IFMLMessage {
|
||||||
|
IMessageHandler<? extends IFMLMessage> handler();
|
||||||
|
void fromBytes(ByteBuf source);
|
||||||
|
void toBytes(ByteBuf target);
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IMessageHandler<M extends IFMLMessage> {
|
||||||
|
/**
|
||||||
|
* Unsigned byte for the discriminator
|
||||||
|
* @return an unsigned byte
|
||||||
|
*/
|
||||||
|
short discriminator();
|
||||||
|
Class<? extends M> messageType(short discriminator);
|
||||||
|
void receiveMessage(M message, NetworkDispatcher dispatcher);
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
package cpw.mods.fml.common.network;
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker for packet handlers
|
* Marker for packet handlers
|
||||||
* @author cpw
|
* @author cpw
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public interface IPacketHandler {
|
public interface IPacketHandler<S extends NetworkSide> {
|
||||||
|
S side();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network;
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.NetworkSide.ClientSide;
|
||||||
|
import cpw.mods.fml.common.network.NetworkSide.ServerSide;
|
||||||
import net.minecraft.network.INetHandler;
|
import net.minecraft.network.INetHandler;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ public interface IPacketHandlerFactory
|
||||||
* @param channel
|
* @param channel
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public IClientSidePacketHandler makeClientPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler clientPlayHandler, String channel);
|
public IPacketHandler<ClientSide> makeClientPacketHandler(NetworkManager manager, INetHandler clientPlayHandler, String channel);
|
||||||
/**
|
/**
|
||||||
* Return a server side packet handler for the specified channel or null if it is not handled on this side
|
* Return a server side packet handler for the specified channel or null if it is not handled on this side
|
||||||
* @param mod
|
* @param mod
|
||||||
|
@ -46,5 +48,5 @@ public interface IPacketHandlerFactory
|
||||||
* @param serverPlayHandler
|
* @param serverPlayHandler
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public IServerSidePacketHandler makeServerPacketHandler(NetworkMod mod, NetworkManager manager, INetHandler serverPlayHandler);
|
public IPacketHandler<ServerSide> makeServerPacketHandler(NetworkManager manager, INetHandler serverPlayHandler, String channel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
package cpw.mods.fml.common.network;
|
|
||||||
|
|
||||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle packets <em>from</em> the client at the server.
|
|
||||||
*
|
|
||||||
* @author cpw
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public interface IServerSidePacketHandler {
|
|
||||||
public void handleCustomPayload(C17PacketCustomPayload packet);
|
|
||||||
}
|
|
|
@ -12,39 +12,23 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network;
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import java.util.List;
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
|
||||||
import net.minecraft.inventory.Container;
|
|
||||||
import net.minecraft.network.*;
|
|
||||||
import net.minecraft.network.packet.*;
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Joiner;
|
|
||||||
import com.google.common.base.Splitter;
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.google.common.collect.ArrayListMultimap;
|
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
|
||||||
import com.google.common.collect.Sets;
|
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.Loader;
|
|
||||||
import cpw.mods.fml.common.LoaderException;
|
|
||||||
import cpw.mods.fml.common.ModContainer;
|
import cpw.mods.fml.common.ModContainer;
|
||||||
import cpw.mods.fml.common.network.packet.FMLPacket;
|
|
||||||
import cpw.mods.fml.common.network.packet.FMLPacket.Type;
|
|
||||||
import cpw.mods.fml.common.network.packet.PacketManager;
|
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,30 +38,74 @@ import cpw.mods.fml.relauncher.Side;
|
||||||
public enum NetworkRegistry
|
public enum NetworkRegistry
|
||||||
{
|
{
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
private Map<String,FMLEmbeddedChannel> channels = Maps.newConcurrentMap();
|
||||||
private Map<ModContainer, IGuiHandler> serverGuiHandlers = Maps.newHashMap();
|
private Map<ModContainer, IGuiHandler> serverGuiHandlers = Maps.newHashMap();
|
||||||
private Map<ModContainer, IGuiHandler> clientGuiHandlers = Maps.newHashMap();
|
private Map<ModContainer, IGuiHandler> clientGuiHandlers = Maps.newHashMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set in the {@link ChannelHandlerContext}
|
||||||
|
*/
|
||||||
|
public static final AttributeKey<String> FML_CHANNEL = new AttributeKey<String>("fml:channelName");
|
||||||
|
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 byte FML_PROTOCOL = 1;
|
||||||
|
|
||||||
|
private NetworkRegistry()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum OutboundTarget {
|
||||||
|
PLAYER, ALL, DIMENSION, ALLAROUNDPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FMLEmbeddedChannel extends EmbeddedChannel {
|
||||||
|
private final String channelName;
|
||||||
|
public FMLEmbeddedChannel(String channelName)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
this.channelName = channelName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmbeddedChannel newChannel(String name)
|
||||||
|
{
|
||||||
|
if (channels.containsKey(name) || name.startsWith("MC|") || name.startsWith("\u0001"))
|
||||||
|
{
|
||||||
|
throw new RuntimeException("That channel is already registered");
|
||||||
|
}
|
||||||
|
FMLEmbeddedChannel channel = new FMLEmbeddedChannel(name);
|
||||||
|
channels.put(name,channel);
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmbeddedChannel getChannel(String name)
|
||||||
|
{
|
||||||
|
return channels.get(name);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
*//**
|
||||||
* Get the packet 250 channel registration string
|
* Get the packet 250 channel registration string
|
||||||
* @return the {@link Packet250CustomPayload} channel registration string
|
* @return the {@link Packet250CustomPayload} channel registration string
|
||||||
*/
|
*//*
|
||||||
byte[] getPacketRegistry(Side side)
|
byte[] getPacketRegistry(Side side)
|
||||||
{
|
{
|
||||||
return Joiner.on('\0').join(Iterables.concat(Arrays.asList("FML"),universalPacketHandlers.keySet(), side.isClient() ? clientPacketHandlers.keySet() : serverPacketHandlers.keySet())).getBytes(Charsets.UTF_8);
|
return Joiner.on('\0').join(Iterables.concat(Arrays.asList("FML"),universalPacketHandlers.keySet(), side.isClient() ? clientPacketHandlers.keySet() : serverPacketHandlers.keySet())).getBytes(Charsets.UTF_8);
|
||||||
}
|
}
|
||||||
/**
|
*//**
|
||||||
* Is the specified channel active for the player?
|
* Is the specified channel active for the player?
|
||||||
* @param channel
|
* @param channel
|
||||||
* @param player
|
* @param player
|
||||||
*/
|
*//*
|
||||||
public boolean isChannelActive(String channel, Player player)
|
public boolean isChannelActive(String channel, Player player)
|
||||||
{
|
{
|
||||||
return activeChannels.containsEntry(player,channel);
|
return activeChannels.containsEntry(player,channel);
|
||||||
}
|
}
|
||||||
/**
|
*//**
|
||||||
* register a channel to a mod
|
* register a channel to a mod
|
||||||
* @param handler the packet handler
|
* @param handler the packet handler
|
||||||
* @param channelName the channel name to register it with
|
* @param channelName the channel name to register it with
|
||||||
*/
|
*//*
|
||||||
public void registerChannel(IPacketHandler handler, String channelName)
|
public void registerChannel(IPacketHandler handler, String channelName)
|
||||||
{
|
{
|
||||||
if (Strings.isNullOrEmpty(channelName) || (channelName!=null && channelName.length()>16))
|
if (Strings.isNullOrEmpty(channelName) || (channelName!=null && channelName.length()>16))
|
||||||
|
@ -111,37 +139,37 @@ public enum NetworkRegistry
|
||||||
serverPacketHandlers.put(channelName, handler);
|
serverPacketHandlers.put(channelName, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
*//**
|
||||||
* Activate the channel for the player
|
* Activate the channel for the player
|
||||||
* @param player
|
* @param player
|
||||||
*/
|
*//*
|
||||||
void activateChannel(Player player, String channel)
|
void activateChannel(Player player, String channel)
|
||||||
{
|
{
|
||||||
activeChannels.put(player, channel);
|
activeChannels.put(player, channel);
|
||||||
}
|
}
|
||||||
/**
|
*//**
|
||||||
* Deactivate the channel for the player
|
* Deactivate the channel for the player
|
||||||
* @param player
|
* @param player
|
||||||
* @param channel
|
* @param channel
|
||||||
*/
|
*//*
|
||||||
void deactivateChannel(Player player, String channel)
|
void deactivateChannel(Player player, String channel)
|
||||||
{
|
{
|
||||||
activeChannels.remove(player, channel);
|
activeChannels.remove(player, channel);
|
||||||
}
|
}
|
||||||
/**
|
*//**
|
||||||
* Register a connection handler
|
* Register a connection handler
|
||||||
*
|
*
|
||||||
* @param handler
|
* @param handler
|
||||||
*/
|
*//*
|
||||||
public void registerConnectionHandler(IConnectionHandler handler)
|
public void registerConnectionHandler(IConnectionHandler handler)
|
||||||
{
|
{
|
||||||
connectionHandlers.add(handler);
|
connectionHandlers.add(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
*//**
|
||||||
* Register a chat listener
|
* Register a chat listener
|
||||||
* @param listener
|
* @param listener
|
||||||
*/
|
*//*
|
||||||
public void registerChatListener(IChatListener listener)
|
public void registerChatListener(IChatListener listener)
|
||||||
{
|
{
|
||||||
chatListeners.add(listener);
|
chatListeners.add(listener);
|
||||||
|
@ -261,7 +289,7 @@ public enum NetworkRegistry
|
||||||
List<String> channels = Lists.newArrayList(Splitter.on('\0').split(request));
|
List<String> channels = Lists.newArrayList(Splitter.on('\0').split(request));
|
||||||
return channels;
|
return channels;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
public void registerGuiHandler(Object mod, IGuiHandler handler)
|
public void registerGuiHandler(Object mod, IGuiHandler handler)
|
||||||
{
|
{
|
||||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||||
|
@ -281,7 +309,7 @@ public enum NetworkRegistry
|
||||||
}
|
}
|
||||||
clientGuiHandlers.put(mc, handler);
|
clientGuiHandlers.put(mc, handler);
|
||||||
}
|
}
|
||||||
void openRemoteGui(ModContainer mc, EntityPlayerMP player, int modGuiId, World world, int x, int y, int z)
|
/* void openRemoteGui(ModContainer mc, EntityPlayerMP player, int modGuiId, World world, int x, int y, int z)
|
||||||
{
|
{
|
||||||
IGuiHandler handler = serverGuiHandlers.get(mc);
|
IGuiHandler handler = serverGuiHandlers.get(mc);
|
||||||
NetworkModHolder nmh = mc.getNetworkModHolder();
|
NetworkModHolder nmh = mc.getNetworkModHolder();
|
||||||
|
@ -301,9 +329,14 @@ public enum NetworkRegistry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void openLocalGui(ModContainer mc, EntityPlayer player, int modGuiId, World world, int x, int y, int z)
|
*/ void openLocalGui(ModContainer mc, EntityPlayer player, int modGuiId, World world, int x, int y, int z)
|
||||||
{
|
{
|
||||||
IGuiHandler handler = clientGuiHandlers.get(mc);
|
IGuiHandler handler = clientGuiHandlers.get(mc);
|
||||||
FMLCommonHandler.instance().showGuiScreen(handler.getClientGuiElement(modGuiId, player, world, x, y, z));
|
FMLCommonHandler.instance().showGuiScreen(handler.getClientGuiElement(modGuiId, player, world, x, y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasChannel(String channelName)
|
||||||
|
{
|
||||||
|
return channels.containsKey(channelName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
|
public abstract class NetworkSide {
|
||||||
|
public static final ServerSide SERVER = new ServerSide();
|
||||||
|
public static final ClientSide CLIENT = new ClientSide();
|
||||||
|
public final Side side;
|
||||||
|
NetworkSide(Side side) {
|
||||||
|
this.side = side;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ServerSide extends NetworkSide {
|
||||||
|
private ServerSide()
|
||||||
|
{
|
||||||
|
super(Side.SERVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class ClientSide extends NetworkSide {
|
||||||
|
private ClientSide()
|
||||||
|
{
|
||||||
|
super(Side.CLIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package cpw.mods.fml.common.network;
|
||||||
|
|
||||||
|
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||||
|
import cpw.mods.fml.common.network.NetworkSide.ServerSide;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle packets <em>from</em> the client at the server.
|
||||||
|
*
|
||||||
|
* @author cpw
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ServerSidePacketHandler implements IPacketHandler<ServerSide> {
|
||||||
|
@Override
|
||||||
|
public ServerSide side()
|
||||||
|
{
|
||||||
|
return NetworkSide.SERVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void handleCustomPayload(C17PacketCustomPayload packet);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import cpw.mods.fml.common.FMLLog;
|
||||||
|
import cpw.mods.fml.common.Loader;
|
||||||
|
import cpw.mods.fml.common.ModContainer;
|
||||||
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
|
enum FMLHandshakeClientState implements IHandshakeState<FMLHandshakeClientState>
|
||||||
|
{
|
||||||
|
START
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||||
|
dispatcher.clientListenForServerHandshake();
|
||||||
|
return HELLO;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
HELLO
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
FMLLog.info("Server protocol version %x", ((FMLHandshakeMessage.ServerHello)msg).protocolVersion());
|
||||||
|
ctx.writeAndFlush(new FMLHandshakeMessage.ClientHello());
|
||||||
|
ctx.writeAndFlush(new FMLHandshakeMessage.ClientModList(Loader.instance().getActiveModList()));
|
||||||
|
return COMPLETE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
COMPLETE
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeClientState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||||
|
dispatcher.continueToClientPlayState();
|
||||||
|
FMLLog.info("Client side modded connection established");
|
||||||
|
ctx.writeAndFlush(new FMLHandshakeMessage.ClientAck());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
|
public class FMLHandshakeCodec extends FMLIndexedMessageToMessageCodec<FMLHandshakeMessage> {
|
||||||
|
public FMLHandshakeCodec()
|
||||||
|
{
|
||||||
|
addDiscriminator((byte)0, FMLHandshakeMessage.ServerHello.class);
|
||||||
|
addDiscriminator((byte)1, FMLHandshakeMessage.ClientHello.class);
|
||||||
|
addDiscriminator((byte)2, FMLHandshakeMessage.ClientModList.class);
|
||||||
|
addDiscriminator((byte)3, FMLHandshakeMessage.ServerModList.class);
|
||||||
|
addDiscriminator((byte)-1, FMLHandshakeMessage.ClientAck.class);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void encodeInto(ChannelHandlerContext ctx, FMLHandshakeMessage msg, ByteBuf target) throws Exception
|
||||||
|
{
|
||||||
|
msg.toBytes(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
msg.fromBytes(source);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,145 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.Loader;
|
||||||
|
import cpw.mods.fml.common.ModContainer;
|
||||||
|
import cpw.mods.fml.common.network.ByteBufUtils;
|
||||||
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
public abstract class FMLHandshakeMessage {
|
||||||
|
public static class ServerHello extends FMLHandshakeMessage {
|
||||||
|
private byte serverProtocolVersion;
|
||||||
|
public void toBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
buffer.writeByte(NetworkRegistry.FML_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
serverProtocolVersion = buffer.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte protocolVersion()
|
||||||
|
{
|
||||||
|
return serverProtocolVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class ClientHello extends FMLHandshakeMessage {
|
||||||
|
private byte serverProtocolVersion;
|
||||||
|
public void toBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
buffer.writeByte(NetworkRegistry.FML_PROTOCOL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void fromBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
serverProtocolVersion = buffer.readByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte protocolVersion()
|
||||||
|
{
|
||||||
|
return serverProtocolVersion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static class ServerModList extends FMLHandshakeMessage {
|
||||||
|
private List<String> modTags = Lists.newArrayList();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
super.toBytes(buffer);
|
||||||
|
ByteBufUtils.writeVarInt(buffer, modTags.size(), 2);
|
||||||
|
for (String modTag: modTags)
|
||||||
|
{
|
||||||
|
ByteBufUtils.writeUTF8String(buffer, modTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
super.fromBytes(buffer);
|
||||||
|
int modCount = ByteBufUtils.readVarInt(buffer, 2);
|
||||||
|
for (int i = 0; i < modCount; i++)
|
||||||
|
{
|
||||||
|
modTags.add(ByteBufUtils.readUTF8String(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ClientModList extends FMLHandshakeMessage {
|
||||||
|
public ClientModList()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public ClientModList(List<ModContainer> modList)
|
||||||
|
{
|
||||||
|
for (ModContainer mod : modList)
|
||||||
|
{
|
||||||
|
modTags.add(new String[] { mod.getModId(), mod.getVersion() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private List<String[]> modTags = Lists.newArrayList();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
super.toBytes(buffer);
|
||||||
|
ByteBufUtils.writeVarInt(buffer, modTags.size(), 2);
|
||||||
|
for (String[] modTag: modTags)
|
||||||
|
{
|
||||||
|
ByteBufUtils.writeUTF8String(buffer, modTag[0]);
|
||||||
|
ByteBufUtils.writeUTF8String(buffer, modTag[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fromBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
super.fromBytes(buffer);
|
||||||
|
int modCount = ByteBufUtils.readVarInt(buffer, 2);
|
||||||
|
for (int i = 0; i < modCount; i++)
|
||||||
|
{
|
||||||
|
modTags.add(new String[] { ByteBufUtils.readUTF8String(buffer), ByteBufUtils.readUTF8String(buffer)});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String modListAsString()
|
||||||
|
{
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
sb.append("[ ");
|
||||||
|
for (int i = 0; i < modTags.size(); i++)
|
||||||
|
{
|
||||||
|
String[] mod = modTags.get(i);
|
||||||
|
sb.append(mod[0]).append("@").append(mod[1]);
|
||||||
|
if (i < modTags.size() - 1) sb.append(", ");
|
||||||
|
}
|
||||||
|
sb.append(" ]");
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int modListSize()
|
||||||
|
{
|
||||||
|
return modTags.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ClientAck extends FMLHandshakeMessage {
|
||||||
|
|
||||||
|
}
|
||||||
|
public void fromBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void toBytes(ByteBuf buffer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import cpw.mods.fml.common.FMLLog;
|
||||||
|
|
||||||
|
enum FMLHandshakeServerState implements IHandshakeState<FMLHandshakeServerState>
|
||||||
|
{
|
||||||
|
START
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeServerState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||||
|
dispatcher.serverInitiateHandshake();
|
||||||
|
ctx.writeAndFlush(new FMLHandshakeMessage.ServerHello());
|
||||||
|
return HELLO;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
HELLO
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeServerState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
// Hello packet first
|
||||||
|
if (msg instanceof FMLHandshakeMessage.ClientHello)
|
||||||
|
{
|
||||||
|
FMLLog.info("Client protocol version %x", ((FMLHandshakeMessage.ClientHello)msg).protocolVersion());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
FMLHandshakeMessage.ClientModList client = (FMLHandshakeMessage.ClientModList)msg;
|
||||||
|
FMLLog.info("Client joining with %d mods : %s", client.modListSize(), client.modListAsString());
|
||||||
|
ctx.writeAndFlush(new FMLHandshakeMessage.ServerModList());
|
||||||
|
return COMPLETE;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
COMPLETE
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public FMLHandshakeServerState accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg)
|
||||||
|
{
|
||||||
|
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||||
|
FMLLog.info("Server side modded connection established");
|
||||||
|
dispatcher.continueToServerPlayState();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import cpw.mods.fml.common.network.FMLProxyPacket;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||||
|
import io.netty.channel.ChannelPromise;
|
||||||
|
|
||||||
|
public class HandshakeInjector extends ChannelOutboundHandlerAdapter {
|
||||||
|
|
||||||
|
private NetworkDispatcher dispatcher;
|
||||||
|
public HandshakeInjector(NetworkDispatcher networkDispatcher)
|
||||||
|
{
|
||||||
|
this.dispatcher = networkDispatcher;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
|
||||||
|
{
|
||||||
|
if (msg instanceof FMLProxyPacket)
|
||||||
|
{
|
||||||
|
this.dispatcher.sendProxy((FMLProxyPacket) msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
|
|
||||||
|
public class HandshakeMessageHandler<S extends Enum<S> & IHandshakeState<S>> extends SimpleChannelInboundHandler<FMLHandshakeMessage> {
|
||||||
|
private static final AttributeKey<IHandshakeState<?>> STATE = new AttributeKey<IHandshakeState<?>>("fml:handshake-state");
|
||||||
|
private final AttributeKey<S> fmlHandshakeState;
|
||||||
|
private S initialState;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public HandshakeMessageHandler(Class<S> stateType)
|
||||||
|
{
|
||||||
|
fmlHandshakeState = (AttributeKey<S>) STATE;
|
||||||
|
initialState = Enum.valueOf(stateType, "START");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext ctx, FMLHandshakeMessage msg) throws Exception
|
||||||
|
{
|
||||||
|
S state = ctx.attr(fmlHandshakeState).get();
|
||||||
|
S newState = state.accept(ctx, msg);
|
||||||
|
ctx.attr(fmlHandshakeState).set(newState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelActive(ChannelHandlerContext ctx) throws Exception
|
||||||
|
{
|
||||||
|
ctx.attr(fmlHandshakeState).set(initialState);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
|
||||||
|
{
|
||||||
|
S state = ctx.attr(fmlHandshakeState).get();
|
||||||
|
S newState = state.accept(ctx, null);
|
||||||
|
ctx.attr(fmlHandshakeState).set(newState);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
|
||||||
|
public interface IHandshakeState<S> {
|
||||||
|
S accept(ChannelHandlerContext ctx, FMLHandshakeMessage msg);
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
package cpw.mods.fml.common.network;
|
package cpw.mods.fml.common.network.handshake;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.channel.SimpleChannelInboundHandler;
|
||||||
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
|
import io.netty.util.concurrent.Future;
|
||||||
|
import io.netty.util.concurrent.GenericFutureListener;
|
||||||
|
import io.netty.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import sun.net.ProgressSource.State;
|
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandler;
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
|
||||||
import io.netty.channel.SimpleChannelInboundHandler;
|
|
||||||
import io.netty.util.AttributeKey;
|
|
||||||
import io.netty.util.ReferenceCountUtil;
|
|
||||||
import io.netty.util.concurrent.ScheduledFuture;
|
|
||||||
import net.minecraft.entity.player.EntityPlayerMP;
|
import net.minecraft.entity.player.EntityPlayerMP;
|
||||||
import net.minecraft.network.EnumConnectionState;
|
import net.minecraft.network.EnumConnectionState;
|
||||||
import net.minecraft.network.NetHandlerPlayServer;
|
import net.minecraft.network.NetHandlerPlayServer;
|
||||||
|
@ -19,12 +19,12 @@ import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||||
|
import net.minecraft.network.play.server.S40PacketDisconnect;
|
||||||
import net.minecraft.server.management.ServerConfigurationManager;
|
import net.minecraft.server.management.ServerConfigurationManager;
|
||||||
|
import net.minecraft.util.ChatComponentText;
|
||||||
import com.google.common.collect.ListMultimap;
|
|
||||||
|
|
||||||
import cpw.mods.fml.common.FMLLog;
|
import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.network.packet.PacketManager;
|
import cpw.mods.fml.common.network.FMLProxyPacket;
|
||||||
|
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
|
|
||||||
public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
|
@ -55,14 +55,14 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
return net;
|
return net;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final AttributeKey<NetworkDispatcher> FML_DISPATCHER = new AttributeKey<NetworkDispatcher>("fml:dispatcher");
|
public static final AttributeKey<NetworkDispatcher> FML_DISPATCHER = new AttributeKey<NetworkDispatcher>("fml:dispatcher");
|
||||||
private static final AttributeKey<ListMultimap<String,NetworkModHolder>> FML_PACKET_HANDLERS = new AttributeKey<ListMultimap<String,NetworkModHolder>>("fml:packet_handlers");
|
|
||||||
private final NetworkManager manager;
|
private final NetworkManager manager;
|
||||||
private final ServerConfigurationManager scm;
|
private final ServerConfigurationManager scm;
|
||||||
private EntityPlayerMP player;
|
private EntityPlayerMP player;
|
||||||
private ConnectionState state;
|
private ConnectionState state;
|
||||||
private ConnectionType connectionType;
|
private ConnectionType connectionType;
|
||||||
private Side side;
|
private final Side side;
|
||||||
|
private final EmbeddedChannel handshakeChannel;
|
||||||
|
|
||||||
public NetworkDispatcher(NetworkManager manager)
|
public NetworkDispatcher(NetworkManager manager)
|
||||||
{
|
{
|
||||||
|
@ -70,6 +70,9 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.scm = null;
|
this.scm = null;
|
||||||
this.side = Side.CLIENT;
|
this.side = Side.CLIENT;
|
||||||
|
this.handshakeChannel = new EmbeddedChannel(new HandshakeInjector(this), new FMLHandshakeCodec(), new HandshakeMessageHandler<FMLHandshakeClientState>(FMLHandshakeClientState.class));
|
||||||
|
this.handshakeChannel.attr(FML_DISPATCHER).set(this);
|
||||||
|
this.handshakeChannel.attr(NetworkRegistry.FML_CHANNEL).set("FML|HS");
|
||||||
}
|
}
|
||||||
|
|
||||||
public NetworkDispatcher(NetworkManager manager, ServerConfigurationManager scm)
|
public NetworkDispatcher(NetworkManager manager, ServerConfigurationManager scm)
|
||||||
|
@ -78,6 +81,9 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.scm = scm;
|
this.scm = scm;
|
||||||
this.side = Side.SERVER;
|
this.side = Side.SERVER;
|
||||||
|
this.handshakeChannel = new EmbeddedChannel(new HandshakeInjector(this), new FMLHandshakeCodec(), new HandshakeMessageHandler<FMLHandshakeServerState>(FMLHandshakeServerState.class));
|
||||||
|
this.handshakeChannel.attr(FML_DISPATCHER).set(this);
|
||||||
|
this.handshakeChannel.attr(NetworkRegistry.FML_CHANNEL).set("FML|HS");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void serverToClientHandshake(EntityPlayerMP player)
|
public void serverToClientHandshake(EntityPlayerMP player)
|
||||||
|
@ -102,46 +108,37 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
public void handlerAdded(ChannelHandlerContext ctx) throws Exception
|
public void handlerAdded(ChannelHandlerContext ctx) throws Exception
|
||||||
{
|
{
|
||||||
this.state = ConnectionState.OPENING;
|
this.state = ConnectionState.OPENING;
|
||||||
if (side == Side.CLIENT)
|
// send ourselves as a user event, to kick the pipeline active
|
||||||
{
|
this.handshakeChannel.pipeline().fireUserEventTriggered(this);
|
||||||
clientListenForServerHandshake();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
serverInitiateHandshake();
|
|
||||||
}
|
|
||||||
this.manager.channel().config().setAutoRead(true);
|
this.manager.channel().config().setAutoRead(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void serverInitiateHandshake()
|
void serverInitiateHandshake()
|
||||||
{
|
{
|
||||||
// Send mod salutation to the client
|
// Send mod salutation to the client
|
||||||
// This will be ignored by vanilla clients
|
// This will be ignored by vanilla clients
|
||||||
this.state = ConnectionState.AWAITING_HANDSHAKE;
|
this.state = ConnectionState.AWAITING_HANDSHAKE;
|
||||||
this.manager.channel().pipeline().addFirst("fml:vanilla_detector", new VanillaTimeoutWaiter());
|
this.manager.channel().pipeline().addFirst("fml:vanilla_detector", new VanillaTimeoutWaiter());
|
||||||
this.manager.func_150725_a(new S3FPacketCustomPayload("FML", new byte[0]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clientListenForServerHandshake()
|
void clientListenForServerHandshake()
|
||||||
{
|
{
|
||||||
manager.func_150723_a(EnumConnectionState.PLAY);
|
manager.func_150723_a(EnumConnectionState.PLAY);
|
||||||
this.state = ConnectionState.AWAITING_HANDSHAKE;
|
this.state = ConnectionState.AWAITING_HANDSHAKE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void continueToClientPlayState()
|
void continueToClientPlayState()
|
||||||
{
|
{
|
||||||
this.state = ConnectionState.CONNECTED;
|
this.state = ConnectionState.CONNECTED;
|
||||||
this.connectionType = ConnectionType.MODDED;
|
this.connectionType = ConnectionType.MODDED;
|
||||||
completeClientSideConnection();
|
completeClientSideConnection();
|
||||||
// Send modded ack to server
|
|
||||||
this.manager.func_150725_a(new C17PacketCustomPayload("FML", new byte[0]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void completeClientSideConnection()
|
private void completeClientSideConnection()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private void continueToServerPlayState()
|
void continueToServerPlayState()
|
||||||
{
|
{
|
||||||
this.state = ConnectionState.CONNECTED;
|
this.state = ConnectionState.CONNECTED;
|
||||||
this.connectionType = ConnectionType.MODDED;
|
this.connectionType = ConnectionType.MODDED;
|
||||||
|
@ -161,16 +158,16 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
boolean handled = false;
|
boolean handled = false;
|
||||||
if (msg instanceof C17PacketCustomPayload)
|
if (msg instanceof C17PacketCustomPayload)
|
||||||
{
|
{
|
||||||
handled = handleServerSideCustomPacket((C17PacketCustomPayload) msg);
|
handled = handleServerSideCustomPacket((C17PacketCustomPayload) msg, ctx);
|
||||||
}
|
}
|
||||||
else if (msg instanceof S3FPacketCustomPayload)
|
else if (msg instanceof S3FPacketCustomPayload)
|
||||||
{
|
{
|
||||||
handled = handleClientSideCustomPacket((S3FPacketCustomPayload)msg);
|
handled = handleClientSideCustomPacket((S3FPacketCustomPayload)msg, ctx);
|
||||||
}
|
}
|
||||||
else if (state != ConnectionState.CONNECTED)
|
else if (state != ConnectionState.CONNECTED)
|
||||||
{
|
{
|
||||||
FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla");
|
FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla");
|
||||||
handleVanillaConnection();
|
kickVanilla();
|
||||||
}
|
}
|
||||||
if (!handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
|
@ -184,46 +181,59 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
if (evt instanceof ConnectionType && side == Side.SERVER)
|
if (evt instanceof ConnectionType && side == Side.SERVER)
|
||||||
{
|
{
|
||||||
FMLLog.info("Timeout occurred, assuming a vanilla client");
|
FMLLog.info("Timeout occurred, assuming a vanilla client");
|
||||||
handleVanillaConnection();
|
kickVanilla();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleVanillaConnection()
|
private void kickVanilla()
|
||||||
{
|
{
|
||||||
state = ConnectionState.CONNECTED;
|
final ChatComponentText chatcomponenttext = new ChatComponentText("This is modded. No modded response received. Bye!");
|
||||||
connectionType = ConnectionType.VANILLA;
|
manager.func_150725_a(new S40PacketDisconnect(chatcomponenttext), new GenericFutureListener<Future<?>>()
|
||||||
if (side == Side.CLIENT)
|
|
||||||
{
|
{
|
||||||
completeClientSideConnection();
|
public void operationComplete(Future<?> result)
|
||||||
}
|
{
|
||||||
else
|
manager.func_150718_a(chatcomponenttext);
|
||||||
{
|
}
|
||||||
completeServerSideConnection();
|
});
|
||||||
}
|
manager.channel().config().setAutoRead(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleClientSideCustomPacket(S3FPacketCustomPayload msg)
|
private boolean handleClientSideCustomPacket(S3FPacketCustomPayload msg, ChannelHandlerContext context)
|
||||||
{
|
{
|
||||||
if ("FML".equals(msg.func_149169_c()))
|
String channelName = msg.func_149169_c();
|
||||||
|
if ("FML|HS".equals(channelName))
|
||||||
{
|
{
|
||||||
continueToClientPlayState();
|
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||||
FMLLog.info("Client side modded connection established");
|
handshakeChannel.writeInbound(proxy);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (NetworkRegistry.INSTANCE.hasChannel(channelName))
|
||||||
|
{
|
||||||
|
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||||
|
context.fireChannelRead(proxy);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleServerSideCustomPacket(C17PacketCustomPayload msg)
|
private boolean handleServerSideCustomPacket(C17PacketCustomPayload msg, ChannelHandlerContext context)
|
||||||
{
|
{
|
||||||
if (state == ConnectionState.AWAITING_HANDSHAKE)
|
if (state == ConnectionState.AWAITING_HANDSHAKE)
|
||||||
{
|
{
|
||||||
this.manager.channel().pipeline().remove("fml:vanilla_detector");
|
this.manager.channel().pipeline().remove("fml:vanilla_detector");
|
||||||
state = ConnectionState.HANDSHAKING;
|
state = ConnectionState.HANDSHAKING;
|
||||||
}
|
}
|
||||||
if ("FML".equals(msg.func_149559_c()))
|
String channelName = msg.func_149559_c();
|
||||||
|
if ("FML|HS".equals(channelName))
|
||||||
{
|
{
|
||||||
FMLLog.info("Server side modded connection established");
|
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||||
continueToServerPlayState();
|
handshakeChannel.writeInbound(proxy);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (NetworkRegistry.INSTANCE.hasChannel(channelName))
|
||||||
|
{
|
||||||
|
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||||
|
context.fireChannelRead(proxy);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -247,7 +257,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}, 10, TimeUnit.SECONDS);
|
}, 10, TimeUnit.HOURS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -256,4 +266,20 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> {
|
||||||
future.cancel(true);
|
future.cancel(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback from the networkmanager
|
||||||
|
* @param fmlProxyPacket
|
||||||
|
*/
|
||||||
|
public void dispatch(FMLProxyPacket fmlProxyPacket)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendProxy(FMLProxyPacket msg)
|
||||||
|
{
|
||||||
|
if (side == Side.CLIENT)
|
||||||
|
manager.func_150725_a(msg.toC17Packet());
|
||||||
|
else
|
||||||
|
manager.func_150725_a(msg.toS3FPacket());
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ import com.google.common.io.ByteStreams;
|
||||||
import cpw.mods.fml.common.FMLCommonHandler;
|
import cpw.mods.fml.common.FMLCommonHandler;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
|
|
||||||
public class EntitySpawnAdjustmentPacket extends FMLPacket
|
public class EntitySpawnAdjustmentPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
|
|
||||||
public EntitySpawnAdjustmentPacket()
|
public EntitySpawnAdjustmentPacket()
|
||||||
|
@ -47,7 +47,7 @@ public class EntitySpawnAdjustmentPacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
entityId = dat.readInt();
|
entityId = dat.readInt();
|
||||||
|
|
|
@ -39,7 +39,7 @@ import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration;
|
||||||
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
import cpw.mods.fml.common.registry.IThrowableEntity;
|
import cpw.mods.fml.common.registry.IThrowableEntity;
|
||||||
|
|
||||||
public class EntitySpawnPacket extends FMLPacket
|
public class EntitySpawnPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
|
|
||||||
public int networkId;
|
public int networkId;
|
||||||
|
@ -142,7 +142,7 @@ public class EntitySpawnPacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
networkId = dat.readInt();
|
networkId = dat.readInt();
|
||||||
|
|
|
@ -30,7 +30,7 @@ import cpw.mods.fml.common.FMLLog;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkException;
|
import cpw.mods.fml.common.network.FMLNetworkException;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
|
|
||||||
public abstract class FMLPacket
|
public abstract class FMLOldPacket
|
||||||
{
|
{
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
@ -68,20 +68,20 @@ public abstract class FMLPacket
|
||||||
MOD_IDMAP(ModIdMapPacket.class, true);
|
MOD_IDMAP(ModIdMapPacket.class, true);
|
||||||
|
|
||||||
|
|
||||||
private Class<? extends FMLPacket> packetType;
|
private Class<? extends FMLOldPacket> packetType;
|
||||||
private boolean isMultipart;
|
private boolean isMultipart;
|
||||||
private String executorClass;
|
private String executorClass;
|
||||||
|
|
||||||
private ConcurrentMap<INetworkManager, FMLPacket> partTracker;
|
private ConcurrentMap<INetworkManager, FMLOldPacket> partTracker;
|
||||||
|
|
||||||
private Type(Class<? extends FMLPacket> clazz, boolean isMultipart, String executorClass)
|
private Type(Class<? extends FMLOldPacket> clazz, boolean isMultipart, String executorClass)
|
||||||
{
|
{
|
||||||
this.packetType = clazz;
|
this.packetType = clazz;
|
||||||
this.isMultipart = isMultipart;
|
this.isMultipart = isMultipart;
|
||||||
this.executorClass = executorClass;
|
this.executorClass = executorClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
FMLPacket make()
|
FMLOldPacket make()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -100,7 +100,7 @@ public abstract class FMLPacket
|
||||||
return isMultipart;
|
return isMultipart;
|
||||||
}
|
}
|
||||||
|
|
||||||
private FMLPacket findCurrentPart(NetworkManager network)
|
private FMLOldPacket findCurrentPart(NetworkManager network)
|
||||||
{
|
{
|
||||||
if (partTracker == null)
|
if (partTracker == null)
|
||||||
{
|
{
|
||||||
|
@ -138,5 +138,5 @@ public abstract class FMLPacket
|
||||||
|
|
||||||
abstract byte[] generatePacketData(Object... data);
|
abstract byte[] generatePacketData(Object... data);
|
||||||
|
|
||||||
abstract FMLPacket consumePacketData(byte[] data);
|
abstract FMLOldPacket consumePacketData(byte[] data);
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network.packet;
|
package cpw.mods.fml.common.network.packet;
|
||||||
|
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_IDMAP;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_IDMAP;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -37,7 +37,7 @@ import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
import cpw.mods.fml.common.registry.ItemData;
|
import cpw.mods.fml.common.registry.ItemData;
|
||||||
|
|
||||||
public class ModIdMapPacket extends FMLPacket {
|
public class ModIdMapPacket extends FMLOldPacket {
|
||||||
private byte[][] partials;
|
private byte[][] partials;
|
||||||
|
|
||||||
public ModIdMapPacket()
|
public ModIdMapPacket()
|
||||||
|
@ -63,7 +63,7 @@ public class ModIdMapPacket extends FMLPacket {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput bdi = ByteStreams.newDataInput(data);
|
ByteArrayDataInput bdi = ByteStreams.newDataInput(data);
|
||||||
int chunkIdx = UnsignedBytes.toInt(bdi.readByte());
|
int chunkIdx = UnsignedBytes.toInt(bdi.readByte());
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network.packet;
|
package cpw.mods.fml.common.network.packet;
|
||||||
|
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_IDENTIFIERS;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_IDENTIFIERS;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -29,7 +29,7 @@ import com.google.common.io.ByteStreams;
|
||||||
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
import cpw.mods.fml.common.network.NetworkModHolder;
|
import cpw.mods.fml.common.network.NetworkModHolder;
|
||||||
|
|
||||||
public class ModIdentifiersPacket extends FMLPacket
|
public class ModIdentifiersPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
|
|
||||||
private Map<String, Integer> modIds = Maps.newHashMap();
|
private Map<String, Integer> modIds = Maps.newHashMap();
|
||||||
|
@ -57,7 +57,7 @@ public class ModIdentifiersPacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
int listSize = dat.readInt();
|
int listSize = dat.readInt();
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network.packet;
|
package cpw.mods.fml.common.network.packet;
|
||||||
|
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_LIST_REQUEST;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_LIST_REQUEST;
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_LIST_RESPONSE;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_LIST_RESPONSE;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -37,7 +37,7 @@ import cpw.mods.fml.common.network.FMLNetworkHandler;
|
||||||
import cpw.mods.fml.common.network.NetworkModHolder;
|
import cpw.mods.fml.common.network.NetworkModHolder;
|
||||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||||
|
|
||||||
public class ModListRequestPacket extends FMLPacket
|
public class ModListRequestPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
private List<String> sentModList;
|
private List<String> sentModList;
|
||||||
private byte compatibilityLevel;
|
private byte compatibilityLevel;
|
||||||
|
@ -62,7 +62,7 @@ public class ModListRequestPacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
sentModList = Lists.newArrayList();
|
sentModList = Lists.newArrayList();
|
||||||
ByteArrayDataInput in = ByteStreams.newDataInput(data);
|
ByteArrayDataInput in = ByteStreams.newDataInput(data);
|
||||||
|
@ -87,7 +87,7 @@ public class ModListRequestPacket extends FMLPacket
|
||||||
* This packet is executed on the client to evaluate the server's mod list against
|
* This packet is executed on the client to evaluate the server's mod list against
|
||||||
* the client
|
* the client
|
||||||
*
|
*
|
||||||
* @see cpw.mods.fml.common.network.packet.FMLPacket#execute(INetworkManager, FMLNetworkHandler, NetHandler, String)
|
* @see cpw.mods.fml.common.network.packet.FMLOldPacket#execute(INetworkManager, FMLNetworkHandler, NetHandler, String)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void execute(INetworkManager mgr, FMLNetworkHandler handler, NetHandler netHandler, String userName)
|
public void execute(INetworkManager mgr, FMLNetworkHandler handler, NetHandler netHandler, String userName)
|
||||||
|
@ -127,6 +127,6 @@ public class ModListRequestPacket extends FMLPacket
|
||||||
FMLLog.fine("The server has compatibility level %d", compatibilityLevel);
|
FMLLog.fine("The server has compatibility level %d", compatibilityLevel);
|
||||||
FMLCommonHandler.instance().getSidedDelegate().setClientCompatibilityLevel(compatibilityLevel);
|
FMLCommonHandler.instance().getSidedDelegate().setClientCompatibilityLevel(compatibilityLevel);
|
||||||
|
|
||||||
mgr.func_74429_a(PacketDispatcher.getPacket("FML", FMLPacket.makePacket(MOD_LIST_RESPONSE, modVersions, missingMods)));
|
mgr.func_74429_a(PacketDispatcher.getPacket("FML", FMLOldPacket.makePacket(MOD_LIST_RESPONSE, modVersions, missingMods)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
|
|
||||||
package cpw.mods.fml.common.network.packet;
|
package cpw.mods.fml.common.network.packet;
|
||||||
|
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_IDENTIFIERS;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_IDENTIFIERS;
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_IDMAP;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_IDMAP;
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_LIST_RESPONSE;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_LIST_RESPONSE;
|
||||||
import static cpw.mods.fml.common.network.packet.FMLPacket.Type.MOD_MISSING;
|
import static cpw.mods.fml.common.network.packet.FMLOldPacket.Type.MOD_MISSING;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -42,7 +42,7 @@ import cpw.mods.fml.common.network.NetworkModHolder;
|
||||||
import cpw.mods.fml.common.network.PacketDispatcher;
|
import cpw.mods.fml.common.network.PacketDispatcher;
|
||||||
import cpw.mods.fml.common.registry.GameData;
|
import cpw.mods.fml.common.registry.GameData;
|
||||||
|
|
||||||
public class ModListResponsePacket extends FMLPacket
|
public class ModListResponsePacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
private Map<String,String> modVersions;
|
private Map<String,String> modVersions;
|
||||||
private List<String> missingMods;
|
private List<String> missingMods;
|
||||||
|
@ -75,7 +75,7 @@ public class ModListResponsePacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
int versionListSize = dat.readInt();
|
int versionListSize = dat.readInt();
|
||||||
|
@ -128,7 +128,7 @@ public class ModListResponsePacket extends FMLPacket
|
||||||
pkt.field_73630_a = "FML";
|
pkt.field_73630_a = "FML";
|
||||||
if (missingClientMods.size()>0 || versionIncorrectMods.size() > 0)
|
if (missingClientMods.size()>0 || versionIncorrectMods.size() > 0)
|
||||||
{
|
{
|
||||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_MISSING, missingClientMods, versionIncorrectMods);
|
pkt.field_73629_c = FMLOldPacket.makePacket(MOD_MISSING, missingClientMods, versionIncorrectMods);
|
||||||
Logger.getLogger("Minecraft").info(String.format("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods));
|
Logger.getLogger("Minecraft").info(String.format("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods));
|
||||||
FMLLog.info("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods);
|
FMLLog.info("User %s connection failed: missing %s, bad versions %s", userName, missingClientMods, versionIncorrectMods);
|
||||||
// Mark this as bad
|
// Mark this as bad
|
||||||
|
@ -138,14 +138,14 @@ public class ModListResponsePacket extends FMLPacket
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pkt.field_73629_c = FMLPacket.makePacket(MOD_IDENTIFIERS, netHandler);
|
pkt.field_73629_c = FMLOldPacket.makePacket(MOD_IDENTIFIERS, netHandler);
|
||||||
Logger.getLogger("Minecraft").info(String.format("User %s connecting with mods %s", userName, modVersions.keySet()));
|
Logger.getLogger("Minecraft").info(String.format("User %s connecting with mods %s", userName, modVersions.keySet()));
|
||||||
FMLLog.info("User %s connecting with mods %s", userName, modVersions.keySet());
|
FMLLog.info("User %s connecting with mods %s", userName, modVersions.keySet());
|
||||||
pkt.field_73628_b = pkt.field_73629_c.length;
|
pkt.field_73628_b = pkt.field_73629_c.length;
|
||||||
network.func_74429_a(pkt);
|
network.func_74429_a(pkt);
|
||||||
NBTTagList itemList = new NBTTagList();
|
NBTTagList itemList = new NBTTagList();
|
||||||
GameData.writeItemData(itemList);
|
GameData.writeItemData(itemList);
|
||||||
byte[][] registryPackets = FMLPacket.makePacketSet(MOD_IDMAP, itemList);
|
byte[][] registryPackets = FMLOldPacket.makePacketSet(MOD_IDMAP, itemList);
|
||||||
for (int i = 0; i < registryPackets.length; i++)
|
for (int i = 0; i < registryPackets.length; i++)
|
||||||
{
|
{
|
||||||
network.func_74429_a(PacketDispatcher.getPacket("FML", registryPackets[i]));
|
network.func_74429_a(PacketDispatcher.getPacket("FML", registryPackets[i]));
|
||||||
|
|
|
@ -32,7 +32,7 @@ import cpw.mods.fml.common.versioning.VersionRange;
|
||||||
import net.minecraft.network.INetworkManager;
|
import net.minecraft.network.INetworkManager;
|
||||||
import net.minecraft.network.packet.NetHandler;
|
import net.minecraft.network.packet.NetHandler;
|
||||||
|
|
||||||
public class ModMissingPacket extends FMLPacket
|
public class ModMissingPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
|
|
||||||
private List<ModData> missing;
|
private List<ModData> missing;
|
||||||
|
@ -76,7 +76,7 @@ public class ModMissingPacket extends FMLPacket
|
||||||
String modVersion;
|
String modVersion;
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
int missingLen = dat.readInt();
|
int missingLen = dat.readInt();
|
||||||
|
|
|
@ -16,7 +16,7 @@ import com.google.common.io.ByteArrayDataInput;
|
||||||
import com.google.common.io.ByteArrayDataOutput;
|
import com.google.common.io.ByteArrayDataOutput;
|
||||||
import com.google.common.io.ByteStreams;
|
import com.google.common.io.ByteStreams;
|
||||||
|
|
||||||
public class OpenGuiPacket extends FMLPacket
|
public class OpenGuiPacket extends FMLOldPacket
|
||||||
{
|
{
|
||||||
int windowId;
|
int windowId;
|
||||||
int networkId;
|
int networkId;
|
||||||
|
@ -39,7 +39,7 @@ public class OpenGuiPacket extends FMLPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FMLPacket consumePacketData(byte[] data)
|
public FMLOldPacket consumePacketData(byte[] data)
|
||||||
{
|
{
|
||||||
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
ByteArrayDataInput dat = ByteStreams.newDataInput(data);
|
||||||
windowId = dat.readInt();
|
windowId = dat.readInt();
|
||||||
|
|
|
@ -11,40 +11,41 @@ import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.primitives.UnsignedBytes;
|
import com.google.common.primitives.UnsignedBytes;
|
||||||
|
|
||||||
import cpw.mods.fml.common.network.NetworkDispatcher;
|
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
|
||||||
import cpw.mods.fml.common.network.packet.FMLPacket.Type;
|
import cpw.mods.fml.common.network.packet.FMLOldPacket.Type;
|
||||||
|
|
||||||
public enum PacketManager {
|
public enum PacketManager {
|
||||||
INSTANCE;
|
INSTANCE;
|
||||||
|
|
||||||
private Map<Class<? extends FMLPacket>, PacketExecutor<?,?>> packetExecutors = Maps.newHashMap();
|
private Map<Class<? extends FMLOldPacket>, PacketExecutor<?,?>> packetExecutors = Maps.newHashMap();
|
||||||
|
|
||||||
|
|
||||||
public C17PacketCustomPayload makeGuiPacket(int windowId, int i, int modGuiId, int x, int y, int z)
|
public C17PacketCustomPayload makeGuiPacket(int windowId, int i, int modGuiId, int x, int y, int z)
|
||||||
{
|
{
|
||||||
byte[] data = FMLPacket.makePacket(Type.GUIOPEN, windowId, i, modGuiId, x, y, z);
|
byte[] data = FMLOldPacket.makePacket(Type.GUIOPEN, windowId, i, modGuiId, x, y, z);
|
||||||
C17PacketCustomPayload packet = new C17PacketCustomPayload("FML", data);
|
C17PacketCustomPayload packet = new C17PacketCustomPayload("FML", data);
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public FMLPacket readPacket(NetworkDispatcher dispatcher, C17PacketCustomPayload clientSentPacket)
|
public FMLOldPacket readPacket(NetworkDispatcher dispatcher, C17PacketCustomPayload clientSentPacket)
|
||||||
{
|
{
|
||||||
byte[] payload = clientSentPacket.func_149558_e();
|
byte[] payload = clientSentPacket.func_149558_e();
|
||||||
return buildPacket(dispatcher, payload);
|
return buildPacket(dispatcher, payload);
|
||||||
}
|
}
|
||||||
public FMLPacket readPacket(NetworkDispatcher dispatcher, S3FPacketCustomPayload serverSentPacket)
|
|
||||||
|
public FMLOldPacket readPacket(NetworkDispatcher dispatcher, S3FPacketCustomPayload serverSentPacket)
|
||||||
{
|
{
|
||||||
byte[] payload = serverSentPacket.func_149168_d();
|
byte[] payload = serverSentPacket.func_149168_d();
|
||||||
return buildPacket(dispatcher, payload);
|
return buildPacket(dispatcher, payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
private FMLPacket buildPacket(NetworkDispatcher dispatcher, byte[] payload)
|
private FMLOldPacket buildPacket(NetworkDispatcher dispatcher, byte[] payload)
|
||||||
{
|
{
|
||||||
int type = UnsignedBytes.toInt(payload[0]);
|
int type = UnsignedBytes.toInt(payload[0]);
|
||||||
Type eType = Type.values()[type];
|
Type eType = Type.values()[type];
|
||||||
FMLPacket pkt;
|
FMLOldPacket pkt;
|
||||||
if (eType.isMultipart())
|
if (eType.isMultipart())
|
||||||
{
|
{
|
||||||
pkt = eType.findCurrentPart(network);
|
pkt = eType.findCurrentPart(network);
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class FMLCorePlugin implements IFMLLoadingPlugin
|
||||||
@Override
|
@Override
|
||||||
public String getModContainerClass()
|
public String getModContainerClass()
|
||||||
{
|
{
|
||||||
return "cpw.mods.fml.common.FMLDummyContainer";
|
return "cpw.mods.fml.common.FMLContainer";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in a new issue