Decompiled source of ShrineBag v1.0.2

ShrineBag.dll

Decompiled 8 hours ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using On.RoR2;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ShrineBag")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+9296a5b680d9ed6fafac8c8f3f4ccf0a46da6560")]
[assembly: AssemblyProduct("ShrineBag")]
[assembly: AssemblyTitle("ShrineBag")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[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 ShrineBag
{
	internal static class ModIcon
	{
		public static Sprite Load()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ShrineBag.icon.png") ?? throw new InvalidOperationException("Embedded mod icon resource was not found.");
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray(), true))
			{
				Object.Destroy((Object)(object)val);
				throw new InvalidOperationException("Failed to load mod icon.");
			}
			((Object)val).name = "PapitaPure_ShrineBagIcon";
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
	internal static class ModSettings
	{
		internal interface IEntryConstraint<TValue> where TValue : IComparable
		{
			AcceptableValueBase AcceptableValue { get; }

			TValue Clamp(TValue value);

			bool IsValid(object value);
		}

		internal sealed class RangeEntryConstraint<TValue> : IEntryConstraint<TValue> where TValue : IComparable
		{
			public AcceptableValueBase AcceptableValue { get; } = (AcceptableValueBase)(object)new AcceptableValueRange<TValue>(min, max);

			public TValue Min { get; }

			public TValue Max { get; }

			public RangeEntryConstraint(TValue min, TValue max)
			{
				Min = min;
				Max = max;
				base..ctor();
			}

			public TValue Clamp(TValue value)
			{
				return (TValue)AcceptableValue.Clamp((object)value);
			}

			public bool IsValid(object value)
			{
				return AcceptableValue.IsValid(value);
			}
		}

		internal class Entry<TValue>(string name, string description, TValue defaultValue) where TValue : IComparable
		{
			public string Name { get; } = name;

			public string Description { get; } = description;

			public TValue Default { get; } = defaultValue;
		}

		internal class ConstrainedEntry<TValue, TConstraint> : Entry<TValue> where TValue : IComparable where TConstraint : IEntryConstraint<TValue>
		{
			public IEntryConstraint<TValue> Constraint { get; }

			public ConstrainedEntry(string name, string description, TValue defaultValue, TConstraint constraint)
			{
				Constraint = constraint;
				base..ctor(name, description, defaultValue);
			}
		}

		public static readonly Entry<bool> Enabled = new Entry<bool>("Enabled", "Enables the mod.", defaultValue: true);

		public static readonly ConstrainedEntry<int, RangeEntryConstraint<int>> Rewards = new ConstrainedEntry<int, RangeEntryConstraint<int>>("Total Rewards", "Number of prayers that constitute a reward.\n=== You offer to the shrine and are rewarded! ===", 2, new RangeEntryConstraint<int>(1, 20));

		public static readonly ConstrainedEntry<int, RangeEntryConstraint<int>> Failures = new ConstrainedEntry<int, RangeEntryConstraint<int>>("Max. Failures", "Number of prayers that will yield nothing.\n=== You offer to the shrine, but gain nothing. ===", 4, new RangeEntryConstraint<int>(0, 20));
	}
	internal static class ModSettingsManagerCompat
	{
		private static bool? enabled;

		public static bool Enabled
		{
			get
			{
				bool valueOrDefault = enabled == true;
				if (!enabled.HasValue)
				{
					valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
					enabled = valueOrDefault;
				}
				return enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetModIcon(Sprite sprite)
		{
			ModSettingsManager.SetModIcon(sprite);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetModDescription(string desc)
		{
			ModSettingsManager.SetModDescription(desc);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddCheckboxOption(ConfigEntry<bool> entry)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(entry));
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddSliderOption<TValue>(ConfigEntry<TValue> entry, ModSettings.RangeEntryConstraint<TValue> range, string formatString = "{0}") where TValue : IComparable
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Expected O, but got Unknown
			//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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			if (entry is ConfigEntry<int> val && range is ModSettings.RangeEntryConstraint<int> rangeEntryConstraint)
			{
				ModSettingsManager.AddOption((BaseOption)new IntSliderOption(val, new IntSliderConfig
				{
					min = rangeEntryConstraint.Min,
					max = rangeEntryConstraint.Max,
					formatString = formatString
				}));
				return;
			}
			ConfigEntry<float> obj = entry as ConfigEntry<float>;
			if (obj == null || !(range is ModSettings.RangeEntryConstraint<float> rangeEntryConstraint2))
			{
				throw new ArgumentException("Expected an int or float entry/constraint for slider option.");
			}
			ModSettingsManager.AddOption((BaseOption)new SliderOption(obj, new SliderConfig
			{
				min = rangeEntryConstraint2.Min,
				max = rangeEntryConstraint2.Max,
				FormatString = formatString
			}));
		}
	}
	[BepInPlugin("com.papitaconpure.shrinebag", "Shrine Bag", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_AddShrineStack <0>__OnAddShrineStack;
		}

		public const string PluginGuid = "com.papitaconpure.shrinebag";

		public const string PluginName = "Shrine Bag";

		public const string PluginVersion = "1.0.2";

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<int> RewardCount;

		internal static ConfigEntry<int> FailureCount;

		private void Awake()
		{
			//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_0027: Expected O, but got Unknown
			RegisterSettings();
			TryRegisterRiskOfOptions();
			object obj = <>O.<0>__OnAddShrineStack;
			if (obj == null)
			{
				hook_AddShrineStack val = OnAddShrineStack;
				<>O.<0>__OnAddShrineStack = val;
				obj = (object)val;
			}
			ShrineChanceBehavior.AddShrineStack += (hook_AddShrineStack)obj;
		}

		private void OnDestroy()
		{
			//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
			object obj = <>O.<0>__OnAddShrineStack;
			if (obj == null)
			{
				hook_AddShrineStack val = OnAddShrineStack;
				<>O.<0>__OnAddShrineStack = val;
				obj = (object)val;
			}
			ShrineChanceBehavior.AddShrineStack -= (hook_AddShrineStack)obj;
		}

		private static void OnAddShrineStack(orig_AddShrineStack origAddShrineStack, ShrineChanceBehavior self, Interactor activator)
		{
			if (!NetworkServer.active || !Enabled.Value || (Object)(object)self == (Object)null)
			{
				origAddShrineStack.Invoke(self, activator);
				return;
			}
			if (!(((Component)self).GetComponent<ShrineChanceBag>() ?? ((Component)self).gameObject.AddComponent<ShrineChanceBag>()).TryDraw(RewardCount.Value, FailureCount.Value, out var rewarded))
			{
				PurchaseInteraction component = ((Component)self).GetComponent<PurchaseInteraction>();
				if (component != null)
				{
					component.SetAvailable(false);
				}
				return;
			}
			float failureChance = self.failureChance;
			self.failureChance = (rewarded ? (-1f) : 1f);
			self.maxPurchaseCount = RewardCount.Value;
			try
			{
				origAddShrineStack.Invoke(self, activator);
			}
			finally
			{
				self.failureChance = failureChance;
			}
		}

		private void RegisterSettings()
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", ModSettings.Enabled.Name, ModSettings.Enabled.Default, ModSettings.Enabled.Description);
			RewardCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", ModSettings.Rewards.Name, ModSettings.Rewards.Default, new ConfigDescription(ModSettings.Rewards.Description, ModSettings.Rewards.Constraint.AcceptableValue, Array.Empty<object>()));
			FailureCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", ModSettings.Failures.Name, ModSettings.Failures.Default, new ConfigDescription(ModSettings.Failures.Description, ModSettings.Failures.Constraint.AcceptableValue, Array.Empty<object>()));
		}

		private void TryRegisterRiskOfOptions()
		{
			if (!ModSettingsManagerCompat.Enabled)
			{
				return;
			}
			try
			{
				ModSettingsManagerCompat.SetModDescription("Each Shrine of Chance gets a finite shuffled bag with a configurable number of rewards and failures.");
				ModSettingsManagerCompat.SetModIcon(ModIcon.Load());
				ModSettingsManagerCompat.AddCheckboxOption(Enabled);
				ModSettingsManagerCompat.AddSliderOption(RewardCount, ModSettings.Rewards.Constraint as ModSettings.RangeEntryConstraint<int>);
				ModSettingsManagerCompat.AddSliderOption(FailureCount, ModSettings.Failures.Constraint as ModSettings.RangeEntryConstraint<int>);
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Could not register Risk of Options settings: {arg}");
			}
		}
	}
	internal sealed class ShrineChanceBag : MonoBehaviour
	{
		private bool initialized;

		private bool[] bag = Array.Empty<bool>();

		private int nextIndex;

		public bool IsDepleted
		{
			get
			{
				if (initialized)
				{
					return nextIndex >= bag.Length;
				}
				return false;
			}
		}

		public int Size => bag.Length;

		public bool TryDraw(int configuredRewards, int configuredFailures, out bool rewarded)
		{
			if (!initialized)
			{
				Initialize(configuredRewards, configuredFailures);
			}
			if (nextIndex >= bag.Length)
			{
				rewarded = false;
				return false;
			}
			rewarded = bag[nextIndex++];
			return true;
		}

		private void Initialize(int configuredRewards, int configuredFailures)
		{
			initialized = true;
			int rewards = ModSettings.Rewards.Constraint.Clamp(configuredRewards);
			int failures = ModSettings.Failures.Constraint.Clamp(configuredFailures);
			Refill(rewards, failures);
			Shuffle();
			Trim();
		}

		private int Refill(int rewards, int failures)
		{
			int num = rewards + failures;
			if (num == 0)
			{
				bag = new bool[1] { true };
				return 1;
			}
			bag = new bool[num];
			for (int i = 0; i < rewards; i++)
			{
				bag[i] = true;
			}
			return num;
		}

		private void Shuffle()
		{
			int num = 397;
			Random random = new Random((Environment.TickCount * num) ^ ((Object)this).GetInstanceID());
			for (int num2 = bag.Length - 1; num2 > 0; num2--)
			{
				int num3 = random.Next(num2 + 1);
				ref bool reference = ref bag[num2];
				ref bool reference2 = ref bag[num3];
				bool flag = bag[num3];
				bool flag2 = bag[num2];
				reference = flag;
				reference2 = flag2;
			}
		}

		private void Trim()
		{
			int num = bag.Length - 1;
			while (num > 0 && !bag[num])
			{
				num--;
			}
			bool[] array = new bool[num + 1];
			for (int i = 0; i <= num; i++)
			{
				array[i] = bag[i];
			}
			bag = array;
		}

		private void FixedUpdate()
		{
			if (NetworkServer.active && IsDepleted)
			{
				PurchaseInteraction component = ((Component)this).GetComponent<PurchaseInteraction>();
				if ((Object)(object)component != (Object)null && component.available)
				{
					component.SetAvailable(false);
				}
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}