17 changed files with 377 additions and 179 deletions
@ -1,34 +0,0 @@ |
|||
using Godot; |
|||
|
|||
public class Client : Peer { |
|||
|
|||
private PacketPeerUDP PacketPeer; |
|||
|
|||
private Connection ServerConn; |
|||
|
|||
private byte[] TempBuffer = {1}; |
|||
private float Timer = 0; |
|||
|
|||
public Client(PacketPeerUDP packetPeer) : base(packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
} |
|||
|
|||
public override void Initialize(string address, int port) { |
|||
GD.print("Start client."); |
|||
GD.print("Starting to send stuff to " + address + ":" + port); |
|||
ServerConn = new Connection(address, port); |
|||
StartListening(port, "*"); |
|||
} |
|||
|
|||
public override void ReceivePacket(byte[] buffer, string address, int port) { |
|||
GD.print("Client received stuff from " + address + " : " + port + " :"); |
|||
} |
|||
|
|||
public override void Update(float delta) { |
|||
Timer += delta; |
|||
if (Timer < 1) { return; } |
|||
Timer = 0; |
|||
GD.print("Update client."); |
|||
SendBuffer(TempBuffer, ServerConn); |
|||
} |
|||
} |
@ -1,13 +0,0 @@ |
|||
|
|||
public class Connection { |
|||
|
|||
private static int IDCounter = 0; |
|||
public readonly int ID = IDCounter++; |
|||
public string Address; |
|||
public int Port; |
|||
|
|||
public Connection(string address, int port) { |
|||
Address = address; |
|||
Port = port; |
|||
} |
|||
} |
@ -1,38 +0,0 @@ |
|||
using Godot; |
|||
using System; |
|||
|
|||
public class Net : Node { |
|||
|
|||
private PacketPeerUDP PacketPeer; |
|||
private Client Client; |
|||
private Server Server; |
|||
|
|||
public bool IsClient { get { return Client != null; } } |
|||
public bool IsServer { get { return Server != null; } } |
|||
|
|||
public override void _Ready() { |
|||
PacketPeer = new PacketPeerUDP(); |
|||
} |
|||
|
|||
public override void _Process(float delta) { |
|||
if (IsServer) { Server.Update(delta); } |
|||
if (IsClient) { Client.Update(delta); } |
|||
} |
|||
|
|||
public override void _ExitTree() { |
|||
if (IsServer) { Server.Free(); } |
|||
if (IsClient) { Client.Free(); } |
|||
} |
|||
|
|||
public void StartClient(string address, int port) { |
|||
if (IsClient || IsServer) { return; } |
|||
Client = new Client(PacketPeer); |
|||
Client.Initialize(address, port); |
|||
} |
|||
|
|||
public void StartServer(string address, int port) { |
|||
if (IsClient || IsServer) { return; } |
|||
Server = new Server(PacketPeer); |
|||
Server.Initialize(address, port); |
|||
} |
|||
} |
@ -1,50 +0,0 @@ |
|||
using Godot; |
|||
using System.Threading; |
|||
using Thread = System.Threading.Thread; |
|||
|
|||
public abstract class Peer : Object { |
|||
|
|||
private static PacketPeerUDP PacketPeer; |
|||
private static Peer Singleton; |
|||
private int LastConnectionSended = -1; |
|||
private Thread ListenerThread; |
|||
|
|||
public Peer(PacketPeerUDP packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
} |
|||
|
|||
public abstract void Initialize(string address, int port); |
|||
public abstract void Update(float delta); |
|||
public abstract void ReceivePacket(byte[] buffer, string address, int port); |
|||
|
|||
public void SendBuffer(byte[] buffer, Connection to) { |
|||
int temp1 = PacketPeer.SetDestAddress(to.Address, to.Port); |
|||
int temp2 = PacketPeer.PutPacket(buffer); |
|||
GD.print("Putting stuff to " + to.Address + ":" + to.Port); |
|||
} |
|||
|
|||
public bool StartListening(int port, string address = "*") { |
|||
if (PacketPeer.IsListening() || ListenerThread != null) { |
|||
GD.printerr("The Peer is already listening or the thread is active!"); |
|||
return false; |
|||
} |
|||
Singleton = this; |
|||
PacketPeer.Listen(port, address); |
|||
ThreadStart ChildRef = new ThreadStart(ListenerThreadMethod); |
|||
ListenerThread = new Thread(ChildRef); |
|||
ListenerThread.Start(); |
|||
return true; |
|||
} |
|||
|
|||
public static void ListenerThreadMethod() { |
|||
GD.print("Started Listener Thread."); |
|||
while (true) { |
|||
PacketPeer.Wait(); |
|||
byte[] Buffer = PacketPeer.GetPacket(); |
|||
string Address = PacketPeer.GetPacketIp(); |
|||
int Port = PacketPeer.GetPacketPort(); |
|||
Singleton.ReceivePacket(Buffer, Address, Port); |
|||
} |
|||
} |
|||
|
|||
} |
@ -1,30 +0,0 @@ |
|||
using Godot; |
|||
using System.Threading; |
|||
|
|||
public class Server : Peer { |
|||
|
|||
private static PacketPeerUDP PacketPeer; |
|||
|
|||
private byte[] TempBuffer = { 1 }; |
|||
|
|||
public Server(PacketPeerUDP packetPeer) : base(packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
} |
|||
|
|||
public override void Initialize(string address, int port) { |
|||
StartListening(port, address); |
|||
GD.print("Server initialization finished."); |
|||
GD.print("Started server on " + address + ":" + port); |
|||
} |
|||
|
|||
public override void ReceivePacket(byte[] buffer, string address, int port) { |
|||
GD.print("Server received stuff from " + address + " : " + port + " :"); |
|||
for (int i = 0; i < buffer.Length; i++) { |
|||
GD.print(buffer[i]); |
|||
} |
|||
SendBuffer(TempBuffer, new Connection(address, port)); |
|||
} |
|||
|
|||
public override void Update(float delta) { |
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
using Godot; |
|||
using Network.PacketHandling; |
|||
|
|||
namespace Network { |
|||
public class Client : Peer { |
|||
|
|||
private PacketPeerUDP PacketPeer; |
|||
|
|||
private Connection ServerConn; |
|||
|
|||
private PacketBuffer TempBuffer; |
|||
private float Timer = 0; |
|||
|
|||
public Client(PacketPeerUDP packetPeer) : base(packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
TempBuffer = NewPacketBuffer(); |
|||
TempBuffer.Write(1); |
|||
} |
|||
|
|||
public override void Initialize(string address, int port) { |
|||
GD.print("Start client."); |
|||
GD.print("Starting to send stuff to " + address + ":" + port); |
|||
ServerConn = new Connection(address, port); |
|||
ServerConn.Name = "Server"; |
|||
StartListening(port, "*"); |
|||
} |
|||
|
|||
public override void Update(float delta) { |
|||
Timer += delta; |
|||
if (Timer < 1) { return; } |
|||
Timer = 0; |
|||
SendBuffer(TempBuffer, ServerConn); |
|||
} |
|||
|
|||
public override void ReceivePacket(PacketBuffer packetBuffer, Connection connection) { |
|||
GD.print("Client received stuff from " + connection.Name + " at " + connection.Address + " : " + connection.Port + " :"); |
|||
while (packetBuffer.HasNext) { |
|||
GD.print(packetBuffer.Read()); |
|||
} |
|||
} |
|||
|
|||
public override void Connected(Connection conn) { |
|||
GD.print("Connected to " + conn.Name + " at " + conn.Address + ":" + conn.Port); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,23 @@ |
|||
|
|||
using System; |
|||
|
|||
namespace Network { |
|||
public class Connection { |
|||
|
|||
private static int IDCounter = 0; |
|||
public readonly int ID = IDCounter++; |
|||
public string Name; |
|||
public string Address; |
|||
public int Port; |
|||
|
|||
public Connection(string address, int port) { |
|||
Name = "Connection-" + ID; |
|||
Address = address; |
|||
Port = port; |
|||
} |
|||
|
|||
public bool Equals(Connection other) { |
|||
return other.Address == Address && other.Port == Port; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,45 @@ |
|||
|
|||
using System.Collections.Generic; |
|||
using Util; |
|||
|
|||
namespace Network { |
|||
public class ConnectionList { |
|||
|
|||
private Peer Peer; |
|||
private List<Connection> Connections; |
|||
|
|||
public int Length { get { return Connections.Count; } } |
|||
public Connection this[int i] { |
|||
get { |
|||
return Connections[i]; |
|||
} |
|||
} |
|||
|
|||
public bool AddConnection(Connection conn) { |
|||
if (!Contains(conn)) { |
|||
Connections.Add(conn); |
|||
Peer.Connected(conn); |
|||
return true; |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public bool Contains(Connection conn) { |
|||
foreach (Connection inList in Connections) { |
|||
if (inList.Equals(conn)) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public Optional<Connection> GetOriginal(Connection conn) { |
|||
foreach (Connection inList in Connections) { |
|||
if (inList.Equals(conn)) { |
|||
return inList; |
|||
} |
|||
} |
|||
return null; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,40 @@ |
|||
using Godot; |
|||
using System; |
|||
|
|||
namespace Network { |
|||
public class Net : Node { |
|||
|
|||
private PacketPeerUDP PacketPeer; |
|||
private Client Client; |
|||
private Server Server; |
|||
|
|||
public bool IsClient { get { return Client != null; } } |
|||
public bool IsServer { get { return Server != null; } } |
|||
|
|||
public override void _Ready() { |
|||
PacketPeer = new PacketPeerUDP(); |
|||
} |
|||
|
|||
public override void _Process(float delta) { |
|||
if (IsServer) { Server.Update(delta); } |
|||
if (IsClient) { Client.Update(delta); } |
|||
} |
|||
|
|||
public override void _ExitTree() { |
|||
if (IsServer) { Server.Free(); } |
|||
if (IsClient) { Client.Free(); } |
|||
} |
|||
|
|||
public void StartClient(string address, int port) { |
|||
if (IsClient || IsServer) { return; } |
|||
Client = new Client(PacketPeer); |
|||
Client.Initialize(address, port); |
|||
} |
|||
|
|||
public void StartServer(string address, int port) { |
|||
if (IsClient || IsServer) { return; } |
|||
Server = new Server(PacketPeer); |
|||
Server.Initialize(address, port); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,86 @@ |
|||
using Godot; |
|||
using Network.PacketHandling; |
|||
using System.Threading; |
|||
using Thread = System.Threading.Thread; |
|||
|
|||
namespace Network { |
|||
public abstract class Peer : Object { |
|||
|
|||
private static PacketPeerUDP PacketPeer; |
|||
private static Peer Singleton; |
|||
private int LastConnectionSended = -1; |
|||
private Thread ListenerThread; |
|||
|
|||
private static byte[] ConfirmationBytes = { 0b10011010, 0b11010011 }; |
|||
|
|||
public ConnectionList ConnectionList = new ConnectionList(); |
|||
|
|||
public Peer(PacketPeerUDP packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
} |
|||
|
|||
public abstract void Initialize(string address, int port); |
|||
public abstract void Update(float delta); |
|||
public abstract void ReceivePacket(PacketBuffer packetBuffer, Connection connection); |
|||
public abstract void Connected(Connection conn); |
|||
|
|||
public void SendBuffer(PacketBuffer packetBuffer, Connection to) { |
|||
if (LastConnectionSended != to.ID) { |
|||
PacketPeer.SetDestAddress(to.Address, to.Port); |
|||
LastConnectionSended = to.ID; |
|||
} |
|||
PacketPeer.PutPacket(packetBuffer.ByteBuffer); |
|||
GD.print("Putting stuff to " + to.Address + ":" + to.Port); |
|||
} |
|||
|
|||
public bool StartListening(int port, string address = "*") { |
|||
if (PacketPeer.IsListening() || ListenerThread != null) { |
|||
GD.printerr("The Peer is already listening or the thread is active!"); |
|||
return false; |
|||
} |
|||
Singleton = this; |
|||
PacketPeer.Listen(port, address); |
|||
ThreadStart ChildRef = new ThreadStart(ListenerThreadMethod); |
|||
ListenerThread = new Thread(ChildRef); |
|||
ListenerThread.Start(); |
|||
return true; |
|||
} |
|||
|
|||
public static PacketBuffer NewPacketBuffer() { |
|||
PacketBuffer PB = new PacketBuffer(); |
|||
foreach (byte B in ConfirmationBytes) { |
|||
PB.Write(B); |
|||
} |
|||
return PB; |
|||
} |
|||
|
|||
private static void ListenerThreadMethod() { |
|||
GD.print("Started Listener Thread."); |
|||
|
|||
while (true) { |
|||
|
|||
PacketPeer.Wait(); |
|||
byte[] Buffer = PacketPeer.GetPacket(); |
|||
string Address = PacketPeer.GetPacketIp(); |
|||
int Port = PacketPeer.GetPacketPort(); |
|||
|
|||
PacketBuffer PB = PacketBuffer.FromByteBuffer(Buffer); |
|||
if (PB.Length > ConfirmationBytes.Length) { |
|||
bool Confirmed = true; |
|||
foreach (byte B in ConfirmationBytes) { |
|||
if (PB.Read() != B) { |
|||
// Ignore packet, confirmation bytes don't match up.
|
|||
Confirmed = false; |
|||
break; |
|||
} |
|||
} |
|||
if (Confirmed) { |
|||
Connection conn = new Connection(Address, Port); |
|||
Singleton.ConnectionList.AddConnection(conn); |
|||
Singleton.ReceivePacket(PB, Singleton.ConnectionList.GetOriginal(conn)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,39 @@ |
|||
using Godot; |
|||
using Network.PacketHandling; |
|||
using System.Threading; |
|||
|
|||
namespace Network { |
|||
public class Server : Peer { |
|||
|
|||
private static PacketPeerUDP PacketPeer; |
|||
|
|||
private PacketBuffer TempBuffer; |
|||
|
|||
public Server(PacketPeerUDP packetPeer) : base(packetPeer) { |
|||
PacketPeer = packetPeer; |
|||
TempBuffer = NewPacketBuffer(); |
|||
TempBuffer.Write(2); |
|||
} |
|||
|
|||
public override void Initialize(string address, int port) { |
|||
StartListening(port, address); |
|||
GD.print("Server initialization finished."); |
|||
GD.print("Started server on " + address + ":" + port); |
|||
} |
|||
|
|||
public override void Update(float delta) { |
|||
} |
|||
|
|||
public override void ReceivePacket(PacketBuffer packetBuffer, Connection connection) { |
|||
GD.print("Server received stuff from " + connection.Name + " at " + connection.Address + " : " + connection.Port + " :"); |
|||
while (packetBuffer.HasNext) { |
|||
GD.print(packetBuffer.Read()); |
|||
} |
|||
SendBuffer(TempBuffer, connection); |
|||
} |
|||
|
|||
public override void Connected(Connection conn) { |
|||
GD.print("Someone connected at " + conn.Address + ":" + conn.Port); |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
using Godot; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Network.PacketHandling { |
|||
public class PacketBuffer { |
|||
|
|||
private List<byte> ByteList; |
|||
private int ReadCounter = 0; |
|||
|
|||
public byte[] ByteBuffer { get { return ByteList.ToArray(); } } |
|||
public int Length { get { return ByteList.Count; } } |
|||
public bool HasNext { get { return ReadCounter > ByteList.Count; } } |
|||
|
|||
public byte Read() { |
|||
if (!HasNext) { |
|||
GD.printerr("Attempted to read byte; Impossible, byte buffer ended."); |
|||
return 0; |
|||
} |
|||
return ByteList[ReadCounter++]; |
|||
} |
|||
|
|||
public void Write(byte toWrite) { |
|||
ByteList.Add(toWrite); |
|||
} |
|||
|
|||
public static PacketBuffer FromByteBuffer(byte[] byteBuffer) { |
|||
PacketBuffer PB = new PacketBuffer(); |
|||
PB.ByteList = new List<byte>(byteBuffer); |
|||
return PB; |
|||
} |
|||
|
|||
} |
|||
} |
@ -0,0 +1,46 @@ |
|||
|
|||
|
|||
namespace Util { |
|||
public class Optional<T> { |
|||
private T _Value; |
|||
public T Value { |
|||
get { |
|||
if (HasValue) { |
|||
return _Value; |
|||
} else { |
|||
throw new System.InvalidOperationException("Value of the Optional is null."); |
|||
} |
|||
} |
|||
set { |
|||
_Value = value; |
|||
} |
|||
} |
|||
|
|||
public Optional(T val) { |
|||
Value = val; |
|||
} |
|||
|
|||
public static explicit operator T(Optional<T> opt) { |
|||
return opt.Value; |
|||
} |
|||
|
|||
public static implicit operator Optional<T>(T val) { |
|||
return new Optional<T>(val); |
|||
} |
|||
|
|||
public static implicit operator T(Optional<T> opt) { |
|||
return opt.Value; |
|||
} |
|||
|
|||
public void Clear() { |
|||
_Value = default(T); |
|||
} |
|||
|
|||
public bool HasValue { get { return _Value != null; } } |
|||
public bool isEmpty { get { return !HasValue; } } |
|||
public bool Equals(Optional<T> opt) { |
|||
if (opt.HasValue == HasValue) { return Equals(opt.Value, Value); } |
|||
else { return opt.HasValue == HasValue; } |
|||
} |
|||
} |
|||
} |
Loading…
Reference in new issue