Add in some doc to packethandler, since I suspect people will be curious how to do it

This commit is contained in:
Christian 2014-02-05 16:28:07 -05:00
parent c90472b66c
commit 7e90e2ac1d
1 changed files with 69 additions and 0 deletions

View File

@ -21,15 +21,30 @@ import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.network.FMLEmbeddedChannel; import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec; import cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec;
import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.internal.FMLProxyPacket;
import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly; import cpw.mods.fml.relauncher.SideOnly;
/**
* Handles the packet wrangling for IronChest
* @author cpw
*
*/
public enum PacketHandler { public enum PacketHandler {
INSTANCE; INSTANCE;
/**
* Our channel "pair" from {@link NetworkRegistry}
*/
private EnumMap<Side, FMLEmbeddedChannel> channels; private EnumMap<Side, FMLEmbeddedChannel> channels;
/**
* Make our packet handler, and add an {@link IronChestCodec} always
*/
private PacketHandler() private PacketHandler()
{ {
// request a channel pair for IronChest from the network registry
// Add the IronChestCodec as a member of both channel pipelines
this.channels = NetworkRegistry.INSTANCE.newChannel("IronChest", new IronChestCodec()); this.channels = NetworkRegistry.INSTANCE.newChannel("IronChest", new IronChestCodec());
if (FMLCommonHandler.instance().getSide() == Side.CLIENT) if (FMLCommonHandler.instance().getSide() == Side.CLIENT)
{ {
@ -37,13 +52,28 @@ public enum PacketHandler {
} }
} }
/**
* This is only called on the client side - it adds an
* {@link IronChestMessageHandler} to the client side pipeline, since the
* only place we expect to <em>handle</em> messages is on the client.
*/
@SideOnly(Side.CLIENT) @SideOnly(Side.CLIENT)
private void addClientHandler() { private void addClientHandler() {
FMLEmbeddedChannel clientChannel = this.channels.get(Side.CLIENT); FMLEmbeddedChannel clientChannel = this.channels.get(Side.CLIENT);
// These two lines find the existing codec (Ironchestcodec) and insert our message handler after it
// in the pipeline
String codec = clientChannel.findChannelHandlerNameForType(IronChestCodec.class); String codec = clientChannel.findChannelHandlerNameForType(IronChestCodec.class);
clientChannel.pipeline().addAfter(codec, "ClientHandler", new IronChestMessageHandler()); clientChannel.pipeline().addAfter(codec, "ClientHandler", new IronChestMessageHandler());
} }
/**
* This class simply handles the {@link IronChestMessage} when it's received
* at the client side It can contain client only code, because it's only run
* on the client.
*
* @author cpw
*
*/
private static class IronChestMessageHandler extends SimpleChannelInboundHandler<IronChestMessage> private static class IronChestMessageHandler extends SimpleChannelInboundHandler<IronChestMessage>
{ {
@Override @Override
@ -59,6 +89,16 @@ public enum PacketHandler {
} }
} }
} }
/**
* This is our "message". In fact, {@link FMLIndexedMessageToMessageCodec}
* can handle many messages on the same channel at once, using a
* discriminator byte. But for IronChest, we only need the one message, so
* we have just this.
*
* @author cpw
*
*/
public static class IronChestMessage public static class IronChestMessage
{ {
int x; int x;
@ -68,8 +108,21 @@ public enum PacketHandler {
int facing; int facing;
int[] items; int[] items;
} }
/**
* This is the codec that automatically transforms the
* {@link FMLProxyPacket} which wraps the client and server custom payload
* packets into a message we care about.
*
* @author cpw
*
*/
private class IronChestCodec extends FMLIndexedMessageToMessageCodec<IronChestMessage> private class IronChestCodec extends FMLIndexedMessageToMessageCodec<IronChestMessage>
{ {
/**
* We register our discriminator bytes here. We only have the one type, so we only
* register one.
*/
public IronChestCodec() public IronChestCodec()
{ {
addDiscriminator(0, IronChestMessage.class); addDiscriminator(0, IronChestMessage.class);
@ -117,6 +170,22 @@ public enum PacketHandler {
} }
/**
* This is a utility method called to transform a packet from a custom
* packet into a "system packet". We're called from
* {@link TileEntity#getDescriptionPacket()} in this case, but there are
* others. All network packet methods in minecraft have been adapted to
* handle {@link FMLProxyPacket} but general purpose objects can't be
* handled sadly.
*
* This method uses the {@link IronChestCodec} to transform a custom packet
* {@link IronChestMessage} into an {@link FMLProxyPacket} by using the
* utility method {@link FMLEmbeddedChannel#generatePacketFrom(Object)} on
* the channel to do exactly that.
*
* @param tileEntityIronChest
* @return
*/
public static Packet getPacket(TileEntityIronChest tileEntityIronChest) public static Packet getPacket(TileEntityIronChest tileEntityIronChest)
{ {
IronChestMessage msg = new IronChestMessage(); IronChestMessage msg = new IronChestMessage();