Decompiled source of CustomAvatars v1.4.0

Mods/CustomAvatars.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using CustomAvatars;
using HarmonyLib;
using Il2CppExitGames.Client.Photon;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppPhoton.Pun;
using Il2CppPhoton.Realtime;
using Il2CppRUMBLE.CharacterCreation.Interactable;
using Il2CppRUMBLE.Interactions.InteractionBase;
using Il2CppRUMBLE.Managers;
using Il2CppRUMBLE.Players;
using Il2CppRUMBLE.Players.Scaling;
using Il2CppRUMBLE.Players.Subsystems;
using Il2CppRUMBLE.Utilities;
using Il2CppRootMotion;
using Il2CppRootMotion.FinalIK;
using Il2CppSmartLocalization.Editor;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.IO;
using Il2CppSystem.Text;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Utils;
using Newtonsoft.Json;
using RumbleModUI;
using RumbleModdingAPI.RMAPI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(Main), "CustomAvatars", "1.4.0", "ERROR", null)]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonOptionalDependencies(new string[] { "RumbleHud" })]
[assembly: MelonColor(255, 255, 0, 0)]
[assembly: MelonAuthorColor(255, 255, 0, 0)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("CustomAvatars")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+42b7cede0b4dbf30484969e662250b6b3c6595d7")]
[assembly: AssemblyProduct("CustomAvatars")]
[assembly: AssemblyTitle("CustomAvatars")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CustomAvatars;

public class AvatarStateSystem
{
	private readonly Dictionary<string, bool> bools = new Dictionary<string, bool>();

	private readonly Dictionary<string, float> floats = new Dictionary<string, float>();

	public event Action<string, bool> OnBoolChanged;

	public event Action<string, float> OnFloatChanged;

	public void SetBool(string name, bool value)
	{
		if (!bools.TryGetValue(name, out var value2) || value2 != value)
		{
			bools[name] = value;
			this.OnBoolChanged?.Invoke(name, value);
		}
	}

	public bool GetBool(string name)
	{
		bool value;
		return bools.TryGetValue(name, out value) && value;
	}

	public void SetFloat(string name, float value)
	{
		if (!floats.TryGetValue(name, out var value2) || !Mathf.Approximately(value2, value))
		{
			floats[name] = value;
			this.OnFloatChanged?.Invoke(name, value);
		}
	}

	public float GetFloat(string name)
	{
		float value;
		return floats.TryGetValue(name, out value) ? value : 0f;
	}
}
[Serializable]
public class ShaderState
{
	public Renderer renderer;

	public string property = "_EmissionStrength";

	public int materialIndex = -1;

	public void ApplyFloat(float value)
	{
		if (!Object.op_Implicit((Object)(object)renderer))
		{
			return;
		}
		Il2CppReferenceArray<Material> materials = renderer.materials;
		if (materialIndex >= 0 && materialIndex < ((Il2CppArrayBase<Material>)(object)materials).Length)
		{
			if ((Object)(object)((Il2CppArrayBase<Material>)(object)materials)[materialIndex] != (Object)null && ((Il2CppArrayBase<Material>)(object)materials)[materialIndex].HasFloat(property))
			{
				((Il2CppArrayBase<Material>)(object)materials)[materialIndex].SetFloat(property, value);
			}
			return;
		}
		foreach (Material item in (Il2CppArrayBase<Material>)(object)materials)
		{
			if (item.HasProperty(property))
			{
				item.SetFloat(property, value);
			}
		}
	}

	public void ApplyBool(bool value)
	{
		ApplyFloat(value ? 1f : 0f);
	}
}
[Serializable]
public class BlendshapeState
{
	public SkinnedMeshRenderer smr;

	public int index = -1;

	public void Apply(float weight)
	{
		if (Object.op_Implicit((Object)(object)smr) && index >= 0)
		{
			smr.SetBlendShapeWeight(index, Mathf.Clamp(weight, 0f, 100f));
		}
	}

	public void Apply(bool on)
	{
		Apply(on ? 100f : 0f);
	}
}
public static class BuildInfo
{
	public const string Name = "CustomAvatars";

	public const string Version = "1.4.0";
}
public static class Extensions
{
	public static string TrimString(this string str)
	{
		return Regex.Replace(str, "<.*?>|\\(.*?\\)|[^a-zA-Z0-9_ ]", "").Trim();
	}

	public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component
	{
		T val = gameObject.GetComponent<T>();
		if ((Object)(object)val == (Object)null)
		{
			val = gameObject.AddComponent<T>();
		}
		return val;
	}

	public static T GetSavedValue<T>(this ModSetting<T> modSetting)
	{
		return (T)(((modSetting != null) ? ((ModSetting)modSetting).SavedValue : null) ?? ((object)default(T)));
	}

	public static T GetValue<T>(this ModSetting<T> modSetting)
	{
		return (T)(((modSetting != null) ? ((ModSetting)modSetting).Value : null) ?? ((object)default(T)));
	}
}
[RegisterTypeInIl2Cpp]
public class CustomRigBone : MonoBehaviour
{
}
public class Main : MelonMod
{
	[CompilerGenerated]
	private sealed class <>c__DisplayClass38_0
	{
		public Main <>4__this;

		public string scene;

		internal void <Initialize>b__0()
		{
			if ((bool)((ModSetting)<>4__this.toggleLocal).SavedValue)
			{
				MelonCoroutines.Start(<>4__this.Initialize(scene));
			}
		}

		internal void <Initialize>b__1()
		{
			<>4__this.UploadAvatar();
		}
	}

	[CompilerGenerated]
	private sealed class <Initialize>d__38 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string scene;

		public Main <>4__this;

		private <>c__DisplayClass38_0 <>8__1;

		private string <filePath>5__2;

		private InteractionButton <interactionButton>5__3;

		private InteractionButton <interactionButtonUpload>5__4;

		private TextMeshPro <text>5__5;

		private TextMeshPro <textUpload>5__6;

		private GameObject <summary>5__7;

		private GameObject <details>5__8;

		private GameObject <warnings>5__9;

		private GameObject <newServerStatus>5__10;

		private Hashtable <props>5__11;

		private List<bool> <toggles>5__12;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <Initialize>d__38(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>8__1 = null;
			<filePath>5__2 = null;
			<interactionButton>5__3 = null;
			<interactionButtonUpload>5__4 = null;
			<text>5__5 = null;
			<textUpload>5__6 = null;
			<summary>5__7 = null;
			<details>5__8 = null;
			<warnings>5__9 = null;
			<newServerStatus>5__10 = null;
			<props>5__11 = null;
			<toggles>5__12 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Expected O, but got Unknown
			//IL_03cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_041a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0480: Unknown result type (might be due to invalid IL or missing references)
			//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0530: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0671: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0724: Unknown result type (might be due to invalid IL or missing references)
			//IL_0729: Unknown result type (might be due to invalid IL or missing references)
			//IL_072e: Unknown result type (might be due to invalid IL or missing references)
			//IL_078a: Unknown result type (might be due to invalid IL or missing references)
			//IL_07af: Unknown result type (might be due to invalid IL or missing references)
			//IL_084b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0855: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass38_0();
				<>8__1.<>4__this = <>4__this;
				<>8__1.scene = scene;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				RigManager.ClearRigs();
				<>4__this.lastProps.Clear();
				<filePath>5__2 = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars", "Opponents");
				Directory.CreateDirectory(<filePath>5__2);
				if (<>4__this.currentScene == "Gym" && !<>4__this.sceneInitialized)
				{
					<>4__this.tryoutModeButton = TryOutModePanel.GetGameObject();
					<>4__this.uploadAvatarButton = Object.Instantiate<GameObject>(<>4__this.tryoutModeButton, <>4__this.tryoutModeButton.transform.parent, false);
					((Object)<>4__this.uploadAvatarButton).name = "Upload Avatar Panel";
					<>4__this.uploadAvatarButton.transform.localPosition = new Vector3(0.1069f, 0.1962f, -0.1014f);
					<>4__this.refreshAvatarButton = Object.Instantiate<GameObject>(<>4__this.tryoutModeButton, <>4__this.tryoutModeButton.transform.parent, false);
					((Object)<>4__this.refreshAvatarButton).name = "Refresh Avatar Panel";
					<>4__this.refreshAvatarButton.transform.localPosition = new Vector3(-0.1164f, 0.1962f, -0.1014f);
					<interactionButton>5__3 = ((Component)<>4__this.refreshAvatarButton.transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>();
					((UnityEventBase)<interactionButton>5__3.onPressed).RemoveAllListeners();
					<interactionButton>5__3.onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
					{
						if ((bool)((ModSetting)<>8__1.<>4__this.toggleLocal).SavedValue)
						{
							MelonCoroutines.Start(<>8__1.<>4__this.Initialize(<>8__1.scene));
						}
					}));
					((InteractionBase)<interactionButton>5__3).interactionAnimParameter = "nan";
					((InteractionBase)<interactionButton>5__3).InteractionAnimParameterL = "nan";
					((InteractionBase)<interactionButton>5__3).InteractionAnimParameterR = "nan";
					<interactionButtonUpload>5__4 = ((Component)<>4__this.uploadAvatarButton.transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>();
					((UnityEventBase)<interactionButtonUpload>5__4.onPressed).RemoveAllListeners();
					<interactionButtonUpload>5__4.onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
					{
						<>8__1.<>4__this.UploadAvatar();
					}));
					<text>5__5 = ((Component)<>4__this.refreshAvatarButton.transform.GetChild(1).GetChild(1)).GetComponent<TextMeshPro>();
					Object.Destroy((Object)(object)((Component)<text>5__5.transform).GetComponent<LocalizedTextTMPro>());
					((TMP_Text)<text>5__5).m_text = "Refresh Avatar";
					((TMP_Text)<text>5__5).fontSize = 0.25f;
					((TMP_Text)<text>5__5).ForceMeshUpdate(false, false);
					<textUpload>5__6 = ((Component)<>4__this.uploadAvatarButton.transform.GetChild(1).GetChild(1)).GetComponent<TextMeshPro>();
					Object.Destroy((Object)(object)((Component)<textUpload>5__6.transform).GetComponent<LocalizedTextTMPro>());
					((TMP_Text)<textUpload>5__6).m_text = "Upload Avatar";
					((TMP_Text)<textUpload>5__6).fontSize = 0.25f;
					((TMP_Text)<textUpload>5__6).ForceMeshUpdate(false, false);
					<>4__this.avatarOptimizationParent = new GameObject("AvatarDetails");
					<>4__this.avatarOptimizationParent.transform.localPosition = new Vector3(-3.5418f, 1.2327f, -0.8255f);
					<>4__this.avatarOptimizationParent.transform.localScale = Vector3.one * 0.5f;
					<>4__this.avatarOptimizationParent.transform.localRotation = Quaternion.Euler(6.3636f, 241.8925f, 0f);
					<>4__this.uploadProgressBar = Object.Instantiate<GameObject>(StatusBar.GetGameObject(), <>4__this.avatarOptimizationParent.transform, false);
					((Object)<>4__this.uploadProgressBar).name = "Upload Progress Bar";
					<>4__this.uploadProgressBar.transform.localScale = new Vector3(0.8562f, 0.0544f, 0.854f);
					<>4__this.uploadProgressBar.transform.localPosition = new Vector3(-1.9034f, 0.2507f, -0.4614f);
					<>4__this.uploadProgressBar.transform.localRotation = Quaternion.Euler(354.8412f, 324.0485f, 3.7311f);
					((Renderer)<>4__this.uploadProgressBar.GetComponent<MeshRenderer>()).material.SetFloat("_RC_Target", 1f);
					<>4__this.uploadProgressBar.SetActive(false);
					<summary>5__7 = Create.NewText("GOOD", 1f, new Color(0f, 0.5f, 0f), Vector3.zero, Quaternion.identity);
					((Object)<summary>5__7).name = "Summary";
					<summary>5__7.transform.SetParent(<>4__this.avatarOptimizationParent.transform, false);
					<summary>5__7.transform.localPosition = new Vector3(0f, 0.0919f, 0f);
					((TMP_Text)<summary>5__7.GetComponent<TextMeshPro>()).enableWordWrapping = false;
					((TMP_Text)<summary>5__7.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
					<details>5__8 = Create.NewText("0 verts, 0 mat(s), 0 texture(s)", 1f, new Color(0f, 0.5f, 0f), Vector3.zero, Quaternion.identity);
					((Object)<details>5__8).name = "Details";
					<details>5__8.transform.SetParent(<>4__this.avatarOptimizationParent.transform, false);
					((TMP_Text)<details>5__8.GetComponent<TextMeshPro>()).enableWordWrapping = false;
					((TMP_Text)<details>5__8.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
					<warnings>5__9 = Create.NewText("WARNINGS:", 1f, new Color(1f, 1f, 0f), Vector3.zero, Quaternion.identity);
					((Object)<warnings>5__9).name = "Warnings";
					<warnings>5__9.transform.SetParent(<>4__this.avatarOptimizationParent.transform, false);
					<warnings>5__9.transform.localPosition = new Vector3(0f, -0.0919f, 0f);
					((TMP_Text)<warnings>5__9.GetComponent<TextMeshPro>()).enableWordWrapping = false;
					((TMP_Text)<warnings>5__9.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
					<newServerStatus>5__10 = Create.NewText("Up To Date", 1f, new Color(0f, 1f, 1f), Vector3.zero, Quaternion.identity);
					((Object)<newServerStatus>5__10).name = "AvatarServerStatus";
					<newServerStatus>5__10.transform.SetParent(<>4__this.avatarOptimizationParent.transform, false);
					<newServerStatus>5__10.transform.localPosition = new Vector3(-1.9309f, 0.2499f, -0.4545f);
					<newServerStatus>5__10.transform.localRotation = Quaternion.Euler(352.9085f, 321.6011f, 3.3454f);
					<>4__this.serverStatusText = <newServerStatus>5__10.GetComponent<TextMeshPro>();
					((TMP_Text)<>4__this.serverStatusText).enableWordWrapping = false;
					((TMP_Text)<>4__this.serverStatusText).alignment = (TextAlignmentOptions)514;
					<>4__this.SetObjectsActive();
					<interactionButton>5__3 = null;
					<interactionButtonUpload>5__4 = null;
					<text>5__5 = null;
					<textUpload>5__6 = null;
					<summary>5__7 = null;
					<details>5__8 = null;
					<warnings>5__9 = null;
					<newServerStatus>5__10 = null;
				}
				if (PhotonNetwork.InRoom)
				{
					<props>5__11 = new Hashtable();
					<props>5__11[Object.op_Implicit("CA_ModVersion")] = Object.op_Implicit("1.4.0");
					<toggles>5__12 = RigManager.avatarSettingBools.Select((ModSetting<bool> s) => (bool)((ModSetting)s).Value).ToList();
					<props>5__11[Object.op_Implicit("Ca_Params")] = Object.op_Implicit(RigManager.PackParams(<toggles>5__12));
					PhotonNetwork.LocalPlayer.SetCustomProperties(<props>5__11, (Hashtable)null, (WebFlags)null);
					<props>5__11 = null;
					<toggles>5__12 = null;
				}
				<>4__this.ApplyAvatars();
				<>4__this.sceneInitialized = true;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public string currentScene = "Loader";

	public bool sceneInitialized;

	public static Main instance;

	public CustomRig localRig;

	public GameObject rigParent;

	public GameObject avatarOptimizationParent;

	public GameObject refreshAvatarButton;

	public GameObject tryoutModeButton;

	public GameObject uploadAvatarButton;

	public GameObject uploadProgressBar;

	public TextMeshPro serverStatusText;

	public GameObject tagObject;

	public (Color color, string status) serverStatus = (Color.cyan, "Up To Date");

	public Mod mod = new Mod();

	public ModSetting<string> reloadKeybind;

	public ModSetting<bool> reloadToggle;

	public ModSetting<bool> toggleLocal;

	public ModSetting<bool> toggleOthers;

	public ModSetting<bool> toggleVisibleToOthers;

	public ModSetting<bool> toggleInMatch;

	public ModSetting<bool> toggleIfNewerVersion;

	public ModSetting<bool> toggleInRockCam;

	public ModSetting<bool> logAvatarStats;

	public ModSetting<bool> logOtherAvatarStats;

	public ModSetting<int> downloadLimitMB;

	public ModSetting<int> maxConcurrentDownloads;

	public ModSetting<bool> uploadAvatar;

	public ModSetting<bool> perPlayerHeader;

	public Dictionary<string, PlayerEntry> perPlayerSettings = new Dictionary<string, PlayerEntry>();

	private Dictionary<int, Hashtable> lastProps = new Dictionary<int, Hashtable>();

	public static Material poseGhostMaterial;

	public List<Transform> previewScanList = new List<Transform>();

	public GameObject bodyDouble;

	public GameObject currentRig;

	public Main()
	{
		//IL_000c: 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_002b: Expected O, but got Unknown
		instance = this;
	}

	public override void OnLateInitializeMelon()
	{
		Actions.onMapInitialized += delegate(string scene)
		{
			MelonCoroutines.Start(Initialize(scene));
		};
		UI.instance.UI_Initialized += OnUIInitialized;
		((MelonBase)this).LoggerInstance.Msg("Custom Avatars Initialized");
		RigManager.Initialize(this);
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		currentScene = sceneName;
		sceneInitialized = false;
		RigManager.rigs.Clear();
		Patches.loadedPlayers.Clear();
		rigParent = null;
		string text = currentScene;
		if ((text == "Gym" || text == "Park") ? true : false)
		{
			RigManager.OpponentID = string.Empty;
		}
	}

	public override void OnDeinitializeMelon()
	{
		string path = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars", "Opponents");
		if (!Directory.Exists(path))
		{
			return;
		}
		string[] files = Directory.GetFiles(path);
		foreach (string path2 in files)
		{
			try
			{
				File.Delete(path2);
			}
			catch (IOException)
			{
			}
			catch (UnauthorizedAccessException)
			{
			}
		}
	}

	[IteratorStateMachine(typeof(<Initialize>d__38))]
	public IEnumerator Initialize(string scene)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <Initialize>d__38(0)
		{
			<>4__this = this,
			scene = scene
		};
	}

	public void SetObjectsActive()
	{
		bool flag = (bool)((ModSetting)toggleLocal).Value && Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").Length != 0;
		tryoutModeButton.SetActive(!flag);
		uploadAvatarButton.SetActive(flag);
		refreshAvatarButton.SetActive(flag);
		avatarOptimizationParent.SetActive(flag);
	}

	public void CheckClonebending(CustomRig customRig, GameObject rig, bool log)
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0284: Unknown result type (might be due to invalid IL or missing references)
		//IL_0287: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Invalid comparison between Unknown and I4
		//IL_0297: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		Type type = Type.GetType("CloneBending2.Core, CloneBending2");
		if (type == null)
		{
			return;
		}
		object obj = type.GetField("instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
		bodyDouble = (GameObject)(type.GetField("bodyDouble", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(obj));
		if (!((Object)(object)bodyDouble != (Object)null))
		{
			return;
		}
		string text = Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").FirstOrDefault();
		AssetBundle val = AssetBundle.LoadFromFile(text);
		GameObject val2 = val.LoadAsset<GameObject>("Rig");
		val.Unload(false);
		((Object)val2).name = "RIG - CloneBending Clone";
		val2.transform.SetParent(rigParent.transform, true);
		SkinnedMeshRenderer component = ((Component)bodyDouble.transform.GetChild(1).GetChild(0)).GetComponent<SkinnedMeshRenderer>();
		CustomRig customRig2 = bodyDouble.GetComponent<CustomRig>();
		if ((Object)(object)customRig2 != (Object)null)
		{
			if (customRig2.blinkCoroutine != null)
			{
				MelonCoroutines.Stop(customRig2.blinkCoroutine);
			}
		}
		else
		{
			customRig2 = bodyDouble.AddComponent<CustomRig>();
			customRig2.PlayerName = "CloneBending Clone";
			customRig2.IsPreview = true;
			customRig2.CaptureOriginal("CloneBending Clone", isLocal: false, component, log);
		}
		customRig2.CaptureRig(val2);
		customRig2.Config = customRig.Config;
		if (!customRig2.Config.swapOriginalMesh)
		{
			rig.transform.SetParent(bodyDouble.transform, true);
		}
		RigManager.ApplyRigToSMR(bodyDouble.transform.GetChild(1).GetChild(1), val2, ((Component)bodyDouble.transform.GetChild(1)).GetComponent<Animator>(), customRig2);
		RigManager.rigs["CloneBending Clone"] = customRig2;
		if (!(bool)((ModSetting)toggleLocal).SavedValue)
		{
			customRig2.Apply(CustomRig.RigState.Original);
		}
		else
		{
			customRig2.Apply(CustomRig.RigState.Rigged);
		}
		Animator component2 = rig.GetComponent<Animator>();
		Animator component3 = val2.GetComponent<Animator>();
		if (!((Object)(object)component2 != (Object)null) || !((Object)(object)component3 != (Object)null) || !component3.isHuman)
		{
			return;
		}
		foreach (HumanBodyBones value in Enum.GetValues(typeof(HumanBodyBones)))
		{
			if ((int)value != 55)
			{
				Transform boneTransform = component2.GetBoneTransform(value);
				Transform boneTransform2 = component3.GetBoneTransform(value);
				if ((Object)(object)boneTransform != (Object)null && (Object)(object)boneTransform2 != (Object)null)
				{
					boneTransform2.localRotation = boneTransform.localRotation;
				}
			}
		}
	}

	public void UploadAvatar()
	{
		string text = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars", Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").FirstOrDefault() ?? string.Empty);
		string playFabMasterId = Players.GetLocalPlayer().Data.GeneralData.PlayFabMasterId;
		if (!File.Exists(text))
		{
			((MelonBase)this).LoggerInstance.Error("Invalid bundle found at path: " + text);
			return;
		}
		float displayedProgress = 0f;
		Material progressBarMat = null;
		((MelonBase)this).LoggerInstance.Msg("Uploading file at path '" + text + "' for MasterID " + playFabMasterId);
		RemoteAvatarLoader.UploadBundle(playFabMasterId, text, delegate
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (currentScene == "Gym")
			{
				uploadProgressBar.SetActive(true);
				progressBarMat = ((Renderer)uploadProgressBar.GetComponent<MeshRenderer>()).material;
				progressBarMat.SetFloat("_RC_Current", 0f);
				((Component)serverStatusText).gameObject.transform.localPosition = new Vector3(-1.9309f, 0.359f, -0.4545f);
				((Graphic)serverStatusText).color = Color.yellow;
			}
		}, delegate(bool success, bool skipped)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			if (currentScene == "Gym")
			{
				uploadProgressBar.SetActive(false);
				serverStatus = (success ? (Color.cyan, "Up To Date") : (Color.red, "Not Uploaded"));
				((Graphic)serverStatusText).color = serverStatus.color;
				((TMP_Text)serverStatusText).text = serverStatus.status;
				((Component)serverStatusText).gameObject.transform.localPosition = new Vector3(-1.9309f, 0.2499f, -0.4545f);
			}
			if (!skipped)
			{
				((MelonBase)this).LoggerInstance.Msg((success ? "File uploaded successfully!" : "Upload failed.") ?? "");
			}
		}, delegate(float progress)
		{
			if (!((Object)(object)progressBarMat == (Object)null) && !(currentScene != "Gym"))
			{
				displayedProgress = Mathf.Lerp(displayedProgress, progress, Time.deltaTime * 10f);
				progressBarMat.SetFloat("_RC_Current", displayedProgress);
			}
		}, serverStatusText);
	}

	public void ApplyAvatars(bool log = true, bool clearAll = true)
	{
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Expected O, but got Unknown
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Expected O, but got Unknown
		if (clearAll)
		{
			RigManager.ClearRigs();
		}
		Camera camera = Singleton<PlayerManager>.instance.LocalPlayer.Controller.GetSubsystem<PlayerCamera>().camera;
		camera.cullingMask |= 4;
		Camera component = RecordingCamera.GetGameObject().GetComponent<Camera>();
		component.cullingMask |= 4;
		Player localPlayer = Players.GetLocalPlayer();
		if ((Object)(object)rigParent == (Object)null)
		{
			rigParent = new GameObject("Rigs");
		}
		CustomRig customRig = ((Component)localPlayer.Controller).gameObject.GetComponent<CustomRig>();
		if ((Object)(object)customRig == (Object)null)
		{
			customRig = ((Component)localPlayer.Controller).gameObject.AddComponent<CustomRig>();
			customRig.CaptureOriginal(localPlayer.Data.GeneralData.PlayFabMasterId, isLocal: true, localPlayer.Controller.GetSubsystem<PlayerVisuals>().renderer, log);
			localRig = customRig;
		}
		else if (customRig.blinkCoroutine != null)
		{
			MelonCoroutines.Stop(customRig.blinkCoroutine);
		}
		MelonCoroutines.Start(RigManager.LoadRigForPlayer(localPlayer, delegate(GameObject rig)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			serverStatus = (Color.yellow, "Checking...");
			((TMP_Text)serverStatusText).text = serverStatus.status;
			((Graphic)serverStatusText).color = serverStatus.color;
			MelonCoroutines.Start(RemoteAvatarLoader.GetSha(Players.GetLocalPlayer().Data.GeneralData.PlayFabMasterId, delegate(string sha)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Unknown result type (might be due to invalid IL or missing references)
				//IL_011c: Unknown result type (might be due to invalid IL or missing references)
				if (sha == null)
				{
					serverStatus = (Color.red, "Not Uploaded");
					if (log)
					{
						((MelonBase)this).LoggerInstance.MsgPastel(ConsoleColor.Red, "An avatar has not been uploaded. Make sure to upload your avatar when you're done!");
					}
				}
				else if (!RemoteAvatarLoader.ShaMatchesLocal(sha, customRig.AvatarFilePath, log: false))
				{
					serverStatus = (Color.red, "Not Uploaded");
					if (log)
					{
						((MelonBase)this).LoggerInstance.MsgPastel(ConsoleColor.Red, "Uploaded file is different from local file. Make sure to reupload your avatar when you're done!");
					}
				}
				else
				{
					serverStatus = (Color.cyan, "Up To Date");
					if (log)
					{
						((MelonBase)this).LoggerInstance.MsgPastel(ConsoleColor.Cyan, "Avatar is up to date on the server.");
					}
				}
				((TMP_Text)serverStatusText).text = serverStatus.status;
				((Graphic)serverStatusText).color = serverStatus.color;
			}, log: false));
			UpdateAvatarVisibility();
			if (currentScene == "Gym" && (Object)(object)rig != (Object)null)
			{
				GameObject previewController = Visuals.GetGameObject();
				currentRig = rig;
				LoadPreviewController();
				CheckClonebending(customRig, currentRig, log);
				MelonCoroutines.Start(RigManager.FixHUDCamera(localPlayer.Data.GeneralData.PlayFabMasterId, delegate
				{
					if (!(bool)((ModSetting)toggleInRockCam).SavedValue)
					{
						((Component)previewController.transform.GetChild(0)).gameObject.layer = 2;
					}
					else
					{
						((Component)previewController.transform.GetChild(0)).gameObject.layer = 23;
					}
				}));
			}
		}, log));
		if (currentScene == "Gym" && (Object)(object)poseGhostMaterial == (Object)null)
		{
			poseGhostMaterial = new Material(((Renderer)Poseghostbody.GetGameObject().GetComponent<SkinnedMeshRenderer>()).material);
			((Object)poseGhostMaterial).hideFlags = (HideFlags)61;
		}
	}

	public void LoadPreviewController()
	{
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0292: Invalid comparison between Unknown and I4
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
		GameObject gameObject = Visuals.GetGameObject();
		string text = Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").FirstOrDefault();
		AssetBundle val = AssetBundle.LoadFromFile(text);
		GameObject val2 = val.LoadAsset<GameObject>("Rig");
		val.Unload(false);
		((Object)val2).name = "RIG - Preview Controller (Dressing Room)";
		val2.transform.SetParent(rigParent.transform, true);
		SkinnedMeshRenderer component = ((Component)gameObject.transform.GetChild(0)).GetComponent<SkinnedMeshRenderer>();
		CustomRig customRig = ((Component)gameObject.transform.parent).GetComponent<CustomRig>();
		if ((Object)(object)customRig != (Object)null)
		{
			if (customRig.blinkCoroutine != null)
			{
				MelonCoroutines.Stop(customRig.blinkCoroutine);
			}
		}
		else
		{
			customRig = ((Component)gameObject.transform.parent).gameObject.AddComponent<CustomRig>();
			customRig.IsPreview = true;
			customRig.PlayerName = "Preview Controller (Dressing Room)";
			customRig.CaptureOriginal("Preview Controller (Dressing Room)", isLocal: false, component, log: false);
		}
		customRig.CaptureRig(val2);
		customRig.Config = localRig.Config;
		previewScanList = RigManager.Scan(val2.transform);
		for (int i = 0; i < customRig.Config.parameters.Count; i++)
		{
			AvatarParam avatarParam = customRig.Config.parameters[i];
			ModSetting<bool> setting = RigManager.avatarSettingBools[i];
			GameObject previewObj = ((Component)previewScanList[avatarParam.targetIndex]).gameObject;
			previewObj.SetActive((bool)((ModSetting)setting).Value);
			((ModSetting)setting).SavedValueChanged += delegate
			{
				previewObj.SetActive((bool)((ModSetting)setting).Value);
			};
		}
		RigManager.ApplyRigToSMR(gameObject.transform.GetChild(1), val2, gameObject.GetComponent<Animator>(), customRig);
		RigManager.rigs["Preview Controller (Dressing Room)"] = customRig;
		if (!(bool)((ModSetting)toggleLocal).SavedValue)
		{
			customRig.Apply(CustomRig.RigState.Original);
		}
		else
		{
			customRig.Apply(CustomRig.RigState.Rigged);
		}
		Animator component2 = currentRig.GetComponent<Animator>();
		Animator component3 = val2.GetComponent<Animator>();
		if (!((Object)(object)component2 != (Object)null) || !((Object)(object)component3 != (Object)null))
		{
			return;
		}
		foreach (HumanBodyBones value in Enum.GetValues(typeof(HumanBodyBones)))
		{
			if ((int)value != 55)
			{
				Transform boneTransform = component2.GetBoneTransform(value);
				Transform boneTransform2 = component3.GetBoneTransform(value);
				if ((Object)(object)boneTransform != (Object)null && (Object)(object)boneTransform2 != (Object)null)
				{
					boneTransform2.localRotation = boneTransform.localRotation;
				}
			}
		}
	}

	public override void OnFixedUpdate()
	{
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_035e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0363: Unknown result type (might be due to invalid IL or missing references)
		//IL_037b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0380: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Unknown result type (might be due to invalid IL or missing references)
		//IL_0389: Unknown result type (might be due to invalid IL or missing references)
		//IL_038f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_039e: Unknown result type (might be due to invalid IL or missing references)
		if (currentScene == "Loader")
		{
			return;
		}
		if (Object.op_Implicit((Object)(object)rigParent) && !rigParent.activeSelf)
		{
			rigParent.SetActive(true);
		}
		if (Object.op_Implicit((Object)(object)refreshAvatarButton) && !refreshAvatarButton.activeSelf && currentScene == "Gym" && (bool)((ModSetting)toggleLocal).SavedValue)
		{
			refreshAvatarButton.SetActive(true);
		}
		if (currentScene == "Gym")
		{
			GameObject gameObject = DressingRoom.GetGameObject();
			if (!gameObject.activeSelf)
			{
				gameObject.SetActive(true);
				((Component)gameObject.transform.GetChild(0)).gameObject.SetActive(false);
				((Component)gameObject.transform.GetChild(1)).gameObject.SetActive(false);
				((Component)gameObject.transform.GetChild(2).GetChild(1)).gameObject.SetActive(false);
				gameObject.transform.position = new Vector3(-0.4274f, 0.093f, -3.1731f);
				avatarOptimizationParent.transform.position = new Vector3(-1.3643f, 1.2603f, -3.4911f);
				avatarOptimizationParent.SetActive(true);
			}
		}
		if (!(currentScene != "Gym"))
		{
			return;
		}
		ModSetting<bool> obj = toggleOthers;
		if (!(bool)(((obj != null) ? ((ModSetting)obj).SavedValue : null) ?? ((object)false)))
		{
			return;
		}
		CustomRig rig = default(CustomRig);
		SpriteRenderer val2 = default(SpriteRenderer);
		CustomRig rig2 = default(CustomRig);
		foreach (Player item in (Il2CppArrayBase<Player>)(object)PhotonNetwork.PlayerList)
		{
			if (item.CustomProperties == null || item == PhotonNetwork.LocalPlayer)
			{
				continue;
			}
			Player playerByActorNo = Players.GetPlayerByActorNo(item.ActorNumber);
			Hashtable customProperties = item.CustomProperties;
			if (customProperties == null)
			{
				continue;
			}
			if (((Dictionary<Object, Object>)(object)customProperties).ContainsKey(Object.op_Implicit("CA_Avatar")) && (Object)(object)localRig != (Object)null)
			{
				bool? obj2;
				if (playerByActorNo == null)
				{
					obj2 = null;
				}
				else
				{
					PlayerController controller = playerByActorNo.Controller;
					obj2 = ((controller != null) ? new bool?(((Component)controller).TryGetComponent<CustomRig>(ref rig)) : null);
				}
				bool? flag = obj2;
				if (flag.GetValueOrDefault())
				{
					RigManager.ResolveRigState(playerByActorNo, rig);
				}
			}
			if (((Dictionary<Object, Object>)(object)customProperties).ContainsKey(Object.op_Implicit(Players.GetLocalPlayer().Data.GeneralData.PlayFabMasterId + "_CAVisibility")))
			{
				RigManager.VisibilityResult visibilityResult = RigManager.CanPlayerSeeMe(item);
				object obj3;
				if (playerByActorNo == null)
				{
					obj3 = null;
				}
				else
				{
					PlayerController controller2 = playerByActorNo.Controller;
					obj3 = ((controller2 != null) ? ((Component)controller2).GetComponent<CustomRig>() : null);
				}
				CustomRig customRig = (CustomRig)obj3;
				if (customRig != null && Object.op_Implicit((Object)(object)customRig))
				{
					Transform val = ((Component)playerByActorNo.Controller).transform.GetChild(9).Find("CustomAvatarTag");
					if ((Object)(object)val != (Object)null && ((Component)val).TryGetComponent<SpriteRenderer>(ref val2))
					{
						SpriteRenderer val3 = val2;
						if (1 == 0)
						{
						}
						Color color = (Color)(visibilityResult switch
						{
							RigManager.VisibilityResult.Visible => Color.white, 
							RigManager.VisibilityResult.Hidden => new Color(1f, 0.5f, 0.5f, 1f), 
							RigManager.VisibilityResult.Unknown => Color.grey, 
							_ => val2.color, 
						});
						if (1 == 0)
						{
						}
						val3.color = color;
					}
				}
			}
			if (((Dictionary<Object, Object>)(object)customProperties).ContainsKey(Object.op_Implicit("CA_Params")) && ((Component)playerByActorNo.Controller).TryGetComponent<CustomRig>(ref rig2))
			{
				int mask = Convert.ToInt32(customProperties[Object.op_Implicit("CA_Params")]);
				RigManager.ApplyRemoteParams(rig2, mask);
			}
		}
	}

	public override void OnUpdate()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		if (reloadKeybind != null && Enum.TryParse<KeyCode>((string)((ModSetting)reloadKeybind).SavedValue, ignoreCase: true, out KeyCode result) && Input.GetKeyDown(result))
		{
			MelonCoroutines.Start(Initialize(currentScene));
		}
	}

	public void AddPlayerToList(Player player)
	{
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Expected O, but got Unknown
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Expected O, but got Unknown
		try
		{
			Player obj = player;
			bool? obj2;
			CustomRig rig = default(CustomRig);
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				PlayerController controller = obj.Controller;
				obj2 = ((controller != null) ? new bool?(((Component)controller).TryGetComponent<CustomRig>(ref rig)) : null);
			}
			bool? flag = obj2;
			if (!flag.GetValueOrDefault())
			{
				return;
			}
			if (string.IsNullOrEmpty(rig.PlayerId))
			{
				return;
			}
			if (perPlayerSettings.Count == 0)
			{
				perPlayerHeader = mod.AddToList("<b><#FFB347>- Per Player Settings", false, 0, "", new Tags
				{
					DoNotSave = true
				});
			}
			PlayerEntry entry = new PlayerEntry();
			entry.Toggle = mod.AddToList(rig.PlayerName + " <#FFF>(" + rig.PlayerId + ")", true, 0, "Toggles the avatar for " + rig.PlayerName + ".", new Tags());
			((ModSetting)entry.Toggle).SavedValueChanged += delegate
			{
				if (toggleOthers.GetValue<bool>())
				{
					rig.Apply(entry.Toggle.GetValue<bool>() ? CustomRig.RigState.Rigged : CustomRig.RigState.Original);
				}
				RigManager.UpdateVisibilityProps();
			};
			entry.ReloadButton = mod.AddToList("   - Reload", false, 0, "Reloads the avatar for " + rig.PlayerName + " <#FFF>upon clicking the button.", new Tags
			{
				DoNotSave = true
			});
			((ModSetting)entry.ReloadButton).CurrentValueChanged += delegate
			{
				if (!RigManager.loadingPlayers.Contains(player.Data.GeneralData.PlayFabMasterId))
				{
					((MelonBase)this).LoggerInstance.Msg("Reloading avatar for " + rig.PlayerName);
					Object.Destroy((Object)(object)rig);
					Patches.loadedPlayers.Remove(player.Data.GeneralData.PlayFabMasterId);
					Patches.ApplyRig(player);
				}
			};
			perPlayerSettings[rig.PlayerId] = entry;
			mod.GetFromFile();
		}
		catch (Exception)
		{
		}
	}

	public void RemovePlayerFromList(Player player)
	{
		string playFabMasterId = player.Data.GeneralData.PlayFabMasterId;
		if (perPlayerSettings.TryGetValue(playFabMasterId, out var value))
		{
			mod.Settings.Remove((ModSetting)(object)value.Toggle);
			mod.Settings.Remove((ModSetting)(object)value.ReloadButton);
			perPlayerSettings.Remove(playFabMasterId);
		}
		if (perPlayerHeader != null && perPlayerSettings.Count == 0)
		{
			mod.Settings.Remove((ModSetting)(object)perPlayerHeader);
			perPlayerHeader = null;
		}
	}

	public void RegeneratePortraits()
	{
		(Type.GetType("RumbleHud.Hud, RumbleHud")?.GetMethod("RegeneratePortraits", BindingFlags.Static | BindingFlags.Public))?.Invoke(null, new object[1] { currentScene == "Gym" });
	}

	private void UpdateAvatarVisibility()
	{
		//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		if (toggleVisibleToOthers == null || toggleInMatch == null || toggleLocal == null)
		{
			return;
		}
		bool flag = (bool)((ModSetting)toggleVisibleToOthers).Value;
		bool flag2 = (bool)((ModSetting)toggleInMatch).Value;
		bool flag3 = (bool)((ModSetting)toggleLocal).Value;
		if (!((Object)(object)localRig == (Object)null))
		{
			bool flag4 = flag3;
			string text = currentScene;
			if ((text == "Map0" || text == "Map1") ? true : false)
			{
				flag4 = flag3 && flag2;
			}
			localRig.Apply(flag4 ? CustomRig.RigState.Rigged : CustomRig.RigState.Original);
			if (currentScene != "Gym" && PhotonNetwork.LocalPlayer != null)
			{
				bool flag5 = flag && flag2;
				Hashtable val = new Hashtable();
				val[Object.op_Implicit("CA_Avatar")] = Object.op_Implicit(flag5);
				PhotonNetwork.LocalPlayer.SetCustomProperties(val, (Hashtable)null, (WebFlags)null);
			}
		}
	}

	public void OnUIInitialized()
	{
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Expected O, but got Unknown
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Expected O, but got Unknown
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected O, but got Unknown
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Expected O, but got Unknown
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0107: Expected O, but got Unknown
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Expected O, but got Unknown
		//IL_0141: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Expected O, but got Unknown
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Expected O, but got Unknown
		//IL_0185: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Expected O, but got Unknown
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Expected O, but got Unknown
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Expected O, but got Unknown
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f8: Expected O, but got Unknown
		//IL_020f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0214: Unknown result type (might be due to invalid IL or missing references)
		//IL_0221: Expected O, but got Unknown
		//IL_0235: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Expected O, but got Unknown
		//IL_0256: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Expected O, but got Unknown
		//IL_0278: Unknown result type (might be due to invalid IL or missing references)
		//IL_027d: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Expected O, but got Unknown
		mod.ModName = "<b><#6A5ACD>Custom Avatars</color></b>";
		mod.ModVersion = "1.4.0";
		mod.SetFolder("CustomAvatars");
		mod.AddToList("Description", "", "Allows custom avatars for you or specific people.", new Tags());
		reloadKeybind = mod.AddToList("Reload Keybind", "R", "The key that reloads your and other's avatars.", new Tags());
		reloadToggle = mod.AddToList("Reload Avatar", false, 0, "Reloads your avatar on toggle.", new Tags
		{
			DoNotSave = true
		});
		mod.AddToList("<b><#114F11>- Avatar Visibility</color></b>", false, 0, "", new Tags
		{
			DoNotSave = true
		});
		toggleLocal = mod.AddToList("Toggle for Self", true, 0, "Toggles whether you see your custom avatar locally. This does not affect what other players see.", new Tags());
		toggleOthers = mod.AddToList("Toggle for Others", true, 0, "Toggles whether you can see other players' custom avatars.", new Tags());
		toggleVisibleToOthers = mod.AddToList("Let Others See My Avatar", true, 0, "Controls whether other players can see your custom avatar. This setting is networked.", new Tags());
		toggleInMatch = mod.AddToList("Toggle In Match", true, 0, "Toggles whether or not you and other players can see your custom avatar in a match. This setting is networked.", new Tags());
		toggleIfNewerVersion = mod.AddToList("Load Higher Version Avatars", false, 0, "Toggles whether or not people that have a higher mod version than you will have their avatars loaded.", new Tags());
		toggleInRockCam = mod.AddToList("Toggle in Rock Cam", true, 0, "Toggles whether or not you can see your custom avatar in Rock Cam or not.\nThis setting takes effect when your avatar is reloaded.", new Tags());
		mod.AddToList("<b><#FFED29>- Statistics</color></b>", false, 0, "", new Tags
		{
			DoNotSave = true
		});
		logAvatarStats = mod.AddToList("Log Avatar Statistics (self)", true, 0, "If enabled, logs mesh info like vertex count, material count, etc. when the local player's avatar is loaded.", new Tags());
		logOtherAvatarStats = mod.AddToList("Log Avatar Statistics (other)", true, 0, "If enabled, logs mesh info like vertex count, material count, etc. when a remote player's avatar is loaded.", new Tags());
		mod.AddToList("<b><#305CDE>- Download & Upload</color></b>", false, 0, "", new Tags
		{
			DoNotSave = true
		});
		downloadLimitMB = mod.AddToList("Max File Download Size", 50, "The max download size for other avatars in MB.", new Tags());
		maxConcurrentDownloads = mod.AddToList("Max Concurrent Downloads", 3, "The maximum number of downloads that can be ran at the same time.", new Tags());
		uploadAvatar = mod.AddToList("Upload Avatar", false, 0, "Uploads the avatar in the folder when the button is clicked and saved.", new Tags
		{
			DoNotSave = true
		});
		((ModSetting)uploadAvatar).SavedValueChanged += delegate
		{
			UploadAvatar();
		};
		((ModSetting)reloadToggle).CurrentValueChanged += delegate
		{
			ApplyAvatars(log: true, clearAll: false);
		};
		((ModSetting)toggleOthers).SavedValueChanged += delegate
		{
			UpdateAllPlayers();
			RigManager.UpdateVisibilityProps();
		};
		((ModSetting)toggleIfNewerVersion).SavedValueChanged += delegate
		{
			UpdateAllPlayers();
		};
		((ModSetting)toggleLocal).SavedValueChanged += delegate
		{
			bool flag = (bool)((ModSetting)toggleLocal).Value;
			UpdateAvatarVisibility();
			if (currentScene == "Gym")
			{
				if (!flag)
				{
					DressingRoom.GetGameObject().GetComponent<DressingRoom>().UpdatePlayerVisuals(true);
				}
				SetObjectsActive();
				PreviewPlayerController.GetGameObject().GetComponent<CustomRig>()?.Apply(flag ? CustomRig.RigState.Rigged : CustomRig.RigState.Original);
			}
			RegeneratePortraits();
		};
		((ModSetting)toggleInMatch).SavedValueChanged += delegate
		{
			string text = currentScene;
			if ((text == "Map0" || text == "Map1") ? true : false)
			{
				UpdateAvatarVisibility();
				RegeneratePortraits();
			}
		};
		((ModSetting)toggleVisibleToOthers).SavedValueChanged += delegate
		{
			if (currentScene != "Gym")
			{
				UpdateAvatarVisibility();
			}
		};
		((ModSetting)logAvatarStats).SavedValueChanged += delegate
		{
			if ((bool)((ModSetting)logAvatarStats).Value)
			{
				((MelonBase)this).LoggerInstance.Msg("Will log on next Avatar Refresh.");
			}
		};
		mod.GetFromFile();
		UI.instance.AddMod(mod);
		void UpdateAllPlayers()
		{
			foreach (KeyValuePair<string, CustomRig> rig in RigManager.rigs)
			{
				if (!(rig.Key == Players.GetLocalPlayer().Data.GeneralData.PlayFabMasterId) && !(rig.Key == "Preview Controller (Dressing Room)") && !(rig.Key == "CloneBending Clone"))
				{
					Player player = ((IEnumerable<Player>)Players.GetAllPlayers().ToArray()).FirstOrDefault((Func<Player, bool>)((Player p) => p.Data.GeneralData.PlayFabMasterId == rig.Key));
					RigManager.ResolveRigState(player, rig.Value);
				}
			}
			RegeneratePortraits();
		}
	}
}
[RegisterTypeInIl2Cpp]
public class CustomRig : MonoBehaviour
{
	public enum RigState
	{
		Original,
		Rigged
	}

