Decompiled source of MultiCosmetic Mod v3.5.0

plugins/com.github.Spider-XD-Gaming.Multi-Cosmetic.dll

Decompiled 2 weeks ago
using 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)
		{
		}
	}
}