Did namespace reworking, fixed incorrectversion, added chat

This commit is contained in:
Sofia 2020-08-05 19:50:28 +03:00
parent 7b426f4f8c
commit fe2eca36c9
21 changed files with 187 additions and 58 deletions

View File

@ -1,30 +1,45 @@
using System.Collections; using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using NeonTea.Quakeball.Net.Peers; using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.Net.Packets;
using System;
namespace NeonTea.Quakeball.Net { namespace NeonTea.Quakeball.Net {
public class CanvasInput : MonoBehaviour, PeerMessageListener { public class CanvasInput : MonoBehaviour, PeerMessageListener {
public Button Host; public Button Host;
public Button Join; public Button Join;
public Button Stop; public Button Stop;
public Button Send;
public InputField HostAddr; public InputField HostAddr;
public InputField Port; public InputField Port;
public InputField MessageField;
public Text TextField; public Text TextField;
private static List<string> Stuff = new List<string>(); private static List<string> Stuff = new List<string>();
void Start() { void Start() {
Host.onClick.AddListener(() => { Host.onClick.AddListener(() => {
Net.Singleton.StartServer("0.0.0.0", 8080, this); string addr = String.IsNullOrWhiteSpace(HostAddr.text) ? "0.0.0.0" : HostAddr.text;
string port = String.IsNullOrWhiteSpace(Port.text) ? "8080" : Port.text;
Debug.Log(addr);
Net.Singleton.StartServer(addr, Int32.Parse(port), this);
}); });
Join.onClick.AddListener(() => { Join.onClick.AddListener(() => {
Net.Singleton.StartClient("127.0.0.1", 8080, this); string addr = String.IsNullOrWhiteSpace(HostAddr.text) ? "127.0.0.1" : HostAddr.text;
string port = String.IsNullOrWhiteSpace(Port.text) ? "8080" : Port.text;
Net.Singleton.StartClient(addr, Int32.Parse(port), this);
}); });
Stop.onClick.AddListener(() => { Stop.onClick.AddListener(() => {
Net.Singleton.Stop(); Net.Singleton.Stop();
}); });
Send.onClick.AddListener(() => {
if (Net.Singleton.Peer != null && Net.Singleton.Connections.Count > 0) {
HelloPckt pckt = new HelloPckt();
pckt.Text = MessageField.text;
Net.Singleton.Peer.SendReliable(Net.Singleton.Connections[0], pckt);
}
});
} }
void Update() { void Update() {
@ -33,7 +48,7 @@ namespace NeonTea.Quakeball.Net {
public void Message(string text) { public void Message(string text) {
Stuff.Add(text); Stuff.Add(text);
Debug.Log(string.Join(", ", Stuff.ToArray())); Debug.Log(text);
} }

View File

@ -1,8 +1,6 @@
using System.Collections.Generic; using UnityEngine;
using System; using NeonTea.Quakeball.TeaNet.Peers;
using UnityEngine; using System.Collections.Generic;
using NeonTea.Quakeball.Net.Peers;
using System.Threading;
namespace NeonTea.Quakeball.Net { namespace NeonTea.Quakeball.Net {
@ -11,6 +9,9 @@ namespace NeonTea.Quakeball.Net {
private static byte[] FP = new byte[] { 0xFF, 0xF7 }; private static byte[] FP = new byte[] { 0xFF, 0xF7 };
public Peer Peer; public Peer Peer;
public List<Connection> Connections = new List<Connection>();
public bool IsServer = false;
public void StartClient(string address, int port, PeerMessageListener listener) { public void StartClient(string address, int port, PeerMessageListener listener) {
if (Peer != null) { if (Peer != null) {
@ -29,6 +30,7 @@ namespace NeonTea.Quakeball.Net {
Debug.Log("Can not start multiple endpoints at once! Use Server if multiple connections are required."); Debug.Log("Can not start multiple endpoints at once! Use Server if multiple connections are required.");
return; return;
} }
IsServer = true;
Peer = new Peer(FP); Peer = new Peer(FP);
Peer.MessageListener = listener; Peer.MessageListener = listener;
Peer.Start(port); Peer.Start(port);

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 195df611d888d7248a7d4d22f10dfd71 guid: adeff8cbe20fc50429024e6798ae38ef
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -0,0 +1,17 @@
using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Packets {
public class HelloPckt : Packet {
public string Text;
public override void Read(ByteBuffer buffer) {
Text = buffer.ReadString();
}
public override void Write(ByteBuffer buffer) {
buffer.WriteString(Text);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3990dcb6938054946ad2a33e57d2aaa7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,8 +1,8 @@
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using UnityEngine; using UnityEngine;
using NeonTea.Quakeball.Net.Peers; using NeonTea.Quakeball.TeaNet.Peers;
using NeonTea.Quakeball.Net; using NeonTea.Quakeball.TeaNet.Packets;
using NeonTea.Quakeball.Net.Packets; using NeonTea.Quakeball.Net.Packets;
namespace NeonTea.Quakeball.Net { namespace NeonTea.Quakeball.Net {
@ -10,14 +10,26 @@ namespace NeonTea.Quakeball.Net {
public class TestProtocol : Protocol { public class TestProtocol : Protocol {
public override byte Identifier => 0x7A; public override byte Identifier => 0x7A;
public override string Version => "0.0.1"; public override string Version => "0.0.2";
public TestProtocol() {
RegisterPacket(typeof(HelloPckt));
}
public override void ConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, Connection conn) { public override void ConnectionStatusChanged(ConnectionStatus oldStatus, ConnectionStatus newStatus, Connection conn) {
Peer.MessageListener.Message($"Connection Status Changed into {newStatus.ToString()} for {conn.Endpoint}"); Peer.MessageListener.Message($"Connection Status Changed into {newStatus.ToString()} for {conn.Endpoint}");
if (newStatus == ConnectionStatus.Ready && !Net.Singleton.Connections.Contains(conn)) {
Net.Singleton.Connections.Add(conn);
} else if (newStatus == ConnectionStatus.Closed) {
Net.Singleton.Peer.MessageListener.Message($"Conncection closed: {conn.ClosingReason}");
}
} }
public override void Receive(Connection conn, Packet packet) { public override void Receive(Connection conn, Packet packet) {
Peer.MessageListener.Message($"Received packet from {conn.Endpoint}"); if (packet is HelloPckt) {
HelloPckt Hello = (HelloPckt)packet;
Peer.MessageListener.Message($"Received HelloPckt: {Hello.Text}");
}
} }
public override void Timeout(Connection conn) { public override void Timeout(Connection conn) {

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fc8812ec471e62b4f9c75b88e23ce48b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 195df611d888d7248a7d4d22f10dfd71
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -2,12 +2,23 @@ using System.Collections.Generic;
using System; using System;
using System.Text; using System.Text;
namespace NeonTea.Quakeball.Net.Packets { namespace NeonTea.Quakeball.TeaNet.Packets {
public abstract class Packet { public abstract class Packet {
public int id; public bool Reliable = true;
public int Id;
public abstract void Write(ByteBuffer buffer); public abstract void Write(ByteBuffer buffer);
public abstract void Read(ByteBuffer buffer); public abstract void Read(ByteBuffer buffer);
public void ReadMeta(ByteBuffer buffer) {
Id = buffer.ReadInt();
Reliable = buffer.ReadBool();
}
public void WriteMeta(ByteBuffer buffer) {
buffer.WriteInt(Id);
buffer.WriteBool(Reliable);
}
} }
public enum PacketStage { public enum PacketStage {
@ -19,9 +30,9 @@ namespace NeonTea.Quakeball.Net.Packets {
public enum ClosingReason { public enum ClosingReason {
Unknown = 0, Unknown = 0,
IncorrectVersion = 1,
} }
public class ByteBuffer { public class ByteBuffer {
private List<byte> Bytes; private List<byte> Bytes;
private int pos = 0; private int pos = 0;
@ -42,6 +53,10 @@ namespace NeonTea.Quakeball.Net.Packets {
return pos < Bytes.Count; return pos < Bytes.Count;
} }
public bool ReadBool() {
return Read() == 1;
}
public int ReadInt() { public int ReadInt() {
return BitConverter.ToInt32(Read(4), 0); return BitConverter.ToInt32(Read(4), 0);
} }
@ -62,6 +77,10 @@ namespace NeonTea.Quakeball.Net.Packets {
return Bytes[pos++]; return Bytes[pos++];
} }
public void WriteBool(bool b) {
Write(b ? (byte)0b1 : (byte)0b0);
}
public void WriteInt(int i) { public void WriteInt(int i) {
Bytes.AddRange(BitConverter.GetBytes(i)); Bytes.AddRange(BitConverter.GetBytes(i));
} }
@ -110,9 +129,27 @@ namespace NeonTea.Quakeball.Net.Packets {
case 0: case 0:
reason = ClosingReason.Unknown; reason = ClosingReason.Unknown;
break; break;
case 1:
reason = ClosingReason.IncorrectVersion;
break;
} }
return reason; return reason;
} }
public void WritePacket(Protocol protocol, Packet p) {
WriteInt(protocol.GetPacketTypeID(p));
p.WriteMeta(this);
p.Write(this);
}
public Packet ReadPacket(Protocol protocol) {
int packetType = ReadInt();
Type t = protocol.GetPacketType(packetType);
Packet p = (Packet)Activator.CreateInstance(t);
p.ReadMeta(this);
p.Read(this);
return p;
}
} }
} }

View File

@ -1,10 +1,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System; using System;
using NeonTea.Quakeball.Net.Peers; using NeonTea.Quakeball.TeaNet.Peers;
namespace NeonTea.Quakeball.Net.Packets { namespace NeonTea.Quakeball.TeaNet.Packets {
public abstract class Protocol { public abstract class Protocol {
private Dictionary<Type, int> PacketToId = new Dictionary<Type, int>(); private Dictionary<Type, int> PacketToId = new Dictionary<Type, int>();
private Dictionary<int, Type> IdToPacket = new Dictionary<int, Type>(); private Dictionary<int, Type> IdToPacket = new Dictionary<int, Type>();
@ -41,7 +41,6 @@ namespace NeonTea.Quakeball.Net.Packets {
} }
buffer.Write(Identifier); buffer.Write(Identifier);
if (connection.Status == ConnectionStatus.Establishing) { if (connection.Status == ConnectionStatus.Establishing) {
Peer.MessageListener.Message("Sending Establishing");
buffer.Write((byte)PacketStage.Establishing); buffer.Write((byte)PacketStage.Establishing);
buffer.WriteString(Version); buffer.WriteString(Version);
} else if (connection.Status == ConnectionStatus.Closed) { } else if (connection.Status == ConnectionStatus.Closed) {
@ -51,12 +50,12 @@ namespace NeonTea.Quakeball.Net.Packets {
buffer.Write((byte)connection.ClosingReason); buffer.Write((byte)connection.ClosingReason);
} else if (connection.Status == ConnectionStatus.Ready) { } else if (connection.Status == ConnectionStatus.Ready) {
buffer.Write((byte)PacketStage.Ready); buffer.Write((byte)PacketStage.Ready);
buffer.WriteInt(connection.LatestPacketReceived); buffer.WriteInt(connection.LatestInwardReliable);
} }
return buffer; return buffer;
} }
public int GetPacketID(Packet packet) { public int GetPacketTypeID(Packet packet) {
return PacketToId[packet.GetType()]; return PacketToId[packet.GetType()];
} }

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System; using System;
using NeonTea.Quakeball.Net.Packets; using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net { namespace NeonTea.Quakeball.TeaNet.Peers {
public class Connection { public class Connection {
public IPEndPoint Endpoint; public IPEndPoint Endpoint;
@ -14,9 +14,13 @@ namespace NeonTea.Quakeball.Net {
public ClosingReason ClosingReason; public ClosingReason ClosingReason;
public long LastMessage; public long LastMessage;
public int LatestPacketSent; // Last Packet ID the connection has told us they have public int LatestOutwardReliable = -1; // Last reliable Packet ID the connection has told us they have
public int LatestPacketReceived; // Last Packet ID we've received from the connection public int LatestOutwardUnreliable = -1; // Last unreliablePacket ID the connection has told us they have
public int PacketIDCounter; // Packet ID counter for packets we're sending them public int LatestInwardReliable = -1; // Last reliable Packet ID we've received from the connection
public int LatestInwardUnreliable = -1; // Last unreliable Packet ID we've received from the connection
public int ReliablePacketIDCounter; // Reliable Packet ID counter for packets we're sending them
public int UnreliablePacketIDCounter; // Unreliable Packet ID counter for packets we're sending them
public Connection(IPEndPoint endpoint, ConnectionStatus status = ConnectionStatus.Establishing) { public Connection(IPEndPoint endpoint, ConnectionStatus status = ConnectionStatus.Establishing) {
Endpoint = endpoint; Endpoint = endpoint;

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: bee661c56fae81b4885405c7da9fbb08 guid: 560e96a51f4b686409986c4ea873941a
MonoImporter: MonoImporter:
externalObjects: {} externalObjects: {}
serializedVersion: 2 serializedVersion: 2

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Net; using System.Net;
using System.Threading; using System.Threading;
using System; using System;
using NeonTea.Quakeball.Net.Packets; using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Peers { namespace NeonTea.Quakeball.TeaNet.Peers {
public class ConnectionManager { public class ConnectionManager {
private Dictionary<IPEndPoint, Connection> Connections = new Dictionary<IPEndPoint, Connection>(); private Dictionary<IPEndPoint, Connection> Connections = new Dictionary<IPEndPoint, Connection>();
private Dictionary<Connection, List<Packet>> PacketQueue = new Dictionary<Connection, List<Packet>>(); private Dictionary<Connection, List<Packet>> PacketQueue = new Dictionary<Connection, List<Packet>>();
@ -48,7 +48,7 @@ namespace NeonTea.Quakeball.Net.Peers {
} }
public void AddPacketToQueue(Connection conn, Packet p) { public void AddPacketToQueue(Connection conn, Packet p) {
p.id = conn.PacketIDCounter++; p.Id = conn.ReliablePacketIDCounter++;
PacketQueue[conn].Add(p); PacketQueue[conn].Add(p);
} }
@ -59,20 +59,20 @@ namespace NeonTea.Quakeball.Net.Peers {
List<Packet> list = PacketQueue[conn]; List<Packet> list = PacketQueue[conn];
buffer.WriteInt(list.Count); buffer.WriteInt(list.Count);
foreach (Packet p in list) { foreach (Packet p in list) {
buffer.WriteInt(protocol.GetPacketID(p)); buffer.WritePacket(protocol, p);
p.Write(buffer);
} }
Send(conn, buffer); Send(conn, buffer);
} }
} }
public void SendSinglePacket(Connection conn, Packet p) { public void SendSingleUnreliable(Connection conn, Packet p) {
p.Id = conn.UnreliablePacketIDCounter++;
p.Reliable = false;
Protocol protocol = Peer.GetProtocol(conn.AssignedProtocol); Protocol protocol = Peer.GetProtocol(conn.AssignedProtocol);
if (protocol != null) { if (protocol != null) {
ByteBuffer buffer = protocol.BuildMessage(conn); ByteBuffer buffer = protocol.BuildMessage(conn);
buffer.WriteInt(1); buffer.WriteInt(1);
buffer.WriteInt(protocol.GetPacketID(p)); buffer.WritePacket(protocol, p);
p.Write(buffer);
Send(conn, buffer); Send(conn, buffer);
} }
} }
@ -108,7 +108,7 @@ namespace NeonTea.Quakeball.Net.Peers {
string version = buffer.ReadString(); string version = buffer.ReadString();
if (protocol == null || !version.Equals(protocol.Version)) { if (protocol == null || !version.Equals(protocol.Version)) {
conn.Status = ConnectionStatus.Rejected; conn.Status = ConnectionStatus.Rejected;
conn.ClosingReason = ClosingReason.Unknown; conn.ClosingReason = ClosingReason.IncorrectVersion;
} else { } else {
conn.Status = ConnectionStatus.Ready; conn.Status = ConnectionStatus.Ready;
} }
@ -125,6 +125,9 @@ namespace NeonTea.Quakeball.Net.Peers {
} }
break; break;
case PacketStage.Closed: case PacketStage.Closed:
if (conn.Status == ConnectionStatus.Stopped) {
break;
}
conn.Status = ConnectionStatus.Stopped; conn.Status = ConnectionStatus.Stopped;
if (protocol != null) { if (protocol != null) {
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn); protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
@ -134,24 +137,29 @@ namespace NeonTea.Quakeball.Net.Peers {
if (conn.AssignedProtocol != protocolId || protocol == null) { if (conn.AssignedProtocol != protocolId || protocol == null) {
break; break;
} }
if (oldStatus == ConnectionStatus.Establishing) { if (oldStatus == ConnectionStatus.Establishing) { // Update connection status
conn.Status = ConnectionStatus.Ready; conn.Status = ConnectionStatus.Ready;
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn); protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
} }
conn.LatestPacketSent = buffer.ReadInt(); conn.LatestOutwardReliable = buffer.ReadInt();
List<Packet> list = PacketQueue[conn]; List<Packet> list = PacketQueue[conn];
list.RemoveAll(p => p.id <= conn.LatestPacketSent); list.RemoveAll(p => p.Id <= conn.LatestOutwardReliable);
PacketQueue[conn] = list; PacketQueue[conn] = list;
int PacketAmount = buffer.ReadInt(); int PacketAmount = buffer.ReadInt();
for (int i = 0; i < PacketAmount; i++) { for (int i = 0; i < PacketAmount; i++) {
int id = buffer.ReadInt(); Packet p = buffer.ReadPacket(protocol);
conn.LatestPacketReceived = Math.Max(conn.LatestPacketReceived, id); if (p.Reliable) {
Type t = protocol.GetPacketType(id); if (p.Id > conn.LatestInwardReliable) {
Packet p = (Packet)Activator.CreateInstance(t); conn.LatestInwardReliable = p.Id;
p.Read(buffer);
protocol.Receive(conn, p); protocol.Receive(conn, p);
} }
} else if (p.Id > conn.LatestInwardUnreliable) {
conn.LatestInwardUnreliable = p.Id;
protocol.Receive(conn, p);
}
}
break; break;
} }
} }
@ -190,7 +198,7 @@ namespace NeonTea.Quakeball.Net.Peers {
Thread.Sleep((int)Interval); Thread.Sleep((int)Interval);
} }
} catch (ThreadAbortException) { } catch (ThreadAbortException) {
Debug.Log("Connection Thread Stopped"); Peer.MessageListener.Message("Connection Thread Stopped");
} }
} }
} }

View File

@ -4,9 +4,9 @@ using System;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using System.Threading;
using NeonTea.Quakeball.Net.Packets; using NeonTea.Quakeball.TeaNet.Packets;
namespace NeonTea.Quakeball.Net.Peers { namespace NeonTea.Quakeball.TeaNet.Peers {
public class ListenerThread { public class ListenerThread {
private IPEndPoint EndPoint; private IPEndPoint EndPoint;
private Thread Thread; private Thread Thread;
@ -37,7 +37,6 @@ namespace NeonTea.Quakeball.Net.Peers {
if (Thread == null) { if (Thread == null) {
return false; return false;
} }
Debug.Log("Stopping ListenerThread!");
Thread.Abort(); Thread.Abort();
return true; return true;
} }
@ -66,7 +65,7 @@ namespace NeonTea.Quakeball.Net.Peers {
} }
} }
} catch (ThreadAbortException) { } catch (ThreadAbortException) {
Debug.Log("Listener Thread stopped"); Peer.MessageListener.Message("Listener Thread stopped");
} }
} }
} }

View File

@ -3,12 +3,9 @@ using UnityEngine;
using System; using System;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Threading; using NeonTea.Quakeball.TeaNet.Packets;
using NeonTea.Quakeball.Net.Packets;
using System.Threading.Tasks;
using System.Runtime.Remoting;
namespace NeonTea.Quakeball.Net.Peers { namespace NeonTea.Quakeball.TeaNet.Peers {
public class Peer : PeerMessageListener { public class Peer : PeerMessageListener {
public UdpClient UdpClient { get; private set; } public UdpClient UdpClient { get; private set; }
public byte[] Fingerprint { get; private set; } public byte[] Fingerprint { get; private set; }
@ -45,6 +42,9 @@ namespace NeonTea.Quakeball.Net.Peers {
} }
private void StartListen(IPEndPoint endpoint) { private void StartListen(IPEndPoint endpoint) {
if (ListenerThread != null) {
return; // Cant listen twice
}
ListenerThread = new ListenerThread(this, endpoint); ListenerThread = new ListenerThread(this, endpoint);
ListenerThread.Start(); ListenerThread.Start();
MessageListener.Message($"Started listening to {endpoint}"); MessageListener.Message($"Started listening to {endpoint}");
@ -58,6 +58,15 @@ namespace NeonTea.Quakeball.Net.Peers {
MessageListener.Message($"Connecting to {endpoint}"); MessageListener.Message($"Connecting to {endpoint}");
} }
public void SendReliable(Connection conn, Packet packet) {
ConnectionManager.AddPacketToQueue(conn, packet);
ConnectionManager.SendPacketQueue(conn);
}
public void SendUnreliable(Connection conn, Packet packet) {
ConnectionManager.SendSingleUnreliable(conn, packet);
}
public byte RegisterProtocol(Protocol protocol) { public byte RegisterProtocol(Protocol protocol) {
byte ident = protocol.Identifier; byte ident = protocol.Identifier;
if (RegisteredProtocols.ContainsKey(ident)) { if (RegisteredProtocols.ContainsKey(ident)) {