	[CompilerGenerated]
	private sealed class <ApplyDefaultBlendshapes>d__36 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CustomRig <>4__this;

		private SkinnedMeshRenderer <renderer>5__1;

		private List<BlendshapeDefault>.Enumerator <>s__2;

		private BlendshapeDefault <blendshape>5__3;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <ApplyDefaultBlendshapes>d__36(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<renderer>5__1 = null;
			<>s__2 = default(List<BlendshapeDefault>.Enumerator);
			<blendshape>5__3 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<renderer>5__1 = (<>4__this.Config.swapOriginalMesh ? <>4__this.MeshRenderer : <>4__this.Root.GetComponentInChildren<SkinnedMeshRenderer>());
				if ((Object)(object)<renderer>5__1 == (Object)null || (Object)(object)<>4__this.MeshRenderer.sharedMesh == (Object)null)
				{
					return false;
				}
				<>s__2 = <>4__this.Config.defaultBlendshapes.GetEnumerator();
				try
				{
					while (<>s__2.MoveNext())
					{
						<blendshape>5__3 = <>s__2.Current;
						if (<blendshape>5__3.index >= 0 && <blendshape>5__3.index < <>4__this.MeshRenderer.sharedMesh.blendShapeCount)
						{
							<renderer>5__1.SetBlendShapeWeight(<blendshape>5__3.index, <blendshape>5__3.weight);
						}
						<blendshape>5__3 = null;
					}
				}
				finally
				{
					((IDisposable)<>s__2).Dispose();
				}
				<>s__2 = default(List<BlendshapeDefault>.Enumerator);
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <AutoBlinkCoroutine>d__37 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CustomRig <>4__this;

		private float <waitTime>5__1;

		private float <blinkDuration>5__2;

		private int <singleIdx>5__3;

		private int <leftIdx>5__4;

		private int <rightIdx>5__5;

		private AvatarDescriptorExport.BlinkType <>s__6;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <AutoBlinkCoroutine>d__37(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
			{
				<>1__state = -1;
				<blinkDuration>5__2 = <>4__this.Config.eyeSettings.blinkSpeed;
				AvatarDescriptorExport.BlinkType blinkType = <>4__this.Config.eyeSettings.blinkType;
				<>s__6 = blinkType;
				switch (<>s__6)
				{
				case AvatarDescriptorExport.BlinkType.Single:
					<singleIdx>5__3 = <>4__this.Config.eyeSettings.blinkBlendshape;
					if (<singleIdx>5__3 >= 0)
					{
						<>2__current = MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<singleIdx>5__3, 100f, <blinkDuration>5__2));
						<>1__state = 2;
						return true;
					}
					break;
				case AvatarDescriptorExport.BlinkType.LeftRight:
					<leftIdx>5__4 = <>4__this.Config.eyeSettings.blinkLeftBlendshape;
					<rightIdx>5__5 = <>4__this.Config.eyeSettings.blinkRightBlendshape;
					if (<leftIdx>5__4 >= 0)
					{
						MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<leftIdx>5__4, 100f, <blinkDuration>5__2));
					}
					if (<rightIdx>5__5 >= 0)
					{
						MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<rightIdx>5__5, 100f, <blinkDuration>5__2));
					}
					<>2__current = (object)new WaitForSeconds(<blinkDuration>5__2);
					<>1__state = 4;
					return true;
				default:
					throw new ArgumentOutOfRangeException();
				case AvatarDescriptorExport.BlinkType.None:
					break;
				}
				break;
			}
			case 2:
				<>1__state = -1;
				<>2__current = MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<singleIdx>5__3, 0f, <blinkDuration>5__2));
				<>1__state = 3;
				return true;
			case 3:
				<>1__state = -1;
				break;
			case 4:
				<>1__state = -1;
				if (<leftIdx>5__4 >= 0)
				{
					MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<leftIdx>5__4, 0f, <blinkDuration>5__2));
				}
				if (<rightIdx>5__5 >= 0)
				{
					MelonCoroutines.Start(<>4__this.BlinkBlendshapeLerp(<rightIdx>5__5, 0f, <blinkDuration>5__2));
				}
				<>2__current = (object)new WaitForSeconds(<blinkDuration>5__2);
				<>1__state = 5;
				return true;
			case 5:
				<>1__state = -1;
				break;
			}
			<waitTime>5__1 = Random.Range(<>4__this.Config.eyeSettings.blinkInterval.x, <>4__this.Config.eyeSettings.blinkInterval.y);
			<>2__current = (object)new WaitForSeconds(<waitTime>5__1);
			<>1__state = 1;
			return true;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <BlinkBlendshapeLerp>d__38 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public int index;

		public float targetWeight;

		public float duration;

		public CustomRig <>4__this;

		private float <startWeight>5__1;

		private float <elapsed>5__2;

		private float <t>5__3;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <BlinkBlendshapeLerp>d__38(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (!Object.op_Implicit((Object)(object)<>4__this.MeshRenderer) || !Object.op_Implicit((Object)(object)<>4__this.MeshRenderer.sharedMesh))
				{
					return false;
				}
				if (index < 0 || index >= <>4__this.MeshRenderer.sharedMesh.blendShapeCount)
				{
					return false;
				}
				try
				{
					<startWeight>5__1 = <>4__this.MeshRenderer.GetBlendShapeWeight(index);
				}
				catch
				{
					return false;
				}
				<elapsed>5__2 = 0f;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if (<elapsed>5__2 < duration)
			{
				<t>5__3 = <elapsed>5__2 / duration;
				<>4__this.MeshRenderer.SetBlendShapeWeight(index, Mathf.Lerp(<startWeight>5__1, targetWeight, <t>5__3));
				<elapsed>5__2 += Time.deltaTime;
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			<>4__this.MeshRenderer.SetBlendShapeWeight(index, targetWeight);
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <FollowEyes>d__30 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public EyeSettings settings;

		public Transform target;

		public float duration;

		public float gain;

		public CustomRig <>4__this;

		private Vector4 <newWeights>5__1;

		private float <targetUp>5__2;

		private float <targetDown>5__3;

		private float <targetLeft>5__4;

		private float <targetRight>5__5;

		private float <currentUp>5__6;

		private float <currentDown>5__7;

		private float <currentLeft>5__8;

		private float <currentRight>5__9;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <FollowEyes>d__30(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)target != (Object)null)
			{
				<newWeights>5__1 = <>4__this.CalculateEyeWeights(<>4__this.Head, target);
				<targetUp>5__2 = <newWeights>5__1.x * gain;
				<targetDown>5__3 = <newWeights>5__1.y * gain;
				<targetLeft>5__4 = <newWeights>5__1.z * gain;
				<targetRight>5__5 = <newWeights>5__1.w * gain;
				<currentUp>5__6 = <>4__this.MeshRenderer.GetBlendShapeWeight(settings.eyeUpBlendshape);
				<currentDown>5__7 = <>4__this.MeshRenderer.GetBlendShapeWeight(settings.eyeDownBlendshape);
				<currentLeft>5__8 = <>4__this.MeshRenderer.GetBlendShapeWeight(settings.eyeLeftBlendshape);
				<currentRight>5__9 = <>4__this.MeshRenderer.GetBlendShapeWeight(settings.eyeRightBlendshape);
				<>4__this.MeshRenderer.SetBlendShapeWeight(settings.eyeUpBlendshape, Mathf.Lerp(<currentUp>5__6, <targetUp>5__2, Time.deltaTime / duration));
				<>4__this.MeshRenderer.SetBlendShapeWeight(settings.eyeDownBlendshape, Mathf.Lerp(<currentDown>5__7, <targetDown>5__3, Time.deltaTime / duration));
				<>4__this.MeshRenderer.SetBlendShapeWeight(settings.eyeLeftBlendshape, Mathf.Lerp(<currentLeft>5__8, <targetLeft>5__4, Time.deltaTime / duration));
				<>4__this.MeshRenderer.SetBlendShapeWeight(settings.eyeRightBlendshape, Mathf.Lerp(<currentRight>5__9, <targetRight>5__5, Time.deltaTime / duration));
				<>2__current = null;
				<>1__state = 1;
				return true;
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public string PlayerId;

	public bool IsLocal;

	public bool IsPreview;

	public string PlayerName;

	public Player Player;

	public string AvatarFilePath;

	public string ModVersion;

	public AvatarDescriptorExport Config;

	public GameObject Root;

	public GameObject PlayerRoot;

	public Transform Head;

	public Animator animator;

	public List<Transform> rigScan;

	public PlayerVoiceSystem voiceSystem;

	public PlayerEyeSystem eyeSystem;

	public LookatAttentionPoint lastAttentionPoint;

	public object lookAtCoroutine;

	public object blinkCoroutine;

	public Material OriginalMaterial;

	public Material OriginalVisualsMaterial;

	public Mesh OriginalMesh;

	public Transform[] OriginalBones;

	public Material[] RigMaterials;

	public Material RigVisualsMaterial;

	public Mesh RigMesh;

	public Transform[] RigBones;

	public SkinnedMeshRenderer MeshRenderer;

	public PlayerVisuals playerVisuals;

	private void Update()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0039: Expected O, but got Unknown
		if ((Object)(object)OriginalMaterial == (Object)null || (Object)(object)OriginalMesh == (Object)null)
		{
			OriginalMaterial = new Material(((Renderer)MeshRenderer).material);
			((Object)OriginalMaterial).hideFlags = (HideFlags)61;
			OriginalMesh = Object.Instantiate<Mesh>(MeshRenderer.sharedMesh);
			((Object)OriginalMesh).hideFlags = (HideFlags)61;
		}
		if (Config == null || !((Object)(object)MeshRenderer != (Object)null))
		{
			return;
		}
		if ((Object)(object)voiceSystem != (Object)null)
		{
			int jawOpenBlendshape = Config.jawOpenBlendshape;
			if (jawOpenBlendshape < MeshRenderer.sharedMesh.blendShapeCount)
			{
				MeshRenderer.SetBlendShapeWeight(jawOpenBlendshape, Mathf.Clamp(voiceSystem.currentJawOpenPercentage * 100f * Config.voiceMultiplier, 0f, 100f));
			}
		}
		if (!((Object)(object)Head != (Object)null) || !((Object)(object)eyeSystem != (Object)null) || !((Object)(object)eyeSystem.CurrentAttentionPoint != (Object)null))
		{
			return;
		}
		EyeSettings eyeSettings = Config.eyeSettings;
		if (eyeSettings.eyeUpBlendshape == -1 || eyeSettings.eyeDownBlendshape == -1 || eyeSettings.eyeLeftBlendshape == -1 || eyeSettings.eyeRightBlendshape == -1)
		{
			return;
		}
		LookatAttentionPoint currentAttentionPoint = eyeSystem.CurrentAttentionPoint;
		if ((Object)(object)lastAttentionPoint != (Object)(object)currentAttentionPoint)
		{
			lastAttentionPoint = currentAttentionPoint;
			if (lookAtCoroutine != null)
			{
				MelonCoroutines.Stop(lookAtCoroutine);
			}
			lookAtCoroutine = MelonCoroutines.Start(FollowEyes(eyeSettings, ((Component)currentAttentionPoint).transform, 0.02f, eyeSettings.eyeGain));
		}
	}

	[IteratorStateMachine(typeof(<FollowEyes>d__30))]
	private IEnumerator FollowEyes(EyeSettings settings, Transform target, float duration, float gain = 1f)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <FollowEyes>d__30(0)
		{
			<>4__this = this,
			settings = settings,
			target = target,
			duration = duration,
			gain = gain
		};
	}

	public Vector4 CalculateEyeWeights(Transform head, Transform target)
	{
		//IL_0002: 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_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: 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_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		Vector3 val = target.position - head.position;
		Vector3 normalized = ((Vector3)(ref val)).normalized;
		Vector3 val2 = head.InverseTransformDirection(normalized);
		float num = Mathf.Clamp01(val2.y) * 100f;
		float num2 = Mathf.Clamp01(0f - val2.y) * 100f;
		float num3 = Mathf.Clamp01(0f - val2.x) * 100f;
		float num4 = Mathf.Clamp01(val2.x) * 100f;
		return new Vector4(num, num2, num3, num4);
	}

	public void CaptureOriginal(string playerId, bool isLocal, SkinnedMeshRenderer renderer, bool log = true)
	{
		if ((Object)(object)renderer == (Object)null)
		{
			if (log)
			{
				((MelonBase)Main.instance).LoggerInstance.Warning("CaptureOriginal: Renderer is null for player " + (playerId ?? "Unknown") + ", skipping.");
			}
			return;
		}
		if ((Object)(object)renderer.sharedMesh == (Object)null)
		{
			if (log)
			{
				((MelonBase)Main.instance).LoggerInstance.Warning("CaptureOriginal: SharedMesh is null for player " + (playerId ?? "Unknown") + ", skipping.");
			}
			return;
		}
		PlayerId = playerId;
		IsLocal = isLocal;
		Player val = ((IEnumerable<Player>)Players.GetAllPlayers().ToArray()).FirstOrDefault((Func<Player, bool>)((Player p) => p.Data.GeneralData.PlayFabMasterId == playerId));
		if (val != null)
		{
			Player = val;
		}
		Transform parent = ((Component)renderer).transform.parent;
		if ((Object)(object)parent != (Object)null && parent.childCount > 1)
		{
			PlayerRoot = ((Component)parent.GetChild(1)).gameObject;
			playerVisuals = ((Component)parent).GetComponent<PlayerVisuals>();
			if ((Object)(object)playerVisuals != (Object)null && isLocal)
			{
			}
			animator = ((Component)parent).GetComponent<Animator>();
			if ((Object)(object)animator != (Object)null)
			{
				Head = RigManager.GetBone(animator, (HumanBodyBones)10);
			}
			OriginalMesh = Object.Instantiate<Mesh>(renderer.sharedMesh);
			((Object)OriginalMesh).hideFlags = (HideFlags)61;
			if ((Object)(object)((Renderer)renderer).material != (Object)null)
			{
				OriginalMaterial = Object.Instantiate<Material>(((Renderer)renderer).material);
				((Object)OriginalMaterial).hideFlags = (HideFlags)61;
			}
			else if (log)
			{
				((MelonBase)Main.instance).LoggerInstance.Warning("CaptureOriginal: Renderer material is null.");
			}
			OriginalBones = Il2CppArrayBase<Transform>.op_Implicit((Il2CppArrayBase<Transform>)(object)(renderer.bones ?? Il2CppReferenceArray<Transform>.op_Implicit(Array.Empty<Transform>())));
			MeshRenderer = renderer;
			if (!IsPreview)
			{
				Transform child = ((Component)renderer).transform.parent.parent.GetChild(2).GetChild(0).GetChild(0);
				voiceSystem = ((Component)child.GetChild(2)).GetComponent<PlayerVoiceSystem>();
				eyeSystem = ((Component)child).GetComponent<PlayerEyeSystem>();
			}
		}
		else if (log)
		{
			((MelonBase)Main.instance).LoggerInstance.Warning("CaptureOriginal: Could not find 'Skelington' (index 1) under renderer's parent for player " + (playerId ?? "Unknown") + ".");
		}
	}

	public void CaptureRig(GameObject rig)
	{
		Root = rig;
		Animator component = rig.GetComponent<Animator>();
		if ((bool)((ModSetting)Main.instance.logAvatarStats).SavedValue || (!IsLocal && (bool)((ModSetting)Main.instance.logOtherAvatarStats).SavedValue))
		{
			if ((Object)(object)component == (Object)null)
			{
				((MelonBase)Main.instance).LoggerInstance.Msg("Rig has no Animator, using raw transform capture.");
			}
			else if (!component.isHuman)
			{
				((MelonBase)Main.instance).LoggerInstance.Msg("Rig Animator is not humanoid, using name-based capture.");
			}
		}
		RigBones = Il2CppArrayBase<Transform>.op_Implicit(rig.GetComponentsInChildren<Transform>());
		rigScan = RigManager.Scan(rig.transform);
	}

	public List<GrabbableObject> ParseGrabbableObjectsRecursive(Transform root, Player player)
	{
		List<GrabbableObject> list = new List<GrabbableObject>();
		for (int i = 0; i < root.childCount; i++)
		{
			Transform child = root.GetChild(i);
			if ((Object)(object)((Component)child).GetComponent<Collider>() != (Object)null && ((Object)child).name.Contains(":Grabbable"))
			{
				GrabbableObject grabbableObject = ((Component)child).gameObject.AddComponent<GrabbableObject>();
				MelonCoroutines.Start(grabbableObject.Init(player));
				((Component)child).gameObject.layer = LayerMask.NameToLayer("InteractionBase");
				list.Add(grabbableObject);
			}
			list.AddRange(ParseGrabbableObjectsRecursive(child, player));
		}
		return list;
	}

	public void Apply(RigState state)
	{
		try
		{
			switch (state)
			{
			case RigState.Original:
			{
				((Renderer)MeshRenderer).materials = Il2CppReferenceArray<Material>.op_Implicit((Material[])(object)new Material[1] { OriginalMaterial });
				MeshRenderer.bones = Il2CppReferenceArray<Transform>.op_Implicit(OriginalBones);
				MeshRenderer.sharedMesh = OriginalMesh;
				Transform[] rigBones2 = RigBones;
				foreach (Transform val2 in rigBones2)
				{
					((Component)val2).gameObject.SetActive(false);
				}
				if (blinkCoroutine != null)
				{
					MelonCoroutines.Stop(blinkCoroutine);
				}
				blinkCoroutine = null;
				break;
			}
			case RigState.Rigged:
			{
				if (Config.swapOriginalMesh && (bool)((ModSetting)Main.instance.toggleInRockCam).SavedValue)
				{
					((Renderer)MeshRenderer).materials = Il2CppReferenceArray<Material>.op_Implicit(RigMaterials);
					MeshRenderer.bones = Il2CppReferenceArray<Transform>.op_Implicit(RigBones);
					MeshRenderer.sharedMesh = RigMesh;
				}
				Root.SetActive(true);
				if (IsLocal)
				{
					if (!(bool)((ModSetting)Main.instance.toggleInRockCam).SavedValue)
					{
						((Renderer)MeshRenderer).shadowCastingMode = (ShadowCastingMode)0;
						((Component)MeshRenderer).gameObject.layer = 2;
						Camera camera = Singleton<PlayerManager>.instance.LocalPlayer.Controller.GetSubsystem<PlayerCamera>().camera;
						camera.cullingMask &= -5;
						Camera component = RecordingCamera.GetGameObject().GetComponent<Camera>();
						component.cullingMask &= -5;
						foreach (Renderer componentsInChild in Root.GetComponentsInChildren<Renderer>())
						{
							((Component)componentsInChild).gameObject.layer = 23;
						}
					}
					else
					{
						((Renderer)MeshRenderer).shadowCastingMode = (ShadowCastingMode)1;
						((Component)MeshRenderer).gameObject.layer = 23;
						Camera camera2 = Singleton<PlayerManager>.instance.LocalPlayer.Controller.GetSubsystem<PlayerCamera>().camera;
						camera2.cullingMask |= 4;
						Camera component2 = RecordingCamera.GetGameObject().GetComponent<Camera>();
						component2.cullingMask |= 4;
					}
				}
				Transform[] rigBones = RigBones;
				foreach (Transform val in rigBones)
				{
					((Component)val).gameObject.SetActive(true);
				}
				if (Config != null)
				{
					if (Config.swapOriginalMesh)
					{
						MelonCoroutines.Start(ApplyDefaultBlendshapes());
					}
					if (Config.eyeSettings.blinkType != 0)
					{
						if (blinkCoroutine != null)
						{
							MelonCoroutines.Stop(blinkCoroutine);
						}
						blinkCoroutine = MelonCoroutines.Start(AutoBlinkCoroutine());
					}
				}
				Player assignedPlayer = ((Component)this).GetComponent<PlayerController>().assignedPlayer;
				if (!Main.instance.perPlayerSettings.ContainsKey(assignedPlayer.Data.GeneralData.PlayFabMasterId) && !IsLocal && !IsPreview)
				{
					Main.instance.AddPlayerToList(assignedPlayer);
				}
				break;
			}
			default:
				throw new ArgumentOutOfRangeException("state", state, null);
			}
		}
		catch
		{
		}
	}

	[IteratorStateMachine(typeof(<ApplyDefaultBlendshapes>d__36))]
	private IEnumerator ApplyDefaultBlendshapes()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <ApplyDefaultBlendshapes>d__36(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<AutoBlinkCoroutine>d__37))]
	private IEnumerator AutoBlinkCoroutine()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <AutoBlinkCoroutine>d__37(0)
		{
			<>4__this = this
		};
	}

	[IteratorStateMachine(typeof(<BlinkBlendshapeLerp>d__38))]
	private IEnumerator BlinkBlendshapeLerp(int index, float targetWeight, float duration)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <BlinkBlendshapeLerp>d__38(0)
		{
			<>4__this = this,
			index = index,
			targetWeight = targetWeight,
			duration = duration
		};
	}

	public void OnDestroy()
	{
		Apply(RigState.Original);
		if (Object.op_Implicit((Object)(object)RigMesh))
		{
			Object.Destroy((Object)(object)RigMesh);
		}
		if (Object.op_Implicit((Object)(object)Root))
		{
			Object.Destroy((Object)(object)Root);
		}
		if (RigMaterials != null)
		{
			Material[] rigMaterials = RigMaterials;
			foreach (Material val in rigMaterials)
			{
				Object.Destroy((Object)(object)val);
			}
		}
		if (blinkCoroutine != null)
		{
			MelonCoroutines.Stop(blinkCoroutine);
			blinkCoroutine = null;
		}
	}
}
public class PlayerEntry
{
	[CompilerGenerated]
	private sealed class <GetAllSettings>d__2 : IEnumerable<ModSetting>, IEnumerable, IEnumerator<ModSetting>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private ModSetting <>2__current;

