Decompiled source of LocalStorage v2.0.4

plugins/LocalStorage/LocalStorage.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.NET.Common;
using BepInExResoniteShim;
using BepisResoniteWrapper;
using Elements.Core;
using FrooxEngine;
using FrooxEngine.Store;
using FrooxEngine.UIX;
using HarmonyLib;
using Newtonsoft.Json;
using SkyFrost.Base;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: TargetFramework(".NETCoreApp,Version=v10.0", FrameworkDisplayName = ".NET 10.0")]
[assembly: AssemblyCompany("art0007i")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.4.0")]
[assembly: AssemblyInformationalVersion("2.0.4+bde9558f7ceb091f9676db93ff4a28b8b4b1f171")]
[assembly: AssemblyProduct("LocalStorage")]
[assembly: AssemblyTitle("LocalStorage")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/art0007i/LocalStorage")]
[assembly: AssemblyVersion("2.0.4.0")]
[module: RefSafetyRules(11)]
namespace LocalStorage;

[ResonitePlugin("art0007i.LocalStorage", "LocalStorage", "2.0.4", "art0007i", "https://github.com/art0007i/LocalStorage")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
	[HarmonyPatch(typeof(InventoryBrowser))]
	private class InventoryPatch
	{
		[HarmonyPatch("ShowInventoryOwners")]
		[HarmonyPrefix]
		public static bool ShowInventoriesPrefix(InventoryBrowser __instance)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			if (!HIDE_LOCAL)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					Engine engine = ((Worker)__instance).Engine;
					if (engine == null)
					{
						obj = null;
					}
					else
					{
						EngineSkyFrostInterface cloud = engine.Cloud;
						obj = ((cloud != null) ? ((SkyFrostInterface)cloud).CurrentUser : null);
					}
				}
				if (obj == null)
				{
					object obj2;
					if (__instance == null)
					{
						obj2 = null;
					}
					else
					{
						RecordDirectory currentDirectory = __instance.CurrentDirectory;
						obj2 = ((currentDirectory != null) ? currentDirectory.OwnerId : null);
					}
					if ((string)obj2 != "L-LocalStorage" && WorldExtensions.IsUserspace(((Worker)__instance).World))
					{
						RecordDirectory val = new RecordDirectory("L-LocalStorage", "Inventory", ((Worker)__instance).Engine, (string)null);
						__instance.Open(val, (Slide)1);
						return false;
					}
				}
			}
			object obj3;
			if (__instance == null)
			{
				obj3 = null;
			}
			else
			{
				RecordDirectory currentDirectory2 = __instance.CurrentDirectory;
				obj3 = ((currentDirectory2 != null) ? currentDirectory2.OwnerId : null);
			}
			if ((string)obj3 == "L-LocalStorage")
			{
				object obj4;
				if (__instance == null)
				{
					obj4 = null;
				}
				else
				{
					Engine engine2 = ((Worker)__instance).Engine;
					if (engine2 == null)
					{
						obj4 = null;
					}
					else
					{
						EngineSkyFrostInterface cloud2 = engine2.Cloud;
						obj4 = ((cloud2 != null) ? ((SkyFrostInterface)cloud2).CurrentUser : null);
					}
				}
				if (obj4 == null && WorldExtensions.IsUserspace(((Worker)__instance).World))
				{
					Traverse.Create((object)__instance).Method("TryInitialize", global::System.Array.Empty<object>()).GetValue((object[])null);
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch("BeginGeneratingNewDirectory")]
		[HarmonyPostfix]
		public static void GenerationPostfix(InventoryBrowser __instance, UIBuilder __result, ref GridLayout folders)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if (!HIDE_LOCAL && __instance.CurrentDirectory == null && WorldExtensions.IsUserspace(((Worker)__instance).World))
			{
				__result.NestInto(((Component)folders).Slot);
				colorX lime = colorX.Lime;
				colorX black = colorX.Black;
				colorX val = MathX.Lerp(ref lime, ref black, 0.5f, (ColorProfileAwareOperation)0);
				ButtonEventHandler<string> val2 = (ButtonEventHandler<string>)(object)AccessTools.Method(typeof(InventoryBrowser), "OpenInventory", (global::System.Type[])null, (global::System.Type[])null).CreateDelegate(typeof(ButtonEventHandler<string>), (object)__instance);
				LocaleString val3 = LocaleString.op_Implicit("Local Storage");
				colorX? val4 = val;
				__result.Button<string>(ref val3, ref val4, val2, "L-LocalStorage", __instance.ActualDoublePressInterval);
				__result.NestOut();
			}
		}

		[HarmonyPatch("OnChanges")]
		[HarmonyPostfix]
		public static void OnChangesPostFix(InventoryBrowser __instance, ref SyncRef<Button> ____inventoriesButton)
		{
			((ComponentBase<Component>)(object)____inventoriesButton.Target).Enabled = true;
		}

		[HarmonyPatch("OnCommonUpdate")]
		[HarmonyPostfix]
		public static void OnCommonUpdate(InventoryBrowser __instance)
		{
			if (HIDE_LOCAL && !WorldExtensions.IsUserspace(((Worker)__instance).World) && __instance.CurrentDirectory != null && __instance.CurrentDirectory.OwnerId == "L-LocalStorage")
			{
				__instance.Open((RecordDirectory)null, (Slide)2);
			}
		}
	}

	[HarmonyPatch(typeof(RecordDirectory))]
	private class RecordDirectoryPatch
	{
		[StructLayout((LayoutKind)3)]
		[CompilerGenerated]
		private struct <RecursiveDelete>d__9 : IAsyncStateMachine
		{
			public int <>1__state;

			public AsyncTaskMethodBuilder <>t__builder;

			public RecordDirectory dir;

			private TaskAwaiter <>u__1;

			private Enumerator<RecordDirectory> <>7__wrap1;

			private void MoveNext()
			{
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_007b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0055: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0143: Unknown result type (might be due to invalid IL or missing references)
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_015e: Unknown result type (might be due to invalid IL or missing references)
				int num = <>1__state;
				try
				{
					TaskAwaiter val;
					if (num != 0)
					{
						if (num == 1)
						{
							goto IL_00ad;
						}
						if (!dir.CanWrite || dir.IsLink)
						{
							goto IL_01e6;
						}
						val = dir.EnsureFullyLoaded().GetAwaiter();
						if (!((TaskAwaiter)(ref val)).IsCompleted)
						{
							num = (<>1__state = 0);
							<>u__1 = val;
							((AsyncTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter, <RecursiveDelete>d__9>(ref val, ref this);
							return;
						}
					}
					else
					{
						val = <>u__1;
						<>u__1 = default(TaskAwaiter);
						num = (<>1__state = -1);
					}
					((TaskAwaiter)(ref val)).GetResult();
					<>7__wrap1 = Enumerable.ToList<RecordDirectory>((global::System.Collections.Generic.IEnumerable<RecordDirectory>)dir.Subdirectories).GetEnumerator();
					goto IL_00ad;
					IL_01e6:
					if (dir.LinkRecord != null)
					{
						File.Delete(Path.Combine(REC_PATH, dir.LinkRecord.Path.Replace('\\', '/'), dir.LinkRecord.Name) + ".json");
					}
					goto end_IL_0007;
					IL_00ad:
					try
					{
						if (num != 1)
						{
							goto IL_0118;
						}
						val = <>u__1;
						<>u__1 = default(TaskAwaiter);
						num = (<>1__state = -1);
						goto IL_0111;
						IL_0111:
						((TaskAwaiter)(ref val)).GetResult();
						goto IL_0118;
						IL_0118:
						if (<>7__wrap1.MoveNext())
						{
							val = RecursiveDelete(<>7__wrap1.Current).GetAwaiter();
							if (!((TaskAwaiter)(ref val)).IsCompleted)
							{
								num = (<>1__state = 1);
								<>u__1 = val;
								((AsyncTaskMethodBuilder)(ref <>t__builder)).AwaitUnsafeOnCompleted<TaskAwaiter, <RecursiveDelete>d__9>(ref val, ref this);
								return;
							}
							goto IL_0111;
						}
					}
					finally
					{
						if (num < 0)
						{
							((global::System.IDisposable)<>7__wrap1/*cast due to .constrained prefix*/).Dispose();
						}
					}
					<>7__wrap1 = default(Enumerator<RecordDirectory>);
					Enumerator<Record> enumerator = Enumerable.ToList<Record>((global::System.Collections.Generic.IEnumerable<Record>)dir.Records).GetEnumerator();
					try
					{
						while (enumerator.MoveNext())
						{
							Record current = enumerator.Current;
							dir.DeleteItem(current);
						}
					}
					finally
					{
						if (num < 0)
						{
							((global::System.IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
						}
					}
					if (dir.DirectoryRecord != null)
					{
						Directory.Delete(Path.Combine(REC_PATH, dir.Path.Replace('\\', '/')));
						Directory.Delete(Path.Combine(DATA_PATH, dir.Path.Replace('\\', '/')));
					}
					goto IL_01e6;
					end_IL_0007:;
				}
				catch (global::System.Exception exception)
				{
					<>1__state = -2;
					((AsyncTaskMethodBuilder)(ref <>t__builder)).SetException(exception);
					return;
				}
				<>1__state = -2;
				((AsyncTaskMethodBuilder)(ref <>t__builder)).SetResult();
			}

			[DebuggerHidden]
			private void SetStateMachine(IAsyncStateMachine stateMachine)
			{
				((AsyncTaskMethodBuilder)(ref <>t__builder)).SetStateMachine(stateMachine);
			}
		}

		[HarmonyPatch("get_CanWrite")]
		[HarmonyPrefix]
		public static bool CanWrite(ref bool __result, RecordDirectory __instance)
		{
			if (__instance.OwnerId == "L-LocalStorage")
			{
				__result = true;
				return false;
			}
			return true;
		}

		[HarmonyPatch("TryLocalCacheLoad")]
		[HarmonyPrefix]
		public static bool CacheLoad(ref global::System.Threading.Tasks.Task<bool> __result, RecordDirectory __instance)
		{
			if (__instance.OwnerId == "L-LocalStorage")
			{
				__result = global::System.Threading.Tasks.Task.Run<bool>((Func<bool>)(() => false));
				return false;
			}
			return true;
		}

		[HarmonyPatch("LoadFrom", new global::System.Type[]
		{
			typeof(string),
			typeof(string)
		})]
		[HarmonyPrefix]
		public static bool LoadFrom(string ownerId, string path, ref global::System.Threading.Tasks.Task __result, RecordDirectory __instance)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			if (ownerId == "L-LocalStorage")
			{
				__result = global::System.Threading.Tasks.Task.Run((Action)delegate
				{
					//IL_0075: Unknown result type (might be due to invalid IL or missing references)
					//IL_007f: Expected O, but got Unknown
					//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00c9: Expected O, but got Unknown
					//IL_0224: Unknown result type (might be due to invalid IL or missing references)
					//IL_022e: Expected O, but got Unknown
					List<RecordDirectory> val = new List<RecordDirectory>();
					List<Record> val2 = new List<Record>();
					path = path.Replace('\\', '/');
					string text = Path.Combine(REC_PATH, path);
					global::System.Collections.Generic.IEnumerator<string> enumerator = Directory.EnumerateDirectories(text).GetEnumerator();
					try
					{
						while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
						{
							string current = enumerator.Current;
							Record val3 = RecordHelper.CreateForDirectory<Record>("L-LocalStorage", path, Path.GetFileNameWithoutExtension(current));
							val.Add(new RecordDirectory(val3, __instance, __instance.Engine));
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator)?.Dispose();
					}
					enumerator = Directory.EnumerateFiles(text).GetEnumerator();
					try
					{
						while (((global::System.Collections.IEnumerator)enumerator).MoveNext())
						{
							string current2 = enumerator.Current;
							if (!(Path.GetExtension(current2) != ".json"))
							{
								Record val4 = new Record();
								Record val5 = JsonConvert.DeserializeObject<Record>(File.ReadAllText(current2));
								val4.RecordId = val5.RecordId;
								val4.OwnerId = val5.OwnerId;
								val4.AssetURI = val5.AssetURI;
								val4.Name = val5.Name;
								val4.Description = val5.Description;
								val4.RecordType = val5.RecordType;
								val4.OwnerName = val5.OwnerName;
								val4.Tags = val5.Tags;
								val4.Path = val5.Path;
								val4.ThumbnailURI = val5.ThumbnailURI;
								val4.IsPublic = val5.IsPublic;
								val4.IsForPatrons = val5.IsForPatrons;
								val4.IsListed = val5.IsListed;
								val4.LastModificationTime = val5.LastModificationTime;
								val4.CreationTime = val5.CreationTime;
								val4.FirstPublishTime = val5.FirstPublishTime;
								val4.Visits = val5.Visits;
								val4.Rating = val5.Rating;
								val4.RandomOrder = val5.RandomOrder;
								val4.Submissions = val5.Submissions;
								val4.AssetManifest = val5.AssetManifest;
								if (val4.RecordType == "link")
								{
									val.Add(new RecordDirectory(val4, __instance, __instance.Engine));
								}
								else
								{
									val2.Add(val4);
								}
							}
						}
					}
					finally
					{
						((global::System.IDisposable)enumerator)?.Dispose();
					}
					AccessTools.Field(typeof(RecordDirectory), "subdirectories").SetValue((object)__instance, (object)val);
					AccessTools.Field(typeof(RecordDirectory), "records").SetValue((object)__instance, (object)val2);
				});
				return false;
			}
			return true;
		}

		[HarmonyPatch("AddItem")]
		[HarmonyPrefix]
		public static bool AddItem(string name, Uri objectData, Uri thumbnail, global::System.Collections.Generic.IEnumerable<string> tags, ref Record __result, RecordDirectory __instance)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.OwnerId == "L-LocalStorage")
			{
				string text = __instance.ChildRecordPath.Replace('\\', '/');
				string text2 = Path.Combine(DATA_PATH, text, name);
				string text3 = text2 + ".json";
				string text4 = text2 + Path.GetExtension(((object)thumbnail).ToString());
				Log.LogDebug((object)("SAVING " + ((object)objectData).ToString()));
				global::System.Threading.Tasks.Task<Stream> task = __instance.Engine.LocalDB.TryOpenAsset(objectData);
				((global::System.Threading.Tasks.Task)task).Wait();
				DataTreeDictionary val = DataTreeConverter.LoadAuto(task.Result);
				StreamWriter val2 = File.CreateText(text3);
				try
				{
					JsonTextWriter val3 = new JsonTextWriter((TextWriter)(object)val2);
					val3.Indentation = 2;
					((JsonWriter)val3).Formatting = (Formatting)1;
					((MethodBase)AccessTools.Method(typeof(DataTreeConverter), "Write", (global::System.Type[])null, (global::System.Type[])null)).Invoke((object)null, new object[2] { val, val3 });
				}
				finally
				{
					((global::System.IDisposable)val2)?.Dispose();
				}
				if (thumbnail != (Uri)null)
				{
					global::System.Threading.Tasks.Task<Stream> task2 = __instance.Engine.LocalDB.TryOpenAsset(thumbnail);
					((global::System.Threading.Tasks.Task)task2).Wait();
					Stream result = task2.Result;
					FileStream val4 = File.Create(text4);
					result.CopyTo((Stream)(object)val4);
					((Stream)val4).Flush();
					((Stream)val4).Dispose();
				}
				string text5 = string.Concat(new string[5] { "lstore:///", text, "/", name, ".json" });
				string text6 = string.Concat(new string[5]
				{
					"lstore:///",
					text,
					"/",
					name,
					Path.GetExtension(((object)thumbnail).ToString())
				});
				Record val5 = RecordHelper.CreateForObject<Record>(name, __instance.OwnerId, text5, text6, (string)null);
				val5.Path = __instance.ChildRecordPath;
				if (tags != null)
				{
					val5.Tags = new HashSet<string>(tags);
				}
				StreamWriter val6 = File.CreateText(Path.Combine(REC_PATH, text, name + ".json"));
				try
				{
					new JsonSerializer
					{
						Formatting = (Formatting)1
					}.Serialize((TextWriter)(object)val6, (object)val5);
				}
				finally
				{
					((global::System.IDisposable)val6)?.Dispose();
				}
				(AccessTools.Field(typeof(RecordDirectory), "records").GetValue((object)__instance) as List<Record>).Add(val5);
				__result = val5;
				return false;
			}
			return true;
		}

		[HarmonyPatch("AddSubdirectory")]
		[HarmonyPrefix]
		public static bool AddSubdirectory(string name, bool dummyOnly, RecordDirectory __instance, ref RecordDirectory __result)
		{
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (__instance.OwnerId == "L-LocalStorage")
			{
				string text = __instance.ChildRecordPath.Replace('\\', '/');
				string text2 = Path.Combine(REC_PATH, text, name);
				if (Directory.Exists(text2))
				{
					throw new global::System.Exception("Subdirectory with name '" + name + "' already exists.");
				}
				Record obj = RecordHelper.CreateForDirectory<Record>("L-LocalStorage", __instance.ChildRecordPath, name);
				if (!dummyOnly)
				{
					Directory.CreateDirectory(text2);
					Directory.CreateDirectory(Path.Combine(DATA_PATH, text, name));
				}
				RecordDirectory val = new RecordDirectory(obj, __instance, __instance.Engine);
				(AccessTools.Field(typeof(RecordDirectory), "subdirectories").GetValue((object)__instance) as List<RecordDirectory>).Add(val);
				__result = val;
				return false;
			}
			return true;
		}

		[HarmonyPatch("AddLinkAsync")]
		[HarmonyPrefix]
		public static bool AddLinkAsync(string name, Uri target, RecordDirectory __instance, ref global::System.Threading.Tasks.Task<Record> __result)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			if (__instance.OwnerId == "L-LocalStorage")
			{
				string text = __instance.ChildRecordPath.Replace('\\', '/');
				Record record = RecordHelper.CreateForLink<Record>(name, __instance.OwnerId, ((object)target).ToString(), (string)null);
				record.Path = __instance.ChildRecordPath;
				StreamWriter val = File.CreateText(Path.Combine(REC_PATH, text, name + ".json"));
				try
				{
					new JsonSerializer
					{
						Formatting = (Formatting)1
					}.Serialize((TextWriter)(object)val, (object)record);
				}
				finally
				{
					((global::System.IDisposable)val)?.Dispose();
				}
				RecordDirectory val2 = new RecordDirectory(record, __instance, __instance.Engine);
				(AccessTools.Field(typeof(RecordDirectory), "subdirectories").GetValue((object)__instance) as List<RecordDirectory>).Add(val2);
				__result = global::System.Threading.Tasks.Task.Run<Record>((Func<Record>)(() => record));
				return false;
			}
			return true;
		}

		[HarmonyPatch("SetPublicRecursively")]
		[HarmonyPrefix]
		public static bool SetPublicRecursively(RecordDirectory __instance)
		{
			if (__instance.OwnerId == "L-LocalStorage")
			{
				throw new global::System.Exception("You cannot set public on a local directory.");
			}
			return true;
		}

		[HarmonyPatch("DeleteItem")]
		[HarmonyPrefix]
		public static bool DeleteItem(Record record, RecordDirectory __instance, ref bool __result)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			if (__instance.OwnerId == "L-LocalStorage")
			{
				bool flag = (AccessTools.Field(typeof(RecordDirectory), "records").GetValue((object)__instance) as List<Record>).Remove(record);
				if (flag)
				{
					Uri val = new Uri(record.AssetURI);
					if (val.Scheme == "lstore")
					{
						File.Delete(ResolveLstore(val));
					}
					File.Delete(Path.Combine(REC_PATH, record.Path.Replace('\\', '/'), record.Name) + ".json");
				}
				__result = flag;
				return false;
			}
			return true;
		}

		[HarmonyPatch("DeleteSubdirectory")]
		[HarmonyPrefix]
		public static bool DeleteSubdirectory(RecordDirectory directory, RecordDirectory __instance)
		{
			if (__instance.OwnerId == "L-LocalStorage")
			{
				if (!(AccessTools.Field(typeof(RecordDirectory), "subdirectories").GetValue((object)__instance) as List<RecordDirectory>).Remove(directory))
				{
					throw new global::System.Exception("Directory doesn't contain given subdirectory");
				}
				RecursiveDelete(directory);
				return false;
			}
			return true;
		}

		[AsyncStateMachine(typeof(<RecursiveDelete>d__9))]
		public static global::System.Threading.Tasks.Task RecursiveDelete(RecordDirectory dir)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			<RecursiveDelete>d__9 <RecursiveDelete>d__ = default(<RecursiveDelete>d__9);
			<RecursiveDelete>d__.<>t__builder = AsyncTaskMethodBuilder.Create();
			<RecursiveDelete>d__.dir = dir;
			<RecursiveDelete>d__.<>1__state = -1;
			((AsyncTaskMethodBuilder)(ref <RecursiveDelete>d__.<>t__builder)).Start<<RecursiveDelete>d__9>(ref <RecursiveDelete>d__);
			return ((AsyncTaskMethodBuilder)(ref <RecursiveDelete>d__.<>t__builder)).Task;
		}
	}

	[HarmonyPatch(typeof(AssetManager))]
	private class AssetManagerPatch
	{
		[HarmonyPatch("GatherAssetFile")]
		[HarmonyPrefix]
		public static bool RequestGather(Uri assetURL, ref global::System.Threading.Tasks.ValueTask<string> __result)
		{
			if (assetURL.Scheme == "lstore")
			{
				__result = new global::System.Threading.Tasks.ValueTask<string>(ResolveLstore(assetURL));
				return false;
			}
			return true;
		}
	}

	[HarmonyPatch(typeof(DataTreeConverter), "Load", new global::System.Type[]
	{
		typeof(string),
		typeof(string)
	})]
	private class JsonSupportAdding
	{
		public static bool Prefix(string file, string ext, ref DataTreeDictionary __result)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if (ext == null)
			{
				ext = Path.GetExtension(file).ToLower().Replace(".", "");
			}
			if (ext == "json")
			{
				StreamReader val = File.OpenText(file);
				try
				{
					JsonTextReader val2 = new JsonTextReader((TextReader)(object)val);
					try
					{
						MethodInfo val3 = AccessTools.Method(typeof(DataTreeConverter), "Read", (global::System.Type[])null, (global::System.Type[])null);
						__result = (DataTreeDictionary)((MethodBase)val3).Invoke((object)null, new object[1] { val2 });
					}
					finally
					{
						((global::System.IDisposable)val2)?.Dispose();
					}
				}
				finally
				{
					((global::System.IDisposable)val)?.Dispose();
				}
				return false;
			}
			return true;
		}
	}

	public const string LOCAL_OWNER = "L-LocalStorage";

	public static bool HIDE_LOCAL = true;

	public static string REC_PATH;

	public static string DATA_PATH;

	internal static ManualLogSource Log;

	internal static ConfigEntry<string> RecordPath;

	internal static ConfigEntry<string> DataPath;

	public override void Load()
	{
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0064: Expected O, but got Unknown
		Log = ((BasePlugin)this).Log;
		RecordPath = ((BasePlugin)this).Config.Bind<string>("General", "RecordPath", "", "The path in which records will be stored. Changing this setting requires a game restart to apply.");
		DataPath = ((BasePlugin)this).Config.Bind<string>("General", "DataPath", "", "The path in which item data will be stored. Changing this setting requires a game restart to apply.");
		ResoniteHooks.OnEngineReady += (Action)([CompilerGenerated] () =>
		{
			((BasePlugin)this).HarmonyInstance.PatchAll();
			if (string.IsNullOrWhiteSpace(RecordPath.Value))
			{
				RecordPath.Value = Path.Combine(Engine.Current.LocalDB.PermanentPath, "LocalStorage", "Records");
			}
			if (string.IsNullOrWhiteSpace(DataPath.Value))
			{
				DataPath.Value = Path.Combine(Engine.Current.LocalDB.PermanentPath, "LocalStorage", "Data");
			}
			Log.LogDebug((object)"Creating local storage directories");
			REC_PATH = RecordPath.Value.Replace('\\', '/');
			DATA_PATH = DataPath.Value.Replace('\\', '/');
			if (!Directory.Exists(REC_PATH))
			{
				try
				{
					Directory.CreateDirectory(Path.Combine(REC_PATH, "Inventory"));
				}
				catch (global::System.Exception ex)
				{
					HIDE_LOCAL = true;
					Log.LogError((object)"A critical error has occured while creating record directory");
					Log.LogError((object)ex);
				}
			}
			if (!Directory.Exists(DATA_PATH))
			{
				try
				{
					Directory.CreateDirectory(Path.Combine(DATA_PATH, "Inventory"));
				}
				catch (global::System.Exception ex2)
				{
					HIDE_LOCAL = true;
					Log.LogError((object)"A critical error has occured while creating data directory");
					Log.LogError((object)ex2);
				}
			}
			Log.LogInfo((object)("Initalized LocalStorage\nData Path: " + DATA_PATH + "\nRecord Path: " + REC_PATH));
			HIDE_LOCAL = false;
		});
	}

	public static string ResolveLstore(Uri uri)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		string text = Path.GetFullPath(DATA_PATH + Uri.UnescapeDataString(uri.AbsolutePath)).Replace('\\', '/');
		if (text.StartsWith(DATA_PATH))
		{
			if (File.Exists(text))
			{
				return text;
			}
			return null;
		}
		throw new FileNotFoundException("Unexpected path was received. Path: " + text + "\nDataPath: " + DATA_PATH);
	}
}
public static class PluginMetadata
{
	public const string GUID = "art0007i.LocalStorage";

	public const string NAME = "LocalStorage";

	public const string VERSION = "2.0.4";

	public const string AUTHORS = "art0007i";

	public const string REPOSITORY_URL = "https://github.com/art0007i/LocalStorage";
}