- Convert TransportBase from abstract class to interface; replace BORADCAST_ID constant with BROADCAST_ID property in transport implementations. - Update SteamTransport to implement the new interface and provide its own BROADCAST_ID. - Refactor event patching: introduce UnityEventPatching to map proxy events to originals, and update UnityEventPatch<T> to use proxy events for patching. - Ensure patched UnityEvents replace originals in SyncablePhysics, so all invocations go through patch logic. - Improve robustness and maintainability of both networking and event patching systems.
83 lines
2.8 KiB
C#
83 lines
2.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using BoneSync.Data;
|
|
using HarmonyLib;
|
|
using StressLevelZero.Interaction;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace BoneSync.Patching
|
|
{
|
|
public class UnityEventPatching
|
|
{
|
|
internal static Dictionary<int, UnityEvent> _patchToOriginalMap = new Dictionary<int, UnityEvent>();
|
|
public static UnityEvent GetOriginalEvent(UnityEvent unityEvent)
|
|
{
|
|
int eventHash = unityEvent.GetHashCode();
|
|
if (_patchToOriginalMap.TryGetValue(eventHash, out UnityEvent originalEvent))
|
|
{
|
|
return originalEvent;
|
|
}
|
|
return unityEvent;
|
|
}
|
|
}
|
|
public class UnityEventPatch<T>
|
|
{
|
|
private static Dictionary<int, UnityEventPatch<T>> patches = new Dictionary<int, UnityEventPatch<T>>();
|
|
|
|
private T arg;
|
|
private UnityEvent unityEvent;
|
|
private Func<T, bool> handler;
|
|
private UnityEvent proxyUnityEvent;
|
|
//private float lastInvokeTime = 0f;
|
|
//private float invokeCooldown = 0.05f;
|
|
private UnityEventPatch(T arg, UnityEvent unityEvent, Func<T, bool> handler)
|
|
{
|
|
this.arg = arg;
|
|
this.unityEvent = unityEvent;
|
|
this.handler = handler;
|
|
this.proxyUnityEvent = new UnityEvent();
|
|
this.proxyUnityEvent.AddListener((UnityAction)OnEventInvoked);
|
|
int patchEventHash = proxyUnityEvent.GetHashCode();
|
|
patches[patchEventHash] = this; // avoid creating multiple patches for same event
|
|
UnityEventPatching._patchToOriginalMap[patchEventHash] = unityEvent;
|
|
}
|
|
|
|
public UnityEvent GetOriginalEvent()
|
|
{
|
|
return unityEvent;
|
|
}
|
|
|
|
private void OnEventInvoked()
|
|
{
|
|
bool allowInvoke = handler.Invoke(arg);
|
|
SyncLogger.Msg("UnityEventPatch invoked for event " + unityEvent.GetHashCode() + ", allowInvoke: " + allowInvoke);
|
|
if (allowInvoke)
|
|
{
|
|
unityEvent.Invoke(); // only invoke the original event if allowed
|
|
}
|
|
}
|
|
|
|
public UnityEvent GetPatchedEvent()
|
|
{
|
|
return proxyUnityEvent;
|
|
}
|
|
|
|
public static UnityEventPatch<T> Patch(T arg, UnityEvent unityEvent, Func<T, bool> handler)
|
|
{
|
|
int eventHash = unityEvent.GetHashCode();
|
|
UnityEventPatch<T> existingPatch = patches.TryGetValue(eventHash, out UnityEventPatch<T> foundPatch) ? foundPatch : null;
|
|
if (existingPatch != null)
|
|
{
|
|
return existingPatch;
|
|
}
|
|
UnityEventPatch<T> patch = new UnityEventPatch<T>(arg, unityEvent, handler);
|
|
patches[eventHash] = patch;
|
|
return patch;
|
|
}
|
|
}
|
|
}
|