The BepInEx console will not appear when launching like it does for other games on Thunderstore (you can turn it back on in your BepInEx.cfg file). If your PEAK crashes on startup, add -dx12 to your launch parameters.
Decompiled source of PhotonCustomPropsUtils v1.0.0
PhotonCustomPropsUtils.dll
Decompiled 2 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using ExitGames.Client.Photon; using Microsoft.CodeAnalysis; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PhotonCustomPropsUtils")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+7a6f1ee1f463947ca9cc507608f1f04cdcd9325e")] [assembly: AssemblyProduct("PhotonCustomPropsUtils")] [assembly: AssemblyTitle("PhotonCustomPropsUtils")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace PhotonCustomPropsUtils { [BepInPlugin("com.snosz.photoncustompropsutils", "PhotonCustomPropsUtils", "1.0.0")] public class PhotonCustomPropsUtilsPlugin : BaseUnityPlugin { public static PhotonCustomPropsUtilsManager UtilsManager; public static bool IsReady { get; private set; } public static event Action OnReady; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown GameObject val = new GameObject("PhotonCustomPropsUtilsManager"); Object.DontDestroyOnLoad((Object)(object)val); UtilsManager = val.AddComponent<PhotonCustomPropsUtilsManager>(); IsReady = true; PhotonCustomPropsUtilsPlugin.OnReady?.Invoke(); } public static PhotonScopedManager GetManager(string modGUID) { return new PhotonScopedManager(modGUID, UtilsManager); } } public class PhotonCustomPropsUtilsManager : MonoBehaviourPunCallbacks { private static readonly Dictionary<string, List<PhotonScopedManager>> scopedManagers = new Dictionary<string, List<PhotonScopedManager>>(); public static void RegisterScopedManager(string modGUID, PhotonScopedManager manager) { if (!scopedManagers.TryGetValue(modGUID, out List<PhotonScopedManager> value)) { value = (scopedManagers[modGUID] = new List<PhotonScopedManager>()); } value.Add(manager); } public override void OnJoinedRoom() { Room currentRoom = PhotonNetwork.CurrentRoom; Hashtable val = ((currentRoom != null) ? ((RoomInfo)currentRoom).CustomProperties : null); Player localPlayer = PhotonNetwork.LocalPlayer; Hashtable val2 = ((localPlayer != null) ? localPlayer.CustomProperties : null); foreach (List<PhotonScopedManager> value in scopedManagers.Values) { foreach (PhotonScopedManager item in value) { if (val != null) { item.OnRoomPropertiesChanged(RoomEventType.OnJoinedRoom, val); } if (val2 != null) { item.OnPlayerPropertiesChanged(PlayerEventType.OnJoinedRoom, val2); } } } } public override void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { foreach (List<PhotonScopedManager> value in scopedManagers.Values) { foreach (PhotonScopedManager item in value) { item.OnRoomPropertiesChanged(RoomEventType.OnRoomPropertyChanged, propertiesThatChanged); } } } public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { foreach (List<PhotonScopedManager> value in scopedManagers.Values) { foreach (PhotonScopedManager item in value) { item.OnPlayerPropertiesChanged(PlayerEventType.OnPlayerPropertyChanged, changedProps); } } } } public enum RoomEventType { OnJoinedRoom, OnRoomPropertyChanged, All } public enum PlayerEventType { OnJoinedRoom, OnPlayerPropertyChanged, All } public class PhotonScopedManager { private struct RoomListener { public RoomEventType Type; public Action<object> Callback; } private struct PlayerListener { public PlayerEventType Type; public Action<object> Callback; } private readonly string modGUID; private readonly PhotonCustomPropsUtilsManager eventManager; private readonly Dictionary<string, List<RoomListener>> roomPropertyListeners = new Dictionary<string, List<RoomListener>>(); private readonly Dictionary<string, List<PlayerListener>> playerPropertyListeners = new Dictionary<string, List<PlayerListener>>(); public PhotonScopedManager(string modGUID, PhotonCustomPropsUtilsManager eventManager) { this.modGUID = modGUID; this.eventManager = eventManager; PhotonCustomPropsUtilsManager.RegisterScopedManager(modGUID, this); } public void RegisterRoomProperty(string propertyKey, RoomEventType type, Action<object> callback) { if (!roomPropertyListeners.TryGetValue(propertyKey, out List<RoomListener> value)) { value = new List<RoomListener>(); roomPropertyListeners[propertyKey] = value; } if (type == RoomEventType.All) { value.Add(new RoomListener { Type = RoomEventType.OnJoinedRoom, Callback = callback }); value.Add(new RoomListener { Type = RoomEventType.OnRoomPropertyChanged, Callback = callback }); } else { value.Add(new RoomListener { Type = type, Callback = callback }); } } public void RegisterRoomProperty<T>(string propertyKey, RoomEventType type, Action<T> callback) { Action<T> callback2 = callback; string propertyKey2 = propertyKey; RegisterRoomProperty(propertyKey2, type, delegate(object val) { if (val is T obj) { callback2(obj); } else { Debug.LogWarning((object)("[PhotonCustomPropsUtils] Expected type " + typeof(T).Name + " for key " + propertyKey2 + ", but got " + (val?.GetType().Name ?? "null"))); } }); } public void RegisterPlayerProperty(string propertyKey, PlayerEventType type, Action<object> callback) { if (!playerPropertyListeners.TryGetValue(propertyKey, out List<PlayerListener> value)) { value = new List<PlayerListener>(); playerPropertyListeners[propertyKey] = value; } if (type == PlayerEventType.All) { value.Add(new PlayerListener { Type = PlayerEventType.OnJoinedRoom, Callback = callback }); value.Add(new PlayerListener { Type = PlayerEventType.OnPlayerPropertyChanged, Callback = callback }); } else { value.Add(new PlayerListener { Type = type, Callback = callback }); } } public void RegisterPlayerProperty<T>(string propertyKey, PlayerEventType type, Action<T> callback) { Action<T> callback2 = callback; string propertyKey2 = propertyKey; RegisterPlayerProperty(propertyKey2, type, delegate(object val) { if (val is T obj) { callback2(obj); } else { Debug.LogWarning((object)("[PhotonScopedManager] Expected type " + typeof(T).Name + " for key " + propertyKey2 + ", but got " + (val?.GetType().Name ?? "null"))); } }); } public void SetRoomProperty(string propertyKey, object value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Hashtable val = new Hashtable { [(object)propertyKey] = value }; Room currentRoom = PhotonNetwork.CurrentRoom; if (currentRoom != null) { currentRoom.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } public void SetPlayerProperty(string propertyKey, object value) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Hashtable val = new Hashtable { [(object)propertyKey] = value }; Player localPlayer = PhotonNetwork.LocalPlayer; if (localPlayer != null) { localPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } } public void OnRoomPropertiesChanged(RoomEventType firedType, Hashtable changedProps) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) DictionaryEntryEnumerator enumerator = changedProps.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext()) { DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current; string key = current.Key.ToString(); if (!roomPropertyListeners.TryGetValue(key, out List<RoomListener> value)) { continue; } foreach (RoomListener item in value) { if (item.Type == firedType) { item.Callback(current.Value); } } } } finally { ((IDisposable)(DictionaryEntryEnumerator)(ref enumerator)).Dispose(); } } public void OnPlayerPropertiesChanged(PlayerEventType firedType, Hashtable changedProps) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) DictionaryEntryEnumerator enumerator = changedProps.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext()) { DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current; string key = current.Key.ToString(); if (!playerPropertyListeners.TryGetValue(key, out List<PlayerListener> value)) { continue; } foreach (PlayerListener item in value) { if (item.Type == firedType) { item.Callback(current.Value); } } } } finally { ((IDisposable)(DictionaryEntryEnumerator)(ref enumerator)).Dispose(); } } } }