Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Pathfixer v1.0.0
plugins/Pathfixer/Pathfixer.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG.Reflection; using HarmonyLib; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using Pathfixer.Utilities.Extensions; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.Options; using RoR2; using RoR2.CharacterAI; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: NetworkCompatibility(/*Could not decode attribute arguments.*/)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Pathfixer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1f43eb0e21debcfd96f822efc9d2eb4d2ea1f886")] [assembly: AssemblyProduct("Pathfixer")] [assembly: AssemblyTitle("Pathfixer")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Pathfixer { internal static class CharacterFootPositionFix { [CompilerGenerated] private static class <>O { public static Manipulator <0>__CharacterBody_CorePositionFix; public static Func<Vector3, CharacterBody, Vector3> <1>__getColliderCenterPosition; } private static bool _tempDisablePatches; public static void Init() { //IL_003a: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.DeclaredPropertyGetter(typeof(CharacterBody), "corePosition"); if (methodInfo != null) { object obj = <>O.<0>__CharacterBody_CorePositionFix; if (obj == null) { Manipulator val = CharacterBody_CorePositionFix; <>O.<0>__CharacterBody_CorePositionFix = val; obj = (object)val; } new ILHook((MethodBase)methodInfo, (Manipulator)obj); } else { Log.Error("Failed to find CharacterBody.get_corePosition method", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\CharacterFootPositionFix.cs", "Init", 24); } MethodInfo methodInfo2 = AccessTools.DeclaredPropertyGetter(typeof(CharacterBody), "footPosition"); if (methodInfo2 != null) { object obj2 = <>O.<0>__CharacterBody_CorePositionFix; if (obj2 == null) { Manipulator val2 = CharacterBody_CorePositionFix; <>O.<0>__CharacterBody_CorePositionFix = val2; obj2 = (object)val2; } new ILHook((MethodBase)methodInfo2, (Manipulator)obj2); } else { Log.Error("Failed to find CharacterBody.get_footPosition method", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\CharacterFootPositionFix.cs", "Init", 34); } } public static Vector3 GetUnmodifiedFootPosition(CharacterBody body) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) _tempDisablePatches = true; try { return body.footPosition; } finally { _tempDisablePatches = false; } } public static Vector3 GetUnmodifiedCorePosition(CharacterBody body) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) _tempDisablePatches = true; try { return body.corePosition; } finally { _tempDisablePatches = false; } } private static void CharacterBody_CorePositionFix(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) ILCursor[] array = default(ILCursor[]); if (new ILCursor(il).TryFindNext(ref array, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdfld<CharacterBody>(x, "transform"), (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt(x, (MethodBase)AccessTools.DeclaredPropertyGetter(typeof(Transform), "position")) })) { ILCursor obj = array[^1]; int index = obj.Index; obj.Index = index + 1; obj.Emit(OpCodes.Ldarg_0); obj.EmitDelegate<Func<Vector3, CharacterBody, Vector3>>((Func<Vector3, CharacterBody, Vector3>)getColliderCenterPosition); } else { Log.Error("Failed to find patch location", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\CharacterFootPositionFix.cs", "CharacterBody_CorePositionFix", 94); } static Vector3 getColliderCenterPosition(Vector3 origPosition, CharacterBody body) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!_tempDisablePatches) { CharacterMotor characterMotor = body.characterMotor; if (Object.op_Implicit((Object)(object)characterMotor) && Object.op_Implicit((Object)(object)characterMotor.capsuleCollider)) { return ((Component)characterMotor.capsuleCollider).transform.TransformPoint(characterMotor.capsuleCollider.center); } } return origPosition; } } } internal static class HalcyonitePathingFix { private static AISkillDriver[] _enableNodeGraphSkillDriverPrefabs = Array.Empty<AISkillDriver>(); public static ConfigEntry<bool> EnableHalcyonitePathingChanges { get; private set; } public static void Init(ConfigFile configFile) { //IL_000b: 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_0026: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) EnableHalcyonitePathingChanges = configFile.Bind<bool>(new ConfigDefinition("Tweaks", "Enable Halcyonite Pathing Changes"), true, new ConfigDescription("Enables or disables tweaks to Halcyonite AI to make it use pathfinding", (AcceptableValueBase)null, Array.Empty<object>())); EnableHalcyonitePathingChanges.SettingChanged += onEnableHalcyonitePathingChangesChanged; Addressables.LoadAssetAsync<GameObject>((object)"RoR2/DLC2/Halcyonite/HalcyoniteMaster.prefab").CallOnSuccess(delegate(GameObject halcyoniteMaster) { AISkillDriver[] components = halcyoniteMaster.GetComponents<AISkillDriver>(); List<AISkillDriver> list = new List<AISkillDriver>(components.Length); AISkillDriver[] array = components; foreach (AISkillDriver val in array) { if (val.customName == "Follow Target" || val.customName == "WhirlwindRush") { if (!val.ignoreNodeGraph) { Log.Warning("Halcyonite SkillDriver " + val.customName + " is already using NodeGraph", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\HalcyonitePathingFix.cs", "Init", 32); } else { list.Add(val); } } } _enableNodeGraphSkillDriverPrefabs = list.ToArray(); refreshIgnoreNodeGraph(); }); } private static void onEnableHalcyonitePathingChangesChanged(object sender, EventArgs e) { refreshIgnoreNodeGraph(); } private static void refreshIgnoreNodeGraph() { AISkillDriver[] enableNodeGraphSkillDriverPrefabs = _enableNodeGraphSkillDriverPrefabs; for (int i = 0; i < enableNodeGraphSkillDriverPrefabs.Length; i++) { enableNodeGraphSkillDriverPrefabs[i].ignoreNodeGraph = !EnableHalcyonitePathingChanges.Value; } } } internal static class Log { private static readonly StringBuilder _sharedStringBuilder; private static readonly int _cachedCallerPathPrefixLength; private static ManualLogSource _logSource; static Log() { _sharedStringBuilder = new StringBuilder(256); _cachedCallerPathPrefixLength = getCallerPathPrefixLength("X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\Log.cs"); static int getCallerPathPrefixLength([CallerFilePath] string callerPath = null) { int num = callerPath.LastIndexOf("Pathfixer\\"); if (num >= 0) { return num + "Pathfixer\\".Length; } Debug.LogError((object)"[Pathfixer] Logger failed to determine caller path prefix length"); return 0; } } internal static void Init(ManualLogSource logSource) { _logSource = logSource; } private static StringBuilder AppendCallerPrefix(this StringBuilder stringBuilder, string callerPath, string callerMemberName, int callerLineNumber) { return stringBuilder.Append(callerPath, _cachedCallerPathPrefixLength, callerPath.Length - _cachedCallerPathPrefixLength).Append(':').Append(callerLineNumber) .Append(" (") .Append(callerMemberName) .Append("):"); } private static StringBuilder buildCallerLogString(string callerPath, string callerMemberName, int callerLineNumber, object data) { return _sharedStringBuilder.Clear().AppendCallerPrefix(callerPath, callerMemberName, callerLineNumber).Append(' ') .Append(data); } [Conditional("DEBUG")] internal static void Debug(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogDebug((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] [Conditional("DEBUG")] internal static void Debug_NoCallerPrefix(object data) { _logSource.LogDebug(data); } internal static void Error(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogError((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Error_NoCallerPrefix(object data) { _logSource.LogError(data); } internal static void Fatal(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogFatal((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Fatal_NoCallerPrefix(object data) { _logSource.LogFatal(data); } internal static void Info(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogInfo((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Info_NoCallerPrefix(object data) { _logSource.LogInfo(data); } internal static void Message(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogMessage((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Message_NoCallerPrefix(object data) { _logSource.LogMessage(data); } internal static void Warning(object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { _logSource.LogWarning((object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void Warning_NoCallerPrefix(object data) { _logSource.LogWarning(data); } internal static void LogType(LogLevel level, object data, [CallerFilePath] string callerPath = "", [CallerMemberName] string callerMemberName = "", [CallerLineNumber] int callerLineNumber = -1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, (object)buildCallerLogString(callerPath, callerMemberName, callerLineNumber, data)); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static void LogType_NoCallerPrefix(LogLevel level, object data) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if ((level & 0x20) == 0) { _logSource.Log(level, data); } } } [BepInPlugin("Gorakh.Pathfixer", "Pathfixer", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class PathfixerPlugin : BaseUnityPlugin { public const string PluginGUID = "Gorakh.Pathfixer"; public const string PluginAuthor = "Gorakh"; public const string PluginName = "Pathfixer"; public const string PluginVersion = "1.0.0"; private static PathfixerPlugin _instance; internal static PathfixerPlugin Instance => _instance; private void Awake() { Stopwatch stopwatch = Stopwatch.StartNew(); SingletonHelper.Assign<PathfixerPlugin>(ref _instance, this); Log.Init(((BaseUnityPlugin)this).Logger); CharacterFootPositionFix.Init(); HalcyonitePathingFix.Init(((BaseUnityPlugin)this).Config); if (RiskOfOptionsCompat.Enabled) { RiskOfOptionsCompat.AddOptions(); } stopwatch.Stop(); Log.Message_NoCallerPrefix($"Initialized in {stopwatch.Elapsed.TotalMilliseconds:F0}ms"); } } internal static class RiskOfOptionsCompat { private static Sprite _iconSprite; private const string MOD_GUID = "Gorakh.Pathfixer"; private const string MOD_NAME = "Pathfixer"; public static bool Enabled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"); [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)] public static void AddOptions() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown ModSettingsManager.SetModDescription("Options for Pathfixer", "Gorakh.Pathfixer", "Pathfixer"); Sprite val = tryGetIcon(); if (Object.op_Implicit((Object)(object)val)) { ModSettingsManager.SetModIcon(val, "Gorakh.Pathfixer", "Pathfixer"); } if (HalcyonitePathingFix.EnableHalcyonitePathingChanges != null) { ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(HalcyonitePathingFix.EnableHalcyonitePathingChanges), "Gorakh.Pathfixer", "Pathfixer"); } } private static Sprite tryGetIcon() { if (!Object.op_Implicit((Object)(object)_iconSprite)) { _iconSprite = tryGenerateIcon(); if (!Object.op_Implicit((Object)(object)_iconSprite)) { Log.Warning("Failed to get config icon", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\RiskOfOptionsCompat.cs", "tryGetIcon", 46); } } return _iconSprite; } private static Sprite tryGenerateIcon() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) FileInfo fileInfo = findIconFileRecursive(new DirectoryInfo(Path.GetDirectoryName(((BaseUnityPlugin)PathfixerPlugin.Instance).Info.Location))); if (fileInfo == null) { return null; } byte[] array; try { array = File.ReadAllBytes(fileInfo.FullName); } catch (Exception arg) { Log.Error_NoCallerPrefix($"Failed to read icon file '{fileInfo.FullName}': {arg}"); return null; } Texture2D val = new Texture2D(256, 256); ((Object)val).name = "texPathfixerIcon"; if (!ImageConversion.LoadImage(val, array)) { Log.Error("Failed to load icon into texture", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\RiskOfOptionsCompat.cs", "tryGenerateIcon", 75); return null; } Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); ((Object)obj).name = "PathfixerIcon"; return obj; } private static FileInfo findIconFileRecursive(DirectoryInfo dir) { if (dir == null) { return null; } if (string.Equals(dir.FullName, Paths.PluginPath, StringComparison.OrdinalIgnoreCase)) { return null; } FileInfo fileInfo = dir.EnumerateFiles("icon.png", SearchOption.TopDirectoryOnly).FirstOrDefault(); if (fileInfo != null) { return fileInfo; } return findIconFileRecursive(dir.Parent); } } } namespace Pathfixer.Utilities.Extensions { public static class AssetLoadExtensions { public static void CallOnSuccess<T>(this AsyncOperationHandle<T> handle, Action<T> onSuccess) { handle.Completed += delegate(AsyncOperationHandle<T> handle) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 if ((int)handle.Status == 2) { Log.Error("Failed to load asset '" + handle.LocationName + "'", "X:\\Git\\RoR2\\Pathfixer\\Pathfixer\\Utilities\\Extensions\\AssetLoadExtensions.cs", "CallOnSuccess", 19); } else { onSuccess(handle.Result); } }; } } }