212 lines
7.8 KiB
C#
212 lines
7.8 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using BoneSync.Data;
|
|
using BoneSync.Networking.Messages;
|
|
using BoneSync.Sync;
|
|
using BoneSync.Sync.Components;
|
|
using HarmonyLib;
|
|
using MelonLoader;
|
|
using StressLevelZero;
|
|
using StressLevelZero.Pool;
|
|
using StressLevelZero.Props.Weapons;
|
|
using UnityEngine;
|
|
|
|
namespace BoneSync.Patching
|
|
{
|
|
public static class PoolBlacklist
|
|
{
|
|
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)
|
|
{
|
|
if (pool.name.Contains("RigidbodyProjectile")) return true;
|
|
if (pool.name.Contains("VFX Despawn Mesh")) return true;
|
|
if (pool.name.Contains("AudioPlayer")) return true;
|
|
if (pool.name.Contains("Decal")) return true;
|
|
if (pool.name.Contains("PopupText")) return true;
|
|
//if (pool.name.Contains("Nimbus")) return true;
|
|
|
|
if (pool.Prefab.GetComponent<SpawnFragment>() != null) return true;
|
|
if (pool.Prefab.GetComponent<SpawnFragmentArray>() != 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))
|
|
return _blacklistedCache[pool];
|
|
_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))]
|
|
public static class PoolPatches
|
|
{
|
|
[HarmonyPatch(nameof(Pool.InstantiatePoolee), new Type[] { typeof(Vector3), typeof(Quaternion) }), HarmonyPrefix]
|
|
private static bool InstantiatePooleePatchPre(Pool __instance)
|
|
{
|
|
if (!__instance.Prefab)
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
[HarmonyPatch(nameof(Pool.InstantiatePoolee), new Type[] { typeof(Vector3), typeof(Quaternion) }), HarmonyPostfix]
|
|
private static void InstantiatePooleePatchPost(Pool __instance, Poolee __result, Vector3 position, Quaternion rotation)
|
|
{
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return;
|
|
if (__instance == null) return;
|
|
if (PoolBlacklist.isBlacklistedPool(__instance)) return;
|
|
//SyncLogger.Msg("Patched Instantiating object in pool: " + __instance.name);
|
|
__result.onSpawnDelegate = Il2CppSystem.Delegate.Combine(__result.onSpawnDelegate, (Il2CppSystem.Action<GameObject>)((g) => { PooleePatches.OnSpawnPatchPost(__result); })).Cast<Il2CppSystem.Action<GameObject>>();
|
|
__result.onDespawnDelegate = Il2CppSystem.Delegate.Combine(__result.onDespawnDelegate, (Il2CppSystem.Action<GameObject>)((g) => { PooleePatches.OnDespawnPatchPost(__result); })).Cast<Il2CppSystem.Action<GameObject>>();
|
|
|
|
}
|
|
|
|
|
|
/*[HarmonyPatch(nameof(Pool.Spawn))]
|
|
[HarmonyPostfix]
|
|
private static void SpawnPatchPost(Pool __instance, ref GameObject __result)
|
|
{
|
|
if (__instance == null) return;
|
|
if (__instance.Prefab == null) return;
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return;
|
|
if (PoolBlacklist.isBlacklistedPool(__instance)) return;
|
|
if (BoneSync.IsConnected)
|
|
{
|
|
SyncLogger.Msg("Patched Spawning object in pool: " + __instance.name);
|
|
bool isHost = BoneSync.lobby.IsHost;
|
|
if (!isHost) GameObject.DestroyImmediate(__result);
|
|
}
|
|
}*/
|
|
|
|
/*[HarmonyPatch(nameof(Pool.Spawn))]
|
|
[HarmonyPrefix]
|
|
private static bool SpawnPatchPre(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable)
|
|
{
|
|
if (__instance == null) return true;
|
|
if (__instance.Prefab == null) return true;
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
|
if (PoolBlacklist.isBlacklistedPool(__instance)) return true;
|
|
if (BoneSync.IsConnected)
|
|
{
|
|
SyncLogger.Msg("Patched Spawning object in pool: " + __instance.name);
|
|
return BoneSync.lobby.IsHost; // only allow host to spawn objects naturally
|
|
}
|
|
__instance.
|
|
return true;
|
|
|
|
}
|
|
*/
|
|
}
|
|
[HarmonyPatch(typeof(Poolee))]
|
|
public static class PooleePatches
|
|
{
|
|
public static void OnSpawnPatchPost(Poolee __instance)
|
|
{
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return;
|
|
if (!BoneSync.IsConnected) return;
|
|
|
|
SyncLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath());
|
|
|
|
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance);
|
|
|
|
bool spawnNormally = BoneSync.lobby.IsHost || PoolBlacklist.IsClientSpawnPool(__instance.pool);
|
|
|
|
SyncLogger.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath() + " syncid:" + syncable?.GetSyncId() + " spawnNormally" + spawnNormally);
|
|
|
|
if (!spawnNormally) {
|
|
MelonCoroutines.Start(OnSpawnClient(__instance)); // block object from spawning
|
|
return;
|
|
}
|
|
|
|
if (syncable == null) return;
|
|
|
|
//
|
|
//
|
|
//
|
|
//.Msg("Poolee.OnSpawn: " + __instance.gameObject.transform.GetPath() + " " + syncable.GetSyncId());
|
|
|
|
|
|
}
|
|
|
|
public static void OnDespawnPatchPost(Poolee __instance)
|
|
{
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return;
|
|
if (!BoneSync.IsConnected) return;
|
|
|
|
SyncLogger.Msg("Poolee.OnDespawn: " + __instance.gameObject.transform.GetPath());
|
|
|
|
//Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance);
|
|
|
|
//if (syncable == null) return;
|
|
|
|
//if (syncable.isOwner) return;
|
|
|
|
//syncable.DiscardSyncable(true);
|
|
}
|
|
|
|
public static IEnumerator OnSpawnClient(Poolee poolee)
|
|
{
|
|
GameObject go = poolee.gameObject;
|
|
if (SceneLoader.loading)
|
|
{
|
|
while (SceneLoader.loading)
|
|
{
|
|
go.SetActive(false);
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
go.SetActive(false);
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
|
|
public static IEnumerator OnSpawnHost(Poolee poolee)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/* // DONT USE THIS PATCH, CRASHES GAME WITH NO ERROR
|
|
[HarmonyPatch(nameof(Poolee.Despawn), new Type[] { typeof(Il2CppSystem.Nullable<bool>), typeof(Il2CppSystem.Nullable<Color>) }), HarmonyPrefix]
|
|
private static bool DespawnPatchPre(Poolee __instance, ref Il2CppSystem.Nullable<bool> playVFX, ref Il2CppSystem.Nullable<Color> despawnColor)
|
|
{
|
|
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
|
if (!BoneSync.IsConnected) return true;
|
|
|
|
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance);
|
|
if (syncable == null) return true;
|
|
if (!syncable.isOwner) return false; // if not owner, don't despawn
|
|
|
|
return true;
|
|
}
|
|
*/
|
|
|
|
}
|
|
|
|
}
|