using System;
using TrueCraft.API.Networking;
using TrueCraft.Core.Networking.Packets;
namespace TrueCraft.Core.Networking
{
public class PacketReader : IPacketReader
{
public static readonly int Version = 14;
public int ProtocolVersion { get { return Version; } }
private Type[] ClientboundPackets = new Type[0x100];
private Type[] ServerboundPackets = new Type[0x100];
///
/// Registers TrueCraft.Core implementations of all packets used by vanilla Minecraft.
///
public void RegisterCorePackets()
{
RegisterPacketType(); // 0x00
RegisterPacketType(serverbound: true, clientbound: false); // 0x01
RegisterPacketType(serverbound: false, clientbound: true); // 0x01
RegisterPacketType(serverbound: true, clientbound: false); // 0x02
RegisterPacketType(serverbound: false, clientbound: true); // 0x02
RegisterPacketType(); // 0x03
RegisterPacketType(serverbound: false, clientbound: true); // 0x04
RegisterPacketType(serverbound: false, clientbound: true); // 0x05 // NOTE: serverbound not confirmed
RegisterPacketType(serverbound: true, clientbound: false); // 0x06
RegisterPacketType(serverbound: false, clientbound: true); // 0x07
RegisterPacketType(serverbound: false, clientbound: true); // 0x08
RegisterPacketType(); // 0x09
RegisterPacketType(serverbound: true, clientbound: false); // 0x0A
RegisterPacketType(serverbound: true, clientbound: false); // 0x0B
RegisterPacketType(serverbound: true, clientbound: false); // 0x0C
RegisterPacketType(serverbound: true, clientbound: false); // 0x0D
RegisterPacketType(serverbound: false, clientbound: true); // 0x0D
RegisterPacketType(serverbound: true, clientbound: false); // 0x0E
RegisterPacketType(serverbound: true, clientbound: false); // 0x0F
RegisterPacketType(serverbound: true, clientbound: false); // 0x10
RegisterPacketType(serverbound: false, clientbound: true); // 0x11
RegisterPacketType(serverbound: false, clientbound: true); // 0x12
RegisterPacketType(serverbound: true, clientbound: false); // 0x13
RegisterPacketType(serverbound: false, clientbound: true); // 0x14
RegisterPacketType(serverbound: false, clientbound: true); // 0x15
RegisterPacketType(serverbound: false, clientbound: true); // 0x16
RegisterPacketType(serverbound: false, clientbound: true); // 0x17
RegisterPacketType(serverbound: false, clientbound: true); // 0x18
RegisterPacketType(serverbound: false, clientbound: true); // 0x19
RegisterPacketType(serverbound: false, clientbound: true); // 0x1C
RegisterPacketType(serverbound: false, clientbound: true); // 0x1E
RegisterPacketType(serverbound: false, clientbound: true); // 0x1F
RegisterPacketType(serverbound: false, clientbound: true); // 0x20
RegisterPacketType(serverbound: false, clientbound: true); // 0x21
RegisterPacketType(serverbound: false, clientbound: true); // 0x22
RegisterPacketType(serverbound: false, clientbound: true); // 0x26
RegisterPacketType(serverbound: false, clientbound: true); // 0x27
RegisterPacketType(serverbound: false, clientbound: true); // 0x28
RegisterPacketType(serverbound: false, clientbound: true); // 0x32
RegisterPacketType(serverbound: false, clientbound: true); // 0x33
RegisterPacketType(serverbound: false, clientbound: true); // 0x34
RegisterPacketType(serverbound: false, clientbound: true); // 0x35
RegisterPacketType(serverbound: false, clientbound: true); // 0x36
RegisterPacketType(serverbound: false, clientbound: true); // 0x3D
RegisterPacketType(serverbound: false, clientbound: true); // 0x46
RegisterPacketType(serverbound: false, clientbound: true); // 0x47
RegisterPacketType(serverbound: false, clientbound: true); // 0x64
RegisterPacketType(); // 0x65
RegisterPacketType(serverbound: true, clientbound: false); // 0x66
RegisterPacketType(serverbound: false, clientbound: true); // 0x67
RegisterPacketType(serverbound: false, clientbound: true); // 0x68
RegisterPacketType(serverbound: false, clientbound: true); // 0x69
RegisterPacketType(serverbound: false, clientbound: true); // 0x6A
RegisterPacketType(); // 0x82
RegisterPacketType(serverbound: false, clientbound: true); // 0x83
RegisterPacketType(serverbound: false, clientbound: true); // 0xC8
RegisterPacketType(); // 0xFF
}
public void RegisterPacketType(bool clientbound = true, bool serverbound = true) where T : IPacket
{
var packet = (IPacket)Activator.CreateInstance(typeof(T));
if (clientbound)
ClientboundPackets[packet.ID] = typeof(T);
if (serverbound)
ServerboundPackets[packet.ID] = typeof(T);
}
public IPacket ReadPacket(IMinecraftStream stream, bool serverbound = true)
{
var id = stream.ReadUInt8();
Type type;
if (serverbound)
type = ServerboundPackets[id];
else
type = ClientboundPackets[id];
if (type == null)
throw new NotSupportedException("Unable to read packet type 0x" + id.ToString("X2"));
var instance = (IPacket)Activator.CreateInstance(type);
instance.ReadPacket(stream);
return instance;
}
public void WritePacket(IMinecraftStream stream, IPacket packet)
{
stream.WriteUInt8(packet.ID);
packet.WritePacket(stream);
}
}
}