using System.Collections.Generic; using System; using NeonTea.Quakeball.TeaNet.Peers; namespace NeonTea.Quakeball.TeaNet.Packets { public abstract class Protocol { private Dictionary PacketToId = new Dictionary(); private Dictionary IdToPacket = new Dictionary(); private int PacketIdCounter; public Peer Peer; public abstract byte Identifier { get; } public abstract string Version { get; } public abstract void Receive(Connection conn, Packet packet); public abstract void ConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, Connection conn); public abstract void Timeout(Connection conn); public void SendPacket(Packet p, Connection conn) { Peer.ConnectionManager.AddPacketToQueue(conn.uid, p); Peer.ConnectionManager.SendPacketQueue(conn.uid); } public int RegisterPacket(Type t) { if (t.BaseType != typeof(Packet) || PacketToId.ContainsKey(t)) { return -1; } int id = PacketIdCounter++; PacketToId.Add(t, id); IdToPacket.Add(id, t); return id; } public ByteBuffer BuildMessage(Connection connection) { ByteBuffer buffer = new ByteBuffer(); foreach (byte b in Peer.Fingerprint) { buffer.Write(b); } buffer.Write(Identifier); if (connection.Status == ConnectionStatus.Establishing) { buffer.Write((byte)PacketStage.Establishing); buffer.WriteString(Version); } else if (connection.Status == ConnectionStatus.Closed) { buffer.Write((byte)PacketStage.Closed); } else if (connection.Status == ConnectionStatus.Rejected) { buffer.Write((byte)PacketStage.Rejected); buffer.Write((byte)connection.ClosingReason); } else if (connection.Status == ConnectionStatus.Ready) { buffer.Write((byte)PacketStage.Ready); buffer.WriteInt(connection.Internal.LatestInwardReliable); } return buffer; } public int GetPacketTypeID(Packet packet) { return PacketToId[packet.GetType()]; } public Type GetPacketType(int id) { return IdToPacket[id]; } } }