diff --git a/Assets/Scripts/Entities/Spawner.cs b/Assets/Scripts/Entities/Spawner.cs
index fffa743..c2ddf17 100644
--- a/Assets/Scripts/Entities/Spawner.cs
+++ b/Assets/Scripts/Entities/Spawner.cs
@@ -1,6 +1,4 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
+using UnityEngine;
using Cyber.Console;
namespace Cyber.Entities {
diff --git a/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs b/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs
new file mode 100644
index 0000000..37154b4
--- /dev/null
+++ b/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs
@@ -0,0 +1,26 @@
+using Cyber.Entities;
+
+namespace Cyber.Networking.Clientside {
+
+ ///
+ /// Represents a connected player on the clientside. This class is used by clients.
+ /// The C stands for "Client".
+ ///
+ class CConnectedPlayer {
+
+ ///
+ /// Connection ID on the global perspective.
+ ///
+ public readonly int ConnectionID;
+
+ ///
+ /// The player's controlled character.
+ ///
+ public Character Character;
+
+ public CConnectedPlayer(int connectionID) {
+ ConnectionID = connectionID;
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs.meta b/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs.meta
new file mode 100644
index 0000000..89a585b
--- /dev/null
+++ b/Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: f30b47eaf72d54f4099f5690a67965e3
+timeCreated: 1494285679
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Clientside/Client.cs b/Assets/Scripts/Networking/Clientside/Client.cs
index 941a139..954ed80 100644
--- a/Assets/Scripts/Networking/Clientside/Client.cs
+++ b/Assets/Scripts/Networking/Clientside/Client.cs
@@ -1,5 +1,6 @@
using Cyber.Console;
using Cyber.Networking.Messages;
+using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
@@ -9,6 +10,13 @@ namespace Cyber.Networking.Clientside {
/// Client-class used to connecting to a server and communicating to it.
/// Also handles all events incoming from the server and forwards them where they should be handled.
///
+ ///
+ /// The pipeline of requests sent by the client:
+ /// 1. Player sends command to server (e.g. player presses 'w') and then processes it on the client.
+ /// 2. Server receives the command and determines weather it's possible
+ /// 3. Server then sends the results(along with a timestamp) to the clients
+ /// 4. Clients receive their results and if the action was possible, starts the action and catches up to the server with the timestamp
+ ///
public class Client : MonoBehaviour {
private NetworkClient NetClient;
@@ -16,6 +24,12 @@ namespace Cyber.Networking.Clientside {
private static Client Singleton;
+ ///
+ /// The player of this client
+ ///
+ private CConnectedPlayer Player;
+ private List Players = new List();
+
///
/// Creates the client and sets it as the signleton.
///
@@ -88,6 +102,8 @@ namespace Cyber.Networking.Clientside {
Running = true;
NetClient.RegisterHandler(PktType.TextMessage, HandlePacket);
+ NetClient.RegisterHandler(PktType.Identity, HandlePacket);
+ NetClient.RegisterHandler(PktType.MassIdentity, HandlePacket);
NetClient.RegisterHandler(MsgType.Connect, OnConnected);
NetClient.RegisterHandler(MsgType.Disconnect, OnDisconnected);
@@ -104,10 +120,29 @@ namespace Cyber.Networking.Clientside {
private void HandlePacket(NetworkMessage msg) {
switch (msg.msgType) {
case (PktType.TextMessage):
- TextMessage TextMsg = new TextMessage();
+ TextMessagePkt TextMsg = new TextMessagePkt();
TextMsg.Deserialize(msg.reader);
Term.Println(TextMsg.Message);
break;
+ case (PktType.Identity):
+ IdentityPkt Identity = new IdentityPkt();
+ Identity.Deserialize(msg.reader);
+ var Conn = new CConnectedPlayer(Identity.ConnectionID);
+ if (Identity.Owned) {
+ Player = Conn;
+ } else {
+ Debug.Log(Conn.ConnectionID + " connected!");
+ Term.Println(Conn.ConnectionID + " connected!");
+ }
+ Players.Add(Conn);
+ break;
+ case (PktType.MassIdentity):
+ MassIdentityPkt Identities = new MassIdentityPkt();
+ Identities.Deserialize(msg.reader);
+ foreach (int currId in Identities.IdList) {
+ Players.Add(new CConnectedPlayer(currId));
+ }
+ break;
default:
Debug.LogError("Received an unknown packet, id: " + msg.msgType);
Term.Println("Received an unknown packet, id: " + msg.msgType);
@@ -123,7 +158,7 @@ namespace Cyber.Networking.Clientside {
Term.AddCommand("send (message)", "Send a message across the vastness of space and time!", (args) => {
Term.Println("You: " + args[0]);
- NetClient.Send(PktType.TextMessage, new TextMessage("A Client: " + args[0]));
+ NetClient.Send(PktType.TextMessage, new TextMessagePkt("A Client: " + args[0]));
});
}
diff --git a/Assets/Scripts/Networking/Messages/IdentityPkt.cs b/Assets/Scripts/Networking/Messages/IdentityPkt.cs
new file mode 100644
index 0000000..96d6ee8
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/IdentityPkt.cs
@@ -0,0 +1,54 @@
+using UnityEngine.Networking;
+
+namespace Cyber.Networking.Messages {
+
+ ///
+ /// Contains the Connection ID of the user and weather the ID belongs to the client or not.
+ ///
+ public class IdentityPkt : MessageBase {
+
+ ///
+ /// ID of the Connection
+ ///
+ public int ConnectionID;
+
+ ///
+ /// Weather the recieving client owns this ID or not.
+ ///
+ public bool Owned;
+
+ ///
+ /// Creates a packet containing an ID and the detail weather the recieving client owns this ID.
+ ///
+ /// ID of the connection.
+ /// Weather the recieving client owns this ID.
+ public IdentityPkt(int connectionID, bool owned) {
+ ConnectionID = connectionID;
+ Owned = owned;
+ }
+
+ ///
+ /// Parameter-less constructor using when deserializing the message.
+ ///
+ public IdentityPkt() {
+ }
+
+ ///
+ /// Used to deserialize a message received via networking.
+ ///
+ ///
+ public override void Deserialize(NetworkReader reader) {
+ ConnectionID = reader.ReadInt32();
+ Owned = reader.ReadBoolean();
+ }
+
+ ///
+ /// Used to serialize the message before it is sent.
+ ///
+ ///
+ public override void Serialize(NetworkWriter writer) {
+ writer.Write(ConnectionID);
+ writer.Write(Owned);
+ }
+ }
+}
diff --git a/Assets/Scripts/Networking/Messages/IdentityPkt.cs.meta b/Assets/Scripts/Networking/Messages/IdentityPkt.cs.meta
new file mode 100644
index 0000000..56c29bd
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/IdentityPkt.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: c30897b96fbb288409d685055ea44926
+timeCreated: 1494285679
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs b/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs
new file mode 100644
index 0000000..ceb7e83
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs
@@ -0,0 +1,38 @@
+
+using UnityEngine.Networking;
+
+namespace Cyber.Networking.Messages {
+
+ ///
+ /// Packet containing a list of ID's of players currently connected.
+ ///
+ public class MassIdentityPkt : MessageBase {
+
+ public int[] IdList;
+
+ public MassIdentityPkt(int[] idList) {
+ IdList = idList;
+ }
+
+ public MassIdentityPkt() {
+
+ }
+
+ public override void Deserialize(NetworkReader reader) {
+ byte[][] ByteArray = new byte[4][];
+ ByteArray[0] = reader.ReadBytesAndSize();
+ ByteArray[1] = reader.ReadBytesAndSize();
+ ByteArray[2] = reader.ReadBytesAndSize();
+ ByteArray[3] = reader.ReadBytesAndSize();
+ IdList = NetworkHelper.DeserializeIntArray(ByteArray);
+ }
+
+ public override void Serialize(NetworkWriter writer) {
+ byte[][] ByteArray = NetworkHelper.SerializeIntArray(IdList);
+ writer.WriteBytesFull(ByteArray[0]);
+ writer.WriteBytesFull(ByteArray[1]);
+ writer.WriteBytesFull(ByteArray[2]);
+ writer.WriteBytesFull(ByteArray[3]);
+ }
+ }
+}
diff --git a/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs.meta b/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs.meta
new file mode 100644
index 0000000..cc36e0d
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/MassIdentityPkt.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 97cd8f5bc9c011e4eb4b6f638b852656
+timeCreated: 1494288982
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Messages/TextMessage.cs b/Assets/Scripts/Networking/Messages/TextMessagePkt.cs
similarity index 90%
rename from Assets/Scripts/Networking/Messages/TextMessage.cs
rename to Assets/Scripts/Networking/Messages/TextMessagePkt.cs
index 90dae19..1ee08ca 100644
--- a/Assets/Scripts/Networking/Messages/TextMessage.cs
+++ b/Assets/Scripts/Networking/Messages/TextMessagePkt.cs
@@ -6,7 +6,7 @@ namespace Cyber.Networking.Messages {
/// Generic Text Message for chat etc.
/// To be removed later when no longer necessary.
///
- public class TextMessage : MessageBase {
+ public class TextMessagePkt : MessageBase {
///
/// Message inside the Text Message. Does not container sender information.
@@ -17,14 +17,14 @@ namespace Cyber.Networking.Messages {
/// Create a TextMessage containing the message to be sent.
///
/// Message to be sent.
- public TextMessage(string message) {
+ public TextMessagePkt(string message) {
this.Message = message;
}
///
/// Parameter-less constructor using when deserializing the message.
///
- public TextMessage() {
+ public TextMessagePkt() {
}
///
diff --git a/Assets/Scripts/Networking/Messages/TextMessage.cs.meta b/Assets/Scripts/Networking/Messages/TextMessagePkt.cs.meta
similarity index 100%
rename from Assets/Scripts/Networking/Messages/TextMessage.cs.meta
rename to Assets/Scripts/Networking/Messages/TextMessagePkt.cs.meta
diff --git a/Assets/Scripts/Networking/NetworkHelper.cs b/Assets/Scripts/Networking/NetworkHelper.cs
new file mode 100644
index 0000000..4f7ab0f
--- /dev/null
+++ b/Assets/Scripts/Networking/NetworkHelper.cs
@@ -0,0 +1,55 @@
+
+using System;
+using UnityEngine;
+
+namespace Cyber.Networking {
+
+ ///
+ /// Class that contains a few functions to help de/serialize some arrays.
+ ///
+ public class NetworkHelper {
+
+ ///
+ /// Divides an int-array into four byte-arrays.
+ ///
+ /// Int-array to divide
+ /// Four byte-arrays
+ public static byte[][] SerializeIntArray(int[] intArray) {
+ byte[][] ByteArray = new byte[4][];
+ for (int i = 0; i < 4; i++) {
+ ByteArray[i] = new byte[intArray.Length];
+ }
+
+ for (int top = 0; top < 4; top++) {
+ for (int i = 0; i < intArray.Length; i++) {
+ byte B = (byte) ((intArray[i] & (0xFF << (top * 8))) >> (top * 8));
+ ByteArray[top][i] = B;
+ }
+ }
+
+ return ByteArray;
+ }
+
+ ///
+ /// Deserializes an int-array from four byte-arrays
+ ///
+ /// Four byte arrays
+ /// An int array
+ public static int[] DeserializeIntArray(byte[][] byteArray) {
+ if (byteArray.GetLength(0) != 4) {
+ throw new ArgumentException("Specified byte-array is invalid (First dimension should be of length 4).");
+ } else if (byteArray.Length <= 0 || byteArray[0] == null) {
+ return new int[0];
+ }
+ int[] IntArray = new int[byteArray[0].Length];
+
+ for (int i = 0; i < byteArray[0].Length; i++) {
+ int I = byteArray[0][i] + (byteArray[1][i] << 8) + (byteArray[2][i] << 16) + (byteArray[3][i] << 24);
+ IntArray[i] = I;
+ }
+
+ return IntArray;
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/NetworkHelper.cs.meta b/Assets/Scripts/Networking/NetworkHelper.cs.meta
new file mode 100644
index 0000000..828857c
--- /dev/null
+++ b/Assets/Scripts/Networking/NetworkHelper.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 914f19b5c62c68c429667403d97f2837
+timeCreated: 1494288981
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/PktType.cs b/Assets/Scripts/Networking/PktType.cs
index 90b21a0..aece22c 100644
--- a/Assets/Scripts/Networking/PktType.cs
+++ b/Assets/Scripts/Networking/PktType.cs
@@ -6,6 +6,19 @@ namespace Cyber.Networking {
///
public class PktType {
+ ///
+ /// Test Text Message for sending stuff like chat.
+ ///
public const short TextMessage = 200;
+
+ ///
+ /// Packet containing identification details, server's given ID and if the ID belongs to you or not.
+ ///
+ public const short Identity = 201;
+
+ ///
+ /// Packet containing the identification details about everyone on the server before the client connected.
+ ///
+ public const short MassIdentity = 202;
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs
new file mode 100644
index 0000000..25fa9b5
--- /dev/null
+++ b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs
@@ -0,0 +1,31 @@
+
+using Cyber.Entities;
+
+namespace Cyber.Networking.Serverside {
+
+ ///
+ /// Represents a player on the server. This class is used by the server.
+ /// The S stands for "Server".
+ ///
+ class SConnectedPlayer {
+
+ ///
+ /// The player's connection ID.
+ ///
+ public readonly int ConnectionID;
+
+ ///
+ /// The player's controlled character
+ ///
+ public Character Character;
+
+ ///
+ /// Create a connected player and give it a connection ID;
+ ///
+ /// The player's connection ID
+ public SConnectedPlayer(int connectionID) {
+ ConnectionID = connectionID;
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs.meta b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs.meta
new file mode 100644
index 0000000..5da3370
--- /dev/null
+++ b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8e1569e7f6fe73a438a3ba0421ac5059
+timeCreated: 1494282762
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Serverside/Server.cs b/Assets/Scripts/Networking/Serverside/Server.cs
index 1366b93..4bfd73e 100644
--- a/Assets/Scripts/Networking/Serverside/Server.cs
+++ b/Assets/Scripts/Networking/Serverside/Server.cs
@@ -1,5 +1,7 @@
using Cyber.Console;
+using Cyber.Entities;
using Cyber.Networking.Messages;
+using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;
@@ -8,10 +10,14 @@ namespace Cyber.Networking.Serverside {
///
/// Server-class used to host a server and communicate to clients.
///
+ /// \todo Change connection channels to Unreliable to optimize ping.
public class Server : MonoBehaviour {
+ private List Players = new List();
private static Server Singleton;
+ private Spawner Spawner;
+
///
/// Creates the server-component, and sets the singleton as itself.
///
@@ -81,6 +87,8 @@ namespace Cyber.Networking.Serverside {
return false;
}
+ Spawner = GetComponent();
+
ConnectionConfig Config = new ConnectionConfig();
Config.AddChannel(QosType.ReliableSequenced);
Config.AddChannel(QosType.UnreliableSequenced);
@@ -99,7 +107,7 @@ namespace Cyber.Networking.Serverside {
Term.AddCommand("send (message)", "Howl at the darkness of space. Does it echo though?", (args) => {
Term.Println("You: " + args[0]);
- SendToAll(PktType.TextMessage, new TextMessage("Server: " + args[0]));
+ SendToAll(PktType.TextMessage, new TextMessagePkt("Server: " + args[0]));
});
return true;
@@ -109,7 +117,7 @@ namespace Cyber.Networking.Serverside {
switch (msg.msgType) {
case PktType.TextMessage:
- TextMessage TextMsg = new TextMessage();
+ TextMessagePkt TextMsg = new TextMessagePkt();
TextMsg.Deserialize(msg.reader);
Term.Println(TextMsg.Message);
break;
@@ -122,9 +130,28 @@ namespace Cyber.Networking.Serverside {
// Internal built-in event handler
- private void OnConnected(NetworkMessage msg) {
- Debug.Log("Someone connected!");
- Term.Println("Someone connected!");
+ private void OnConnected(NetworkMessage msg) {
+ int Id = msg.conn.connectionId;
+
+ Debug.Log(Id + " connected!");
+ Term.Println(Id + " connected!");
+
+ int[] IdList = new int[Players.Count];
+ for (int i = 0; i < Players.Count; i++) {
+ SConnectedPlayer P = Players[i];
+ IdList[i] = P.ConnectionID;
+ NetworkServer.SendToClient(P.ConnectionID, PktType.Identity, new IdentityPkt(Id, false));
+ }
+ foreach (int id in IdList) {
+ Debug.Log("id: " + id);
+ }
+ NetworkServer.SendToClient(Id, PktType.MassIdentity, new MassIdentityPkt(IdList));
+
+ SConnectedPlayer Player = new SConnectedPlayer(msg.conn.connectionId);
+ Players.Add(Player);
+
+ NetworkServer.SendToClient(msg.conn.connectionId,
+ PktType.Identity, new IdentityPkt(msg.conn.connectionId, true));
}
private void OnDisconnected(NetworkMessage msg) {