using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SyncLib")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SyncLib")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b18f4863-ab4c-4f82-9c5c-3bab379766fb")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace cn_xc.SyncLib; [BepInPlugin("cn_xc.SyncLib", "SyncLib", "1.1.0")] public class SyncRelay : MonoBehaviourPunCallbacks, IOnEventCallback { private static SyncRelay _instance; private static readonly HashSet RegisteredRpcs = new HashSet(); private static readonly List> OnPlayerJoinedCallbacks = new List>(); private static readonly Dictionary> EventHandlers = new Dictionary>(); private static readonly Dictionary> PendingRequests = new Dictionary>(); private static int requestIdCounter; private static readonly Dictionary> ConfigChangeHandlers = new Dictionary>(); private static readonly Dictionary RegisteredConfigs = new Dictionary(); private const byte CONFIG_SYNC_EVENT = 200; private const byte SNAPSHOT_REQUEST_EVENT = 201; private const byte SNAPSHOT_RESPONSE_EVENT = 202; private static Func _snapshotProvider; private static Action _snapshotApplier; private static readonly Queue PendingSnapshotPlayers = new Queue(); private static bool _snapshotEnabled; public static SyncRelay Instance { get { if ((Object)(object)_instance == (Object)null) { PunManager val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null) { _instance = ((Component)val).GetComponent(); if ((Object)(object)_instance == (Object)null) { _instance = ((Component)val).gameObject.AddComponent(); } Object.DontDestroyOnLoad((Object)(object)((Component)_instance).gameObject); } } return _instance; } } private void Awake() { if ((Object)(object)_instance != (Object)null && (Object)(object)_instance != (Object)(object)this) { Object.Destroy((Object)(object)this); return; } _instance = this; if ((Object)(object)((Component)this).GetComponent() == (Object)null) { ((Component)this).gameObject.AddComponent(); } Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); PhotonNetwork.AddCallbackTarget((object)this); Debug.Log((object)"[SyncLib] 初始化完成"); } private void OnDestroy() { PhotonNetwork.RemoveCallbackTarget((object)this); } public static void RegisterRpc(string name) { if (RegisteredRpcs.Add(name)) { Debug.Log((object)("[SyncLib] RPC 已注册: " + name)); } } public void Broadcast(string method, params object[] args) { if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { ((MonoBehaviourPun)this).photonView.RPC(method, (RpcTarget)0, args); } } public void BroadcastBuffered(string method, params object[] args) { if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { ((MonoBehaviourPun)this).photonView.RPC(method, (RpcTarget)3, args); } } public void SendToPlayer(Player target, string method, params object[] args) { if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom && target != null) { ((MonoBehaviourPun)this).photonView.RPC(method, target, args); } } public void RequestHost(string method, params object[] args) { if (!PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { ((MonoBehaviourPun)this).photonView.RPC(method, (RpcTarget)2, args); } } public static void RegisterEventHandler(byte eventCode, Action handler) { EventHandlers[eventCode] = handler; Debug.Log((object)$"[SyncLib] 事件已注册: {eventCode}"); } public void RaiseEventBroadcast(byte eventCode, object content, bool reliable = true) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; SendOptions val2 = default(SendOptions); ((SendOptions)(ref val2)).Reliability = reliable; SendOptions val3 = val2; PhotonNetwork.RaiseEvent(eventCode, content, val, val3); } } void IOnEventCallback.OnEvent(EventData photonEvent) { if (EventHandlers.TryGetValue(photonEvent.Code, out var value)) { value?.Invoke(photonEvent); } } public void SendRequest(byte eventCode, object content, Action callback, bool reliable = true) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) int num = ++requestIdCounter; PendingRequests[num] = callback; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; SendOptions val2 = default(SendOptions); ((SendOptions)(ref val2)).Reliability = reliable; SendOptions val3 = val2; object[] array = new object[2] { num, content }; PhotonNetwork.RaiseEvent(eventCode, (object)array, val, val3); } public void SendResponse(byte eventCode, int reqId, object content, Player target, bool reliable = true) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) RaiseEventOptions val = new RaiseEventOptions(); val.TargetActors = new int[1] { target.ActorNumber }; RaiseEventOptions val2 = val; SendOptions val3 = default(SendOptions); ((SendOptions)(ref val3)).Reliability = reliable; SendOptions val4 = val3; object[] array = new object[2] { reqId, content }; PhotonNetwork.RaiseEvent(eventCode, (object)array, val2, val4); } public void HandleResponse(int reqId, object[] data) { if (PendingRequests.TryGetValue(reqId, out var value)) { PendingRequests.Remove(reqId); value?.Invoke(data); } } public static void SetRoomProperty(string key, object value) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown if (PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom && PhotonNetwork.CurrentRoom != null) { Hashtable val = new Hashtable { [(object)key] = value }; PhotonNetwork.CurrentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } public static T GetRoomProperty(string key, T fallback = default(T)) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return fallback; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; return (((Dictionary)(object)customProperties).ContainsKey((object)key) && customProperties[(object)key] is T val) ? val : fallback; } public static void RegisterOnPlayerJoinedCallback(Action callback) { if (!OnPlayerJoinedCallbacks.Contains(callback)) { OnPlayerJoinedCallbacks.Add(callback); } } public override void OnPlayerEnteredRoom(Player newPlayer) { foreach (Action onPlayerJoinedCallback in OnPlayerJoinedCallbacks) { try { onPlayerJoinedCallback?.Invoke(newPlayer); } catch (Exception ex) { Debug.LogError((object)("[SyncLib] 回调失败: " + ex.Message)); } } if (_snapshotEnabled && PhotonNetwork.IsMasterClient) { PendingSnapshotPlayers.Enqueue(newPlayer); Debug.Log((object)("[SyncLib] 新玩家 " + newPlayer.NickName + " 加入快照队列")); } } public static void EnableSnapshotSync(Func snapshotProvider, Action snapshotApplier) { _snapshotProvider = snapshotProvider; _snapshotApplier = snapshotApplier; _snapshotEnabled = true; RegisterEventHandler(202, OnSnapshotResponseReceived); Debug.Log((object)"[SyncLib] 快照补发已启用"); } public static void DisableSnapshotSync() { _snapshotEnabled = false; _snapshotProvider = null; _snapshotApplier = null; PendingSnapshotPlayers.Clear(); Debug.Log((object)"[SyncLib] 快照补发已禁用"); } public void RequestSnapshot() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient && PhotonNetwork.InRoom) { RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)2 }; PhotonNetwork.RaiseEvent((byte)201, (object)null, val, SendOptions.SendReliable); Debug.Log((object)"[SyncLib] 已请求快照补发"); } } private void ProcessSnapshotRequest(Player requester) { if (_snapshotProvider != null) { string text = _snapshotProvider(); if (!string.IsNullOrEmpty(text)) { SendResponse(202, 0, text, requester); Debug.Log((object)("[SyncLib] 快照已发送给 " + requester.NickName)); } } } private static void OnSnapshotResponseReceived(EventData eventData) { if (eventData.CustomData is string obj) { _snapshotApplier?.Invoke(obj); Debug.Log((object)"[SyncLib] 快照已应用"); } } private void Update() { if (_snapshotEnabled && PhotonNetwork.IsMasterClient && PendingSnapshotPlayers.Count > 0) { Player requester = PendingSnapshotPlayers.Dequeue(); ProcessSnapshotRequest(requester); } } public static void RegisterSyncedConfig(string configKey, string defaultValue, Action onConfigChanged) { if (!RegisteredConfigs.ContainsKey(configKey)) { RegisteredConfigs[configKey] = defaultValue; ConfigChangeHandlers[configKey] = onConfigChanged; Debug.Log((object)("[SyncLib] 配置已注册: " + configKey + " = " + defaultValue)); } } public static void SetSyncedConfig(string configKey, string newValue) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { Debug.LogWarning((object)("[SyncLib] 非房主尝试设置同步配置: " + configKey)); return; } if (!RegisteredConfigs.ContainsKey(configKey)) { Debug.LogWarning((object)("[SyncLib] 未注册的配置键: " + configKey)); return; } RegisteredConfigs[configKey] = newValue; Debug.Log((object)("[SyncLib] 房主设置配置: " + configKey + " = " + newValue)); if (ConfigChangeHandlers.TryGetValue(configKey, out var value)) { value?.Invoke(configKey, newValue); } object[] array = new object[2] { configKey, newValue }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; PhotonNetwork.RaiseEvent((byte)200, (object)array, val, SendOptions.SendReliable); } public static string GetSyncedConfig(string configKey) { string value; return RegisteredConfigs.TryGetValue(configKey, out value) ? value : null; } private static void OnConfigSyncReceived(EventData eventData) { if (!(eventData.CustomData is object[] array) || array.Length < 2) { return; } string text = array[0] as string; string text2 = array[1] as string; if (text != null && RegisteredConfigs.ContainsKey(text)) { RegisteredConfigs[text] = text2; if (ConfigChangeHandlers.TryGetValue(text, out var value)) { value?.Invoke(text, text2); } Debug.Log((object)("[SyncLib] 配置已同步: " + text + " = " + text2)); } } public static string SerializeConfigSnapshot() { StringBuilder stringBuilder = new StringBuilder(); foreach (KeyValuePair registeredConfig in RegisteredConfigs) { stringBuilder.AppendLine(registeredConfig.Key + "=" + registeredConfig.Value); } return stringBuilder.ToString(); } public static void ApplyConfigSnapshot(string snapshot) { if (string.IsNullOrEmpty(snapshot)) { return; } string[] array = snapshot.Split(new char[2] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries); string[] array2 = array; foreach (string text in array2) { string[] array3 = text.Split(new char[1] { '=' }); if (array3.Length == 2 && RegisteredConfigs.ContainsKey(array3[0])) { RegisteredConfigs[array3[0]] = array3[1]; if (ConfigChangeHandlers.TryGetValue(array3[0], out var value)) { value?.Invoke(array3[0], array3[1]); } } } Debug.Log((object)$"[SyncLib] 配置快照已应用: {array.Length} 项"); } }