Expose the nethandler in a few places, and pull out FMLEmbeddedChannel, exposing a utility method on it.

More to come.
This commit is contained in:
Christian 2013-12-31 09:45:26 -05:00
parent a80409c59a
commit e4d2f73fe2
10 changed files with 100 additions and 30 deletions

View file

@ -31,6 +31,7 @@ import net.minecraft.crash.CrashReport;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.server.MinecraftServer;
import org.apache.logging.log4j.Level;
@ -482,6 +483,11 @@ public class FMLClientHandler implements IFMLSidedHandler
}
}
@Override
public INetHandler getClientPlayHandler()
{
return this.client.func_147114_u();
}
@Override
public NetworkManager getClientToServerNetworkManager()
{

View file

@ -24,6 +24,7 @@ import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.World;
@ -485,4 +486,9 @@ public class FMLCommonHandler
{
bus().post(new PlayerEvent.ItemSmeltedEvent(player, smelted));
}
public INetHandler getClientPlayHandler()
{
return sidedDelegate.getClientPlayHandler();
}
}

View file

@ -14,6 +14,7 @@ package cpw.mods.fml.common;
import java.util.List;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.server.MinecraftServer;
import cpw.mods.fml.relauncher.Side;
@ -45,4 +46,6 @@ public interface IFMLSidedHandler
void serverStopped();
NetworkManager getClientToServerNetworkManager();
INetHandler getClientPlayHandler();
}

View file

@ -0,0 +1,52 @@
package cpw.mods.fml.common.network;
import net.minecraft.network.Packet;
import io.netty.channel.ChannelHandler;
import io.netty.channel.embedded.EmbeddedChannel;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.network.FMLOutboundHandler.OutboundTarget;
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
import cpw.mods.fml.relauncher.Side;
/**
* Utility wrapper around {@link EmbeddedChannel}. Provides some convenience methods
* associated with the specific needs of FML network handling.
*
* @author cpw
*
*/
public 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(NetworkRegistry.FML_CHANNEL).set(channelName);
this.attr(NetworkRegistry.CHANNEL_SOURCE).set(source);
this.attr(NetworkRegistry.MOD_CONTAINER).setIfAbsent(container);
this.pipeline().addFirst("fml:outbound",new FMLOutboundHandler());
}
/**
* Utility method to generate a regular packet from a custom packet. Basically, it writes the packet through the
* outbound side which should have a message to message codec present (such as {@link FMLIndexedMessageToMessageCodec},
* transforming from mod packets to standard {@link FMLProxyPacket}s.
*
* This is mostly useful in cases where vanilla expects a packet, such as the TileEntity getDescriptionPacket.
*
* @param object The inbound packet
* @return A Packet suitable for passing to vanilla network code.
*/
public Packet generatePacketFrom(Object object)
{
OutboundTarget outboundTarget = attr(FMLOutboundHandler.FML_MESSAGETARGET).getAndSet(OutboundTarget.NOWHERE);
writeOutbound(object);
Packet pkt = (Packet) outboundMessages().poll();
attr(FMLOutboundHandler.FML_MESSAGETARGET).set(outboundTarget);
return pkt;
}
}

View file

