Decompiled source of Mercenary Skins Fix v1.2.4

plugins/MercSkinsFix/MercSkinsFix.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using MonoMod.RuntimeDetour;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2BepInExPack.GameAssetPaths.Version_1_35_0;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MercSkinsFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ec5d5c865e15669d9885120c1db36be980c8024c")]
[assembly: AssemblyProduct("MercSkinsFix")]
[assembly: AssemblyTitle("MercSkinsFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MercSkinsFix
{
	internal static class Log
	{
		private static readonly StringBuilder _sharedStringBuilder;

		private static readonly object _stringBuilderLock;

		private static readonly int _cachedCallerPathPrefixLength;

		private static ManualLogSource _logSource;

		static Log()
		{
			_sharedStringBuilder = new StringBuilder(256);
			_stringBuilderLock = new object();
			_cachedCallerPathPrefixLength = getCallerPathPrefixLength("D:\\Git\\RoR2\\MercSkinsFix\\MercSkinsFix\\Log.cs");
			static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null)
			{
				int num = callerPath.LastIndexOf("MercSkinsFix\\");
				if (num >= 0)
				{
					return num + "MercSkinsFix\\".Length;
				}
				Debug.LogError((object)"[MercSkinsFix] Logger failed to determine caller path prefix length");
				return 0;
			}
		}

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data)
		{
			lock (_stringBuilderLock)
			{
				return _sharedStringBuilder.Clear().Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':')
					.Append(callerLineNumber)
					.Append(" (")
					.Append(callerMemberName)
					.Append("): ")
					.Append(data)
					.ToString();
			}
		}

		[Conditional("DEBUG")]
		internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		[Conditional("DEBUG")]
		internal static void Debug_NoCallerPrefix(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Error_NoCallerPrefix(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Fatal_NoCallerPrefix(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Info_NoCallerPrefix(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Message_NoCallerPrefix(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			_logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void Warning_NoCallerPrefix(object data)
		{
			_logSource.LogWarning(data);
		}

		internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data));
			}
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		internal static void LogType_NoCallerPrefix(LogLevel level, object data)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: 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)
			if ((level & 0x20) == 0)
			{
				_logSource.Log(level, data);
			}
		}
	}
	[BepInPlugin("___com.Gorakh.MercSkinsFix", "MercSkinsFix", "1.2.4")]
	public sealed class MercSkinsFixPlugin : BaseUnityPlugin
	{
		private delegate ScriptableObject orig_ScriptableObject_CreateInstance(Type type);

		public const string PluginGUID = "___com.Gorakh.MercSkinsFix";

		public const string PluginAuthor = "Gorakh";

		public const string PluginName = "MercSkinsFix";

		public const string PluginVersion = "1.2.4";

		private static readonly Dictionary<Assembly, PluginInfo> _assemblyPluginLookup = new Dictionary<Assembly, PluginInfo>();

		private static readonly Dictionary<SkinDef, Assembly> _skinOwnerAssemblies = new Dictionary<SkinDef, Assembly>();

		private static readonly Dictionary<Assembly, DateTime?> _assemblyTimestampLookup = new Dictionary<Assembly, DateTime?>();

		private Hook _scriptableObjectCreateInstanceHook;

		internal static MercSkinsFixPlugin Instance { get; private set; }

		private void Awake()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			Log.Init(((BaseUnityPlugin)this).Logger);
			Instance = SingletonHelper.Assign<MercSkinsFixPlugin>(Instance, this);
			_scriptableObjectCreateInstanceHook = new Hook((MethodBase)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => ScriptableObject.CreateInstance((Type)null))), (Delegate)new Func<orig_ScriptableObject_CreateInstance, Type, ScriptableObject>(ScriptableObject_CreateInstance));
			stopwatch.Stop();
			Log.Info_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(onLoad));
		}

		private void OnDestroy()
		{
			Instance = SingletonHelper.Unassign<MercSkinsFixPlugin>(Instance, this);
			Hook scriptableObjectCreateInstanceHook = _scriptableObjectCreateInstanceHook;
			if (scriptableObjectCreateInstanceHook != null)
			{
				scriptableObjectCreateInstanceHook.Dispose();
			}
			_scriptableObjectCreateInstanceHook = null;
		}

		private static ScriptableObject ScriptableObject_CreateInstance(orig_ScriptableObject_CreateInstance orig, Type type)
		{
			ScriptableObject val = orig(type);
			try
			{
				SkinDef val2 = (SkinDef)(object)((val is SkinDef) ? val : null);
				if (val2 != null)
				{
					StackTrace stackTrace = new StackTrace();
					for (int i = 0; i < stackTrace.FrameCount; i++)
					{
						Assembly assembly = stackTrace.GetFrame(i)?.GetMethod()?.DeclaringType?.Assembly;
						if (assembly == null || assembly == Assembly.GetExecutingAssembly())
						{
							continue;
						}
						if (!_assemblyPluginLookup.TryGetValue(assembly, out var value))
						{
							value = null;
							foreach (PluginInfo value3 in Chainloader.PluginInfos.Values)
							{
								if (Object.op_Implicit((Object)(object)value3.Instance) && ((object)value3.Instance).GetType().Assembly == assembly)
								{
									value = value3;
									break;
								}
							}
							_assemblyPluginLookup.Add(assembly, value);
						}
						if (value == null)
						{
							continue;
						}
						if (!_assemblyTimestampLookup.ContainsKey(assembly))
						{
							DateTime? value2 = null;
							string location = assembly.Location;
							if (!string.IsNullOrEmpty(location) && File.Exists(location))
							{
								try
								{
									using FileStream fileStream = File.Open(location, FileMode.Open, FileAccess.Read, FileShare.Read);
									byte[] array = new byte[2048];
									int num = fileStream.Read(array, 0, 2048);
									if (num >= 60)
									{
										int num2 = BitConverter.ToInt32(array, 60) + 8;
										if (num >= num2 + 4)
										{
											int num3 = BitConverter.ToInt32(array, num2);
											DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(num3);
											if (dateTime > new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc) && dateTime < DateTime.UtcNow)
											{
												value2 = dateTime;
											}
										}
									}
								}
								catch (Exception arg)
								{
									Log.Error_NoCallerPrefix($"Failed to determine assembly date for {assembly.GetName()}: {arg}");
								}
							}
							_assemblyTimestampLookup.Add(assembly, value2);
						}
						_skinOwnerAssemblies.Add(val2, assembly);
						break;
					}
				}
			}
			catch (Exception data)
			{
				Log.Error_NoCallerPrefix(data);
			}
			return val;
		}

		private void onLoad()
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0458: Unknown result type (might be due to invalid IL or missing references)
			//IL_045f: Expected O, but got Unknown
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_049f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Expected O, but got Unknown
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(onLoad));
			SkinDef[] array = (SkinDef[])(object)new SkinDef[5]
			{
				Addressables.LoadAssetAsync<SkinDef>((object)RoR2_Base_Merc.skinMercDefault_asset).WaitForCompletion(),
				Addressables.LoadAssetAsync<SkinDef>((object)RoR2_Base_Merc.skinMercAlt_asset).WaitForCompletion(),
				Addressables.LoadAssetAsync<SkinDef>((object)RoR2_Base_Merc.skinMercAltPrisoner_asset).WaitForCompletion(),
				Addressables.LoadAssetAsync<SkinDef>((object)RoR2_Base_Merc.skinMercAltColossus_asset).WaitForCompletion(),
				Addressables.LoadAssetAsync<SkinDef>((object)RoR2_Base_Merc.skinMercAltVulture_asset).WaitForCompletion()
			};
			Dictionary<string, HashSet<string>> dictionary = new Dictionary<string, HashSet<string>>();
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = false;
			bool flag = false;
			SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(BodyCatalog.FindBodyIndex("MercBody"));
			foreach (SkinDef skin in bodySkinDefs)
			{
				if (Array.IndexOf(array, skin) != -1)
				{
					continue;
				}
				Assembly valueSafe = GeneralExtensions.GetValueSafe<SkinDef, Assembly>(_skinOwnerAssemblies, skin);
				PluginInfo val = ((valueSafe != null) ? GeneralExtensions.GetValueSafe<Assembly, PluginInfo>(_assemblyPluginLookup, valueSafe) : null);
				string key = "Unknown";
				bool flag2 = false;
				if (val != null && valueSafe != null)
				{
					if (_assemblyTimestampLookup.TryGetValue(valueSafe, out var value) && value.HasValue)
					{
						DateTime dateTime = new DateTime(2024, 5, 20, 0, 0, 0, DateTimeKind.Utc);
						if (value.Value < dateTime)
						{
							flag2 = true;
						}
					}
					key = val.Metadata.Name + " (" + Path.GetFileName(valueSafe.Location) + ")";
				}
				string text;
				if (!string.IsNullOrEmpty(skin.nameToken))
				{
					text = ((!string.IsNullOrEmpty(((Object)skin).name)) ? (Language.GetString(skin.nameToken, "en") + " (" + ((Object)skin).name + ")") : Language.GetString(skin.nameToken, "en"));
				}
				else if (string.IsNullOrEmpty(((Object)skin).name))
				{
					SkinIndex skinIndex = skin.skinIndex;
					text = ((object)(SkinIndex)(ref skinIndex)).ToString();
				}
				else
				{
					text = ((Object)skin).name;
				}
				string text2 = Regex.Replace(text, "<[^<>]+>", string.Empty);
				if (!string.IsNullOrEmpty(text2))
				{
					text = text2;
				}
				text = text.FilterConfigKey();
				if (string.IsNullOrEmpty(text))
				{
					Random random = new Random(skin.nameToken.GetHashCode());
					StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
					byte[] array2 = new byte[16];
					random.NextBytes(array2);
					for (int j = 0; j < array2.Length; j++)
					{
						stringBuilder.Append(array2[j].ToString("X2"));
					}
					text = $"INVALID SKIN NAME {stringBuilder}";
					StringBuilderPool.ReturnStringBuilder(stringBuilder);
				}
				if (dictionary.TryGetValue(key, out var value2))
				{
					if (!value2.Add(text))
					{
						string arg = text;
						int num = 1;
						do
						{
							text = $"{arg} ({num})";
							num++;
						}
						while (!value2.Add(text));
					}
				}
				else
				{
					dictionary.Add(key, new HashSet<string> { text });
				}
				ConfigEntry<bool> obj = ((BaseUnityPlugin)this).Config.Bind<bool>(key.FilterConfigKey(), ("Fix " + text).FilterConfigKey(), flag2, "Apply the fix to this skin");
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(obj), "___com.Gorakh.MercSkinsFix", "Mercenary Skins Fix");
				flag = true;
				if (obj.Value)
				{
					RebakeSkin.SetApplyToSkin(skin, apply: true);
				}
				obj.SettingChanged += delegate(object s, EventArgs e)
				{
					SettingChangedEventArgs val3 = (SettingChangedEventArgs)(object)((e is SettingChangedEventArgs) ? e : null);
					if (val3 != null)
					{
						bool apply = (bool)val3.ChangedSetting.BoxedValue;
						RebakeSkin.SetApplyToSkin(skin, apply);
					}
				};
			}
			((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
			((BaseUnityPlugin)this).Config.Save();
			if (flag)
			{
				ModSettingsManager.SetModDescription("Fix broken Mercenary skins after the Devotion update", "___com.Gorakh.MercSkinsFix", "Mercenary Skins Fix");
				FileInfo fileInfo = null;
				DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location));
				do
				{
					FileInfo[] files = directoryInfo.GetFiles("icon.png", SearchOption.TopDirectoryOnly);
					if (files != null && files.Length != 0)
					{
						fileInfo = files[0];
						break;
					}
					directoryInfo = directoryInfo.Parent;
				}
				while (directoryInfo != null && !string.Equals(directoryInfo.Name, "plugins", StringComparison.OrdinalIgnoreCase));
				if (fileInfo != null)
				{
					Texture2D val2 = new Texture2D(256, 256);
					if (ImageConversion.LoadImage(val2, File.ReadAllBytes(fileInfo.FullName)))
					{
						ModSettingsManager.SetModIcon(Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)), "___com.Gorakh.MercSkinsFix", "Mercenary Skins Fix");
					}
				}
			}
			Hook scriptableObjectCreateInstanceHook = _scriptableObjectCreateInstanceHook;
			if (scriptableObjectCreateInstanceHook != null)
			{
				scriptableObjectCreateInstanceHook.Dispose();
			}
			_scriptableObjectCreateInstanceHook = null;
		}
	}
	public static class RebakeSkin
	{
		public static void SetApplyToSkin(SkinDef skin, bool apply)
		{
			GameObject gameObject = ((Component)BodyCatalog.FindBodyPrefab("MercBody").GetComponent<ModelLocator>().modelTransform).gameObject;
			Renderer[] componentsInChildren = gameObject.GetComponentsInChildren<Renderer>(true);
			Renderer[] array = new Renderer[5];
			Transform obj = gameObject.transform.Find("MercArmature/ROOT/base/stomach/chest/PreDashEffect/ContractingEnergy");
			array[0] = ((obj != null) ? ((Component)obj).GetComponent<Renderer>() : null);
			Transform obj2 = gameObject.transform.Find("MercArmature/ROOT/base/stomach/chest/PreDashEffect/FireEmission");
			array[1] = ((obj2 != null) ? ((Component)obj2).GetComponent<Renderer>() : null);
			Transform obj3 = gameObject.transform.Find("MercArmature/ROOT/base/stomach/chest/PreDashEffect/BrightRing");
			array[2] = ((obj3 != null) ? ((Component)obj3).GetComponent<Renderer>() : null);
			Transform obj4 = gameObject.transform.Find("MercMesh");
			array[3] = ((obj4 != null) ? ((Component)obj4).GetComponent<Renderer>() : null);
			Transform obj5 = gameObject.transform.Find("MercSwordMesh");
			array[4] = ((obj5 != null) ? ((Component)obj5).GetComponent<Renderer>() : null);
			Renderer[] array2 = (Renderer[])(object)array;
			Renderer[] array3 = (apply ? componentsInChildren : array2);
			Renderer[] array4 = (apply ? array2 : componentsInChildren);
			for (int i = 0; i < skin.rendererInfos.Length; i++)
			{
				ref RendererInfo reference = ref skin.rendererInfos[i];
				if (Object.op_Implicit((Object)(object)reference.renderer))
				{
					int num = Array.IndexOf(array3, reference.renderer);
					if (num >= 0 && num < array4.Length)
					{
						Log.Info($"Changing {((Object)skin).name} RendererInfo renderer {reference.renderer} -> {array4[num]}", "D:\\Git\\RoR2\\MercSkinsFix\\MercSkinsFix\\RebakeSkin.cs", "SetApplyToSkin", 38);
						reference.renderer = array4[num];
					}
				}
			}
			for (int j = 0; j < skin.meshReplacements.Length; j++)
			{
				ref MeshReplacement reference2 = ref skin.meshReplacements[j];
				if (Object.op_Implicit((Object)(object)reference2.renderer))
				{
					int num2 = Array.IndexOf(array3, reference2.renderer);
					if (num2 >= 0 && num2 < array4.Length)
					{
						Log.Info($"Changing {((Object)skin).name} MeshReplacement renderer {reference2.renderer} -> {array4[num2]}", "D:\\Git\\RoR2\\MercSkinsFix\\MercSkinsFix\\RebakeSkin.cs", "SetApplyToSkin", 52);
						reference2.renderer = array4[num2];
					}
				}
			}
			if (skin.runtimeSkin != null)
			{
				RebakeSkinAsync(skin);
			}
		}

		public static void RebakeSkinAsync(SkinDef orig)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			orig._runtimeSkin = null;
			SkinDefParams skinDefParams = orig.skinDefParams;
			if (Object.op_Implicit((Object)(object)skinDefParams))
			{
				skinDefParams.rendererInfos = ((orig.rendererInfos != null) ? ArrayUtils.Clone<RendererInfo>(orig.rendererInfos) : Array.Empty<RendererInfo>());
				SkinDefParams val = skinDefParams;
				GameObjectActivation[] gameObjectActivations2;
				if (orig.gameObjectActivations != null)
				{
					GameObjectActivation[] gameObjectActivations = orig.gameObjectActivations;
					int num = 0;
					GameObjectActivation[] array = (GameObjectActivation[])(object)new GameObjectActivation[gameObjectActivations.Length];
					GameObjectActivation[] array2 = gameObjectActivations;
					foreach (GameObjectActivation val2 in array2)
					{
						array[num] = GameObjectActivation.op_Implicit(val2);
						num++;
					}
					gameObjectActivations2 = array;
				}
				else
				{
					gameObjectActivations2 = Array.Empty<GameObjectActivation>();
				}
				val.gameObjectActivations = gameObjectActivations2;
				val = skinDefParams;
				MeshReplacement[] meshReplacements2;
				if (orig.meshReplacements != null)
				{
					MeshReplacement[] meshReplacements = orig.meshReplacements;
					int num = 0;
					MeshReplacement[] array3 = (MeshReplacement[])(object)new MeshReplacement[meshReplacements.Length];
					MeshReplacement[] array4 = meshReplacements;
					foreach (MeshReplacement val3 in array4)
					{
						array3[num] = MeshReplacement.op_Implicit(val3);
						num++;
					}
					meshReplacements2 = array3;
				}
				else
				{
					meshReplacements2 = Array.Empty<MeshReplacement>();
				}
				val.meshReplacements = meshReplacements2;
				val = skinDefParams;
				ProjectileGhostReplacement[] projectileGhostReplacements2;
				if (orig.projectileGhostReplacements != null)
				{
					ProjectileGhostReplacement[] projectileGhostReplacements = orig.projectileGhostReplacements;
					int num = 0;
					ProjectileGhostReplacement[] array5 = (ProjectileGhostReplacement[])(object)new ProjectileGhostReplacement[projectileGhostReplacements.Length];
					ProjectileGhostReplacement[] array6 = projectileGhostReplacements;
					foreach (ProjectileGhostReplacement val4 in array6)
					{
						array5[num] = ProjectileGhostReplacement.op_Implicit(val4);
						num++;
					}
					projectileGhostReplacements2 = array5;
				}
				else
				{
					projectileGhostReplacements2 = Array.Empty<ProjectileGhostReplacement>();
				}
				val.projectileGhostReplacements = projectileGhostReplacements2;
				val = skinDefParams;
				MinionSkinReplacement[] minionSkinReplacements2;
				if (orig.minionSkinReplacements != null)
				{
					MinionSkinReplacement[] minionSkinReplacements = orig.minionSkinReplacements;
					int num = 0;
					MinionSkinReplacement[] array7 = (MinionSkinReplacement[])(object)new MinionSkinReplacement[minionSkinReplacements.Length];
					MinionSkinReplacement[] array8 = minionSkinReplacements;
					foreach (MinionSkinReplacement val5 in array8)
					{
						array7[num] = MinionSkinReplacement.op_Implicit(val5);
						num++;
					}
					minionSkinReplacements2 = array7;
				}
				else
				{
					minionSkinReplacements2 = Array.Empty<MinionSkinReplacement>();
				}
				val.minionSkinReplacements = minionSkinReplacements2;
			}
			IEnumerator enumerator = orig.BakeAsync();
			while (enumerator.MoveNext())
			{
			}
		}
	}
	public static class StringExtensions
	{
		private static readonly char[] _invalidConfigDefinitionChars = (char[])AccessTools.DeclaredField(typeof(ConfigDefinition), "_invalidConfigChars")?.GetValue(null);

		public static string FilterChars(this string str, char[] invalidChars)
		{
			if (str.IndexOfAny(invalidChars) == -1)
			{
				return str;
			}
			StringBuilder stringBuilder = StringBuilderPool.RentStringBuilder();
			foreach (char value in str)
			{
				if (Array.IndexOf(invalidChars, value) == -1)
				{
					stringBuilder.Append(value);
				}
			}
			string result = stringBuilder.ToString();
			StringBuilderPool.ReturnStringBuilder(stringBuilder);
			return result;
		}

		public static string FilterConfigKey(this string key)
		{
			if (_invalidConfigDefinitionChars == null)
			{
				Log.Error("_invalidConfigDefinitionChars is null", "D:\\Git\\RoR2\\MercSkinsFix\\MercSkinsFix\\StringExtensions.cs", "FilterConfigKey", 36);
				return key;
			}
			return key.FilterChars(_invalidConfigDefinitionChars).Trim();
		}
	}
}