Decompiled source of RedeemAllTokens v1.0.1

BepInEx/plugins/RedeemAllTokens/RedeemAllTokens.dll

Decompiled 15 hours ago
using System;
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(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RedeemAllTokens")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Redeem All Tokens")]
[assembly: AssemblyTitle("RedeemAllTokens")]
[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 RedeemAllTokens
{
	internal static class GameRefs
	{
		internal static FieldRef<MetaManager, List<int>> CosmeticTokens;

		internal static bool Initialize()
		{
			try
			{
				if (AccessTools.Field(typeof(MetaManager), "cosmeticTokens") == null)
				{
					throw new MissingFieldException("MetaManager", "cosmeticTokens");
				}
				CosmeticTokens = AccessTools.FieldRefAccess<MetaManager, List<int>>("cosmeticTokens");
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Failed to bind to the game's token list: " + ex.Message));
				return false;
			}
		}

		internal static int TokenCount()
		{
			MetaManager instance = MetaManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return 0;
			}
			return CosmeticTokens.Invoke(instance)?.Count ?? 0;
		}

		internal static bool HudReady()
		{
			return (Object)(object)CosmeticTokenUI.instance != (Object)null;
		}
	}
	internal static class InstantRedeem
	{
		internal static void RedeemAll()
		{
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected I4, but got Unknown
			MetaManager instance = MetaManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Plugin.Log.LogInfo((object)"Redeem all ignored: no save loaded.");
				return;
			}
			List<int> list = GameRefs.CosmeticTokens.Invoke(instance);
			if (list == null || list.Count == 0)
			{
				Report("No tokens to redeem.", warning: true);
				return;
			}
			if (!GameRefs.HudReady())
			{
				Plugin.Log.LogInfo((object)"Redeem all ignored: not in a game yet.");
				Report("Join a game before redeeming tokens.", warning: true);
				return;
			}
			bool flag = SemiFunc.IsMasterClientOrSingleplayer();
			int count = list.Count;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = count + 1;
			while (list.Count > num3 && num4-- > 0)
			{
				int index = list.Count - 1;
				Rarity val = (Rarity)list[index];
				CosmeticAsset val2 = instance.CosmeticLockedGet(val);
				if ((Object)(object)val2 != (Object)null)
				{
					if (instance.CosmeticUnlock(val2))
					{
						num++;
					}
					instance.CosmeticTokenRemove();
				}
				else if (!flag)
				{
					list.RemoveAt(index);
					list.Insert(0, (int)val);
					num3++;
				}
				else
				{
					num2 += CurrencyReward(val);
					instance.CosmeticTokenRemove();
				}
			}
			if (num2 > 0)
			{
				AwardCurrency(num2);
			}
			int num5 = count - num3;
			string text = "Redeemed " + num5 + " token" + ((num5 == 1) ? "" : "s") + ": " + num + " new cosmetic" + ((num == 1) ? "" : "s");
			if (num2 > 0)
			{
				text = text + ", +" + Dollars(num2);
			}
			text += ".";
			if (num3 > 0)
			{
				text = text + " Kept " + num3 + " (only the host can award the money those would pay out).";
			}
			Report(text, warning: false);
		}

		private static void AwardCurrency(int amount)
		{
			try
			{
				SemiFunc.StatSetRunCurrency(SemiFunc.StatGetRunCurrency() + amount);
				if ((Object)(object)CurrencyUI.instance != (Object)null)
				{
					CurrencyUI.instance.FetchCurrency();
				}
				if ((Object)(object)ShopIncreaseUI.instance != (Object)null)
				{
					ShopIncreaseUI.instance.ShowIncrease(amount, 3f);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not award currency: " + ex));
			}
		}

		private static int CurrencyReward(Rarity rarity)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected I4, but got Unknown
			return (int)rarity switch
			{
				0 => 2, 
				1 => 4, 
				2 => 8, 
				3 => 15, 
				_ => 0, 
			};
		}

		private static string Dollars(int value)
		{
			try
			{
				return SemiFunc.DollarGetString(value);
			}
			catch
			{
				return "$" + value;
			}
		}

		private static void Report(string message, bool warning)
		{
			Plugin.Log.LogInfo((object)message);
			Plugin.Notify(message, warning);
		}
	}
	internal sealed class ModConfig
	{
		internal ConfigEntry<bool> RedeemAllNow { get; }

		internal ModConfig(ConfigFile file)
		{
			RedeemAllNow = file.Bind<bool>("Actions", "Redeem All Tokens", false, "Click ON to spend every token you are carrying, right now. Switches itself back to OFF - it is a button, not a setting.");
		}
	}
	internal static class ModInfo
	{
		internal const string Guid = "com.averul.redeemalltokens";

		internal const string Name = "RedeemAllTokens";

		internal const string Version = "1.0.1";
	}
	[BepInPlugin("com.averul.redeemalltokens", "RedeemAllTokens", "1.0.1")]
	[BepInProcess("REPO.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log { get; private set; }

		internal static ModConfig Cfg { get; private set; }

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = new ModConfig(((BaseUnityPlugin)this).Config);
			if (!GameRefs.Initialize())
			{
				Log.LogError((object)"RedeemAllTokens is disabled: the game's cosmetic token data no longer matches what this mod was built against (R.E.P.O. v0.4.4). It probably needs an update.");
				return;
			}
			WireActionEntry(Cfg.RedeemAllNow, InstantRedeem.RedeemAll);
			Log.LogInfo((object)"RedeemAllTokens 1.0.1 loaded. Actions are on this mod's page under Escape > Mods.");
		}

		private static void WireActionEntry(ConfigEntry<bool> entry, Action action)
		{
			if (entry.Value)
			{
				entry.Value = false;
			}
			bool running = false;
			entry.SettingChanged += delegate
			{
				if (running || !entry.Value)
				{
					return;
				}
				running = true;
				try
				{
					entry.Value = false;
					action();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Action failed: " + ex));
				}
				finally
				{
					running = false;
				}
			};
		}

		internal static void Notify(string message, bool warning)
		{
			//IL_0019: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			try
			{
				Color val = (Color)(warning ? new Color(1f, 0.6f, 0.2f) : Color.white);
				SemiFunc.UIFocusText(message, val, val, 5f);
			}
			catch
			{
				Log.LogDebug((object)("No mission UI available for: " + message));
			}
		}
	}
}