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