Decompiled source of ExtraBiomeBounties v1.0.0

plugins/TXC.ExtraBiomeBounties.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EpicLoot.Adventure;
using EpicLoot.Adventure.Feature;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: AssemblyCompany("TXC.ExtraBiomeBounties")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TXC.ExtraBiomeBounties")]
[assembly: AssemblyTitle("TXC.ExtraBiomeBounties")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace TXC.ExtraBiomeBounties
{
	[BepInPlugin("txc.extrabiomebounties", "TXC Extra Biome Bounties", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "txc.extrabiomebounties";

		public const string PluginName = "TXC Extra Biome Bounties";

		public const string PluginVersion = "1.0.0";

		private static readonly Biome[] ConfigurableBiomes;

		internal static ManualLogSource Log;

		internal static readonly Dictionary<Biome, ConfigEntry<int>> BountyCounts;

		private Harmony _harmony;

		private unsafe void Awake()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fd: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Biome[] configurableBiomes = ConfigurableBiomes;
			for (int i = 0; i < configurableBiomes.Length; i++)
			{
				Biome val = configurableBiomes[i];
				BountyCounts[val] = ((BaseUnityPlugin)this).Config.Bind<int>("BountyCount", ((object)(*(Biome*)(&val))/*cast due to .constrained prefix*/).ToString(), 1, new ConfigDescription($"Bounties offered for {val} on each player's board. " + "0 = none, 1 = EpicLoot default, 2+ = extra bounties with different targets (capped by the number of distinct targets configured for the biome).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = true
				} }));
			}
			try
			{
				if (!BountyPatch.Resolve(out var original, out var missing))
				{
					Log.LogWarning((object)("EpicLoot bounty internals not found (" + missing + "). Plugin disabled; bounty boards are unchanged."));
					return;
				}
				_harmony = new Harmony("txc.extrabiomebounties");
				_harmony.Patch((MethodBase)original, new HarmonyMethod(typeof(BountyPatch), "Prefix", (Type[])null), new HarmonyMethod(typeof(BountyPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				Log.LogInfo((object)("Patched " + original.DeclaringType?.Name + "." + original.Name + "."));
			}
			catch (Exception arg)
			{
				Log.LogWarning((object)$"Failed to patch EpicLoot bounties, plugin disabled: {arg}");
			}
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		static Plugin()
		{
			Biome[] array = new Biome[8];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			ConfigurableBiomes = (Biome[])(object)array;
			BountyCounts = new Dictionary<Biome, ConfigEntry<int>>();
		}
	}
	internal static class BountyPatch
	{
		private const int StreamBase = 4242;

		private static Func<int, int, int, Random> _getRandomForInterval;

		private static Func<Random, bool, bool, int> _getTargetLevel;

		private static readonly HashSet<string> Warned = new HashSet<string>();

		internal static bool Resolve(out MethodInfo original, out string missing)
		{
			original = AccessTools.Method(typeof(BountiesAdventureFeature), "GetAvailableBounties", new Type[3]
			{
				typeof(int),
				typeof(bool),
				typeof(List<BountyFilterNote>)
			}, (Type[])null);
			MethodInfo methodInfo = AccessTools.Method(typeof(AdventureFeature), "GetRandomForInterval", new Type[3]
			{
				typeof(int),
				typeof(int),
				typeof(int)
			}, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(BountiesAdventureFeature), "GetTargetLevel", new Type[3]
			{
				typeof(Random),
				typeof(bool),
				typeof(bool)
			}, (Type[])null);
			missing = string.Join(", ", new string[3]
			{
				(original == null) ? "GetAvailableBounties(int, bool, List<BountyFilterNote>)" : null,
				(methodInfo == null) ? "GetRandomForInterval(int, int, int)" : null,
				(methodInfo2 == null) ? "GetTargetLevel(Random, bool, bool)" : null
			}.Where((string x) => x != null));
			if (original == null || methodInfo == null || methodInfo2 == null)
			{
				return false;
			}
			_getRandomForInterval = AccessTools.MethodDelegate<Func<int, int, int, Random>>(methodInfo, (object)null, true);
			_getTargetLevel = AccessTools.MethodDelegate<Func<Random, bool, bool, int>>(methodInfo2, (object)null, true);
			return true;
		}

		internal static void Prefix(ref bool removeAcceptedBounties, out bool __state)
		{
			__state = removeAcceptedBounties;
			removeAcceptedBounties = false;
		}

		internal static void Postfix(BountiesAdventureFeature __instance, int interval, List<BountyInfo> __result, bool __state)
		{
			if (__result == null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			try
			{
				if ((Object)(object)localPlayer != (Object)null)
				{
					ApplyBountyCounts(__instance, interval, localPlayer, __result);
				}
			}
			catch (Exception arg)
			{
				WarnOnce("apply", $"Error adjusting bounty board, extra bounties skipped: {arg}");
			}
			if (!__state || !((Object)(object)localPlayer != (Object)null))
			{
				return;
			}
			AdventureSaveData saveData = PlayerExtensions_Adventure.GetAdventureSaveData(localPlayer);
			if (saveData != null)
			{
				__result.RemoveAll((BountyInfo x) => saveData.HasAcceptedBounty(x.Interval, x.ID));
			}
		}

		private static void ApplyBountyCounts(BountiesAdventureFeature feature, int interval, Player player, List<BountyInfo> bounties)
		{
			//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)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Biome, ConfigEntry<int>> bountyCount in Plugin.BountyCounts)
			{
				Biome biome = bountyCount.Key;
				int value = bountyCount.Value.Value;
				if (value == 1)
				{
					continue;
				}
				int num = bounties.FindLastIndex((BountyInfo x) => x.Biome == biome);
				if (num < 0)
				{
					continue;
				}
				if (value <= 0)
				{
					bounties.RemoveAll((BountyInfo x) => x.Biome == biome);
					continue;
				}
				HashSet<string> usedTargets = new HashSet<string>(from x in bounties
					where x.Biome == biome
					select x.Target.MonsterID);
				int num2 = value - usedTargets.Count;
				if (num2 > 0)
				{
					List<BountyTargetConfig> list = (from t in AdventureDataManager.Config.Bounties.Targets
						where t.GetBiome() == biome && !usedTargets.Contains(t.TargetID) && (Object)(object)PrefabManager.Instance.GetPrefab(t.TargetID) != (Object)null
						group t by t.TargetID into g
						select g.First()).ToList();
					Random random = _getRandomForInterval(interval, ((AdventureFeature)feature).RefreshInterval, 4242 + BiomeIndex(biome));
					List<BountyInfo> list2 = new List<BountyInfo>();
					while (list2.Count < num2 && list.Count > 0)
					{
						int index = random.Next(0, list.Count);
						list2.Add(CreateBounty(list[index], interval, player, random));
						list.RemoveAt(index);
					}
					if (list2.Count < num2)
					{
						WarnOnce($"short.{biome}.{interval}", $"{biome}: BountyCount is {value} but only {usedTargets.Count + list2.Count} distinct targets are available.");
					}
					bounties.InsertRange(num + 1, list2);
				}
			}
		}

		private static BountyInfo CreateBounty(BountyTargetConfig targetConfig, int interval, Player player, Random random)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_006f: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			return new BountyInfo
			{
				Biome = targetConfig.GetBiome(),
				Interval = interval,
				PlayerID = player.GetPlayerID(),
				Target = new BountyTargetInfo
				{
					MonsterID = targetConfig.TargetID,
					Level = _getTargetLevel(random, targetConfig.RewardGold > 0, arg3: false),
					Count = 1
				},
				TargetName = BountiesAdventureFeature.GenerateTargetName(random),
				RewardIron = targetConfig.RewardIron,
				RewardGold = targetConfig.RewardGold,
				RewardCoins = targetConfig.RewardCoins,
				Adds = ((IEnumerable<BountyTargetAddConfig>)(targetConfig.Adds ?? new List<BountyTargetAddConfig>())).Select((Func<BountyTargetAddConfig, BountyTargetInfo>)((BountyTargetAddConfig x) => new BountyTargetInfo
				{
					MonsterID = x.ID,
					Count = x.Count,
					Level = _getTargetLevel(random, arg2: false, arg3: true)
				})).ToList()
			};
		}

		private static int BiomeIndex(Biome biome)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			uint num = (uint)(int)biome;
			int num2 = 0;
			while (num > 1)
			{
				num >>= 1;
				num2++;
			}
			return num2;
		}

		private static void WarnOnce(string key, string message)
		{
			if (Warned.Add(key))
			{
				Plugin.Log.LogWarning((object)message);
			}
		}
	}
}