Add in a simple(ish) event driven network handling system. Register using newEventDrivenChannel
and you'll get a simple network handler that will fire events at the subscriber(s) of your choice, whenever a packet is received. You'll also get some convenience methods for sending to things.
This commit is contained in:
parent
7a8eda46c4
commit
670f76accd
7 changed files with 212 additions and 11 deletions
|
@ -0,0 +1,88 @@
|
|||
package cpw.mods.fml.common.network;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.EnumMap;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.network.NetHandlerPlayServer;
|
||||
import cpw.mods.fml.common.eventhandler.EventBus;
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class FMLEventChannel {
|
||||
private EnumMap<Side, FMLEmbeddedChannel> channels;
|
||||
private EventBus eventBus;
|
||||
|
||||
FMLEventChannel(String name)
|
||||
{
|
||||
this.channels = NetworkRegistry.INSTANCE.newChannel(name, new NetworkEventFiringHandler(this));
|
||||
this.eventBus = new EventBus();
|
||||
}
|
||||
|
||||
public void register(Object object)
|
||||
{
|
||||
this.eventBus.register(object);
|
||||
}
|
||||
|
||||
public void unregister(Object object)
|
||||
{
|
||||
this.eventBus.unregister(object);
|
||||
}
|
||||
|
||||
void fireRead(FMLProxyPacket msg, ChannelHandlerContext ctx)
|
||||
{
|
||||
FMLNetworkEvent.CustomPacketEvent<?> event = null;
|
||||
if (msg.handler() instanceof NetHandlerPlayClient)
|
||||
{
|
||||
NetHandlerPlayClient client = (NetHandlerPlayClient) msg.handler();
|
||||
event = new FMLNetworkEvent.ClientCustomPacketEvent(client.func_147298_b(), msg);
|
||||
}
|
||||
else if (msg.handler() instanceof NetHandlerPlayServer)
|
||||
{
|
||||
NetHandlerPlayServer server = (NetHandlerPlayServer) msg.handler();
|
||||
event = new FMLNetworkEvent.ServerCustomPacketEvent(server.func_147362_b(), msg);
|
||||
}
|
||||
if (event != null)
|
||||
{
|
||||
this.eventBus.post(event);
|
||||
if (event.reply != null)
|
||||
{
|
||||
ctx.channel().attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.REPLY);
|
||||
ctx.writeAndFlush(event.reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendToAll(FMLProxyPacket pkt)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt);
|
||||
}
|
||||
|
||||
public void sendTo(FMLProxyPacket pkt, EntityPlayerMP player)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt);
|
||||
}
|
||||
|
||||
public void sendToAllAround(FMLProxyPacket pkt, NetworkRegistry.TargetPoint point)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt);
|
||||
}
|
||||
|
||||
public void sendToDimension(FMLProxyPacket pkt, int dimensionId)
|
||||
{
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.DIMENSION);
|
||||
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(dimensionId);
|
||||
channels.get(Side.SERVER).writeAndFlush(pkt);
|
||||
}
|
||||
|
||||
public void sendToServer(FMLProxyPacket pkt)
|
||||
{
|
||||
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER);
|
||||
channels.get(Side.CLIENT).writeAndFlush(pkt);
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import net.minecraft.network.NetworkManager;
|
|||
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||
import net.minecraft.network.play.INetHandlerPlayServer;
|
||||
import cpw.mods.fml.common.eventhandler.Event;
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class FMLNetworkEvent<T extends INetHandler> extends Event {
|
||||
public final T handler;
|
||||
|
@ -49,4 +51,49 @@ public class FMLNetworkEvent<T extends INetHandler> extends Event {
|
|||
super((INetHandlerPlayClient) manager.func_150729_e(), INetHandlerPlayClient.class, manager);
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class CustomPacketEvent<S extends INetHandler> extends FMLNetworkEvent<S> {
|
||||
/**
|
||||
* The packet that generated the event
|
||||
*/
|
||||
public final FMLProxyPacket packet;
|
||||
|
||||
/**
|
||||
* Set this packet to reply to the originator
|
||||
*/
|
||||
public FMLProxyPacket reply;
|
||||
CustomPacketEvent(S thing, Class<S> type, NetworkManager manager, FMLProxyPacket packet)
|
||||
{
|
||||
super(thing, type, manager);
|
||||
this.packet = packet;
|
||||
}
|
||||
|
||||
public abstract Side side();
|
||||
}
|
||||
|
||||
public static class ClientCustomPacketEvent extends CustomPacketEvent<INetHandlerPlayClient> {
|
||||
public ClientCustomPacketEvent(NetworkManager manager, FMLProxyPacket packet)
|
||||
{
|
||||
super((INetHandlerPlayClient) manager.func_150729_e(), INetHandlerPlayClient.class, manager, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Side side()
|
||||
{
|
||||
return Side.CLIENT;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ServerCustomPacketEvent extends CustomPacketEvent<INetHandlerPlayServer> {
|
||||
public ServerCustomPacketEvent(NetworkManager manager, FMLProxyPacket packet)
|
||||
{
|
||||
super((INetHandlerPlayServer) manager.func_150729_e(), INetHandlerPlayServer.class, manager, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Side side()
|
||||
{
|
||||
return Side.SERVER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,12 +31,26 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
},
|
||||
REPLY
|
||||
{
|
||||
@Override
|
||||
public void validateArgs(Object args)
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
return ImmutableList.of(packet.getDispatcher());
|
||||
}
|
||||
},
|
||||
PLAYER
|
||||
{
|
||||
@Override
|
||||
|
@ -48,7 +62,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
}
|
||||
}
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
EntityPlayerMP player = (EntityPlayerMP) args;
|
||||
NetworkDispatcher dispatcher = player.field_71135_a.field_147371_a.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
|
@ -63,7 +77,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.<NetworkDispatcher>builder();
|
||||
for (EntityPlayerMP player : (List<EntityPlayerMP>)FMLCommonHandler.instance().getMinecraftServerInstance().func_71203_ab().field_72404_b)
|
||||
|
@ -86,7 +100,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
int dimension = (Integer)args;
|
||||
ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.<NetworkDispatcher>builder();
|
||||
|
@ -114,7 +128,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
TargetPoint tp = (TargetPoint)args;
|
||||
ImmutableList.Builder<NetworkDispatcher> builder = ImmutableList.<NetworkDispatcher>builder();
|
||||
|
@ -144,7 +158,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
throw new RuntimeException("Cannot set TOSERVER as a target on the server");
|
||||
}
|
||||
@Override
|
||||
public List<NetworkDispatcher> selectNetworks(Object args)
|
||||
public List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet)
|
||||
{
|
||||
NetworkManager clientConnection = FMLCommonHandler.instance().getClientToServerNetworkManager();
|
||||
return clientConnection == null ? ImmutableList.<NetworkDispatcher>of() : ImmutableList.of(clientConnection.channel().attr(NetworkDispatcher.FML_DISPATCHER).get());
|
||||
|
@ -152,7 +166,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
};
|
||||
|
||||
public abstract void validateArgs(Object args);
|
||||
public abstract List<NetworkDispatcher> selectNetworks(Object args);
|
||||
public abstract List<NetworkDispatcher> selectNetworks(Object args, ChannelHandlerContext context, FMLProxyPacket packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -162,6 +176,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
{
|
||||
return;
|
||||
}
|
||||
FMLProxyPacket pkt = (FMLProxyPacket) msg;
|
||||
OutboundTarget outboundTarget;
|
||||
Object args = null;
|
||||
NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
|
||||
|
@ -182,7 +197,7 @@ public class FMLOutboundHandler extends ChannelOutboundHandlerAdapter {
|
|||
|
||||
outboundTarget.validateArgs(args);
|
||||
}
|
||||
List<NetworkDispatcher> dispatchers = outboundTarget.selectNetworks(args);
|
||||
List<NetworkDispatcher> dispatchers = outboundTarget.selectNetworks(args, ctx, pkt);
|
||||
|
||||
// This will drop the messages into the output queue at the embedded channel
|
||||
if (dispatchers == null)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
package cpw.mods.fml.common.network;
|
||||
|
||||
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
|
||||
/**
|
||||
* Use this handler as the only thing in your channel, to receive network events
|
||||
* whenever your channel receives a message.
|
||||
* Note: it will not forward on to other handlers.
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class NetworkEventFiringHandler extends SimpleChannelInboundHandler<FMLProxyPacket> {
|
||||
private FMLEventChannel eventChannel;
|
||||
|
||||
NetworkEventFiringHandler(FMLEventChannel fmlEventChannel)
|
||||
{
|
||||
this.eventChannel = fmlEventChannel;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FMLProxyPacket msg) throws Exception
|
||||
{
|
||||
eventChannel.fireRead(msg,ctx);
|
||||
}
|
||||
|
||||
}
|
|
@ -127,6 +127,10 @@ public enum NetworkRegistry
|
|||
return result;
|
||||
}
|
||||
|
||||
public FMLEventChannel newEventDrivenChannel(String name)
|
||||
{
|
||||
return new FMLEventChannel(name);
|
||||
}
|
||||
/**
|
||||
* INTERNAL Create a new channel pair with the specified name and channel handlers.
|
||||
* This is used internally in forge and FML
|
||||
|
|
|
@ -67,7 +67,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
|
|||
|
||||
public static final AttributeKey<NetworkDispatcher> FML_DISPATCHER = new AttributeKey<NetworkDispatcher>("fml:dispatcher");
|
||||
public static final AttributeKey<Boolean> IS_LOCAL = new AttributeKey<Boolean>("fml:isLocal");
|
||||
private final NetworkManager manager;
|
||||
public final NetworkManager manager;
|
||||
private final ServerConfigurationManager scm;
|
||||
private EntityPlayerMP player;
|
||||
private ConnectionState state;
|
||||
|
@ -259,6 +259,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
|
|||
else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.CLIENT))
|
||||
{
|
||||
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||
proxy.setDispatcher(this);
|
||||
context.fireChannelRead(proxy);
|
||||
return true;
|
||||
}
|
||||
|
@ -293,6 +294,7 @@ public class NetworkDispatcher extends SimpleChannelInboundHandler<Packet> imple
|
|||
else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.SERVER))
|
||||
{
|
||||
FMLProxyPacket proxy = new FMLProxyPacket(msg);
|
||||
proxy.setDispatcher(this);
|
||||
context.fireChannelRead(proxy);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,15 @@ package cpw.mods.fml.common.network.internal;
|
|||
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.NetworkManager;
|
||||
import net.minecraft.network.Packet;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.network.play.client.C17PacketCustomPayload;
|
||||
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.common.network.handshake.NetworkDispatcher;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
|
||||
public class FMLProxyPacket extends Packet {
|
||||
|
@ -19,6 +19,7 @@ public class FMLProxyPacket extends Packet {
|
|||
private Side target;
|
||||
private final ByteBuf payload;
|
||||
private INetHandler netHandler;
|
||||
private NetworkDispatcher dispatcher;
|
||||
|
||||
private FMLProxyPacket(byte[] payload, String channel)
|
||||
{
|
||||
|
@ -92,4 +93,19 @@ public class FMLProxyPacket extends Packet {
|
|||
{
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
public void setDispatcher(NetworkDispatcher networkDispatcher)
|
||||
{
|
||||
this.dispatcher = networkDispatcher;
|
||||
}
|
||||
|
||||
public NetworkManager getOrigin()
|
||||
{
|
||||
return this.dispatcher != null ? this.dispatcher.manager : null;
|
||||
}
|
||||
|
||||
public NetworkDispatcher getDispatcher()
|
||||
{
|
||||
return this.dispatcher;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue