Bunch more networking stuff

This commit is contained in:
2025-02-28 14:35:14 +02:00
parent 1dce1960f6
commit d0eb7f89be
8 changed files with 126 additions and 36 deletions

View File

@@ -180,18 +180,9 @@ namespace BoneSync.Networking
}; };
} }
public void WriteEnum<T>(T value) where T : Enum
{
WriteByte((byte)(object)value);
}
public T ReadEnum<T>() where T : Enum
{
return (T)(object)ReadByte();
}
public void WriteSLZAttack(Attack attack) public void WriteSLZAttack(Attack attack)
{ {
WriteEnum(attack.attackType); WriteByte((byte)attack.attackType);
WriteFloat(attack.damage); WriteFloat(attack.damage);
} }

View File

@@ -50,7 +50,7 @@ namespace BoneSync.Networking.Messages
{ {
_objectEventInfo = objectEventInfo; _objectEventInfo = objectEventInfo;
byteEncoder.WriteUShort(_objectEventInfo.objectId); byteEncoder.WriteUShort(_objectEventInfo.objectId);
byteEncoder.WriteEnum(_objectEventInfo.eventType); byteEncoder.WriteByte((byte)_objectEventInfo.eventType);
byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health); byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health);
byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits); byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits);
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to write the rest of the data if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to write the rest of the data
@@ -63,7 +63,7 @@ namespace BoneSync.Networking.Messages
{ {
byteEncoder.WriteBytes(packet.Data); byteEncoder.WriteBytes(packet.Data);
_objectEventInfo.objectId = byteEncoder.ReadUShort(); _objectEventInfo.objectId = byteEncoder.ReadUShort();
_objectEventInfo.eventType = byteEncoder.ReadEnum<ObjectDamageType>(); _objectEventInfo.eventType = (ObjectDamageType)byteEncoder.ReadByte();
_objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat(); _objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat();
_objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt(); _objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt();
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data

View File

@@ -1,4 +1,5 @@
using BoneSync.Sync; using BoneSync.Patching;
using BoneSync.Sync;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -12,12 +13,19 @@ namespace BoneSync.Networking.Messages
RegisterFromPath = 0, RegisterFromPath = 0,
RegisterAndSpawn = 1, RegisterAndSpawn = 1,
} }
public struct SpawnPoolableInfo
{
public string poolName;
public SimpleTransform spawnLocation;
}
public struct RegisterSyncableInfo public struct RegisterSyncableInfo
{ {
public string transformPath; public string transformPath;
public ushort id; public ushort id;
public ulong ownerId; public ulong ownerId;
public RegisterSyncType type; public RegisterSyncType type;
public SpawnPoolableInfo? spawnInfo;
} }
[PacketType(PacketType.RegisterSyncable)] [PacketType(PacketType.RegisterSyncable)]
@@ -28,20 +36,41 @@ namespace BoneSync.Networking.Messages
public RegisterSyncableMessage(RegisterSyncableInfo info) public RegisterSyncableMessage(RegisterSyncableInfo info)
{ {
_info = info; _info = info;
byteEncoder.WriteEnum<RegisterSyncType>(_info.type); byteEncoder.WriteByte((byte)_info.type);
byteEncoder.WriteString(_info.transformPath);
byteEncoder.WriteUlong(_info.ownerId); byteEncoder.WriteUlong(_info.ownerId);
byteEncoder.WriteUShort(_info.id); byteEncoder.WriteUShort(_info.id);
switch (_info.type)
{
case RegisterSyncType.RegisterAndSpawn:
byteEncoder.WriteString(_info.spawnInfo.Value.poolName);
byteEncoder.WriteSimpleTransform(_info.spawnInfo.Value.spawnLocation);
break;
case RegisterSyncType.RegisterFromPath:
byteEncoder.WriteString(_info.transformPath);
break;
}
} }
public RegisterSyncableMessage(Packet packet) public RegisterSyncableMessage(Packet packet)
{ {
byteEncoder.WriteBytes(packet.Data); byteEncoder.WriteBytes(packet.Data);
_info.type = byteEncoder.ReadEnum<RegisterSyncType>(); _info.type = (RegisterSyncType)byteEncoder.ReadByte();
_info.transformPath = byteEncoder.ReadString();
_info.ownerId = byteEncoder.ReadUlong(); _info.ownerId = byteEncoder.ReadUlong();
_info.id = byteEncoder.ReadUShort(); _info.id = byteEncoder.ReadUShort();
switch (_info.type)
{
case RegisterSyncType.RegisterAndSpawn:
_info.spawnInfo = new SpawnPoolableInfo()
{
poolName = byteEncoder.ReadString(),
spawnLocation = byteEncoder.ReadSimpleTransform(),
};
break;
case RegisterSyncType.RegisterFromPath:
_info.transformPath = byteEncoder.ReadString();
break;
}
} }
public override void Execute() public override void Execute()

View File

@@ -17,24 +17,25 @@ namespace BoneSync.Patching
private set; private set;
get; get;
} }
public static void TakeDamage(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType) public static void TakeDamage(ObjectDestructable __instance, Vector3 normal, float damage, bool crit, AttackType attackType)
{ {
allowPatchedMethodCall = true; allowPatchedMethodCall = true;
__instance.TakeDamage(normal, damage, crit, attackType); __instance.TakeDamage(normal, damage, crit, attackType);
allowPatchedMethodCall = false; allowPatchedMethodCall = false;
} }
public static void TakeDamage(Prop_Health __instance, ref float damage, ref bool crit, ref AttackType attackType) public static void TakeDamage(Prop_Health __instance, float damage, bool crit, AttackType attackType)
{ {
allowPatchedMethodCall = true; allowPatchedMethodCall = true;
__instance.TAKEDAMAGE(damage, crit, attackType); __instance.TAKEDAMAGE(damage, crit, attackType);
allowPatchedMethodCall = false; allowPatchedMethodCall = false;
} }
public static GameObject PoolSpawn(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable) public static GameObject PoolSpawn(Pool __instance, Vector3 position, Quaternion rotation, Vector3 scale)
{ {
allowPatchedMethodCall = true; allowPatchedMethodCall = true;
GameObject result = __instance.Spawn(position, rotation, scale, autoEnable); Il2CppSystem.Nullable<Vector3> scaleNullable = new Il2CppSystem.Nullable<Vector3>(scale);
GameObject result = __instance.Spawn(position, rotation, scaleNullable, new Il2CppSystem.Nullable<bool>(true));
allowPatchedMethodCall = false; allowPatchedMethodCall = false;
return result; return result;
} }

View File

@@ -4,6 +4,8 @@ using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using BoneSync.Networking.Messages;
using BoneSync.Sync;
using HarmonyLib; using HarmonyLib;
using MelonLoader; using MelonLoader;
using StressLevelZero; using StressLevelZero;
@@ -17,6 +19,27 @@ namespace BoneSync.Patching
internal class PoolPatches internal class PoolPatches
{ {
public readonly static string[] ignoredPools = new string[] {
"RigidbodyProjectile",
"VFX Despawn Mesh",
"AudioPlayer",
"Decal",
"PopupText",
};
public static bool IsIgnoredPool(string poolName)
{
string lowercasePoolName = poolName.ToLower();
foreach (string ignoredPool in ignoredPools)
{
if (lowercasePoolName.Contains(ignoredPool.ToLower()))
{
return true;
}
}
return false;
}
[HarmonyPatch(nameof(Pool.Spawn))] [HarmonyPatch(nameof(Pool.Spawn))]
[HarmonyPostfix] [HarmonyPostfix]
private static void SpawnPatchPost(Pool __instance, ref GameObject __result) private static void SpawnPatchPost(Pool __instance, ref GameObject __result)
@@ -29,11 +52,12 @@ namespace BoneSync.Patching
private static bool SpawnPatchPre(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable) private static bool SpawnPatchPre(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable)
{ {
if (CallPatchedMethods.allowPatchedMethodCall) return true; if (CallPatchedMethods.allowPatchedMethodCall) return true;
if (IsIgnoredPool(__instance.name)) return true;
if (BoneSync.lobby.IsConnected()) if (BoneSync.lobby.IsConnected())
{ {
MelonLogger.Msg("Patched Spawning object in pool: " + __instance.name); MelonLogger.Msg("Patched Spawning object in pool: " + __instance.name);
return false; return BoneSync.lobby.IsHost; // only allow host to spawn objects naturally
} }
return true; return true;
} }

View File

@@ -115,6 +115,21 @@ namespace BoneSync.Sync.Components
public void OnEnable() public void OnEnable()
{ {
FindComponents(); FindComponents();
bool shouldAutoSync = CheckIfShouldAutoSync();
if (shouldAutoSync)
{
MelonLogger.Msg("AutoSyncing: " + transform.GetPath());
RegisterSyncable();
}
}
public bool CheckIfShouldAutoSync()
{
if (poolee && poolee.pool) {
return true;
}
return false;
} }
public string GetSyncableWorldPath() public string GetSyncableWorldPath()
@@ -151,14 +166,7 @@ namespace BoneSync.Sync.Components
public bool CanBeSynced() public bool CanBeSynced()
{ {
FindComponents(); FindComponents();
if (interactableManager && interactableManager.hosts.Count > 0) if (rigidbodies.Length > 0) return true;
{
return true;
}
if (interactableHost && interactableHost.hasRigidbody)
{
return true;
}
return false; return false;
} }

View File

@@ -42,14 +42,14 @@ namespace BoneSync.Sync.Components
if (eventType == ObjectDamageType.DestructibleTakeDamage && objectDestructable) if (eventType == ObjectDamageType.DestructibleTakeDamage && objectDestructable)
{ {
MelonLogger.Msg("NetworkDestructableTakeDamage: " + healthInfo.damage); MelonLogger.Msg("NetworkDestructableTakeDamage: " + healthInfo.damage);
CallPatchedMethods.TakeDamage(objectDestructable, ref healthInfo.normal, ref healthInfo.damage, ref healthInfo.crit, ref healthInfo.attackType); CallPatchedMethods.TakeDamage(objectDestructable, healthInfo.normal, healthInfo.damage, healthInfo.crit, healthInfo.attackType);
return; return;
} }
if (eventType == ObjectDamageType.PropHealthTakeDamage && propHealth) if (eventType == ObjectDamageType.PropHealthTakeDamage && propHealth)
{ {
MelonLogger.Msg("NetworkPropHealthTakeDamage: " + healthInfo.damage); MelonLogger.Msg("NetworkPropHealthTakeDamage: " + healthInfo.damage);
CallPatchedMethods.TakeDamage(propHealth, ref healthInfo.damage, ref healthInfo.crit, ref healthInfo.attackType); CallPatchedMethods.TakeDamage(propHealth, healthInfo.damage, healthInfo.crit, healthInfo.attackType);
return; return;
} }

View File

@@ -1,4 +1,6 @@
using BoneSync.Networking.Messages; using BoneSync.Networking;
using BoneSync.Networking.Messages;
using BoneSync.Patching;
using BoneSync.Sync.Components; using BoneSync.Sync.Components;
using MelonLoader; using MelonLoader;
using StressLevelZero.Interaction; using StressLevelZero.Interaction;
@@ -34,12 +36,16 @@ namespace BoneSync.Sync
ownerId = syncable._ownerId, ownerId = syncable._ownerId,
}; };
} }
else if (syncable.poolee) else if (syncable.poolee && syncable.poolee.pool)
{ {
info = new RegisterSyncableInfo() info = new RegisterSyncableInfo()
{ {
type = RegisterSyncType.RegisterAndSpawn, type = RegisterSyncType.RegisterAndSpawn,
transformPath = syncable.poolee.transform.GetPath(), spawnInfo = new SpawnPoolableInfo()
{
poolName = syncable.poolee.pool.name,
spawnLocation = new SimpleTransform(syncable.poolee.transform),
},
}; };
} }
return info; return info;
@@ -57,6 +63,8 @@ namespace BoneSync.Sync
RegisterSyncableInfo info = infoNullable.Value; RegisterSyncableInfo info = infoNullable.Value;
RegisterSyncableMessage message = new RegisterSyncableMessage(info); RegisterSyncableMessage message = new RegisterSyncableMessage(info);
if (BoneSync.lobby.IsHost) if (BoneSync.lobby.IsHost)
{ {
@@ -65,9 +73,16 @@ namespace BoneSync.Sync
} }
else else
{ {
if (message.senderId != BoneSync.lobby.GetHostId())
{
MelonLogger.Warning("Non host tried to send register syncable message");
}
info.id = 0; info.id = 0;
message.Send(BoneSync.lobby.GetHostId()); message.Send(BoneSync.lobby.GetHostId());
} }
MelonLogger.Msg("Sending register syncable message for: " + syncable.transform.name + " with id: " + info.id + " and type : " + info.type);
return info.id; return info.id;
} }
@@ -135,6 +150,20 @@ namespace BoneSync.Sync
return _MakeOrGetSyncable(interactableHostManager.gameObject); return _MakeOrGetSyncable(interactableHostManager.gameObject);
} }
public static Syncable SpawnPooleeAndMakeSyncable(string poolName, RegisterSyncableInfo info)
{
SimpleTransform spawnLocation = info.spawnInfo.Value.spawnLocation;
Pool pool = PoolManager.GetPool(poolName);
if (pool == null)
{
MelonLogger.Warning("Pool not found: " + poolName);
return null;
}
GameObject spawned = CallPatchedMethods.PoolSpawn(pool, spawnLocation.position, spawnLocation.rotation, spawnLocation.scale);
MelonLogger.Msg("Spawned object: " + spawned.transform.GetPath() + " in pool: " + poolName);
Poolee poolee = spawned.GetComponent<Poolee>();
return _MakeOrGetSyncable(poolee.gameObject);
}
public static void OnRegisterSyncMessage(RegisterSyncableMessage registerSyncableMessage) public static void OnRegisterSyncMessage(RegisterSyncableMessage registerSyncableMessage)
{ {
Syncable syncable = null; Syncable syncable = null;
@@ -152,9 +181,17 @@ namespace BoneSync.Sync
syncable = ObjectSyncCache.GetSyncable(info.transformPath); syncable = ObjectSyncCache.GetSyncable(info.transformPath);
break; break;
case RegisterSyncType.RegisterAndSpawn: case RegisterSyncType.RegisterAndSpawn:
MelonLogger.Msg("Registering and spawning syncable from pool: " + info.spawnInfo.Value.poolName + " with id: " + info.id);
syncable = SpawnPooleeAndMakeSyncable(info.spawnInfo.Value.poolName, info);
break; break;
} }
if (!syncable)
{
MelonLogger.Warning("Failed to create/obtain syncable for register sync message "+ info.id);
return;
}
syncable.SetSyncId(info.id); syncable.SetSyncId(info.id);
syncable.SetOwner(info.ownerId); syncable.SetOwner(info.ownerId);
} }