Ownership transfer and shit, and some pool stuff
This commit is contained in:
@@ -86,6 +86,7 @@
|
||||
<ItemGroup>
|
||||
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />
|
||||
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
|
||||
<Compile Include="Networking\Messages\OnwershipTransferMessage.cs" />
|
||||
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
|
||||
<Compile Include="Patching\CallPatchedMethod.cs" />
|
||||
<Compile Include="Patching\InteractableHostPatches.cs" />
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace BoneSync.Networking
|
||||
return Encoding.UTF8.GetString(ReadBytes(length));
|
||||
}
|
||||
|
||||
public void WriteUlong(ulong value)
|
||||
public void WriteULong(ulong value)
|
||||
{
|
||||
WriteBytes(BitConverter.GetBytes(value));
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ namespace BoneSync.Networking.LobbyManager
|
||||
SteamMatchmaking.OnLobbyMemberJoined += (Lobby lobby, Friend friend) =>
|
||||
{
|
||||
MelonLogger.Msg("Member joined " + friend.Id);
|
||||
SteamFriends.SetPlayedWith(friend.Id);
|
||||
UpdateLobbyData();
|
||||
};
|
||||
MelonLogger.Msg("SteamLobbyManager initialized");
|
||||
@@ -55,8 +56,6 @@ namespace BoneSync.Networking.LobbyManager
|
||||
ulong lobbyId = ulong.Parse(connectString.Split(':')[1]);
|
||||
JoinLobby(lobbyId);
|
||||
};
|
||||
|
||||
SteamNetworkingUtils.InitRelayNetworkAccess();
|
||||
}
|
||||
|
||||
private Lobby _lobbyInstance;
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace BoneSync.Networking.Messages
|
||||
public ObjectHealthInfo objectHealthInfo;
|
||||
}
|
||||
|
||||
[PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.UnreliableNoDelay)]
|
||||
[PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Unreliable)]
|
||||
public class ObjectDamageMessage : NetworkMessage
|
||||
{
|
||||
public ObjectDamageInfo objectEventInfo => _objectEventInfo;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace BoneSync.Networking.Messages
|
||||
public ObjectSyncTransform[] objectSyncTransforms;
|
||||
}
|
||||
|
||||
[PacketType(PacketType.ObjectSync), PacketReliability(PacketReliability.UnreliableNoDelay)]
|
||||
[PacketType(PacketType.ObjectSync), PacketReliability(PacketReliability.Unreliable)]
|
||||
internal class ObjectSyncMessage : NetworkMessage
|
||||
{
|
||||
private ObjectSyncMessageData _objectSyncMessageData = new ObjectSyncMessageData();
|
||||
|
||||
43
BoneSync/Networking/Messages/OnwershipTransferMessage.cs
Normal file
43
BoneSync/Networking/Messages/OnwershipTransferMessage.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BoneSync.Sync;
|
||||
|
||||
namespace BoneSync.Networking.Messages
|
||||
{
|
||||
public struct OnwershipTransferMessageData
|
||||
{
|
||||
public ushort SyncId;
|
||||
public bool force;
|
||||
public ulong NewOwnerId;
|
||||
}
|
||||
|
||||
[PacketType(PacketType.ObjectOwnership)]
|
||||
internal class OnwershipTransferMessage : NetworkMessage
|
||||
{
|
||||
private OnwershipTransferMessageData Data;
|
||||
public OnwershipTransferMessage(OnwershipTransferMessageData data)
|
||||
{
|
||||
Data = data;
|
||||
byteEncoder.WriteUShort(Data.SyncId);
|
||||
byteEncoder.WriteULong(Data.NewOwnerId);
|
||||
byteEncoder.WriteBool(Data.force);
|
||||
}
|
||||
|
||||
public OnwershipTransferMessage(Packet packet)
|
||||
{
|
||||
byteEncoder.WriteBytes(packet.Data);
|
||||
Data.SyncId = byteEncoder.ReadUShort();
|
||||
Data.NewOwnerId = byteEncoder.ReadUlong();
|
||||
Data.force = byteEncoder.ReadBool();
|
||||
}
|
||||
|
||||
override public void Execute()
|
||||
{
|
||||
ObjectSync.OnOwnershipChangeMessage(Data.SyncId, Data.NewOwnerId, Data.force);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,12 +23,13 @@ namespace BoneSync.Networking.Messages
|
||||
{
|
||||
public string transformPath;
|
||||
public ushort id;
|
||||
public ushort callbackId;
|
||||
public ulong ownerId;
|
||||
public RegisterSyncType type;
|
||||
public SpawnPoolableInfo? spawnInfo;
|
||||
}
|
||||
|
||||
[PacketType(PacketType.RegisterSyncable)]
|
||||
[PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast)]
|
||||
internal class RegisterSyncableMessage : NetworkMessage
|
||||
{
|
||||
private RegisterSyncableInfo _info;
|
||||
@@ -37,8 +38,9 @@ namespace BoneSync.Networking.Messages
|
||||
{
|
||||
_info = info;
|
||||
byteEncoder.WriteByte((byte)_info.type);
|
||||
byteEncoder.WriteUlong(_info.ownerId);
|
||||
byteEncoder.WriteULong(_info.ownerId);
|
||||
byteEncoder.WriteUShort(_info.id);
|
||||
byteEncoder.WriteUShort(_info.callbackId);
|
||||
switch (_info.type)
|
||||
{
|
||||
case RegisterSyncType.RegisterAndSpawn:
|
||||
@@ -58,6 +60,7 @@ namespace BoneSync.Networking.Messages
|
||||
_info.type = (RegisterSyncType)byteEncoder.ReadByte();
|
||||
_info.ownerId = byteEncoder.ReadUlong();
|
||||
_info.id = byteEncoder.ReadUShort();
|
||||
_info.callbackId = byteEncoder.ReadUShort();
|
||||
switch (_info.type)
|
||||
{
|
||||
case RegisterSyncType.RegisterAndSpawn:
|
||||
|
||||
@@ -118,9 +118,9 @@ namespace BoneSync.Networking
|
||||
|
||||
|
||||
|
||||
public Packet GetPacket(int id, ulong senderId, ulong receiverId)
|
||||
public Packet GetPacket(ulong senderId, ulong receiverId)
|
||||
{
|
||||
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, GetPacketType(), GetPacketReliability());
|
||||
PacketInfo packetInfo = new PacketInfo(senderId, receiverId, GetPacketType(), GetPacketReliability());
|
||||
Packet packet = new Packet(packetInfo, GetBytes());
|
||||
return packet;
|
||||
}
|
||||
@@ -140,9 +140,8 @@ namespace BoneSync.Networking
|
||||
MelonLogger.Warning("Cannot send packet, not connected to lobby");
|
||||
return;
|
||||
}
|
||||
int PacketId = Packet.GenerateId();
|
||||
ulong senderId = BoneSync.lobby.GetLocalId();
|
||||
Packet packet = GetPacket(PacketId, senderId, receiverId);
|
||||
Packet packet = GetPacket(senderId, receiverId);
|
||||
BoneSync.transport.Send(packet);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,35 +15,61 @@ namespace BoneSync.Networking
|
||||
public enum PacketReliability
|
||||
{
|
||||
Unreliable = 0,
|
||||
UnreliableNoDelay = 1,
|
||||
Reliable = 2,
|
||||
ReliableWithBuffering = 3,
|
||||
Reliable = 1,
|
||||
ReliableFast = 2,
|
||||
}
|
||||
public struct PacketInfo
|
||||
{
|
||||
public int id;
|
||||
public ulong id;
|
||||
public ulong senderId;
|
||||
public ulong receiverId;
|
||||
public PacketType packetType;
|
||||
public PacketReliability reliability;
|
||||
|
||||
public PacketInfo(
|
||||
int id,
|
||||
ulong senderId,
|
||||
ulong receiverId,
|
||||
PacketType packetType,
|
||||
PacketReliability reliability = PacketReliability.Reliable
|
||||
PacketReliability reliability = PacketReliability.Reliable,
|
||||
ulong id = 0
|
||||
)
|
||||
{
|
||||
this.id = id;
|
||||
this.senderId = senderId;
|
||||
this.receiverId = receiverId;
|
||||
this.packetType = packetType;
|
||||
this.reliability = reliability;
|
||||
this.id = id == 0 ? Packet.GenerateId() : id;
|
||||
|
||||
}
|
||||
}
|
||||
public class Packet
|
||||
{
|
||||
private static ulong _packetId = 1;
|
||||
|
||||
private static Dictionary<ulong, Dictionary<PacketType, ulong>> _latestPacketIds = new Dictionary<ulong, Dictionary<PacketType, ulong>>();
|
||||
|
||||
private static void SetLatestPacketId(ulong id, PacketType packetType, ulong value)
|
||||
{
|
||||
if (!_latestPacketIds.ContainsKey(id))
|
||||
{
|
||||
_latestPacketIds.Add(id, new Dictionary<PacketType, ulong>());
|
||||
}
|
||||
_latestPacketIds[id][packetType] = value;
|
||||
}
|
||||
|
||||
private static ulong GetLatestPacketId(ulong id, PacketType packetType)
|
||||
{
|
||||
if (!_latestPacketIds.ContainsKey(id))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (!_latestPacketIds[id].ContainsKey(packetType))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return _latestPacketIds[id][packetType];
|
||||
}
|
||||
|
||||
public PacketInfo Info
|
||||
{
|
||||
get => _packetInfo;
|
||||
@@ -66,11 +92,11 @@ namespace BoneSync.Networking
|
||||
|
||||
byte packetType = byteEncoder.ReadByte();
|
||||
byte reliability = byteEncoder.ReadByte();
|
||||
int id = byteEncoder.ReadInt();
|
||||
ulong id = byteEncoder.ReadUlong();
|
||||
ulong senderId = byteEncoder.ReadUlong();
|
||||
ulong receiverId = byteEncoder.ReadUlong();
|
||||
|
||||
PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, (PacketType)packetType, (PacketReliability)reliability);
|
||||
PacketInfo packetInfo = new PacketInfo(senderId, receiverId, (PacketType)packetType, (PacketReliability)reliability, id);
|
||||
return new Packet(packetInfo, byteEncoder.ToArray());
|
||||
}
|
||||
|
||||
@@ -79,15 +105,24 @@ namespace BoneSync.Networking
|
||||
ByteEncoder byteEncoder = new ByteEncoder();
|
||||
byteEncoder.WriteByte((byte)_packetInfo.packetType);
|
||||
byteEncoder.WriteByte((byte)_packetInfo.reliability);
|
||||
byteEncoder.WriteInt(_packetInfo.id);
|
||||
byteEncoder.WriteUlong(_packetInfo.senderId);
|
||||
byteEncoder.WriteUlong(_packetInfo.receiverId);
|
||||
byteEncoder.WriteULong(_packetInfo.id);
|
||||
byteEncoder.WriteULong(_packetInfo.senderId);
|
||||
byteEncoder.WriteULong(_packetInfo.receiverId);
|
||||
byteEncoder.WriteBytes(_dataBytes);
|
||||
return byteEncoder.ToArray();
|
||||
}
|
||||
|
||||
public static bool OnPacketReceived(Packet packet)
|
||||
{
|
||||
if (packet._packetInfo.reliability == PacketReliability.ReliableFast)
|
||||
{
|
||||
if (packet.Info.id <= GetLatestPacketId(packet.Info.senderId, packet.Info.packetType))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SetLatestPacketId(packet.Info.senderId, packet.Info.packetType, packet.Info.id);
|
||||
}
|
||||
|
||||
NetworkMessage networkMessage = NetworkMessage.ParsePacket(packet);
|
||||
networkMessage.Execute();
|
||||
return true;
|
||||
@@ -95,9 +130,9 @@ namespace BoneSync.Networking
|
||||
|
||||
public byte[] Data => _dataBytes;
|
||||
|
||||
public static int GenerateId()
|
||||
public static ulong GenerateId()
|
||||
{
|
||||
return new Random().Next();
|
||||
return _packetId++;
|
||||
}
|
||||
}
|
||||
#if TEST
|
||||
|
||||
@@ -14,5 +14,6 @@ namespace BoneSync.Networking
|
||||
RegisterSyncable = 3,
|
||||
ObjectSync = 4,
|
||||
ObjectEvent = 5,
|
||||
ObjectOwnership = 6,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ using BoneSync.Networking.LobbyManager;
|
||||
using Facepunch.Steamworks;
|
||||
using Facepunch.Steamworks.Data;
|
||||
using MelonLoader;
|
||||
using Oculus.Platform;
|
||||
|
||||
namespace BoneSync.Networking.Transport
|
||||
{
|
||||
@@ -17,6 +18,7 @@ namespace BoneSync.Networking.Transport
|
||||
public SteamTransport()
|
||||
{
|
||||
SteamNetworking.OnP2PSessionRequest += OnP2PSessionRequest;
|
||||
SteamNetworkingUtils.InitRelayNetworkAccess();
|
||||
}
|
||||
private List<SteamId> OpenP2PConnections = new List<SteamId>();
|
||||
private void OnP2PSessionRequest(SteamId steamId)
|
||||
@@ -72,18 +74,44 @@ namespace BoneSync.Networking.Transport
|
||||
return processed > 0;
|
||||
}
|
||||
|
||||
public void SendP2P(SteamId peer, byte[] data, P2PSend sendType)
|
||||
public P2PSend GetSteamSendType(PacketReliability packetReliability)
|
||||
{
|
||||
switch (packetReliability)
|
||||
{
|
||||
case PacketReliability.Unreliable:
|
||||
return P2PSend.UnreliableNoDelay;
|
||||
case PacketReliability.Reliable:
|
||||
return P2PSend.Reliable;
|
||||
default:
|
||||
return P2PSend.Reliable;
|
||||
}
|
||||
}
|
||||
|
||||
public void SendP2P(SteamId peer, byte[] data, PacketReliability sendType)
|
||||
{
|
||||
|
||||
if (peer == BoneSync.lobby.GetLocalId())
|
||||
{
|
||||
//MelonLogger.Msg("Trying to send packet to self");
|
||||
return;
|
||||
}
|
||||
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, sendType);
|
||||
|
||||
if (sendType == PacketReliability.ReliableFast)
|
||||
{
|
||||
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, P2PSend.UnreliableNoDelay);
|
||||
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, P2PSend.Reliable);
|
||||
return;
|
||||
}
|
||||
|
||||
P2PSend steamSendType = GetSteamSendType(sendType);
|
||||
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, steamSendType);
|
||||
|
||||
|
||||
|
||||
}
|
||||
public override void Send(Packet packet)
|
||||
{
|
||||
P2PSend sendType = (P2PSend)packet.Info.reliability;
|
||||
|
||||
LobbyManager.LobbyManager _instance = BoneSync.lobby;
|
||||
if (_instance == null)
|
||||
{
|
||||
@@ -94,14 +122,14 @@ namespace BoneSync.Networking.Transport
|
||||
{
|
||||
foreach (SteamId peer in _instance.GetPeers())
|
||||
{
|
||||
SendP2P(peer, packet.ToBytes(), sendType);
|
||||
SendP2P(peer, packet.ToBytes(), packet.Info.reliability);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendP2P(packet.Info.receiverId, packet.ToBytes(), sendType);
|
||||
SendP2P(packet.Info.receiverId, packet.ToBytes(), packet.Info.reliability);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ namespace BoneSync.Patching
|
||||
{
|
||||
public static class PoolBlacklist
|
||||
{
|
||||
private static Dictionary<Pool, Boolean> _blacklistedCache = new Dictionary<Pool, bool>();
|
||||
private static Dictionary<Pool, bool> _blacklistedCache = new Dictionary<Pool, bool>();
|
||||
private static Dictionary<Pool, bool> _clientSpawnCache = new Dictionary<Pool, bool>();
|
||||
|
||||
private static bool _isBlacklistedPool(Pool pool)
|
||||
{
|
||||
@@ -31,10 +32,15 @@ namespace BoneSync.Patching
|
||||
|
||||
if (pool.Prefab.GetComponent<SpawnFragment>() != null) return true;
|
||||
if (pool.Prefab.GetComponent<SpawnFragmentArray>() != null) return true;
|
||||
if (pool.Prefab.GetComponent<Magazine>() != null) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool _isClientSpawnPool(Pool pool)
|
||||
{
|
||||
if (pool.Prefab.GetComponent<Magazine>() != null) return true;
|
||||
return false;
|
||||
}
|
||||
public static bool isBlacklistedPool(Pool pool)
|
||||
{
|
||||
if (_blacklistedCache.ContainsKey(pool))
|
||||
@@ -42,6 +48,14 @@ namespace BoneSync.Patching
|
||||
_blacklistedCache[pool] = _isBlacklistedPool(pool);
|
||||
return _blacklistedCache[pool];
|
||||
}
|
||||
|
||||
public static bool IsClientSpawnPool(Pool pool)
|
||||
{
|
||||
if (_clientSpawnCache.ContainsKey(pool))
|
||||
return _clientSpawnCache[pool];
|
||||
_clientSpawnCache[pool] = _isClientSpawnPool(pool);
|
||||
return _clientSpawnCache[pool];
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(Pool))]
|
||||
@@ -110,19 +124,19 @@ namespace BoneSync.Patching
|
||||
public static void OnSpawnPatchPost(Poolee __instance)
|
||||
{
|
||||
if (CallPatchedMethods.allowPatchedMethodCall) return;
|
||||
if (__instance.pool == null) return;
|
||||
if (PoolBlacklist.isBlacklistedPool(__instance.pool)) return;
|
||||
MelonLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath());
|
||||
if (!BoneSync.lobby.IsConnected()) return;
|
||||
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance);
|
||||
|
||||
if (BoneSync.lobby.IsHost)
|
||||
{
|
||||
//syncable.RegisterSyncable();
|
||||
} else
|
||||
{
|
||||
MelonCoroutines.Start(OnSpawnClient(__instance));
|
||||
}
|
||||
MelonLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath());
|
||||
|
||||
ObjectSync.MakeOrGetSyncable(__instance);
|
||||
|
||||
bool spawnNormally = BoneSync.lobby.IsHost || PoolBlacklist.IsClientSpawnPool(__instance.pool);
|
||||
|
||||
if (spawnNormally) return;
|
||||
|
||||
|
||||
MelonCoroutines.Start(OnSpawnClient(__instance)); // block object from spawning
|
||||
|
||||
}
|
||||
|
||||
public static IEnumerator OnSpawnClient(Poolee poolee)
|
||||
@@ -135,8 +149,6 @@ namespace BoneSync.Patching
|
||||
go.SetActive(false);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
|
||||
@@ -72,23 +72,6 @@ namespace BoneSync.Sync.Components
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool ShouldSendSync()
|
||||
{
|
||||
if (!Registered) return false;
|
||||
if (!isOwner) return false;
|
||||
if (isStale) return true;
|
||||
if (AllRigidbodiesSleeping()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public ushort GetSyncId() => _syncId;
|
||||
public void SetSyncId(ushort id)
|
||||
{
|
||||
|
||||
_syncId = id;
|
||||
ObjectSyncCache.UpdateSyncId(this);
|
||||
}
|
||||
|
||||
public InteractableHost interactableHost { private set; get; }
|
||||
public InteractableHostManager interactableManager { private set; get; }
|
||||
public Poolee poolee { private set; get; }
|
||||
@@ -117,7 +100,7 @@ namespace BoneSync.Sync.Components
|
||||
FindComponents();
|
||||
|
||||
bool shouldAutoSync = CheckIfShouldAutoSync();
|
||||
if (shouldAutoSync && BoneSync.lobby.IsHost)
|
||||
if (shouldAutoSync && (BoneSync.lobby.IsHost || ClientSpawningAllowed()))
|
||||
{
|
||||
MelonLogger.Msg("AutoSyncing: " + transform.GetPath());
|
||||
RegisterSyncable();
|
||||
@@ -181,27 +164,29 @@ namespace BoneSync.Sync.Components
|
||||
|
||||
public void DiscardSyncable()
|
||||
{
|
||||
if (Registered)
|
||||
{
|
||||
MelonLogger.Warning("Discarding registered syncable: " + transform.GetPath());
|
||||
}
|
||||
syncablesCache.Remove(gameObject);
|
||||
ObjectSyncCache.RemoveSyncable(this);
|
||||
Destroy(this);
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
if (!Registered)
|
||||
{
|
||||
DiscardSyncable();
|
||||
return;
|
||||
}
|
||||
|
||||
MelonLogger.Warning("Registered Syncable disabled: " + transform.GetPath());
|
||||
}
|
||||
|
||||
public void RegisterSyncable()
|
||||
{
|
||||
if (!BoneSync.lobby.IsConnected()) return;
|
||||
if (Registered)
|
||||
{
|
||||
TryBecomeOwner();
|
||||
return;
|
||||
}
|
||||
if (_attemptedRegister) return;
|
||||
if (Registered) return;
|
||||
if (!CanBeSynced()) return;
|
||||
_attemptedRegister = true;
|
||||
_SendRegisterSync();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using MelonLoader;
|
||||
using BoneSync.Networking.Messages;
|
||||
using BoneSync.Patching;
|
||||
using MelonLoader;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@@ -37,6 +39,16 @@ namespace BoneSync.Sync.Components
|
||||
MelonCoroutines.Start(SyncCoroutineAsync());
|
||||
UpdateKinematic();
|
||||
}
|
||||
|
||||
public bool ClientSpawningAllowed()
|
||||
{
|
||||
if (poolee && poolee.pool)
|
||||
{
|
||||
return PoolBlacklist.IsClientSpawnPool(poolee.pool);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void _SendRegisterSync()
|
||||
{
|
||||
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
|
||||
@@ -46,12 +58,53 @@ namespace BoneSync.Sync.Components
|
||||
|
||||
public void OnOwnershipTransferRequest(ulong newOwnerId)
|
||||
{
|
||||
MelonLogger.Msg("Ownership transfer request for " + _syncId + " to " + newOwnerId);
|
||||
if (isOwner)
|
||||
//MelonLogger.Msg("Ownership transfer request for " + _syncId + " to " + newOwnerId);
|
||||
if (isOwner && !IsHolding())
|
||||
{
|
||||
MelonLogger.Msg("Sending ownership transfer for " + _syncId + " to " + newOwnerId);
|
||||
//BoneSync.lobby.SendOwnershipTransferMessage(_syncId, newOwnerId);
|
||||
OnwershipTransferMessageData data = new OnwershipTransferMessageData()
|
||||
{
|
||||
SyncId = _syncId,
|
||||
NewOwnerId = newOwnerId,
|
||||
force = true
|
||||
};
|
||||
OnwershipTransferMessage message = new OnwershipTransferMessage(data);
|
||||
message.Broadcast();
|
||||
SetOwner(newOwnerId);
|
||||
}
|
||||
}
|
||||
|
||||
public void TryBecomeOwner()
|
||||
{
|
||||
if (!isOwner)
|
||||
{
|
||||
MelonLogger.Msg("Attempting to become owner of " + _syncId);
|
||||
OnwershipTransferMessageData data = new OnwershipTransferMessageData()
|
||||
{
|
||||
SyncId = _syncId,
|
||||
NewOwnerId = BoneSync.lobby.GetLocalId(),
|
||||
force = false
|
||||
};
|
||||
OnwershipTransferMessage message = new OnwershipTransferMessage(data);
|
||||
message.Broadcast();
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShouldSendSync()
|
||||
{
|
||||
if (!Registered) return false;
|
||||
if (!isOwner) return false;
|
||||
if (isStale) return true;
|
||||
if (AllRigidbodiesSleeping()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public ushort GetSyncId() => _syncId;
|
||||
public void SetSyncId(ushort id)
|
||||
{
|
||||
|
||||
_syncId = id;
|
||||
ObjectSyncCache.UpdateSyncId(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,27 @@ namespace BoneSync.Sync.Components
|
||||
public bool AllRigidbodiesSleeping()
|
||||
{
|
||||
foreach (Rigidbody rb in rigidbodies)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!rb.IsSleeping()) return false;
|
||||
}
|
||||
catch { } // ignore null rigidbodies
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
private void SetKinematic(bool kinematic)
|
||||
{
|
||||
foreach (Rigidbody rb in rigidbodies)
|
||||
{
|
||||
try
|
||||
{
|
||||
rb.isKinematic = kinematic;
|
||||
}
|
||||
catch { } // ignore null rigidbodies
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectSyncTransform[] GetObjectSyncTransforms()
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace BoneSync.Sync
|
||||
{
|
||||
@@ -23,8 +24,10 @@ namespace BoneSync.Sync
|
||||
return _nextSyncableId++;
|
||||
}
|
||||
|
||||
public static RegisterSyncableInfo? GetRegisterInfo(Syncable syncable)
|
||||
|
||||
public static RegisterSyncableInfo? GetRegisterInfo(Syncable syncable, bool allowClientRegister)
|
||||
{
|
||||
ulong ownerId = BoneSync.lobby.GetLocalId();
|
||||
RegisterSyncableInfo? info = null;
|
||||
string path = syncable.GetSyncableWorldPath();
|
||||
if (path.Length > 0)
|
||||
@@ -33,13 +36,14 @@ namespace BoneSync.Sync
|
||||
{
|
||||
type = RegisterSyncType.RegisterFromPath,
|
||||
transformPath = path,
|
||||
ownerId = syncable._ownerId,
|
||||
ownerId = ownerId,
|
||||
};
|
||||
}
|
||||
else if (syncable.poolee && syncable.poolee.pool && BoneSync.lobby.IsHost)
|
||||
else if (syncable.poolee && syncable.poolee.pool && (BoneSync.lobby.IsHost || allowClientRegister))
|
||||
{
|
||||
info = new RegisterSyncableInfo()
|
||||
{
|
||||
ownerId = ownerId,
|
||||
type = RegisterSyncType.RegisterAndSpawn,
|
||||
spawnInfo = new SpawnPoolableInfo()
|
||||
{
|
||||
@@ -53,7 +57,7 @@ namespace BoneSync.Sync
|
||||
|
||||
public static ushort SendRegisterSyncableMessage(Syncable syncable)
|
||||
{
|
||||
RegisterSyncableInfo? infoNullable = GetRegisterInfo(syncable);
|
||||
RegisterSyncableInfo? infoNullable = GetRegisterInfo(syncable, syncable.ClientSpawningAllowed());
|
||||
|
||||
if (infoNullable == null)
|
||||
{
|
||||
@@ -71,7 +75,8 @@ namespace BoneSync.Sync
|
||||
new RegisterSyncableMessage(info).Broadcast();
|
||||
} else
|
||||
{
|
||||
info.id = 0;
|
||||
info.callbackId = (ushort)Random.Range(1, ushort.MaxValue);
|
||||
ObjectSyncCache._callbackIdToSyncable[info.callbackId] = syncable;
|
||||
new RegisterSyncableMessage(info).SendToHost();
|
||||
}
|
||||
|
||||
@@ -100,10 +105,13 @@ namespace BoneSync.Sync
|
||||
//Scene scene = gameObject.scene;
|
||||
//MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name);
|
||||
|
||||
Syncable[] subSyncables = gameObject.GetComponentsInChildren<Syncable>();
|
||||
|
||||
Syncable syncable = gameObject.GetComponent<Syncable>();
|
||||
|
||||
// delete all sub syncables
|
||||
if (deleteSubSyncabled)
|
||||
{
|
||||
Syncable[] subSyncables = gameObject.GetComponentsInChildren<Syncable>(true);
|
||||
for (int i = 0; i < subSyncables.Length; i++)
|
||||
{
|
||||
if (subSyncables[i] != syncable)
|
||||
@@ -111,15 +119,12 @@ namespace BoneSync.Sync
|
||||
subSyncables[i].DiscardSyncable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (syncable == null)
|
||||
{
|
||||
syncable = gameObject.AddComponent<Syncable>();
|
||||
}
|
||||
else
|
||||
{
|
||||
syncable.FindComponents();
|
||||
}
|
||||
return syncable;
|
||||
}
|
||||
|
||||
@@ -158,10 +163,9 @@ namespace BoneSync.Sync
|
||||
return _MakeOrGetSyncable(interactableHostManager.gameObject);
|
||||
}
|
||||
|
||||
public static Syncable SpawnPooleeAndMakeSyncable(RegisterSyncableInfo info)
|
||||
public static Syncable SpawnPooleeAndMakeSyncable(SpawnPoolableInfo spawnInfo)
|
||||
{
|
||||
|
||||
SpawnPoolableInfo spawnInfo = info.spawnInfo.Value;
|
||||
SimpleTransform spawnLocation = spawnInfo.spawnLocation;
|
||||
|
||||
// !! This is a bit of a hack, but it works for now
|
||||
@@ -180,6 +184,7 @@ namespace BoneSync.Sync
|
||||
Poolee poolee = CallPatchedMethods.InstantiatePoolee(pool, spawnLocation.position, spawnLocation.rotation, pool.Prefab.transform.localScale);
|
||||
|
||||
Syncable syncable = MakeOrGetSyncable(poolee);
|
||||
MelonLogger.Msg("Spawned poolee with syncable: " + poolee.transform.GetPath());
|
||||
return syncable;
|
||||
}
|
||||
public static void OnRegisterSyncMessage(RegisterSyncableMessage registerSyncableMessage)
|
||||
@@ -192,6 +197,7 @@ namespace BoneSync.Sync
|
||||
new RegisterSyncableMessage(info).Broadcast();
|
||||
} else
|
||||
{
|
||||
// only host can register syncables, all spawn requests should be sent to host
|
||||
if (registerSyncableMessage.senderId != BoneSync.lobby.GetHostId())
|
||||
{
|
||||
MelonLogger.Warning("Received register sync message from non-host: " + registerSyncableMessage.senderId);
|
||||
@@ -199,6 +205,19 @@ namespace BoneSync.Sync
|
||||
}
|
||||
}
|
||||
|
||||
bool hasCallback = info.callbackId != 0;
|
||||
if (hasCallback)
|
||||
{
|
||||
MelonLogger.Msg("Received register sync message with callback id: " + info.callbackId);
|
||||
}
|
||||
|
||||
if (hasCallback && ObjectSyncCache._callbackIdToSyncable.ContainsKey(info.callbackId))
|
||||
{
|
||||
MelonLogger.Msg("Found syncable for callback id: " + info.callbackId);
|
||||
syncable = ObjectSyncCache._callbackIdToSyncable[info.callbackId];
|
||||
ObjectSyncCache._callbackIdToSyncable.Remove(info.callbackId);
|
||||
} else
|
||||
{
|
||||
switch (info.type)
|
||||
{
|
||||
case RegisterSyncType.RegisterFromPath:
|
||||
@@ -207,9 +226,10 @@ namespace BoneSync.Sync
|
||||
break;
|
||||
case RegisterSyncType.RegisterAndSpawn:
|
||||
MelonLogger.Msg("Registering and spawning syncable from pool: " + info.spawnInfo.Value.poolName + " with id: " + info.id);
|
||||
syncable = SpawnPooleeAndMakeSyncable(info);
|
||||
syncable = SpawnPooleeAndMakeSyncable(info.spawnInfo.Value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!syncable)
|
||||
{
|
||||
@@ -241,7 +261,7 @@ namespace BoneSync.Sync
|
||||
Syncable syncable = ObjectSyncCache.GetSyncable(damageInfo.objectId);
|
||||
if (syncable == null)
|
||||
{
|
||||
MelonLogger.Msg("DamageEvent: Syncable not found for id: " + damageInfo.objectId);
|
||||
//MelonLogger.Msg("DamageEvent: Syncable not found for id: " + damageInfo.objectId);
|
||||
return;
|
||||
}
|
||||
syncable.Damage(damageInfo);
|
||||
@@ -259,5 +279,23 @@ namespace BoneSync.Sync
|
||||
message.Broadcast();
|
||||
message.Execute();
|
||||
}
|
||||
|
||||
internal static void OnOwnershipChangeMessage(ushort syncId, ulong newOwnerId, bool force)
|
||||
{
|
||||
Syncable syncable = ObjectSyncCache.GetSyncable(syncId);
|
||||
if (syncable == null)
|
||||
{
|
||||
MelonLogger.Warning("Ownership transfer request for non-existant syncable: " + syncId);
|
||||
return;
|
||||
}
|
||||
if (force)
|
||||
{
|
||||
syncable.SetOwner(newOwnerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
syncable.OnOwnershipTransferRequest(newOwnerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace BoneSync.Sync
|
||||
private static Dictionary<InteractableHost, Syncable> _interactableHostToSyncable = new Dictionary<InteractableHost, Syncable>();
|
||||
private static Dictionary<InteractableHostManager, Syncable> _interactableHostManagerToSyncable = new Dictionary<InteractableHostManager, Syncable>();
|
||||
|
||||
public static Dictionary<ushort, Syncable> _callbackIdToSyncable = new Dictionary<ushort, Syncable>();
|
||||
|
||||
public static void AddSyncable(Syncable syncable)
|
||||
{
|
||||
string path = syncable.GetSyncableWorldPath();
|
||||
|
||||
Reference in New Issue
Block a user