using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Silksong.DataManager.Data;
using Silksong.DataManager.Json;
using TeamCherry.Localization;
using UnityEngine;
using UnityEngine.UI;
[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("Silksong.DataManager")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("DataManager is a Silksong mod that saves and loads data - global as well as save slot-specific - on behalf of other mods.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+25249b2f92915785fa1818b1f81859f5a4722502")]
[assembly: AssemblyProduct("Silksong.DataManager")]
[assembly: AssemblyTitle("DataManager")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/silksong-modding/Silksong.DataManager")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 System.Runtime.Versioning
{
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresPreviewFeaturesAttribute : Attribute
{
public string? Message { get; }
public string? Url { get; set; }
public RequiresPreviewFeaturesAttribute()
{
}
public RequiresPreviewFeaturesAttribute(string? message)
{
Message = message;
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CallerArgumentExpressionAttribute : Attribute
{
public string ParameterName { get; }
public CallerArgumentExpressionAttribute(string parameterName)
{
ParameterName = parameterName;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CollectionBuilderAttribute : Attribute
{
public Type BuilderType { get; }
public string MethodName { get; }
public CollectionBuilderAttribute(Type builderType, string methodName)
{
BuilderType = builderType;
MethodName = methodName;
}
}
[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class CompilerFeatureRequiredAttribute : Attribute
{
public const string RefStructs = "RefStructs";
public const string RequiredMembers = "RequiredMembers";
public string FeatureName { get; }
public bool IsOptional { get; set; }
public CompilerFeatureRequiredAttribute(string featureName)
{
FeatureName = featureName;
}
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
{
public string[] Arguments { get; }
public InterpolatedStringHandlerArgumentAttribute(string argument)
{
Arguments = new string[1] { argument };
}
public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
{
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class InterpolatedStringHandlerAttribute : Attribute
{
}
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal static class IsExternalInit
{
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ModuleInitializerAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class OverloadResolutionPriorityAttribute : Attribute
{
public int Priority { get; }
public OverloadResolutionPriorityAttribute(int priority)
{
Priority = priority;
}
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = true, AllowMultiple = false)]
[ExcludeFromCodeCoverage]
internal sealed class ParamCollectionAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class RequiredMemberAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[ExcludeFromCodeCoverage]
internal sealed class RequiresLocationAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SkipLocalsInitAttribute : Attribute
{
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ConstantExpectedAttribute : Attribute
{
public object? Min { get; set; }
public object? Max { get; set; }
}
[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class ExperimentalAttribute : Attribute
{
public string DiagnosticId { get; }
public string? UrlFormat { get; set; }
public ExperimentalAttribute(string diagnosticId)
{
DiagnosticId = diagnosticId;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullAttribute : Attribute
{
public string[] Members { get; }
public MemberNotNullAttribute(string member)
{
Members = new string[1] { member };
}
public MemberNotNullAttribute(params string[] members)
{
Members = members;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
[ExcludeFromCodeCoverage]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public string[] Members { get; }
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new string[1] { member };
}
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class SetsRequiredMembersAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class StringSyntaxAttribute : Attribute
{
public const string CompositeFormat = "CompositeFormat";
public const string DateOnlyFormat = "DateOnlyFormat";
public const string DateTimeFormat = "DateTimeFormat";
public const string EnumFormat = "EnumFormat";
public const string GuidFormat = "GuidFormat";
public const string Json = "Json";
public const string NumericFormat = "NumericFormat";
public const string Regex = "Regex";
public const string TimeOnlyFormat = "TimeOnlyFormat";
public const string TimeSpanFormat = "TimeSpanFormat";
public const string Uri = "Uri";
public const string Xml = "Xml";
public string Syntax { get; }
public object?[] Arguments { get; }
public StringSyntaxAttribute(string syntax)
{
Syntax = syntax;
Arguments = new object[0];
}
public StringSyntaxAttribute(string syntax, params object?[] arguments)
{
Syntax = syntax;
Arguments = arguments;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
[ExcludeFromCodeCoverage]
internal sealed class UnscopedRefAttribute : Attribute
{
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace Silksong.DataManager
{
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("org.silksong-modding.datamanager", "DataManager", "1.1.0")]
public class DataManagerPlugin : BaseUnityPlugin, IOnceSaveDataMod<DMOnceSaveData>, IOnceSaveDataMod
{
internal Dictionary<string, ManagedMod> ManagedMods = new Dictionary<string, ManagedMod>();
public const string Id = "org.silksong-modding.datamanager";
internal static DataManagerPlugin Instance { get; private set; }
internal static ManualLogSource InstanceLogger => ((BaseUnityPlugin)Instance).Logger;
internal ManagedMod ManagedSelf => ManagedMods[((BaseUnityPlugin)this).Info.Metadata.GUID];
internal DMOnceSaveData? OnceSaveData { get; set; }
DMOnceSaveData? IOnceSaveDataMod<DMOnceSaveData>.OnceSaveData
{
get
{
return OnceSaveData;
}
set
{
OnceSaveData = value;
}
}
public static string Name => "DataManager";
public static string Version => "1.1.0";
private void Awake()
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
new Harmony("org.silksong-modding.datamanager").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod Loaded");
}
private void Start()
{
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
pluginInfo.Deconstruct(out var key, out var value);
string key2 = key;
PluginInfo obj = value;
BaseUnityPlugin val = ((obj != null) ? obj.Instance : null);
if (val != null && ManagedMod.TryCreate(val, out ManagedMod instance))
{
instance.LoadProfileData();
instance.LoadGlobalData();
ManagedMods.Add(key2, instance);
}
}
}
internal static void ClearModdedSaveSlot(int saveSlot)
{
string path = DataPaths.SaveSlotDir(saveSlot);
try
{
Directory.Delete(path, recursive: true);
InstanceLogger.LogInfo((object)$"Cleared modded save slot for slot {saveSlot}");
}
catch (DirectoryNotFoundException)
{
InstanceLogger.LogInfo((object)$"No modded save slot to clear for slot {saveSlot}");
}
catch (Exception arg)
{
InstanceLogger.LogError((object)$"Error clearing modded save slot for slot {saveSlot}: {arg}");
}
}
internal static LocalisedString SetSaveIncompatibleText(SaveSlotButton button, LocalisedString s)
{
//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_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
AutoLocalizeTextUI component = ((Component)((Component)button.saveIncompatibleText).gameObject.transform.Find("Small Desc")).gameObject.GetComponent<AutoLocalizeTextUI>();
LocalisedString text = component.Text;
component.Text = s;
return text;
}
internal List<string> MissingMods(int saveSlot)
{
try
{
ManagedSelf.LoadOnceSaveData(saveSlot);
}
catch (IOException)
{
return new List<string>();
}
return (OnceSaveData?.RequiredModGuids ?? new List<string>()).Where((string guid) => !ManagedMods.ContainsKey(guid)).ToList();
}
}
public static class DataPaths
{
public static string ProfileDataDir => Paths.ConfigPath;
public static string GlobalDataDir => ModdedDir("Global");
private static string ModdedDir(string subdir)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
return Path.Combine(((DesktopPlatform)Platform.Current).saveDirPath, "Modded", subdir);
}
internal static string SaveSlotDir(int saveSlot)
{
return ModdedDir($"user{saveSlot}");
}
public static string SaveDataDir(int saveSlot)
{
return Path.Combine(SaveSlotDir(saveSlot), "SaveData");
}
public static string OnceSaveDataDir(int saveSlot)
{
return Path.Combine(SaveSlotDir(saveSlot), "OncePerSave");
}
}
[HarmonyPatch(typeof(GameManager), "OnApplicationQuit")]
internal static class OnQuitGameHook
{
private static void Postfix()
{
Directory.CreateDirectory(DataPaths.ProfileDataDir);
Directory.CreateDirectory(DataPaths.GlobalDataDir);
foreach (ManagedMod value in DataManagerPlugin.Instance.ManagedMods.Values)
{
value.SaveProfileData();
value.SaveGlobalData();
}
}
}
[HarmonyPatch(typeof(GameManager), "SetLoadedGameData", new Type[]
{
typeof(SaveGameData),
typeof(int)
})]
internal static class SaveDataLoadHook
{
private static void Postfix(int saveSlot)
{
Dictionary<string, ManagedMod>.ValueCollection values = DataManagerPlugin.Instance.ManagedMods.Values;
if (saveSlot == 0)
{
foreach (ManagedMod item in values)
{
ISaveDataMod saveData = item.SaveData;
if (saveData != null)
{
saveData.UntypedSaveData = null;
}
IOnceSaveDataMod onceSaveData = item.OnceSaveData;
if (onceSaveData != null)
{
onceSaveData.UntypedOnceSaveData = null;
}
}
return;
}
foreach (ManagedMod item2 in values)
{
item2.LoadOnceSaveData(saveSlot);
item2.LoadSaveData(saveSlot);
}
}
}
[HarmonyPatch(typeof(GameManager), "SaveGame", new Type[]
{
typeof(int),
typeof(Action<bool>),
typeof(bool),
typeof(AutoSaveName)
})]
internal static class SaveDataSaveHook
{
private static void Prefix(int saveSlot, ref Action<bool> ogCallback)
{
if (saveSlot == 0)
{
return;
}
Action<bool> ogCallbackCopy = ogCallback;
ogCallback = delegate(bool didSave)
{
ogCallbackCopy?.Invoke(didSave);
if (!didSave)
{
return;
}
Directory.CreateDirectory(DataPaths.SaveDataDir(saveSlot));
foreach (ManagedMod value in DataManagerPlugin.Instance.ManagedMods.Values)
{
value.SaveSaveData(saveSlot);
}
};
}
}
[HarmonyPatch(typeof(GameManager), "StartNewGame")]
internal static class OnceSetupHook
{
private static void Postfix(GameManager __instance)
{
int profileID = __instance.profileID;
if (profileID == 0)
{
return;
}
Dictionary<string, ManagedMod>.ValueCollection values = DataManagerPlugin.Instance.ManagedMods.Values;
string path = DataPaths.OnceSaveDataDir(profileID);
DataManagerPlugin.ClearModdedSaveSlot(profileID);
Directory.CreateDirectory(path);
List<string> requiredModGuids = (from x in values
where x.IsRequired
select x.Guid).ToList();
DataManagerPlugin.Instance.OnceSaveData = new DMOnceSaveData
{
RequiredModGuids = requiredModGuids
};
foreach (ManagedMod item in values)
{
item.SaveOnceSaveData(profileID);
}
}
}
[HarmonyPatch(typeof(GameManager), "ClearSaveFile")]
internal static class SaveDataClearHook
{
private static void Postfix(int saveSlot)
{
if (saveSlot != 0)
{
DataManagerPlugin.ClearModdedSaveSlot(saveSlot);
}
}
}
[HarmonyPatch(typeof(SaveSlotButton), "ProcessSaveStats")]
internal static class ValidationHook
{
private static LocalisedString? vanillaSaveIncompatibleText;
private static bool Prefix(SaveSlotButton __instance, ref bool __result, bool doAnimate, string errorInfo)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: 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)
//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
int saveSlotIndex = __instance.SaveSlotIndex;
List<string> list = DataManagerPlugin.Instance.MissingMods(saveSlotIndex);
if (list.Count == 0)
{
LocalisedString? val = vanillaSaveIncompatibleText;
if (val.HasValue)
{
LocalisedString valueOrDefault = val.GetValueOrDefault();
DataManagerPlugin.SetSaveIncompatibleText(__instance, valueOrDefault);
vanillaSaveIncompatibleText = null;
}
return true;
}
DataManagerPlugin.InstanceLogger.LogInfo((object)$"save slot {saveSlotIndex} has save data for missing mods:");
foreach (string item in list)
{
DataManagerPlugin.InstanceLogger.LogInfo((object)item);
}
vanillaSaveIncompatibleText = DataManagerPlugin.SetSaveIncompatibleText(__instance, new LocalisedString("Mods.org.silksong-modding.datamanager", "REQUIRED_MODS_MISSING"));
CheatManager.LastErrorText = errorInfo;
__instance.ChangeSaveFileState((SaveFileStates)5, doAnimate);
__result = true;
return false;
}
}
[HarmonyPatch(typeof(SaveSlotButton), "OverrideSaveData")]
internal static class OverrideSaveDataHook
{
private static void Postfix(SaveSlotButton __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Invalid comparison between Unknown and I4
if ((int)__instance.State != 10)
{
return;
}
int saveSlotIndex = __instance.SaveSlotIndex;
string path = DataPaths.SaveDataDir(saveSlotIndex);
try
{
Directory.Delete(path, recursive: true);
}
catch (Exception arg)
{
DataManagerPlugin.InstanceLogger.LogError((object)$"Error overring save data for slot {saveSlotIndex}: {arg}");
}
}
}
public interface IGlobalDataMod<T> : IGlobalDataMod where T : class
{
T? GlobalData { get; set; }
Type IGlobalDataMod.GlobalDataType => typeof(T);
object? IGlobalDataMod.UntypedGlobalData
{
get
{
return GlobalData;
}
set
{
GlobalData = ((value == null) ? null : ((T)value));
}
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IGlobalDataMod
{
Type GlobalDataType { get; }
object? UntypedGlobalData { get; set; }
}
public interface IOnceSaveDataMod<T> : IOnceSaveDataMod where T : class
{
T? OnceSaveData { get; set; }
Type IOnceSaveDataMod.OnceSaveDataType => typeof(T);
object? IOnceSaveDataMod.UntypedOnceSaveData
{
get
{
return OnceSaveData;
}
set
{
OnceSaveData = ((value == null) ? null : ((T)value));
}
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IOnceSaveDataMod
{
Type OnceSaveDataType { get; }
object? UntypedOnceSaveData { get; set; }
}
public interface IProfileDataMod<T> : IProfileDataMod where T : class
{
T? ProfileData { get; set; }
Type IProfileDataMod.ProfileDataType => typeof(T);
object? IProfileDataMod.UntypedProfileData
{
get
{
return ProfileData;
}
set
{
ProfileData = ((value == null) ? null : ((T)value));
}
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public interface IProfileDataMod
{
Type ProfileDataType { get; }
object? UntypedProfileData { get; set; }
}
public interface IRequiredMod
{
bool IsRequired { get; }
}
public interface ISaveDataMod<T> : ISaveDataMod where T : class
{
T? SaveData { get; set; }
Type ISaveDataMod.SaveDataType => typeof(T);
object? ISaveDataMod.UntypedSaveData
{
get
{
return SaveData;
}
set
{
SaveData = ((value == null) ? null : ((T)value));
}
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public interface ISaveDataMod
{
Type SaveDataType { get; }
object? UntypedSaveData { get; set; }
}
internal record ManagedMod(string Guid, IProfileDataMod? ProfileData, IGlobalDataMod? GlobalData, ISaveDataMod? SaveData, IOnceSaveDataMod? OnceSaveData, IRequiredMod? RequiredMod)
{
public bool HasAnyGlobalData
{
get
{
if (ProfileData == null)
{
return GlobalData != null;
}
return true;
}
}
public bool HasAnySaveData
{
get
{
if (SaveData == null)
{
return OnceSaveData != null;
}
return true;
}
}
public bool IsRequired => RequiredMod?.IsRequired ?? false;
private string ProfileDataPath => Path.Combine(DataPaths.ProfileDataDir, Guid + ".json");
private string GlobalDataPath => Path.Combine(DataPaths.GlobalDataDir, Guid + ".json.dat");
internal static bool TryCreate(BaseUnityPlugin plugin, [NotNullWhen(true)] out ManagedMod? instance)
{
instance = null;
string gUID = plugin.Info.Metadata.GUID;
IProfileDataMod profileDataMod = plugin as IProfileDataMod;
IGlobalDataMod globalDataMod = plugin as IGlobalDataMod;
ISaveDataMod saveDataMod = plugin as ISaveDataMod;
IOnceSaveDataMod onceSaveDataMod = plugin as IOnceSaveDataMod;
IRequiredMod requiredMod = plugin as IRequiredMod;
if (profileDataMod == null && globalDataMod == null && saveDataMod == null && onceSaveDataMod == null && requiredMod == null)
{
return false;
}
instance = new ManagedMod(gUID, profileDataMod, globalDataMod, saveDataMod, onceSaveDataMod, requiredMod);
DataManagerPlugin.InstanceLogger.LogInfo((object)(gUID + " uses data manager"));
return true;
}
internal void LoadProfileData()
{
if (ProfileData != null)
{
LoadUntypedData(ProfileDataPath, ProfileData.ProfileDataType, delegate(object? obj)
{
ProfileData.UntypedProfileData = obj;
});
}
}
internal void SaveProfileData()
{
if (ProfileData != null)
{
SaveUntypedData(ProfileDataPath, ProfileData.ProfileDataType, ProfileData.UntypedProfileData);
}
}
internal void LoadGlobalData()
{
if (GlobalData != null)
{
LoadUntypedData(GlobalDataPath, GlobalData.GlobalDataType, delegate(object? obj)
{
GlobalData.UntypedGlobalData = obj;
});
}
}
internal void SaveGlobalData()
{
if (GlobalData != null)
{
SaveUntypedData(GlobalDataPath, GlobalData.GlobalDataType, GlobalData.UntypedGlobalData);
}
}
internal void LoadSaveData(int saveSlot)
{
if (SaveData != null)
{
LoadUntypedData(SaveDataPath(saveSlot), SaveData.SaveDataType, delegate(object? obj)
{
SaveData.UntypedSaveData = obj;
});
}
}
internal void SaveSaveData(int saveSlot)
{
if (SaveData != null)
{
SaveUntypedData(SaveDataPath(saveSlot), SaveData.SaveDataType, SaveData.UntypedSaveData);
}
}
internal void LoadOnceSaveData(int saveSlot)
{
if (OnceSaveData != null)
{
LoadUntypedData(OnceSaveDataPath(saveSlot), OnceSaveData.OnceSaveDataType, delegate(object? obj)
{
OnceSaveData.UntypedOnceSaveData = obj;
});
}
}
internal void SaveOnceSaveData(int saveSlot)
{
if (OnceSaveData != null)
{
SaveUntypedData(OnceSaveDataPath(saveSlot), OnceSaveData.OnceSaveDataType, OnceSaveData.UntypedOnceSaveData);
}
}
private string SaveDataPath(int slot)
{
return Path.Combine(DataPaths.SaveDataDir(slot), Guid + ".json.dat");
}
private string OnceSaveDataPath(int slot)
{
return Path.Combine(DataPaths.OnceSaveDataDir(slot), Guid + ".json.dat");
}
private void LoadUntypedData(string path, Type dataType, Action<object?> onLoad)
{
try
{
object obj = JsonUtil.Deserialize(path, dataType);
onLoad(obj);
DataManagerPlugin.InstanceLogger.LogInfo((object)("Loaded " + dataType.Name + " for mod " + Guid));
}
catch (Exception ex) when (((ex is FileNotFoundException || ex is DirectoryNotFoundException) ? 1 : 0) != 0)
{
onLoad(null);
}
catch (Exception arg)
{
onLoad(null);
DataManagerPlugin.InstanceLogger.LogError((object)$"Error loading {dataType.Name} for mod {Guid}: {arg}");
}
}
private void SaveUntypedData(string path, Type dataType, object? untypedData)
{
if (untypedData == null)
{
return;
}
try
{
JsonUtil.Serialize(path, untypedData);
DataManagerPlugin.InstanceLogger.LogInfo((object)("Saved " + dataType.Name + " for mod " + Guid));
}
catch (Exception arg)
{
DataManagerPlugin.InstanceLogger.LogError((object)$"Error saving {dataType.Name} for mod {Guid}: {arg}");
}
}
[CompilerGenerated]
protected virtual bool PrintMembers(StringBuilder builder)
{
RuntimeHelpers.EnsureSufficientExecutionStack();
builder.Append("Guid = ");
builder.Append((object?)Guid);
builder.Append(", ProfileData = ");
builder.Append(ProfileData);
builder.Append(", GlobalData = ");
builder.Append(GlobalData);
builder.Append(", SaveData = ");
builder.Append(SaveData);
builder.Append(", OnceSaveData = ");
builder.Append(OnceSaveData);
builder.Append(", RequiredMod = ");
builder.Append(RequiredMod);
builder.Append(", HasAnyGlobalData = ");
builder.Append(HasAnyGlobalData.ToString());
builder.Append(", HasAnySaveData = ");
builder.Append(HasAnySaveData.ToString());
builder.Append(", IsRequired = ");
builder.Append(IsRequired.ToString());
return true;
}
}
}
namespace Silksong.DataManager.Json
{
internal static class JsonUtil
{
private static readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
TypeNameHandling = (TypeNameHandling)4,
ObjectCreationHandling = (ObjectCreationHandling)2
};
internal static object? Deserialize(string path, Type type)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using StreamReader streamReader = File.OpenText(path);
JsonTextReader val = new JsonTextReader((TextReader)streamReader);
try
{
return JsonSerializer.CreateDefault(_settings).Deserialize((JsonReader)(object)val, type);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
internal static void Serialize(string path, object value)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Expected O, but got Unknown
using StreamWriter streamWriter = File.CreateText(path);
JsonTextWriter val = new JsonTextWriter((TextWriter)streamWriter);
try
{
JsonSerializer.CreateDefault(_settings).Serialize((JsonWriter)(object)val, value);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
}
namespace Silksong.DataManager.Data
{
internal class DMOnceSaveData
{
public List<string> RequiredModGuids = new List<string>();
}
}