Some mods may be broken due to the recent Alloyed Collective update.
Decompiled source of Pathfixer v1.0.0
plugins/Pathfixer/Pathfixer.dll
Decompiled a year 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); } }; } } }