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 ShrineBag v1.0.2
ShrineBag.dll
Decompiled 12 hours agousing 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) { } } }