diff --git a/Assets/Scripts/Controls/PlayerController.cs b/Assets/Scripts/Controls/PlayerController.cs index 5a3b318..2cd517e 100644 --- a/Assets/Scripts/Controls/PlayerController.cs +++ b/Assets/Scripts/Controls/PlayerController.cs @@ -39,10 +39,8 @@ namespace Cyber.Controls { Vector3 Move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); if (Move.sqrMagnitude != 0) { Character.Move(Character.transform.TransformDirection(Move)); - Client.Send(PktType.MoveCreature, new MoveCreaturePkt(Character.transform.TransformDirection(Move), Character.ID)); } else if (Character.Moving()) { Character.Stop(); - Client.Send(PktType.MoveCreature, new MoveCreaturePkt(new Vector3(), Character.ID)); } // Rotation @@ -58,7 +56,7 @@ namespace Cyber.Controls { if (LookingAt != null && (LookingAt.transform.position - Character.GetPosition()).magnitude < Character.InteractionDistance) { LookingAt.Interact(Character); if (LookingAt.GetInteractableSyncdata().PublicInteractions) { - Client.Send(PktType.InteractPkt, new InteractionPkt(LookingAt.ID)); + Client.Send(PktType.Interact, new InteractionPkt(LookingAt.ID)); } } } diff --git a/Assets/Scripts/Entities/SyncBases/Character.cs b/Assets/Scripts/Entities/SyncBases/Character.cs index c784e29..0339dc4 100644 --- a/Assets/Scripts/Entities/SyncBases/Character.cs +++ b/Assets/Scripts/Entities/SyncBases/Character.cs @@ -83,6 +83,14 @@ namespace Cyber.Entities.SyncBases { return MovementDirection.sqrMagnitude != 0; } + /// + /// Returns the current movement direction; + /// + /// The Movement Direction Vector3 + public Vector3 GetMovementDirection() { + return MovementDirection; + } + /// /// The character's rotation. Intended to be given as an input to /// . diff --git a/Assets/Scripts/Networking/Clientside/Client.cs b/Assets/Scripts/Networking/Clientside/Client.cs index c6074f3..54a018a 100644 --- a/Assets/Scripts/Networking/Clientside/Client.cs +++ b/Assets/Scripts/Networking/Clientside/Client.cs @@ -75,6 +75,15 @@ namespace Cyber.Networking.Clientside { } } + public static bool SendByChannel(short msgType, MessageBase message, byte channelID) { + if (Singleton.Running) { + Singleton.NetClient.SendByChannel(msgType, message, channelID); + return true; + } else { + return false; + } + } + /// /// Returns if the client is running or not. /// This is independant weather the client is connected or not. @@ -126,9 +135,9 @@ namespace Cyber.Networking.Clientside { NetClient.RegisterHandler(PktType.MassIdentity, HandlePacket); NetClient.RegisterHandler(PktType.SpawnEntity, HandlePacket); NetClient.RegisterHandler(PktType.MoveCreature, HandlePacket); - NetClient.RegisterHandler(PktType.SyncPacket, HandlePacket); - NetClient.RegisterHandler(PktType.InteractPkt, HandlePacket); - NetClient.RegisterHandler(PktType.StaticObjectIdsPkt, HandlePacket); + NetClient.RegisterHandler(PktType.Sync, HandlePacket); + NetClient.RegisterHandler(PktType.Interact, HandlePacket); + NetClient.RegisterHandler(PktType.StaticObjectIds, HandlePacket); NetClient.RegisterHandler(MsgType.Connect, OnConnected); NetClient.RegisterHandler(MsgType.Disconnect, OnDisconnected); @@ -182,6 +191,10 @@ namespace Cyber.Networking.Clientside { if (SpawnPkt.OwnerID > -1) { Players[SpawnPkt.OwnerID].Character = Obj.GetComponent(); } + + if (SpawnPkt.OwnerID == Player.ConnectionID) { + gameObject.AddComponent(); + } break; case (PktType.MoveCreature): MoveCreaturePkt MoveCreature = new MoveCreaturePkt(); @@ -197,7 +210,7 @@ namespace Cyber.Networking.Clientside { } break; - case (PktType.InteractPkt): + case (PktType.Interact): InteractionPkt Interaction = new InteractionPkt(); Interaction.Deserialize(msg.reader); if (Interaction.OwnerSyncBaseID == Player.Character.ID) { @@ -211,10 +224,10 @@ namespace Cyber.Networking.Clientside { Term.Println("Server has sent an erroneus SyncBase ID!"); } break; - case (PktType.SyncPacket): + case (PktType.Sync): SyncHandler.HandleSyncPkt(msg); break; - case (PktType.StaticObjectIdsPkt): + case (PktType.StaticObjectIds): Term.Println("The static object id packet!"); IntListPkt StaticIds = new IntListPkt(); StaticIds.Deserialize(msg.reader); diff --git a/Assets/Scripts/Networking/Clientside/ClientSyncer.cs b/Assets/Scripts/Networking/Clientside/ClientSyncer.cs new file mode 100644 index 0000000..c9d008b --- /dev/null +++ b/Assets/Scripts/Networking/Clientside/ClientSyncer.cs @@ -0,0 +1,47 @@ + +using Cyber.Networking.Messages; +using UnityEngine; + +namespace Cyber.Networking.Clientside { + + /// + /// Syncer used on the clientside which sends sync packets from the client to the server containing their movement direction, rotation and possible checksums. + /// + public class ClientSyncer : MonoBehaviour { + + private const int ChecksumInterval = 10; // Every 10 ticks -> 1 per second + + private const float TickInterval = 1 / 10f; + private float TimeSinceLastTick = TickInterval; + private int TickCounter = 0; + + private int SyncIDCounter = 0; + + private void Update() { + TimeSinceLastTick += Time.deltaTime; + if (TimeSinceLastTick >= TickInterval) { + + ClientSyncPkt SyncPkt = new ClientSyncPkt(); + + if (TickCounter % ChecksumInterval == 0) { + // Add checksums + } + + var PlayerCharacter = Client.GetConnectedPlayer().Character; + SyncPkt.ClientSyncID = SyncIDCounter++; + SyncPkt.MoveDirection = PlayerCharacter.GetMovementDirection(); + SyncPkt.Rotation = PlayerCharacter.GetRotation(); + + Client.SendByChannel(PktType.ClientSync, SyncPkt, NetworkChannelID.Unreliable); + + if (TickCounter < int.MaxValue) { + TickCounter += 1; + } else { + TickCounter = 0; + } + TimeSinceLastTick -= TickInterval; + } + } + + } +} diff --git a/Assets/Scripts/Networking/Clientside/ClientSyncer.cs.meta b/Assets/Scripts/Networking/Clientside/ClientSyncer.cs.meta new file mode 100644 index 0000000..c959812 --- /dev/null +++ b/Assets/Scripts/Networking/Clientside/ClientSyncer.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: d36fbc4015a1ed24ab842868cc05d5b3 +timeCreated: 1494527802 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Networking/Clientside/SyncHandler.cs b/Assets/Scripts/Networking/Clientside/SyncHandler.cs index 3599bbd..7d172aa 100644 --- a/Assets/Scripts/Networking/Clientside/SyncHandler.cs +++ b/Assets/Scripts/Networking/Clientside/SyncHandler.cs @@ -1,7 +1,6 @@  using Cyber.Entities; using Cyber.Networking.Messages; -using UnityEngine; using UnityEngine.Networking; namespace Cyber.Networking.Clientside { @@ -24,7 +23,7 @@ namespace Cyber.Networking.Clientside { } /// - /// Handle a given Network message. Must be checked to be first. + /// Handle a given Network message. Must be checked to be first. /// /// public void HandleSyncPkt(NetworkMessage message) { diff --git a/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs b/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs new file mode 100644 index 0000000..02b044d --- /dev/null +++ b/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs @@ -0,0 +1,59 @@ + +using UnityEngine; +using UnityEngine.Networking; + +namespace Cyber.Networking.Messages { + + /// + /// This Packet contains sync data from the client to the server like movement direction and rotation. + /// + public class ClientSyncPkt : MessageBase { + + /// + /// ID of this client sync packet. This is separate from the server sync id. + /// + public int ClientSyncID; + + /// + /// Current movement direction of the player + /// + public Vector3 MoveDirection; + + /// + /// Current rotation of the player + /// + public Vector3 Rotation; + + /// + /// Create an empty client sync packet. + /// + public ClientSyncPkt() { } + + /// + /// Deserializes the sync packet. Does not deserialize everything, only the ID. + /// + /// + public override void Deserialize(NetworkReader reader) { + ClientSyncID = reader.ReadInt32(); + } + + /// + /// Reads the rest of the sync packet. Must be deserialized first. + /// + /// + public void ReadTheRest(NetworkReader reader) { + MoveDirection = reader.ReadVector3(); + Rotation = reader.ReadVector3(); + } + + /// + /// Serializes the entire packet for sending. + /// + /// + public override void Serialize(NetworkWriter writer) { + writer.Write(ClientSyncID); + writer.Write(MoveDirection); + writer.Write(Rotation); + } + } +} diff --git a/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs.meta b/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs.meta new file mode 100644 index 0000000..08367f1 --- /dev/null +++ b/Assets/Scripts/Networking/Messages/ClientSyncPkt.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: a048f03c7254eee44adec0eb68be8cc5 +timeCreated: 1494527802 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Networking/Messages/IntListPkt.cs b/Assets/Scripts/Networking/Messages/IntListPkt.cs index 6adf626..b8b3133 100644 --- a/Assets/Scripts/Networking/Messages/IntListPkt.cs +++ b/Assets/Scripts/Networking/Messages/IntListPkt.cs @@ -4,7 +4,7 @@ using UnityEngine.Networking; namespace Cyber.Networking.Messages { /// - /// Packet containing integers, used in many packet types, such as and . + /// Packet containing integers, used in many packet types, such as and . /// public class IntListPkt : MessageBase { diff --git a/Assets/Scripts/Networking/PktType.cs b/Assets/Scripts/Networking/PktType.cs index ee5704a..90d2458 100644 --- a/Assets/Scripts/Networking/PktType.cs +++ b/Assets/Scripts/Networking/PktType.cs @@ -35,20 +35,25 @@ namespace Cyber.Networking { public const short MoveCreature = 204; /// - /// Packet containing sync data. + /// Packet containing sync data from the server. /// - public const short SyncPacket = 205; + public const short Sync = 205; /// /// Packet telling that someone has made an interactive remark. /// - public const short InteractPkt = 206; + public const short Interact = 206; /// /// Packet containing an id list of static objects existing in the ready game. /// This packet contains an . /// - public const short StaticObjectIdsPkt = 207; + public const short StaticObjectIds = 207; + + /// + /// Packet containing sync data from the client to the server, like movement direction and rotation. + /// + public const short ClientSync = 208; } } \ No newline at end of file diff --git a/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs index b4180e0..93d818a 100644 --- a/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs +++ b/Assets/Scripts/Networking/Serverside/SConnectedPlayer.cs @@ -6,7 +6,7 @@ namespace Cyber.Networking.Serverside { /// Represents a player on the server. This class is used by the server. /// The S stands for "Server". /// - class SConnectedPlayer { + public class SConnectedPlayer { /// /// The player's connection ID. diff --git a/Assets/Scripts/Networking/Serverside/Server.cs b/Assets/Scripts/Networking/Serverside/Server.cs index 7a1bacc..e014995 100644 --- a/Assets/Scripts/Networking/Serverside/Server.cs +++ b/Assets/Scripts/Networking/Serverside/Server.cs @@ -25,6 +25,8 @@ namespace Cyber.Networking.Serverside { /// public Syncer Syncer; + private ServerSyncHandler ServerSyncHandler; + /// /// Creates the server-component, and sets the singleton as itself. /// @@ -125,7 +127,8 @@ namespace Cyber.Networking.Serverside { NetworkServer.RegisterHandler(PktType.TextMessage, HandlePacket); NetworkServer.RegisterHandler(PktType.MoveCreature, HandlePacket); - NetworkServer.RegisterHandler(PktType.InteractPkt, HandlePacket); + NetworkServer.RegisterHandler(PktType.Interact, HandlePacket); + NetworkServer.RegisterHandler(PktType.ClientSync, HandlePacket); NetworkServer.RegisterHandler(MsgType.Connect, OnConnected); NetworkServer.RegisterHandler(MsgType.Disconnect, OnDisconnected); @@ -141,6 +144,8 @@ namespace Cyber.Networking.Serverside { gameObject.AddComponent(); + ServerSyncHandler = new ServerSyncHandler(Players); + return true; } @@ -172,7 +177,7 @@ namespace Cyber.Networking.Serverside { NetworkServer.SendToClient(Player.Value.ConnectionID, PktType.MoveCreature, MoveCreature); } break; - case PktType.InteractPkt: + case PktType.Interact: InteractionPkt Interaction = new InteractionPkt(); Interaction.Deserialize(msg.reader); @@ -187,7 +192,7 @@ namespace Cyber.Networking.Serverside { float ServerInteractionDistance = Sender.InteractionDistance + Sender.MovementSpeed * 0.5f; if (Delta.magnitude <= ServerInteractionDistance) { Interacted.Interact(Sender); - NetworkServer.SendToAll(PktType.InteractPkt, Interaction); + NetworkServer.SendToAll(PktType.Interact, Interaction); if (Interacted.GetInteractableSyncdata().RequiresSyncing) { Syncer.DirtSyncBase(Interacted.ID); } @@ -196,6 +201,9 @@ namespace Cyber.Networking.Serverside { Term.Println("Client has reported an erronous SyncBase ID!"); } + break; + case PktType.ClientSync: + ServerSyncHandler.HandleSyncPkt(msg); break; default: Debug.LogError("Received an unknown packet, id: " + msg.msgType); @@ -241,7 +249,7 @@ namespace Cyber.Networking.Serverside { NetworkServer.SendToAll(PktType.SpawnEntity, new SpawnEntityPkt(EntityType.NPC, Position, EntityIdList, Id)); // Send ID's of every existing static SyncBase object in the world. - NetworkServer.SendToClient(Id, PktType.StaticObjectIdsPkt, new IntListPkt(Spawner.SyncDB.GetStaticSyncBaseIDList())); + NetworkServer.SendToClient(Id, PktType.StaticObjectIds, new IntListPkt(Spawner.SyncDB.GetStaticSyncBaseIDList())); // Send every entity to the player who just connected. foreach (var Entry in Players) { diff --git a/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs new file mode 100644 index 0000000..748a85c --- /dev/null +++ b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs @@ -0,0 +1,43 @@ + +using Cyber.Entities.SyncBases; +using Cyber.Networking.Messages; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Networking; + +namespace Cyber.Networking.Serverside { + public class ServerSyncHandler { + + private Dictionary LastSyncIDReceived = new Dictionary(); + private Dictionary Players; + + public ServerSyncHandler(Dictionary players) { + Players = players; + } + + /// + /// Handle the given sync from a client. Must be checked to be first. + /// + /// + public void HandleSyncPkt(NetworkMessage message) { + ClientSyncPkt SyncPkt = new ClientSyncPkt(); + SyncPkt.Deserialize(message.reader); + int LastID = -1; + if (LastSyncIDReceived.ContainsKey(message.conn.connectionId)) { + LastID = LastSyncIDReceived[message.conn.connectionId]; + } + if (SyncPkt.ClientSyncID > LastID) { + SyncPkt.ReadTheRest(message.reader); + LastSyncIDReceived[message.conn.connectionId] = SyncPkt.ClientSyncID; + + 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. + } + + } +} diff --git a/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs.meta b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs.meta new file mode 100644 index 0000000..e508057 --- /dev/null +++ b/Assets/Scripts/Networking/Serverside/ServerSyncHandler.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: f02e0de4b2abc7e43862d3d9d824fea9 +timeCreated: 1494527802 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Networking/Serverside/Syncer.cs b/Assets/Scripts/Networking/Serverside/Syncer.cs index c221681..ec89e9a 100644 --- a/Assets/Scripts/Networking/Serverside/Syncer.cs +++ b/Assets/Scripts/Networking/Serverside/Syncer.cs @@ -65,7 +65,7 @@ namespace Cyber.Networking.Serverside { if (QueuedSyncs.Count > 0) { int[] SyncIDs = QueuedSyncs.ToArray(); SyncPkt SyncPacket = new SyncPkt(Database, SyncIDs, SyncPacketID++); - Server.SendToAllByChannel(PktType.SyncPacket, SyncPacket, NetworkChannelID.Unreliable); + Server.SendToAllByChannel(PktType.Sync, SyncPacket, NetworkChannelID.Unreliable); QueuedSyncs.Clear(); DirtySyncBases.Clear();