Did namespace reworking, fixed incorrectversion, added chat
This commit is contained in:
parent
7b426f4f8c
commit
fe2eca36c9
@ -1,30 +1,45 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using NeonTea.Quakeball.Net.Peers;
|
||||
using NeonTea.Quakeball.TeaNet.Peers;
|
||||
using NeonTea.Quakeball.Net.Packets;
|
||||
using System;
|
||||
|
||||
namespace NeonTea.Quakeball.Net {
|
||||
public class CanvasInput : MonoBehaviour, PeerMessageListener {
|
||||
public Button Host;
|
||||
public Button Join;
|
||||
public Button Stop;
|
||||
public Button Send;
|
||||
public InputField HostAddr;
|
||||
public InputField Port;
|
||||
public InputField MessageField;
|
||||
public Text TextField;
|
||||
|
||||
private static List<string> Stuff = new List<string>();
|
||||
|
||||
void Start() {
|
||||
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(() => {
|
||||
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(() => {
|
||||
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() {
|
||||
@ -33,7 +48,7 @@ namespace NeonTea.Quakeball.Net {
|
||||
|
||||
public void Message(string text) {
|
||||
Stuff.Add(text);
|
||||
Debug.Log(string.Join(", ", Stuff.ToArray()));
|
||||
Debug.Log(text);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using NeonTea.Quakeball.Net.Peers;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using NeonTea.Quakeball.TeaNet.Peers;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace NeonTea.Quakeball.Net {
|
||||
|
||||
@ -11,6 +9,9 @@ namespace NeonTea.Quakeball.Net {
|
||||
private static byte[] FP = new byte[] { 0xFF, 0xF7 };
|
||||
|
||||
public Peer Peer;
|
||||
public List<Connection> Connections = new List<Connection>();
|
||||
|
||||
public bool IsServer = false;
|
||||
|
||||
public void StartClient(string address, int port, PeerMessageListener listener) {
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
IsServer = true;
|
||||
Peer = new Peer(FP);
|
||||
Peer.MessageListener = listener;
|
||||
Peer.Start(port);
|
||||
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 195df611d888d7248a7d4d22f10dfd71
|
||||
guid: adeff8cbe20fc50429024e6798ae38ef
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
|
17
Assets/Scripts/Net/Packets/HelloPckt.cs
Normal file
17
Assets/Scripts/Net/Packets/HelloPckt.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Scripts/Net/Packets/HelloPckt.cs.meta
Normal file
11
Assets/Scripts/Net/Packets/HelloPckt.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3990dcb6938054946ad2a33e57d2aaa7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,8 +1,8 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using NeonTea.Quakeball.Net.Peers;
|
||||
using NeonTea.Quakeball.Net;
|
||||
using NeonTea.Quakeball.TeaNet.Peers;
|
||||
using NeonTea.Quakeball.TeaNet.Packets;
|
||||
using NeonTea.Quakeball.Net.Packets;
|
||||
|
||||
namespace NeonTea.Quakeball.Net {
|
||||
@ -10,14 +10,26 @@ namespace NeonTea.Quakeball.Net {
|
||||
public class TestProtocol : Protocol {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
|
8
Assets/Scripts/TeaNet.meta
Normal file
8
Assets/Scripts/TeaNet.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc8812ec471e62b4f9c75b88e23ce48b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
Assets/Scripts/TeaNet/Packets.meta
Normal file
8
Assets/Scripts/TeaNet/Packets.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 195df611d888d7248a7d4d22f10dfd71
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -2,12 +2,23 @@ using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace NeonTea.Quakeball.Net.Packets {
|
||||
namespace NeonTea.Quakeball.TeaNet.Packets {
|
||||
public abstract class Packet {
|
||||
public int id;
|
||||
public bool Reliable = true;
|
||||
public int Id;
|
||||
|
||||
public abstract void Write(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 {
|
||||
@ -19,9 +30,9 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
|
||||
public enum ClosingReason {
|
||||
Unknown = 0,
|
||||
IncorrectVersion = 1,
|
||||
}
|
||||
|
||||
|
||||
public class ByteBuffer {
|
||||
private List<byte> Bytes;
|
||||
private int pos = 0;
|
||||
@ -42,6 +53,10 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
return pos < Bytes.Count;
|
||||
}
|
||||
|
||||
public bool ReadBool() {
|
||||
return Read() == 1;
|
||||
}
|
||||
|
||||
public int ReadInt() {
|
||||
return BitConverter.ToInt32(Read(4), 0);
|
||||
}
|
||||
@ -62,6 +77,10 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
return Bytes[pos++];
|
||||
}
|
||||
|
||||
public void WriteBool(bool b) {
|
||||
Write(b ? (byte)0b1 : (byte)0b0);
|
||||
}
|
||||
|
||||
public void WriteInt(int i) {
|
||||
Bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
@ -110,9 +129,27 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
case 0:
|
||||
reason = ClosingReason.Unknown;
|
||||
break;
|
||||
case 1:
|
||||
reason = ClosingReason.IncorrectVersion;
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
using System.Collections.Generic;
|
||||
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 {
|
||||
private Dictionary<Type, int> PacketToId = new Dictionary<Type, int>();
|
||||
private Dictionary<int, Type> IdToPacket = new Dictionary<int, Type>();
|
||||
@ -41,7 +41,6 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
}
|
||||
buffer.Write(Identifier);
|
||||
if (connection.Status == ConnectionStatus.Establishing) {
|
||||
Peer.MessageListener.Message("Sending Establishing");
|
||||
buffer.Write((byte)PacketStage.Establishing);
|
||||
buffer.WriteString(Version);
|
||||
} else if (connection.Status == ConnectionStatus.Closed) {
|
||||
@ -51,12 +50,12 @@ namespace NeonTea.Quakeball.Net.Packets {
|
||||
buffer.Write((byte)connection.ClosingReason);
|
||||
} else if (connection.Status == ConnectionStatus.Ready) {
|
||||
buffer.Write((byte)PacketStage.Ready);
|
||||
buffer.WriteInt(connection.LatestPacketReceived);
|
||||
buffer.WriteInt(connection.LatestInwardReliable);
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public int GetPacketID(Packet packet) {
|
||||
public int GetPacketTypeID(Packet packet) {
|
||||
return PacketToId[packet.GetType()];
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Net;
|
||||
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 IPEndPoint Endpoint;
|
||||
@ -14,9 +14,13 @@ namespace NeonTea.Quakeball.Net {
|
||||
public ClosingReason ClosingReason;
|
||||
|
||||
public long LastMessage;
|
||||
public int LatestPacketSent; // Last Packet ID the connection has told us they have
|
||||
public int LatestPacketReceived; // Last Packet ID we've received from the connection
|
||||
public int PacketIDCounter; // Packet ID counter for packets we're sending them
|
||||
public int LatestOutwardReliable = -1; // Last reliable Packet ID the connection has told us they have
|
||||
public int LatestOutwardUnreliable = -1; // Last unreliablePacket ID the connection has told us they have
|
||||
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) {
|
||||
Endpoint = endpoint;
|
@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bee661c56fae81b4885405c7da9fbb08
|
||||
guid: 560e96a51f4b686409986c4ea873941a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
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 {
|
||||
private Dictionary<IPEndPoint, Connection> Connections = new Dictionary<IPEndPoint, Connection>();
|
||||
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) {
|
||||
p.id = conn.PacketIDCounter++;
|
||||
p.Id = conn.ReliablePacketIDCounter++;
|
||||
PacketQueue[conn].Add(p);
|
||||
}
|
||||
|
||||
@ -59,20 +59,20 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
List<Packet> list = PacketQueue[conn];
|
||||
buffer.WriteInt(list.Count);
|
||||
foreach (Packet p in list) {
|
||||
buffer.WriteInt(protocol.GetPacketID(p));
|
||||
p.Write(buffer);
|
||||
buffer.WritePacket(protocol, p);
|
||||
}
|
||||
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);
|
||||
if (protocol != null) {
|
||||
ByteBuffer buffer = protocol.BuildMessage(conn);
|
||||
buffer.WriteInt(1);
|
||||
buffer.WriteInt(protocol.GetPacketID(p));
|
||||
p.Write(buffer);
|
||||
buffer.WritePacket(protocol, p);
|
||||
Send(conn, buffer);
|
||||
}
|
||||
}
|
||||
@ -108,7 +108,7 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
string version = buffer.ReadString();
|
||||
if (protocol == null || !version.Equals(protocol.Version)) {
|
||||
conn.Status = ConnectionStatus.Rejected;
|
||||
conn.ClosingReason = ClosingReason.Unknown;
|
||||
conn.ClosingReason = ClosingReason.IncorrectVersion;
|
||||
} else {
|
||||
conn.Status = ConnectionStatus.Ready;
|
||||
}
|
||||
@ -125,6 +125,9 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
}
|
||||
break;
|
||||
case PacketStage.Closed:
|
||||
if (conn.Status == ConnectionStatus.Stopped) {
|
||||
break;
|
||||
}
|
||||
conn.Status = ConnectionStatus.Stopped;
|
||||
if (protocol != null) {
|
||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
||||
@ -134,24 +137,29 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
if (conn.AssignedProtocol != protocolId || protocol == null) {
|
||||
break;
|
||||
}
|
||||
if (oldStatus == ConnectionStatus.Establishing) {
|
||||
if (oldStatus == ConnectionStatus.Establishing) { // Update connection status
|
||||
conn.Status = ConnectionStatus.Ready;
|
||||
protocol.ConnectionStatusChanged(oldStatus, conn.Status, conn);
|
||||
}
|
||||
conn.LatestPacketSent = buffer.ReadInt();
|
||||
conn.LatestOutwardReliable = buffer.ReadInt();
|
||||
|
||||
List<Packet> list = PacketQueue[conn];
|
||||
list.RemoveAll(p => p.id <= conn.LatestPacketSent);
|
||||
list.RemoveAll(p => p.Id <= conn.LatestOutwardReliable);
|
||||
PacketQueue[conn] = list;
|
||||
|
||||
int PacketAmount = buffer.ReadInt();
|
||||
for (int i = 0; i < PacketAmount; i++) {
|
||||
int id = buffer.ReadInt();
|
||||
conn.LatestPacketReceived = Math.Max(conn.LatestPacketReceived, id);
|
||||
Type t = protocol.GetPacketType(id);
|
||||
Packet p = (Packet)Activator.CreateInstance(t);
|
||||
p.Read(buffer);
|
||||
Packet p = buffer.ReadPacket(protocol);
|
||||
if (p.Reliable) {
|
||||
if (p.Id > conn.LatestInwardReliable) {
|
||||
conn.LatestInwardReliable = p.Id;
|
||||
protocol.Receive(conn, p);
|
||||
}
|
||||
} else if (p.Id > conn.LatestInwardUnreliable) {
|
||||
conn.LatestInwardUnreliable = p.Id;
|
||||
protocol.Receive(conn, p);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -190,7 +198,7 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
Thread.Sleep((int)Interval);
|
||||
}
|
||||
} catch (ThreadAbortException) {
|
||||
Debug.Log("Connection Thread Stopped");
|
||||
Peer.MessageListener.Message("Connection Thread Stopped");
|
||||
}
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@ using System;
|
||||
using System.Net.Sockets;
|
||||
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 {
|
||||
private IPEndPoint EndPoint;
|
||||
private Thread Thread;
|
||||
@ -37,7 +37,6 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
if (Thread == null) {
|
||||
return false;
|
||||
}
|
||||
Debug.Log("Stopping ListenerThread!");
|
||||
Thread.Abort();
|
||||
return true;
|
||||
}
|
||||
@ -66,7 +65,7 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
}
|
||||
}
|
||||
} catch (ThreadAbortException) {
|
||||
Debug.Log("Listener Thread stopped");
|
||||
Peer.MessageListener.Message("Listener Thread stopped");
|
||||
}
|
||||
}
|
||||
}
|
@ -3,12 +3,9 @@ using UnityEngine;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using NeonTea.Quakeball.Net.Packets;
|
||||
using System.Threading.Tasks;
|
||||
using System.Runtime.Remoting;
|
||||
using NeonTea.Quakeball.TeaNet.Packets;
|
||||
|
||||
namespace NeonTea.Quakeball.Net.Peers {
|
||||
namespace NeonTea.Quakeball.TeaNet.Peers {
|
||||
public class Peer : PeerMessageListener {
|
||||
public UdpClient UdpClient { get; private set; }
|
||||
public byte[] Fingerprint { get; private set; }
|
||||
@ -45,6 +42,9 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
}
|
||||
|
||||
private void StartListen(IPEndPoint endpoint) {
|
||||
if (ListenerThread != null) {
|
||||
return; // Cant listen twice
|
||||
}
|
||||
ListenerThread = new ListenerThread(this, endpoint);
|
||||
ListenerThread.Start();
|
||||
MessageListener.Message($"Started listening to {endpoint}");
|
||||
@ -58,6 +58,15 @@ namespace NeonTea.Quakeball.Net.Peers {
|
||||
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) {
|
||||
byte ident = protocol.Identifier;
|
||||
if (RegisteredProtocols.ContainsKey(ident)) {
|
Loading…
Reference in New Issue
Block a user