diff --git a/Assets/Scripts/Entities/SyncBases/Inventory.cs b/Assets/Scripts/Entities/SyncBases/Inventory.cs index fa162dd..28af025 100644 --- a/Assets/Scripts/Entities/SyncBases/Inventory.cs +++ b/Assets/Scripts/Entities/SyncBases/Inventory.cs @@ -1,6 +1,8 @@  +using Cyber.Console; using Cyber.Items; using Cyber.Networking; +using Cyber.Networking.Serverside; using UnityEngine; using UnityEngine.Networking; @@ -21,8 +23,23 @@ namespace Cyber.Entities.SyncBases { /// public Inventory() { Drive = new Drive(10f); - Drive.AddItem(ItemDB.Singleton.Get(0)); - Drive.AddItem(ItemDB.Singleton.Get(1)); + if (Server.IsRunning()) { + Drive.AddItem(ItemDB.Singleton.Get(0)); + Drive.AddItem(ItemDB.Singleton.Get(1)); + } + } + + /// + /// Generates a checksum for the inventory + /// + /// A checksum of the IDs of the items + public override int GenerateChecksum() { + var Items = Drive.GetItems().ToArray(); + int Checksum = 0; + for (int i = 0; i < Items.Length; i++) { + Checksum ^= Items[i].ID; + } + return Checksum; } /// @@ -38,6 +55,8 @@ namespace Cyber.Entities.SyncBases { /// /// public override void Deserialize(NetworkReader reader) { + Debug.Log("Deserializing inventory!"); + byte[][] ByteArray = new byte[4][]; ByteArray[0] = reader.ReadBytesAndSize(); ByteArray[1] = reader.ReadBytesAndSize(); diff --git a/Assets/Scripts/Networking/Clientside/SyncHandler.cs b/Assets/Scripts/Networking/Clientside/SyncHandler.cs index 7d172aa..c5775e9 100644 --- a/Assets/Scripts/Networking/Clientside/SyncHandler.cs +++ b/Assets/Scripts/Networking/Clientside/SyncHandler.cs @@ -1,6 +1,9 @@  +using Cyber.Console; using Cyber.Entities; +using Cyber.Entities.SyncBases; using Cyber.Networking.Messages; +using System.Collections.Generic; using UnityEngine.Networking; namespace Cyber.Networking.Clientside { @@ -32,6 +35,20 @@ namespace Cyber.Networking.Clientside { if (LatestSyncID < SyncPacket.SyncPacketID) { LatestSyncID = SyncPacket.SyncPacketID; SyncPacket.ApplySync(message.reader); + + int[] SyncBases = SyncPacket.ChecksummedSyncBases; + int[] Checksums = SyncPacket.Checksums; + if (SyncBases.Length > 0) { + List FailedSyncBases = new List(); + for (int i = 0; i < SyncBases.Length; i++) { + SyncBase SyncBase = SyncDB.Get(SyncBases[i]); + if (SyncBase.GenerateChecksum() != Checksums[i]) { + FailedSyncBases.Add(SyncBase.ID); + } + } + + Client.Send(PktType.FailedChecksums, new IntListPkt(FailedSyncBases.ToArray())); + } } // Otherwise disregard the sync. diff --git a/Assets/Scripts/Networking/Messages/SyncPkt.cs b/Assets/Scripts/Networking/Messages/SyncPkt.cs index 2eb9150..55c05a3 100644 --- a/Assets/Scripts/Networking/Messages/SyncPkt.cs +++ b/Assets/Scripts/Networking/Messages/SyncPkt.cs @@ -20,6 +20,16 @@ namespace Cyber.Networking.Messages { /// public int[] SyncedSyncBases; + /// + /// The Array of SyncIDs that have their hashes in this syncpacket + /// + public int[] ChecksummedSyncBases; + + /// + /// The Array of Checksums that are sent with . + /// + public int[] Checksums; + private SyncDB SyncDB; /// @@ -27,11 +37,15 @@ namespace Cyber.Networking.Messages { /// /// SyncDB to sync from. /// The ID's of the SyncBases to sync. + /// + /// /// ID of the sync packet itself. - public SyncPkt(SyncDB syncDB, int[] syncBases, int syncPacketID) { + public SyncPkt(SyncDB syncDB, int[] syncBases, int[] checksummedSyncBases, int[] checksums, int syncPacketID) { SyncPacketID = syncPacketID; SyncDB = syncDB; SyncedSyncBases = syncBases; + ChecksummedSyncBases = checksummedSyncBases; + Checksums = checksums; } /// @@ -40,6 +54,8 @@ namespace Cyber.Networking.Messages { /// SyncBase to sync to. public SyncPkt(SyncDB syncDB) { SyncDB = syncDB; + ChecksummedSyncBases = new int[0]; + Checksums = new int[0]; } /// @@ -65,6 +81,25 @@ namespace Cyber.Networking.Messages { foreach (int syncId in SyncedSyncBases) { SyncDB.Get(syncId).Deserialize(reader); } + + bool checksums = reader.ReadBoolean(); + + if (checksums) { + byte[][] SummedIdsByteArray = new byte[4][]; + SummedIdsByteArray[0] = reader.ReadBytesAndSize(); + SummedIdsByteArray[1] = reader.ReadBytesAndSize(); + SummedIdsByteArray[2] = reader.ReadBytesAndSize(); + SummedIdsByteArray[3] = reader.ReadBytesAndSize(); + + byte[][] SumsByteArray = new byte[4][]; + SumsByteArray[0] = reader.ReadBytesAndSize(); + SumsByteArray[1] = reader.ReadBytesAndSize(); + SumsByteArray[2] = reader.ReadBytesAndSize(); + SumsByteArray[3] = reader.ReadBytesAndSize(); + + ChecksummedSyncBases = NetworkHelper.DeserializeIntArray(SummedIdsByteArray); + Checksums = NetworkHelper.DeserializeIntArray(SumsByteArray); + } } /// @@ -74,15 +109,33 @@ namespace Cyber.Networking.Messages { public override void Serialize(NetworkWriter writer) { writer.Write(SyncPacketID); - byte[][] ByteArray = NetworkHelper.SerializeIntArray(SyncedSyncBases); - writer.WriteBytesFull(ByteArray[0]); - writer.WriteBytesFull(ByteArray[1]); - writer.WriteBytesFull(ByteArray[2]); - writer.WriteBytesFull(ByteArray[3]); + byte[][] SyncedIdsByteArray = NetworkHelper.SerializeIntArray(SyncedSyncBases); + writer.WriteBytesFull(SyncedIdsByteArray[0]); + writer.WriteBytesFull(SyncedIdsByteArray[1]); + writer.WriteBytesFull(SyncedIdsByteArray[2]); + writer.WriteBytesFull(SyncedIdsByteArray[3]); foreach (int syncId in SyncedSyncBases) { SyncDB.Get(syncId).Serialize(writer); } + + if (ChecksummedSyncBases.Length == 0) { + writer.Write(false); + } else { + writer.Write(true); + + byte[][] SummedIdsByteArray = NetworkHelper.SerializeIntArray(ChecksummedSyncBases); + writer.WriteBytesFull(SummedIdsByteArray[0]); + writer.WriteBytesFull(SummedIdsByteArray[1]); + writer.WriteBytesFull(SummedIdsByteArray[2]); + writer.WriteBytesFull(SummedIdsByteArray[3]); + + byte[][] SumsByteArray = NetworkHelper.SerializeIntArray(Checksums); + writer.WriteBytesFull(SumsByteArray[0]); + writer.WriteBytesFull(SumsByteArray[1]); + writer.WriteBytesFull(SumsByteArray[2]); + writer.WriteBytesFull(SumsByteArray[3]); + } } } diff --git a/Assets/Scripts/Networking/PktType.cs b/Assets/Scripts/Networking/PktType.cs index c84c02c..644ba6b 100644 --- a/Assets/Scripts/Networking/PktType.cs +++ b/Assets/Scripts/Networking/PktType.cs @@ -60,5 +60,10 @@ namespace Cyber.Networking { /// public const short Disconnect = 209; + /// + /// Packet containing SyncBase id's of the SyncBases which failed the checksum test. + /// + public const short FailedChecksums = 210; + } } \ No newline at end of file diff --git a/Assets/Scripts/Networking/Serverside/Server.cs b/Assets/Scripts/Networking/Serverside/Server.cs index 5b97de5..b02269f 100644 --- a/Assets/Scripts/Networking/Serverside/Server.cs +++ b/Assets/Scripts/Networking/Serverside/Server.cs @@ -148,6 +148,7 @@ namespace Cyber.Networking.Serverside { NetworkServer.RegisterHandler(PktType.Interact, HandlePacket); NetworkServer.RegisterHandler(PktType.ClientSync, HandlePacket); NetworkServer.RegisterHandler(PktType.Disconnect, HandlePacket); + NetworkServer.RegisterHandler(PktType.FailedChecksums, HandlePacket); NetworkServer.RegisterHandler(MsgType.Connect, OnConnected); NetworkServer.RegisterHandler(MsgType.Disconnect, OnDisconnected); @@ -232,6 +233,13 @@ namespace Cyber.Networking.Serverside { case PktType.Disconnect: msg.conn.Disconnect(); break; + case PktType.FailedChecksums: + IntListPkt FailedSyncs = new IntListPkt(); + FailedSyncs.Deserialize(msg.reader); + foreach (int SyncBaseId in FailedSyncs.IdList) { + Syncer.DirtSyncBase(SyncBaseId); + } + break; default: Debug.LogError("Received an unknown packet, id: " + msg.msgType); Term.Println("Received an unknown packet, id: " + msg.msgType); diff --git a/Assets/Scripts/Networking/Serverside/Syncer.cs b/Assets/Scripts/Networking/Serverside/Syncer.cs index 13af6fd..bcbe82c 100644 --- a/Assets/Scripts/Networking/Serverside/Syncer.cs +++ b/Assets/Scripts/Networking/Serverside/Syncer.cs @@ -31,6 +31,9 @@ namespace Cyber.Networking.Serverside { /// /// The ID of the SyncBase. See public void DirtSyncBase(int syncBaseID) { + if (DirtySyncBases.Contains(syncBaseID)) { + return; + } DirtySyncBases.Add(syncBaseID); } @@ -51,6 +54,8 @@ namespace Cyber.Networking.Serverside { if (TimeSinceLastTick >= TickInterval) { var Categorized = Database.GetCategorizedDatabase(); + List checksummedIds = new List(); + List checksums = new List(); foreach (Type type in Categorized.Keys) { SyncHandletype Handletype = Database.GetSyncHandletypes()[type]; @@ -59,6 +64,13 @@ namespace Cyber.Networking.Serverside { bool Contains = DirtySyncBases.Contains(SyncBaseID); if (Contains == Handletype.RequireHash || Contains) { QueueSyncBase(SyncBaseID); + if (Contains) { + DirtySyncBases.Remove(SyncBaseID); + } + } + if (Handletype.RequireHash) { + checksummedIds.Add(SyncBaseID); + checksums.Add(Database.Get(SyncBaseID).GenerateChecksum()); } } } @@ -66,11 +78,10 @@ namespace Cyber.Networking.Serverside { if (QueuedSyncs.Count > 0) { int[] SyncIDs = QueuedSyncs.ToArray(); - SyncPkt SyncPacket = new SyncPkt(Database, SyncIDs, SyncPacketID++); + SyncPkt SyncPacket = new SyncPkt(Database, SyncIDs, checksummedIds.ToArray(), checksums.ToArray(), SyncPacketID++); Server.SendToAllByChannel(PktType.Sync, SyncPacket, NetworkChannelID.Unreliable); - + QueuedSyncs.Clear(); - DirtySyncBases.Clear(); }