using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UIElements.Collections;
[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("PersistentPurchasesRewritten")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Keeps bought ship objects after failing to meet quota")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("PersistentPurchasesRewritten")]
[assembly: AssemblyTitle("PersistentPurchasesRewritten")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 PersistentPurchasesRewritten
{
public class ConfigManager
{
public static Dictionary<int, ConfigEntry<bool>> unlockablesConfigEntries = new Dictionary<int, ConfigEntry<bool>>();
private static string[] uselessButCoolFurnitures = new string[18]
{
"Cozy lights", "Television", "Cupboard", "File Cabinet", "Toilet", "Shower", "Light switch", "Record player", "Table", "Romantic table",
"Bunkbeds", "JackOLantern", "Welcome mat", "Goldfish", "Plushie pajama man", "Small Rug", "Large Rug", "Fatalities Sign"
};
private static string[] uselessButCoolSuits = new string[5] { "Orange suit", "Green suit", "Hazard suit", "Pajama suit", "Purple Suit" };
public static ConfigFile configFile { get; set; }
public static ConfigEntry<bool> shouldKeepSuits { get; set; }
public static ConfigEntry<bool> shouldKeepFurniture { get; set; }
public static ConfigEntry<bool> shouldKeepPlacement { get; set; }
public static bool IsWhitelisted(UnlockableItem item)
{
return item.unlockableType switch
{
0 => uselessButCoolSuits.Contains(item.unlockableName),
1 => uselessButCoolFurnitures.Contains(item.unlockableName),
_ => false,
};
}
public static void SetupConfig(List<UnlockableItem> unlockableItems)
{
shouldKeepSuits = configFile.Bind<bool>("General", "KeepSuits", true, "Keeps every suits you've unlocked");
shouldKeepFurniture = configFile.Bind<bool>("General", "KeepFurnitures", true, "Keeps every cosmetic furnitures you've unlocked");
shouldKeepPlacement = configFile.Bind<bool>("General", "KeepPlacement", true, "Places back every furnitures inside the ship and puts everything else in storage.");
for (int i = 0; i < unlockableItems.Count; i++)
{
if (!IsWhitelisted(unlockableItems[i]))
{
Plugin.log.LogDebug((object)("The " + unlockableItems[i].unlockableName + " item is not whitelisted internally."));
continue;
}
Plugin.log.LogDebug((object)$"Trying to register the config for {unlockableItems[i].unlockableName} with the type {unlockableItems[i].unlockableType}(id {i})");
switch (unlockableItems[i].unlockableType)
{
case 0:
unlockablesConfigEntries[i] = configFile.Bind<bool>("Items.Suits", unlockableItems[i].unlockableName, true, (ConfigDescription)null);
break;
case 1:
unlockablesConfigEntries[i] = configFile.Bind<bool>("Items.Furniture", unlockableItems[i].unlockableName, true, (ConfigDescription)null);
break;
}
}
}
}
[HarmonyPatch]
public class Patches
{
[HarmonyPostfix]
[HarmonyPatch(typeof(Terminal), "Start")]
[HarmonyPriority(-23)]
public static void generateConfig()
{
ConfigManager.SetupConfig(StartOfRound.Instance.unlockablesList.unlockables);
}
[HarmonyPrefix]
[HarmonyPatch(typeof(StartOfRound), "playersFiredGameOver")]
public static void StoreUnlocked(StartOfRound __instance)
{
if (!GameNetworkManager.Instance.isHostingGame)
{
return;
}
Plugin.log.LogInfo((object)"Taking note of bought unlockables");
SavedUnlockables.unlockablesStore = new Dictionary<int, UnlockableItem>();
List<UnlockableItem> unlockables = __instance.unlockablesList.unlockables;
for (int i = 0; i < unlockables.Count; i++)
{
UnlockableItem val = unlockables[i];
if ((val.unlockableType != 0 || ConfigManager.shouldKeepSuits.Value) && (val.unlockableType != 1 || ConfigManager.shouldKeepFurniture.Value) && val.hasBeenUnlockedByPlayer && ConfigManager.IsWhitelisted(val) && ConfigManager.unlockablesConfigEntries[i].Value)
{
Plugin.log.LogInfo((object)$"{val.unlockableName}(ID: {i}) was unlocked");
SavedUnlockables.unlockablesStore[i] = SavedUnlockables.CopyUnlockable(val);
}
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(StartOfRound), "ResetShip")]
public static void LoadUnlocked(StartOfRound __instance)
{
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_016c: Unknown result type (might be due to invalid IL or missing references)
//IL_0178: Unknown result type (might be due to invalid IL or missing references)
//IL_017e: Unknown result type (might be due to invalid IL or missing references)
Plugin.log.LogInfo((object)"Rebuying unlockables");
foreach (KeyValuePair<int, UnlockableItem> item in SavedUnlockables.unlockablesStore)
{
Plugin.log.LogInfo((object)$"Restoring item {item.Key} {item.Value.unlockableName}");
__instance.BuyShipUnlockableServerRpc(item.Key, TimeOfDay.Instance.quotaVariables.startingCredits);
if (item.Value.unlockableType != 1)
{
continue;
}
if (__instance.SpawnedShipUnlockables.ContainsKey(item.Key))
{
NetworkObject component = DictionaryExtensions.Get<int, GameObject>((IDictionary<int, GameObject>)__instance.SpawnedShipUnlockables, item.Key, (GameObject)null).GetComponent<NetworkObject>();
if ((Object)(object)component != (Object)null)
{
if (!ConfigManager.shouldKeepPlacement.Value || item.Value.inStorage)
{
ShipBuildModeManager.Instance.StoreObjectServerRpc(NetworkObjectReference.op_Implicit(component), 0);
Plugin.log.LogInfo((object)("Put item " + item.Value.unlockableName + " in storage"));
}
else if (item.Value.IsPlaceable)
{
PlaceableShipObject componentInChildren = DictionaryExtensions.Get<int, GameObject>((IDictionary<int, GameObject>)__instance.SpawnedShipUnlockables, item.Key, (GameObject)null).GetComponentInChildren<PlaceableShipObject>();
ShipBuildModeManager.Instance.PlaceShipObject(item.Value.placedPosition, item.Value.placedRotation, componentInChildren, false);
ShipBuildModeManager.Instance.PlaceShipObjectServerRpc(item.Value.placedPosition, item.Value.placedRotation, NetworkObjectReference.op_Implicit(component), 0);
Plugin.log.LogInfo((object)("Placed item " + item.Value.unlockableName + " in the ship"));
}
}
else
{
Plugin.log.LogWarning((object)("Failed to find NetworkObject for " + item.Value.unlockableName));
}
}
else
{
Plugin.log.LogWarning((object)("SpawnedShipUnlockables did not contain " + item.Value.unlockableName));
}
}
SavedUnlockables.unlockablesStore.Clear();
}
}
[BepInPlugin("PersistentPurchasesRewritten", "PersistentPurchasesRewritten", "1.0.0")]
public class Plugin : BaseUnityPlugin
{
public static ManualLogSource log = new ManualLogSource("PersistentPurchasesRewritten");
public static Harmony harmony = new Harmony("PersistentPurchasesRewritten");
private void Awake()
{
ConfigManager.configFile = ((BaseUnityPlugin)this).Config;
Logger.Sources.Add((ILogSource)(object)log);
harmony.PatchAll(typeof(Patches));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin PersistentPurchasesRewritten is loaded!");
}
}
public class SavedUnlockables
{
public static Dictionary<int, UnlockableItem> unlockablesStore { get; set; }
public static UnlockableItem CopyUnlockable(UnlockableItem unlockableItem)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Expected O, but got Unknown
return new UnlockableItem
{
unlockableName = unlockableItem.unlockableName,
placedPosition = unlockableItem.placedPosition,
placedRotation = unlockableItem.placedRotation,
IsPlaceable = unlockableItem.IsPlaceable,
inStorage = unlockableItem.inStorage,
unlockableType = unlockableItem.unlockableType
};
}
}
public enum UnlockableTypes
{
Suits,
Furniture
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "PersistentPurchasesRewritten";
public const string PLUGIN_NAME = "PersistentPurchasesRewritten";
public const string PLUGIN_VERSION = "1.0.0";
}
}