Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SyncLib v1.1.0
plugins/SyncLib.dll
Decompiled 19 hours agousing 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<string> RegisteredRpcs = new HashSet<string>(); private static readonly List<Action<Player>> OnPlayerJoinedCallbacks = new List<Action<Player>>(); private static readonly Dictionary<byte, Action<EventData>> EventHandlers = new Dictionary<byte, Action<EventData>>(); private static readonly Dictionary<int, Action<object[]>> PendingRequests = new Dictionary<int, Action<object[]>>(); private static int requestIdCounter; private static readonly Dictionary<string, Action<string, string>> ConfigChangeHandlers = new Dictionary<string, Action<string, string>>(); private static readonly Dictionary<string, string> RegisteredConfigs = new Dictionary<string, string>(); private const byte CONFIG_SYNC_EVENT = 200; private const byte SNAPSHOT_REQUEST_EVENT = 201; private const byte SNAPSHOT_RESPONSE_EVENT = 202; private static Func<string> _snapshotProvider; private static Action<string> _snapshotApplier; private static readonly Queue<Player> PendingSnapshotPlayers = new Queue<Player>(); private static bool _snapshotEnabled; public static SyncRelay Instance { get { if ((Object)(object)_instance == (Object)null) { PunManager val = Object.FindObjectOfType<PunManager>(); if ((Object)(object)val != (Object)null) { _instance = ((Component)val).GetComponent<SyncRelay>(); if ((Object)(object)_instance == (Object)null) { _instance = ((Component)val).gameObject.AddComponent<SyncRelay>(); } 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<PhotonView>() == (Object)null) { ((Component)this).gameObject.AddComponent<PhotonView>(); } 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<EventData> 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<object[]> 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<T>(string key, T fallback = default(T)) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { return fallback; } Hashtable customProperties = ((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties; return (((Dictionary<object, object>)(object)customProperties).ContainsKey((object)key) && customProperties[(object)key] is T val) ? val : fallback; } public static void RegisterOnPlayerJoinedCallback(Action<Player> callback) { if (!OnPlayerJoinedCallbacks.Contains(callback)) { OnPlayerJoinedCallbacks.Add(callback); } } public override void OnPlayerEnteredRoom(Player newPlayer) { foreach (Action<Player> 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<string> snapshotProvider, Action<string> 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<string, string> 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<string, string> 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} 项"); } }