Decompiled source of CustomAvatars v1.3.2

Mods/CustomAvatars.dll

Decompiled a month 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 System.Threading.Tasks;
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.Players;
using Il2CppRUMBLE.Players.Scaling;
using Il2CppRUMBLE.Players.Subsystems;
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;
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.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Main), "CustomAvatars", "1.3.2", "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("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b00f2204f7b9a43f036e5d9737e3272e5ddb0e0a")]
[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)
	{
		if (!floats.TryGetValue(name, out var value))
		{
			return 0f;
		}
		return value;
	}
}
[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.3.2";
}
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
{
	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()
	{
		Calls.onMapInitialized += Initialize;
		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)
			{
			}
		}
	}

	public void Initialize()
	{
		//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_05bf: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Expected O, but got Unknown
		//IL_026a: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0289: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0321: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_0393: Unknown result type (might be due to invalid IL or missing references)
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_041c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0421: Unknown result type (might be due to invalid IL or missing references)
		//IL_0426: Unknown result type (might be due to invalid IL or missing references)
		//IL_0486: Unknown result type (might be due to invalid IL or missing references)
		//IL_048b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_050f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0514: Unknown result type (might be due to invalid IL or missing references)
		//IL_0519: Unknown result type (might be due to invalid IL or missing references)
		//IL_055b: Unknown result type (might be due to invalid IL or missing references)
		//IL_057a: Unknown result type (might be due to invalid IL or missing references)
		RigManager.ClearRigs();
		lastProps.Clear();
		Directory.CreateDirectory(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars", "Opponents"));
		ApplyAvatars();
		if (currentScene == "Gym" && !sceneInitialized)
		{
			tryoutModeButton = TryOutModePanel.GetGameObject();
			uploadAvatarButton = Object.Instantiate<GameObject>(tryoutModeButton, tryoutModeButton.transform.parent, false);
			((Object)uploadAvatarButton).name = "Upload Avatar Panel";
			uploadAvatarButton.transform.localPosition = new Vector3(0.1069f, 0.1962f, -0.1014f);
			refreshAvatarButton = Object.Instantiate<GameObject>(tryoutModeButton, tryoutModeButton.transform.parent, false);
			((Object)refreshAvatarButton).name = "Refresh Avatar Panel";
			refreshAvatarButton.transform.localPosition = new Vector3(-0.1164f, 0.1962f, -0.1014f);
			InteractionButton component = ((Component)refreshAvatarButton.transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>();
			((UnityEventBase)component.onPressed).RemoveAllListeners();
			component.onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
			{
				if ((bool)((ModSetting)toggleLocal).SavedValue)
				{
					Initialize();
				}
			}));
			((InteractionBase)component).interactionAnimParameter = "nan";
			((InteractionBase)component).InteractionAnimParameterL = "nan";
			((InteractionBase)component).InteractionAnimParameterR = "nan";
			InteractionButton component2 = ((Component)uploadAvatarButton.transform.GetChild(1).GetChild(0)).GetComponent<InteractionButton>();
			((UnityEventBase)component2.onPressed).RemoveAllListeners();
			component2.onPressed.AddListener(UnityAction.op_Implicit((Action)delegate
			{
				UploadAvatar();
			}));
			TextMeshPro component3 = ((Component)refreshAvatarButton.transform.GetChild(1).GetChild(1)).GetComponent<TextMeshPro>();
			Object.Destroy((Object)(object)((Component)component3.transform).GetComponent<LocalizedTextTMPro>());
			((TMP_Text)component3).m_text = "Refresh Avatar";
			((TMP_Text)component3).fontSize = 0.25f;
			((TMP_Text)component3).ForceMeshUpdate(false, false);
			TextMeshPro component4 = ((Component)uploadAvatarButton.transform.GetChild(1).GetChild(1)).GetComponent<TextMeshPro>();
			Object.Destroy((Object)(object)((Component)component4.transform).GetComponent<LocalizedTextTMPro>());
			((TMP_Text)component4).m_text = "Upload Avatar";
			((TMP_Text)component4).fontSize = 0.25f;
			((TMP_Text)component4).ForceMeshUpdate(false, false);
			avatarOptimizationParent = new GameObject("AvatarDetails");
			avatarOptimizationParent.transform.localPosition = new Vector3(-3.5418f, 1.2327f, -0.8255f);
			avatarOptimizationParent.transform.localScale = Vector3.one * 0.5f;
			avatarOptimizationParent.transform.localRotation = Quaternion.Euler(6.3636f, 241.8925f, 0f);
			uploadProgressBar = Object.Instantiate<GameObject>(StatusBar.GetGameObject(), avatarOptimizationParent.transform, false);
			((Object)uploadProgressBar).name = "Upload Progress Bar";
			uploadProgressBar.transform.localScale = new Vector3(0.8562f, 0.0544f, 0.854f);
			uploadProgressBar.transform.localPosition = new Vector3(-1.9034f, 0.2507f, -0.4614f);
			uploadProgressBar.transform.localRotation = Quaternion.Euler(354.8412f, 324.0485f, 3.7311f);
			((Renderer)uploadProgressBar.GetComponent<MeshRenderer>()).material.SetFloat("_RC_Target", 1f);
			uploadProgressBar.SetActive(false);
			GameObject obj = Create.NewText("GOOD", 1f, new Color(0f, 0.5f, 0f), Vector3.zero, Quaternion.identity);
			((Object)obj).name = "Summary";
			obj.transform.SetParent(avatarOptimizationParent.transform, false);
			obj.transform.localPosition = new Vector3(0f, 0.0919f, 0f);
			((TMP_Text)obj.GetComponent<TextMeshPro>()).enableWordWrapping = false;
			((TMP_Text)obj.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
			GameObject obj2 = Create.NewText("0 verts, 0 mat(s), 0 texture(s)", 1f, new Color(0f, 0.5f, 0f), Vector3.zero, Quaternion.identity);
			((Object)obj2).name = "Details";
			obj2.transform.SetParent(avatarOptimizationParent.transform, false);
			((TMP_Text)obj2.GetComponent<TextMeshPro>()).enableWordWrapping = false;
			((TMP_Text)obj2.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
			GameObject obj3 = Create.NewText("WARNINGS:", 1f, new Color(1f, 1f, 0f), Vector3.zero, Quaternion.identity);
			((Object)obj3).name = "Warnings";
			obj3.transform.SetParent(avatarOptimizationParent.transform, false);
			obj3.transform.localPosition = new Vector3(0f, -0.0919f, 0f);
			((TMP_Text)obj3.GetComponent<TextMeshPro>()).enableWordWrapping = false;
			((TMP_Text)obj3.GetComponent<TextMeshPro>()).alignment = (TextAlignmentOptions)514;
			GameObject val = Create.NewText("Up To Date", 1f, new Color(0f, 1f, 1f), Vector3.zero, Quaternion.identity);
			((Object)val).name = "AvatarServerStatus";
			val.transform.SetParent(avatarOptimizationParent.transform, false);
			val.transform.localPosition = new Vector3(-1.9309f, 0.2499f, -0.4545f);
			val.transform.localRotation = Quaternion.Euler(352.9085f, 321.6011f, 3.3454f);
			serverStatusText = val.GetComponent<TextMeshPro>();
			((TMP_Text)serverStatusText).enableWordWrapping = false;
			((TMP_Text)serverStatusText).alignment = (TextAlignmentOptions)514;
			SetObjectsActive();
		}
		if (PhotonNetwork.InRoom)
		{
			Hashtable val2 = new Hashtable();
			val2[Object.op_Implicit("CA_ModVersion")] = Object.op_Implicit("1.3.2");
			List<bool> list = RigManager.avatarSettingBools.Select((ModSetting<bool> s) => (bool)((ModSetting)s).Value).ToList();
			val2[Object.op_Implicit("Ca_Params")] = Object.op_Implicit(RigManager.PackParams(list));
			PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null);
		}
		sceneInitialized = true;
	}

	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_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Expected O, but got Unknown
		//IL_022a: Unknown result type (might be due to invalid IL or missing references)
		//IL_022f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0231: Unknown result type (might be due to invalid IL or missing references)
		//IL_0235: Invalid comparison between Unknown and I4
		//IL_0239: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: 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;
		}
		GameObject val = Calls.LoadAssetBundleGameObjectFromFile(Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").FirstOrDefault(), "Rig");
		((Object)val).name = "RIG - CloneBending Clone";
		val.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(val);
		customRig2.Config = customRig.Config;
		if (!customRig2.Config.swapOriginalMesh)
		{
			rig.transform.SetParent(bodyDouble.transform, true);
		}
		RigManager.ApplyRigToSMR(bodyDouble.transform.GetChild(1).GetChild(1), val, ((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 = val.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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0078: Expected O, but got Unknown
		//IL_0175: Unknown result type (might be due to invalid IL or missing references)
		//IL_017f: Expected O, but got Unknown
		if (clearAll)
		{
			RigManager.ClearRigs();
		}
		Camera camera = Players.GetPlayerController().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_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: 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_0233: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023a: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Invalid comparison between Unknown and I4
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		GameObject gameObject = Visuals.GetGameObject();
		GameObject val = Calls.LoadAssetBundleGameObjectFromFile(Directory.GetFiles(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomAvatars"), "*.rumbleavatar").FirstOrDefault(), "Rig");
		((Object)val).name = "RIG - Preview Controller (Dressing Room)";
		val.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(val);
		customRig.Config = localRig.Config;
		previewScanList = RigManager.Scan(val.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), val, 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 = val.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_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0301: Unknown result type (might be due to invalid IL or missing references)
		//IL_0306: Unknown result type (might be due to invalid IL or missing references)
		//IL_030a: Unknown result type (might be due to invalid IL or missing references)
		//IL_030f: Unknown result type (might be due to invalid IL or missing references)
		//IL_031e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0315: Unknown result type (might be due to invalid IL or missing references)
		//IL_031a: 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;
						val3.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 (((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_0022: 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))
		{
			Initialize();
		}
	}

	public void AddPlayerToList(Player player)
	{
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Expected O, but got Unknown
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Expected O, but got Unknown
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: 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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Expected O, but got Unknown
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_008d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Expected O, but got Unknown
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Expected O, but got Unknown
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Expected O, but got Unknown
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Expected O, but got Unknown
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Expected O, but got Unknown
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Expected O, but got Unknown
		//IL_017f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Expected O, but got Unknown
		//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b1: Expected O, but got Unknown
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cf: Expected O, but got Unknown
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Expected O, but got Unknown
		//IL_0208: Unknown result type (might be due to invalid IL or missing references)
		//IL_020d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0219: Expected O, but got Unknown
		//IL_022d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Expected O, but got Unknown
		//IL_024e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Expected O, but got Unknown
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0275: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Expected O, but got Unknown
		mod.ModName = "<b><#6A5ACD>Custom Avatars</color></b>";
		mod.ModVersion = "1.3.1";
		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"))
				{
					RigManager.ResolveRigState(((IEnumerable<Player>)Players.GetAllPlayers().ToArray()).FirstOrDefault((Func<Player, bool>)((Player p) => p.Data.GeneralData.PlayFabMasterId == rig.Key)), 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;

		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()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			int num = <>1__state;
			CustomRig customRig = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				SkinnedMeshRenderer val = (customRig.Config.swapOriginalMesh ? customRig.MeshRenderer : customRig.Root.GetComponentInChildren<SkinnedMeshRenderer>());
				if ((Object)(object)val == (Object)null || (Object)(object)customRig.MeshRenderer.sharedMesh == (Object)null)
				{
					return false;
				}
				foreach (BlendshapeDefault defaultBlendshape in customRig.Config.defaultBlendshapes)
				{
					if (defaultBlendshape.index >= 0 && defaultBlendshape.index < customRig.MeshRenderer.sharedMesh.blendShapeCount)
					{
						val.SetBlendShapeWeight(defaultBlendshape.index, defaultBlendshape.weight);
					}
				}
				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 <blinkDuration>5__2;

		private int <singleIdx>5__3;

		private int <leftIdx>5__4;

		private int <rightIdx>5__5;

		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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Expected O, but got Unknown
			int num = <>1__state;
			CustomRig customRig = <>4__this;
			float num2;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				goto IL_0035;
			case 1:
				<>1__state = -1;
				<blinkDuration>5__2 = customRig.Config.eyeSettings.blinkSpeed;
				switch (customRig.Config.eyeSettings.blinkType)
				{
				case AvatarDescriptorExport.BlinkType.None:
					break;
				case AvatarDescriptorExport.BlinkType.Single:
					<singleIdx>5__3 = customRig.Config.eyeSettings.blinkBlendshape;
					if (<singleIdx>5__3 >= 0)
					{
						<>2__current = MelonCoroutines.Start(customRig.BlinkBlendshapeLerp(<singleIdx>5__3, 100f, <blinkDuration>5__2));
						<>1__state = 2;
						return true;
					}
					break;
				case AvatarDescriptorExport.BlinkType.LeftRight:
					<leftIdx>5__4 = customRig.Config.eyeSettings.blinkLeftBlendshape;
					<rightIdx>5__5 = customRig.Config.eyeSettings.blinkRightBlendshape;
					if (<leftIdx>5__4 >= 0)
					{
						MelonCoroutines.Start(customRig.BlinkBlendshapeLerp(<leftIdx>5__4, 100f, <blinkDuration>5__2));
					}
					if (<rightIdx>5__5 >= 0)
					{
						MelonCoroutines.Start(customRig.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();
				}
				goto IL_0035;
			case 2:
				<>1__state = -1;
				<>2__current = MelonCoroutines.Start(customRig.BlinkBlendshapeLerp(<singleIdx>5__3, 0f, <blinkDuration>5__2));
				<>1__state = 3;
				return true;
			case 3:
				<>1__state = -1;
				goto IL_0035;
			case 4:
				<>1__state = -1;
				if (<leftIdx>5__4 >= 0)
				{
					MelonCoroutines.Start(customRig.BlinkBlendshapeLerp(<leftIdx>5__4, 0f, <blinkDuration>5__2));
				}
				if (<rightIdx>5__5 >= 0)
				{
					MelonCoroutines.Start(customRig.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;
					goto IL_0035;
				}
				IL_0035:
				num2 = Random.Range(customRig.Config.eyeSettings.blinkInterval.x, customRig.Config.eyeSettings.blinkInterval.y);
				<>2__current = (object)new WaitForSeconds(num2);
				<>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 CustomRig <>4__this;

		public int index;

		public float duration;

		public float targetWeight;

		private float <startWeight>5__2;

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

		public Transform target;

		public float gain;

		public EyeSettings settings;

		public float duration;

		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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			int num = <>1__state;
			CustomRig customRig = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				break;
			case 1:
				<>1__state = -1;
				break;
			}
			if ((Object)(object)target != (Object)null)
			{
				Vector4 val = customRig.CalculateEyeWeights(customRig.Head, target);
				float num2 = val.x * gain;
				float num3 = val.y * gain;
				float num4 = val.z * gain;
				float num5 = val.w * gain;
				float blendShapeWeight = customRig.MeshRenderer.GetBlendShapeWeight(settings.eyeUpBlendshape);
				float blendShapeWeight2 = customRig.MeshRenderer.GetBlendShapeWeight(settings.eyeDownBlendshape);
				float blendShapeWeight3 = customRig.MeshRenderer.GetBlendShapeWeight(settings.eyeLeftBlendshape);
				float blendShapeWeight4 = customRig.MeshRenderer.GetBlendShapeWeight(settings.eyeRightBlendshape);
				customRig.MeshRenderer.SetBlendShapeWeight(settings.eyeUpBlendshape, Mathf.Lerp(blendShapeWeight, num2, Time.deltaTime / duration));
				customRig.MeshRenderer.SetBlendShapeWeight(settings.eyeDownBlendshape, Mathf.Lerp(blendShapeWeight2, num3, Time.deltaTime / duration));
				customRig.MeshRenderer.SetBlendShapeWeight(settings.eyeLeftBlendshape, Mathf.Lerp(blendShapeWeight3, num4, Time.deltaTime / duration));
				customRig.MeshRenderer.SetBlendShapeWeight(settings.eyeRightBlendshape, Mathf.Lerp(blendShapeWeight4, num5, 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_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: 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_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: 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_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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)
			{
				OriginalVisualsMaterial = Object.Instantiate<Material>(playerVisuals.NonHeadClippedMaterial);
				((Object)OriginalVisualsMaterial).hideFlags = (HideFlags)61;
			}
			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.root.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;
				Root.SetActive(false);
				Transform[] rigBones = RigBones;
				for (int i = 0; i < rigBones.Length; i++)
				{
					((Component)rigBones[i]).gameObject.SetActive(false);
				}
				if ((Object)(object)playerVisuals != (Object)null && IsLocal)
				{
					playerVisuals.NonHeadClippedMaterial = OriginalVisualsMaterial;
				}
				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;
					if ((Object)(object)playerVisuals != (Object)null && IsLocal)
					{
						playerVisuals.NonHeadClippedMaterial = RigVisualsMaterial;
					}
				}
				Root.SetActive(true);
				if (IsLocal)
				{
					if (!(bool)((ModSetting)Main.instance.toggleInRockCam).SavedValue)
					{
						((Renderer)MeshRenderer).shadowCastingMode = (ShadowCastingMode)0;
						((Component)MeshRenderer).gameObject.layer = 2;
						Camera camera = Players.GetPlayerController().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 = Players.GetPlayerController().GetSubsystem<PlayerCamera>().camera;
						camera2.cullingMask |= 4;
						Camera component2 = RecordingCamera.GetGameObject().GetComponent<Camera>();
						component2.cullingMask |= 4;
					}
				}
				Transform[] rigBones = RigBones;
				for (int i = 0; i < rigBones.Length; i++)
				{
					((Component)rigBones[i]).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;
			for (int i = 0; i < rigMaterials.Length; i++)
			{
				Object.Destroy((Object)(object)rigMaterials[i]);
			}
		}
		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()
		{
			int num = <>1__state;
			PlayerEntry playerEntry = <>4__this;
			switch (num)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				if (playerEntry.Toggle != null)
				{
					<>2__current = (ModSetting)(object)playerEntry.Toggle;
					<>1__state = 1;
					return true;
				}
				goto IL_004d;
			case 1:
				<>1__state = -1;
				goto IL_004d;
			case 2:
				{
					<>1__state = -1;
					break;
				}
				IL_004d:
				if (playerEntry.ReloadButton != null)
				{
					<>2__current = (ModSetting)(object)playerEntry.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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if (!IsEnabled())
			{
				Player localPlayer = Players.GetLocalPlayer();
				PlayerController val = ((localPlayer != null) ? localPlayer.Controller : null);
				CustomRig customRig = default(CustomRig);
				if (val != null && ((Component)val).TryGetComponent<CustomRig>(ref customRig))
				{
					customRig.OriginalVisualsMaterial = new Material(val.GetSubsystem<PlayerVisuals>().NonHeadClippedMaterial);
					((Object)customRig.OriginalVisualsMaterial).hideFlags = (HideFlags)61;
				}
			}
		}

		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;
			if ((bool)(((toggleLocal != null) ? ((ModSetting)toggleLocal).SavedValue : null) ?? ((object)false)))
			{
				return localRig.Config.swapOriginalMesh;
			}
			return false;
		}
	}

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

		private object <>2__current;

		public Player player;

		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()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			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;
				Player obj = ((currentRoom != null) ? currentRoom.GetPlayer((int)player.Data.GeneralData.ActorNo, false) : null);
				Hashtable val = ((obj != null) ? obj.CustomProperties : null);
				Object val2 = default(Object);
				if (val != null && ((Dictionary<Object, Object>)(object)val).TryGetValue(Object.op_Implicit("CA_ModVersion"), ref val2) && ((Dictionary<Object, Object>)(object)PhotonNetwork.LocalPlayer.CustomProperties).ContainsKey(Object.op_Implicit("CA_ModVersion")))
				{
					string modVersion = ((val2 != null) ? val2.ToString() : null) ?? "Unknown";
					if ((Object)(object)Main.instance.tagObject == (Object)null)
					{
						Sprite sprite = Calls.LoadAssetFromStream<Sprite>((MelonMod)(object)Main.instance, "CustomAvatars.AssetBundles.avatarthingies", "icon");
						GameObject val3 = new GameObject("CustomAvatarTag");
						val3.AddComponent<SpriteRenderer>().sprite = sprite;
						Object.DontDestroyOnLoad((Object)(object)val3);
						val3.SetActive(false);
						Main.instance.tagObject = val3;
					}
					GameObject tagObject = Main.instance.tagObject;
					PlayerController controller = player.Controller;
					GameObject obj2 = Object.Instantiate<GameObject>(tagObject, (controller != null) ? ((Component)controller).transform.GetChild(9) : null);
					obj2.SetActive(true);
					((Object)obj2).name = "CustomAvatarTag";
					obj2.transform.localScale = Vector3.one * 0.04f;
					obj2.transform.localPosition = new Vector3(0.2301f, -0.1633f, 0f);
					PlayerController controller2 = player.Controller;
					CustomRig customRig = default(CustomRig);
					if (controller2 != null && ((Component)controller2).TryGetComponent<CustomRig>(ref customRig))
					{
						customRig.ModVersion = modVersion;
					}
				}
				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>();
				((Component)player.Controller).gameObject.AddComponent<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));
					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 UnityWebRequest <metaReq>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 <DownloadToFile>d__21(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

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

		private bool MoveNext()
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: 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;
				}
				string text = "https://api.github.com/repos/xLoadingx/custom-avatars/contents/avatars/" + Uri.EscapeDataString(masterId) + "?ref=main";
				<metaReq>5__2 = UnityWebRequest.Get(text);
				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;
					Il2CppStructArray<byte> val = ((downloadHandler != null) ? downloadHandler.data : null);
					if (val == null || ((Il2CppArrayBase<byte>)(object)val).Length == 0)
					{
						<metaReq>5__2.Dispose();
						_downloadingPlayers.Remove(masterId);
						return false;
					}
					string @string = Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)val));
					int num = @string.IndexOf("\"size\":", StringComparison.Ordinal);
					if (num >= 0)
					{
						num += 7;
						int num2 = @string.IndexOfAny(new char[2] { ',', '}' }, num);
						if (int.TryParse(@string.Substring(num, num2 - num).Trim(), out var result))
						{
							int num3 = (int)((ModSetting)Main.instance.downloadLimitMB).SavedValue * 1024 * 1024;
							if (result > num3)
							{
								((MelonBase)Main.instance).LoggerInstance.Warning($"Download skipped: {result / 1048576} MB exceeds limit of {num3 / 1048576} MB.");
								<metaReq>5__2.Dispose();
								_downloadingPlayers.Remove(masterId);
								return false;
							}
						}
					}
				}
				catch (Exception ex)
				{
					((MelonBase)Main.instance).LoggerInstance.Error("Error parsing metadata for " + masterId + ": " + ex.Message);
					<metaReq>5__2.Dispose();
					_downloadingPlayers.Remove(masterId);
					return false;
				}
				<metaReq>5__2.Dispose();
				<req>5__3 = UnityWebRequest.Get(GhUrl(masterId));
				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
				{
					Il2CppStructArray<byte> data = <req>5__3.downloadHandler.data;
					if (data == null || ((Il2CppArrayBase<byte>)(object)data).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;
					}
					byte[] bytes = XorCrypt(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)data), 90);
					File.WriteAllBytes(savePath, bytes);
				}
				_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 bool log;

		public string masterId;

		public Action<string> cb;

		private UnityWebRequest <req>5__2;

		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()
		{
			<req>5__2 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Invalid comparison between Unknown and I4
			//IL_00f3: 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 + "...");
				}
				string text = "https://api.github.com/repos/xLoadingx/custom-avatars/contents/avatars/" + Uri.EscapeDataString(masterId) + "?ref=main";
				<req>5__2 = UnityWebRequest.Get(text);
				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;
				Il2CppStructArray<byte> val = ((downloadHandler != null) ? downloadHandler.data : null);
				<req>5__2.Dispose();
				if (val == null || ((Il2CppArrayBase<byte>)(object)val).Length == 0)
				{
					cb(null);
					return false;
				}
				string @string = Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)val));
				int num = @string.IndexOf("\"sha\":\"", StringComparison.Ordinal);
				if (num < 0)
				{
					cb(null);
					return false;
				}
				num += 7;
				int num2 = @string.IndexOf('"', num);
				cb((num2 > num) ? @string.Substring(num, num2 - num) : 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 Action<(bool hasAvatar, string returnedSha)> callback;

		public string masterId;

		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()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				<>c__DisplayClass18_0 CS$<>8__locals0 = new <>c__DisplayClass18_0
				{
					callback = callback
				};
				<>2__current = MelonCoroutines.Start(GetSha(masterId, delegate(string sha)
				{
					CS$<>8__locals0.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 UnityWebRequest <req>5__2;

		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()
		{
			<req>5__2 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
			{
				<>1__state = -1;
				string text = UploadUrlForPath($"logs/{DateTime.UtcNow:yyyy-MM-dd}/{Guid.NewGuid():N}.json");
				string s = "{\"message\":\"log:" + tag + "\",\"content\":\"" + Convert.ToBase64String(Encoding.UTF8.GetBytes(jsonPayload)) + "\",\"branch\":\"main\"}";
				<req>5__2 = new UnityWebRequest(text, "PUT");
				<req>5__2.uploadHandler = (UploadHandler)new UploadHandlerRaw(Il2CppStructArray<byte>.op_Implicit(Encoding.UTF8.GetBytes(s)));
				<req>5__2.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				<req>5__2.SetRequestHeader("Content-Type", "application/json");
				SetGhHeaders(<req>5__2, wantRaw: false);
				<>2__current = <req>5__2.SendWebRequest();
				<>1__state = 1;
				return true;
			}
			case 1:
				<>1__state = -1;
				<req>5__2.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 TextMeshPro serverStatusText;

		public Action<bool, bool> done;

		public string path;

		private <>c__DisplayClass16_0 <>8__1;

		public Action onStartUpload;

		public Action<float> onProgress;

		private GeneralData <data>5__2;

		private byte[] <bytes>5__3;

		private UnityWebRequest <req>5__4;

		private UnityWebRequestAsyncOperation <op>5__5;

		private bool <ok>5__6;

		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;
			<req>5__4 = null;
			<op>5__5 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0566: Expected O, but got Unknown
			//IL_0623: Unknown result type (might be due to invalid IL or missing references)
			//IL_062d: Expected O, but got Unknown
			//IL_0643: Unknown result type (might be due to invalid IL or missing references)
			//IL_064d: Expected O, but got Unknown
			//IL_0653: Unknown result type (might be due to invalid IL or missing references)
			//IL_065d: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0417: Expected O, but got Unknown
			//IL_049d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Expected O, but got Unknown
			//IL_0738: Unknown result type (might be due to invalid IL or missing references)
			//IL_073e: Invalid comparison between Unknown and I4
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Expected O, but got Unknown
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_08cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d5: Expected O, but got Unknown
			//IL_08ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_087b: Unknown result type (might be due to invalid IL or missing references)
			int num;
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass16_0();
				<data>5__2 = Players.GetLocalPlayer().Data.GeneralData;
				if (masterId != <data>5__2.PlayFabMasterId)
				{
					((MelonBase)Main.instance).LoggerInstance.Error("Player tried to upload avtar for masterId that isn't theirs.");
					MelonCoroutines.Start(SendAudit("masterId_mismatch", $"[{DateTime.UtcNow:O}] Player {<data>5__2.PublicUsername.TrimString()} ({<data>5__2.PlayFabMasterId}) tried to write avatar for MasterId {masterId}"));
					uploadCoroutine = null;
					if ((Object)(object)serverStatusText != (Object)null)
					{
						((Graphic)serverStatusText).color = Color.red;
						((TMP_Text)serverStatusText).text = "MasterId Mismatch";
					}
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				}
				if (!File.Exists(path))
				{
					((MelonBase)Main.instance).LoggerInstance.Error("AssetBundle at path '" + path + "' does not exist.");
					if ((Object)(object)serverStatusText != (Object)null)
					{
						((Graphic)serverStatusText).color = Color.red;
						((TMP_Text)serverStatusText).text = "Avatar doesn't exist";
					}
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 2;
					return true;
				}
				try
				{
					<bytes>5__3 = File.ReadAllBytes(path);
				}
				catch (Exception ex)
				{
					((MelonBase)Main.instance).LoggerInstance.Error("ReadAllBytes failed: " + ex.Message);
					done?.Invoke(arg1: false, arg2: false);
					uploadCoroutine = null;
					return false;
				}
				if (<bytes>5__3.Length > 26214400)
				{
					((MelonBase)Main.instance).LoggerInstance.Error($"Upload failed: Bundle size {<bytes>5__3.Length / 1048576} MB exceeds {25} MB Limit.");
					if ((Object)(object)serverStatusText != (Object)null)
					{
						((Graphic)serverStatusText).color = Color.red;
						((TMP_Text)serverStatusText).text = $"Bundle size is bigger than {25} MB limit";
					}
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 3;
					return true;
				}
				if (string.IsNullOrWhiteSpace(masterId) || <bytes>5__3.Length == 0)
				{
					done?.Invoke(arg1: false, arg2: false);
					return false;
				}
				<>8__1.sha = null;
				((MelonBase)Main.instance).LoggerInstance.Msg("Fetching Remote SHA...");
				if ((Object)(object)serverStatusText != (Object)null)
				{
					((TMP_Text)serverStatusText).text = "Fetching Remote SHA...";
				}
				<>2__current = GetSha(masterId, delegate(string s)
				{
					<>8__1.sha = s;
				});
				<>1__state = 4;
				return true;
			case 1:
				<>1__state = -1;
				done?.Invoke(arg1: false, arg2: false);
				return false;
			case 2:
				<>1__state = -1;
				done?.Invoke(arg1: false, arg2: false);
				uploadCoroutine = null;
				return false;
			case 3:
				<>1__state = -1;
				done?.Invoke(arg1: false, arg2: false);
				uploadCoroutine = null;
				return false;
			case 4:
				<>1__state = -1;
				((MelonBase)Main.instance).LoggerInstance.Msg((<>8__1.sha != null) ? ("Remote SHA: " + <>8__1.sha.Substring(0, 8)) : "No remote file found - will create new file.");
				if ((Object)(object)serverStatusText != (Object)null)
				{
					((TMP_Text)serverStatusText).text = ((<>8__1.sha != null) ? "Remote File Exists" : "No remote file found - will create new file.");
				}
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 5;
				return true;
			case 5:
				<>1__state = -1;
				if (<>8__1.sha != null && !string.IsNullOrEmpty(<>8__1.sha) && ShaMatchesLocal(<>8__1.sha, path))
				{
					((MelonBase)Main.instance).LoggerInstance.Msg("Upload Skipped: Local file is identical to the server version.");
					if ((Object)(object)serverStatusText != (Object)null)
					{
						((TMP_Text)serverStatusText).text = "Local file is identical to the server version.";
					}
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 6;
					return true;
				}
				((MelonBase)Main.instance).LoggerInstance.Msg($"File size: {(float)<bytes>5__3.Length / 1024f / 1024f:F2} MB");
				((MelonBase)Main.instance).LoggerInstance.Msg("Uploading to GitHub...");
				if ((Object)(object)serverStatusText != (Object)null)
				{
					((TMP_Text)serverStatusText).text = $"Uploading {(float)<bytes>5__3.Length / 1024f / 1024f:F2} MB to GitHub...";
				}
				<>2__current = (object)new WaitForSeconds(2f);
				<>1__state = 7;
				return true;
			case 6:
				<>1__state = -1;
				done?.Invoke(arg1: true, arg2: true);
				uploadCoroutine = null;
				return false;
			case 7:
			{
				<>1__state = -1;
				string s2 = "{\"message\":\"Upload bundle for " + masterId + ". Uploaded by " + <data>5__2.PublicUsername.TrimString() + "\",\"content\":\"" + Convert.ToBase64String(<bytes>5__3) + "\",\"branch\":\"main\"" + ((<>8__1.sha != null) ? (",\"sha\":\"" + <>8__1.sha + "\"") : "") + "}";
				string text = UploadUrlForPath("avatars/" + masterId);
				<req>5__4 = new UnityWebRequest(text, "PUT");
				<req>5__4.uploadHandler = (UploadHandler)new UploadHandlerRaw(Il2CppStructArray<byte>.op_Implicit(Encoding.UTF8.GetBytes(s2)));
				<req>5__4.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
				<req>5__4.SetRequestHeader("Content-Type", "application/json");
				SetGhHeaders(<req>5__4, wantRaw: false);
				<op>5__5 = <req>5__4.SendWebRequest();
				onStartUpload?.Invoke();
				goto IL_070e;
			}
			case 8:
				<>1__state = -1;
				goto IL_070e;
			case 9:
				{
					<>1__state = -1;
					<req>5__4.Dispose();
					uploadCoroutine = null;
					done?.Invoke(<ok>5__6, arg2: false);
					return false;
				}
				IL_070e:
				if (!((AsyncOperation)<op>5__5).isDone)
				{
					onProgress?.Invoke(<req>5__4.uploadProgress);
					if ((Object)(object)serverStatusText != (Object)null)
					{
						((TMP_Text)serverStatusText).text = $"{<req>5__4.uploadProgress * 100f:F2}%";
					}
					<>2__current = null;
					<>1__state = 8;
					return true;
				}
				onProgress?.Invoke(1f);
				if ((int)<req>5__4.result == 1)
				{
					long responseCode = <req>5__4.responseCode;
					num = ((responseCode >= 200 && responseCode < 300) ? 1 : 0);
				}
				else
				{
					num = 0;
				}
				<ok>5__6 = (byte)num != 0;
				if (!<ok>5__6)
				{
					DownloadHandler downloadHandler = <req>5__4.downloadHandler;
					Il2CppStructArray<byte> val = ((downloadHandler != null) ? downloadHandler.data : null);
					string text2 = ((val != null) ? Encoding.UTF8.GetString(Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)val)) : "");
					((MelonBase)Main.instance).LoggerInstance.Error($"Upload failed {masterId}: {<req>5__4.responseCode} {<req>5__4.error}\n{text2}");
					MelonCoroutines.Start(SendAudit("upload_fail", $"[{DateTime.UtcNow:O}] Upload failed for Mas