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> CosmeticTokens; internal static bool Initialize() { try { if (AccessTools.Field(typeof(MetaManager), "cosmeticTokens") == null) { throw new MissingFieldException("MetaManager", "cosmeticTokens"); } CosmeticTokens = AccessTools.FieldRefAccess>("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 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 RedeemAllNow { get; } internal ModConfig(ConfigFile file) { RedeemAllNow = file.Bind("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 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)); } } } }