From 22ba6fda5ee2dbf29dc03ba93ff9c7707edeaeee Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 31 Dec 2013 09:45:26 -0500 Subject: [PATCH] Expose the nethandler in a few places, and pull out FMLEmbeddedChannel, exposing a utility method on it. More to come. --- .../cpw/mods/fml/client/FMLClientHandler.java | 6 +++ .../cpw/mods/fml/common/FMLCommonHandler.java | 6 +++ .../cpw/mods/fml/common/IFMLSidedHandler.java | 3 ++ .../common/network/FMLEmbeddedChannel.java | 52 +++++++++++++++++++ .../network/NetworkHandshakeEstablished.java | 6 ++- .../fml/common/network/NetworkRegistry.java | 31 +++-------- .../network/handshake/NetworkDispatcher.java | 10 ++++ .../network/internal/FMLNetworkHandler.java | 9 ++-- .../network/internal/FMLProxyPacket.java | 1 + .../cpw/mods/fml/server/FMLServerHandler.java | 6 +++ 10 files changed, 100 insertions(+), 30 deletions(-) create mode 100644 src/main/java/cpw/mods/fml/common/network/FMLEmbeddedChannel.java diff --git a/src/main/java/cpw/mods/fml/client/FMLClientHandler.java b/src/main/java/cpw/mods/fml/client/FMLClientHandler.java index 034809fb95..93629fad86 100644 --- a/src/main/java/cpw/mods/fml/client/FMLClientHandler.java +++ b/src/main/java/cpw/mods/fml/client/FMLClientHandler.java @@ -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() { diff --git a/src/main/java/cpw/mods/fml/common/FMLCommonHandler.java b/src/main/java/cpw/mods/fml/common/FMLCommonHandler.java index 0ea0c04ba7..434d0662ff 100644 --- a/src/main/java/cpw/mods/fml/common/FMLCommonHandler.java +++ b/src/main/java/cpw/mods/fml/common/FMLCommonHandler.java @@ -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(); + } } diff --git a/src/main/java/cpw/mods/fml/common/IFMLSidedHandler.java b/src/main/java/cpw/mods/fml/common/IFMLSidedHandler.java index 3e06d7f860..9390142f55 100644 --- a/src/main/java/cpw/mods/fml/common/IFMLSidedHandler.java +++ b/src/main/java/cpw/mods/fml/common/IFMLSidedHandler.java @@ -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(); } diff --git a/src/main/java/cpw/mods/fml/common/network/FMLEmbeddedChannel.java b/src/main/java/cpw/mods/fml/common/network/FMLEmbeddedChannel.java new file mode 100644 index 0000000000..6a78904725 --- /dev/null +++ b/src/main/java/cpw/mods/fml/common/network/FMLEmbeddedChannel.java @@ -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; + } +} \ No newline at end of file diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkHandshakeEstablished.java b/src/main/java/cpw/mods/fml/common/network/NetworkHandshakeEstablished.java index 4d8593a493..02dc0f79c2 100644 --- a/src/main/java/cpw/mods/fml/common/network/NetworkHandshakeEstablished.java +++ b/src/main/java/cpw/mods/fml/common/network/NetworkHandshakeEstablished.java @@ -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; } diff --git a/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java b/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java index eb7a16ab0f..801075bc84 100644 --- a/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java +++ b/src/main/java/cpw/mods/fml/common/network/NetworkRegistry.java @@ -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 FML_CHANNEL = new AttributeKey("fml:channelName"); public static final AttributeKey CHANNEL_SOURCE = new AttributeKey("fml:channelSource"); public static final AttributeKey MOD_CONTAINER = new AttributeKey("fml:modContainer"); + public static final AttributeKey NET_HANDLER = new AttributeKey("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 newChannel(String name, ChannelHandler... handlers) + public EnumMap 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 result = Maps.newEnumMap(Side.class); + EnumMap result = Maps.newEnumMap(Side.class); for (Side side : Side.values()) { @@ -140,13 +125,13 @@ public enum NetworkRegistry return result; } - public EnumMap newChannel(ModContainer container, String name, ChannelHandler... handlers) + public EnumMap 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 result = Maps.newEnumMap(Side.class); + EnumMap 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 channel : channels.get(origin).entrySet()) { channel.getValue().pipeline().fireUserEventTriggered(handshake); diff --git a/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java b/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java index b1f880a773..7e00a9e293 100644 --- a/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java +++ b/src/main/java/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java @@ -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 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 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 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 imple } } + public INetHandler getNetHandler() + { + return netHandler; + } + @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java index 4a5fcc69de..126cc07452 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java @@ -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 channelPair; + private static EnumMap 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) diff --git a/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java b/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java index e071443e40..69d5f58a1a 100644 --- a/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java +++ b/src/main/java/cpw/mods/fml/common/network/internal/FMLProxyPacket.java @@ -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); diff --git a/src/main/java/cpw/mods/fml/server/FMLServerHandler.java b/src/main/java/cpw/mods/fml/server/FMLServerHandler.java index 3a01bcd7ad..78d5d230ef 100644 --- a/src/main/java/cpw/mods/fml/server/FMLServerHandler.java +++ b/src/main/java/cpw/mods/fml/server/FMLServerHandler.java @@ -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; + } }