using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Matsu.BountyHuntersFixed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Matsu.BountyHuntersFixed")] [assembly: AssemblyTitle("Matsu.BountyHuntersFixed")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [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 Matsu.BountyHuntersFixed { [BepInPlugin("com.matsu.bountyhuntersfixed", "Bounty Hunters Fixed", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string Guid = "com.matsu.bountyhuntersfixed"; public const string Name = "Bounty Hunters Fixed"; public const string Version = "1.0.0"; private const string BountyHuntersGuid = "denis.repo.bountyhuntersui"; public static ManualLogSource Log; public static ConfigEntry Tier1Value; public static ConfigEntry Tier2Value; public static ConfigEntry Tier3Value; public static ConfigEntry DefaultValue; private void Awake() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; Tier1Value = ((BaseUnityPlugin)this).Config.Bind("Bounty", "Difficulty1Value", 2000, "Bounty paid for an unregistered/mod-added enemy of difficulty tier 1 (matches vanilla easy enemies, e.g. Elsa/Peeper)."); Tier2Value = ((BaseUnityPlugin)this).Config.Bind("Bounty", "Difficulty2Value", 3000, "Bounty paid for an unregistered/mod-added enemy of difficulty tier 2 (matches vanilla medium enemies, e.g. Hidden/Mentalist)."); Tier3Value = ((BaseUnityPlugin)this).Config.Bind("Bounty", "Difficulty3Value", 5000, "Bounty paid for an unregistered/mod-added enemy of difficulty tier 3 (matches vanilla hard enemies, e.g. Cleanup Crew/Huntsman)."); DefaultValue = ((BaseUnityPlugin)this).Config.Bind("Bounty", "FallbackValue", 2000, "Bounty paid when an enemy's difficulty can't be determined (falls back to the lowest tier)."); Type type = AccessTools.TypeByName("BountyHunters.EnemyNameDirectory"); Type type2 = AccessTools.TypeByName("BountyHunters.BountyRewardTable"); if (type == null || type2 == null) { Log.LogInfo((object)"Bounty Hunters not found — patch idle (soft dependency)."); return; } try { BhBridge.Init(type, type2); Harmony val = new Harmony("com.matsu.bountyhuntersfixed"); MethodInfo methodInfo = AccessTools.Method(type, "Normalize", new Type[1] { typeof(string) }, (Type[])null); val.Patch((MethodBase)methodInfo, new HarmonyMethod(AccessTools.Method(typeof(NormalizePatch), "Prefix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.Method(type2, "TryGetReward", (Type[])null, (Type[])null); val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(AccessTools.Method(typeof(TryGetRewardPatch), "Postfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)"Bounty Hunters Fixed 1.0.0 — patched Bounty Hunters (unregistered enemies now get an auto bounty; warning spam suppressed)."); } catch (Exception arg) { Log.LogError((object)$"Failed to patch Bounty Hunters: {arg}"); } } public static int TierValue(Difficulty d) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown return (int)d switch { 0 => Tier1Value.Value, 1 => Tier2Value.Value, 2 => Tier3Value.Value, _ => DefaultValue.Value, }; } } internal static class BhBridge { private static IDictionary? _nameMapping; public static void Init(Type enemyNameDirectory, Type rewardTable) { _nameMapping = AccessTools.Field(enemyNameDirectory, "NameMapping")?.GetValue(null) as IDictionary; } public static bool TryMapName(string rawName, out string mapped) { mapped = rawName; if (_nameMapping == null) { return false; } if (_nameMapping.Contains(rawName)) { mapped = (string)_nameMapping[rawName]; return true; } return false; } } internal static class DifficultyCache { private static readonly Dictionary _valueByName = new Dictionary(); public static void RefreshFromLiveEnemies() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) try { EnemyDirector instance = EnemyDirector.instance; if (instance?.enemiesSpawned == null) { return; } foreach (EnemyParent item in instance.enemiesSpawned) { if (!((Object)(object)item == (Object)null)) { string enemyName = item.enemyName; if (!string.IsNullOrEmpty(enemyName) && !_valueByName.ContainsKey(enemyName)) { _valueByName[enemyName] = Plugin.TierValue(item.difficulty); } } } } catch { } } public static int ValueFor(string name) { if (!_valueByName.TryGetValue(name, out var value)) { return Plugin.DefaultValue.Value; } return value; } } internal static class NormalizePatch { public static bool Prefix(string rawName, ref string __result) { DifficultyCache.RefreshFromLiveEnemies(); if (string.IsNullOrWhiteSpace(rawName)) { __result = "Unknown"; return false; } if (BhBridge.TryMapName(rawName, out string mapped)) { __result = mapped; return false; } __result = rawName; return false; } } internal static class TryGetRewardPatch { public static void Postfix(string rawEnemyName, ref int reward, ref bool __result) { if (!__result && !string.IsNullOrWhiteSpace(rawEnemyName)) { reward = DifficultyCache.ValueFor(rawEnemyName.Trim()); __result = true; } } } }