Decompiled source of UniversalObjectLoader v1.0.0

ObjectLoader.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using ObjectLoader.Converter;
using SOD.Common.BepInEx;
using UnityEngine;
using UniverseLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ObjectLoader")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+cd04219769b842d862c69c60d7155a0c4e6b7c24")]
[assembly: AssemblyProduct("ObjectLoader")]
[assembly: AssemblyTitle("ObjectLoader")]
[assembly: AssemblyVersion("1.0.0.0")]
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;
		}
	}
}
namespace ObjectLoader
{
	[BepInPlugin("truedartt.objectloader", "Object Loader", "1.0.0")]
	public class Plugin : PluginController<Plugin>
	{
		public const string PLUGIN_GUID = "truedartt.objectloader";

		public const string PLUGIN_NAME = "Object Loader";

		public const string PLUGIN_VERSION = "1.0.0";

		public static Assembly? assembly;

		public static Assembly? unityAssembly;

		public override void Load()
		{
			assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly asm) => asm.GetName().Name == "Assembly-CSharp");
			unityAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly asm) => asm.GetName().Name == "UnityEngine.CoreModule");
		}
	}
	public static class Loader
	{
		public static readonly JsonSerializerOptions cleanOptions = new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true,
			IncludeFields = true,
			AllowTrailingCommas = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement
		};

		public static readonly JsonSerializerOptions options = new JsonSerializerOptions
		{
			PropertyNameCaseInsensitive = true,
			IncludeFields = true,
			AllowTrailingCommas = true,
			ReadCommentHandling = JsonCommentHandling.Skip,
			UnknownTypeHandling = JsonUnknownTypeHandling.JsonElement,
			Converters = 
			{
				(JsonConverter)new TextAssetConverter(),
				(JsonConverter)new SOConverter(),
				(JsonConverter)new CollectionConverter(),
				(JsonConverter)new ExtraConverter()
			}
		};

		private static bool inUse = false;

		private static string? oldPath;

		public static T? LoadFromJson<T>(string path)
		{
			if (!File.Exists(path))
			{
				throw new FileNotFoundException("File not found at path: " + path);
			}
			return LoadObject<T>(File.ReadAllText(path));
		}

		public static T? LoadObject<T>(string json)
		{
			T val = JsonSerializer.Deserialize<T>(json, options);
			if (typeof(T).IsSubclassOf(typeof(ScriptableObject)))
			{
				Toolbox.Instance.resourcesCache[Il2CppType.Of<T>()].Add(ReflectionExtensions.TryCast<SoCustomComparison>((object)val).presetName ?? ((Object)ReflectionExtensions.TryCast<ScriptableObject>((object)val)).name, ReflectionExtensions.TryCast<ScriptableObject>((object)val));
			}
			return val;
		}

		public static void SetPath(string pathBase)
		{
			FileConverter.path = pathBase;
			oldPath = null;
			inUse = false;
		}

		public static void TempChangePath(string pathBase)
		{
			if (oldPath == null)
			{
				oldPath = FileConverter.path;
				inUse = true;
			}
			FileConverter.path = pathBase;
		}

		public static void RevertPath()
		{
			FileConverter.path = oldPath;
			oldPath = null;
			inUse = false;
		}
	}
	public static class Helpers
	{
		public static ScriptableObject GetScriptableObject(string name, Type type)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			bool flag = default(bool);
			try
			{
				Type val = Il2CppType.From(type);
				object obj;
				try
				{
					obj = ReflectionExtensions.TryCast((object)Toolbox.Instance.resourcesCache[val][name], type);
				}
				catch
				{
					ManualLogSource log = PluginController<Plugin, IEmptyBindings>.Log;
					BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(37, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" of type ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Type>(type);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" not found at resourcescache");
					}
					log.LogMessage(val2);
					throw new Exception();
				}
				return (ScriptableObject)((obj is ScriptableObject) ? obj : null);
			}
			catch (KeyNotFoundException ex)
			{
				ManualLogSource log2 = PluginController<Plugin, IEmptyBindings>.Log;
				BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(26, 0, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Something went wrong......");
				}
				log2.LogMessage(val2);
				throw ex;
			}
		}

		public static JsonConverter? GetConverter(Type type)
		{
			if (type.IsSubclassOf(typeof(ScriptableObject)))
			{
				return new SOConverter();
			}
			if (type.IsGenericType)
			{
				return new CollectionConverter();
			}
			if (type.IsSubclassOf(typeof(Object)))
			{
				return new ExtraConverter();
			}
			return null;
		}

		public static JsonConverter? GetConverter(Type type, string token)
		{
			if (token.Contains("__") && !token.Contains('/'))
			{
				return new SOConverter();
			}
			if (token.Contains('/'))
			{
				return new FileConverter();
			}
			return null;
		}

		public static JsonSerializerOptions GetSpecialOptions(JsonConverter? converter)
		{
			if (converter == null)
			{
				return Loader.options;
			}
			return new JsonSerializerOptions(Loader.cleanOptions)
			{
				Converters = { converter }
			};
		}

		public static Dictionary<TKey, TVal> ToIl2CppDict<TKey, TVal>(Dictionary<TKey, TVal> dict)
		{
			Dictionary<TKey, TVal> val = new Dictionary<TKey, TVal>();
			foreach (KeyValuePair<TKey, TVal> item in dict)
			{
				val.Add(item.Key, item.Value);
			}
			return val;
		}

		public static Dictionary<TKey, TVal> ToDict<TKey, TVal>(Dictionary<TKey, TVal> dict)
		{
			Dictionary<TKey, TVal> dictionary = new Dictionary<TKey, TVal>();
			Enumerator<TKey, TVal> enumerator = dict.GetEnumerator();
			while (enumerator.MoveNext())
			{
				KeyValuePair<TKey, TVal> current = enumerator.Current;
				dictionary.Add(current.Key, current.Value);
			}
			return dictionary;
		}

		public static object ParseString(string str, Type type)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			if (type.IsPrimitive || type == typeof(string))
			{
				return str;
			}
			if (str.Contains('/') && !str.Contains(' '))
			{
				JsonSerializerOptions specialOptions = GetSpecialOptions(GetConverter(type, str));
				string text = File.ReadAllText(Path.Combine(FileConverter.path, str));
				if (type == typeof(TextAsset))
				{
					return (object)new TextAsset(text)
					{
						name = GetName(str)
					};
				}
				return JsonSerializer.Deserialize(text, type, specialOptions);
			}
			if (!str.Contains(' ') && str.Contains("__"))
			{
				return ReflectionExtensions.TryCast((object)ScriptableObject.CreateInstance(Il2CppType.From(type)), type);
			}
			if (!str.Contains(' '))
			{
				return GetScriptableObject(str, type);
			}
			return JsonSerializer.Deserialize(str, type, Loader.options);
		}

		public static string GetName(string str)
		{
			string text = str.Split('/').Last();
			return text.Remove(text.Length - 5);
		}
	}
}
namespace ObjectLoader.Converter
{
	public class SOConverter : JsonConverterFactory
	{
		private class SOConverterInner<T> : JsonConverter<T> where T : ScriptableObject
		{
			public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				if (reader.TokenType == JsonTokenType.Null)
				{
					return default(T);
				}
				if (reader.TokenType == JsonTokenType.String)
				{
					string @string = reader.GetString();
					if (string.IsNullOrEmpty(@string))
					{
						return default(T);
					}
					if (@string.EndsWith("__default"))
					{
						return ScriptableObject.CreateInstance<T>();
					}
					if (@string.Contains('/'))
					{
						return JsonSerializer.Deserialize<T>(File.ReadAllText(Path.Combine(FileConverter.path, @string)), Loader.options);
					}
					return ((Il2CppObjectBase)Helpers.GetScriptableObject(@string, typeToConvert)).Cast<T>();
				}
				using JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader);
				JsonElement rootElement = jsonDocument.RootElement;
				T obj = ScriptableObject.CreateInstance<T>();
				((Object)(object)obj).hideFlags = (HideFlags)32;
				Object.DontDestroyOnLoad((Object)(object)obj);
				MemberInfo[] members = typeToConvert.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				Dictionary<string, JsonElement> dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(rootElement.GetRawText(), Loader.cleanOptions) ?? new Dictionary<string, JsonElement>();
				MemberInfo[] array = members;
				foreach (MemberInfo memberInfo in array)
				{
					FieldInfo field = memberInfo as FieldInfo;
					Type type;
					Action<object> action;
					if ((object)field != null)
					{
						type = field.FieldType;
						action = delegate(object? val)
						{
							field.SetValue(obj, val);
						};
					}
					else
					{
						PropertyInfo property = memberInfo as PropertyInfo;
						if ((object)property == null)
						{
							continue;
						}
						type = property.PropertyType;
						action = delegate(object? val)
						{
							property.SetValue(obj, val);
						};
					}
					if (dictionary.TryGetValue(memberInfo.Name, out var value))
					{
						if (value.ValueKind == JsonValueKind.Null)
						{
							action(null);
						}
						if (value.ValueKind == JsonValueKind.String)
						{
							string string2 = value.GetString();
							action(Helpers.ParseString(string2, type));
						}
						else
						{
							action(JsonSerializer.Deserialize(value.GetRawText(), type, Loader.options));
						}
					}
				}
				return ((Il2CppObjectBase)(object)obj).Cast<T>();
			}