@ -1,5 +1,6 @@
package cpw.mods.fml.common.network;
import net.minecraft.network.INetHandler;
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
import cpw.mods.fml.relauncher.Side;
@ -16,8 +17,11 @@ import cpw.mods.fml.relauncher.Side;
public class NetworkHandshakeEstablished {
public final NetworkDispatcher dispatcher;
public final Side side;
public NetworkHandshakeEstablished(NetworkDispatcher dispatcher, Side origin)
public final INetHandler netHandler;
public NetworkHandshakeEstablished(NetworkDispatcher dispatcher, INetHandler netHandler, Side origin)
{
this.netHandler = netHandler;
this.dispatcher = dispatcher;
this.side = origin;
}

View file

@ -14,7 +14,6 @@ package cpw.mods.fml.common.network;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.util.AttributeKey;
@ -25,6 +24,7 @@ import java.util.Set;
import org.apache.logging.log4j.Level;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.network.INetHandler;
import net.minecraft.world.World;
import com.google.common.collect.ImmutableMap;
@ -32,7 +32,6 @@ 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;
@ -58,6 +57,7 @@ public enum NetworkRegistry
public static final AttributeKey<String> FML_CHANNEL = new AttributeKey<String>("fml:channelName");
public static final AttributeKey<Side> CHANNEL_SOURCE = new AttributeKey<Side>("fml:channelSource");
public static final AttributeKey<ModContainer> MOD_CONTAINER = new AttributeKey<ModContainer>("fml:modContainer");
public static final AttributeKey<INetHandler> NET_HANDLER = new AttributeKey<INetHandler>("fml:netHandler");
public static final byte FML_PROTOCOL = 1;
@ -82,21 +82,6 @@ public enum NetworkRegistry
public final double range;
public final int dimension;
}
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("fml:outbound",new FMLOutboundHandler());
}
}
/**
* Create a new synchronous message channel pair based on netty.
* There are two channels created : one for each logical side (considered as the source of an outbound message)
@ -123,13 +108,13 @@ public enum NetworkRegistry
* @param handlers
* @return
*/
public EnumMap<Side,EmbeddedChannel> newChannel(String name, ChannelHandler... handlers)
public EnumMap<Side,FMLEmbeddedChannel> newChannel(String name, ChannelHandler... handlers)
{
if (channels.containsKey(name) || name.startsWith("MC|") || name.startsWith("\u0001") || name.startsWith("FML"))
{
throw new RuntimeException("That channel is already registered");
}
EnumMap<Side,EmbeddedChannel> result = Maps.newEnumMap(Side.class);
EnumMap<Side,FMLEmbeddedChannel> result = Maps.newEnumMap(Side.class);
for (Side side : Side.values())
{
@ -140,13 +125,13 @@ public enum NetworkRegistry
return result;
}
public EnumMap<Side,EmbeddedChannel> newChannel(ModContainer container, String name, ChannelHandler... handlers)
public EnumMap<Side,FMLEmbeddedChannel> 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);
EnumMap<Side,FMLEmbeddedChannel> result = Maps.newEnumMap(Side.class);
for (Side side : Side.values())
{
@ -157,7 +142,7 @@ public enum NetworkRegistry
return result;
}
public EmbeddedChannel getChannel(String name, Side source)
public FMLEmbeddedChannel getChannel(String name, Side source)
{
return channels.get(source).get(name);
}
@ -428,7 +413,7 @@ public enum NetworkRegistry
public void fireNetworkHandshake(NetworkDispatcher networkDispatcher, Side origin)
{
NetworkHandshakeEstablished handshake = new NetworkHandshakeEstablished(networkDispatcher, origin);
NetworkHandshakeEstablished handshake = new NetworkHandshakeEstablished(networkDispatcher, networkDispatcher.getNetHandler(), origin);
for (Entry<String, FMLEmbeddedChannel> channel : channels.get(origin).entrySet())
{
channel.getValue().pipeline().fireUserEventTriggered(handshake);

View file

@ -16,6 +16,7 @@ import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
@ -68,10 +69,12 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
private final ServerConfigurationManager scm;
private EntityPlayerMP player;
private ConnectionState state;
@SuppressWarnings("unused")
private ConnectionType connectionType;
private final Side side;
private final EmbeddedChannel handshakeChannel;
private NetHandlerPlayServer serverHandler;
private INetHandler netHandler;
public NetworkDispatcher(NetworkManager manager)
{
@ -134,6 +137,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
this.manager.channel().pipeline().addFirst("fml:vanilla_detector", new VanillaTimeoutWaiter());
// Need to start the handler here, so we can send custompayload packets
serverHandler = new NetHandlerPlayServer(scm.func_72365_p(), manager, player);
this.netHandler = serverHandler;
// NULL the play server here - we restore it further on. If not, there are packets sent before the login
player.field_71135_a = null;
// manually for the manager into the PLAY state, so we can send packets later
@ -143,6 +147,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
void clientListenForServerHandshake()
{
manager.func_150723_a(EnumConnectionState.PLAY);
this.netHandler = FMLCommonHandler.instance().getClientPlayHandler();
this.state = ConnectionState.AWAITING_HANDSHAKE;
}
@ -184,6 +189,11 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
}
}
public INetHandler getNetHandler()
{
return netHandler;
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception
{

View file

@ -35,6 +35,7 @@ import com.google.common.collect.Lists;
import cpw.mods.fml.common.FMLContainer;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLOutboundHandler;
import cpw.mods.fml.common.network.FMLOutboundHandler.OutboundTarget;
import cpw.mods.fml.common.network.NetworkRegistry;
@ -50,7 +51,7 @@ public class FMLNetworkHandler
{
public static final int READ_TIMEOUT = Integers.parseInt(System.getProperty("fml.readTimeout","30"),30);
public static final int LOGIN_TIMEOUT = Integers.parseInt(System.getProperty("fml.loginTimeout","600"),600);
private static EnumMap<Side, EmbeddedChannel> channelPair;
private static EnumMap<Side, FMLEmbeddedChannel> channelPair;
/* private static final int FML_HASH = Hashing.murmur3_32().hashString("FML").asInt();
private static final int PROTOCOL_VERSION = 0x2;
@ -472,11 +473,7 @@ public class FMLNetworkHandler
return null;
}
EmbeddedChannel embeddedChannel = channelPair.get(Side.SERVER);
embeddedChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(OutboundTarget.NOWHERE);
embeddedChannel.writeOutbound(new FMLMessage.EntitySpawnMessage(er, entity, er.getContainer()));
FMLProxyPacket result = (FMLProxyPacket) embeddedChannel.outboundMessages().poll();
return result;
return channelPair.get(Side.SERVER).generatePacketFrom(new FMLMessage.EntitySpawnMessage(er, entity, er.getContainer()));
}
public static String checkModList(FMLHandshakeMessage.ModList modListPacket, Side side)

View file

@ -59,6 +59,7 @@ public class FMLProxyPacket extends Packet {
{
this.netHandler = inethandler;
EmbeddedChannel internalChannel = NetworkRegistry.INSTANCE.getChannel(this.channel, this.target);
internalChannel.attr(NetworkRegistry.NET_HANDLER).set(this.netHandler);
if (internalChannel != null)
{
internalChannel.writeInbound(this);

View file

@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.StringTranslate;
@ -215,4 +216,9 @@ public class FMLServerHandler implements IFMLSidedHandler
{
throw new RuntimeException("Missing");
}
@Override
public INetHandler getClientPlayHandler()
{
return null;
}
}