Decompiled source of RumbleModUIPlus v2.0.0

Mods/RumbleModUIPlus.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using RumbleModUI;
using RumbleModUIPlus;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(RumbleModUIPlusClass), "RumbleModUIPlus", "2.0.0", "ninjaguardian", "https://thunderstore.io/c/rumble/p/ninjaguardian/RumbleModUIPlus")]
[assembly: MelonGame("Buckethead Entertainment", "RUMBLE")]
[assembly: MelonColor(255, 0, 160, 230)]
[assembly: MelonAuthorColor(255, 0, 160, 230)]
[assembly: MelonPlatformDomain(/*Could not decode attribute arguments.*/)]
[assembly: VerifyLoaderVersion("0.7.1", true)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ninjaguardian (github)")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2025 ninjaguardian (github), This work is dedicated to the public domain under CC0 1.0.")]
[assembly: AssemblyDescription("Adds stuff for devs to RumbleModUI (also some bug fixes)")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0")]
[assembly: AssemblyProduct("RumbleModUIPlus")]
[assembly: AssemblyTitle("RumbleModUIPlus")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ninjaguardian/RumbleModUIPlus")]
[assembly: AssemblyVersion("2.0.0.0")]
namespace RumbleModUIPlus;

public static class BuildInfo
{
	public const string ModName = "RumbleModUIPlus";

	public const string ModVersion = "2.0.0";

	public const string MLVersion = "0.7.1";

	public const string Author = "ninjaguardian";

	public const string DownloadLink = "https://thunderstore.io/c/rumble/p/ninjaguardian/RumbleModUIPlus";
}
public class Mod : Mod
{
	protected const string DuplicateErrorMsg = "AddToList failed: Name not unique";

	private string _modFormatVersion;

	public string ModFormatVersion
	{
		get
		{
			return _modFormatVersion ?? ((Mod)this).ModVersion;
		}
		set
		{
			_modFormatVersion = value;
		}
	}

	public ModSetting<string> AddDescriptionAtStart(string Name, string Value, string Description, Tags tags)
	{
		return AddDescriptionAtIndex(Name, Value, Description, tags, 0);
	}

	public ModSetting<string> AddDescriptionAtIndex(string Name, string Value, string Description, Tags tags, int Index)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<string> obj = new ModSetting<string>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)0;
		ModSetting<string> val = obj;
		tags.DoNotSave = true;
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSetting<string> AddToListAtStart(string Name, string Value, string Description, Tags tags)
	{
		return AddToListAtIndex(Name, Value, Description, tags, 0);
	}

	public ModSetting<string> AddToListAtIndex(string Name, string Value, string Description, Tags tags, int Index)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<string> obj = new ModSetting<string>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)1;
		ModSetting<string> val = obj;
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSetting<bool> AddToListAtStart(string Name, bool Value, int LinkGroup, string Description, Tags tags)
	{
		return AddToListAtIndex(Name, Value, LinkGroup, Description, tags, 0);
	}

	public ModSetting<bool> AddToListAtIndex(string Name, bool Value, int LinkGroup, string Description, Tags tags, int Index)
	{
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<bool> obj = new ModSetting<bool>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = LinkGroup;
		((ModSetting)obj).ValueType = (AvailableTypes)5;
		ModSetting<bool> val = obj;
		if (LinkGroup != 0)
		{
			((Mod)this).SetLinkGroup(LinkGroup, "Group");
			base.LinkGroups.Find((LinkGroup x) => x.Index == LinkGroup).Settings.Add((ModSetting)(object)val);
		}
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSetting<int> AddToListAtStart(string Name, int Value, string Description, Tags tags)
	{
		return AddToListAtIndex(Name, Value, Description, tags, 0);
	}

	public ModSetting<int> AddToListAtIndex(string Name, int Value, string Description, Tags tags, int Index)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<int> obj = new ModSetting<int>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)2;
		ModSetting<int> val = obj;
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSetting<float> AddToListAtStart(string Name, float Value, string Description, Tags tags)
	{
		return AddToListAtIndex(Name, Value, Description, tags, 0);
	}

	public ModSetting<float> AddToListAtIndex(string Name, float Value, string Description, Tags tags, int Index)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<float> obj = new ModSetting<float>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)3;
		ModSetting<float> val = obj;
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSetting<double> AddToListAtStart(string Name, double Value, string Description, Tags tags)
	{
		return AddToListAtIndex(Name, Value, Description, tags, 0);
	}

	public ModSetting<double> AddToListAtIndex(string Name, double Value, string Description, Tags tags, int Index)
	{
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == Name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + Name);
			return null;
		}
		ModSetting<double> obj = new ModSetting<double>
		{
			Name = Name,
			Description = Description
		};
		((ModSetting)obj).Value = Value;
		((ModSetting)obj).SavedValue = Value;
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)4;
		ModSetting<double> val = obj;
		((Mod)this).AddTags((ModSetting)(object)val, tags);
		if (Index < 0 || Index > base.Settings.Count)
		{
			MelonLogger.Error($"Index {Index} is out of bounds for list with size {base.Settings.Count}. Falling back to Settings.Add");
			base.Settings.Add((ModSetting)(object)val);
		}
		else
		{
			base.Settings.Insert(Index, (ModSetting)(object)val);
		}
		return val;
	}

	public ModSettingFolder AddFolder(string name, string description = "")
	{
		//IL_0082: Unknown result type (might be due to invalid IL or missing references)
		if (base.Settings.Count > 0 && base.Settings.Exists((ModSetting x) => x.Name == name))
		{
			MelonLogger.Warning("AddToList failed: Name not unique: " + name);
			return null;
		}
		ModSettingFolder obj = new ModSettingFolder
		{
			Name = name,
			Description = description
		};
		((ModSetting)obj).Value = "";
		((ModSetting)obj).SavedValue = "";
		((ModSetting)obj).LinkGroup = 0;
		((ModSetting)obj).ValueType = (AvailableTypes)0;
		ModSettingFolder modSettingFolder = obj;
		Tags tags = new Tags();
		((Tags)tags).DoNotSave = true;
		((Tags)tags).IsEmpty = true;
		((Mod)this).AddTags((ModSetting)(object)modSettingFolder, (Tags)(object)tags);
		base.Settings.Add((ModSetting)(object)modSettingFolder);
		return modSettingFolder;
	}
}
public class RumbleModUIPlusClass : MelonMod
{
	[HarmonyPatch(typeof(UI), "DoOnSettingsSelect")]
	private static class UI_DoOnSettingsSelect_Patch
	{
		private static void Prefix(UI __instance)
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Invalid comparison between Unknown and I4
			Mod selectedMod = getSelectedMod(__instance);
			int selectedModSettingIndex = getSelectedModSettingIndex(__instance);
			if (!(selectedMod.Settings[selectedModSettingIndex] is ModSettingFolder modSettingFolder))
			{
				return;
			}
			UI_OnSettingsSelectionChange_Patch.Empty(__instance);
			List<string> val = new List<string>();
			val.Add("<―― back");
			List<LinkGroup> linkGroups = selectedMod.LinkGroups;
			Dictionary<int, int> dictionary = UI_OnSettingsSelectionChange_Patch.ItemLookup[__instance];
			dictionary.Add(0, selectedMod.Settings.IndexOf((ModSetting)(object)modSettingFolder.Parent));
			int num = -1;
			int i = 0;
			int count = val.Count;
			for (; i < selectedMod.Settings.Count; i++)
			{
				ModSetting setting = selectedMod.Settings[i];
				if (i == selectedModSettingIndex)
				{
					num = count;
					dictionary.Add(count++, i);
					val.Add(setting.Name);
				}
				else
				{
					if (!modSettingFolder.Settings.Contains(setting))
					{
						continue;
					}
					dictionary.Add(count++, i);
					if ((int)setting.ValueType == 5 && setting.LinkGroup != 0)
					{
						val.Add(linkGroups.Find((LinkGroup x) => x.Index == setting.LinkGroup).Name + " - " + setting.Name);
					}
					else
					{
						val.Add(setting.Name);
					}
				}
			}
			UI_OnSettingsSelectionChange_Patch.SimplifyItemLookup(__instance, dictionary);
			TMP_Dropdown uI_DropDown_Settings = getUI_DropDown_Settings(__instance);
			uI_DropDown_Settings.ClearOptions();
			uI_DropDown_Settings.AddOptions(val);
			if (num == -1)
			{
				MelonLogger.Error("Could not find selected ModSettingFolder");
			}
			else
			{
				uI_DropDown_Settings.SetValueWithoutNotify(num);
			}
		}
	}

	[HarmonyPatch(typeof(UI), "DoOnModSelect")]
	private static class UI_DoOnModSelect_Patch
	{
		private class SettingOverride
		{
			internal int firstSummary = -1;

			internal int firstNonFolder = -1;
		}

		private static readonly Dictionary<UI, SettingOverride> settingOverride = new Dictionary<UI, SettingOverride>();

		private static readonly Dictionary<UI, int> settingIdx = new Dictionary<UI, int>();

		private static void Prefix(UI __instance)
		{
			if ((int)SettingsOverride.GetValue(__instance) == 0)
			{
				settingOverride.Add(__instance, new SettingOverride());
			}
			settingIdx.Add(__instance, 0);
			UI_OnSettingsSelectionChange_Patch.Empty(__instance);
		}

		private static bool DoContinue(UI instance, ModSetting setting)
		{
			int value = settingIdx[instance]++;
			if (setting.Tags is Tags tags && tags.InFolder)
			{
				return true;
			}
			int count = UI_OnSettingsSelectionChange_Patch.ItemLookup[instance].Count;
			if (settingOverride.TryGetValue(instance, out var value2))
			{
				if (value2.firstSummary == -1 && setting.Tags.IsSummary)
				{
					value2.firstSummary = count;
				}
				else if (value2.firstNonFolder == -1 && !(setting is ModSettingFolder))
				{
					value2.firstNonFolder = count;
				}
			}
			UI_OnSettingsSelectionChange_Patch.ItemLookup[instance].Add(count, value);
			return false;
		}

		private static void Finalizer(UI __instance)
		{
			if (__instance != null)
			{
				settingOverride.Remove(__instance);
				if (!settingIdx.Remove(__instance))
				{
					MelonLogger.Error("Removal of UI from settingIdx failed");
				}
				if (UI_OnSettingsSelectionChange_Patch.ItemLookup.TryGetValue(__instance, out var value))
				{
					UI_OnSettingsSelectionChange_Patch.SimplifyItemLookup(__instance, value);
				}
			}
		}

		private static void SettingsOverrideHelper(UI instance)
		{
			if (settingOverride.TryGetValue(instance, out var value))
			{
				SettingsOverride.SetValue(instance, (value.firstSummary != -1) ? value.firstSummary : ((value.firstNonFolder != -1) ? value.firstNonFolder : 0));
				settingOverride.Remove(instance);
			}
		}

		private static int LookupSetting(UI instance, int settingOverride)
		{
			if (!UI_OnSettingsSelectionChange_Patch.ItemLookup.TryGetValue(instance, out var value) || !value.TryGetValue(settingOverride, out var value2))
			{
				return settingOverride;
			}
			return value2;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: 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_0027: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Expected O, but got Unknown
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Expected O, but got Unknown
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Expected O, but got Unknown
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Expected O, but got Unknown
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Expected O, but got Unknown
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Expected O, but got Unknown
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Expected O, but got Unknown
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Expected O, but got Unknown
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Expected O, but got Unknown
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b8: Expected O, but got Unknown
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Expected O, but got Unknown
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Expected O, but got Unknown
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Expected O, but got Unknown
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Expected O, but got Unknown
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Expected O, but got Unknown
			//IL_03d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d9: Expected O, but got Unknown
			Label label = default(Label);
			return new CodeMatcher(instructions, generator).Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Brtrue, (object)null, (string)null)
			}).ThrowIfInvalid("Could not match end of foreach in DoOnModSelect")
				.CreateLabel(ref label)
				.Start()
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
				{
					new CodeMatch((OpCode?)OpCodes.Ldloc_2, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloca_S, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stfld, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Nop, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_2, (object)null, (string)null)
				})
				.ThrowIfInvalid("Could not match start of foreach in DoOnModSelect")
				.Insert((CodeInstruction[])(object)new CodeInstruction[5]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Ldloc_2, (object)null),
					new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(UI).GetNestedType("<>c__DisplayClass92_0", BindingFlags.Instance | BindingFlags.NonPublic), "setting")),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UI_DoOnModSelect_Patch), "DoContinue", (Type[])null, (Type[])null)),
					new CodeInstruction(OpCodes.Brtrue, (object)label)
				})
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Cgt_Un, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null)
				})
				.ThrowIfInvalid("Could not match: this.SettingsOverride != 0")
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null),
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UI_DoOnModSelect_Patch), "SettingsOverrideHelper", (Type[])null, (Type[])null))
				})
				.RemoveInstructions(8)
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[4]
				{
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stfld, (object)null, (string)null)
				})
				.ThrowIfInvalid("Could not match: this.SettingsSelection = this.SettingsOverride")
				.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Ldarg_0, (object)null)
				})
				.Advance(4)
				.Insert((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(UI_DoOnModSelect_Patch), "LookupSetting", (Type[])null, (Type[])null))
				})
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.PropertySetter(typeof(TMP_Dropdown), "value"), (string)null)
				})
				.ThrowIfInvalid("Could not match callvirt TMP_Dropdown.value setter")
				.SetOperandAndAdvance((object)AccessTools.Method(typeof(TMP_Dropdown), "SetValueWithoutNotify", new Type[1] { typeof(int) }, (Type[])null))
				.MatchForward(false, (CodeMatch[])(object)new CodeMatch[5]
				{
					new CodeMatch((OpCode?)OpCodes.Nop, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldc_I4_0, (object)null, (string)null),
					new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(typeof(UI), "SettingsSelection"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Nop, (object)null, (string)null)
				})
				.ThrowIfInvalid("Could not match else")
				.Advance(-1)
				.RemoveInstructions(6)
				.InstructionEnumeration();
		}
	}

	[HarmonyPatch(typeof(UI), "OnSettingsSelectionChange")]
	private static class UI_OnSettingsSelectionChange_Patch
	{
		internal static readonly Dictionary<UI, Dictionary<int, int>> ItemLookup = new Dictionary<UI, Dictionary<int, int>>();

		internal static void SimplifyItemLookup(UI instance, Dictionary<int, int> map)
		{
			foreach (int item in map.Keys.Where((int k) => (k != 0) ? (map[k] == k) : (map[0] == 0)).ToList())
			{
				map.Remove(item);
			}
			if (map.Count == 0)
			{
				ItemLookup.Remove(instance);
			}
		}

		private static bool Prefix(UI __instance, ref int Input)
		{
			if (ItemLookup.TryGetValue(__instance, out var value) && value.TryGetValue(Input, out var value2))
			{
				if (value2 == -1)
				{
					SettingsOverride.SetValue(__instance, 0);
					DoOnModSelect.Invoke(__instance, null);
					return false;
				}
				Input = value2;
			}
			return true;
		}

		internal static void Empty(UI instance)
		{
			if (!ItemLookup.TryAdd(instance, new Dictionary<int, int>()))
			{
				ItemLookup[instance].Clear();
			}
		}
	}

	private static class Mod_Log_Patches
	{
		private static readonly CodeMatch MelonLoggerMsg = new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(MelonLogger), "Msg", new Type[1] { typeof(string) }, (Type[])null), (string)null);

		private static readonly CodeInstruction MelonLoggerWarning = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(MelonLogger), "Warning", new Type[1] { typeof(string) }, (Type[])null));

		private static HarmonyMethod GetTranspiler => new HarmonyMethod(typeof(Mod_Log_Patches).GetMethod("Transpiler", BindingFlags.Static | BindingFlags.NonPublic));

		internal static void PatchAll(Harmony harmony)
		{
			MethodInfo[] methods = typeof(Mod).GetMethods();
			foreach (MethodInfo methodInfo in methods)
			{
				if (methodInfo.DeclaringType == typeof(Mod))
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, GetTranspiler, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return new CodeMatcher(instructions, generator).Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { MelonLoggerMsg }).Repeat((Action<CodeMatcher>)delegate(CodeMatcher match)
			{
				match.RemoveInstruction();
				match.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { MelonLoggerWarning });
			}, (Action<string>)null)
				.InstructionEnumeration();
		}
	}

	[HarmonyPatch(typeof(UI), "SaveSettings")]
	private static class UI_SaveSettings_Patch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			foreach (CodeInstruction instruction in instructions)
			{
				yield return instruction;
				if (instruction.opcode == OpCodes.Ldstr && instruction.operand is string text && text.StartsWith("Created by: "))
				{
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					yield return Transpilers.EmitDelegate<Func<string, UI, string>>((Func<string, UI, string>)((string str, UI instance) => (!(getSelectedMod(instance) is Mod)) ? str : (str + " and RumbleModUIPlus 2.0.0")));
				}
			}
		}
	}

	[HarmonyPatch(typeof(Mod), "GetFromFile")]
	private static class Mod_GetFromFile_Patch
	{
		private static bool Prefix(Mod __instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Folders val = (Folders)Mod_Folders.GetValue(__instance);
			bool flag = (bool)Mod_debug.GetValue(__instance);
			string subFolder = val.GetSubFolder(0);
			string path = ((subFolder == null) ? val.GetFolderString("", false) : val.GetFolderString(subFolder, false)) + "\\" + __instance.SettingsFile;
			if (File.Exists(path))
			{
				string[] array = File.ReadAllLines(path);
				if (array.Length >= 2 && array[0] == __instance.ModName + " " + ((__instance is Mod mod) ? mod.ModFormatVersion : __instance.ModVersion))
				{
					HashSet<ModSetting> hashSet = new HashSet<ModSetting>();
					for (int i = 2; i < array.Length; i++)
					{
						string text = array[i];
						foreach (ModSetting setting in __instance.Settings)
						{
							if (!hashSet.Contains(setting) && !setting.Tags.DoNotSave && text.StartsWith(setting.Name + ": "))
							{
								MethodInfo mod_ValueValidation = Mod_ValueValidation;
								object[] array2 = new object[2];
								string text2 = text;
								int num = setting.Name.Length + 2;
								array2[0] = text2.Substring(num, text2.Length - num);
								array2[1] = setting;
								if ((bool)mod_ValueValidation.Invoke(__instance, array2))
								{
									setting.SavedValue = setting.Value;
								}
								else
								{
									MelonLogger.Msg(__instance.ModName + " - " + setting.Name + " File Read Error.");
								}
								if (flag)
								{
									MelonLogger.Msg(__instance.ModName + " - " + setting.Name + " " + setting.Value);
								}
								hashSet.Add(setting);
								break;
							}
						}
					}
					Mod_IsFileLoadedSetter.Invoke(__instance, new object[1] { true });
				}
				else
				{
					Mod_IsFileLoadedSetter.Invoke(__instance, new object[1] { false });
					if (array.Length < 2)
					{
						MelonLogger.Error("Could not load " + __instance.ModName + "'s settings because there were less than two lines in the settings file.");
					}
					else if (flag)
					{
						MelonLogger.Warning(__instance.ModName + "'s settings did not match pattern.");
					}
				}
			}
			return false;
		}
	}

	[HarmonyPatch(typeof(Mod), "SaveModData")]
	private static class Mod_SaveModData
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo get_ModVersion = AccessTools.PropertyGetter(typeof(Mod), "ModVersion");
			foreach (CodeInstruction instruction in instructions)
			{
				if (instruction.opcode == OpCodes.Call && instruction.operand is MethodInfo methodInfo && methodInfo == get_ModVersion)
				{
					yield return Transpilers.EmitDelegate<Func<Mod, string>>((Func<Mod, string>)((Mod instance) => (!(instance is Mod mod)) ? instance.ModVersion : mod.ModFormatVersion));
				}
				else
				{
					yield return instruction;
				}
			}
		}
	}

	private static FieldInfo Mod_Options = AccessTools.Field(typeof(UI), "Mod_Options");

	private static FieldInfo ModSelection = AccessTools.Field(typeof(UI), "ModSelection");

	private static FieldInfo SettingsSelection = AccessTools.Field(typeof(UI), "SettingsSelection");

	private static FieldInfo SettingsOverride = AccessTools.Field(typeof(UI), "SettingsOverride");

	private static FieldInfo UI_DropDown_Settings = AccessTools.Field(typeof(UI), "UI_DropDown_Settings");

	private static MethodInfo DoOnModSelect = AccessTools.Method(typeof(UI), "DoOnModSelect", (Type[])null, (Type[])null);

	private static FieldInfo Mod_Folders = AccessTools.Field(typeof(Mod), "Folders");

	private static FieldInfo Mod_debug = AccessTools.Field(typeof(Mod), "debug");

	private static MethodInfo Mod_IsFileLoadedSetter = AccessTools.PropertySetter(typeof(Mod), "IsFileLoaded");

	private static MethodInfo Mod_ValueValidation = AccessTools.Method(typeof(Mod), "ValueValidation", (Type[])null, (Type[])null);

	public override void OnInitializeMelon()
	{
		Mod_Log_Patches.PatchAll(((MelonBase)this).HarmonyInstance);
	}

	private static Mod getSelectedMod(UI instance)
	{
		return ((List<Mod>)Mod_Options.GetValue(instance))[(int)ModSelection.GetValue(instance)];
	}

	private static int getSelectedModSettingIndex(UI instance)
	{
		return (int)SettingsSelection.GetValue(instance);
	}

	private static TMP_Dropdown getUI_DropDown_Settings(UI instance)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		return ((GameObject)UI_DropDown_Settings.GetValue(instance)).GetComponent<TMP_Dropdown>();
	}

	public static Mod GetSelectedMod()
	{
		return getSelectedMod(UI.instance);
	}

	public static ModSetting GetSelectedModSetting()
	{
		return getSelectedMod(UI.instance).Settings[getSelectedModSettingIndex(UI.instance)];
	}
}
public class ModSettingFolder : ModSetting
{
	public readonly HashSet<ModSetting> Settings = new HashSet<ModSetting>();

