using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Marioalexsan.AutoSaver.HarmonyReversePatches;
using Marioalexsan.AutoSaver.SoftDependencies;
using Microsoft.CodeAnalysis;
using Nessie.ATLYSS.EasySettings;
using Nessie.ATLYSS.EasySettings.UIElements;
using UnityEngine;
using UnityEngine.Events;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Marioalexsan.AutoSaver")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: AssemblyInformationalVersion("1.2.0+eac7c96a4c4d7add33a385f141609bc2e371d826")]
[assembly: AssemblyProduct("AutoSaver")]
[assembly: AssemblyTitle("Marioalexsan.AutoSaver")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.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.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]
[Microsoft.CodeAnalysis.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]
[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 Marioalexsan.AutoSaver
{
[BepInPlugin("Marioalexsan.AutoSaver", "AutoSaver", "1.2.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class AutoSaver : BaseUnityPlugin
{
public const string MoreBankTabsIndentifier = "com.16mb.morebanktabs";
private static AutoSaver? _plugin;
private readonly Harmony _harmony;
private TimeSpan _elapsedAutosaveTime;
private readonly char[] BannedChars;
private readonly string ModDataFolderName;
private bool _checkedForOldAutosaverBackups;
public static AutoSaver Plugin => _plugin ?? throw new InvalidOperationException("AutoSaver hasn't been initialized yet. Either wait until initialization, or check via ChainLoader instead.");
public ManualLogSource Logger { get; private set; }
public ConfigEntry<bool> EnableAutosaving { get; private set; }
public ConfigEntry<bool> SaveOnMapChange { get; private set; }
public ConfigEntry<bool> EnableExperimentalFeatures { get; private set; }
public ConfigEntry<bool> AppendSlotToSaveName { get; private set; }
public ConfigEntry<KeyCode> SaveMultiplayerKeyCode { get; private set; }
public ConfigEntry<int> BackupIntervalInMinutesConfig { get; private set; }
public ConfigEntry<int> SaveCountToKeepConfig { get; private set; }
public int BackupIntervalInMinutes { get; private set; }
public int SaveCountToKeep { get; private set; }
public bool IsInGame { get; private set; }
public TimeSpan AutosaveInterval => TimeSpan.FromMinutes(BackupIntervalInMinutes);
public bool DetectedMoreBankTabsMod { get; private set; } = false;
private string ObsoleteModDataFolderPath => Path.Combine(ProfileDataManager._current._dataPath, ModDataFolderName);
private string ModDataFolderPath => Path.Combine(Path.GetDirectoryName(Paths.ExecutablePath), ModDataFolderName);
private string CharacterFolderPath => Path.Combine(ModDataFolderPath, "Characters");
private string ItemBankFolderPath => Path.Combine(ModDataFolderPath, "ItemBank");
private string MultiSavesFolderPath => Path.Combine(ModDataFolderPath, "Multi");
public string SanitizedCurrentTime
{
get
{
string text = DateTime.UtcNow.ToString("yyyy:MM:dd-HH:mm:ss", CultureInfo.InvariantCulture);
for (int i = 0; i < BannedChars.Length; i++)
{
text = text.Replace($"{BannedChars[i]}", "_");
}
return text;
}
}
public AutoSaver()
{
//IL_00be: Unknown result type (might be due to invalid IL or missing references)
//IL_00c8: Expected O, but got Unknown
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Expected O, but got Unknown
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_0191: Expected O, but got Unknown
char[] invalidPathChars = Path.GetInvalidPathChars();
char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
int num = 0;
char[] array = new char[invalidPathChars.Length + invalidFileNameChars.Length];
ReadOnlySpan<char> readOnlySpan = new ReadOnlySpan<char>(invalidPathChars);
readOnlySpan.CopyTo(new Span<char>(array).Slice(num, readOnlySpan.Length));
num += readOnlySpan.Length;
ReadOnlySpan<char> readOnlySpan2 = new ReadOnlySpan<char>(invalidFileNameChars);
readOnlySpan2.CopyTo(new Span<char>(array).Slice(num, readOnlySpan2.Length));
num += readOnlySpan2.Length;
BannedChars = array;
ModDataFolderName = "Marioalexsan_AutoSaver";
_checkedForOldAutosaverBackups = false;
((BaseUnityPlugin)this)..ctor();
_plugin = this;
Logger = ((BaseUnityPlugin)this).Logger;
_harmony = new Harmony("Marioalexsan.AutoSaver");
EnableAutosaving = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableAutosaving", true, "True to enable autosaving every few minutes, false to disable it.");
SaveOnMapChange = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SaveOnMapChange", false, "Set to true to trigger autosaving whenever a new level is loaded.");
AppendSlotToSaveName = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AppendSlotToSaveName", true, "Set to true to append slot index to the saved character names, false to use the character name only. Recommended if you use characters with duplicate names.");
BackupIntervalInMinutesConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "BackupInterval", 4, new ConfigDescription("Interval between save backups, in minutes.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>()));
SaveCountToKeepConfig = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SavesToKeep", 15, new ConfigDescription("Maximum number of saves to keep.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 50), Array.Empty<object>()));
BackupIntervalInMinutes = BackupIntervalInMinutesConfig.Value;
SaveCountToKeep = SaveCountToKeepConfig.Value;
EnableExperimentalFeatures = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "EnableExperimentalFeatures", false, "Set to true to enable experimental features.");
SaveMultiplayerKeyCode = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Experimental", "SaveMultiplayerKeyCode", (KeyCode)270, "Key to trigger saving other people's saves in multiplayer under the \"Multi\" folder." + Environment.NewLine + "Note that saves saved in this way are lackluster.");
}
private void Awake()
{
_harmony.PatchAll();
InitializeConfiguration();
Logging.LogInfo("AutoSaver initialized!");
}
private void CheckForOldAutosaverBackups()
{
if (!Directory.Exists(ObsoleteModDataFolderPath))
{
return;
}
if (Directory.Exists(ModDataFolderPath))
{
Logging.LogWarning("Found old Autosaver folder in " + ObsoleteModDataFolderPath + ", but new save location " + ModDataFolderPath + " already exists.");
Logging.LogWarning("Please backup and move " + ObsoleteModDataFolderPath + " out of the profileCollections folder manually!");
return;
}
Logging.LogInfo("Found old Autosaver folder in " + ObsoleteModDataFolderPath + ", will try to move it to the new save location " + ModDataFolderPath + ".");
try
{
Directory.Move(ObsoleteModDataFolderPath, ModDataFolderPath);
Logging.LogInfo("Backup data moved successfully to the new location!");
}
catch (Exception ex)
{
Logging.LogError("Failed to move old backup folder! Please send the exception message to the mod developer:");
Logging.LogError(ex.ToString());
Logging.LogError("Please check " + ObsoleteModDataFolderPath + " and backup and move it out of the profileCollections folder manually!");
}
}
private void InitializeConfiguration()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Expected O, but got Unknown
if (!EasySettings.IsAvailable)
{
return;
}
EasySettings.OnApplySettings.AddListener((UnityAction)delegate
{
try
{
((BaseUnityPlugin)this).Config.Save();
BackupIntervalInMinutes = BackupIntervalInMinutesConfig.Value;
SaveCountToKeep = SaveCountToKeepConfig.Value;
}
catch (Exception ex)
{
Logging.LogError("AutoSaevr crashed in OnApplySettings! Please report this error to the mod developer:");
Logging.LogError(ex.ToString());
}
});
EasySettings.OnInitialized.AddListener((UnityAction)delegate
{
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
EasySettings.AddHeader("AutoSaver");
EasySettings.AddToggle("Enable periodic autosaves", EnableAutosaving);
EasySettings.AddToggle("Enable autosaving whenever map changes", SaveOnMapChange);
EasySettings.AddToggle("Append save slot to save names (recommended)", AppendSlotToSaveName);
EasySettings.AddAdvancedSlider("Backup interval (minutes)", BackupIntervalInMinutesConfig);
EasySettings.AddAdvancedSlider("Number of saves to keep", SaveCountToKeepConfig);
EasySettings.AddButton("Open save backups folder", (UnityAction)delegate
{
Application.OpenURL(new Uri(ModDataFolderPath ?? "").AbsoluteUri);
});
});
}
internal void GameEntered()
{
bool flag = false;
if (!IsInGame)
{
IsInGame = true;
flag = true;
Logging.LogInfo("Game entered. Activating character autosaves.");
}
else if (SaveOnMapChange.Value)
{
flag = true;
Logging.LogInfo("Map changed. Autosaving.");
}
if (flag)
{
ProfileDataManager._current.Load_ItemStorageData();
RunAutosaves();
}
}
internal void GameExited()
{
Logging.LogInfo("Game exited. Stopping character autosaves.");
RunAutosaves();
IsInGame = false;
}
private void Update()
{
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
if (!_checkedForOldAutosaverBackups && ProfileDataManager._current?._dataPath != null)
{
_checkedForOldAutosaverBackups = true;
CheckForOldAutosaverBackups();
}
if (!DetectedMoreBankTabsMod && Chainloader.PluginInfos.ContainsKey("com.16mb.morebanktabs"))
{
DetectedMoreBankTabsMod = true;
Logging.LogInfo("Detected MoreBankTabs mod (com.16mb.morebanktabs).");
Logging.LogInfo("Will try to backup the extra bank tabs.");
}
if (IsInGame)
{
_elapsedAutosaveTime += TimeSpan.FromSeconds(Time.deltaTime);
if (EnableAutosaving.Value && _elapsedAutosaveTime >= AutosaveInterval)
{
Logging.LogInfo($"Periodic autosave triggered ({AutosaveInterval.TotalMinutes} minutes have passed).");
RunAutosaves();
}
if (!CharacterAutoSaver.SaveDone)
{
AutosaveCurrentCharacter();
}
if (!ItemBankAutoSaver.SaveDone)
{
AutosaveCurrentItemBank();
}
}
if (!EnableExperimentalFeatures.Value || !Input.GetKeyDown(SaveMultiplayerKeyCode.Value))
{
return;
}
Logging.LogInfo("[Experimental] Saving every online player's saves.");
Player[] array = Object.FindObjectsOfType<Player>();
foreach (Player val in array)
{
Logging.LogInfo("Saving player data for " + val._nickname);
Directory.CreateDirectory(MultiSavesFolderPath);
CharacterAutoSaver.TrySaveSpecificProfileToLocation(val, Path.Combine(MultiSavesFolderPath, SanitizePlayerName(val)));
if (!CharacterAutoSaver.SaveDone)
{
Logging.LogWarning($"Failed to do save for {val._nickname}. Current game status is {val._currentGameCondition}.");
}
}
}
private void RunAutosaves()
{
_elapsedAutosaveTime = TimeSpan.Zero;
AutosaveCurrentCharacter();
AutosaveCurrentItemBank();
}
public string SanitizePlayerName(Player player)
{
string text = player._nickname;
for (int i = 0; i < BannedChars.Length; i++)
{
int num = char.ConvertToUtf32($"{BannedChars[i]}", 0);
text = text.Replace($"{BannedChars[i]}", $"_{num}");
}
return text;
}
public string GetBackupNameForCurrentPlayer()
{
if (AppendSlotToSaveName.Value)
{
return $"{SanitizePlayerName(Player._mainPlayer)}_slot{ProfileDataManager._current._selectedFileIndex}";
}
return SanitizePlayerName(Player._mainPlayer) ?? "";
}
private void RunItemBankGarbageCollector()
{
if (!Directory.Exists(ItemBankFolderPath))
{
Logging.LogWarning("Couldn't find backup path " + ItemBankFolderPath + " to run garbage collection for.");
return;
}
List<string> list = new List<string>();
foreach (string item in Directory.EnumerateDirectories(ItemBankFolderPath))
{
list.Add(Path.GetFileName(item));
}
list.Remove("_latest");
list.Sort();
while (list.Count > SaveCountToKeep)
{
string path = list[0];
list.RemoveAt(0);
string text = Path.Combine(ItemBankFolderPath, path);
if (!text.Contains(ModDataFolderName))
{
throw new InvalidOperationException("Got an invalid folder to delete " + text + ", please notify the mod developer!");
}
Directory.Delete(Path.Combine(ItemBankFolderPath, path), recursive: true);
}
}
private void RunCharacterGarbageCollector()
{
string text = Path.Combine(CharacterFolderPath, GetBackupNameForCurrentPlayer());
if (!Directory.Exists(text))
{
Logging.LogWarning("Couldn't find backup path " + text + " to run garbage collection for.");
return;
}
List<string> list = new List<string>();
foreach (string item in Directory.EnumerateFiles(text))
{
list.Add(Path.GetFileName(item));
}
list.Remove("_latest");
list.Sort();
while (list.Count > SaveCountToKeep)
{
string path = list[0];
list.RemoveAt(0);
string text2 = Path.Combine(CharacterFolderPath, GetBackupNameForCurrentPlayer(), path);
if (!text2.Contains(ModDataFolderName))
{
throw new InvalidOperationException("Got an invalid file to delete " + text2 + ", please notify the mod developer!");
}
File.Delete(text2);
}
}
private void AutosaveCurrentItemBank()
{
try
{
Directory.CreateDirectory(ModDataFolderPath);
string text = Path.Combine(ItemBankFolderPath, SanitizedCurrentTime);
Directory.CreateDirectory(text);
ItemBankAutoSaver.TrySaveCurrentProfileToLocation(text);
if (ItemBankAutoSaver.SaveDone)
{
if (DetectedMoreBankTabsMod)
{
ItemBankAutoSaver.SaveModBankTabsToLocation(text);
}
string text2 = Path.Combine(ItemBankFolderPath, "_latest");
Directory.CreateDirectory(text2);
foreach (string item in Directory.EnumerateFiles(text))
{
File.Copy(item, Path.Combine(text2, Path.GetFileName(item)), overwrite: true);
}
}
RunItemBankGarbageCollector();
}
catch (Exception arg)
{
Logging.LogError("Failed to autosave!");
Logging.LogError($"Exception message: {arg}");
}
}
private void AutosaveCurrentCharacter()
{
try
{
if (!Object.op_Implicit((Object)(object)Player._mainPlayer))
{
Logging.LogError("Couldn't autosave! No main player found.");
return;
}
Directory.CreateDirectory(ModDataFolderPath);
string text = Path.Combine(CharacterFolderPath, GetBackupNameForCurrentPlayer());
Directory.CreateDirectory(text);
string text2 = Path.Combine(text, SanitizedCurrentTime);
CharacterAutoSaver.TrySaveCurrentProfileToLocation(text2);
if (CharacterAutoSaver.SaveDone)
{
File.Copy(text2, Path.Combine(text, "_latest"), overwrite: true);
}
RunCharacterGarbageCollector();
}
catch (Exception arg)
{
Logging.LogError("Couldn't autosave!");
Logging.LogError($"Exception message: {arg}");
}
}
}
internal static class Logging
{
private static ManualLogSource InternalLogger => AutoSaver.Plugin.Logger;
public static void LogFatal(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)1, toggle);
}
public static void LogError(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)2, toggle);
}
public static void LogWarning(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)4, toggle);
}
public static void LogMessage(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)8, toggle);
}
public static void LogInfo(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)16, toggle);
}
public static void LogDebug(object data, ConfigEntry<bool>? toggle = null)
{
Log(data, (LogLevel)32, toggle);
}
private static void Log(object data, LogLevel level = 16, ConfigEntry<bool>? toggle = null)
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
if (toggle == null || toggle.Value)
{
ManualLogSource internalLogger = InternalLogger;
if (internalLogger != null)
{
internalLogger.Log(level, data);
}
}
}
}
internal static class ModInfo
{
public const string PLUGIN_GUID = "Marioalexsan.AutoSaver";
public const string PLUGIN_NAME = "AutoSaver";
public const string PLUGIN_VERSION = "1.2.0";
}
}
namespace Marioalexsan.AutoSaver.SoftDependencies
{
public static class EasySettings
{
private const MethodImplOptions SoftDepend = MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization;
public const string ModID = "EasySettings";
public static readonly Version ExpectedVersion = new Version("1.1.6");
private static BaseUnityPlugin? _plugin;
private static bool _initialized;
public static bool IsAvailable
{
get
{
if (!_initialized)
{
_plugin = (Chainloader.PluginInfos.TryGetValue("EasySettings", out var value) ? value.Instance : null);
_initialized = true;
if ((Object)(object)_plugin == (Object)null)
{
Logging.LogWarning("Soft dependency EasySettings was not found.");
}
else if (_plugin.Info.Metadata.Version != ExpectedVersion)
{
Logging.LogWarning(string.Format("Soft dependency {0} has a different version than expected (have: {1}, expect: {2}).", "EasySettings", _plugin.Info.Metadata.Version, ExpectedVersion));
}
}
return (Object)(object)_plugin != (Object)null;
}
}
public static UnityEvent OnInitialized
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
return Settings.OnInitialized;
}
}
public static UnityEvent OnCancelSettings
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
return Settings.OnCancelSettings;
}
}
public static UnityEvent OnApplySettings
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
return Settings.OnApplySettings;
}
}
public static UnityEvent OnCloseSettings
{
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
get
{
return Settings.OnCloseSettings;
}
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddSpace()
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddSpace()).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddHeader(string label)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddHeader(label)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddButton(string buttonLabel, UnityAction onClick)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddButton(buttonLabel, onClick)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddToggle(string label, ConfigEntry<bool> config)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddToggle(label, config)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddSlider(string label, ConfigEntry<float> config, bool wholeNumbers = false)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddSlider(label, config, wholeNumbers)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddAdvancedSlider(string label, ConfigEntry<float> config, bool wholeNumbers = false)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddAdvancedSlider(label, config, wholeNumbers)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddAdvancedSlider(string label, ConfigEntry<int> config)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddAdvancedSlider(label, config)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddDropdown<T>(string label, ConfigEntry<T> config) where T : Enum
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddDropdown<T>(label, config)).Root).gameObject;
}
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static GameObject AddKeyButton(string label, ConfigEntry<KeyCode> config)
{
return ((Component)((BaseAtlyssElement)Settings.ModTab.AddKeyButton(label, config)).Root).gameObject;
}
}
}
namespace Marioalexsan.AutoSaver.HarmonyReversePatches
{
[HarmonyPatch(typeof(ProfileDataManager), "Save_ProfileData")]
internal static class CharacterAutoSaver
{
private static string? SaveLocationOverride;
private static string? TempContents;
private static Player? TargetPlayer;
internal static bool SaveDone { get; private set; } = true;
public static void TrySaveCurrentProfileToLocation(string location)
{
if (SaveDone)
{
AutoSaver.Plugin.Logger.LogInfo((object)"Triggering character save process...");
}
SaveLocationOverride = location;
SaveDone = false;
TargetPlayer = Player._mainPlayer;
SaveProfileData(ProfileDataManager._current);
}
public static void TrySaveSpecificProfileToLocation(Player player, string location)
{
if (SaveDone)
{
AutoSaver.Plugin.Logger.LogInfo((object)"Triggering character save process...");
}
SaveLocationOverride = location;
SaveDone = false;
TargetPlayer = player;
SaveProfileData(ProfileDataManager._current);
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPriority(0)]
private static void SaveProfileData(ProfileDataManager __instance)
{
Transpiler(null);
throw new NotImplementedException("Stub method");
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> data)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Expected O, but got Unknown
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
//IL_01f5: Expected O, but got Unknown
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_0250: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(data, (ILGenerator)null);
int num = 0;
while (true)
{
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => File.WriteAllText(null, null))), (string)null)
});
if (val.IsInvalid)
{
break;
}
num++;
val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[5]
{
new CodeInstruction(OpCodes.Stsfld, (object)AccessTools.Field(typeof(CharacterAutoSaver), "TempContents")),
new CodeInstruction(OpCodes.Pop, (object)null),
new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(CharacterAutoSaver), "SaveLocationOverride")),
new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => MarkSaveDone(null)))),
new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(CharacterAutoSaver), "TempContents"))
});
val.Advance(1);
}
if (num != 2)
{
AutoSaver.Plugin.Logger.LogWarning((object)$"WARNING: CharacterAutoSaver expected {2} patch locations, got {num}.");
AutoSaver.Plugin.Logger.LogWarning((object)"Either the vanilla code changed, or mods added extra stuff. This may or may not cause issues.");
}
val.Start();
num = 0;
while (true)
{
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Ldsfld, (object)AccessTools.Field(typeof(Player), "_mainPlayer"), (string)null)
});
if (val.IsInvalid)
{
break;
}
List<Label> list = val.Instruction.labels.ToList();
val.RemoveInstruction();
val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(CharacterAutoSaver), "TargetPlayer")), (IEnumerable<Label>)list) });
num++;
}
AutoSaver.Plugin.Logger.LogInfo((object)$"Patched {num} instances of Player._mainPlayer.");
return val.InstructionEnumeration();
}
}
private static string MarkSaveDone(string location)
{
SaveDone = true;
return location;
}
}
[HarmonyPatch(typeof(ProfileDataManager), "Save_ItemStorageData")]
internal static class ItemBankAutoSaver
{
private static string? SaveLocationOverride;
private static string? TempContents;
private static int BanksDone = 0;
private static int BanksMax = 0;
internal static bool SaveDone { get; private set; } = true;
public static void TrySaveCurrentProfileToLocation(string location)
{
if (SaveDone)
{
AutoSaver.Plugin.Logger.LogInfo((object)"Triggering item bank save process...");
}
SaveLocationOverride = location;
BanksDone = 0;
SaveDone = false;
SaveProfileData(ProfileDataManager._current);
}
[HarmonyReversePatch(/*Could not decode attribute arguments.*/)]
[HarmonyPriority(0)]
private static void SaveProfileData(ProfileDataManager __instance)
{
Transpiler(null);
throw new NotImplementedException("Stub method");
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> data)
{
//IL_0003: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: Expected O, but got Unknown
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Expected O, but got Unknown
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Expected O, but got Unknown
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Expected O, but got Unknown
//IL_0130: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Expected O, but got Unknown
//IL_0151: Unknown result type (might be due to invalid IL or missing references)
//IL_0157: Expected O, but got Unknown
CodeMatcher val = new CodeMatcher(data, (ILGenerator)null);
int num = 0;
while (true)
{
val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
{
new CodeMatch((OpCode?)OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => File.WriteAllText(null, null))), (string)null)
});
if (val.IsInvalid)
{
break;
}
num++;
val.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[5]
{
new CodeInstruction(OpCodes.Stsfld, (object)AccessTools.Field(typeof(ItemBankAutoSaver), "TempContents")),
new CodeInstruction(OpCodes.Pop, (object)null),
new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(ItemBankAutoSaver), "SaveLocationOverride")),
new CodeInstruction(OpCodes.Call, (object)SymbolExtensions.GetMethodInfo((Expression<Action>)(() => MarkSaveDone(null)))),
new CodeInstruction(OpCodes.Ldsfld, (object)AccessTools.Field(typeof(ItemBankAutoSaver), "TempContents"))
});
val.Advance(1);
}
if (num != 3)
{
AutoSaver.Plugin.Logger.LogWarning((object)$"WARNING: ItemBankAutoSaver expected {3} patch locations, got {num}.");
AutoSaver.Plugin.Logger.LogWarning((object)"Either the vanilla code changed, or mods added extra stuff. This may or may not cause issues.");
}
BanksMax = 3;
return val.InstructionEnumeration();
}
}
private static string MarkSaveDone(string location)
{
BanksDone++;
if (BanksDone >= BanksMax)
{
SaveDone = true;
}
return Path.Combine(location, $"itembank_{BanksDone - 1}");
}
public static void SaveModBankTabsToLocation(string location)
{
try
{
AutoSaver.Plugin.Logger.LogInfo((object)"Attempting to save MoreBankTabs data...");
BaseUnityPlugin instance = Chainloader.PluginInfos["com.16mb.morebanktabs"].Instance;
object value = AccessTools.Field(((object)instance).GetType(), "_itemStorageProfile_03").GetValue(instance);
object value2 = AccessTools.Field(((object)instance).GetType(), "_itemStorageProfile_04").GetValue(instance);
object value3 = AccessTools.Field(((object)instance).GetType(), "_itemStorageProfile_05").GetValue(instance);
object value4 = AccessTools.Field(((object)instance).GetType(), "_itemDatas_03").GetValue(instance);
object value5 = AccessTools.Field(((object)instance).GetType(), "_itemDatas_04").GetValue(instance);
object value6 = AccessTools.Field(((object)instance).GetType(), "_itemDatas_05").GetValue(instance);
object value7 = AccessTools.Method(value4.GetType(), "ToArray", (Type[])null, (Type[])null).Invoke(value4, Array.Empty<object>());
object value8 = AccessTools.Method(value5.GetType(), "ToArray", (Type[])null, (Type[])null).Invoke(value5, Array.Empty<object>());
object value9 = AccessTools.Method(value6.GetType(), "ToArray", (Type[])null, (Type[])null).Invoke(value6, Array.Empty<object>());
AccessTools.Field(value.GetType(), "_heldItemStorage").SetValue(value, value7);
AccessTools.Field(value2.GetType(), "_heldItemStorage").SetValue(value2, value8);
AccessTools.Field(value3.GetType(), "_heldItemStorage").SetValue(value3, value9);
string contents = JsonUtility.ToJson(value, true);
string contents2 = JsonUtility.ToJson(value2, true);
string contents3 = JsonUtility.ToJson(value3, true);
File.WriteAllText(Path.Combine(location, "MoreBankTabs_itemBank_03"), contents);
File.WriteAllText(Path.Combine(location, "MoreBankTabs_itemBank_04"), contents2);
File.WriteAllText(Path.Combine(location, "MoreBankTabs_itemBank_05"), contents3);
AutoSaver.Plugin.Logger.LogInfo((object)"MoreBankTabs slots saved.");
}
catch (Exception arg)
{
AutoSaver.Plugin.Logger.LogError((object)"Failed to save MoreBankTabs info.");
AutoSaver.Plugin.Logger.LogError((object)$"Exception info: {arg}");
}
}
}
}
namespace Marioalexsan.AutoSaver.HarmonyPatches
{
[HarmonyPatch]
internal static class InGameUI_Init_SaveQuitGame
{
private static MethodInfo TargetMethod()
{
string version = Application.version;
if (1 == 0)
{
}
MethodInfo result = ((version == "Beta 1.6.2b") ? AccessTools.Method("InGameUI:Init_SaveQuitGame", (Type[])null, (Type[])null) : ((!(version == "Beta 2.0.5d")) ? AccessTools.Method("OptionsMenuCell:Init_SaveQuitGame", (Type[])null, (Type[])null) : AccessTools.Method("OptionsMenuCell:Init_SaveQuitGame", (Type[])null, (Type[])null)));
if (1 == 0)
{
}
return result;
}
private static void Prefix()
{
AutoSaver.Plugin.GameExited();
}
}
[HarmonyPatch(typeof(Player), "OnPlayerMapInstanceChange")]
internal static class Player_OnPlayerMapInstanceChange
{
private static void Postfix(Player __instance, MapInstance _new)
{
if ((Object)(object)__instance == (Object)(object)Player._mainPlayer)
{
AutoSaver.Plugin.GameEntered();
}
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}