diff --git a/Assets/Scripts/Entities/Character.cs b/Assets/Scripts/Entities/Character.cs
index d98d470..b347f92 100644
--- a/Assets/Scripts/Entities/Character.cs
+++ b/Assets/Scripts/Entities/Character.cs
@@ -1,4 +1,6 @@
-using UnityEngine;
+using System;
+using UnityEngine;
+using UnityEngine.Networking;
namespace Cyber.Entities {
@@ -75,6 +77,35 @@ namespace Cyber.Entities {
transform.localEulerAngles.y, Head.localEulerAngles.z);
}
+ ///
+ /// Gets the Sync Handletype for Character, which doesn't require hash differences and syncs every tick.
+ ///
+ ///
+ public override SyncHandletype GetSyncHandletype() {
+ return new SyncHandletype(false, 1);
+ }
+
+ ///
+ /// Deserializes the character.
+ ///
+ ///
+ public override void Deserialize(NetworkReader reader) {
+ Vector3 pos = reader.ReadVector3();
+ transform.position.Set(pos.x, pos.y, pos.z);
+ Move(reader.ReadVector3());
+ Vector3 rot = reader.ReadVector3();
+ }
+
+ ///
+ /// Serializes the character.
+ ///
+ ///
+ public override void Serialize(NetworkWriter writer) {
+ writer.Write(transform.position);
+ writer.Write(MovementDirection);
+ writer.Write(GetRotation());
+ }
+
private void FixedUpdate() {
CharacterController.Move(MovementDirection * MovementSpeed * Time.fixedDeltaTime);
}
diff --git a/Assets/Scripts/Entities/SyncBase.cs b/Assets/Scripts/Entities/SyncBase.cs
index 9b0bc5d..3a7b875 100644
--- a/Assets/Scripts/Entities/SyncBase.cs
+++ b/Assets/Scripts/Entities/SyncBase.cs
@@ -1,6 +1,5 @@
-using System.Collections;
-using System.Collections.Generic;
-using UnityEngine;
+using UnityEngine;
+using UnityEngine.Networking;
namespace Cyber.Entities {
@@ -8,12 +7,38 @@ namespace Cyber.Entities {
/// A base class for all syncable components. An instance of
/// will contain all of the game's synced components.
///
- public class SyncBase : MonoBehaviour {
+ public abstract class SyncBase : MonoBehaviour {
///
/// The ID this syncable component can be found with from its parent
/// .
///
public int ID;
+
+ ///
+ /// Return the Sync Handletype information for .
+ ///
+ /// Sync Handletype containing sync information.
+ public abstract SyncHandletype GetSyncHandletype();
+
+ ///
+ /// Deserializes this SyncBase for further use.
+ ///
+ ///
+ public abstract void Deserialize(NetworkReader reader);
+
+ ///
+ /// Serialize this SyncBase into a sync packet.
+ ///
+ ///
+ public abstract void Serialize(NetworkWriter writer);
+
+ ///
+ /// Generates a checksum of the contents, or 0 if no checksum is overriden.
+ ///
+ /// The integer checksum.
+ public virtual int GenerateChecksum() {
+ return 0;
+ }
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/Entities/SyncDB.cs b/Assets/Scripts/Entities/SyncDB.cs
index 2866fc7..9eb2f6f 100644
--- a/Assets/Scripts/Entities/SyncDB.cs
+++ b/Assets/Scripts/Entities/SyncDB.cs
@@ -1,7 +1,7 @@
-using System.Collections;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System;
using UnityEngine;
+using Cyber.Networking.Serverside;
namespace Cyber.Entities {
@@ -17,6 +17,8 @@ namespace Cyber.Entities {
private int IDCounter = 0;
private Dictionary Database = new Dictionary();
+ private Dictionary> CategorizedDatabase = new Dictionary>();
+ private Dictionary SyncHandletypes = new Dictionary();
///
/// Add an entity to the database with the given IDs.
@@ -31,6 +33,14 @@ namespace Cyber.Entities {
if (Syncable != null) {
Syncable.ID = ids[Index];
Database[ids[Index++]] = Syncable;
+ if (Server.IsRunning()) {
+ Type Type = Syncable.GetType();
+ if (!CategorizedDatabase.ContainsKey(Type)) {
+ CategorizedDatabase.Add(Type, new List());
+ SyncHandletypes.Add(Type, Syncable.GetSyncHandletype());
+ }
+ CategorizedDatabase[Type].Add(Syncable.ID);
+ }
}
}
}
@@ -83,6 +93,22 @@ namespace Cyber.Entities {
return Database[id];
}
+ ///
+ /// Gives the database categorized into lists of their types.
+ ///
+ /// A dictionary of categorized SyncBases.
+ public Dictionary> GetCategorizedDatabase() {
+ return CategorizedDatabase;
+ }
+
+ ///
+ /// Gets the Sync Handletypes currently known by the SyncDB.
+ ///
+ /// The Sync Handletypes by Type.
+ public Dictionary GetSyncHandletypes() {
+ return SyncHandletypes;
+ }
+
///
/// Creates a new ID which isn't in use yet.
///
diff --git a/Assets/Scripts/Entities/SyncHandletype.cs b/Assets/Scripts/Entities/SyncHandletype.cs
new file mode 100644
index 0000000..29b0924
--- /dev/null
+++ b/Assets/Scripts/Entities/SyncHandletype.cs
@@ -0,0 +1,33 @@
+
+namespace Cyber.Entities {
+
+ ///
+ /// A struct that gives the following information to Syncer about a SyncBase type:
+ /// Does it require a hash difference when syncing?
+ /// How often should this sync be done?
+ ///
+ public struct SyncHandletype {
+
+ ///
+ /// Weather hash difference should be checked before this sync can be done.
+ /// If true, will override .
+ ///
+ public bool RequireHash;
+
+ ///
+ /// How often in ticks should the syncer sync this.
+ ///
+ public int TickInterval;
+
+ ///
+ /// A one-liner to create this struct.
+ ///
+ /// Weather the SyncBase requires a hash to be synced.
+ /// How often should this be synced.
+ public SyncHandletype(bool requireHash, int tickInterval) {
+ RequireHash = requireHash;
+ TickInterval = tickInterval;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Assets/Scripts/Entities/SyncHandletype.cs.meta b/Assets/Scripts/Entities/SyncHandletype.cs.meta
new file mode 100644
index 0000000..4e4f002
--- /dev/null
+++ b/Assets/Scripts/Entities/SyncHandletype.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: df50627e354741e4295b8da5ba13aa29
+timeCreated: 1494329035
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Clientside/Client.cs b/Assets/Scripts/Networking/Clientside/Client.cs
index 7b5db31..8a40e6f 100644
--- a/Assets/Scripts/Networking/Clientside/Client.cs
+++ b/Assets/Scripts/Networking/Clientside/Client.cs
@@ -27,6 +27,8 @@ namespace Cyber.Networking.Clientside {
private Spawner Spawner;
+ private SyncHandler SyncHandler;
+
///
/// The player of this client
///
@@ -92,6 +94,7 @@ namespace Cyber.Networking.Clientside {
private void Start() {
Spawner = GetComponent();
+ SyncHandler = new SyncHandler(Spawner.SyncDB);
}
private bool LaunchClient(string ip, int port) {
@@ -100,8 +103,9 @@ namespace Cyber.Networking.Clientside {
}
ConnectionConfig Config = new ConnectionConfig();
- Config.AddChannel(QosType.ReliableSequenced);
- Config.AddChannel(QosType.UnreliableSequenced);
+ NetworkChannelID.ReliableSequenced = Config.AddChannel(QosType.ReliableSequenced);
+ NetworkChannelID.UnreliableSequenced = Config.AddChannel(QosType.UnreliableSequenced);
+ NetworkChannelID.Unreliable = Config.AddChannel(QosType.Unreliable);
NetworkServer.Configure(Config, 10);
NetClient = new NetworkClient();
@@ -114,6 +118,7 @@ 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(MsgType.Connect, OnConnected);
NetClient.RegisterHandler(MsgType.Disconnect, OnDisconnected);
@@ -129,60 +134,63 @@ namespace Cyber.Networking.Clientside {
private void HandlePacket(NetworkMessage msg) {
switch (msg.msgType) {
- case (PktType.TextMessage):
- TextMessagePkt TextMsg = new TextMessagePkt();
- TextMsg.Deserialize(msg.reader);
- Term.Println(TextMsg.Message);
- break;
- case (PktType.Identity):
- IdentityPkt Identity = new IdentityPkt();
- Identity.Deserialize(msg.reader);
- var Conn = new CConnectedPlayer(Identity.ConnectionID);
- if (Identity.Owned) {
- Player = Conn;
- } else {
- Debug.Log(Conn.ConnectionID + " connected!");
- Term.Println(Conn.ConnectionID + " connected!");
- }
- Players.Add(Conn.ConnectionID, Conn);
- break;
- case (PktType.MassIdentity):
- MassIdentityPkt Identities = new MassIdentityPkt();
- Identities.Deserialize(msg.reader);
- foreach (int currId in Identities.IdList) {
- Players.Add(currId, new CConnectedPlayer(currId));
- }
- break;
- case (PktType.SpawnEntity):
- SpawnEntityPkt SpawnPkt = new SpawnEntityPkt();
- SpawnPkt.Deserialize(msg.reader);
+ case (PktType.TextMessage):
+ TextMessagePkt TextMsg = new TextMessagePkt();
+ TextMsg.Deserialize(msg.reader);
+ Term.Println(TextMsg.Message);
+ break;
+ case (PktType.Identity):
+ IdentityPkt Identity = new IdentityPkt();
+ Identity.Deserialize(msg.reader);
+ var Conn = new CConnectedPlayer(Identity.ConnectionID);
+ if (Identity.Owned) {
+ Player = Conn;
+ } else {
+ Debug.Log(Conn.ConnectionID + " connected!");
+ Term.Println(Conn.ConnectionID + " connected!");
+ }
+ Players.Add(Conn.ConnectionID, Conn);
+ break;
+ case (PktType.MassIdentity):
+ MassIdentityPkt Identities = new MassIdentityPkt();
+ Identities.Deserialize(msg.reader);
+ foreach (int currId in Identities.IdList) {
+ Players.Add(currId, new CConnectedPlayer(currId));
+ }
+ break;
+ case (PktType.SpawnEntity):
+ SpawnEntityPkt SpawnPkt = new SpawnEntityPkt();
+ SpawnPkt.Deserialize(msg.reader);
- EntityType EntityType = SpawnPkt.EntityType;
- // Check if you are the owner and if they are spawning an NPC
- if (SpawnPkt.OwnerID == Player.ConnectionID && EntityType == EntityType.NPC) {
- // Change it into a PC instead.
- EntityType = EntityType.PC;
- }
- Spawner.Spawn(EntityType, SpawnPkt.Position, SpawnPkt.SyncBaseIDList);
- break;
- case (PktType.MoveCreature):
- MoveCreaturePkt MoveCreature = new MoveCreaturePkt();
- MoveCreature.Deserialize(msg.reader);
+ EntityType EntityType = SpawnPkt.EntityType;
+ // Check if you are the owner and if they are spawning an NPC
+ if (SpawnPkt.OwnerID == Player.ConnectionID && EntityType == EntityType.NPC) {
+ // Change it into a PC instead.
+ EntityType = EntityType.PC;
+ }
+ Spawner.Spawn(EntityType, SpawnPkt.Position, SpawnPkt.SyncBaseIDList);
+ break;
+ case (PktType.MoveCreature):
+ MoveCreaturePkt MoveCreature = new MoveCreaturePkt();
+ MoveCreature.Deserialize(msg.reader);
- SyncBase SyncBase = Spawner.SyncDB.Get(MoveCreature.SyncBaseID);
- if (SyncBase != null || SyncBase is Character ) {
- Character Character = (Character) SyncBase;
- Character.Move(MoveCreature.Direction);
- } else {
- Debug.LogError("SyncBase " + MoveCreature.SyncBaseID + " is not a Creature");
- Term.Println("SyncBase " + MoveCreature.SyncBaseID + " is not a Creature");
- }
+ SyncBase SyncBase = Spawner.SyncDB.Get(MoveCreature.SyncBaseID);
+ if (SyncBase != null || SyncBase is Character ) {
+ Character Character = (Character) SyncBase;
+ Character.Move(MoveCreature.Direction);
+ } else {
+ Debug.LogError("SyncBase " + MoveCreature.SyncBaseID + " is not a Creature");
+ Term.Println("SyncBase " + MoveCreature.SyncBaseID + " is not a Creature");
+ }
- break;
- default:
- Debug.LogError("Received an unknown packet, id: " + msg.msgType);
- Term.Println("Received an unknown packet, id: " + msg.msgType);
- break;
+ break;
+ case (PktType.SyncPacket):
+ SyncHandler.HandleSyncPkt(msg);
+ break;
+ default:
+ Debug.LogError("Received an unknown packet, id: " + msg.msgType);
+ Term.Println("Received an unknown packet, id: " + msg.msgType);
+ break;
}
}
diff --git a/Assets/Scripts/Networking/Clientside/SyncHandler.cs b/Assets/Scripts/Networking/Clientside/SyncHandler.cs
new file mode 100644
index 0000000..b070508
--- /dev/null
+++ b/Assets/Scripts/Networking/Clientside/SyncHandler.cs
@@ -0,0 +1,43 @@
+
+using Cyber.Entities;
+using Cyber.Networking.Messages;
+using UnityEngine;
+using UnityEngine.Networking;
+
+namespace Cyber.Networking.Clientside {
+
+ ///
+ /// A Short clientside class for handling sync packages.
+ /// It simply keeps track of sync-packages and will not apply them if they are too old.
+ ///
+ public class SyncHandler {
+
+ private SyncDB SyncDB;
+ private int LatestSyncID = -1;
+
+ ///
+ /// Creates the SyncHandler with SyncDB.
+ ///
+ ///
+ public SyncHandler(SyncDB syncDB) {
+ SyncDB = syncDB;
+ }
+
+ ///
+ /// Handle a given Network message. Must be checked to be first.
+ ///
+ ///
+ public void HandleSyncPkt(NetworkMessage message) {
+ SyncPkt SyncPacket = new SyncPkt(SyncDB);
+ SyncPacket.Deserialize(message.reader);
+ if (LatestSyncID < SyncPacket.SyncPacketID) {
+ LatestSyncID = SyncPacket.SyncPacketID;
+ SyncPacket.ApplySync(message.reader);
+ Debug.Log("Applied Sync " + LatestSyncID);
+ }
+ // Otherwise disregard the sync.
+
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Clientside/SyncHandler.cs.meta b/Assets/Scripts/Networking/Clientside/SyncHandler.cs.meta
new file mode 100644
index 0000000..f485756
--- /dev/null
+++ b/Assets/Scripts/Networking/Clientside/SyncHandler.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6377ec5e92cc97c48aa26423059e4b3a
+timeCreated: 1494337627
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/Messages/SyncPkt.cs b/Assets/Scripts/Networking/Messages/SyncPkt.cs
new file mode 100644
index 0000000..9e41fe3
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/SyncPkt.cs
@@ -0,0 +1,88 @@
+
+using Cyber.Entities;
+using UnityEngine.Networking;
+
+namespace Cyber.Networking.Messages {
+
+ ///
+ /// Contains sync data to sync stuff with.
+ ///
+ public class SyncPkt : MessageBase {
+
+ ///
+ /// The Sync Packet ID of this packet.
+ ///
+ public int SyncPacketID;
+
+ ///
+ /// The Array of SyncID added in this SyncPkt
+ ///
+ public int[] SyncedSyncBases;
+
+ private SyncDB SyncDB;
+
+ ///
+ /// Creates a SyncPkt on the serverside.
+ ///
+ /// 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) {
+ SyncPacketID = syncPacketID;
+ SyncDB = syncDB;
+ SyncedSyncBases = syncBases;
+ }
+
+ ///
+ /// Creates SyncPkt for deserializing.
+ ///
+ /// SyncBase to sync to.
+ public SyncPkt(SyncDB syncDB) {
+ SyncDB = syncDB;
+ }
+
+ ///
+ /// Deserializes the SynkPkt with ONLY the Sync Packet ID.
+ ///
+ ///
+ public override void Deserialize(NetworkReader reader) {
+ SyncPacketID = reader.ReadInt32();
+ }
+
+ ///
+ /// Applies the SyncPkt.
+ ///
+ ///
+ public void ApplySync(NetworkReader reader) {
+ byte[][] ByteArray = new byte[4][];
+ ByteArray[0] = reader.ReadBytesAndSize();
+ ByteArray[1] = reader.ReadBytesAndSize();
+ ByteArray[2] = reader.ReadBytesAndSize();
+ ByteArray[3] = reader.ReadBytesAndSize();
+ SyncedSyncBases = NetworkHelper.DeserializeIntArray(ByteArray);
+
+ foreach (int syncId in SyncedSyncBases) {
+ SyncDB.Get(syncId).Deserialize(reader);
+ }
+ }
+
+ ///
+ /// Serializes the SyncPkt and writes everything it needs.
+ ///
+ ///
+ 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]);
+
+ foreach (int syncId in SyncedSyncBases) {
+ SyncDB.Get(syncId).Serialize(writer);
+ }
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Messages/SyncPkt.cs.meta b/Assets/Scripts/Networking/Messages/SyncPkt.cs.meta
new file mode 100644
index 0000000..696575a
--- /dev/null
+++ b/Assets/Scripts/Networking/Messages/SyncPkt.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b17a30eca8d025d47aa9738d5eaa9b61
+timeCreated: 1494336224
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Assets/Scripts/Networking/NetworkChannelID.cs b/Assets/Scripts/Networking/NetworkChannelID.cs
new file mode 100644
index 0000000..2a90947
--- /dev/null
+++ b/Assets/Scripts/Networking/NetworkChannelID.cs
@@ -0,0 +1,24 @@
+
+namespace Cyber.Networking {
+
+ ///
+ /// Networked channel ID's to be used.
+ ///
+ public class NetworkChannelID {
+
+ ///
+ /// The default channel which is reliable and sequenced. True TCP!
+ ///
+ public static byte ReliableSequenced;
+
+ ///
+ /// Another channel which is unreliable (like UDP) but always in correct sending order (like TCP).
+ ///
+ public static byte UnreliableSequenced;
+
+ ///
+ /// Very unreliable, true UDP!
+ ///
+ public static byte Unreliable;
+ }
+}
diff --git a/Assets/Scripts/Networking/NetworkChannelID.cs.meta b/Assets/Scripts/Networking/NetworkChannelID.cs.meta
new file mode 100644
index 0000000..223477c
--- /dev/null
+++ b/Assets/Scripts/Networking/NetworkChannelID.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: daf9802139051fb4eab0348011f699af
+timeCreated: 1494338663
+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 2bd1db5..9909872 100644
--- a/Assets/Scripts/Networking/PktType.cs
+++ b/Assets/Scripts/Networking/PktType.cs
@@ -32,5 +32,11 @@ namespace Cyber.Networking {
/// to inform actual movement.
///
public const short MoveCreature = 204;
+
+ ///
+ /// Packet containing sync data.
+ ///
+ public const short SyncPacket = 205;
+
}
}
\ No newline at end of file
diff --git a/Assets/Scripts/Networking/Serverside/Server.cs b/Assets/Scripts/Networking/Serverside/Server.cs
index 6d3e9ef..1d845c2 100644
--- a/Assets/Scripts/Networking/Serverside/Server.cs
+++ b/Assets/Scripts/Networking/Serverside/Server.cs
@@ -40,6 +40,23 @@ namespace Cyber.Networking.Serverside {
return Singleton.LaunchServer(port);
}
+ ///
+ /// Sends Message to all clients using specified channel.
+ /// defaults to .
+ ///
+ /// Message type being sent.
+ /// Message contents.
+ /// Channel being used.
+ ///
+ public static bool SendToAllByChannel(short msgType, MessageBase message, byte channel) {
+ if (NetworkServer.active) {
+ NetworkServer.SendByChannelToAll(msgType, message, channel);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
///
/// Attempts to send a message to all clients who are listening.
/// Returns false if server wasn't active, true otherwise.
@@ -91,8 +108,9 @@ namespace Cyber.Networking.Serverside {
Spawner = GetComponent();
ConnectionConfig Config = new ConnectionConfig();
- Config.AddChannel(QosType.ReliableSequenced);
- Config.AddChannel(QosType.UnreliableSequenced);
+ NetworkChannelID.ReliableSequenced = Config.AddChannel(QosType.ReliableSequenced);
+ NetworkChannelID.UnreliableSequenced = Config.AddChannel(QosType.UnreliableSequenced);
+ NetworkChannelID.Unreliable = Config.AddChannel(QosType.Unreliable);
NetworkServer.Configure(Config, 10);
NetworkServer.Listen(port);
@@ -112,6 +130,8 @@ namespace Cyber.Networking.Serverside {
SendToAll(PktType.TextMessage, new TextMessagePkt("Server: " + args[0]));
});
+ gameObject.AddComponent();
+
return true;
}
@@ -129,8 +149,6 @@ namespace Cyber.Networking.Serverside {
// Check if the player is allowed to move this character
Character Controlled = Players[msg.conn.connectionId].Character.GetComponent();
- Debug.Log(Controlled.ID);
- Debug.Log(MoveCreature.SyncBaseID);
if (Controlled.ID != MoveCreature.SyncBaseID) {
break;
}
diff --git a/Assets/Scripts/Networking/Serverside/Syncer.cs b/Assets/Scripts/Networking/Serverside/Syncer.cs
new file mode 100644
index 0000000..44eda17
--- /dev/null
+++ b/Assets/Scripts/Networking/Serverside/Syncer.cs
@@ -0,0 +1,95 @@
+
+using Cyber.Entities;
+using Cyber.Networking.Messages;
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace Cyber.Networking.Serverside {
+
+ ///
+ /// Keeps stuff in-sync over at clients. Periodically collects stuff that needs to be synced and then sends them on the next 'tick.'
+ ///
+ public class Syncer : MonoBehaviour {
+
+ private SyncDB Database;
+
+ private int TickCounter = 0;
+ private const float TickInterval = 1f / 10;
+
+ private float TimeSinceLastTick = TickInterval;
+
+ private List QueuedSyncs = new List();
+ private List DirtySyncBases = new List();
+
+ private int SyncPacketID = 0;
+
+ ///
+ /// Mark a SyncBase "Dirty", which makes it eligible to sync.
+ ///
+ /// The ID of the SyncBase. See
+ public void DirtSyncBase(int syncBaseID) {
+ DirtySyncBases.Add(syncBaseID);
+ }
+
+ ///
+ /// Queue a SyncBase directly, so it will be synced next time a sync tick is called.
+ ///
+ /// The ID of the SyncBase. See
+ public void QueueSyncBase(int SyncBaseID) {
+ QueuedSyncs.Add(SyncBaseID);
+ }
+
+ private void Start() {
+ Database = GetComponent();
+ }
+
+ private void Update() {
+ TimeSinceLastTick += Time.deltaTime;
+ if (TimeSinceLastTick >= TickInterval) {
+
+ var Categorized = Database.GetCategorizedDatabase();
+
+ foreach (Type type in Categorized.Keys) {
+ SyncHandletype Handletype = Database.GetSyncHandletypes()[type];
+ if (Handletype.RequireHash) {
+ foreach (int SyncBaseID in Categorized[type]) {
+ if (DirtySyncBases.Contains(SyncBaseID)) {
+ QueueSyncBase(SyncBaseID);
+ }
+ }
+ } else {
+ if (TickCounter % Handletype.TickInterval == 0) {
+ foreach (int SyncBaseID in Categorized[type]) {
+ if (DirtySyncBases.Contains(SyncBaseID)) {
+ QueueSyncBase(SyncBaseID);
+ }
+ }
+ }
+ }
+ }
+
+ TickCounter++;
+ TimeSinceLastTick -= TickInterval;
+
+ if (QueuedSyncs.Count > 0) {
+ int[] SyncIDs = QueuedSyncs.ToArray();
+ SyncPkt SyncPacket = new SyncPkt(Database, SyncIDs, SyncPacketID++);
+ Server.SendToAllByChannel(PktType.SyncPacket, SyncPacket, NetworkChannelID.Unreliable);
+
+ QueuedSyncs.Clear();
+ DirtySyncBases.Clear();
+ }
+
+ if (Categorized.ContainsKey(typeof(Character))) {
+ foreach (int i in Categorized[typeof(Character)]) {
+ DirtSyncBase(i);
+ }
+ }
+ }
+
+
+ }
+
+ }
+}
diff --git a/Assets/Scripts/Networking/Serverside/Syncer.cs.meta b/Assets/Scripts/Networking/Serverside/Syncer.cs.meta
new file mode 100644
index 0000000..d46e4d0
--- /dev/null
+++ b/Assets/Scripts/Networking/Serverside/Syncer.cs.meta
@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 36a5eba300b7514419b2a8df64f8e7df
+timeCreated: 1494327632
+licenseType: Free
+MonoImporter:
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant: