2020-08-05 03:21:04 +02:00
using System.Collections.Generic ;
using System ;
2020-08-05 18:50:28 +02:00
using NeonTea.Quakeball.TeaNet.Peers ;
2020-08-05 03:21:04 +02:00
2020-08-05 18:50:28 +02:00
namespace NeonTea.Quakeball.TeaNet.Packets {
2020-08-06 20:49:51 +02:00
/// <summary>Manages a single form of conversation between clients for the Peer. Don't forget to register your packets with <see cref="Protocol.RegisterPacket(Type)"/></summary>
2020-08-05 03:21:04 +02:00
public abstract class Protocol {
private Dictionary < Type , int > PacketToId = new Dictionary < Type , int > ( ) ;
private Dictionary < int , Type > IdToPacket = new Dictionary < int , Type > ( ) ;
private int PacketIdCounter ;
2020-08-06 20:49:51 +02:00
/// <summary>Refers to the peer it is registered to</summary>
2020-08-05 03:21:04 +02:00
public Peer Peer ;
2020-08-06 20:49:51 +02:00
/// <summary>Unique identifier for the protocol. This should be different for every protocol.</summary>
2020-08-05 03:21:04 +02:00
public abstract byte Identifier { get ; }
2020-08-06 20:49:51 +02:00
/// <summary>Version of the protocol, should be changed if existing packets are changed, new packets are registered or old packets are removed.</summary>
2020-08-05 03:21:04 +02:00
public abstract string Version { get ; }
2020-08-06 20:49:51 +02:00
/// <summary>Called when the Peer receives a packet from a connection that uses this protocol</summary>
2020-08-05 03:21:04 +02:00
public abstract void Receive ( Connection conn , Packet packet ) ;
2020-08-06 20:49:51 +02:00
/// <summary>Called when a ConnectionStatus is changed for a connection that uses this protocol</summary>
2020-08-05 03:21:04 +02:00
public abstract void ConnectionStatusChanged ( ConnectionStatus oldStatus , ConnectionStatus newStatus , Connection conn ) ;
2020-08-06 20:49:51 +02:00
/// <summary>Called when a connection that uses this protocol is timed out suddenly.</summary>
2020-08-05 03:21:04 +02:00
public abstract void Timeout ( Connection conn ) ;
2020-08-06 20:49:51 +02:00
/// <summary>Register a packet for sending and receiving.</summary>
2020-08-05 03:21:04 +02:00
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 ) ;
2020-08-05 20:38:37 +02:00
buffer . Write ( Version ) ;
2020-08-05 03:21:04 +02:00
} 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 ) ;
2020-08-05 20:38:37 +02:00
buffer . Write ( connection . Internal . LatestInwardReliable ) ;
2020-08-10 22:18:37 +02:00
buffer . Write ( connection . Internal . CurrentFirstPacket ) ;
2020-08-05 03:21:04 +02:00
}
return buffer ;
}
2020-08-05 18:50:28 +02:00
public int GetPacketTypeID ( Packet packet ) {
2020-08-05 03:21:04 +02:00
return PacketToId [ packet . GetType ( ) ] ;
}
public Type GetPacketType ( int id ) {
return IdToPacket [ id ] ;
}
}
}