Clean up some warnings. Add in simple network impl

This commit is contained in:
Christian committed 2014-01-16 18:06:36 -05:00
1 parent cb33a05824
commit 42c04dab2e
8 files changed
+313 -7

No files matched your search

@@ -21,9 +21,6 @@ import com.google.common.collect.Maps;
import cpw.mods.fml.relauncher.FMLLaunchHandler;
public class FMLTweaker implements ITweaker {
private List<String> args;
private File assetsDir;
private String profile;
private File gameDir;
private Map<String, String> launchArgs;
private List<String> standaloneArgs;
@@ -34,9 +31,6 @@ public class FMLTweaker implements ITweaker {
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile)
{
this.gameDir = (gameDir == null ? new File(".") : gameDir);
this.assetsDir = assetsDir;
this.profile = profile;
this.args = args;
this.launchArgs = (Map<String, String>)Launch.blackboard.get("launchArgs");
@@ -20,6 +20,7 @@ import com.google.gson.GsonBuilder;
* Basic implementation of Mojang's 'Yggdrasil' login system, purely intended as a dev time bare bones login.
* Login errors are not handled.
*/
@SuppressWarnings("unused")
public class Yggdrasil {
private static class Request {
Agent agent = new Agent();
@@ -88,7 +89,7 @@ public class Yggdrasil {
OutputStream out = null;
InputStream in = null;
try
try
{
HttpURLConnection con = (HttpURLConnection)(new URL("https://authserver.mojang.com/authenticate")).openConnection();
con.setConnectTimeout(15000);
@@ -0,0 +1,24 @@
package cpw.mods.fml.common.network.simpleimpl;
import io.netty.buffer.ByteBuf;
/**
* Implement this interface for each message you wish to define.
*
* @author cpw
*
*/
public interface IMessage {
/**
* Convert from the supplied buffer into your specific message type
*
* @param buf
*/
public void fromBytes(ByteBuf buf);
/**
* Deconstruct your message into the supplied byte buffer
* @param buf
*/
public void toBytes(ByteBuf buf);
}
@@ -0,0 +1,24 @@
package cpw.mods.fml.common.network.simpleimpl;
/**
* A message handler based on {@link IMessage}. Implement and override {@link #onMessage(IMessage)} to
* process your packet. Supply the class to {@link SimpleNetworkWrapper#registerMessage(Class, Class, byte, cpw.mods.fml.relauncher.Side)}
* to register both the message type and it's associated handler.
*
* @author cpw
*
* @param <REQ> This is the request type - it is the message you expect to <em>receive</em> from remote.
* @param <REPLY> This is the reply type - it is the message you expect to <em>send</em> in reply. You can use IMessage as the type here
* if you don't anticipate sending a reply.
*/
public interface IMessageHandler<REQ extends IMessage, REPLY extends IMessage> {
/**
* Called when a message is received of the appropriate type. You can optionally return a reply message, or null if no reply
* is needed.
*
* @param message The message
* @return an optional return message
*/
public REPLY onMessage(REQ message, MessageContext ctx);
}
@@ -0,0 +1,43 @@
package cpw.mods.fml.common.network.simpleimpl;
import cpw.mods.fml.relauncher.Side;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetHandlerPlayServer;
/**
* Context for the {@link IMessageHandler}
*
* @author cpw
*
*/
public class MessageContext {
/**
* The {@link INetHandler} for this message. It could be a client or server handler, depending
* on the {@link #side} recieved.
*/
public final INetHandler netHandler;
/**
* The Side this message has been received on
*/
public final Side side;
/**
* @param netHandler
*/
MessageContext(INetHandler netHandler, Side side)
{
this.netHandler = netHandler;
this.side = side;
}
public NetHandlerPlayServer getServerHandler()
{
return (NetHandlerPlayServer) netHandler;
}
public NetHandlerPlayClient getClientHandler()
{
return (NetHandlerPlayClient) netHandler;
}
}
@@ -0,0 +1,36 @@
package cpw.mods.fml.common.network.simpleimpl;
import net.minecraft.network.INetHandler;
import com.google.common.base.Throwables;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.relauncher.Side;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class SimpleChannelHandlerWrapper<REQ extends IMessage, REPLY extends IMessage> extends SimpleChannelInboundHandler<REQ> {
private IMessageHandler<REQ, REPLY> messageHandler;
private Side side;
public SimpleChannelHandlerWrapper(Class<? extends IMessageHandler<REQ, REPLY>> handler, Side side)
{
try
{
messageHandler = handler.newInstance();
} catch (Exception e)
{
Throwables.propagate(e);
}
this.side = side;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, REQ msg) throws Exception
{
INetHandler iNetHandler = ctx.attr(NetworkRegistry.NET_HANDLER).get();
MessageContext context = new MessageContext(iNetHandler, side);
REPLY result = messageHandler.onMessage(msg, context);
if (result != null)
{
ctx.writeAndFlush(result);
}
}
}
@@ -0,0 +1,20 @@
package cpw.mods.fml.common.network.simpleimpl;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import cpw.mods.fml.common.network.FMLIndexedMessageToMessageCodec;
public class SimpleIndexedCodec extends FMLIndexedMessageToMessageCodec<IMessage> {
@Override
public void encodeInto(ChannelHandlerContext ctx, IMessage msg, ByteBuf target) throws Exception
{
msg.toBytes(target);
}
@Override
public void decodeInto(ChannelHandlerContext ctx, ByteBuf source, IMessage msg)
{
msg.fromBytes(source);
}
}
@@ -0,0 +1,164 @@
package cpw.mods.fml.common.network.simpleimpl;
import java.util.EnumMap;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.INetHandler;
import net.minecraft.network.Packet;
import net.minecraft.tileentity.TileEntity;
import cpw.mods.fml.common.network.FMLEmbeddedChannel;
import cpw.mods.fml.common.network.FMLOutboundHandler;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint;
import cpw.mods.fml.relauncher.Side;
/**
* This class is a simplified netty wrapper for those not wishing to deal with the full power of netty.
* It provides a simple message driven system, based on a discriminator byte over the custom packet channel.
*
* Usage is simple:<ul>
* <li>construct, and store, an instance of this class. It will automatically register and configure your underlying netty channel.
*
* <li>Then, call {@link #registerMessage(Class, Class, byte, Side)} for each message type you want to exchange
* providing an {@link IMessageHandler} implementation class as well as an {@link IMessage} implementation class. The side parameter
* to that method indicates which side (server or client) the <em>message processing</em> 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).
* <li>To get a packet suitable for presenting to the rest of minecraft, you can call {@link #getPacketFrom(IMessage)}. The return result
* is suitable for returning from things like {@link TileEntity#func_145844_m()} for example.
* <li>Finally, use the sendXXX to send unsolicited messages to various classes of recipients.
* </ul>
*
*
*
* @author cpw
*
*/
public class SimpleNetworkWrapper {
private EnumMap<Side, FMLEmbeddedChannel> channels;
private SimpleIndexedCodec packetCodec;
public SimpleNetworkWrapper(String channelName)
{
packetCodec = new SimpleIndexedCodec();
channels = NetworkRegistry.INSTANCE.newChannel(channelName, packetCodec);
}
/**
* Register a message and it's associated handler. The message will have the supplied discriminator byte. The message handler will
* be registered on the supplied side (this is the side where you want the message to be processed and acted upon).
*
* @param messageHandler the message handler type
* @param message the message type
* @param discriminator a discriminator byte
* @param side the side for the handler
*/
public <REQ extends IMessage, REPLY extends IMessage> void registerMessage(Class<? extends IMessageHandler<REQ, REPLY>> messageHandler, Class<REQ> message, int discriminator, Side side)
{
packetCodec.addDiscriminator(discriminator, message);
FMLEmbeddedChannel channel = channels.get(side);
String type = channel.findChannelHandlerNameForType(SimpleIndexedCodec.class);
if (side == Side.SERVER)
{
addServerHandlerAfter(channel, type, messageHandler);
}
else
{
addClientHandlerAfter(channel, type, messageHandler);
}
}
private <REQ extends IMessage, REPLY extends IMessage, NH extends INetHandler> void addServerHandlerAfter(FMLEmbeddedChannel channel, String type, Class<? extends IMessageHandler<REQ, REPLY>> messageHandler)
{
SimpleChannelHandlerWrapper<REQ, REPLY> handler = getHandlerWrapper(messageHandler, Side.SERVER);
channel.pipeline().addAfter(type, messageHandler.getName(), handler);
}
private <REQ extends IMessage, REPLY extends IMessage, NH extends INetHandler> void addClientHandlerAfter(FMLEmbeddedChannel channel, String type, Class<? extends IMessageHandler<REQ, REPLY>> messageHandler)
{
SimpleChannelHandlerWrapper<REQ, REPLY> handler = getHandlerWrapper(messageHandler, Side.CLIENT);
channel.pipeline().addAfter(type, messageHandler.getName(), handler);
}
private <REPLY extends IMessage, REQ extends IMessage> SimpleChannelHandlerWrapper<REQ, REPLY> getHandlerWrapper(Class<? extends IMessageHandler<REQ, REPLY>> messageHandler, Side side)
{
return new SimpleChannelHandlerWrapper<REQ, REPLY>(messageHandler, side);
}
/**
* Construct a minecraft packet from the supplied message. Can be used where minecraft packets are required, such as
* {@link TileEntity#func_145844_m()}.
*
* @param message The message to translate into packet form
* @return A minecraft {@link Packet} suitable for use in minecraft APIs
*/
public Packet getPacketFrom(IMessage message)
{
return channels.get(Side.SERVER).generatePacketFrom(message);
}
/**
* Send this message to everyone.
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
*
* @param message The message to send
*/
public void sendToAll(IMessage message)
{
channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.ALL);
channels.get(Side.SERVER).writeAndFlush(message);
}
/**
* Send this message to the specified player.
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
*
* @param message The message to send
* @param player The player to send it to
*/
public void sendTo(IMessage message, 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(message);
}
/**
* Send this message to everyone within a certain range of a point.
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
*
* @param message The message to send
* @param point The {@link TargetPoint} around which to send
*/
public void sendToAllAround(IMessage message, 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(message);
}
/**
* Send this message to everyone within the supplied dimension.
* The {@link IMessageHandler} for this message type should be on the CLIENT side.
*
* @param message The message to send
* @param dimensionId The dimension id to target
*/
public void sendToDimension(IMessage message, 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(message);
}
/**
* Send this message to the server.
* The {@link IMessageHandler} for this message type should be on the SERVER side.
*
* @param message The message to send
*/
public void sendToServer(IMessage message)
{
channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.TOSERVER);
channels.get(Side.CLIENT).writeAndFlush(message);
}
}