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 MultiCosmetic Mod v3.5.0
plugins/com.github.Spider-XD-Gaming.Multi-Cosmetic.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading.Tasks; using BepInEx; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.Spider-XD-Gaming.Multi-Cosmetic")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("3.5.0.0")] [assembly: AssemblyInformationalVersion("3.5.0")] [assembly: AssemblyProduct("com.github.Spider-XD-Gaming.Multi-Cosmetic")] [assembly: AssemblyTitle("Multi_Cosmetic")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.5.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Multi_Cosmetic { [BepInPlugin("com.github.Spider-XD-Gaming.Multi-Cosmetic", "Multi_Cosmetic", "3.5.0")] public class Plugin : BaseUnityPlugin { private static Dictionary<CharacterCustomization, List<Renderer>> playerToDestroyMap = new Dictionary<CharacterCustomization, List<Renderer>>(); private static Dictionary<PlayerCustomizationDummy, List<Renderer>> dummyToDestroyMap = new Dictionary<PlayerCustomizationDummy, List<Renderer>>(); private static Dictionary<PlayerGhost, List<Renderer>> ghostToDestroyMap = new Dictionary<PlayerGhost, List<Renderer>>(); private static int[][] currentData = new int[2][] { Array.Empty<int>(), Array.Empty<int>() }; public const string Id = "com.github.Spider-XD-Gaming.Multi-Cosmetic"; internal static ManualLogSource Log { get; private set; } = null; public static string Name => "Multi_Cosmetic"; public static string Version => "3.5.0"; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(typeof(Plugin), (string)null); dataFromString(); Log.LogInfo((object)("plugin " + Name + " loaded i think")); } [HarmonyPatch(typeof(Player), "OnPlayerEnteredRoom")] [HarmonyPatch(typeof(NetworkConnector), "OnJoinedRoom")] [HarmonyPostfix] private static void ResendLocalPhotonData() { Log.LogInfo((object)"COSMETICS - > player entered the room, re-updating the frickinge cosmetic properties"); Task.Run((Func<Task?>)eventuallyUpdate); } private static async Task eventuallyUpdate() { bool cont = true; while (cont) { cont = (Object)(object)Character.localCharacter == (Object)null || (Object)(object)((MonoBehaviourPun)Character.localCharacter).photonView == (Object)null; await Task.Delay(100); } UpdateCustomPropertiesValue(-1, 0); } private static void UpdateCustomPropertiesValue(int key, int value) { Hashtable val = hashtableOrNone(((MonoBehaviourPun)Character.localCharacter).photonView.Owner); if (key != -1) { int[][] array = new int[2][] { Array.Empty<int>(), Array.Empty<int>() }; if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { array = (int[][])val[(object)"SXDMultiCosmetics"]; } if (Extensions.Contains(array[key], value)) { array[key] = array[key].Except(new int[1] { value }).ToArray(); } else { array[key] = array[key].Concat(new int[1] { value }).ToArray(); } currentData = array; } if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { val[(object)"SXDMultiCosmetics"] = currentData; } else { ((Dictionary<object, object>)(object)val).Add((object)"SXDMultiCosmetics", (object)currentData); } Log.LogInfo((object)("COSMETICS - > updated photon properties & playerprefs to [" + string.Join(", ", currentData[0]) + "], [" + string.Join(", ", currentData[1]) + "]")); string text = dataToString(); PlayerPrefs.SetString("SXDMultiCosmetics", text); ((MonoBehaviourPun)Character.localCharacter).photonView.Owner.SetCustomProperties(val, (Hashtable)null, (WebFlags)null); } private static string dataToString() { return string.Join(",", currentData[0]) + "|" + string.Join(",", currentData[1]); } private static void dataFromString() { string @string = PlayerPrefs.GetString("SXDMultiCosmetics", "|"); Log.LogInfo((object)("COSMETICS - > getting \"" + @string + "\" from playerprefs")); if (!@string.Equals("|")) { string[] source = @string.Split('|')[0].Split(','); string[] source2 = @string.Split('|')[1].Split(','); int[] array = Array.Empty<int>(); int[] array2 = Array.Empty<int>(); try { array = source.Select(int.Parse).ToArray(); } catch { Log.LogWarning((object)"COSMETICS - > erm the accessories are malformed"); } try { array2 = source2.Select(int.Parse).ToArray(); } catch { Log.LogWarning((object)"COSMETICS - > erm the hats are malformed"); } currentData = new int[2][] { array, array2 }; } else { Log.LogInfo((object)"COSMETICS - > no data"); } } [HarmonyPatch(typeof(CharacterCustomization), "OnPlayerDataChange")] [HarmonyPostfix] private static void OverwriteCosmetics(CharacterCustomization __instance, ref CustomizationRefs ___refs) { int[][] array = (int[][])(__instance._character.IsLocal ? ((Array)currentData) : ((Array)new int[2][] { Array.Empty<int>(), Array.Empty<int>() })); Hashtable val = hashtableOrNone(__instance.view.Owner); if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { array = (int[][])val[(object)"SXDMultiCosmetics"]; } if (array != null) { if (!playerToDestroyMap.TryGetValue(__instance, out List<Renderer> value)) { value = new List<Renderer>(); } playerToDestroyMap[__instance] = faceHelper(array[0], value, ___refs.accessoryRenderer); hatHelper(array[1], ___refs.playerHats); } } [HarmonyPatch(typeof(PlayerCustomizationDummy), "UpdateDummy")] [HarmonyPostfix] private static void DummyAccessory(PlayerCustomizationDummy __instance, ref CustomizationRefs ___refs) { int[][] array = currentData; Hashtable val = hashtableOrNone(((MonoBehaviourPun)Character.localCharacter).photonView.Owner); if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { array = (int[][])val[(object)"SXDMultiCosmetics"]; } if (!dummyToDestroyMap.TryGetValue(__instance, out List<Renderer> value)) { value = new List<Renderer>(); } dummyToDestroyMap[__instance] = faceHelper(array[0], value, ___refs.accessoryRenderer); } [HarmonyPatch(typeof(PlayerCustomizationDummy), "SetPlayerHat")] [HarmonyPostfix] private static void DummyHat(PlayerCustomizationDummy __instance, ref CustomizationRefs ___refs) { int[][] array = currentData; Hashtable val = hashtableOrNone(((MonoBehaviourPun)Character.localCharacter).photonView.Owner); if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { array = (int[][])val[(object)"SXDMultiCosmetics"]; } hatHelper(array[1], ___refs.playerHats); } [HarmonyPatch(typeof(PassportManager), "SetActiveButton")] [HarmonyPostfix] private static void PassportButtons(PassportManager __instance, ref PassportButton[] ___buttons, ref Type ___activeType, ref Color ___activeBorderColor, ref Color ___inactiveBorderColor) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if ((int)___activeType != 10 && (int)___activeType != 50) { return; } Hashtable val = hashtableOrNone(((MonoBehaviourPun)Character.localCharacter).photonView.Owner); if (((Dictionary<object, object>)(object)val).ContainsKey((object)"SXDMultiCosmetics")) { int[][] array = (int[][])val[(object)"SXDMultiCosmetics"]; for (int i = 0; i < ___buttons.Length; i++) { ((Graphic)___buttons[i].border).color = (Extensions.Contains(array[((int)___activeType != 10) ? 1u : 0u], i) ? ___activeBorderColor : ___inactiveBorderColor); } } } [HarmonyPatch(typeof(PassportManager), "SetOption")] [HarmonyPrefix] private static bool passportTrigger(CustomizationOption option, int index) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if ((int)option.type == 10) { UpdateCustomPropertiesValue(0, index); } else if ((int)option.type == 50) { UpdateCustomPropertiesValue(1, index); } return true; } [HarmonyPatch(typeof(PlayerGhost), "CustomizeGhost")] [HarmonyPostfix] private static void GhostAccessory(PlayerGhost __instance, ref Renderer ___accessoryRenderer, ref PhotonView ___m_view) { bool flag = true; Character val = default(Character); if (!Character.GetCharacterWithPhotonID(___m_view.ViewID, ref val)) { flag = false; } if (flag) { flag = val.IsLocal; } int[][] array = (int[][])(flag ? ((Array)currentData) : ((Array)new int[2][] { Array.Empty<int>(), Array.Empty<int>() })); Hashtable val2 = hashtableOrNone(___m_view.Owner); if (((Dictionary<object, object>)(object)val2).ContainsKey((object)"SXDMultiCosmetics")) { array = (int[][])val2[(object)"SXDMultiCosmetics"]; } if (!ghostToDestroyMap.TryGetValue(__instance, out List<Renderer> value)) { value = new List<Renderer>(); } ghostToDestroyMap[__instance] = faceHelper(array[0], value, ___accessoryRenderer); } private static List<Renderer> faceHelper(int[] faceData, List<Renderer> toDestroy, Renderer accessoryRenderer) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown List<Texture> list = new List<Texture>(); foreach (int num in faceData) { try { list.Add(Singleton<Customization>.Instance.accessories[num].texture); } catch { UpdateCustomPropertiesValue(0, num); } } if (list.Count == 0) { list.Add(Singleton<Customization>.Instance.accessories[0].texture); } if (toDestroy.Count > 0) { foreach (Renderer item in toDestroy) { Object.Destroy((Object)(object)item); } toDestroy.Clear(); } for (int j = 0; j < list.Count; j++) { if (j == 0) { accessoryRenderer.material.SetTexture(CharacterCustomization.MainTex, list[0]); continue; } Renderer val = Object.Instantiate<Renderer>(accessoryRenderer); ((Component)val).transform.SetParent(((Component)accessoryRenderer).transform.parent, false); val.enabled = true; ((Component)val).gameObject.SetActive(true); ((Component)val).transform.localPosition = ((Component)accessoryRenderer).transform.localPosition; ((Component)val).transform.localRotation = ((Component)accessoryRenderer).transform.localRotation; ((Component)val).transform.localScale = ((Component)accessoryRenderer).transform.localScale; val.material = new Material(val.material); val.material.SetTexture(CharacterCustomization.MainTex, list[j]); toDestroy.Add(val); } return toDestroy; } private static void hatHelper(int[] hatData, Renderer[] playerHats) { for (int i = 0; i < playerHats.Length; i++) { try { ((Component)playerHats[i]).gameObject.SetActive(Extensions.Contains(hatData, i)); } catch { UpdateCustomPropertiesValue(1, i); } } } private static Hashtable hashtableOrNone(Player player) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown try { return player.CustomProperties; } catch { return new Hashtable(); } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }