Share network identities throughout clients
This commit is contained in:
parent
7134c406f3
commit
504b2a08d4
@ -1,6 +1,4 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
using Cyber.Console;
|
||||
|
||||
namespace Cyber.Entities {
|
||||
|
26
Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs
Normal file
26
Assets/Scripts/Networking/Clientside/CConnectedPlayer.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using Cyber.Entities;
|
||||
|
||||
namespace Cyber.Networking.Clientside {
|
||||
|
||||
/// <summary>
|
||||
/// Represents a connected player on the clientside. This class is used by clients.
|
||||
/// The C stands for "Client".
|
||||
/// </summary>
|
||||
class CConnectedPlayer {
|
||||
|
||||
/// <summary>
|
||||
/// Connection ID on the global perspective.
|
||||
/// </summary>
|
||||
public readonly int ConnectionID;
|
||||
|
||||
/// <summary>
|
||||
/// The player's controlled character.
|
||||
/// </summary>
|
||||
public Character Character;
|
||||
|
||||
public CConnectedPlayer(int connectionID) {
|
||||
ConnectionID = connectionID;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f30b47eaf72d54f4099f5690a67965e3
|
||||
timeCreated: 1494285679
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// </remarks>
|
||||
public class Client : MonoBehaviour {
|
||||
|
||||
private NetworkClient NetClient;
|
||||
@ -16,6 +24,12 @@ namespace Cyber.Networking.Clientside {
|
||||
|
||||
private static Client Singleton;
|
||||
|
||||
/// <summary>
|
||||
/// The player of this client
|
||||
/// </summary>
|
||||
private CConnectedPlayer Player;
|
||||
private List<CConnectedPlayer> Players = new List<CConnectedPlayer>();
|
||||
|
||||
/// <summary>
|
||||
/// Creates the client and sets it as the signleton.
|
||||
/// </summary>
|
||||
@ -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]));
|
||||
});
|
||||
}
|
||||
|
||||
|
54
Assets/Scripts/Networking/Messages/IdentityPkt.cs
Normal file
54
Assets/Scripts/Networking/Messages/IdentityPkt.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Cyber.Networking.Messages {
|
||||
|
||||
/// <summary>
|
||||
/// Contains the Connection ID of the user and weather the ID belongs to the client or not.
|
||||
/// </summary>
|
||||
public class IdentityPkt : MessageBase {
|
||||
|
||||
/// <summary>
|
||||
/// ID of the Connection
|
||||
/// </summary>
|
||||
public int ConnectionID;
|
||||
|
||||
/// <summary>
|
||||
/// Weather the recieving client owns this ID or not.
|
||||
/// </summary>
|
||||
public bool Owned;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a packet containing an ID and the detail weather the recieving client owns this ID.
|
||||
/// </summary>
|
||||
/// <param name="connectionID">ID of the connection.</param>
|
||||
/// <param name="owned">Weather the recieving client owns this ID.</param>
|
||||
public IdentityPkt(int connectionID, bool owned) {
|
||||
ConnectionID = connectionID;
|
||||
Owned = owned;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameter-less constructor using when deserializing the message.
|
||||
/// </summary>
|
||||
public IdentityPkt() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to deserialize a message received via networking.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
public override void Deserialize(NetworkReader reader) {
|
||||
ConnectionID = reader.ReadInt32();
|
||||
Owned = reader.ReadBoolean();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to serialize the message before it is sent.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
public override void Serialize(NetworkWriter writer) {
|
||||
writer.Write(ConnectionID);
|
||||
writer.Write(Owned);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Scripts/Networking/Messages/IdentityPkt.cs.meta
Normal file
12
Assets/Scripts/Networking/Messages/IdentityPkt.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c30897b96fbb288409d685055ea44926
|
||||
timeCreated: 1494285679
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
38
Assets/Scripts/Networking/Messages/MassIdentityPkt.cs
Normal file
38
Assets/Scripts/Networking/Messages/MassIdentityPkt.cs
Normal file
@ -0,0 +1,38 @@
|
||||
|
||||
using UnityEngine.Networking;
|
||||
|
||||
namespace Cyber.Networking.Messages {
|
||||
|
||||
/// <summary>
|
||||
/// Packet containing a list of ID's of players currently connected.
|
||||
/// </summary>
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
12
Assets/Scripts/Networking/Messages/MassIdentityPkt.cs.meta
Normal file
12
Assets/Scripts/Networking/Messages/MassIdentityPkt.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97cd8f5bc9c011e4eb4b6f638b852656
|
||||
timeCreated: 1494288982
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -6,7 +6,7 @@ namespace Cyber.Networking.Messages {
|
||||
/// Generic Text Message for chat etc.
|
||||
/// To be removed later when no longer necessary.
|
||||
/// </summary>
|
||||
public class TextMessage : MessageBase {
|
||||
public class TextMessagePkt : MessageBase {
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="message">Message to be sent.</param>
|
||||
public TextMessage(string message) {
|
||||
public TextMessagePkt(string message) {
|
||||
this.Message = message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parameter-less constructor using when deserializing the message.
|
||||
/// </summary>
|
||||
public TextMessage() {
|
||||
public TextMessagePkt() {
|
||||
}
|
||||
|
||||
/// <summary>
|
55
Assets/Scripts/Networking/NetworkHelper.cs
Normal file
55
Assets/Scripts/Networking/NetworkHelper.cs
Normal file
@ -0,0 +1,55 @@
|
||||
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cyber.Networking {
|
||||
|
||||
/// <summary>
|
||||
/// Class that contains a few functions to help de/serialize some arrays.
|
||||
/// </summary>
|
||||
public class NetworkHelper {
|
||||
|
||||
/// <summary>
|
||||
/// Divides an int-array into four byte-arrays.
|
||||
/// </summary>
|
||||
/// <param name="intArray">Int-array to divide</param>
|
||||
/// <returns>Four byte-arrays</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes an int-array from four byte-arrays
|
||||
/// </summary>
|
||||
/// <param name="byteArray">Four byte arrays</param>
|
||||
/// <returns>An int array</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
12
Assets/Scripts/Networking/NetworkHelper.cs.meta
Normal file
12
Assets/Scripts/Networking/NetworkHelper.cs.meta
Normal file
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 914f19b5c62c68c429667403d97f2837
|
||||
timeCreated: 1494288981
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -6,6 +6,19 @@ namespace Cyber.Networking {
|
||||
/// </summary>
|
||||
public class PktType {
|
||||
|
||||
/// <summary>
|
||||
/// Test Text Message for sending stuff like chat.
|
||||
/// </summary>
|
||||
public const short TextMessage = 200;
|
||||
|
||||
/// <summary>
|
||||
/// Packet containing identification details, server's given ID and if the ID belongs to you or not.
|
||||
/// </summary>
|
||||
public const short Identity = 201;
|
||||
|
||||
/// <summary>
|
||||
/// Packet containing the identification details about everyone on the server before the client connected.
|
||||
/// </summary>
|
||||
public const short MassIdentity = 202;
|
||||
}
|
||||
}
|
31
Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs
Normal file
31
Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
using Cyber.Entities;
|
||||
|
||||
namespace Cyber.Networking.Serverside {
|
||||
|
||||
/// <summary>
|
||||
/// Represents a player on the server. This class is used by the server.
|
||||
/// The S stands for "Server".
|
||||
/// </summary>
|
||||
class SConnectedPlayer {
|
||||
|
||||
/// <summary>
|
||||
/// The player's connection ID.
|
||||
/// </summary>
|
||||
public readonly int ConnectionID;
|
||||
|
||||
/// <summary>
|
||||
/// The player's controlled character
|
||||
/// </summary>
|
||||
public Character Character;
|
||||
|
||||
/// <summary>
|
||||
/// Create a connected player and give it a connection ID;
|
||||
/// </summary>
|
||||
/// <param name="connectionID">The player's connection ID</param>
|
||||
public SConnectedPlayer(int connectionID) {
|
||||
ConnectionID = connectionID;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e1569e7f6fe73a438a3ba0421ac5059
|
||||
timeCreated: 1494282762
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -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 {
|
||||
/// <summary>
|
||||
/// Server-class used to host a server and communicate to clients.
|
||||
/// </summary>
|
||||
/// \todo Change connection channels to Unreliable to optimize ping.
|
||||
public class Server : MonoBehaviour {
|
||||
|
||||
private List<SConnectedPlayer> Players = new List<SConnectedPlayer>();
|
||||
private static Server Singleton;
|
||||
|
||||
private Spawner Spawner;
|
||||
|
||||
/// <summary>
|
||||
/// Creates the server-component, and sets the singleton as itself.
|
||||
/// </summary>
|
||||
@ -81,6 +87,8 @@ namespace Cyber.Networking.Serverside {
|
||||
return false;
|
||||
}
|
||||
|
||||
Spawner = GetComponent<Spawner>();
|
||||
|
||||
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;
|
||||
@ -123,8 +131,27 @@ namespace Cyber.Networking.Serverside {
|
||||
// Internal built-in event handler
|
||||
|
||||
private void OnConnected(NetworkMessage msg) {
|
||||
Debug.Log("Someone connected!");
|
||||
Term.Println("Someone connected!");
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user