	internal ModSettingFolder Parent;

	public override object Value { get; set; }

	public override object SavedValue { get; set; }

	public ModSettingFolder AddSetting(ModSetting setting)
	{
		if (setting.Tags is Tags tags)
		{
			tags.InFolder = true;
		}
		else
		{
			setting.Tags = (Tags)(object)new Tags(setting.Tags)
			{
				InFolder = true
			};
		}
		if (setting is ModSettingFolder modSettingFolder)
		{
			modSettingFolder.Parent = this;
		}
		Settings.Add(setting);
		return this;
	}

	public bool RemoveSetting(ModSetting setting)
	{
		((Tags)(object)setting.Tags).InFolder = false;
		if (setting is ModSettingFolder modSettingFolder)
		{
			modSettingFolder.Parent = null;
		}
		return Settings.Remove(setting);
	}

	public ModSettingFolder RemoveSettingC(ModSetting setting, out bool success)
	{
		success = RemoveSetting(setting);
		return this;
	}

	public ModSettingFolder RemoveSettingC(ModSetting setting)
	{
		RemoveSetting(setting);
		return this;
	}

	public ModSettingFolder RemoveAllSettings()
	{
		foreach (ModSetting setting in Settings)
		{
			RemoveSetting(setting);
		}
		return this;
	}

	public bool RemoveFolder(List<ModSetting> settings)
	{
		RemoveAllSettings();
		return settings.Remove((ModSetting)(object)this);
	}

	public bool RemoveFolder(Mod mod)
	{
		return RemoveFolder(mod.Settings);
	}

	public override string GetValueAsString()
	{
		return "";
	}
}
public class Tags : Tags
{
	public bool InFolder { get; set; }

	public Tags()
	{
		InFolder = false;
	}

	public Tags(Tags tags)
		: this()
	{
		((Tags)this).IsSummary = tags.IsSummary;
		((Tags)this).IsEmpty = tags.IsEmpty;
		((Tags)this).IsCustom = tags.IsCustom;
		((Tags)this).CustomString = tags.CustomString;
		((Tags)this).IsPassword = tags.IsPassword;
		((Tags)this).DoNotSave = tags.DoNotSave;
	}
}