From 7676602154e69f855582f9215921a9c3b2cb0504 Mon Sep 17 00:00:00 2001 From: teascade Date: Fri, 12 May 2017 00:35:53 +0300 Subject: [PATCH] Fix #6 and add disconnect/unhost commands for convinience --- Assets/Scripts/Console/DebugConsole.cs | 9 +++- Assets/Scripts/Entities/Spawner.cs | 5 ++ Assets/Scripts/Entities/SyncDB.cs | 16 +++++++ .../Scripts/Networking/Clientside/Client.cs | 32 +++++++++++++ .../Networking/Messages/DisconnectPkt.cs | 46 +++++++++++++++++++ .../Networking/Messages/DisconnectPkt.cs.meta | 12 +++++ Assets/Scripts/Networking/PktType.cs | 5 ++ .../Scripts/Networking/Serverside/Server.cs | 42 +++++++++++++++-- .../Serverside/ServerSyncHandler.cs | 7 +-- 9 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 Assets/Scripts/Networking/Messages/DisconnectPkt.cs create mode 100644 Assets/Scripts/Networking/Messages/DisconnectPkt.cs.meta 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); + } + } }