Basic object sync
This commit is contained in:
@@ -35,6 +35,7 @@ namespace BoneSync
|
|||||||
transport = new SteamTransport();
|
transport = new SteamTransport();
|
||||||
|
|
||||||
SceneSync.Initialize();
|
SceneSync.Initialize();
|
||||||
|
NetworkMessage.RegisterPacketTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void PatchAll()
|
public static void PatchAll()
|
||||||
@@ -62,21 +63,12 @@ namespace BoneSync
|
|||||||
{
|
{
|
||||||
|
|
||||||
transport.Tick();
|
transport.Tick();
|
||||||
PlayerRig.Tick();
|
//PlayerRig.Tick();
|
||||||
|
|
||||||
if (Input.GetKeyDown(KeyCode.P))
|
if (Input.GetKeyDown(KeyCode.P))
|
||||||
{
|
{
|
||||||
MelonLogger.Msg("P key pressed");
|
MelonLogger.Msg("P key pressed");
|
||||||
PlayerRig playerRig = PlayerRig.InstantiatePlayerRigPrefab();
|
//PlayerRig playerRig = PlayerRig.InstantiatePlayerRigPrefab();
|
||||||
if (playerRig == null)
|
|
||||||
{
|
|
||||||
MelonLogger.Error("Failed to instantiate player rig prefab");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MelonLogger.Msg("Player rig instantiated");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (Input.GetKeyDown(KeyCode.I))
|
if (Input.GetKeyDown(KeyCode.I))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ namespace BoneSync.Networking
|
|||||||
}
|
}
|
||||||
public byte[] ReadBytes(int count)
|
public byte[] ReadBytes(int count)
|
||||||
{
|
{
|
||||||
|
if (Data.Count < count)
|
||||||
|
{
|
||||||
|
throw new Exception("Not enough data to read, expected " + count + " but only have " + Data.Count);
|
||||||
|
}
|
||||||
byte[] value = Data.GetRange(0, count).ToArray();
|
byte[] value = Data.GetRange(0, count).ToArray();
|
||||||
Data.RemoveRange(0, count);
|
Data.RemoveRange(0, count);
|
||||||
return value;
|
return value;
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ namespace BoneSync.Networking.LobbyManager
|
|||||||
public abstract ulong GetLobbyId();
|
public abstract ulong GetLobbyId();
|
||||||
public abstract ulong GetHostId();
|
public abstract ulong GetHostId();
|
||||||
public abstract ulong GetLocalId();
|
public abstract ulong GetLocalId();
|
||||||
|
public bool IsHost => GetLocalId() == GetHostId();
|
||||||
|
public abstract bool IsConnected();
|
||||||
|
|
||||||
public abstract void CreateLobby();
|
public abstract void CreateLobby();
|
||||||
public abstract void JoinLobby(ulong lobbyId);
|
public abstract void JoinLobby(ulong lobbyId);
|
||||||
|
|||||||
@@ -42,8 +42,22 @@ namespace BoneSync.Networking.LobbyManager
|
|||||||
UpdateLobbyData();
|
UpdateLobbyData();
|
||||||
};
|
};
|
||||||
MelonLogger.Msg("SteamLobbyManager initialized");
|
MelonLogger.Msg("SteamLobbyManager initialized");
|
||||||
}
|
|
||||||
|
|
||||||
|
SteamFriends.OnGameLobbyJoinRequested += (Lobby lobby, SteamId friend) =>
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Joining lobby " + lobby.Id);
|
||||||
|
JoinLobby(lobby.Id.Value);
|
||||||
|
};
|
||||||
|
|
||||||
|
SteamFriends.OnGameRichPresenceJoinRequested += (Friend friend, string connectString) =>
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Joining lobby " + connectString);
|
||||||
|
ulong lobbyId = ulong.Parse(connectString.Split(':')[1]);
|
||||||
|
JoinLobby(lobbyId);
|
||||||
|
};
|
||||||
|
|
||||||
|
SteamNetworkingUtils.InitRelayNetworkAccess();
|
||||||
|
}
|
||||||
|
|
||||||
private Lobby _lobbyInstance;
|
private Lobby _lobbyInstance;
|
||||||
public Friend[] LobbyMembers
|
public Friend[] LobbyMembers
|
||||||
@@ -57,6 +71,11 @@ namespace BoneSync.Networking.LobbyManager
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool IsConnected()
|
||||||
|
{
|
||||||
|
return _lobbyInstance.Id.IsValid;
|
||||||
|
}
|
||||||
|
|
||||||
public override ulong[] GetPeers() => steamIds.Select(x => x.Value).ToArray();
|
public override ulong[] GetPeers() => steamIds.Select(x => x.Value).ToArray();
|
||||||
public override ulong GetLocalId() => SteamClient.SteamId.Value;
|
public override ulong GetLocalId() => SteamClient.SteamId.Value;
|
||||||
public override ulong GetHostId() => _lobbyInstance.Owner.Id.Value;
|
public override ulong GetHostId() => _lobbyInstance.Owner.Id.Value;
|
||||||
@@ -88,6 +107,7 @@ namespace BoneSync.Networking.LobbyManager
|
|||||||
|
|
||||||
public override void CreateLobby()
|
public override void CreateLobby()
|
||||||
{
|
{
|
||||||
|
LeaveLobby();
|
||||||
MelonLogger.Msg("Trying to create lobby");
|
MelonLogger.Msg("Trying to create lobby");
|
||||||
_ = SteamMatchmaking.CreateLobbyAsync(16);
|
_ = SteamMatchmaking.CreateLobbyAsync(16);
|
||||||
|
|
||||||
@@ -95,13 +115,16 @@ namespace BoneSync.Networking.LobbyManager
|
|||||||
|
|
||||||
public override void JoinLobby(ulong lobbyId)
|
public override void JoinLobby(ulong lobbyId)
|
||||||
{
|
{
|
||||||
|
LeaveLobby();
|
||||||
MelonLogger.Msg("Trying to join lobby " + lobbyId);
|
MelonLogger.Msg("Trying to join lobby " + lobbyId);
|
||||||
_ = SteamMatchmaking.JoinLobbyAsync(lobbyId);
|
_ = SteamMatchmaking.JoinLobbyAsync(lobbyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void LeaveLobby()
|
public override void LeaveLobby()
|
||||||
{
|
{
|
||||||
|
if (!IsConnected()) return;
|
||||||
_lobbyInstance.Leave();
|
_lobbyInstance.Leave();
|
||||||
|
_lobbyInstance = new Lobby();
|
||||||
BoneSync.transport.CleanUp();
|
BoneSync.transport.CleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using BoneSync.Sync;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@@ -15,9 +16,11 @@ namespace BoneSync.Networking.Messages
|
|||||||
}
|
}
|
||||||
public struct ObjectSyncMessageData
|
public struct ObjectSyncMessageData
|
||||||
{
|
{
|
||||||
public ulong objectId;
|
public ushort objectId;
|
||||||
public ObjectSyncTransform[] objectSyncTransforms;
|
public ObjectSyncTransform[] objectSyncTransforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[PacketType(PacketType.ObjectSync), PacketReliability(PacketReliability.UnreliableNoDelay)]
|
||||||
internal class ObjectSyncMessage : NetworkMessage
|
internal class ObjectSyncMessage : NetworkMessage
|
||||||
{
|
{
|
||||||
private ObjectSyncMessageData _objectSyncMessageData = new ObjectSyncMessageData();
|
private ObjectSyncMessageData _objectSyncMessageData = new ObjectSyncMessageData();
|
||||||
@@ -26,7 +29,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public ObjectSyncMessage(ObjectSyncMessageData objectSyncMessageData)
|
public ObjectSyncMessage(ObjectSyncMessageData objectSyncMessageData)
|
||||||
{
|
{
|
||||||
_objectSyncMessageData = objectSyncMessageData;
|
_objectSyncMessageData = objectSyncMessageData;
|
||||||
byteEncoder.WriteUlong(_objectSyncMessageData.objectId);
|
byteEncoder.WriteUShort(_objectSyncMessageData.objectId);
|
||||||
byte length = (byte)_objectSyncMessageData.objectSyncTransforms.Length;
|
byte length = (byte)_objectSyncMessageData.objectSyncTransforms.Length;
|
||||||
byteEncoder.WriteByte(length);
|
byteEncoder.WriteByte(length);
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
@@ -39,7 +42,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public ObjectSyncMessage(Packet packet)
|
public ObjectSyncMessage(Packet packet)
|
||||||
{
|
{
|
||||||
byteEncoder.WriteBytes(packet.Data);
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
_objectSyncMessageData.objectId = byteEncoder.ReadUlong();
|
_objectSyncMessageData.objectId = byteEncoder.ReadUShort();
|
||||||
byte length = byteEncoder.ReadByte();
|
byte length = byteEncoder.ReadByte();
|
||||||
_objectSyncMessageData.objectSyncTransforms = new ObjectSyncTransform[length];
|
_objectSyncMessageData.objectSyncTransforms = new ObjectSyncTransform[length];
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
@@ -49,11 +52,9 @@ namespace BoneSync.Networking.Messages
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
ObjectSync.OnObjectSyncMessage(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,30 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace BoneSync.Networking.Messages
|
namespace BoneSync.Networking.Messages
|
||||||
{
|
{
|
||||||
|
public enum RegisterSyncType
|
||||||
|
{
|
||||||
|
RegisterFromPath = 0,
|
||||||
|
RegisterAndSpawn = 1,
|
||||||
|
}
|
||||||
public struct RegisterSyncableInfo
|
public struct RegisterSyncableInfo
|
||||||
{
|
{
|
||||||
public string transformPath;
|
public string transformPath;
|
||||||
public ushort id;
|
public ushort id;
|
||||||
|
public ulong ownerId;
|
||||||
|
public RegisterSyncType type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[PacketType(PacketType.RegisterSyncable)]
|
||||||
internal class RegisterSyncableMessage : NetworkMessage
|
internal class RegisterSyncableMessage : NetworkMessage
|
||||||
{
|
{
|
||||||
private RegisterSyncableInfo _info;
|
private RegisterSyncableInfo _info;
|
||||||
|
public RegisterSyncableInfo info => _info;
|
||||||
public RegisterSyncableMessage(RegisterSyncableInfo info)
|
public RegisterSyncableMessage(RegisterSyncableInfo info)
|
||||||
{
|
{
|
||||||
_info = info;
|
_info = info;
|
||||||
|
byteEncoder.WriteByte((byte)_info.type);
|
||||||
byteEncoder.WriteString(_info.transformPath);
|
byteEncoder.WriteString(_info.transformPath);
|
||||||
|
byteEncoder.WriteUlong(_info.ownerId);
|
||||||
byteEncoder.WriteUShort(_info.id);
|
byteEncoder.WriteUShort(_info.id);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -26,13 +38,15 @@ namespace BoneSync.Networking.Messages
|
|||||||
public RegisterSyncableMessage(Packet packet)
|
public RegisterSyncableMessage(Packet packet)
|
||||||
{
|
{
|
||||||
byteEncoder.WriteBytes(packet.Data);
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
|
_info.type = (RegisterSyncType)byteEncoder.ReadByte();
|
||||||
_info.transformPath = byteEncoder.ReadString();
|
_info.transformPath = byteEncoder.ReadString();
|
||||||
|
_info.ownerId = byteEncoder.ReadUlong();
|
||||||
_info.id = byteEncoder.ReadUShort();
|
_info.id = byteEncoder.ReadUShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
|
ObjectSync.OnRegisterSyncMessage(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,16 @@ namespace BoneSync.Networking
|
|||||||
public PacketType packetType { get; }
|
public PacketType packetType { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class PacketReliabilityAttribute : Attribute
|
||||||
|
{
|
||||||
|
public PacketReliabilityAttribute(PacketReliability reliability)
|
||||||
|
{
|
||||||
|
this.reliability = reliability;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PacketReliability reliability { get; }
|
||||||
|
}
|
||||||
|
|
||||||
public abstract class NetworkMessage
|
public abstract class NetworkMessage
|
||||||
{
|
{
|
||||||
public ulong senderId
|
public ulong senderId
|
||||||
@@ -33,6 +43,7 @@ namespace BoneSync.Networking
|
|||||||
internal static Dictionary<PacketType, Type> PacketTypeMap = new Dictionary<PacketType, Type>();
|
internal static Dictionary<PacketType, Type> PacketTypeMap = new Dictionary<PacketType, Type>();
|
||||||
|
|
||||||
internal PacketType _packetType;
|
internal PacketType _packetType;
|
||||||
|
internal PacketReliability? _reliability;
|
||||||
internal ByteEncoder byteEncoder = new ByteEncoder();
|
internal ByteEncoder byteEncoder = new ByteEncoder();
|
||||||
|
|
||||||
public byte[] GetBytes() => byteEncoder.ToArray();
|
public byte[] GetBytes() => byteEncoder.ToArray();
|
||||||
@@ -53,6 +64,20 @@ namespace BoneSync.Networking
|
|||||||
return _packetType;
|
return _packetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PacketReliability GetPacketReliability()
|
||||||
|
{
|
||||||
|
if (_reliability.HasValue) return _reliability.Value;
|
||||||
|
PacketReliabilityAttribute reliabilityAttribute = GetType().GetCustomAttribute<PacketReliabilityAttribute>();
|
||||||
|
if (reliabilityAttribute == null)
|
||||||
|
{
|
||||||
|
_reliability = PacketReliability.Reliable;
|
||||||
|
return PacketReliability.Reliable;
|
||||||
|
}
|
||||||
|
|
||||||
|
_reliability = reliabilityAttribute.reliability;
|
||||||
|
return _reliability.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public static void RegisterPacketTypes()
|
public static void RegisterPacketTypes()
|
||||||
{
|
{
|
||||||
if (PacketTypesRegistered)
|
if (PacketTypesRegistered)
|
||||||
@@ -73,6 +98,7 @@ namespace BoneSync.Networking
|
|||||||
}
|
}
|
||||||
public static NetworkMessage ParsePacket(Packet packet)
|
public static NetworkMessage ParsePacket(Packet packet)
|
||||||
{
|
{
|
||||||
|
MelonLogger.Msg("Received packet of type " + packet.Info.packetType + " from " + packet.Info.senderId + " Length: " + packet.Data.Length);
|
||||||
// find a class that can parse this packet using Reflection
|
// find a class that can parse this packet using Reflection
|
||||||
// and return it
|
// and return it
|
||||||
if (!PacketTypeMap.ContainsKey(packet.Info.packetType))
|
if (!PacketTypeMap.ContainsKey(packet.Info.packetType))
|
||||||
@@ -92,7 +118,7 @@ namespace BoneSync.Networking
|
|||||||
|
|
||||||
public Packet GetPacket(int id, ulong senderId, ulong receiverId)
|
public Packet GetPacket(int id, ulong senderId, ulong receiverId)
|
||||||
{
|
{
|
||||||
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, GetPacketType());
|
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, GetPacketType(), GetPacketReliability());
|
||||||
Packet packet = new Packet(packetInfo, GetBytes());
|
Packet packet = new Packet(packetInfo, GetBytes());
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
@@ -102,6 +128,11 @@ namespace BoneSync.Networking
|
|||||||
}
|
}
|
||||||
public void Send(ulong receiverId)
|
public void Send(ulong receiverId)
|
||||||
{
|
{
|
||||||
|
if (BoneSync.lobby.IsConnected() == false)
|
||||||
|
{
|
||||||
|
MelonLogger.Warning("Cannot send packet, not connected to lobby");
|
||||||
|
return;
|
||||||
|
}
|
||||||
int PacketId = Packet.GenerateId();
|
int PacketId = Packet.GenerateId();
|
||||||
ulong senderId = BoneSync.lobby.GetLocalId();
|
ulong senderId = BoneSync.lobby.GetLocalId();
|
||||||
Packet packet = GetPacket(PacketId, senderId, receiverId);
|
Packet packet = GetPacket(PacketId, senderId, receiverId);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using BoneSync.Networking.Messages;
|
using BoneSync.Networking.Messages;
|
||||||
|
using Facepunch.Steamworks;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,19 +10,34 @@ using Xunit;
|
|||||||
namespace BoneSync.Networking
|
namespace BoneSync.Networking
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public enum PacketReliability
|
||||||
|
{
|
||||||
|
Unreliable = 0,
|
||||||
|
UnreliableNoDelay = 1,
|
||||||
|
Reliable = 2,
|
||||||
|
ReliableWithBuffering = 3,
|
||||||
|
}
|
||||||
public struct PacketInfo
|
public struct PacketInfo
|
||||||
{
|
{
|
||||||
public int id;
|
public int id;
|
||||||
public ulong senderId;
|
public ulong senderId;
|
||||||
public ulong receiverId;
|
public ulong receiverId;
|
||||||
public PacketType packetType;
|
public PacketType packetType;
|
||||||
|
public PacketReliability reliability;
|
||||||
|
|
||||||
public PacketInfo(int id, ulong senderId, ulong receiverId, PacketType packetType)
|
public PacketInfo(
|
||||||
|
int id,
|
||||||
|
ulong senderId,
|
||||||
|
ulong receiverId,
|
||||||
|
PacketType packetType,
|
||||||
|
PacketReliability reliability = PacketReliability.Reliable
|
||||||
|
)
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.senderId = senderId;
|
this.senderId = senderId;
|
||||||
this.receiverId = receiverId;
|
this.receiverId = receiverId;
|
||||||
this.packetType = packetType;
|
this.packetType = packetType;
|
||||||
|
this.reliability = reliability;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class Packet
|
public class Packet
|
||||||
@@ -46,19 +62,21 @@ namespace BoneSync.Networking
|
|||||||
ByteEncoder byteEncoder = new ByteEncoder();
|
ByteEncoder byteEncoder = new ByteEncoder();
|
||||||
byteEncoder.WriteBytes(bytes);
|
byteEncoder.WriteBytes(bytes);
|
||||||
|
|
||||||
int packetType = byteEncoder.ReadInt();
|
byte packetType = byteEncoder.ReadByte();
|
||||||
|
byte reliability = byteEncoder.ReadByte();
|
||||||
int id = byteEncoder.ReadInt();
|
int id = byteEncoder.ReadInt();
|
||||||
ulong senderId = byteEncoder.ReadUlong();
|
ulong senderId = byteEncoder.ReadUlong();
|
||||||
ulong receiverId = byteEncoder.ReadUlong();
|
ulong receiverId = byteEncoder.ReadUlong();
|
||||||
|
|
||||||
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, (PacketType)packetType);
|
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, (PacketType)packetType, (PacketReliability)reliability);
|
||||||
return new Packet(packetInfo, byteEncoder.ToArray());
|
return new Packet(packetInfo, byteEncoder.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ToBytes()
|
public byte[] ToBytes()
|
||||||
{
|
{
|
||||||
ByteEncoder byteEncoder = new ByteEncoder();
|
ByteEncoder byteEncoder = new ByteEncoder();
|
||||||
byteEncoder.WriteInt((int)_packetInfo.packetType);
|
byteEncoder.WriteByte((byte)_packetInfo.packetType);
|
||||||
|
byteEncoder.WriteByte((byte)_packetInfo.reliability);
|
||||||
byteEncoder.WriteInt(_packetInfo.id);
|
byteEncoder.WriteInt(_packetInfo.id);
|
||||||
byteEncoder.WriteUlong(_packetInfo.senderId);
|
byteEncoder.WriteUlong(_packetInfo.senderId);
|
||||||
byteEncoder.WriteUlong(_packetInfo.receiverId);
|
byteEncoder.WriteUlong(_packetInfo.receiverId);
|
||||||
|
|||||||
@@ -11,5 +11,7 @@ namespace BoneSync.Networking
|
|||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
LobbyInfo = 1,
|
LobbyInfo = 1,
|
||||||
PlayerSync = 2,
|
PlayerSync = 2,
|
||||||
|
RegisterSyncable = 3,
|
||||||
|
ObjectSync = 4,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||||||
using BoneSync.Sync;
|
using BoneSync.Sync;
|
||||||
using BoneSync.Sync.Components;
|
using BoneSync.Sync.Components;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
|
using MelonLoader;
|
||||||
using StressLevelZero.Interaction;
|
using StressLevelZero.Interaction;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -24,8 +25,29 @@ namespace BoneSync.Patching
|
|||||||
[HarmonyPatch(nameof(InteractableHost.OnDestroy)), HarmonyPostfix]
|
[HarmonyPatch(nameof(InteractableHost.OnDestroy)), HarmonyPostfix]
|
||||||
public static void OnDestroyPatch(InteractableHost __instance)
|
public static void OnDestroyPatch(InteractableHost __instance)
|
||||||
{
|
{
|
||||||
MelonLoader.MelonLogger.Msg("InteractableHost destroyed: " + __instance.name);
|
MelonLogger.Msg("InteractableHost destroyed: " + __instance.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(nameof(InteractableHost.AttachHand)), HarmonyPostfix]
|
||||||
|
public static void AttachHandPatch(InteractableHost __instance, Hand hand)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("InteractableHost attached to hand: " + __instance.name + " Hand: " + hand.name);
|
||||||
|
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance);
|
||||||
|
if (syncable == null)
|
||||||
|
{
|
||||||
|
MelonLogger.Error("Syncable is null for " + __instance.name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syncable.RegisterSyncable();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*[HarmonyPatch(nameof(InteractableHost.AddForcePullGrip)), HarmonyPostfix]
|
||||||
|
public static void AddForcePullGripPatch(InteractableHost __instance, ForcePullGrip grip)
|
||||||
|
{
|
||||||
|
MelonLoader.MelonLogger.Msg("AddForcePullGrip to hand: " + __instance.name + " Hand: " + grip.name);
|
||||||
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(typeof(InteractableHostManager))]
|
[HarmonyPatch(typeof(InteractableHostManager))]
|
||||||
|
|||||||
@@ -17,9 +17,8 @@ namespace BoneSync.Player
|
|||||||
{
|
{
|
||||||
internal class PlayerRig
|
internal class PlayerRig
|
||||||
{
|
{
|
||||||
public const string RIGMANAGER_SCENE_NAME = "[RigManager (Default Brett)]";
|
//public const string RIGMANAGER_SCENE_NAME = "[RigManager (Default Brett)]";
|
||||||
|
|
||||||
private static GameObject _rigPrefabCache = null;
|
|
||||||
private static List<PlayerRig> _playerRigs = new List<PlayerRig>();
|
private static List<PlayerRig> _playerRigs = new List<PlayerRig>();
|
||||||
|
|
||||||
private GameObject playerRig;
|
private GameObject playerRig;
|
||||||
@@ -29,100 +28,18 @@ namespace BoneSync.Player
|
|||||||
private Animator repAnimator;
|
private Animator repAnimator;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo)
|
public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo)
|
||||||
{
|
{
|
||||||
playerRig.transform.ApplySimpleTransform(playerSyncInfo.headPos);
|
//playerRig.transform.ApplySimpleTransform(playerSyncInfo.headPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Tick()
|
public PlayerRig()
|
||||||
{
|
{
|
||||||
TryRegisterRigPrefab();
|
|
||||||
foreach (PlayerRig playerRig in _playerRigs)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
playerRig.UpdateRig();
|
|
||||||
} catch (Exception e)
|
|
||||||
{
|
|
||||||
MelonLogger.Error(e.Message);
|
|
||||||
//MelonLogger.Error("Failed to update player rig");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public static void TryRegisterRigPrefab()
|
|
||||||
{
|
|
||||||
return; // disable this for now
|
|
||||||
if (_rigPrefabCache) return;
|
|
||||||
GetPlayerRigPrefab();
|
|
||||||
}
|
|
||||||
public static GameObject GetPlayerRigPrefab()
|
|
||||||
{
|
|
||||||
if (_rigPrefabCache == null)
|
|
||||||
{
|
|
||||||
// find the rig game object in the scene
|
|
||||||
GameObject playerRig = GameObject.Find(RIGMANAGER_SCENE_NAME);
|
|
||||||
if (playerRig == null)
|
|
||||||
{
|
|
||||||
MelonLogger.Error("Failed to find RigManager scene object");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// create a clone of the rig
|
|
||||||
GameObject playerRep = GameObject.Instantiate(playerRig);
|
|
||||||
playerRep.gameObject.SetActive(false);
|
|
||||||
playerRep.name = "[RigManager (Networked)]";
|
|
||||||
|
|
||||||
RigManager repRigManager = playerRep.GetComponent<RigManager>();
|
|
||||||
repRigManager.oculusControllerRig.gameObject.SetActive(false);
|
|
||||||
repRigManager.steamControllerRig.gameObject.SetActive(false);
|
|
||||||
repRigManager.uiRig.gameObject.SetActive(false);
|
|
||||||
repRigManager.enabled = false;
|
|
||||||
|
|
||||||
|
|
||||||
_rigPrefabCache = playerRep;
|
|
||||||
MelonLogger.Msg("Player rig prefab created");
|
|
||||||
}
|
|
||||||
return _rigPrefabCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PlayerRig InstantiatePlayerRigPrefab()
|
|
||||||
{
|
|
||||||
GameObject prefab = GetPlayerRigPrefab();
|
|
||||||
if (prefab == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
GameObject go = GameObject.Instantiate(prefab);
|
|
||||||
go.SetActive(true);
|
|
||||||
PlayerRig playerRig = new PlayerRig(go);
|
|
||||||
|
|
||||||
return playerRig;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateRig()
|
|
||||||
{
|
|
||||||
Vector3 velocity = Vector3.zero;
|
|
||||||
Vector3 acceleration = Vector3.zero;
|
|
||||||
//SkeletonRig skeletonRig = rigManager.gameWorldSkeletonRig;
|
|
||||||
//skeletonRig.OnLateUpdate();
|
|
||||||
rigManager.ControllerRig.gameObject.SetActive(false);
|
|
||||||
characterAnimationManager.OnLateUpdate();
|
|
||||||
body.FullBodyUpdate(velocity, acceleration);
|
|
||||||
body.ArtToBlender.UpdateBlender();
|
|
||||||
repAnimator.Update(Time.deltaTime);
|
|
||||||
}
|
|
||||||
private PlayerRig(GameObject go)
|
|
||||||
{
|
|
||||||
playerRig = go;
|
|
||||||
rigManager = playerRig.GetComponent<RigManager>();
|
|
||||||
rigManager.enabled = true;
|
|
||||||
|
|
||||||
UpdateRig();
|
|
||||||
_playerRigs.Add(this);
|
_playerRigs.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
_playerRigs.Remove(this);
|
_playerRigs.Remove(this);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ using UnityEngine.Experimental.PlayerLoop;
|
|||||||
using BoneSync.Networking.Messages;
|
using BoneSync.Networking.Messages;
|
||||||
using BoneSync.Networking;
|
using BoneSync.Networking;
|
||||||
using StressLevelZero.Data;
|
using StressLevelZero.Data;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
|
||||||
namespace BoneSync.Sync.Components
|
namespace BoneSync.Sync.Components
|
||||||
@@ -46,22 +47,95 @@ namespace BoneSync.Sync.Components
|
|||||||
[RegisterTypeInIl2Cpp]
|
[RegisterTypeInIl2Cpp]
|
||||||
public class Syncable : MonoBehaviour
|
public class Syncable : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
public const int SYNC_FPS = 20;
|
||||||
|
|
||||||
public Syncable(IntPtr intPtr) : base(intPtr) { }
|
public static List<Syncable> syncablesCache = new List<Syncable>();
|
||||||
|
public Syncable(IntPtr intPtr) : base(intPtr) {
|
||||||
|
syncablesCache.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _syncCoroutineRunning;
|
||||||
|
|
||||||
|
public ulong _ownerId
|
||||||
|
{
|
||||||
|
private set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
private ushort _syncId;
|
private ushort _syncId;
|
||||||
public bool Registered => _syncId != 0;
|
|
||||||
|
|
||||||
private ulong _lastSyncTime;
|
private ulong _lastSyncTime;
|
||||||
private ulong _ownerId;
|
|
||||||
|
|
||||||
|
private bool _attemptedRegister;
|
||||||
|
|
||||||
|
public bool Registered => _syncId != 0;
|
||||||
public bool isStale => Time.time - _lastSyncTime > 5f;
|
public bool isStale => Time.time - _lastSyncTime > 5f;
|
||||||
|
public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId();
|
||||||
|
|
||||||
|
public ushort GetSyncId() => _syncId;
|
||||||
|
public void SetSyncId(ushort id)
|
||||||
|
{
|
||||||
|
|
||||||
|
_syncId = id;
|
||||||
|
ObjectSyncCache.UpdateSyncId(this);
|
||||||
|
}
|
||||||
|
|
||||||
public InteractableHost interactableHost;
|
public InteractableHost interactableHost;
|
||||||
public InteractableHostManager interactableManager;
|
public InteractableHostManager interactableManager;
|
||||||
public Poolee poolee;
|
public Poolee poolee;
|
||||||
|
|
||||||
|
private Rigidbody[] rigidbodies;
|
||||||
private Transform[] transforms;
|
private Transform[] transforms;
|
||||||
|
|
||||||
|
private void SetKinematic(bool kinematic)
|
||||||
|
{
|
||||||
|
foreach (Rigidbody rb in rigidbodies)
|
||||||
|
{
|
||||||
|
rb.isKinematic = kinematic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectSyncTransform[] GetObjectSyncTransforms()
|
||||||
|
{
|
||||||
|
ObjectSyncTransform[] objectSyncTransforms = new ObjectSyncTransform[transforms.Length];
|
||||||
|
for (int i = 0; i < transforms.Length; i++)
|
||||||
|
{
|
||||||
|
objectSyncTransforms[i] = new ObjectSyncTransform()
|
||||||
|
{
|
||||||
|
transform = new SimpleTransform(transforms[i]),
|
||||||
|
velocity = Vector3.zero
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return objectSyncTransforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
|
||||||
|
{
|
||||||
|
if (objectSyncTransforms.Length != transforms.Length)
|
||||||
|
{
|
||||||
|
MelonLogger.Warning("ObjectSyncTransforms length mismatch: " + objectSyncTransforms.Length + " != " + transforms.Length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < objectSyncTransforms.Length; i++)
|
||||||
|
{
|
||||||
|
ObjectSyncTransform objectSyncTransform = objectSyncTransforms[i];
|
||||||
|
transforms[i].ApplySimpleTransform(objectSyncTransform.transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SyncCoroutineAsync()
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Running sync coroutine for: " + gameObject.name);
|
||||||
|
if (_syncCoroutineRunning) return;
|
||||||
|
_syncCoroutineRunning = true;
|
||||||
|
while (isOwner)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Sending object sync message for: " + gameObject.name);
|
||||||
|
ObjectSync.SendObjectSyncMessage(this);
|
||||||
|
await Task.Delay( GetSyncId() == 0 ? 1000 : 1000 / SYNC_FPS);
|
||||||
|
}
|
||||||
|
_syncCoroutineRunning = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
public void OnEnable()
|
public void OnEnable()
|
||||||
{
|
{
|
||||||
FindComponents();
|
FindComponents();
|
||||||
@@ -88,22 +162,26 @@ namespace BoneSync.Sync.Components
|
|||||||
{
|
{
|
||||||
if (poolee && poolee.pool)
|
if (poolee && poolee.pool)
|
||||||
{
|
{
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
if (interactableHost)
|
if (interactableHost || interactableManager)
|
||||||
{
|
{
|
||||||
// get full path from root
|
return transform.GetPath();
|
||||||
return interactableHost.transform.GetPath();
|
|
||||||
}
|
}
|
||||||
return null;
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FindComponents()
|
public void FindComponents()
|
||||||
{
|
{
|
||||||
|
ObjectSyncCache.RemoveSyncable(this);
|
||||||
|
|
||||||
interactableManager = GetComponent<InteractableHostManager>();
|
interactableManager = GetComponent<InteractableHostManager>();
|
||||||
interactableHost = GetComponent<InteractableHost>();
|
interactableHost = GetComponent<InteractableHost>();
|
||||||
poolee = GetComponent<Poolee>();
|
poolee = GetComponent<Poolee>();
|
||||||
|
rigidbodies = GetComponentsInChildren<Rigidbody>();
|
||||||
UpdateTransformList();
|
UpdateTransformList();
|
||||||
|
|
||||||
|
ObjectSyncCache.AddSyncable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShouldSync()
|
public bool ShouldSync()
|
||||||
@@ -123,39 +201,48 @@ namespace BoneSync.Sync.Components
|
|||||||
|
|
||||||
public void DiscardSyncable()
|
public void DiscardSyncable()
|
||||||
{
|
{
|
||||||
|
ObjectSyncCache.RemoveSyncable(this);
|
||||||
Destroy(this);
|
Destroy(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnDisable()
|
public void OnDisable()
|
||||||
{
|
{
|
||||||
DiscardSyncable();
|
if (!Registered)
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectSyncMessageData GetObjectSyncData()
|
|
||||||
{
|
|
||||||
ObjectSyncMessageData data = new ObjectSyncMessageData()
|
|
||||||
{
|
{
|
||||||
objectId = _syncId,
|
DiscardSyncable();
|
||||||
objectSyncTransforms = new ObjectSyncTransform[transforms.Length],
|
return;
|
||||||
};
|
|
||||||
|
|
||||||
for (int i = 0; i < transforms.Length; i++)
|
|
||||||
{
|
|
||||||
data.objectSyncTransforms[i] = new ObjectSyncTransform()
|
|
||||||
{
|
|
||||||
transform = new SimpleTransform(transforms[i]),
|
|
||||||
velocity = Vector3.zero
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
return data;
|
|
||||||
|
MelonLogger.Warning("Registered Syncable disabled: " + transform.GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetOwner(ulong ownerId)
|
||||||
|
{
|
||||||
|
_ownerId = ownerId;
|
||||||
|
MelonLogger.Msg("Set owner for " + gameObject.name + " to " + ownerId);
|
||||||
|
_ = SyncCoroutineAsync();
|
||||||
|
UpdateKinematic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateKinematic()
|
||||||
|
{
|
||||||
|
SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void _SendRegisterSync()
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
|
||||||
|
SetOwner(BoneSync.lobby.GetLocalId());
|
||||||
|
SetSyncId(ObjectSync.SendRegisterSyncableMessage(this));
|
||||||
|
}
|
||||||
public void RegisterSyncable()
|
public void RegisterSyncable()
|
||||||
{
|
{
|
||||||
|
if (!BoneSync.lobby.IsConnected()) return;
|
||||||
|
if (_attemptedRegister) return;
|
||||||
if (Registered) return;
|
if (Registered) return;
|
||||||
if (!ShouldSync()) return;
|
if (!ShouldSync()) return;
|
||||||
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
|
_attemptedRegister = true;
|
||||||
ObjectSync.RegisterSyncable(this);
|
_SendRegisterSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
using BoneSync.Sync.Components;
|
using BoneSync.Networking.Messages;
|
||||||
|
using BoneSync.Sync.Components;
|
||||||
|
using MelonLoader;
|
||||||
using StressLevelZero.Interaction;
|
using StressLevelZero.Interaction;
|
||||||
|
using StressLevelZero.Pool;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -9,12 +12,206 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace BoneSync.Sync
|
namespace BoneSync.Sync
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static class ObjectSyncCache
|
||||||
|
{
|
||||||
|
private static Dictionary<string, Syncable> _pathToSyncable = new Dictionary<string, Syncable>();
|
||||||
|
private static Dictionary<ushort, Syncable> _idToSyncable = new Dictionary<ushort, Syncable>();
|
||||||
|
private static Dictionary<Poolee, Syncable> _pooleeToSyncable = new Dictionary<Poolee, Syncable>();
|
||||||
|
private static Dictionary<InteractableHost, Syncable> _interactableHostToSyncable = new Dictionary<InteractableHost, Syncable>();
|
||||||
|
private static Dictionary<InteractableHostManager, Syncable> _interactableHostManagerToSyncable = new Dictionary<InteractableHostManager, Syncable>();
|
||||||
|
|
||||||
|
|
||||||
|
public static void AddSyncable(Syncable syncable)
|
||||||
|
{
|
||||||
|
string path = syncable.transform.GetPath();
|
||||||
|
if (path != null && path != "")
|
||||||
|
{
|
||||||
|
_pathToSyncable[path] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.GetSyncId() != 0)
|
||||||
|
{
|
||||||
|
_idToSyncable[syncable.GetSyncId()] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.interactableHost)
|
||||||
|
{
|
||||||
|
_interactableHostToSyncable[syncable.interactableHost] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.interactableManager)
|
||||||
|
{
|
||||||
|
_interactableHostManagerToSyncable[syncable.interactableManager] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.poolee)
|
||||||
|
{
|
||||||
|
_pooleeToSyncable[syncable.poolee] = syncable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveSyncable(Syncable syncable)
|
||||||
|
{
|
||||||
|
if (syncable.transform)
|
||||||
|
{
|
||||||
|
_pathToSyncable.Remove(syncable.transform.GetPath());
|
||||||
|
}
|
||||||
|
if (syncable.GetSyncId() != 0)
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(syncable.GetSyncId());
|
||||||
|
}
|
||||||
|
if (syncable.interactableHost)
|
||||||
|
{
|
||||||
|
_interactableHostToSyncable.Remove(syncable.interactableHost);
|
||||||
|
}
|
||||||
|
if (syncable.interactableManager)
|
||||||
|
{
|
||||||
|
_interactableHostManagerToSyncable.Remove(syncable.interactableManager);
|
||||||
|
}
|
||||||
|
if (syncable.poolee)
|
||||||
|
{
|
||||||
|
_pooleeToSyncable.Remove(syncable.poolee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateSyncId(Syncable syncable)
|
||||||
|
{
|
||||||
|
// remove other enties where value is the same
|
||||||
|
foreach (KeyValuePair<ushort, Syncable> entry in _idToSyncable)
|
||||||
|
{
|
||||||
|
if (entry.Value == syncable)
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(entry.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ushort id = syncable.GetSyncId();
|
||||||
|
if (_idToSyncable.ContainsKey(id))
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(id);
|
||||||
|
}
|
||||||
|
_idToSyncable[id] = syncable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(string path)
|
||||||
|
{
|
||||||
|
if (_pathToSyncable.ContainsKey(path))
|
||||||
|
{
|
||||||
|
return _pathToSyncable[path];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(ushort id)
|
||||||
|
{
|
||||||
|
if (_idToSyncable.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _idToSyncable[id];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(Poolee poolee)
|
||||||
|
{
|
||||||
|
if (_pooleeToSyncable.ContainsKey(poolee))
|
||||||
|
{
|
||||||
|
return _pooleeToSyncable[poolee];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(InteractableHost interactableHost)
|
||||||
|
{
|
||||||
|
if (_interactableHostToSyncable.ContainsKey(interactableHost))
|
||||||
|
{
|
||||||
|
return _interactableHostToSyncable[interactableHost];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(InteractableHostManager interactableHostManager)
|
||||||
|
{
|
||||||
|
if (_interactableHostManagerToSyncable.ContainsKey(interactableHostManager))
|
||||||
|
{
|
||||||
|
return _interactableHostManagerToSyncable[interactableHostManager];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DISCARD_ALL_SYNCABLES() {
|
||||||
|
foreach (Syncable syncable in Syncable.syncablesCache)
|
||||||
|
{
|
||||||
|
syncable.DiscardSyncable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
internal class ObjectSync
|
internal class ObjectSync
|
||||||
{
|
{
|
||||||
|
private static ushort _nextSyncableId = 1;
|
||||||
public static void RegisterSyncable(Syncable syncable)
|
public static ushort GetNextId()
|
||||||
{
|
{
|
||||||
|
return _nextSyncableId++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RegisterSyncableInfo? GetRegisterInfo(Syncable syncable)
|
||||||
|
{
|
||||||
|
RegisterSyncableInfo? info = null;
|
||||||
|
string path = syncable.GetSyncableWorldPath();
|
||||||
|
if (path.Length > 0)
|
||||||
|
{
|
||||||
|
info = new RegisterSyncableInfo()
|
||||||
|
{
|
||||||
|
type = RegisterSyncType.RegisterFromPath,
|
||||||
|
transformPath = path,
|
||||||
|
ownerId = syncable._ownerId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (syncable.poolee)
|
||||||
|
{
|
||||||
|
info = new RegisterSyncableInfo()
|
||||||
|
{
|
||||||
|
type = RegisterSyncType.RegisterAndSpawn,
|
||||||
|
transformPath = syncable.poolee.transform.GetPath(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ushort SendRegisterSyncableMessage(Syncable syncable)
|
||||||
|
{
|
||||||
|
RegisterSyncableInfo? infoNullable = GetRegisterInfo(syncable);
|
||||||
|
|
||||||
|
if (infoNullable == null)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("No valid registeration method for syncable");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegisterSyncableInfo info = infoNullable.Value;
|
||||||
|
|
||||||
|
RegisterSyncableMessage message = new RegisterSyncableMessage(info);
|
||||||
|
if (BoneSync.lobby.IsHost)
|
||||||
|
{
|
||||||
|
info.id = GetNextId();
|
||||||
|
message.Broadcast();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info.id = 0;
|
||||||
|
message.Send(BoneSync.lobby.GetHostId());
|
||||||
|
}
|
||||||
|
return info.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendObjectSyncMessage(Syncable syncable)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Sending object sync message for: " + syncable.transform.name);
|
||||||
|
ObjectSyncTransform[] objectSyncTransforms = syncable.GetObjectSyncTransforms();
|
||||||
|
|
||||||
|
ObjectSyncMessageData data = new ObjectSyncMessageData()
|
||||||
|
{
|
||||||
|
objectId = syncable.GetSyncId(),
|
||||||
|
objectSyncTransforms = objectSyncTransforms,
|
||||||
|
};
|
||||||
|
|
||||||
|
ObjectSyncMessage message = new ObjectSyncMessage(data);
|
||||||
|
message.Broadcast();
|
||||||
}
|
}
|
||||||
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncabled = true)
|
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncabled = true)
|
||||||
{
|
{
|
||||||
@@ -34,6 +231,10 @@ namespace BoneSync.Sync
|
|||||||
{
|
{
|
||||||
syncable = gameObject.AddComponent<Syncable>();
|
syncable = gameObject.AddComponent<Syncable>();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syncable.FindComponents();
|
||||||
|
}
|
||||||
return syncable;
|
return syncable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,5 +248,41 @@ namespace BoneSync.Sync
|
|||||||
{
|
{
|
||||||
return _MakeOrGetSyncable(interactableHostManager.gameObject);
|
return _MakeOrGetSyncable(interactableHostManager.gameObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void OnRegisterSyncMessage(RegisterSyncableMessage registerSyncableMessage)
|
||||||
|
{
|
||||||
|
Syncable syncable = null;
|
||||||
|
RegisterSyncableInfo info = registerSyncableMessage.info;
|
||||||
|
if (BoneSync.lobby.IsHost)
|
||||||
|
{
|
||||||
|
info.id = GetNextId();
|
||||||
|
new RegisterSyncableMessage(info).Broadcast();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (info.type)
|
||||||
|
{
|
||||||
|
case RegisterSyncType.RegisterFromPath:
|
||||||
|
MelonLogger.Msg("Registering syncable from path: " + info.transformPath + " with id: " + info.id);
|
||||||
|
syncable = ObjectSyncCache.GetSyncable(info.transformPath);
|
||||||
|
break;
|
||||||
|
case RegisterSyncType.RegisterAndSpawn:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncable.SetSyncId(info.id);
|
||||||
|
syncable.SetOwner(info.ownerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void OnObjectSyncMessage(ObjectSyncMessage objectSyncMessage)
|
||||||
|
{
|
||||||
|
ObjectSyncMessageData data = objectSyncMessage.objectSyncMessageData;
|
||||||
|
Syncable syncable = ObjectSyncCache.GetSyncable(data.objectId);
|
||||||
|
if (syncable == null)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Syncable not found for id: " + data.objectId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syncable.ApplyObjectSyncTransforms(data.objectSyncTransforms);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace BoneSync.Sync
|
|||||||
{
|
{
|
||||||
if (!_playerRigMap.ContainsKey(playerId))
|
if (!_playerRigMap.ContainsKey(playerId))
|
||||||
{
|
{
|
||||||
PlayerRig playerRig = PlayerRig.InstantiatePlayerRigPrefab();
|
PlayerRig playerRig = new PlayerRig();
|
||||||
_playerRigMap.Add(playerId, playerRig);
|
_playerRigMap.Add(playerId, playerRig);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,12 +38,8 @@ namespace BoneSync.Sync
|
|||||||
|
|
||||||
public static void SyncPlayer()
|
public static void SyncPlayer()
|
||||||
{
|
{
|
||||||
if (!_localPlayerRig)
|
|
||||||
{
|
|
||||||
_localPlayerRig = GameObject.Find(PlayerRig.RIGMANAGER_SCENE_NAME);
|
|
||||||
}
|
|
||||||
PlayerSyncInfo playerSyncInfo = new PlayerSyncInfo();
|
PlayerSyncInfo playerSyncInfo = new PlayerSyncInfo();
|
||||||
playerSyncInfo.headPos = new SimpleTransform(_localPlayerRig.transform);
|
playerSyncInfo.headPos = new SimpleTransform();
|
||||||
playerSyncInfo.leftHandPos = new SimpleTransform();
|
playerSyncInfo.leftHandPos = new SimpleTransform();
|
||||||
playerSyncInfo.rightHandPos = new SimpleTransform();
|
playerSyncInfo.rightHandPos = new SimpleTransform();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user