		private int <>l__initialThreadId;

		public PlayerEntry <>4__this;

		ModSetting IEnumerator<ModSetting>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <GetAllSettings>d__2(int <>1__state)
		{
			this.<>1__state = <>1__state;
			<>l__initialThreadId = Environment.CurrentManagedThreadId;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (<>4__this.Toggle != null)
				{
					<>2__current = (ModSetting)(object)<>4__this.Toggle;
					<>1__state = 1;
					return true;
				}
				goto IL_005e;
			case 1:
				<>1__state = -1;
				goto IL_005e;
			case 2:
				{
					<>1__state = -1;
					break;
				}
				IL_005e:
				if (<>4__this.ReloadButton != null)
				{
					<>2__current = (ModSetting)(object)<>4__this.ReloadButton;
					<>1__state = 2;
					return true;
				}
				break;
			}
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}

		[DebuggerHidden]
		IEnumerator<ModSetting> IEnumerable<ModSetting>.GetEnumerator()
		{
			<GetAllSettings>d__2 result;
			if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
			{
				<>1__state = 0;
				result = this;
			}
			else
			{
				result = new <GetAllSettings>d__2(0)
				{
					<>4__this = <>4__this
				};
			}
			return result;
		}

		[DebuggerHidden]
		IEnumerator IEnumerable.GetEnumerator()
		{
			return ((IEnumerable<ModSetting>)this).GetEnumerator();
		}
	}

	public ModSetting<bool> Toggle;

	public ModSetting<bool> ReloadButton;

	[IteratorStateMachine(typeof(<GetAllSettings>d__2))]
	public IEnumerable<ModSetting> GetAllSettings()
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <GetAllSettings>d__2(-2)
		{
			<>4__this = this
		};
	}
}
public class Patches
{
	[HarmonyPatch(typeof(PlayerController), "Initialize", new Type[] { typeof(Player) })]
	public static class PlayerSpawn
	{
		private static void Postfix(ref PlayerController __instance, ref Player player)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			string playFabMasterId = player.Data.GeneralData.PlayFabMasterId;
			if ((int)__instance.controllerType != 1 && !loadedPlayers.Contains(playFabMasterId))
			{
				if (!loadedPlayers.Contains(playFabMasterId))
				{
					loadedPlayers.Add(playFabMasterId);
				}
				ApplyRig(player);
			}
		}
	}

	[HarmonyPatch(typeof(PlayerController), "OnDestroy")]
	public static class PlayerRemove
	{
		private static void Prefix(PlayerController __instance)
		{
			if (!Main.instance.sceneInitialized || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			Player assignedPlayer = __instance.assignedPlayer;
			object obj;
			if (assignedPlayer == null)
			{
				obj = null;
			}
			else
			{
				PlayerData data = assignedPlayer.Data;
				obj = ((data != null) ? data.GeneralData : null);
			}
			if (obj == null)
			{
				return;
			}
			string playFabMasterId = assignedPlayer.Data.GeneralData.PlayFabMasterId;
			if (RigManager.rigs.TryGetValue(playFabMasterId, out var value))
			{
				if ((Object)(object)value != (Object)null)
				{
					Object.Destroy((Object)(object)value.Root);
					Main.instance.RemovePlayerFromList(assignedPlayer);
				}
				RigManager.rigs.Remove(playFabMasterId);
				loadedPlayers.Remove(playFabMasterId);
			}
		}
	}

	[HarmonyPatch(typeof(DressingRoom), "UpdatePlayerVisuals")]
	public static class DressingRoomVisuals
	{
		private static bool Prefix(bool saveChanges)
		{
			return !IsEnabled();
		}

		private static void Postfix(bool saveChanges)
		{
			if (!IsEnabled())
			{
				Player localPlayer = Singleton<PlayerManager>.instance.LocalPlayer;
				PlayerController val = ((localPlayer != null) ? localPlayer.Controller : null);
				CustomRig customRig = default(CustomRig);
				if (val != null && !((Component)val).TryGetComponent<CustomRig>(ref customRig))
				{
				}
			}
		}

		private static bool IsEnabled()
		{
			if (!Main.instance.sceneInitialized)
			{
				return false;
			}
			CustomRig localRig = Main.instance.localRig;
			if ((Object)(object)localRig == (Object)null)
			{
				return false;
			}
			ModSetting<bool> toggleLocal = Main.instance.toggleLocal;
			return (bool)(((toggleLocal != null) ? ((ModSetting)toggleLocal).SavedValue : null) ?? ((object)false)) && localRig.Config.swapOriginalMesh;
		}
	}

	[CompilerGenerated]
	private sealed class <CheckForMod>d__2 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public Player player;

		private Player <photonPlayer>5__1;

		private Hashtable <props>5__2;

		private Object <remoteVerObj>5__3;

		private string <remoteVer>5__4;

		private GameObject <tagClone>5__5;

		private CustomRig <rig>5__6;

		private Stream <stream>5__7;

		private MemoryStream <ms>5__8;

		private AssetBundle <bundle>5__9;

		private Sprite <tagIcon>5__10;

		private GameObject <tag>5__11;

		private SpriteRenderer <renderer>5__12;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <CheckForMod>d__2(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<photonPlayer>5__1 = null;
			<props>5__2 = null;
			<remoteVerObj>5__3 = null;
			<remoteVer>5__4 = null;
			<tagClone>5__5 = null;
			<rig>5__6 = null;
			<stream>5__7 = null;
			<ms>5__8 = null;
			<bundle>5__9 = null;
			<tagIcon>5__10 = null;
			<tag>5__11 = null;
			<renderer>5__12 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				Room currentRoom = PhotonNetwork.CurrentRoom;
				<photonPlayer>5__1 = ((currentRoom != null) ? currentRoom.GetPlayer((int)player.Data.GeneralData.ActorNo, false) : null);
				Player obj = <photonPlayer>5__1;
				<props>5__2 = ((obj != null) ? obj.CustomProperties : null);
				if (<props>5__2 != null)
				{
					if (((Dictionary<Object, Object>)(object)<props>5__2).TryGetValue(Object.op_Implicit("CA_ModVersion"), ref <remoteVerObj>5__3) && ((Dictionary<Object, Object>)(object)PhotonNetwork.LocalPlayer.CustomProperties).ContainsKey(Object.op_Implicit("CA_ModVersion")))
					{
						Object obj2 = <remoteVerObj>5__3;
						<remoteVer>5__4 = ((obj2 != null) ? obj2.ToString() : null) ?? "Unknown";
						if ((Object)(object)Main.instance.tagObject == (Object)null)
						{
							<stream>5__7 = Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomAvatars.AssetBundles.avatarthingies");
							try
							{
								<ms>5__8 = new MemoryStream();
								try
								{
									<stream>5__7.CopyTo(<ms>5__8);
									<bundle>5__9 = AssetBundle.LoadFromMemory(Il2CppStructArray<byte>.op_Implicit(<ms>5__8.ToArray()));
									<tagIcon>5__10 = <bundle>5__9.LoadAsset<Sprite>("icon");
									<tag>5__11 = new GameObject("CustomAvatarTag");
									<renderer>5__12 = <tag>5__11.AddComponent<SpriteRenderer>();
									<renderer>5__12.sprite = <tagIcon>5__10;
									Object.DontDestroyOnLoad((Object)(object)<tag>5__11);
									<tag>5__11.SetActive(false);
									Main.instance.tagObject = <tag>5__11;
								}
								finally
								{
									if (<ms>5__8 != null)
									{
										((IDisposable)<ms>5__8).Dispose();
									}
								}
							}
							finally
							{
								if (<stream>5__7 != null)
								{
									((IDisposable)<stream>5__7).Dispose();
								}
							}
							<stream>5__7 = null;
							<ms>5__8 = null;
							<bundle>5__9 = null;
							<tagIcon>5__10 = null;
							<tag>5__11 = null;
							<renderer>5__12 = null;
						}
						GameObject tagObject = Main.instance.tagObject;
						PlayerController controller = player.Controller;
						<tagClone>5__5 = Object.Instantiate<GameObject>(tagObject, (controller != null) ? ((Component)controller).transform.GetChild(9) : null);
						<tagClone>5__5.SetActive(true);
						((Object)<tagClone>5__5).name = "CustomAvatarTag";
						<tagClone>5__5.transform.localScale = Vector3.one * 0.04f;
						<tagClone>5__5.transform.localPosition = new Vector3(0.2301f, -0.1633f, 0f);
						PlayerController controller2 = player.Controller;
						if (controller2 != null && ((Component)controller2).TryGetComponent<CustomRig>(ref <rig>5__6))
						{
							<rig>5__6.ModVersion = <remoteVer>5__4;
						}
						<remoteVer>5__4 = null;
						<tagClone>5__5 = null;
						<rig>5__6 = null;
					}
					<remoteVerObj>5__3 = null;
				}
				return false;
			}
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public static List<string> loadedPlayers = new List<string>();

	public static void ApplyRig(Player player)
	{
		MelonCoroutines.Start(RemoteAvatarLoader.PlayerHasAvatar(player.Data.GeneralData.PlayFabMasterId, delegate((bool hasAvatar, string returnedSha) avatarDetails)
		{
			if (!avatarDetails.hasAvatar)
			{
				MelonCoroutines.Start(CheckForMod(player));
			}
			else
			{
				PlayerVisuals subsystem = player.Controller.GetSubsystem<PlayerVisuals>();
				CustomRig customRig = ((Component)player.Controller).gameObject.AddComponent<CustomRig>();
				customRig.CaptureOriginal(player.Data.GeneralData.PlayFabMasterId, isLocal: false, subsystem.renderer);
				((Renderer)subsystem.renderer).material = Main.poseGhostMaterial;
				MelonCoroutines.Start(RigManager.LoadRigForPlayer(player, delegate
				{
					MelonCoroutines.Start(RigManager.FixHUDCamera(player.Data.GeneralData.PlayFabMasterId.Split(new char[1] { '_' })[0]));
					RigManager.UpdateVisibilityProps();
					MelonCoroutines.Start(CheckForMod(player));
				}, log: true, avatarDetails.returnedSha));
			}
		}));
	}

	[IteratorStateMachine(typeof(<CheckForMod>d__2))]
	private static IEnumerator CheckForMod(Player player)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <CheckForMod>d__2(0)
		{
			player = player
		};
	}
}
public class RemoteAvatarLoader
{
	[CompilerGenerated]
	private sealed class <>c__DisplayClass16_0
	{
		public string sha;