			public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
			{
				throw new NotImplementedException();
			}
		}

		public override bool CanConvert(Type typeToConvert)
		{
			return typeToConvert.IsSubclassOf(typeof(ScriptableObject));
		}

		public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			return (JsonConverter)Activator.CreateInstance(typeof(SOConverterInner<>).MakeGenericType(typeToConvert));
		}
	}
	public class CollectionConverter : JsonConverterFactory
	{
		private class ListConverter<T> : JsonConverter<List<T>>
		{
			public override List<T>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				using JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader);
				JsonElement rootElement = jsonDocument.RootElement;
				Type type = typeToConvert.GetGenericArguments()[0];
				List<T> val = new List<T>();
				JsonSerializerOptions specialOptions = Helpers.GetSpecialOptions(Helpers.GetConverter(type));
				foreach (JsonElement item in rootElement.EnumerateArray())
				{
					if (item.ValueKind == JsonValueKind.String)
					{
						string @string = item.GetString();
						val.Add(ReflectionExtensions.TryCast<T>(Helpers.ParseString(@string, type)));
					}
					else
					{
						val.Add(JsonSerializer.Deserialize<T>(item.GetRawText(), specialOptions));
					}
				}
				return val;
			}

			public override void Write(Utf8JsonWriter writer, List<T> value, JsonSerializerOptions options)
			{
				throw new NotImplementedException();
			}
		}

		private class DictionaryConverter<TKey, TValue> : JsonConverter<Dictionary<TKey, TValue>>
		{
			public override Dictionary<TKey, TValue>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				Type type = typeToConvert.GetGenericArguments()[0];
				Type type2 = typeToConvert.GetGenericArguments()[1];
				JsonConverter? converter = Helpers.GetConverter(type);
				JsonConverter converter2 = Helpers.GetConverter(type2);
				JsonSerializerOptions specialOptions = Helpers.GetSpecialOptions(converter);
				JsonSerializerOptions specialOptions2 = Helpers.GetSpecialOptions(converter2);
				using JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader);
				JsonElement rootElement = jsonDocument.RootElement;
				Dictionary<TKey, TValue> val = new Dictionary<TKey, TValue>();
				foreach (JsonProperty item in rootElement.EnumerateObject())
				{
					TKey val2;
					try
					{
						val2 = ReflectionExtensions.TryCast<TKey>(Helpers.ParseString(item.Name, type));
					}
					catch
					{
						val2 = JsonSerializer.Deserialize<TKey>(item.Name, specialOptions);
					}
					if (item.Value.ValueKind == JsonValueKind.String)
					{
						string @string = item.Value.GetString();
						val.Add(val2, ReflectionExtensions.TryCast<TValue>(Helpers.ParseString(@string, type2)));
					}
					else
					{
						TValue val3 = JsonSerializer.Deserialize<TValue>(item.Value.GetRawText(), specialOptions2);
						val.Add(val2, val3);
					}
				}
				return val;
			}

			public override void Write(Utf8JsonWriter writer, Dictionary<TKey, TValue> value, JsonSerializerOptions options)
			{
				throw new NotImplementedException();
			}
		}

		public override bool CanConvert(Type typeToConvert)
		{
			try
			{
				Type genericTypeDefinition = typeToConvert.GetGenericTypeDefinition();
				if (genericTypeDefinition == typeof(List<>) || genericTypeDefinition == typeof(Dictionary<, >))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			if (!typeToConvert.IsGenericType)
			{
				throw new NotSupportedException("Type is not generic.");
			}
			Type genericTypeDefinition = typeToConvert.GetGenericTypeDefinition();
			if (genericTypeDefinition == typeof(List<>))
			{
				Type type = typeToConvert.GetGenericArguments()[0];
				return (JsonConverter)Activator.CreateInstance(typeof(ListConverter<>).MakeGenericType(type));
			}
			if (genericTypeDefinition == typeof(Dictionary<, >))
			{
				Type[] genericArguments = typeToConvert.GetGenericArguments();
				return (JsonConverter)Activator.CreateInstance(typeof(DictionaryConverter<, >).MakeGenericType(genericArguments[0], genericArguments[1]));
			}
			throw new NotSupportedException($"Unsupported IL2CPP collection type: {typeToConvert}");
		}
	}
	public class ExtraConverter : JsonConverterFactory
	{
		private class ExtraConverterInner<T> : JsonConverter<T> where T : Object
		{
			public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				using JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader);
				JsonElement rootElement = jsonDocument.RootElement;
				Object obj = Activator.CreateInstance(Il2CppType.From(typeToConvert));
				MemberInfo[] members = typeToConvert.GetMembers(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				Dictionary<string, JsonElement> dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(rootElement.GetRawText(), Loader.cleanOptions) ?? new Dictionary<string, JsonElement>();
				MemberInfo[] array = members;
				foreach (MemberInfo memberInfo in array)
				{
					bool flag = true;
					FieldInfo field = memberInfo as FieldInfo;
					Type type;
					Action<object> action;
					if ((object)field != null)
					{
						type = field.FieldType;
						action = delegate(object? val)
						{
							field.SetValue(obj, val);
						};
					}
					else
					{
						PropertyInfo property = memberInfo as PropertyInfo;
						if ((object)property == null)
						{
							continue;
						}
						type = property.PropertyType;
						if (property.DeclaringType == typeof(Object) || !property.CanWrite)
						{
							continue;
						}
						flag = Nullable.GetUnderlyingType(type) != null;
						action = delegate(object? val)
						{
							property.SetValue(ReflectionExtensions.TryCast((object)obj, property.DeclaringType), val);
						};
					}
					if (!dictionary.TryGetValue(memberInfo.Name, out var value))
					{
						continue;
					}
					if (value.ValueKind == JsonValueKind.Null)
					{
						if (!flag)
						{
							continue;
						}
						action(null);
					}
					if (value.ValueKind == JsonValueKind.String)
					{
						string @string = value.GetString();
						action(Helpers.ParseString(@string, type));
					}
					else
					{
						object obj2 = JsonSerializer.Deserialize(value.GetRawText(), type, Loader.options);
						action(obj2);
					}
				}
				return ((Il2CppObjectBase)obj).Cast<T>();
			}

			public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
			{
				throw new NotImplementedException();
			}
		}

		public override bool CanConvert(Type typeToConvert)
		{
			if (!typeToConvert.IsSubclassOf(typeof(ScriptableObject)) && typeToConvert.IsSubclassOf(typeof(Object)))
			{
				return Plugin.assembly.GetType(typeToConvert.FullName) != null;
			}
			return false;
		}

		public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			return (JsonConverter)Activator.CreateInstance(typeof(ExtraConverterInner<>).MakeGenericType(typeToConvert));
		}
	}
	public class FileConverter : JsonConverterFactory
	{
		private class FileConverterInner<T> : JsonConverter<T>
		{
			public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
			{
				return Loader.LoadFromJson<T>(Path.Combine(path, reader.GetString()));
			}

			public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
			{
				throw new NotImplementedException();
			}
		}

		public static string path;

		public override bool CanConvert(Type typeToConvert)
		{
			return !typeToConvert.IsPrimitive;
		}

		public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
		{
			throw new NotImplementedException();
		}
	}
	public class TextAssetConverter : JsonConverter<TextAsset>
	{
		public override TextAsset? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//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_003b: Expected O, but got Unknown
			if (!reader.GetString().Contains('/'))
			{
				return new TextAsset(reader.GetString());
			}
			return new TextAsset(File.ReadAllText(Path.Combine(FileConverter.path, reader.GetString())))
			{
				name = Helpers.GetName(reader.GetString())
			};
		}

		public override void Write(Utf8JsonWriter writer, TextAsset value, JsonSerializerOptions options)
		{
			throw new NotImplementedException();
		}
	}
}