Implement inventory syncing, fixes #10

This commit is contained in:
Sofia 2017-05-14 01:59:30 +03:00
parent 43eb01e9de
commit 307b4ba079
6 changed files with 126 additions and 11 deletions

View File

@ -1,6 +1,8 @@

using Cyber.Console;
using Cyber.Items;
using Cyber.Networking;
using Cyber.Networking.Serverside;
using UnityEngine;
using UnityEngine.Networking;
@ -21,9 +23,24 @@ namespace Cyber.Entities.SyncBases {
/// </summary>
public Inventory() {
Drive = new Drive(10f);
if (Server.IsRunning()) {
Drive.AddItem(ItemDB.Singleton.Get(0));
Drive.AddItem(ItemDB.Singleton.Get(1));
}
}
/// <summary>
/// Generates a checksum for the inventory
/// </summary>
/// <returns>A checksum of the IDs of the items</returns>
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;
}
/// <summary>
/// Returns the sync handletype indicating how the inventory should be synced.
@ -38,6 +55,8 @@ namespace Cyber.Entities.SyncBases {
/// </summary>
/// <param name="reader"></param>
public override void Deserialize(NetworkReader reader) {
Debug.Log("Deserializing inventory!");
byte[][] ByteArray = new byte[4][];
ByteArray[0] = reader.ReadBytesAndSize();
ByteArray[1] = reader.ReadBytesAndSize();

View File

@ -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,22 @@ 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) {
Term.Println("Found checksums!");
List<int> FailedSyncBases = new List<int>();
for (int i = 0; i < SyncBases.Length; i++) {
SyncBase SyncBase = SyncDB.Get(SyncBases[i]);
if (SyncBase.GenerateChecksum() != Checksums[i]) {
Term.Println("Diffrentiating checksum!");
FailedSyncBases.Add(SyncBase.ID);
}
}
Client.Send(PktType.FailedChecksums, new IntListPkt(FailedSyncBases.ToArray()));
}
}
// Otherwise disregard the sync.

View File

@ -20,6 +20,16 @@ namespace Cyber.Networking.Messages {
/// </summary>
public int[] SyncedSyncBases;
/// <summary>
/// The Array of SyncIDs that have their hashes in this syncpacket
/// </summary>
public int[] ChecksummedSyncBases;
/// <summary>
/// The Array of Checksums that are sent with <see cref="ChecksummedSyncBases"/>.
/// </summary>
public int[] Checksums;
private SyncDB SyncDB;
/// <summary>
@ -27,11 +37,15 @@ namespace Cyber.Networking.Messages {
/// </summary>
/// <param name="syncDB">SyncDB to sync from.</param>
/// <param name="syncBases">The ID's of the SyncBases to sync.</param>
/// <param name="checksummedSyncBases"></param>
/// <param name="checksums"></param>
/// <param name="syncPacketID">ID of the sync packet itself.</param>
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;
}
/// <summary>
@ -40,6 +54,8 @@ namespace Cyber.Networking.Messages {
/// <param name="syncDB">SyncBase to sync to.</param>
public SyncPkt(SyncDB syncDB) {
SyncDB = syncDB;
ChecksummedSyncBases = new int[0];
Checksums = new int[0];
}
/// <summary>
@ -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);
}
}
/// <summary>
@ -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]);
}
}
}

View File

@ -60,5 +60,10 @@ namespace Cyber.Networking {
/// </summary>
public const short Disconnect = 209;
/// <summary>
/// Packet containing SyncBase id's of the SyncBases which failed the checksum test.
/// </summary>
public const short FailedChecksums = 210;
}
}

View File

@ -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);

View File

@ -31,6 +31,9 @@ namespace Cyber.Networking.Serverside {
/// </summary>
/// <param name="syncBaseID">The ID of the SyncBase. See <see cref="SyncBase.ID"/></param>
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<int> checksummedIds = new List<int>();
List<int> checksums = new List<int>();
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();
}