Decompiled source of DebugToolkit v3.18.2
DebugToolkit.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DebugToolkit.Code; using DebugToolkit.Commands; using DebugToolkit.Permissions; using EntityStates; using EntityStates.TeleporterHealNovaController; using HG; using HG.Reflection; using IL.RoR2; using IL.RoR2.Networking; using IL.RoR2.UI; using KinematicCharacterController; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.RoR2; using On.RoR2.Networking; using On.RoR2.UI; using R2API; using R2API.Utils; using Rewired; using RoR2; using RoR2.Artifacts; using RoR2.CharacterAI; using RoR2.ConVar; using RoR2.ExpansionManagement; using RoR2.Navigation; using RoR2.Networking; using RoR2.UI; using ShareSuite; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.AddressableAssets.ResourceLocators; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.UI; [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DebugToolkit Contributors")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyProduct("DebugToolkit")] [assembly: AssemblyTitle("DebugToolkit")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/harbingerofme/DebugToolkit")] [assembly: AssemblyInformationalVersion("3.18.2+34e2559c82b37a2ac6426166207b30426f323a53")] [assembly: AssemblyCopyright("2024 DebugToolkit Contributors")] [assembly: AssemblyDescription("DebugToolkit is an expansive list of console commands for Risk of Rain 2, intended to make forcing specific situation easier. This is supposed to help with testing of interactions, mods, and what else.")] [assembly: AssemblyFileVersion("3.18.2.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.18.2.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [Microsoft.CodeAnalysis.Embedded] [CompilerGenerated] [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 DebugToolkit { [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] public sealed class AutoCompleteAttribute : Attribute { internal class Result { internal AutoCompleteParser parser; internal string signature; internal List<string>[] parameters; internal Result(AutoCompleteParser parser, string signature, List<string>[] parameters) { this.parser = parser; this.signature = signature; this.parameters = parameters; } } public string args; public AutoCompleteAttribute(string args) { this.args = args; } internal Result Parse(AutoCompleteParser parser) { MatchCollection matchCollection = Regex.Matches(args, "\\{(.*?)\\}|\\[(.*?)\\]|<(.*?)>"); List<string>[] array = new List<string>[matchCollection.Count]; for (int i = 0; i < matchCollection.Count; i++) { GroupCollection groups = matchCollection[i].Groups; string text = ((!string.IsNullOrEmpty(groups[1].Value)) ? groups[1] : ((!string.IsNullOrEmpty(groups[2].Value)) ? groups[2] : groups[3])).Value.Split(':')[0]; Match match = Regex.Match(text, "\\((.*)\\)"); array[i] = new List<string>(); string[] strings; AutoCompleteParser.DynamicCatalog catalog; if (match.Success) { foreach (string item in from s in match.Groups[1].Value.Split('|') select s.Trim()) { string text2 = item.Trim(); if (text2.StartsWith("'") && text2.EndsWith("'")) { array[i].Add(text2); } else if (parser.TryGetStaticVariable(text2, out strings) || parser.TryGetDynamicVariable(text2, out catalog)) { array[i].Add(text2); } } } else { text = text.Trim(); if (parser.TryGetStaticVariable(text, out strings) || parser.TryGetDynamicVariable(text, out catalog)) { array[i].Add(text); } } } return new Result(parser, string.Join(" ", from Match m in matchCollection select m.Groups[0].Value), array); } } internal static class AutoCompleteManager { private static readonly Dictionary<string, AutoCompleteAttribute.Result> commands = new Dictionary<string, AutoCompleteAttribute.Result>(); internal static string CurrentCommand { get; private set; } internal static List<string>[] CurrentParameters { get; private set; } internal static string CurrentSignature { get; private set; } internal static void PrepareCommandOptions(string commandName) { commandName = commandName.ToLower(); if (CurrentCommand == commandName) { return; } CurrentCommand = commandName; if (!commands.TryGetValue(commandName, out var value)) { CurrentParameters = new List<string>[0]; CurrentSignature = null; return; } AutoCompleteParser parser = value.parser; List<string>[] array = new List<string>[value.parameters.Length]; for (int i = 0; i < array.Length; i++) { array[i] = new List<string>(); foreach (string item in value.parameters[i]) { string[] strings; AutoCompleteParser.DynamicCatalog catalog; if (item.StartsWith("'") && item.EndsWith("'")) { array[i].Add(item.Trim('\'')); } else if (parser.TryGetStaticVariable(item, out strings)) { array[i].AddRange(strings); } else if (parser.TryGetDynamicVariable(item, out catalog)) { array[i].AddRange(catalog.Rebuild()); } } } CurrentParameters = array; CurrentSignature = value.signature; } internal static void ClearCommandOptions() { CurrentCommand = null; CurrentParameters = null; CurrentSignature = null; } internal static void RegisterCommand(string commandName, AutoCompleteAttribute.Result parameters) { commands[commandName.ToLower()] = parameters; } internal static void RegisterAutoCompleteCommands() { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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) AutoCompleteParser autoCompleteParser = new AutoCompleteParser(); autoCompleteParser.RegisterStaticVariable("0", "0"); autoCompleteParser.RegisterStaticVariable("1", "1"); autoCompleteParser.RegisterStaticVariable("ai", MasterCatalog.allAiMasters.Select((CharacterMaster i) => $"{(int)i.masterIndex}|{((Object)i).name}|{StringFinder.GetLangInvar(StringFinder.GetMasterName(i))}")); autoCompleteParser.RegisterStaticVariable("artifact", ArtifactCatalog.artifactDefs.Select((ArtifactDef i) => $"{(int)i.artifactIndex}|{i.cachedName}|{StringFinder.GetLangInvar(i.nameToken)}")); autoCompleteParser.RegisterStaticVariable("body", BodyCatalog.allBodyPrefabBodyBodyComponents.Select((CharacterBody i) => $"{(int)i.bodyIndex}|{((Object)i).name}|{StringFinder.GetLangInvar(i.baseNameToken)}")); autoCompleteParser.RegisterStaticVariable("buff", BuffCatalog.buffDefs.Select((BuffDef i) => $"{(int)i.buffIndex}|{StringFinder.GetLangInvar(((Object)i).name)}")); autoCompleteParser.RegisterStaticVariable("droptable", from i in (IEnumerable<ItemTierDef>)(object)ItemTierCatalog.allItemTierDefs orderby i.tier select $"{(int)i.tier}|{((Object)i).name}"); autoCompleteParser.RegisterStaticVariable("elite", new string[1] { "-1|None" }.Concat(EliteCatalog.eliteDefs.Select((EliteDef i) => $"{(int)i.eliteIndex}|{((Object)i).name}|{StringFinder.GetLangInvar(i.modifierToken)}"))); autoCompleteParser.RegisterStaticVariable("equip", EquipmentCatalog.equipmentDefs.Select((EquipmentDef i) => $"{(int)i.equipmentIndex}|{((Object)i).name}|{StringFinder.GetLangInvar(i.nameToken)}")); autoCompleteParser.RegisterStaticVariable("item", ((IEnumerable<ItemDef>)(object)ItemCatalog.allItemDefs).Select((ItemDef i) => $"{(int)i.itemIndex}|{((Object)i).name}|{StringFinder.GetLangInvar(i.nameToken)}")); autoCompleteParser.RegisterStaticVariable("specific_stage", from i in (IEnumerable<SceneDef>)(object)SceneCatalog.allSceneDefs where !i.isOfflineScene select $"{(int)i.sceneDefIndex}|{i.cachedName}|{StringFinder.GetLangInvar(i.nameToken)}"); autoCompleteParser.RegisterStaticVariable("dot", CollectEnumNames(typeof(DotIndex), typeof(sbyte)).Skip(1)); autoCompleteParser.RegisterStaticVariable("permission_level", CollectEnumNames(typeof(Level), typeof(int))); autoCompleteParser.RegisterStaticVariable("team", CollectEnumNames(typeof(TeamIndex), typeof(sbyte))); autoCompleteParser.RegisterDynamicVariable("director_card", StringFinder.Instance.DirectorCards, "spawnCard"); autoCompleteParser.RegisterDynamicVariable("interactable", StringFinder.Instance.InteractableSpawnCards); autoCompleteParser.RegisterDynamicVariable("player", NetworkUser.instancesList, "userName"); autoCompleteParser.Scan(Assembly.GetExecutingAssembly()); } private static IEnumerable<string> CollectEnumNames(Type enumType, Type castTo) { if (enumType == null) { Log.Message("Input type is null", Log.LogLevel.Warning, Log.Target.Bepinex); yield break; } if (!enumType.IsEnum) { Log.Message("Input type is not enum: " + enumType.Name, Log.LogLevel.Warning, Log.Target.Bepinex); yield break; } FieldInfo[] fields = enumType.GetFields(); for (int i = 0; i < fields.Length; i++) { string name = fields[i].Name; if (name != "value__" && name != "Count") { yield return $"{Convert.ChangeType(Enum.Parse(enumType, name), castTo)}|{name}"; } } } } public sealed class AutoCompleteParser { internal class DynamicCatalog { private readonly IEnumerable<object> catalog; private readonly string nestedField; private readonly bool isToken; private readonly bool showIndex; internal DynamicCatalog(IEnumerable<object> catalog, string nestedField, bool isToken, bool showIndex) { this.catalog = catalog; this.nestedField = nestedField; this.isToken = isToken; this.showIndex = showIndex; } internal IEnumerable<string> Rebuild() { string[] block = ((!string.IsNullOrEmpty(nestedField)) ? nestedField.Split('/') : new string[0]); int index = 0; foreach (object item in catalog) { string text; if (block.Length != 0) { object fieldValue = Reflection.GetFieldValue<object>(item, block[0]); for (int i = 1; i < block.Length; i++) { fieldValue = Reflection.GetFieldValue<object>(fieldValue, block[i]); } text = fieldValue.ToString(); } else { text = item.ToString(); } if (text.Contains("(RoR")) { text = text.Substring(0, text.IndexOf('(')); } text = (isToken ? StringFinder.GetLangInvar(text) : StringFinder.RemoveSpacesAndAlike(text)); yield return showIndex ? $"{index}|{text}" : text; index++; } } } private readonly Dictionary<string, string[]> staticVariables = new Dictionary<string, string[]>(); private readonly Dictionary<string, DynamicCatalog> dynamicVariables = new Dictionary<string, DynamicCatalog>(); public void RegisterStaticVariable(string name, string value) { RegisterStaticVariable(name, new string[1] { value }); } public void RegisterStaticVariable(string name, IEnumerable<string> values) { staticVariables[name] = values.ToArray(); } public void RegisterDynamicVariable(string name, IEnumerable<object> catalog, string nestedField = "", bool isToken = false, bool showIndex = true) { dynamicVariables[name] = new DynamicCatalog(catalog, nestedField, isToken, showIndex); } internal bool TryGetStaticVariable(string name, out string[] strings) { return staticVariables.TryGetValue(name, out strings); } internal bool TryGetDynamicVariable(string name, out DynamicCatalog catalog) { return dynamicVariables.TryGetValue(name, out catalog); } public void Scan(Assembly assembly) { if (assembly == null) { Log.Message("Null assembly encountered for autocompletion scanning", Log.LogLevel.Warning, Log.Target.Bepinex); return; } Type[] source; try { source = assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { source = ex.Types.Where((Type x) => x != null).ToArray(); Exception[] loaderExceptions = ex.LoaderExceptions; for (int i = 0; i < loaderExceptions.Length; i++) { _ = loaderExceptions[i]; Log.Message(ex.Message, Log.LogLevel.Error, Log.Target.Bepinex); } } foreach (MethodInfo item in source.SelectMany((Type x) => x.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))) { object[] customAttributes; try { customAttributes = item.GetCustomAttributes(inherit: false); } catch (TypeLoadException ex2) { Log.Message(ex2.Message, Log.LogLevel.Error, Log.Target.Bepinex); continue; } catch (InvalidOperationException ex3) { Log.Message(ex3.Message, Log.LogLevel.Error, Log.Target.Bepinex); continue; } if (customAttributes == null) { continue; } AutoCompleteAttribute autoCompleteAttribute = customAttributes.OfType<AutoCompleteAttribute>().DefaultIfEmpty(null).FirstOrDefault(); if (autoCompleteAttribute == null) { continue; } ConCommandAttribute[] array = customAttributes.OfType<ConCommandAttribute>().ToArray(); if (array.Length != 0) { AutoCompleteAttribute.Result parameters = autoCompleteAttribute.Parse(this); ConCommandAttribute[] array2 = array; for (int i = 0; i < array2.Length; i++) { AutoCompleteManager.RegisterCommand(array2[i].commandName, parameters); } } } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("iHarbHD.DebugToolkit", "DebugToolkit", "3.18.2")] public class DebugToolkit : BaseUnityPlugin { public const string modname = "DebugToolkit"; public const string modver = "3.18.2"; public const string GUID = "iHarbHD.DebugToolkit"; internal static ConfigFile Configuration; private void Awake() { Configuration = ((BaseUnityPlugin)this).Config; new Log(((BaseUnityPlugin)this).Logger); Log.Message("Created by Harb, iDeathHD and . Based on RoR2Cheats by Morris1927.", Log.LogLevel.Info, Log.Target.Bepinex); MacroSystem.Init(); PermissionSystem.Init(); Hooks.InitializeHooks(); NetworkManager.Init(); } private void LogBuildInfo() { } private void Start() { _ = StringFinder.Instance; } private void Update() { MacroSystem.Update(); if (Object.op_Implicit((Object)(object)Run.instance) && Command_Noclip.IsActivated) { Command_Noclip.Update(); } } public static void InvokeCMD(NetworkUser user, string commandName, params string[] arguments) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) List<string> list = arguments.ToList(); CmdSender val = default(CmdSender); ((CmdSender)(ref val))..ctor(user); if (Object.op_Implicit((Object)(object)Console.instance)) { Console.instance.RunCmd(val, commandName, list); } else { Log.Message("InvokeCMD called whilst no console instance exists.", Log.LogLevel.Error, Log.Target.Bepinex); } } public static string GetModVer() { return "3.18.2"; } } public sealed class Hooks { internal struct PingCache { internal CharacterBody body; internal CharacterMaster master; } [CompilerGenerated] private static class <>O { public static Manipulator <0>__UnlockConsole; public static hook_CacheConVars <1>__InitCommandsAndFreeConvars; public static Manipulator <2>__WarnUserOfServerCommandOffline; public static hook_SetSearchString <3>__BetterAutoCompletion; public static Action <4>__InitDroptableData; public static Action <5>__InitPortals; public static Action <6>__RegisterAutoCompleteCommands; public static Action<Run> <7>__CollectItemTiers; public static hook_Start <8>__AddConCommandSignatureHint; public static hook_OnInputFieldValueChanged <9>__UpdateCommandSignature; public static Manipulator <10>__ApplyTextWithoutColorTags; public static Manipulator <11>__SmoothDropDownSuggestionNavigation; public static Manipulator <12>__AllowTabAutocompleteConCommands; public static Manipulator <13>__EnableCheatsInCCSetScene; public static hook_CCSceneList <14>__OverrideVanillaSceneList; public static hook_Save <15>__PreventSave; public static hook_RebuildPing <16>__InterceptPing; public static Manipulator <17>__InfiniteTowerRun_BeginNextWave; public static hook_SetNextSpawnAsBoss <18>__SetNextBossForDirector; public static hook_Initialize <19>__SetNextBossForSimulacrumDirector; public static hook_AttemptSpawnOnTarget <20>__OverrideBossCombatDirectorSpawnResult; public static hook_Start <21>__CreateNetworkObject; public static hook_OnDestroy <22>__DestroyNetworkObject; public static hook_OnStopClient <23>__DisableOnStopClient; public static hook_TeleportBody <24>__DisableOOBCheck; public static Action<Run> <25>__DisableOnRunDestroy; public static hook_TakeDamage <26>__NonLethalDamage; public static hook_Awake <27>__SetGodMode; public static Manipulator <28>__FixCommandHelpText; public static Manipulator <29>__FixCCFind; public static hook_IsAvailable <30>__ForceFamilyDirectorCardCategorySelectionToBeAvailable; public static hook_GenerateWeightedSelection <31>__ForceFamilyEventForDccsPoolStages; public static hook_RebuildCards <32>__ForceFamilyEvent; } private const ConVarFlags AllFlagsNoCheat = 23; private const string GRAY = "<color=#808080>"; private const string COMMAND_SIGNATURE = "<color=#ffa000>{0} {1}</color>"; private static orig_RunCmd _origRunCmd; private static bool buddha; private static bool god; private static GameObject commandSignatureText; private static CombatDirector bossDirector; private static bool skipSpawnIfTooCheapBackup; private static readonly Dictionary<CharacterMaster, PingCache> pingedTargets = new Dictionary<CharacterMaster, PingCache>(); private const float changeSelectedItemTimer = 0.1f; private static float _lastSelectedItemChange; public static void InitializeHooks() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Expected O, but got Unknown //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Expected O, but got Unknown //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Expected O, but got Unknown //IL_02a6: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Expected O, but got Unknown //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Expected O, but got Unknown //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Expected O, but got Unknown //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Expected O, but got Unknown //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Expected O, but got Unknown //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Expected O, but got Unknown //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Expected O, but got Unknown //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Expected O, but got Unknown //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Expected O, but got Unknown //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Expected O, but got Unknown //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Unknown result type (might be due to invalid IL or missing references) //IL_04b5: Expected O, but got Unknown BindingFlags bindingAttr = (BindingFlags)(-1); MethodInfo? methodInfo = typeof(Console).GetNestedTypes(bindingAttr).FirstOrDefault((Type t) => t.Name.Contains("AwakeCoroutine")).GetMethods(bindingAttr) .FirstOrDefault((MethodInfo m) => m.Name.Contains("MoveNext")); object obj = <>O.<0>__UnlockConsole; if (obj == null) { Manipulator val = UnlockConsole; <>O.<0>__UnlockConsole = val; obj = (object)val; } new ILHook((MethodBase)methodInfo, (Manipulator)obj); object obj2 = <>O.<1>__InitCommandsAndFreeConvars; if (obj2 == null) { hook_CacheConVars val2 = InitCommandsAndFreeConvars; <>O.<1>__InitCommandsAndFreeConvars = val2; obj2 = (object)val2; } Console.CacheConVars += (hook_CacheConVars)obj2; _origRunCmd = new Hook((MethodBase)Reflection.GetMethodCached(typeof(Console), "RunCmd"), Reflection.GetMethodCached(typeof(Hooks), "LogNetworkCommandsAndCheckPermissions"), new HookConfig { Priority = 1 }).GenerateTrampoline<orig_RunCmd>(); object obj3 = <>O.<2>__WarnUserOfServerCommandOffline; if (obj3 == null) { Manipulator val3 = WarnUserOfServerCommandOffline; <>O.<2>__WarnUserOfServerCommandOffline = val3; obj3 = (object)val3; } Console.RunCmd += (Manipulator)obj3; object obj4 = <>O.<3>__BetterAutoCompletion; if (obj4 == null) { hook_SetSearchString val4 = BetterAutoCompletion; <>O.<3>__BetterAutoCompletion = val4; obj4 = (object)val4; } AutoComplete.SetSearchString += (hook_SetSearchString)obj4; RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Items.InitDroptableData)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(Spawners.InitPortals)); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AutoCompleteManager.RegisterAutoCompleteCommands)); Run.onRunStartGlobal += Items.CollectItemTiers; object obj5 = <>O.<8>__AddConCommandSignatureHint; if (obj5 == null) { hook_Start val5 = AddConCommandSignatureHint; <>O.<8>__AddConCommandSignatureHint = val5; obj5 = (object)val5; } ConsoleWindow.Start += (hook_Start)obj5; object obj6 = <>O.<9>__UpdateCommandSignature; if (obj6 == null) { hook_OnInputFieldValueChanged val6 = UpdateCommandSignature; <>O.<9>__UpdateCommandSignature = val6; obj6 = (object)val6; } ConsoleWindow.OnInputFieldValueChanged += (hook_OnInputFieldValueChanged)obj6; object obj7 = <>O.<10>__ApplyTextWithoutColorTags; if (obj7 == null) { Manipulator val7 = ApplyTextWithoutColorTags; <>O.<10>__ApplyTextWithoutColorTags = val7; obj7 = (object)val7; } ConsoleWindow.ApplyAutoComplete += (Manipulator)obj7; object obj8 = <>O.<11>__SmoothDropDownSuggestionNavigation; if (obj8 == null) { Manipulator val8 = SmoothDropDownSuggestionNavigation; <>O.<11>__SmoothDropDownSuggestionNavigation = val8; obj8 = (object)val8; } ConsoleWindow.Update += (Manipulator)obj8; object obj9 = <>O.<12>__AllowTabAutocompleteConCommands; if (obj9 == null) { Manipulator val9 = AllowTabAutocompleteConCommands; <>O.<12>__AllowTabAutocompleteConCommands = val9; obj9 = (object)val9; } HUD.Update += (Manipulator)obj9; object obj10 = <>O.<13>__EnableCheatsInCCSetScene; if (obj10 == null) { Manipulator val10 = EnableCheatsInCCSetScene; <>O.<13>__EnableCheatsInCCSetScene = val10; obj10 = (object)val10; } NetworkManagerSystem.CCSetScene += (Manipulator)obj10; object obj11 = <>O.<14>__OverrideVanillaSceneList; if (obj11 == null) { hook_CCSceneList val11 = OverrideVanillaSceneList; <>O.<14>__OverrideVanillaSceneList = val11; obj11 = (object)val11; } NetworkManagerSystem.CCSceneList += (hook_CCSceneList)obj11; object obj12 = <>O.<15>__PreventSave; if (obj12 == null) { hook_Save val12 = Profile.PreventSave; <>O.<15>__PreventSave = val12; obj12 = (object)val12; } SaveSystem.Save += (hook_Save)obj12; object obj13 = <>O.<16>__InterceptPing; if (obj13 == null) { hook_RebuildPing val13 = InterceptPing; <>O.<16>__InterceptPing = val13; obj13 = (object)val13; } PingerController.RebuildPing += (hook_RebuildPing)obj13; object obj14 = <>O.<17>__InfiniteTowerRun_BeginNextWave; if (obj14 == null) { Manipulator val14 = InfiniteTowerRun_BeginNextWave; <>O.<17>__InfiniteTowerRun_BeginNextWave = val14; obj14 = (object)val14; } InfiniteTowerRun.BeginNextWave += (Manipulator)obj14; object obj15 = <>O.<18>__SetNextBossForDirector; if (obj15 == null) { hook_SetNextSpawnAsBoss val15 = SetNextBossForDirector; <>O.<18>__SetNextBossForDirector = val15; obj15 = (object)val15; } CombatDirector.SetNextSpawnAsBoss += (hook_SetNextSpawnAsBoss)obj15; object obj16 = <>O.<19>__SetNextBossForSimulacrumDirector; if (obj16 == null) { hook_Initialize val16 = SetNextBossForSimulacrumDirector; <>O.<19>__SetNextBossForSimulacrumDirector = val16; obj16 = (object)val16; } InfiniteTowerExplicitSpawnWaveController.Initialize += (hook_Initialize)obj16; object obj17 = <>O.<20>__OverrideBossCombatDirectorSpawnResult; if (obj17 == null) { hook_AttemptSpawnOnTarget val17 = OverrideBossCombatDirectorSpawnResult; <>O.<20>__OverrideBossCombatDirectorSpawnResult = val17; obj17 = (object)val17; } CombatDirector.AttemptSpawnOnTarget += (hook_AttemptSpawnOnTarget)obj17; Run.onRunDestroyGlobal += delegate { CurrentRun.ResetNextBoss(); }; object obj18 = <>O.<21>__CreateNetworkObject; if (obj18 == null) { hook_Start val18 = NetworkManager.CreateNetworkObject; <>O.<21>__CreateNetworkObject = val18; obj18 = (object)val18; } NetworkSession.Start += (hook_Start)obj18; object obj19 = <>O.<22>__DestroyNetworkObject; if (obj19 == null) { hook_OnDestroy val19 = NetworkManager.DestroyNetworkObject; <>O.<22>__DestroyNetworkObject = val19; obj19 = (object)val19; } NetworkSession.OnDestroy += (hook_OnDestroy)obj19; object obj20 = <>O.<23>__DisableOnStopClient; if (obj20 == null) { hook_OnStopClient val20 = Command_Noclip.DisableOnStopClient; <>O.<23>__DisableOnStopClient = val20; obj20 = (object)val20; } NetworkManagerSystem.OnStopClient += (hook_OnStopClient)obj20; object obj21 = <>O.<24>__DisableOOBCheck; if (obj21 == null) { hook_TeleportBody val21 = Command_Noclip.DisableOOBCheck; <>O.<24>__DisableOOBCheck = val21; obj21 = (object)val21; } MapZone.TeleportBody += (hook_TeleportBody)obj21; Run.onRunDestroyGlobal += Command_Noclip.DisableOnRunDestroy; object obj22 = <>O.<26>__NonLethalDamage; if (obj22 == null) { hook_TakeDamage val22 = NonLethalDamage; <>O.<26>__NonLethalDamage = val22; obj22 = (object)val22; } HealthComponent.TakeDamage += (hook_TakeDamage)obj22; object obj23 = <>O.<27>__SetGodMode; if (obj23 == null) { hook_Awake val23 = SetGodMode; <>O.<27>__SetGodMode = val23; obj23 = (object)val23; } CharacterMaster.Awake += (hook_Awake)obj23; object obj24 = <>O.<28>__FixCommandHelpText; if (obj24 == null) { Manipulator val24 = FixCommandHelpText; <>O.<28>__FixCommandHelpText = val24; obj24 = (object)val24; } Console.ShowHelpText += (Manipulator)obj24; object obj25 = <>O.<29>__FixCCFind; if (obj25 == null) { Manipulator val25 = FixCCFind; <>O.<29>__FixCCFind = val25; obj25 = (object)val25; } Console.CCFind += (Manipulator)obj25; } private static void FixCommandHelpText(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (val.Instrs.Count > 1) { Log.Message("Skipped patching the command help text method. Maybe fixed already?", Log.LogLevel.Warning, Log.Target.Bepinex); return; } val.Emit(OpCodes.Ldarg_0); val.Emit<Console>(OpCodes.Call, "GetHelpText"); val.Emit<Debug>(OpCodes.Call, "Log"); } private static void FixCCFind(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Console>(x, "Find"), (Instruction x) => ILPatternMatchingExt.MatchPop(x) })) { Log.Message("Could not patch \"find\" command. Maybe fixed already?", Log.LogLevel.Warning, Log.Target.Bepinex); return; } val.Index += 1; val.Emit<Debug>(OpCodes.Call, "Log"); val.Remove(); } private static void SetGodMode(orig_Awake orig, CharacterMaster self) { orig.Invoke(self); if (NetworkServer.active) { self.godMode |= Object.op_Implicit((Object)(object)self.playerCharacterMasterController) && god; } } private static void NonLethalDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo) { //IL_0016: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (buddha && self.body.isPlayerControlled) { damageInfo.damageType |= DamageTypeCombo.op_Implicit((DamageType)1); } orig.Invoke(self, damageInfo); } private static void InfiniteTowerRun_BeginNextWave(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 0) })) { Log.Message("Failed to patch RoR2.InfiniteTowerRun.BeginNextWave", Log.LogLevel.Warning, Log.Target.Bepinex); return; } val.Index += 1; val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<GameObject, InfiniteTowerRun, GameObject>>((Func<GameObject, InfiniteTowerRun, GameObject>)delegate(GameObject wavePrefab, InfiniteTowerRun run) { wavePrefab = CurrentRun.selectedWavePrefab ?? wavePrefab; CurrentRun.selectedWavePrefab = null; return wavePrefab; }); } private static void InterceptPing(orig_RebuildPing orig, PingerController self, PingInfo pingInfo) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, pingInfo); CharacterMaster component = ((Component)self).GetComponent<CharacterMaster>(); if (!Object.op_Implicit((Object)(object)component)) { return; } if (Object.op_Implicit((Object)(object)self.pingIndicator) && Object.op_Implicit((Object)(object)self.pingIndicator.pingTarget)) { CharacterBody component2 = self.pingIndicator.pingTarget.GetComponent<CharacterBody>(); if ((Object)(object)component2 != (Object)null) { pingedTargets[component] = new PingCache { body = component2, master = component2.master }; } else { pingedTargets[component] = default(PingCache); } } else { pingedTargets[component] = default(PingCache); } } private static void OverrideVanillaSceneList(orig_CCSceneList orig, ConCommandArgs args) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); foreach (SceneDef item in ((IEnumerable<SceneDef>)(object)SceneCatalog.allSceneDefs).Where((SceneDef def) => !Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)def.requiredExpansion) || Run.instance.IsExpansionEnabled(def.requiredExpansion))) { stringBuilder.AppendLine($"[{item.sceneDefIndex}] - {item.cachedName} "); } Log.Message(stringBuilder, Log.LogLevel.MessageClientOnly); } private static void EnableCheatsInCCSetScene(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodInfo method = Reflection.GetMethodCached(typeof(SceneCatalog), "GetSceneDefFromSceneName"); MethodInfo methodCached = Reflection.GetMethodCached(typeof(Hooks), "FilterExpansionLockedScenes"); val.GotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)method) }); val.Remove(); val.Emit(OpCodes.Call, (MethodBase)methodCached); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<CheatsConVar>(x, "get_boolValue") }); val.Emit(OpCodes.Pop); val.Emit(OpCodes.Ldc_I4_1); } public static SceneDef FilterExpansionLockedScenes(string sceneName) { SceneDef sceneDefFromSceneName = SceneCatalog.GetSceneDefFromSceneName(sceneName); if (!Object.op_Implicit((Object)(object)sceneDefFromSceneName)) { return null; } if (!Object.op_Implicit((Object)(object)Run.instance) || !Object.op_Implicit((Object)(object)sceneDefFromSceneName.requiredExpansion) || Run.instance.IsExpansionEnabled(sceneDefFromSceneName.requiredExpansion)) { return sceneDefFromSceneName; } Debug.Log((object)string.Format("An expansion is required for this {0}: {1}", "scene", Util.GetExpansion(sceneDefFromSceneName.requiredExpansion))); return null; } private static void UnlockConsole(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCastclass(x, typeof(ConCommandAttribute)) }); val.EmitDelegate<Func<ConCommandAttribute, ConCommandAttribute>>((Func<ConCommandAttribute, ConCommandAttribute>)delegate(ConCommandAttribute conAttr) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) conAttr.flags = (ConVarFlags)(conAttr.flags & 0x17); if (conAttr.commandName == "run_set_stages_cleared") { conAttr.helpText = "Sets the amount of stages cleared. This does not change the current stage."; } return conAttr; }); } private static void InitCommandsAndFreeConvars(orig_CacheConVars orig, Console self) { orig.Invoke(self); RemoveCheatFlag(self.FindConVar("sv_time_transmit_interval")); RemoveCheatFlag(self.FindConVar("run_scene_override")); RemoveCheatFlag(self.FindConVar("stage1_pod")); BaseConVar obj = self.FindConVar("timescale"); obj.helpText += " Use time_scale instead!"; BaseConVar obj2 = self.FindConVar("director_combat_disable"); obj2.helpText += " Use no_enemies instead!"; BaseConVar obj3 = self.FindConVar("timestep"); obj3.helpText += " Let the DebugToolkit team know if you need this convar."; BaseConVar obj4 = self.FindConVar("cmotor_safe_collision_step_threshold"); obj4.helpText += " Let the DebugToolkit team know if you need this convar."; BaseConVar obj5 = self.FindConVar("cheats"); obj5.helpText += " But you already have the DebugToolkit mod installed..."; static void RemoveCheatFlag(BaseConVar cv) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) cv.flags = (ConVarFlags)(cv.flags & 0x17); } } private static void LogNetworkCommandsAndCheckPermissions(Console self, CmdSender sender, string concommandName, List<string> userArgs) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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) //IL_005a: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) StringBuilder sb = new StringBuilder(); userArgs.ForEach(delegate(string str) { sb.AppendLine(str); }); if ((Object)(object)sender.networkUser != (Object)null && sender.localUser == null) { Log.Message($"{sender.networkUser.userName}({sender.networkUser.id.value}) issued: {concommandName} {sb}"); } else if (Application.isBatchMode) { Log.Message(string.Format("{0}({1}) issued: {2} {3}", "Server", 0, concommandName, sb)); } bool flag = true; if ((Object)(object)sender.networkUser != (Object)null && sender.localUser == null && PermissionSystem.IsEnabled.Value) { flag = PermissionSystem.CanUserExecute(sender.networkUser, concommandName, userArgs); } if (flag) { _origRunCmd.Invoke(self, sender, concommandName, userArgs); ScrollConsoleDown(); } } private static void WarnUserOfServerCommandOffline(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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_007d: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Console>(x, "ForwardCmdToServer") })) { Log.Message("Failed to patch RoR2.Console.RunCmd", Log.LogLevel.Error, Log.Target.Bepinex); return; } Instruction next = val.Next; val.Emit<NetworkSession>(OpCodes.Call, "get_instance"); val.Emit(OpCodes.Brtrue_S, next); val.Emit(OpCodes.Ldstr, "This command requires a network or game session."); val.Emit<Debug>(OpCodes.Call, "Log"); } private static void AddConCommandSignatureHint(orig_Start orig, ConsoleWindow self) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self); Transform child = ((Component)self).gameObject.transform.GetChild(0).GetChild(1); commandSignatureText = new GameObject("CommandHint", new Type[1] { typeof(RectTransform) }); commandSignatureText.transform.SetParent(child); Transform transform = commandSignatureText.transform; Transform obj = ((transform is RectTransform) ? transform : null); ((RectTransform)obj).anchorMin = new Vector2(0f, 0f); ((RectTransform)obj).anchorMax = new Vector2(1f, 1f); ((RectTransform)obj).pivot = new Vector2(0f, 0.5f); ((RectTransform)obj).offsetMin = new Vector2(14f, 29f); ((RectTransform)obj).offsetMax = new Vector2(-26f, 19f); obj.localScale = ((Component)child).transform.GetChild(0).localScale; HGTextMeshProUGUI obj2 = commandSignatureText.AddComponent<HGTextMeshProUGUI>(); ((TMP_Text)obj2).fontSize = 14f; ((TMP_Text)obj2).overflowMode = (TextOverflowModes)1; ((TMP_Text)obj2).enableWordWrapping = false; } private static void UpdateCommandSignature(orig_OnInputFieldValueChanged orig, ConsoleWindow self, string text) { orig.Invoke(self, text); HGTextMeshProUGUI val = default(HGTextMeshProUGUI); if (Object.op_Implicit((Object)(object)commandSignatureText) && commandSignatureText.TryGetComponent<HGTextMeshProUGUI>(ref val)) { if (text == "") { AutoCompleteManager.ClearCommandOptions(); } string currentCommand = AutoCompleteManager.CurrentCommand; string currentSignature = AutoCompleteManager.CurrentSignature; if (currentCommand == null || currentSignature == null) { ((TMP_Text)val).text = ""; } else { ((TMP_Text)val).text = $"<color=#ffa000>{currentCommand} {currentSignature}</color>"; } } } internal static void ScrollConsoleDown() { if (Object.op_Implicit((Object)(object)ConsoleWindow.instance) && Object.op_Implicit((Object)(object)ConsoleWindow.instance.outputField.verticalScrollbar)) { ConsoleWindow.instance.outputField.verticalScrollbar.value = 1f; } } private static bool BetterAutoCompletion(orig_SetSearchString orig, AutoComplete self, string newSearchString) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) if (self.searchString == newSearchString) { return false; } self.searchString = newSearchString; List<string> list = new Lexer(newSearchString).GetTokens().ToList(); list.RemoveAt(list.Count - 1); if (list.Count == 0) { return false; } int num = list.LastIndexOf(";") + 1; List<MatchInfo> list2 = new List<MatchInfo>(); if (list[list.Count - 1] == ";" || newSearchString.EndsWith(list[num])) { AutoCompleteManager.ClearCommandOptions(); List<string> list3 = Console.instance.allConVars.Keys.ToList(); list3.AddRange(Console.instance.concommandCatalog.Keys); list3.Sort(); string text2 = ((list[list.Count - 1] == ";") ? "" : list[num].ToLowerInvariant()); foreach (string item in list3) { int num2 = item.IndexOf(text2); if (num2 == 0) { list2.Add(new MatchInfo { similarity = 1000 + text2.Length - item.Length, str = item.Substring(0, text2.Length) + GrayOutText(item, text2.Length) }); } else if (num2 > 0) { list2.Add(new MatchInfo { similarity = text2.Length - item.Length, str = GrayOutText(item, 0, num2) + item.Substring(num2, text2.Length) + GrayOutText(item, num2 + text2.Length) }); } } } else { int num3 = list.Count - 1; if (!newSearchString.EndsWith(list[list.Count - 1])) { num3++; TMP_Dropdown autoCompleteDropdown = ConsoleWindow.instance.autoCompleteDropdown; if ((Object)(object)autoCompleteDropdown != (Object)null) { autoCompleteDropdown.SetValue(0, false); autoCompleteDropdown.Hide(); ((Selectable)ConsoleWindow.instance.inputField).Select(); } } string text3 = list[num].ToLowerInvariant(); if (text3 != AutoCompleteManager.CurrentCommand) { AutoCompleteManager.PrepareCommandOptions(text3); } List<string>[] currentParameters = AutoCompleteManager.CurrentParameters; int num4 = num3 - num - 1; if (num4 < currentParameters.Length && currentParameters[num4].Count > 0) { List<string> list4 = currentParameters[num4]; string text4 = ((num3 < list.Count) ? list[num3] : ""); if (text4 == "") { foreach (string item2 in list4) { list2.Add(new MatchInfo { similarity = int.MinValue, str = GrayOutText(item2, 0) }); } } else { int num5 = default(int); if (TextSerialization.TryParseInvariant(text4, ref num5)) { text4 = num5.ToString(); } foreach (string item3 in list4) { if (item3.IndexOf(text4, StringComparison.InvariantCultureIgnoreCase) < 0) { continue; } List<string> list5 = new List<string>(); int num6 = int.MinValue; string[] array = item3.Split('|'); foreach (string text5 in array) { int num7 = text5.IndexOf(text4, StringComparison.InvariantCultureIgnoreCase); if (num7 == 0) { num6 = Math.Max(1000 + text4.Length - text5.Length, num6); list5.Add(text5.Substring(0, text4.Length) + GrayOutText(text5, text4.Length)); } else if (num7 > 0) { num6 = Math.Max(text4.Length - text5.Length, num6); list5.Add(GrayOutText(text5, 0, num7) + text5.Substring(num7, text4.Length) + GrayOutText(text5, num7 + text4.Length)); } else { list5.Add(GrayOutText(text5, 0)); } } list2.Add(new MatchInfo { similarity = num6, str = string.Join("|", list5) }); } } } } self.resultsList = (from m in list2 orderby m.similarity descending select m.str).ToList(); return true; static string GrayOutText(string text, int startIndex, int length = -1) { text = ((length < 0) ? text.Substring(startIndex) : text.Substring(startIndex, length)); return "<color=#808080>" + text + "</color>"; } } private static void ApplyTextWithoutColorTags(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, typeof(OptionData), "get_text") })) { Log.Message("Failed to patch ConsoleWindow", Log.LogLevel.Error, Log.Target.Bepinex); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<string, ConsoleWindow, string>>((Func<string, ConsoleWindow, string>)delegate(string text, ConsoleWindow consoleWindow) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) text = text.Split('|')[0].Replace("<color=#808080>", "").Replace("</color>", ""); string text2 = consoleWindow.inputField.text; List<string> list = new Lexer(text2).GetTokens().ToList(); list.RemoveAt(list.Count - 1); if (list.Count == 0) { return text; } string text3 = list[list.Count - 1]; return (!text2.EndsWith(text3)) ? (text2 + text) : (text2.Substring(0, text2.Length - text3.Length) + text); }); } private static void SmoothDropDownSuggestionNavigation(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); MethodReference operand = il.Import((MethodBase)Reflection.GetMethodCached(typeof(Input), "GetKey", new Type[1] { typeof(KeyCode) })); val.GotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 273), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Input>(x, "GetKeyDown") }); val.Prev.Operand = operand; val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)LimitChangeItemFrequency); val.GotoNext((MoveType)2, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 274), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Input>(x, "GetKeyDown") }); val.Prev.Operand = operand; val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)LimitChangeItemFrequency); ILLabel val4 = default(ILLabel); val.GotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 3), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val4) }); val.Index += 1; val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)ScrollAutocompleteNextWithTab); ILLabel val3 = default(ILLabel); for (int i = 0; i < 3; i++) { if (i != 1) { val.GotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 3), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val3) }); val.Index += 1; val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)ScrollAutocompleteNextWithTab); } } ILLabel val2 = default(ILLabel); val.GotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdloc(x, 2), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val2) }); val.Index += 1; val.EmitDelegate<Func<bool, bool>>((Func<bool, bool>)((bool previousKeyPressed) => previousKeyPressed || (Input.GetKey((KeyCode)306) && Input.GetKeyDown((KeyCode)9)))); static bool LimitChangeItemFrequency(bool canChangeItem) { if (canChangeItem) { float time = Time.time; if (time > 0.1f + _lastSelectedItemChange) { _lastSelectedItemChange = time; return true; } return false; } return canChangeItem; } static bool ScrollAutocompleteNextWithTab(bool isNextKeyPressed) { if (!isNextKeyPressed) { if (!Input.GetKey((KeyCode)306)) { return Input.GetKeyDown((KeyCode)9); } return false; } return true; } } private static void AllowTabAutocompleteConCommands(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel jumpLabel = null; if (!val.TryGotoNext(new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "info"), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Player>(x, "GetButtonDown") }) || !val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[3] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<HUD>(x, "get_targetBodyObject"), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(x, "op_Implicit"), (Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref jumpLabel) })) { Log.Message("Failed to patch RoR2.UI.HUD.Update", Log.LogLevel.Error, Log.Target.Bepinex); return; } val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<Func<HUD, bool>>((Func<HUD, bool>)delegate(HUD self) { MPEventSystemProvider eventSystemProvider = self.eventSystemProvider; object obj; if (eventSystemProvider == null) { obj = null; } else { MPEventSystem eventSystem = eventSystemProvider.eventSystem; obj = ((eventSystem != null) ? ((EventSystem)eventSystem).currentSelectedGameObject : null); } GameObject val2 = (GameObject)obj; if (Object.op_Implicit((Object)(object)val2)) { ConsoleWindow instance = ConsoleWindow.instance; object obj2; if (instance == null) { obj2 = null; } else { TMP_InputField inputField = instance.inputField; obj2 = ((inputField != null) ? ((Component)inputField).gameObject : null); } return !((Object)(object)val2 == (Object)obj2); } return true; }); val.Emit(OpCodes.Brfalse_S, jumpLabel.Target); } internal static WeightedSelection<DirectorCardCategorySelection> ForceFamilyEventForDccsPoolStages(orig_GenerateWeightedSelection orig, DccsPool self) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0052: 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_005d: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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) if ((Object)(object)ClassicStageInfo.instance.monsterDccsPool != (Object)(object)self) { return orig.Invoke(self); } object obj = <>O.<30>__ForceFamilyDirectorCardCategorySelectionToBeAvailable; if (obj == null) { hook_IsAvailable val = ForceFamilyDirectorCardCategorySelectionToBeAvailable; <>O.<30>__ForceFamilyDirectorCardCategorySelectionToBeAvailable = val; obj = (object)val; } FamilyDirectorCardCategorySelection.IsAvailable += (hook_IsAvailable)obj; WeightedSelection<DirectorCardCategorySelection> val2 = orig.Invoke(self); object obj2 = <>O.<30>__ForceFamilyDirectorCardCategorySelectionToBeAvailable; if (obj2 == null) { hook_IsAvailable val3 = ForceFamilyDirectorCardCategorySelectionToBeAvailable; <>O.<30>__ForceFamilyDirectorCardCategorySelectionToBeAvailable = val3; obj2 = (object)val3; } FamilyDirectorCardCategorySelection.IsAvailable -= (hook_IsAvailable)obj2; List<ChoiceInfo<DirectorCardCategorySelection>> list = new List<ChoiceInfo<DirectorCardCategorySelection>>(); ChoiceInfo<DirectorCardCategorySelection>[] choices = val2.choices; for (int i = 0; i < choices.Length; i++) { ChoiceInfo<DirectorCardCategorySelection> item = choices[i]; if (Object.op_Implicit((Object)(object)item.value) && item.value is FamilyDirectorCardCategorySelection) { list.Add(item); } } if (list.Count > 0) { val2.choices = list.ToArray(); val2.Count = list.Count; val2.RecalculateTotalWeight(); } return val2; } private static bool ForceFamilyDirectorCardCategorySelectionToBeAvailable(orig_IsAvailable orig, FamilyDirectorCardCategorySelection self) { return true; } internal static void ForceFamilyEvent(orig_RebuildCards orig, ClassicStageInfo self, DirectorCardCategorySelection forcedMonsterCategory, DirectorCardCategorySelection forcedInteractableCategory) { //IL_0010: 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_001b: Expected O, but got Unknown //IL_004b: 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) //IL_0056: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00fd: 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) //IL_0108: Expected O, but got Unknown object obj = <>O.<31>__ForceFamilyEventForDccsPoolStages; if (obj == null) { hook_GenerateWeightedSelection val = ForceFamilyEventForDccsPoolStages; <>O.<31>__ForceFamilyEventForDccsPoolStages = val; obj = (object)val; } DccsPool.GenerateWeightedSelection += (hook_GenerateWeightedSelection)obj; float monsterFamilyChance = ClassicStageInfo.monsterFamilyChance; MonsterFamily[] possibleMonsterFamilies = self.possibleMonsterFamilies; ClassicStageInfo.monsterFamilyChance = 1f; MonsterFamily[] array = (MonsterFamily[])(object)new MonsterFamily[possibleMonsterFamilies.Length]; for (int i = 0; i < self.possibleMonsterFamilies.Length; i++) { MonsterFamily val2 = self.possibleMonsterFamilies[i]; array[i] = new MonsterFamily { monsterFamilyCategories = val2.monsterFamilyCategories, familySelectionChatString = val2.familySelectionChatString, selectionWeight = val2.selectionWeight, minimumStageCompletion = 0, maximumStageCompletion = int.MaxValue }; } self.possibleMonsterFamilies = array; orig.Invoke(self, forcedMonsterCategory, forcedInteractableCategory); object obj2 = <>O.<31>__ForceFamilyEventForDccsPoolStages; if (obj2 == null) { hook_GenerateWeightedSelection val3 = ForceFamilyEventForDccsPoolStages; <>O.<31>__ForceFamilyEventForDccsPoolStages = val3; obj2 = (object)val3; } DccsPool.GenerateWeightedSelection -= (hook_GenerateWeightedSelection)obj2; ClassicStageInfo.monsterFamilyChance = monsterFamilyChance; self.possibleMonsterFamilies = possibleMonsterFamilies; object obj3 = <>O.<32>__ForceFamilyEvent; if (obj3 == null) { hook_RebuildCards val4 = ForceFamilyEvent; <>O.<32>__ForceFamilyEvent = val4; obj3 = (object)val4; } ClassicStageInfo.RebuildCards -= (hook_RebuildCards)obj3; } internal static void SetNextBossForDirector(orig_SetNextSpawnAsBoss orig, CombatDirector self) { orig.Invoke(self); if (CurrentRun.nextBoss != null && !((Object)((Component)self).gameObject).name.Contains("DeepVoidPortalBattery")) { bossDirector = self; DirectorCard nextBoss = CurrentRun.nextBoss; self.OverrideCurrentMonsterCard(nextBoss); EliteDef val = (self.currentActiveEliteDef = CurrentRun.nextBossElite); self.currentActiveEliteTier = Spawners.GetTierDef(val); string text = (((Object)(object)val == (Object)null) ? "non-elite" : ((Object)val).name); int nextBossCount = CurrentRun.nextBossCount; self.monsterCredit = (float)(nextBoss.cost * nextBossCount) * self.currentActiveEliteTier.costMultiplier; skipSpawnIfTooCheapBackup = self.skipSpawnIfTooCheap; self.skipSpawnIfTooCheap = false; Log.Message($"The director credits have been set to {self.monsterCredit} to spawn {nextBossCount} {text} {((Object)nextBoss.spawnCard).name}", Log.LogLevel.Info, Log.Target.Ror2); } } private static bool OverrideBossCombatDirectorSpawnResult(orig_AttemptSpawnOnTarget orig, CombatDirector self, Transform spawnTarget, PlacementMode placementMode) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) bool flag = orig.Invoke(self, spawnTarget, placementMode); if ((Object)(object)self != (Object)(object)bossDirector) { return flag; } if (bossDirector.spawnCountInCurrentWave >= CurrentRun.nextBossCount || !flag) { self.skipSpawnIfTooCheap = skipSpawnIfTooCheapBackup; bossDirector = null; CurrentRun.ResetNextBoss(); return false; } return flag; } internal static void SetNextBossForSimulacrumDirector(orig_Initialize orig, InfiniteTowerExplicitSpawnWaveController self, int waveIndex, Inventory enemyInventory, GameObject spawnTargetObject) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0046: 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) if (CurrentRun.nextBoss != null) { self.spawnList = (SpawnInfo[])(object)new SpawnInfo[1] { new SpawnInfo { spawnCard = (CharacterSpawnCard)CurrentRun.nextBoss.spawnCard, eliteDef = CurrentRun.nextBossElite, count = CurrentRun.nextBossCount } }; } orig.Invoke(self, waveIndex, enemyInventory, spawnTargetObject); CurrentRun.ResetNextBoss(); } internal static void SeedHook(orig_Awake orig, PreGameController self) { orig.Invoke(self); if (CurrentRun.seed != 0L) { self.runSeed = CurrentRun.seed; } } internal static void DenyMapSpawns(orig_SpendAllCreditsOnMapSpawns orig, CombatDirector self, Transform mapSpawnTarget) { self.monsterCredit = 0f; orig.Invoke(self, mapSpawnTarget); } internal static void DenyExperience(orig_AwardExperience orig, ExperienceManager self, Vector3 origin, CharacterBody body, ulong amount) { } internal static PingCache GetPingedTarget(CharacterMaster player) { if (pingedTargets.TryGetValue(player, out var value)) { return value; } return default(PingCache); } internal static bool ToggleBuddha() { return buddha = !buddha; } internal static bool ToggleGod() { return god = !god; } } public static class Lang { public const string ADDPORTAL_ARGS = "Requires 1 argument: {portal ('blue'|'celestial'|'gold'|'green'|'void'|'all')}"; public const string BAN_ARGS = "Requires 1 argument: {player}"; public const string BIND_ARGS = "Requires 2 arguments: {key} [console_commands]"; public const string BIND_DELETE_ARGS = "Requires 1 argument: {key}"; public const string CHANGETEAM_ARGS = "Requires 1 (2 if from server) argument: {team} [player:<self>]"; public const string CHARGEZONE_ARGS = "Requires 1 argument: {charge}"; public const string CREATEPICKUP_ARGS = "Requires 1 (3 if from server) argument: {object (item|equip|'lunarcoin'|'voidcoin')} [search ('item'|'equip'|'both'):'both'] *[player:<self>]"; public const string CREATEPOTENTIAL_ARGS = "Requires 0 (3 if from server) arguments: [droptable (droptable|'all'):'all'] [count:3] *[player:<self>]"; public const string DUMPSTATE_ARGS = "Requires 0 (1 if from server) argument: [target (player|'pinged'):<self>]"; public const string DUMPSTATS_ARGS = "Requires 1 argument: {body}"; public const string FIXEDTIME_ARGS = "Requires 0 or 1 argument: [time]"; public const string FORCEWAVE_ARGS = "Requires 0 or 1 argument [wave_prefab]"; public const string GIVEBUFF_ARGS = "Requires 1 (4 if from server) arguments: {buff} [count:1] [duration:0] [target (player|'pinged'):<self>]"; public const string GIVEDOT_ARGS = "Requires 1 (4 if from server) argument: {dot} [count:1] [target (player|'pinged'):<self>] [attacker (player|'pinged'):<self>]"; public const string GIVEEQUIP_ARGS = "Requires 1 (2 if from server) argument: {equip (equip|'random')} [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string GIVEITEM_ARGS = "Requires 1 (3 if from server) argument: {item} [count:1] [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string GIVELUNAR_ARGS = "Requires 0 arguments: [amount:1]"; public const string GIVEMONEY_ARGS = "Requires 1 argument: {amount} [target (player|'all')]"; public const string KICK_ARGS = "Requires 1 argument: {player}"; public const string KILLALL_ARGS = "Requires 0 arguments: [team:Monster]"; public const string LISTSKIN_ARGS = "Requires 0 arguments: [selection (body|'all'|'body'|'self'):'all']"; public const string LISTQUERY_ARGS = "Requires 0 arguments: [query]"; public const string LOADOUTSKIN_ARGS = "Requires 2 argument: {body_name (body|'self')} {skin_index}"; public const string NEXTBOSS_ARGS = "Requires 1 argument: {director_card} [count:1] [elite:None]"; public const string NEXTSTAGE_ARGS = "Requires 0 arguments: [specific_stage]"; public const string NO_ARGS = "Requires 0 arguments."; public const string PERM_ENABLE_ARGS = "Requires 0 or 1 arguments: [value (0|1)]"; public const string PERM_MOD_ARGS = "Requires 2 arguments: {permission_level} {player}"; public const string POSTSOUNDEVENT_ARGS = "Requires 1 argument: {sound_event (event_name|event_id)}"; public const string PREVENT_PROFILE_WRITING_ARGS = "Requires 0 or 1 arguments [flag (0|1)]"; public const string RANDOMITEM_ARGS = "Requires 1 (3 if from server) argument: {count} [droptable (droptable|'all'):'all'] [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEALLBUFFS_ARGS = "Requires 0 (2 if from server) arguments: [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEALLDOTS_ARGS = "Requires 0 (1 if from server) arguments: [target (player|'pinged'):<self>]"; public const string REMOVEALLITEMS_ARGS = "Requires 0 (1 if from server) arguments: [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEBUFF_ARGS = "Requires 1 (4 if from server) arguments: {buff} [count:1] [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEBUFFSTACKS_ARGS = "Requires 1 (3 if from server) arguments: {buff} [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEDOT_ARGS = "Requires 1 (3 if from server) argument: {dot} [count:1] [target (player|'pinged'):<self>]"; public const string REMOVEDOTSTACKS_ARGS = "Requires 1 (2 if from server) argument: {dot} [target (player|'pinged'):<self>]"; public const string REMOVEEQUIP_ARGS = "Requires 0 (1 if from server) arguments: [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEITEMSTACKS_ARGS = "Requires 1 (2 if from server) argument: {item} [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string RESPAWN_ARGS = "Requires 0 (1 if from server) arguments: [player:<self>]"; public const string RESTOCKEQUIP_ARGS = "Requires 0 (2 if from server) arguments: [count:1] *[target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string RUNSETWAVESCLEARED_ARGS = "Requires 1 argument {wave}"; public const string SEED_ARGS = "Requires 0 or 1 argument: [new_seed]"; public const string SETARTIFACT_ARGS = "Requires 1 (2 if using 'all') argument: {artifact (artifact|'all')} [enable (0|1)]"; public const string SPAWNAI_ARGS = "Requires 1 argument: {ai} [count:1] [elite:None] [braindead (0|1):0/false] [team:Monster]"; public const string SPAWNAS_ARGS = "Requires 1 (2 if from server) argument: {body} [player:<self>]"; public const string SPAWNBODY_ARGS = "Requires 1 argument: {body}"; public const string SPAWNINTERACTABLE_ARGS = "Requires 1 argument: {interactable}"; public const string SPAWNPORTAL_ARGS = "Requires 1 argument: {portal ('artifact'|'blue'|'celestial'|'deepvoid'|'gold'|'green'|'null'|'void')}"; public const string TIMESCALE_ARGS = "Requires 1 argument: {time_scale}"; public const string TRUEKILL_ARGS = "Requires 0 (1 if from server) arguments: [player:<self>]"; public const string ADDPORTAL_HELP = "Add a portal to the current Teleporter on completion. Requires 1 argument: {portal ('blue'|'celestial'|'gold'|'green'|'void'|'all')}"; public const string BAN_HELP = "Bans the specified player from the session. Requires 1 argument: {player}"; public const string BIND_HELP = "Bind a key to execute specific commands. Requires 2 arguments: {key} [console_commands]"; public const string BIND_DELETE_HELP = "Remove a custom bind from the macro system of DebugToolkit. Requires 1 argument: {key}"; public const string BIND_RELOAD_HELP = "Reload the macro system of DebugToolkit. Requires 0 arguments."; public const string BUDDHA_HELP = "Become immortal. Instead of refusing damage you just refuse to take lethal damage.\nIt works by giving all damage a player takes DamageType.NonLethal. Requires 0 arguments."; public const string CHANGETEAM_HELP = "Change the specified player to the specified team. Requires 1 (2 if from server) argument: {team} [player:<self>]"; public const string CHARGEZONE_HELP = "Set the charge of all active holdout zones. Requires 1 argument: {charge}"; public const string CREATEPICKUP_HELP = "Creates a PickupDroplet infront of your position. Requires 1 (3 if from server) argument: {object (item|equip|'lunarcoin'|'voidcoin')} [search ('item'|'equip'|'both'):'both'] *[player:<self>]"; public const string CREATEPOTENTIAL_HELP = "Creates a potential PickupDroplet infront of your position. Requires 0 (3 if from server) arguments: [droptable (droptable|'all'):'all'] [count:3] *[player:<self>]"; public const string CURSORTELEPORT_HELP = "Teleport you to where your cursor is currently aiming at. Requires 0 arguments."; public const string DUMPBUFFS_HELP = "List the buffs/debuffs of all spawned bodies. Requires 0 arguments."; public const string DUMPINVENTORIES_HELP = "List the inventory items and equipment of all spawned bodies. Requires 0 arguments."; public const string DUMPSTATE_HELP = "List the current stats, entity state, and skill cooldown of a specified body. Requires 0 (1 if from server) argument: [target (player|'pinged'):<self>]"; public const string DUMPSTATS_HELP = "List the base stats of a specific body. Requires 1 argument: {body}"; public const string FAMILYEVENT_HELP = "Forces a family event to occur during the next stage. Requires 0 arguments."; public const string FIXEDTIME_HELP = "Sets the run timer to the specified value. Requires 0 or 1 argument: [time]"; public const string FORCEWAVE_HELP = "Set the next wave prefab. Leave empty to see all options. Requires 0 or 1 argument [wave_prefab]"; public const string GIVEBUFF_HELP = "Gives the specified buff to a character. A duration of 0 means permanent. Requires 1 (4 if from server) arguments: {buff} [count:1] [duration:0] [target (player|'pinged'):<self>]"; public const string GIVEDOT_HELP = "Gives the specified DoT to a character. Requires 1 (4 if from server) argument: {dot} [count:1] [target (player|'pinged'):<self>] [attacker (player|'pinged'):<self>]"; public const string GIVEEQUIP_HELP = "Gives the specified equipment to a target. Requires 1 (2 if from server) argument: {equip (equip|'random')} [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string GIVEITEM_HELP = "Gives the specified item to a target. Requires 1 (3 if from server) argument: {item} [count:1] [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string GIVELUNAR_HELP = "Gives a lunar coin to you. Requires 0 arguments: [amount:1]"; public const string GIVEMONEY_HELP = "Gives the specified amount of money to the specified player. Requires 1 argument: {amount} [target (player|'all')]"; public const string GOD_HELP = "Become invincible. Requires 0 arguments."; public const string KICK_HELP = "Kicks the specified player from the session. Requires 1 argument: {player}"; public const string KILLALL_HELP = "Kill all entities on the specified team. Requires 0 arguments: [team:Monster]"; public const string LISTAI_HELP = "List all Masters and their language invariants. Requires 0 arguments: [query]"; public const string LISTARTIFACT_HELP = "List all Artifacts and their language invariants. Requires 0 arguments: [query]"; public const string LISTBODY_HELP = "List all Bodies and their language invariants. Requires 0 arguments: [query]"; public const string LISTBUFF_HELP = "List all Buffs and whether they stack. Requires 0 arguments: [query]"; public const string LISTDIRECTORCARDS_HELP = "List all Director Cards. Requires 0 arguments: [query]"; public const string LISTDOT_HELP = "List all DoTs. Requires 0 arguments: [query]"; public const string LISTELITE_HELP = "List all Elites and their language invariants. Requires 0 arguments: [query]"; public const string LISTEQUIP_HELP = "List all equipment and their availability. Requires 0 arguments: [query]"; public const string LISTINTERACTABLE_HELP = "Lists all interactables. Requires 0 arguments: [query]"; public const string LISTITEMTIER_HELP = "List all item tiers. Requires 0 arguments: [query]"; public const string LISTITEM_HELP = "List all items and their availability. Requires 0 arguments: [query]"; public const string LISTPLAYER_HELP = "List all players and their ID. Requires 0 arguments: [query]"; public const string LISTSCENE_HELP = "List all scenes and their language invariants. Requires 0 arguments: [query]"; public const string LISTSKIN_HELP = "List all bodies with skins. Requires 0 arguments: [selection (body|'all'|'body'|'self'):'all']"; public const string LISTTEAM_HELP = "List all Teams and their language invariants. Requires 0 arguments: [query]"; public const string LOADOUTSKIN_HELP = "Change your loadout's skin. Requires 2 argument: {body_name (body|'self')} {skin_index}"; public const string LOCKEXP_HELP = "Toggle Experience gain. Requires 0 arguments."; public const string MACRO_DTZOOM_HELP = "Gives you 20 hooves and 200 feathers for getting around quickly."; public const string MACRO_LATEGAME_HELP = "Sets the current run to the 'lategame' as defined by HG. This command is DESTRUCTIVE."; public const string MACRO_MIDGAME_HELP = "Sets the current run to the 'midgame' as defined by HG. This command is DESTRUCTIVE."; public const string NEXTBOSS_HELP = "Sets the next teleporter/simulacrum boss to the specified boss. Requires 1 argument: {director_card} [count:1] [elite:None]"; public const string NEXTSTAGE_HELP = "Forces a stage change to the specified stage. Requires 0 arguments: [specific_stage]"; public const string NEXTWAVE_HELP = "Advance to the next Simulacrum wave. Requires 0 arguments."; public const string NOCLIP_HELP = "Allow flying and going through objects. Sprinting will double the speed. Requires 0 arguments."; public const string NOENEMIES_HELP = "Toggle Monster spawning. Requires 0 arguments."; public const string PERM_ENABLE_HELP = "Enable or disable the permission system.Requires 0 or 1 arguments: [value (0|1)]"; public const string PERM_MOD_HELP = "Change the permission level of the specified playerid/usernameRequires 2 arguments: {permission_level} {player}"; public const string PERM_RELOAD_HELP = "Reload the permission system, updates user and commands permissions."; public const string POSTSOUNDEVENT_HELP = "Post a sound event to the AkSoundEngine (WWise) either by its event name or event ID. Requires 1 argument: {sound_event (event_name|event_id)}"; public const string PREVENT_PROFILE_WRITING_HELP = "Prevent saving the user profile to avoid bogus data. Requires 0 or 1 arguments [flag (0|1)]"; public const string RANDOMITEM_HELP = "Generate random items from the available item tiers. Requires 1 (3 if from server) argument: {count} [droptable (droptable|'all'):'all'] [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string RELOADCONFIG_HELP = "Reload all default config files from all loaded plugins."; public const string REMOVEALLBUFFS_HELP = "Removes all buffs from a character. Requires 0 (2 if from server) arguments: [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEALLDOTS_HELP = "Removes all DoTs from a character. Requires 0 (1 if from server) arguments: [target (player|'pinged'):<self>]"; public const string REMOVEALLITEMS_HELP = "Removes all items from a target. Requires 0 (1 if from server) arguments: [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEBUFF_HELP = "Removes a specified buff from a character. Timed buffs prioritise the longest expiration stack. Requires 1 (4 if from server) arguments: {buff} [count:1] [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEBUFFSTACKS_HELP = "Removes all stacks of a specified buff from a character. Requires 1 (3 if from server) arguments: {buff} [timed (0|1):0/false] [target (player|'pinged'):<self>]"; public const string REMOVEDOT_HELP = "Remove a DoT stack with the longest expiration from a character. Requires 1 (3 if from server) argument: {dot} [count:1] [target (player|'pinged'):<self>]"; public const string REMOVEDOTSTACKS_HELP = "Remove all stacks of a specified DoT from a character. Requires 1 (2 if from server) argument: {dot} [target (player|'pinged'):<self>]"; public const string REMOVEEQUIP_HELP = "Removes the equipment from a target. Requires 0 (1 if from server) arguments: [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEITEM_HELP = "Removes the specified quantities of an item from a target. Requires 1 (3 if from server) argument: {item} [count:1] [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string REMOVEITEMSTACKS_HELP = "Removes all the stacks of a specified item from a target. Requires 1 (2 if from server) argument: {item} [target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string RESPAWN_HELP = "Respawns the specified player. Requires 0 (1 if from server) arguments: [player:<self>]"; public const string RESTOCKEQUIP_HELP = "Restock charges for the current equipment. Requires 0 (2 if from server) arguments: [count:1] *[target (player|'pinged'|'evolution'|'simulacrum'|'voidfields'|'devotion'):<self>]"; public const string RUNSETWAVESCLEARED_HELP = "Set the Simulacrum waves cleared. Must be positive. Requires 1 argument {wave}"; public const string SEED_HELP = "Gets/Sets the game seed until game close. Use 0 to reset to vanilla generation. Requires 0 or 1 argument: [new_seed]"; public const string SETARTIFACT_HELP = "Enable/disable an Artifact. Requires 1 (2 if using 'all') argument: {artifact (artifact|'all')} [enable (0|1)]"; public const string SPAWNAS_HELP = "Respawn the specified player using the specified body prefab. Requires 1 (2 if from server) argument: {body} [player:<self>]"; public const string SPAWNAI_HELP = "Spawns the specified CharacterMaster. Requires 1 argument: {ai} [count:1] [elite:None] [braindead (0|1):0/false] [team:Monster]"; public const string SPAWNBODY_HELP = "Spawns the specified dummy body. Requires 1 argument: {body}"; public const string SPAWNINTERACTABLE_HELP = "Spawns the specified interactable. List_Interactable for options. Requires 1 argument: {interactable}"; public const string SPAWNPORTAL_HELP = "Spawns a portal in front of the player. Requires 1 argument: {portal ('artifact'|'blue'|'celestial'|'deepvoid'|'gold'|'green'|'null'|'void')}"; public const string TIMESCALE_HELP = "Sets the Time Delta. Requires 1 argument: {time_scale}"; public const string TRUEKILL_HELP = "Ignore Dio's and kill the entity. Requires 0 (1 if from server) arguments: [player:<self>]"; public const string CREATEPICKUP_AMBIGIOUS_2 = "Could not choose between {0} and {1}, please be more precise. Consider using 'equip' or 'item' as the second argument."; public const string CREATEPICKUP_NOTFOUND = "Could not find any item nor equipment with that name."; public const string CREATEPICKUP_SUCCESS_1 = "Successfully created the pickup {0}."; public const string CREATEPICKUP_SUCCESS_2 = "Successfully created a potential with {0} options."; public const string GIVELUNAR_2 = "{0} {1} lunar coin(s)."; public const string GIVEOBJECT = "Gave {0} {1} to {2}."; public const string OBSOLETEWARNING = "This command has become obsolete and will be removed in the next version. "; public const string NETWORKING_OTHERPLAYER_4 = "{0}({1}) issued: {2} {3}"; public const string NOMESSAGE = "Yell at the modmakers if you see this message!"; public const string PARTIALIMPLEMENTATION_WARNING = "WARNING: PARTIAL IMPLEMENTATION. WIP."; public const string PLAYER_DEADRESPAWN = "Player will spawn as the specified body next round. Use 'respawn' to skip the wait."; public const string PLAYER_SKINCHANGERESPAWN = "Player will spawn with the specified skin next round. Use 'respawn' to skip the wait."; public const string REMOVEOBJECT = "Removed {0} {1} from {2}."; public const string RUNSETSTAGESCLEARED_HELP = "Sets the amount of stages cleared. This does not change the current stage."; public const string SETTING_ENABLED = "{0} <color=green>enabled</color>"; public const string SETTING_DISABLED = "{0} <color=red>disabled</color>"; public const string SPAWN_ATTEMPT_1 = "Attempting to spawn: {0}"; public const string SPAWN_ATTEMPT_2 = "Attempting to spawn {0}: {1}"; public const string USE_RESPAWN = "Use 'respawn' to skip the wait."; public const string BODY_NOTFOUND = "Specified body not found. Please use list_body for options."; public const string DOTCONTROLLER_NOTFOUND = "The selected target has no DoTs."; public const string ELITE_NOTFOUND = "Elite type not recognized. Please use list_elite for options."; public const string EXPANSION_LOCKED = "An expansion is required for this {0}: {1}"; public const string INSUFFICIENT_ARGS = "Insufficient number of arguments. "; public const string INTERACTABLE_NOTFOUND = "Interactable not found. Please use list_interactables for options."; public const string INVALID_ARG_VALUE = "Invalid value for {0}."; public const string INVENTORY_ERROR = "The selected target has no inventory."; public const string NEGATIVE_ARG = "Negative value for {0} encountered. It needs to be zero or higher."; public const string NOCONNECTION_ERROR = "Not connected to a server."; public const string NOMATCH_ERROR = "No {0} found that match \"{1}\"."; public const string NOTINARUN_ERROR = "This command only works when in a Run!"; public const string NOTINASIMULACRUMRUN_ERROR = "Must be in a Simulacrum Run!"; public const string NOTINVOIDFIELDS_ERROR = "Must be on Void Fields!"; public const string OBJECT_NOTFOUND = "No {0} with the name \"{1}\" could be found."; public const string PARSE_ERROR = "Unable to parse {0} to {1}."; public const string PINGEDBODY_NOTFOUND = "Pinged target not found. Either the last ping was not a character, or it has been destroyed since."; public const string PLAYER_NOTFOUND = "Specified player not found or isn't alive. Please use list_player for options."; public const string SPAWN_ERROR = "Could not spawn: "; public const string STAGE_NOTFOUND = "Stage not found. Please use list_scene for options."; public const string TEAM_NOTFOUND = "Team type not found. Please use list_team for options."; public const string ALL = "ALL"; public const string BOTH = "BOTH"; public const string COIN_LUNAR = "LUNARCOIN"; public const string COIN_VOID = "VOIDCOIN"; public const string DEFAULT_VALUE = ""; public const string DEVOTION = "DEVOTION"; public const string EQUIP = "EQUIP"; public const string EVOLUTION = "EVOLUTION"; public const string ITEM = "ITEM"; public const string PINGED = "PINGED"; public const string RANDOM = "RANDOM"; public const string SIMULACRUM = "SIMULACRUM"; public const string VOIDFIELDS = "VOIDFIELDS"; public const string PS_ARGUSER_HAS_MORE_PERM = "Specified user {0} has a greater permission level than you."; public const string PS_ARGUSER_HAS_SAME_PERM = "Specified user {0} has the same permission level as you."; public const string PS_NO_REQUIRED_LEVEL = "You don't have the required permission {0} to use this command."; public const string DS_INVALIDARG = "This command doesn't support the '{0}' argument from a dedicated server."; public const string DS_NOTAVAILABLE = "This command doesn't make sense to run from a dedicated server."; public const string DS_NOTYETIMPLEMENTED = "This command has not yet been implemented to be run from a dedicated server,"; } internal class Log { public enum LogLevel { Info = 0, Message = 1, Warning = 2, Error = 3, InfoClientOnly = 69, MessageClientOnly = 70, WarningClientOnly = 71, ErrorClientOnly = 72 } public enum Target { Bepinex = -2, Ror2 } private const bool BepinexInfoAlwaysLogs = true; private const int NetworkEnum = 69; private static ManualLogSource logger; public static BoolConVar DebugConvar = new BoolConVar("DebugToolkit".ToLower() + "_debug", (ConVarFlags)0, "0", "DebugToolkit extensive debugging"); public Log(ManualLogSource bepLogger) { logger = bepLogger; } internal static void InitRPC() { NetworkManager.DebugToolKitComponents.AddComponent<LogNet>(); } public static void Message(object input, LogLevel level = LogLevel.Message, Target target = Target.Ror2) { switch (target) { case Target.Ror2: Ror2Log(input, level); return; case Target.Bepinex: BepinexLog(input, level); return; } if (NetworkUser.readOnlyInstancesList.Count - 1 >= (int)target && target >= (Target)0) { if (input.GetType() != typeof(string)) { Message($"Couldn't send network message because the message was not a string: {input}.", LogLevel.Error, Target.Bepinex); return; } NetworkUser networkUser = NetworkUser.readOnlyInstancesList[(int)target]; MessageInfo($"Send a network message to {(int)target}, length={((string)input).Length}"); Message((string)input, networkUser, level); } else { Message($"Couldn't find target {(int)target} for message: {input}", LogLevel.Error, Target.Bepinex); } } public static void MessageNetworked(string input, ConCommandArgs args, LogLevel level = LogLevel.Message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)args.sender != (Object)null && !((NetworkBehaviour)args.sender).isLocalPlayer) { Message(input, args.sender, level); } if (level < LogLevel.InfoClientOnly || (Object)(object)args.sender == (Object)null || ((NetworkBehaviour)args.sender).isLocalPlayer) { Message(input, level, Target.Ror2); } } public static void Message(string input, NetworkUser networkUser, LogLevel level = LogLevel.Message) { if (!((Object)(object)networkUser == (Object)null)) { LogNet.Invoke(networkUser, input, (int)level); } } public static void MessageWarning(object input, Target target = Target.Ror2) { Message(input, LogLevel.Warning, target); } public static void MessageInfo(object input, Target target = Target.Ror2) { Message(input, LogLevel.Info, target); } private static void Ror2Log(object input, LogLevel level) { switch (level) { case LogLevel.Info: case LogLevel.InfoClientOnly: if (DebugConvar.value) { Debug.Log(input); } break; case LogLevel.Message: case LogLevel.MessageClientOnly: Debug.Log(input); break; case LogLevel.Warning: case LogLevel.WarningClientOnly: Debug.LogWarning(input); break; case LogLevel.Error: case LogLevel.ErrorClientOnly: Debug.LogError(input); break; } } private static void BepinexLog(object input, LogLevel level) { if (logger == null) { throw new NullReferenceException("Log Class in " + Assembly.GetExecutingAssembly().GetName().Name + " not initialized prior to message call!"); } switch (level) { case LogLevel.Info: case LogLevel.InfoClientOnly: logger.LogInfo(input); break; case LogLevel.Message: case LogLevel.MessageClientOnly: logger.LogMessage(input); break; case LogLevel.Warning: case LogLevel.WarningClientOnly: logger.LogWarning(input); break; case LogLevel.Error: case LogLevel.ErrorClientOnly: logger.LogError(input); break; } } } internal class LogNet : NetworkBehaviour { private static LogNet _instance; private static int kTargetRpcTargetLog; private void Awake() { _instance = this; } internal static void Invoke(NetworkUser networkUser, string msg, int level) { _instance.CallTargetLog(((NetworkBehaviour)networkUser).connectionToClient, msg, level); } [TargetRpc] private void TargetLog(NetworkConnection _, string msg, int level) { Log.Message(msg, (Log.LogLevel)level, Log.Target.Ror2); Hooks.ScrollConsoleDown(); } private void UNetVersion() { } protected static void InvokeRpcTargetLog(NetworkBehaviour obj, NetworkReader reader) { if (!NetworkClient.active) { Debug.LogError((object)"TargetRPC TargetLog called on server."); } else { ((LogNet)(object)obj).TargetLog(ClientScene.readyConnection, reader.ReadString(), (int)reader.ReadPackedUInt32()); } } public void CallTargetLog(NetworkConnection _, string msg, int level) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { Debug.LogError((object)"TargetRPC Function TargetLog called on client."); return; } if (_ is ULocalConnectionToServer) { Debug.LogError((object)"TargetRPC Function TargetLog called on connection to server"); return; } NetworkWriter val = new NetworkWriter(); val.Write((short)0); val.Write((short)2); val.WritePackedUInt32((uint)kTargetRpcTargetLog); val.Write(((Component)this).GetComponent<NetworkIdentity>().netId); val.Write(msg); val.WritePackedUInt32((uint)level); ((NetworkBehaviour)this).SendTargetRPCInternal(_, val, 0, "TargetLog"); } static LogNet() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown kTargetRpcTargetLog = -2011288276; NetworkBehaviour.RegisterRpcDelegate(typeof(LogNet), kTargetRpcTargetLog, new CmdDelegate(InvokeRpcTargetLog)); NetworkCRC.RegisterBehaviour("LogNet", 0); } public override bool OnSerialize(NetworkWriter writer, bool forceAll) { bool result = default(bool); return result; } public override void OnDeserialize(NetworkReader reader, bool initialState) { } } internal static class NetworkManager { internal static GameObject DebugToolKitComponents; private static GameObject _debugToolKitComponentsSpawned; internal static void Init() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_001c: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown GameObject val = new GameObject("dtcn"); val.AddComponent<NetworkIdentity>(); DebugToolKitComponents = PrefabAPI.InstantiateClone(val, "DebugToolKitComponentsNetworked"); Object.Destroy((Object)val); Log.InitRPC(); Command_Noclip.InitRPC(); Command_Teleport.InitRPC(); DebugToolKitComponents.AddComponent<TimescaleNet>(); DebugToolKitComponents.AddComponent<SetDontDestroyOnLoad>(); } internal static void CreateNetworkObject(orig_Start orig, NetworkSession self) { orig.Invoke(self); if (!Object.op_Implicit((Object)(object)_debugToolKitComponentsSpawned) && NetworkServer.active) { _debugToolKitComponentsSpawned = Object.Instantiate<GameObject>(DebugToolKitComponents); NetworkServer.Spawn(_debugToolKitComponentsSpawned); } } internal static void DestroyNetworkObject(orig_OnDestroy orig, NetworkSession self) { if (Object.op_Implicit((Object)(object)_debugToolKitComponentsSpawned) && NetworkServer.active) { NetworkServer.Destroy(_debugToolKitComponentsSpawned); _debugToolKitComponentsSpawned = null; } orig.Invoke(self); } } public sealed class StringFinder { private struct MatchSimilarity { public int similarity; public object item; } private static readonly Dictionary<string, string[]> BodyAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> MasterAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> BuffAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> DotAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> ItemAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> EquipAlias = new Dictionary<string, string[]>(); private static readonly Dictionary<string, string[]> SkinAlias = new Dictionary<string, string[]>(); private static StringFinder instance; private static readonly List<DirectorCard> characterSpawnCard = new List<DirectorCard>(); private static readonly List<InteractableSpawnCard> interactableSpawnCards = new List<InteractableSpawnCard>(); private static readonly string NAME_NOTFOUND = "???"; public static EliteIndex EliteIndex_NotFound = (EliteIndex)(-2); public static ItemTier ItemTier_NotFound = (ItemTier)(-1); public static TeamIndex TeamIndex_NotFound = (TeamIndex)(-2); public static StringFinder Instance => instance ?? (instance = new StringFinder()); public List<DirectorCard> DirectorCards => characterSpawnCard; public List<InteractableSpawnCard> InteractableSpawnCards => interactableSpawnCards; private StringFinder() { BodyAlias.Add("ToolbotBody", new string[3] { "MULT", "MUL-T", "ShoppingTrolly" }); BodyAlias.Add("MercBody", new string[2] { "Mercenary", "Ninja" }); BodyAlias.Add("MageBody", new string[2] { "Artificer", "Arti" }); BodyAlias.Add("EngiBody", new string[1] { "Engineer" }); BodyAlias.Add("HANDBody", new string[1] { "HAN-D" }); BodyAlias.Add("TreebotBody", new string[4] { "Treebot", "REX", "PlantBot", "Shrub" }); BodyAlias.Add("CrocoBody", new string[1] { "barney" }); BodyAlias.Add("RoboBallBossBody", new string[2] { "SCU", "roboboss" }); BodyAlias.Add("SuperRoboBallBossBody", new string[1] { "AWU" }); MasterAlias.Add("LemurianBruiserMasterFire", new string[2] { "LemurianBruiserFire", "BruiserFire" }); MasterAlias.Add("LemurianBruiserMasterIce", new string[2] { "LemurianBruiserIce", "BruiserIce" }); MasterAlias.Add("LemurianBruiserMasterHaunted", new string[2] { "LemurianBruiserHaunted", "BruiserHaunter" }); MasterAlias.Add("LemurianBruiserMasterPoison", new string[3] { "LemurianBruiserPoison", "LemurianBruiserBlight", "LemurianBruisermalechite" }); MasterAlias.