blob: 04c5ce345a6fa79149e44c144e9fd4e8b7e01a9a [file] [log] [blame] [raw]
package mekanism.common;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.List;
import mekanism.api.Coord4D;
import mekanism.common.network.IMekanismPacket;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteStreams;
/**
* Mekanism packet handler. As always, use packets sparingly!
* @author AidanBrady
*
*/
public class PacketHandler //implements IPacketHandler
{
/*
/** The ArrayList of registered packet classes, who's index tells which packet is which. *
public static List<Class<? extends IMekanismPacket>> packets = new ArrayList<Class<? extends IMekanismPacket>>();
@Override
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player)
{
ByteArrayDataInput dataStream = ByteStreams.newDataInput(packet.data);
EntityPlayer entityplayer = (EntityPlayer)player;
if(packet.channel.equals("MEK"))
{
try {
int packetIndex = dataStream.readInt();
if(packets.get(packetIndex) == null)
{
System.err.println("[Mekanism] Received unknown packet identifier '" + packetIndex + ".' Ignorning!");
return;
}
IMekanismPacket packetType = packets.get(packetIndex).newInstance();
if(packetType == null)
{
System.err.println("[Mekanism] Unable to create instance of packet type '" + packetIndex + ".' Ignoring!");
return;
}
try {
packetType.read(dataStream, entityplayer, entityplayer.getWorldObj());
} catch(Exception e) {
System.err.println("[Mekanism] Error while reading '" + packetType.getName() + "' packet.");
e.printStackTrace();
}
} catch(Exception e) {
System.err.println("[Mekanism] Error while handling packet.");
e.printStackTrace();
}
}
}
/**
* Registers a packet class for identification and reflection purposes. This MUST be called both server-side and client-side,
* otherwise the packet will not be handled correctly.
* @param packetClass - class of the packet to register
*
public static void registerPacket(Class<? extends IMekanismPacket> packetClass)
{
if(!packets.contains(packetClass))
{
packets.add(packetClass);
}
}
/**
* Encodes an Object[] of data into a DataOutputStream.
* @param dataValues - an Object[] of data to encode
* @param output - the output stream to write to
*
public static void encode(Object[] dataValues, DataOutputStream output)
{
try {
for(Object data : dataValues)
{
if(data instanceof Integer)
{
output.writeInt((Integer)data);
}
else if(data instanceof Boolean)
{
output.writeBoolean((Boolean)data);
}
else if(data instanceof Double)
{
output.writeDouble((Double)data);
}
else if(data instanceof Float)
{
output.writeFloat((Float)data);
}
else if(data instanceof String)
{
output.writeUTF((String)data);
}
else if(data instanceof Byte)
{
output.writeByte((Byte)data);
}
else if(data instanceof int[])
{
for(int i : (int[])data)
{
output.writeInt(i);
}
}
else if(data instanceof byte[])
{
for(byte b : (byte[])data)
{
output.writeByte(b);
}
}
else if(data instanceof ArrayList)
{
encode(((ArrayList)data).toArray(), output);
}
}
} catch(Exception e) {
System.err.println("[Mekanism] Error while encoding packet data.");
e.printStackTrace();
}
}
/**
* Sends a packet with the defined type of transmission.
* @param trans - the type of transmission to use with this packet
* @param packetType - the object representing this packet, both registered and properly using write()
* @param transParams - any extra parameters the transmission type requires
*
public static void sendPacket(Transmission trans, IMekanismPacket packetType, Object... transParams)
{
if(packetType == null)
{
System.err.println("[Mekanism] Attempted to send null packet, ignoring!");
return;
}
if(!packets.contains(packetType.getClass()))
{
System.err.println("[Mekanism] Attempted to send unregistered packet '" + packetType.getName() + ",' ignoring!");
return;
}
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
DataOutputStream data = new DataOutputStream(bytes);
try {
data.writeInt(packets.indexOf(packetType.getClass()));
packetType.write(data);
} catch(Exception e) {
System.err.println("[Mekanism] Error while encoding packet data.");
e.printStackTrace();
}
Packet250CustomPayload packet = new Packet250CustomPayload();
packet.channel = "MEK";
packet.data = bytes.toByteArray();
packet.length = packet.data.length;
switch(trans)
{
case SERVER:
PacketDispatcher.sendPacketToServer(packet);
break;
case ALL_CLIENTS:
PacketDispatcher.sendPacketToAllPlayers(packet);
break;
case CLIENTS_RANGE:
Coord4D obj = (Coord4D)transParams[0];
PacketDispatcher.sendPacketToAllAround(obj.xCoord, obj.yCoord, obj.zCoord, (Double)transParams[1], obj.dimensionId, packet);
break;
case CLIENTS_DIM:
PacketDispatcher.sendPacketToAllInDimension(packet, (Integer)transParams[0]);
break;
case SINGLE_CLIENT:
((EntityPlayerMP)transParams[0]).playerNetServerHandler.sendPacketToPlayer(packet);
break;
}
log(trans, packetType, transParams);
}
/**
* Writes a log to the console with information about a packet recently sent.
* @param trans - transmission type this packet used when it was sent
* @param packetType - object representing this packet
* @param transParams - any extra parameters the transmission type requires
*
private static void log(Transmission trans, IMekanismPacket packetType, Object[] transParams)
{
if(Mekanism.logPackets)
{
switch(trans)
{
case SERVER:
System.out.println("[Mekanism] Sent '" + packetType.getName() + "' packet to server.");
break;
case ALL_CLIENTS:
System.out.println("[Mekanism] Sent '" + packetType.getName() + "' packet to all clients.");
break;
case CLIENTS_RANGE:
System.out.println("[Mekanism] Sent '" + packetType.getName() + "' packet to clients in a " + (Double)transParams[1] + " block range.");
break;
case CLIENTS_DIM:
System.out.println("[Mekanism] Sent '" + packetType.getName() + "' packet to clients in dimension ID " + (Integer)transParams[0] + ".");
break;
case SINGLE_CLIENT:
System.out.println("[Mekanism] Sent '" + packetType.getName() + "' packet to " + ((EntityPlayer)transParams[0]).username);
break;
}
}
}
public static enum Transmission
{
/** No additional parameters. *
SERVER(0),
/** No additional parameters. *
ALL_CLIENTS(0),
/** 2 parameters - Object3D representing the location of the transmission, and a double of the distance this packet can be sent in. *
CLIENTS_RANGE(2),
/** 1 parameter - int representing the dimension ID to send this packet to. *
CLIENTS_DIM(1),
/** 1 parameter - EntityPlayer to send this packet to. *
SINGLE_CLIENT(1),
public int parameters;
private Transmission(int params)
{
parameters = params;
}
}*/
}