public class SimpleNetworkWrapper
extends java.lang.Object
registerMessage(Class, Class, int, Side)
for each message type you want to exchange
providing an IMessageHandler
implementation class as well as an IMessage
implementation class. The side parameter
to that method indicates which side (server or client) the message processing will occur on. The discriminator byte
should be unique for this channelName - it is used to discriminate between different types of message that might
occur on this channel (a simple form of message channel multiplexing, if you will).
getPacketFrom(IMessage)
. The return result
is suitable for returning from things like TileEntity#getDescriptionPacket()
for example.
// Request message
public Message1 implements IMessage {
// message structure
public fromBytes(ByteBuf buf) {
// build message from byte array
}
public toBytes(ByteBuf buf) {
// put message content into byte array
}
}
// Reply message
public Message2 implements IMessage {
// stuff as before
}
// Message1Handler expects input of type Message1 and returns type Message2
public Message1Handler implements IMessageHandler {
public Message2 onMessage(Message1 message, MessageContext ctx) {
// do something and generate reply message
return aMessage2Object;
}
}
// Message2Handler expects input of type Message2 and returns no message (IMessage)
public Message2Handler implements IMessageHandler {
public IMessage onMessage(Message2 message, MessageContext ctx) {
// handle the message 2 response message at the other end
// no reply for this message - return null
return null;
}
}
// Code in a FMLPreInitializationEvent
or FMLInitializationEvent
handler
SimpleNetworkWrapper wrapper = NetworkRegistry.newSimpleChannel("MYCHANNEL");
// Message1 is handled by the Message1Handler class, it has discriminator id 1 and it's on the client
wrapper.registerMessage(Message1Handler.class, Message1.class, 1, Side.CLIENT);
// Message2 is handled by the Message2Handler class, it has discriminator id 2 and it's on the server
wrapper.registerMessage(Message2Handler.class, Message2.class, 2, Side.SERVER);
Note: As of Minecraft 1.8 packets are by default handled on the network thread.
That means that your IMessageHandler
can not interact with most game objects directly.
Minecraft provides a convenient way to make your code execute on the main thread instead using IThreadListener.addScheduledTask(Runnable)
.
The way to obtain an IThreadListener
is using either the Minecraft
instance (client side) or a WorldServer
instance (server side).Modifier and Type | Field and Description |
---|---|
private java.util.EnumMap<Side,FMLEmbeddedChannel> |
channels |
private static java.lang.Class<?> |
defaultChannelPipeline |
private static java.lang.reflect.Method |
generateName |
private SimpleIndexedCodec |
packetCodec |
Constructor and Description |
---|
SimpleNetworkWrapper(java.lang.String channelName) |
Modifier and Type | Method and Description |
---|---|
private <REQ extends IMessage,REPLY extends IMessage,NH extends INetHandler> |
addClientHandlerAfter(FMLEmbeddedChannel channel,
java.lang.String type,
IMessageHandler<? super REQ,? extends REPLY> messageHandler,
java.lang.Class<REQ> requestType) |
private <REQ extends IMessage,REPLY extends IMessage,NH extends INetHandler> |
addServerHandlerAfter(FMLEmbeddedChannel channel,
java.lang.String type,
IMessageHandler<? super REQ,? extends REPLY> messageHandler,
java.lang.Class<REQ> requestType) |
private java.lang.String |
generateName(io.netty.channel.ChannelPipeline pipeline,
io.netty.channel.ChannelHandler handler) |
private <REPLY extends IMessage,REQ extends IMessage> |
getHandlerWrapper(IMessageHandler<? super REQ,? extends REPLY> messageHandler,
Side side,
java.lang.Class<REQ> requestType) |
Packet<?> |
getPacketFrom(IMessage message)
Construct a minecraft packet from the supplied message.
|
(package private) static <REQ extends IMessage,REPLY extends IMessage> |
instantiate(java.lang.Class<? extends IMessageHandler<? super REQ,? extends REPLY>> handler) |
<REQ extends IMessage,REPLY extends IMessage> |
registerMessage(java.lang.Class<? extends IMessageHandler<REQ,REPLY>> messageHandler,
java.lang.Class<REQ> requestMessageType,
int discriminator,
Side side)
Register a message and it's associated handler.
|
<REQ extends IMessage,REPLY extends IMessage> |
registerMessage(IMessageHandler<? super REQ,? extends REPLY> messageHandler,
java.lang.Class<REQ> requestMessageType,
int discriminator,
Side side)
Register a message and it's associated handler.
|
void |
sendTo(IMessage message,
EntityPlayerMP player)
Send this message to the specified player.
|
void |
sendToAll(IMessage message)
Send this message to everyone.
|
void |
sendToAllAround(IMessage message,
NetworkRegistry.TargetPoint point)
Send this message to everyone within a certain range of a point.
|
void |
sendToAllTracking(IMessage message,
Entity entity)
Sends this message to everyone tracking an entity.
|
void |
sendToAllTracking(IMessage message,
NetworkRegistry.TargetPoint point)
Sends this message to everyone tracking a point.
|
void |
sendToDimension(IMessage message,
int dimensionId)
Send this message to everyone within the supplied dimension.
|
void |
sendToServer(IMessage message)
Send this message to the server.
|
private java.util.EnumMap<Side,FMLEmbeddedChannel> channels
private SimpleIndexedCodec packetCodec
private static java.lang.Class<?> defaultChannelPipeline
private static java.lang.reflect.Method generateName
private java.lang.String generateName(io.netty.channel.ChannelPipeline pipeline, io.netty.channel.ChannelHandler handler)
public <REQ extends IMessage,REPLY extends IMessage> void registerMessage(java.lang.Class<? extends IMessageHandler<REQ,REPLY>> messageHandler, java.lang.Class<REQ> requestMessageType, int discriminator, Side side)
messageHandler
- the message handler typerequestMessageType
- the message typediscriminator
- a discriminator byteside
- the side for the handlerstatic <REQ extends IMessage,REPLY extends IMessage> IMessageHandler<? super REQ,? extends REPLY> instantiate(java.lang.Class<? extends IMessageHandler<? super REQ,? extends REPLY>> handler)
public <REQ extends IMessage,REPLY extends IMessage> void registerMessage(IMessageHandler<? super REQ,? extends REPLY> messageHandler, java.lang.Class<REQ> requestMessageType, int discriminator, Side side)
messageHandler
- the message handler instancerequestMessageType
- the message typediscriminator
- a discriminator byteside
- the side for the handlerprivate <REQ extends IMessage,REPLY extends IMessage,NH extends INetHandler> void addServerHandlerAfter(FMLEmbeddedChannel channel, java.lang.String type, IMessageHandler<? super REQ,? extends REPLY> messageHandler, java.lang.Class<REQ> requestType)
private <REQ extends IMessage,REPLY extends IMessage,NH extends INetHandler> void addClientHandlerAfter(FMLEmbeddedChannel channel, java.lang.String type, IMessageHandler<? super REQ,? extends REPLY> messageHandler, java.lang.Class<REQ> requestType)
private <REPLY extends IMessage,REQ extends IMessage> SimpleChannelHandlerWrapper<REQ,REPLY> getHandlerWrapper(IMessageHandler<? super REQ,? extends REPLY> messageHandler, Side side, java.lang.Class<REQ> requestType)
public Packet<?> getPacketFrom(IMessage message)
TileEntity#getDescriptionPacket()
.message
- The message to translate into packet formPacket
suitable for use in minecraft APIspublic void sendToAll(IMessage message)
IMessageHandler
for this message type should be on the CLIENT side.message
- The message to sendpublic void sendTo(IMessage message, EntityPlayerMP player)
IMessageHandler
for this message type should be on the CLIENT side.message
- The message to sendplayer
- The player to send it topublic void sendToAllAround(IMessage message, NetworkRegistry.TargetPoint point)
IMessageHandler
for this message type should be on the CLIENT side.message
- The message to sendpoint
- The NetworkRegistry.TargetPoint
around which to sendpublic void sendToAllTracking(IMessage message, NetworkRegistry.TargetPoint point)
IMessageHandler
for this message type should be on the CLIENT side.
The range
field of the NetworkRegistry.TargetPoint
is ignored.message
- The message to sendpoint
- The tracked NetworkRegistry.TargetPoint
around which to sendpublic void sendToAllTracking(IMessage message, Entity entity)
IMessageHandler
for this message type should be on the CLIENT side.
This is not equivalent to #sendToAllTracking(IMessage, TargetPoint)
because entities have different tracking distances based on their type.message
- The message to sendentity
- The tracked entity around which to sendpublic void sendToDimension(IMessage message, int dimensionId)
IMessageHandler
for this message type should be on the CLIENT side.message
- The message to senddimensionId
- The dimension id to targetpublic void sendToServer(IMessage message)
IMessageHandler
for this message type should be on the SERVER side.message
- The message to send