Decompiled source of SyncLib v1.1.0

plugins/SyncLib.dll

Decompiled 19 hours ago
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<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} 项");
	}
}