using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Mirror; 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: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 PersistentUpgrades { [BepInPlugin("com.cristokos.persistentupgrades", "PersistentUpgrades", "1.0.0")] public sealed class PluginMain : BaseUnityPlugin { public const string PluginGuid = "com.cristokos.persistentupgrades"; public const string PluginName = "PersistentUpgrades"; public const string PluginVersion = "1.0.0"; private Harmony? _harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; _harmony = new Harmony("com.cristokos.persistentupgrades"); _harmony.PatchAll(); Log.LogInfo((object)"PersistentUpgrades 1.0.0 initialized."); } private void OnDestroy() { Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } } namespace PersistentUpgrades.Patches { [HarmonyPatch(typeof(PlayerProfile), "OnSync")] internal static class UpgradeLateJoinPatch { private static void Postfix(PlayerProfile __instance, bool oldValue, bool newValue) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || oldValue == newValue || !newValue) { return; } UpgradeManager val = Object.FindFirstObjectByType(); if ((Object)(object)val == (Object)null) { return; } ulong steamId = __instance.steamId; int num = 0; foreach (var (num2, val2, num3) in UpgradeState.All()) { if (num2 == steamId && val.GetUpgradeData(steamId, val2) != num3) { val.SetUpgradeData(steamId, val2, num3); num++; } } if (num > 0) { PluginMain.Log.LogInfo((object)$"Backfilled {num} shared upgrade value(s) for a newly synced player."); } } } [HarmonyPatch(typeof(UpgradeManager), "ServerResetAllUpgradesToDefaults")] internal static class UpgradePersistencePatch { private static void Postfix(UpgradeManager __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return; } int num = 0; foreach (var (num2, val, num3) in UpgradeState.All()) { __instance.SetUpgradeData(num2, val, num3); num++; } if (num > 0) { PluginMain.Log.LogInfo((object)$"Restored {num} persistent upgrade value(s) for the new day."); } } } [HarmonyPatch(typeof(UpgradeManager), "ChangeUpgradeData")] internal static class UpgradeSharePatch { private static bool _isProcessing; private static bool Prefix(UpgradeManager __instance, ulong steamId, PlayerUpgradeType type, float amount) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { return true; } if (_isProcessing) { return true; } try { _isProcessing = true; PlayerProfile[] array = Object.FindObjectsByType((FindObjectsSortMode)0); PlayerProfile[] array2 = array; foreach (PlayerProfile val in array2) { __instance.ChangeUpgradeData(val.steamId, type, amount); UpgradeState.Remember(val.steamId, type, __instance.GetUpgradeData(val.steamId, type)); } PluginMain.Log.LogInfo((object)$"Shared upgrade {type} (+{amount}) with {array.Length} player(s)."); return false; } finally { _isProcessing = false; } } } internal static class UpgradeState { private static readonly ConcurrentDictionary> Values = new ConcurrentDictionary>(); public static void Remember(ulong steamId, PlayerUpgradeType type, float value) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) Dictionary orAdd = Values.GetOrAdd(steamId, (ulong _) => new Dictionary()); lock (orAdd) { orAdd[type] = value; } } public static void Clear() { Values.Clear(); } public static IEnumerable<(ulong SteamId, PlayerUpgradeType Type, float Value)> All() { foreach (KeyValuePair> kvp in Values) { Dictionary dictionary; lock (kvp.Value) { dictionary = new Dictionary(kvp.Value); } foreach (KeyValuePair item in dictionary) { yield return (SteamId: kvp.Key, Type: item.Key, Value: item.Value); } } } } [HarmonyPatch(typeof(SaveManager), "ResetCurrentSaveToDefaults")] internal static class UpgradeStateResetPatch { private static void Prefix() { if (NetworkServer.active) { UpgradeState.Clear(); PluginMain.Log.LogInfo((object)"Cleared remembered persistent upgrades for new save."); } } } }