diff --git a/Assets/Scripts/Console/DebugConsole.cs b/Assets/Scripts/Console/DebugConsole.cs
index 6b7aa42..823ca89 100644
--- a/Assets/Scripts/Console/DebugConsole.cs
+++ b/Assets/Scripts/Console/DebugConsole.cs
@@ -1,4 +1,5 @@
-using System.Collections;
+using Cyber.Networking.Clientside;
+using Cyber.Networking.Serverside;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;
@@ -185,6 +186,12 @@ namespace Cyber.Console {
});
AddCommand("shutdown", "Shuts the game down.", (args) => {
+ if (Client.IsRunning()) {
+ Client.Shutdown();
+ }
+ if (Server.IsRunning()) {
+ Server.Shutdown();
+ }
Application.Quit();
});
diff --git a/Assets/Scripts/Entities/Spawner.cs b/Assets/Scripts/Entities/Spawner.cs
index c2c00c1..66c7e9c 100644
--- a/Assets/Scripts/Entities/Spawner.cs
+++ b/Assets/Scripts/Entities/Spawner.cs
@@ -53,5 +53,10 @@ namespace Cyber.Entities {
}
return Spawned;
}
+
+ public void Remove(GameObject gameObject) {
+ SyncDB.RemoveEntity(gameObject);
+ Destroy(gameObject);
+ }
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/Entities/SyncDB.cs b/Assets/Scripts/Entities/SyncDB.cs
index 3d49d77..ee5b800 100644
--- a/Assets/Scripts/Entities/SyncDB.cs
+++ b/Assets/Scripts/Entities/SyncDB.cs
@@ -44,6 +44,22 @@ namespace Cyber.Entities {
}
}
+ ///
+ /// Clears the given gameobject's s from the Database.
+ ///
+ /// The GameObject to remove.
+ public void RemoveEntity(GameObject gameObject) {
+ for (int i = 0; i < SyncableClasses.Length; i++) {
+ SyncBase Syncable = (SyncBase) gameObject.GetComponent(SyncableClasses[i]);
+ if (Syncable != null) {
+ Database.Remove(Syncable.ID);
+ if (Server.IsRunning()) {
+ CategorizedDatabase[Syncable.GetType()].RemoveAll(x => x == Syncable.ID);
+ }
+ }
+ }
+ }
+
///
/// Makes an ordered list of the given gameobject's syncable components'
/// IDs.
diff --git a/Assets/Scripts/Networking/Clientside/Client.cs b/Assets/Scripts/Networking/Clientside/Client.cs
index b6a196a..89b28e6 100644
--- a/Assets/Scripts/Networking/Clientside/Client.cs
+++ b/Assets/Scripts/Networking/Clientside/Client.cs
@@ -117,6 +117,20 @@ namespace Cyber.Networking.Clientside {
return Singleton.Player;
}
+ ///
+ /// Properly shut down the client.
+ ///
+ /// True if the client was active, false if not.
+ public static bool Shutdown() {
+ if (IsRunning()) {
+ Send(PktType.Disconnect, new DisconnectPkt());
+ Singleton.NetClient.Shutdown();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private void Start() {
Spawner = GetComponent();
SyncHandler = new SyncHandler(Spawner.SyncDB);
@@ -146,6 +160,7 @@ namespace Cyber.Networking.Clientside {
NetClient.RegisterHandler(PktType.Sync, HandlePacket);
NetClient.RegisterHandler(PktType.Interact, HandlePacket);
NetClient.RegisterHandler(PktType.StaticObjectIds, HandlePacket);
+ NetClient.RegisterHandler(PktType.Disconnect, HandlePacket);
NetClient.RegisterHandler(MsgType.Connect, OnConnected);
NetClient.RegisterHandler(MsgType.Disconnect, OnDisconnected);
@@ -240,6 +255,14 @@ namespace Cyber.Networking.Clientside {
StaticIds.Deserialize(msg.reader);
Spawner.SyncDB.SetStaticObjectsIDs(StaticIds.IdList);
break;
+ case (PktType.Disconnect):
+ DisconnectPkt Disconnect = new DisconnectPkt();
+ Disconnect.Deserialize(msg.reader);
+
+ Term.Println(Disconnect.ConnectionID + " disconnected!");
+ Spawner.Remove(Players[Disconnect.ConnectionID].Character.gameObject);
+ Players.Remove(Disconnect.ConnectionID);
+ break;
default:
Debug.LogError("Received an unknown packet, id: " + msg.msgType);
Term.Println("Received an unknown packet, id: " + msg.msgType);
@@ -257,11 +280,20 @@ namespace Cyber.Networking.Clientside {
Term.Println("You: " + args[0]);
NetClient.Send(PktType.TextMessage, new TextMessagePkt("A Client: " + args[0]));
});
+
+ Term.AddCommand("disconnect", "Disconnect from the server.", (args) => {
+ NetClient.Send(PktType.Disconnect, new DisconnectPkt());
+ });
}
private void OnDisconnected(NetworkMessage msg) {
Debug.Log("Disconnected!");
Term.Println("Disconnected!");
+
+ foreach (var Entry in Players) {
+ Spawner.Remove(Entry.Value.Character.gameObject);
+ }
+ Players.Clear();
Running = false;
}
diff --git a/Assets/Scripts/Networking/Messages/DisconnectPkt.cs b/Assets/Scripts/Networking/Messages/DisconnectPkt.cs
new file mode 100644
index 0000000..b238245
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/DisconnectPkt.cs
@@ -0,0 +1,46 @@
+
+using UnityEngine.Networking;
+
+namespace Cyber.Networking.Messages {
+
+ ///
+ /// Packet containing a mesasge, that someone has disconnected.
+ ///
+ public class DisconnectPkt : MessageBase {
+
+ ///
+ /// ID of the connection, which disconnected.
+ ///
+ public int ConnectionID;
+
+ ///
+ /// Creates a disconnect package.
+ ///
+ ///
+ public DisconnectPkt(int connectionID) {
+ ConnectionID = connectionID;
+ }
+
+ ///
+ /// Creates an empty disconnect package for whatever reason.
+ ///
+ public DisconnectPkt() { }
+
+ ///
+ /// Deserializes the disconnect package.
+ ///
+ ///
+ public override void Deserialize(NetworkReader reader) {
+ ConnectionID = reader.ReadInt32();
+ }
+
+ ///
+ /// Serializes the disconnect package for sending!
+ ///
+ ///
+ public override void Serialize(NetworkWriter writer) {
+ writer.Write(ConnectionID);
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Messages/DisconnectPkt.cs.meta b/Assets/Scripts/Networking/Messages/DisconnectPkt.cs.meta
new file mode 100644
index 0000000..b2c384e
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/DisconnectPkt.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0fbb56086af16da44bd7432c506088ac
+timeCreated: 1494534278
+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 90d2458..c84c02c 100644
--- a/Assets/Scripts/Networking/PktType.cs
+++ b/Assets/Scripts/Networking/PktType.cs
@@ -55,5 +55,10 @@ namespace Cyber.Networking {
///
public const short ClientSync = 208;
+ ///
+ /// Packet informing the reciever that the client either wishes to disconnect from the server, or is disconnected.
+ ///
+ public const short Disconnect = 209;
+
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/Networking/Serverside/Server.cs b/Assets/Scripts/Networking/Serverside/Server.cs
index 9166d0b..4a76fa7 100644
--- a/Assets/Scripts/Networking/Serverside/Server.cs
+++ b/Assets/Scripts/Networking/Serverside/Server.cs
@@ -108,6 +108,24 @@ namespace Cyber.Networking.Serverside {
return NetworkServer.active;
}
+ ///
+ /// Properly shuts the server down.
+ /// \todo Server should inform all client that the server was shut down.
+ ///
+ /// True if the server was running, false if not.
+ public static bool Shutdown() {
+ if (NetworkServer.active) {
+ foreach (var Entry in Singleton.Players) {
+ Singleton.Spawner.Remove(Entry.Value.Character.gameObject);
+ }
+ Singleton.Players.Clear();
+ NetworkServer.Shutdown();
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private bool LaunchServer(int port) {
if (NetworkServer.active) {
return false;
@@ -129,6 +147,7 @@ namespace Cyber.Networking.Serverside {
NetworkServer.RegisterHandler(PktType.MoveCreature, HandlePacket);
NetworkServer.RegisterHandler(PktType.Interact, HandlePacket);
NetworkServer.RegisterHandler(PktType.ClientSync, HandlePacket);
+ NetworkServer.RegisterHandler(PktType.Disconnect, HandlePacket);
NetworkServer.RegisterHandler(MsgType.Connect, OnConnected);
NetworkServer.RegisterHandler(MsgType.Disconnect, OnDisconnected);
@@ -142,6 +161,11 @@ namespace Cyber.Networking.Serverside {
SendToAll(PktType.TextMessage, new TextMessagePkt("Server: " + args[0]));
});
+ Term.AddCommand("unhost", "Shuts down the server, shut it all down!", (args) => {
+ Term.Println("Unhosting the server.");
+ Shutdown();
+ });
+
Syncer = gameObject.AddComponent();
ServerSyncHandler = new ServerSyncHandler(Players);
@@ -205,6 +229,9 @@ namespace Cyber.Networking.Serverside {
case PktType.ClientSync:
ServerSyncHandler.HandleSyncPkt(msg);
break;
+ case PktType.Disconnect:
+ msg.conn.Disconnect();
+ break;
default:
Debug.LogError("Received an unknown packet, id: " + msg.msgType);
Term.Println("Received an unknown packet, id: " + msg.msgType);
@@ -218,7 +245,6 @@ namespace Cyber.Networking.Serverside {
// Get client's ID
int Id = msg.conn.connectionId;
- Debug.Log(Id + " connected!");
Term.Println(Id + " connected!");
// Send all other clients a notification and collect their id's
@@ -265,8 +291,18 @@ namespace Cyber.Networking.Serverside {
}
private void OnDisconnected(NetworkMessage msg) {
- Debug.Log("Someone disconnected.");
- Term.Println("Someone disconnected.");
+ // Get client's ID
+ int Id = msg.conn.connectionId;
+
+ Term.Println(Id + " disconnected.");
+
+ Spawner.Remove(Players[Id].Character.gameObject);
+ Players.Remove(Id);
+ ServerSyncHandler.ClearConnectionFromSyncDict(Id);
+
+ foreach (var Entry in Players) {
+ Send(Entry.Key, PktType.Disconnect, new DisconnectPkt(Id));
+ }
}
private void OnError(NetworkMessage msg) {
diff --git a/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs
index 9824e34..e95ae08 100644
--- a/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs
+++ b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs
@@ -2,7 +2,6 @@
using Cyber.Entities.SyncBases;
using Cyber.Networking.Messages;
using System.Collections.Generic;
-using UnityEngine;
using UnityEngine.Networking;
namespace Cyber.Networking.Serverside {
@@ -41,11 +40,13 @@ namespace Cyber.Networking.Serverside {
Character PlayerCharacter = Players[message.conn.connectionId].Character;
PlayerCharacter.Move(SyncPkt.MoveDirection);
PlayerCharacter.SetRotation(SyncPkt.Rotation);
-
- Debug.Log("MoveDirection: " + SyncPkt.MoveDirection);
}
// Disregard the package, it's too old.
}
+ public void ClearConnectionFromSyncDict(int connectionID) {
+ LastSyncIDReceived.Remove(connectionID);
+ }
+
}
}