		internal void <UploadBundleCoroutine>b__0(string s)
		{
			sha = s;
		}
	}

	[CompilerGenerated]
	private sealed class <>c__DisplayClass18_0
	{
		public Action<(bool hasAvatar, string returnedSha)> callback;

		internal void <PlayerHasAvatar>b__0(string sha)
		{
			callback((!string.IsNullOrEmpty(sha), sha));
		}
	}

	[CompilerGenerated]
	private sealed class <DownloadToFile>d__21 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string masterId;

		public string savePath;

		private string <metaUrl>5__1;

		private UnityWebRequest <metaReq>5__2;

		private UnityWebRequest <req>5__3;

		private Il2CppStructArray<byte> <bytes>5__4;

		private string <json>5__5;

		private int <sizeIndex>5__6;

		private int <endIndex>5__7;

		private string <sizeStr>5__8;

		private int <fileSizeBytes>5__9;

		private int <maxDownloadBytes>5__10;

		private Exception <e>5__11;

		private Il2CppStructArray<byte> <data>5__12;

		private byte[] <encrypted>5__13;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DownloadToFile>d__21(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<metaUrl>5__1 = null;
			<metaReq>5__2 = null;
			<req>5__3 = null;
			<bytes>5__4 = null;
			<json>5__5 = null;
			<sizeStr>5__8 = null;
			<e>5__11 = null;
			<data>5__12 = null;
			<encrypted>5__13 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Invalid comparison between Unknown and I4
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Invalid comparison between Unknown and I4
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (!_downloadingPlayers.Add(masterId))
				{
					((MelonBase)Main.instance).LoggerInstance.Warning("Player " + masterId + " is already being downloaded.");
					return false;
				}
				<metaUrl>5__1 = "https://api.github.com/repos/xLoadingx/custom-avatars/contents/avatars/" + Uri.EscapeDataString(masterId.Split(new char[1] { '_' })[0]) + "?ref=main";
				<metaReq>5__2 = UnityWebRequest.Get(<metaUrl>5__1);
				SetGhHeaders(<metaReq>5__2, wantRaw: false);
				<>2__current = <metaReq>5__2.SendWebRequest();
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if ((int)<metaReq>5__2.result != 1)
				{
					((MelonBase)Main.instance).LoggerInstance.Error("Metadata fetch failed for " + masterId + ": " + <metaReq>5__2.error);
					<metaReq>5__2.Dispose();
					_downloadingPlayers.Remove(masterId);
					return false;
				}
				try
				{
					DownloadHandler downloadHandler = <metaReq>5__2.downloadHandler;
					<bytes>5__4 = ((downloadHandler != null) ? downloadHandler.data : null);
					if (<bytes>5__4 == null || ((Il2CppArrayBase<byte>)(object)<bytes>5__4).Length == 0)
					{
						<metaReq>5__2.Dispose();
						_downloadingPlayers.Remove(masterId);
						return false;
					}
					<json>5__5 = Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)<bytes>5__4));
					<sizeIndex>5__6 = <json>5__5.IndexOf("\"size\":", StringComparison.Ordinal);
					if (<sizeIndex>5__6 >= 0)
					{
						<sizeIndex>5__6 += 7;
						<endIndex>5__7 = <json>5__5.IndexOfAny(new char[2] { ',', '}' }, <sizeIndex>5__6);
						<sizeStr>5__8 = <json>5__5.Substring(<sizeIndex>5__6, <endIndex>5__7 - <sizeIndex>5__6).Trim();
						if (int.TryParse(<sizeStr>5__8, out <fileSizeBytes>5__9))
						{
							<maxDownloadBytes>5__10 = (int)((ModSetting)Main.instance.downloadLimitMB).SavedValue * 1024 * 1024;
							if (<fileSizeBytes>5__9 > <maxDownloadBytes>5__10)
							{
								((MelonBase)Main.instance).LoggerInstance.Warning($"Download skipped: {<fileSizeBytes>5__9 / 1048576} MB exceeds limit of {<maxDownloadBytes>5__10 / 1048576} MB.");
								<metaReq>5__2.Dispose();
								_downloadingPlayers.Remove(masterId);
								return false;
							}
						}
						<sizeStr>5__8 = null;
					}
					<bytes>5__4 = null;
					<json>5__5 = null;
				}
				catch (Exception ex)
				{
					<e>5__11 = ex;
					((MelonBase)Main.instance).LoggerInstance.Error("Error parsing metadata for " + masterId + ": " + <e>5__11.Message);
					<metaReq>5__2.Dispose();
					_downloadingPlayers.Remove(masterId);
					return false;
				}
				<metaReq>5__2.Dispose();
				<req>5__3 = UnityWebRequest.Get(GhUrl(masterId.Split(new char[1] { '_' })[0]));
				SetGhHeaders(<req>5__3, wantRaw: true);
				<>2__current = <req>5__3.SendWebRequest();
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				if ((int)<req>5__3.result != 1)
				{
					((MelonBase)Main.instance).LoggerInstance.Error("Download failed for " + masterId + ": " + <req>5__3.error);
				}
				else
				{
					<data>5__12 = <req>5__3.downloadHandler.data;
					if (<data>5__12 == null || ((Il2CppArrayBase<byte>)(object)<data>5__12).Length < 16)
					{
						((MelonBase)Main.instance).LoggerInstance.Error("Blocked: " + masterId + " file too small to be a valid AssetBundle.");
						_downloadingPlayers.Remove(masterId);
						<req>5__3.Dispose();
						return false;
					}
					<encrypted>5__13 = XorCrypt(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)<data>5__12), 90);
					File.WriteAllBytes(savePath, <encrypted>5__13);
					<data>5__12 = null;
					<encrypted>5__13 = null;
				}
				_downloadingPlayers.Remove(masterId);
				<req>5__3.Dispose();
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <GetSha>d__19 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string masterId;

		public Action<string> cb;

		public bool log;

		private string <url>5__1;

		private UnityWebRequest <req>5__2;

		private Il2CppStructArray<byte> <data>5__3;

		private string <txt>5__4;

		private int <i>5__5;

		private int <j>5__6;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <GetSha>d__19(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<url>5__1 = null;
			<req>5__2 = null;
			<data>5__3 = null;
			<txt>5__4 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Invalid comparison between Unknown and I4
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (log)
				{
					((MelonBase)Main.instance).LoggerInstance.Msg("Fetching remote SHA for masterId " + masterId + "...");
				}
				<url>5__1 = "https://api.github.com/repos/xLoadingx/custom-avatars/contents/avatars/" + Uri.EscapeDataString(masterId) + "?ref=main";
				<req>5__2 = UnityWebRequest.Get(<url>5__1);
				SetGhHeaders(<req>5__2, wantRaw: false);
				<>2__current = <req>5__2.SendWebRequest();
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				if (<req>5__2.responseCode == 404)
				{
					<req>5__2.Dispose();
					cb(null);
					return false;
				}
				if (log)
				{
					((MelonBase)Main.instance).LoggerInstance.Msg($"GitHub responded {<req>5__2.responseCode}: {<req>5__2.result}");
				}
				if ((int)<req>5__2.result != 1)
				{
					((MelonBase)Main.instance).LoggerInstance.Error($"Web request completed unsuccessfully | ERROR {<req>5__2.responseCode} | {<req>5__2.error}");
					<req>5__2.Dispose();
					cb(null);
					return false;
				}
				DownloadHandler downloadHandler = <req>5__2.downloadHandler;
				<data>5__3 = ((downloadHandler != null) ? downloadHandler.data : null);
				<req>5__2.Dispose();
				if (<data>5__3 == null || ((Il2CppArrayBase<byte>)(object)<data>5__3).Length == 0)
				{
					cb(null);
					return false;
				}
				<txt>5__4 = Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)<data>5__3));
				<i>5__5 = <txt>5__4.IndexOf("\"sha\":\"", StringComparison.Ordinal);
				if (<i>5__5 < 0)
				{
					cb(null);
					return false;
				}
				<i>5__5 += 7;
				<j>5__6 = <txt>5__4.IndexOf('"', <i>5__5);
				cb((<j>5__6 > <i>5__5) ? <txt>5__4.Substring(<i>5__5, <j>5__6 - <i>5__5) : null);
				return false;
			}
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <PlayerHasAvatar>d__18 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string masterId;

		public Action<(bool hasAvatar, string returnedSha)> callback;

		private <>c__DisplayClass18_0 <>8__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <PlayerHasAvatar>d__18(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>8__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass18_0();
				<>8__1.callback = callback;
				<>2__current = MelonCoroutines.Start(GetSha(masterId, delegate(string sha)
				{
					<>8__1.callback((!string.IsNullOrEmpty(sha), sha));
				}));
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <SendAudit>d__14 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string tag;

		public string jsonPayload;

		private string <url>5__1;

		private string <body>5__2;

		private UnityWebRequest <req>5__3;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <SendAudit>d__14(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<url>5__1 = null;
			<body>5__2 = null;
			<req>5__3 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<url>5__1 = UploadUrlForPath($"logs/{DateTime.UtcNow:yyyy-MM-dd}/{Guid.NewGuid():N}.json");
				<body>5__2 = "{\"message\":\"log:" + tag + "\",\"content\":\"" + Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonPayload)) + "\",\"branch\":\"main\"}";
				<req>5__3 = new UnityWebRequest(<url>5__1, "PUT");
				<req>5__3.uploadHandler = (UploadHandler)new UploadHandlerRaw(Il2CppStructArray<byte>.op_Implicit(Encoding.UTF8.GetBytes(<body>5__2)));
				<req>5__3.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				<req>5__3.SetRequestHeader("Content-Type", "application/json");
				SetGhHeaders(<req>5__3, wantRaw: false);
				<>2__current = <req>5__3.SendWebRequest();
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				<req>5__3.Dispose();
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <UploadBundleCoroutine>d__16 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public string masterId;

		public string path;

		public Action onStartUpload;

		public Action<bool, bool> done;

		public Action<float> onProgress;

		public TextMeshPro serverStatusText;

		private <>c__DisplayClass16_0 <>8__1;

		private GeneralData <data>5__2;

		private byte[] <bytes>5__3;

		private byte[] <encryped>5__4;

		private string <body>5__5;

		private string <url>5__6;

		private UnityWebRequest <req>5__7;

		private UnityWebRequestAsyncOperation <op>5__8;

		private bool <ok>5__9;

		private Exception <e>5__10;

		private Il2CppStructArray<byte> <errBytes>5__11;

		private string <errTxt>5__12;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <UploadBundleCoroutine>d__16(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>8__1 = null;
			<data>5__2 = null;
			<bytes>5__3 = null;
			<encryped>5__4 = null;
			<body>5__5 = null;
			<url>5__6 = null;
			<req>5__7 = null;
			<op>5__8 = null;
			<e>5__10 = null;
			<errBytes>5__11 = null;
			<errTxt>5__12 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_015f: Unknown result type (might be due to