Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Jotunn v2.28.0
plugins/Jotunn.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Extensions; using Jotunn.GUI; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using SimpleJson; using SimpleJson.Reflection; using SoftReferenceableAssets; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.LowLevel; using UnityEngine.SceneManagement; using UnityEngine.U2D; using UnityEngine.UI; using YamlDotNet.Serialization; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("JotunnTests")] [assembly: InternalsVisibleTo("JotunnDoc")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Valheim-Modding team")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Jötunn (/ˈjɔːtʊn/, \"giant\") is a modding library for Valheim, with the goal of making the lives of mod developers easier.")] [assembly: AssemblyFileVersion("2.28.0.0")] [assembly: AssemblyInformationalVersion("2.28.0+7ffd26af4ded4de211d691ef4c957e2fbbb75de7")] [assembly: AssemblyProduct("JotunnLib")] [assembly: AssemblyTitle("Jotunn")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Valheim-Modding/Jotunn")] [assembly: NeutralResourcesLanguage("en")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.28.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } internal class CompatibilityWindow : MonoBehaviour { public ScrollRect scrollRect; public Text failedConnection; public Text localVersion; public Text remoteVersion; public Text errorMessages; public Button continueButton; public Button logFileButton; public Button troubleshootingButton; public void UpdateTextPositions() { //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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown float preferredHeight = failedConnection.preferredHeight; float preferredHeight2 = localVersion.preferredHeight; float preferredHeight3 = remoteVersion.preferredHeight; float preferredHeight4 = errorMessages.preferredHeight; Vector2 anchoredPosition = ((Graphic)localVersion).rectTransform.anchoredPosition; Vector2 anchoredPosition2 = ((Graphic)remoteVersion).rectTransform.anchoredPosition; float num = preferredHeight + 32f; ((Graphic)localVersion).rectTransform.anchoredPosition = new Vector2(anchoredPosition.x, 0f - num); ((Graphic)remoteVersion).rectTransform.anchoredPosition = new Vector2(anchoredPosition2.x, 0f - num); Vector2 anchoredPosition3 = ((Graphic)errorMessages).rectTransform.anchoredPosition; float num2 = num + Mathf.Max(preferredHeight2, preferredHeight3) + 32f; ((Graphic)errorMessages).rectTransform.anchoredPosition = new Vector2(anchoredPosition3.x, 0f - num2); RectTransform val = (RectTransform)((Component)scrollRect.content).transform; val.SetSizeWithCurrentAnchors((Axis)1, num2 + preferredHeight4); } } public sealed class ConfigurationManagerAttributes { public bool? ShowRangeAsPercent; public Action<ConfigEntryBase> CustomDrawer; public bool? Browsable; public string Category; public object DefaultValue; public bool? HideDefaultButton; public bool? HideSettingName; public string Description; public string DispName; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; public Func<object, string> ObjToStr; public Func<string, object> StrToObj; private bool isAdminOnly; private bool isUnlocked = true; private static readonly PropertyInfo[] _myProperties = typeof(ConfigurationManagerAttributes).GetProperties(BindingFlags.Instance | BindingFlags.Public); private static readonly FieldInfo[] _myFields = typeof(ConfigurationManagerAttributes).GetFields(BindingFlags.Instance | BindingFlags.Public); public bool IsAdminOnly { get { return isAdminOnly; } set { isAdminOnly = value; bool flag = isAdminOnly && !SynchronizationManager.Instance.PlayerIsAdmin; IsUnlocked = !flag; } } public Color EntryColor { get; set; } public Color DescriptionColor { get; set; } public bool IsUnlocked { get { return isUnlocked; } internal set { ReadOnly = !value; HideDefaultButton = !value; isUnlocked = value; } } public ConfigurationManagerAttributes() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) EntryColor = new Color(1f, 0.631f, 0.235f, 1f); DescriptionColor = Color.white; } public void SetFromAttributes(object[] attribs) { if (attribs == null || attribs.Length == 0) { return; } foreach (object obj in attribs) { if (obj == null) { continue; } if (!(obj is DisplayNameAttribute displayNameAttribute)) { if (!(obj is CategoryAttribute categoryAttribute)) { if (!(obj is DescriptionAttribute descriptionAttribute)) { if (!(obj is DefaultValueAttribute defaultValueAttribute)) { if (!(obj is ReadOnlyAttribute readOnlyAttribute)) { if (!(obj is BrowsableAttribute browsableAttribute)) { if (obj is string text) { switch (text) { case "ReadOnly": ReadOnly = true; break; case "Browsable": Browsable = true; break; case "Unbrowsable": case "Hidden": Browsable = false; break; case "Advanced": IsAdvanced = true; break; } continue; } Type type = obj.GetType(); if (!(type.Name == "ConfigurationManagerAttributes")) { break; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (var item in from my in _myProperties join other in fields on my.Name equals other.Name select new { my, other }) { try { object obj2 = item.other.GetValue(obj); if (obj2 != null) { if (item.my.PropertyType != item.other.FieldType && typeof(Delegate).IsAssignableFrom(item.my.PropertyType)) { obj2 = Delegate.CreateDelegate(item.my.PropertyType, ((Delegate)obj2).Target, ((Delegate)obj2).Method); } item.my.SetValue(this, obj2, null); } } catch (Exception ex) { Logger.LogWarning("Failed to copy value " + item.my.Name + " from provided tag object " + type.FullName + " - " + ex.Message); } } foreach (var item2 in from my in _myFields join other in fields on my.Name equals other.Name select new { my, other }) { try { object obj3 = item2.other.GetValue(obj); if (obj3 != null) { if (item2.my.FieldType != item2.other.FieldType && typeof(Delegate).IsAssignableFrom(item2.my.FieldType)) { obj3 = Delegate.CreateDelegate(item2.my.FieldType, ((Delegate)obj3).Target, ((Delegate)obj3).Method); } item2.my.SetValue(this, obj3); } } catch (Exception ex2) { Logger.LogWarning("Failed to copy value " + item2.my.Name + " from provided tag object " + type.FullName + " - " + ex2.Message); } } } else { Browsable = browsableAttribute.Browsable; } } else { ReadOnly = readOnlyAttribute.IsReadOnly; } } else { DefaultValue = defaultValueAttribute.Value; } } else { Description = descriptionAttribute.Description; } } else { Category = categoryAttribute.Category; } } else { DispName = displayNameAttribute.DisplayName; } } } } public static class ObjImporter { private struct meshStruct { public Vector3[] vertices; public Vector3[] normals; public Vector2[] uv; public Vector2[] uv1; public Vector2[] uv2; public int[] triangles; public int[] faceVerts; public int[] faceUVs; public Vector3[] faceData; public string name; public string fileName; } public static Mesh ImportFile(string filePath) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_009e: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) meshStruct mesh = CreateMeshStruct(filePath); PopulateMeshStruct(ref mesh); Vector3[] array = (Vector3[])(object)new Vector3[mesh.faceData.Length]; Vector2[] array2 = (Vector2[])(object)new Vector2[mesh.faceData.Length]; Vector3[] array3 = (Vector3[])(object)new Vector3[mesh.faceData.Length]; int num = 0; Vector3[] faceData = mesh.faceData; foreach (Vector3 val in faceData) { array[num] = mesh.vertices[(int)val.x - 1]; if (val.y >= 1f) { array2[num] = mesh.uv[(int)val.y - 1]; } if (val.z >= 1f) { array3[num] = mesh.normals[(int)val.z - 1]; } num++; } Mesh val2 = new Mesh(); val2.vertices = array; val2.uv = array2; val2.normals = array3; val2.triangles = mesh.triangles; val2.RecalculateBounds(); val2.Optimize(); return val2; } private static meshStruct CreateMeshStruct(string filename) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; meshStruct result = default(meshStruct); result.fileName = filename; StreamReader streamReader = File.OpenText(filename); string s = streamReader.ReadToEnd(); streamReader.Close(); using (StringReader stringReader = new StringReader(s)) { string text = stringReader.ReadLine(); char[] separator = new char[1] { ' ' }; while (text != null) { if (!text.StartsWith("f ") && !text.StartsWith("v ") && !text.StartsWith("vt ") && !text.StartsWith("vn ")) { text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } continue; } text = text.Trim(); string[] array = text.Split(separator, 50); switch (array[0]) { case "v": num2++; break; case "vt": num3++; break; case "vn": num4++; break; case "f": num5 = num5 + array.Length - 1; num += 3 * (array.Length - 2); break; } text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } } } result.triangles = new int[num]; result.vertices = (Vector3[])(object)new Vector3[num2]; result.uv = (Vector2[])(object)new Vector2[num3]; result.normals = (Vector3[])(object)new Vector3[num4]; result.faceData = (Vector3[])(object)new Vector3[num5]; return result; } private static void PopulateMeshStruct(ref meshStruct mesh) { //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d0: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_02ff: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) StreamReader streamReader = File.OpenText(mesh.fileName); string s = streamReader.ReadToEnd(); streamReader.Close(); using StringReader stringReader = new StringReader(s); string text = stringReader.ReadLine(); char[] separator = new char[1] { ' ' }; char[] separator2 = new char[1] { '/' }; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; while (text != null) { if (!text.StartsWith("f ") && !text.StartsWith("v ") && !text.StartsWith("vt ") && !text.StartsWith("vn ") && !text.StartsWith("g ") && !text.StartsWith("usemtl ") && !text.StartsWith("mtllib ") && !text.StartsWith("vt1 ") && !text.StartsWith("vt2 ") && !text.StartsWith("vc ") && !text.StartsWith("usemap ")) { text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } continue; } text = text.Trim(); string[] array = text.Split(separator, 50); switch (array[0]) { case "v": mesh.vertices[num3] = new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])); num3++; break; case "vt": mesh.uv[num5] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num5++; break; case "vt1": mesh.uv[num6] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num6++; break; case "vt2": mesh.uv[num7] = new Vector2(Convert.ToSingle(array[1]), Convert.ToSingle(array[2])); num7++; break; case "vn": mesh.normals[num4] = new Vector3(Convert.ToSingle(array[1]), Convert.ToSingle(array[2]), Convert.ToSingle(array[3])); num4++; break; case "f": { int num8 = 1; List<int> list = new List<int>(); while (num8 < array.Length && (array[num8] ?? "").Length > 0) { Vector3 val = default(Vector3); string[] array2 = array[num8].Split(separator2, 3); val.x = Convert.ToInt32(array2[0]); if (array2.Length > 1) { if (array2[1] != "") { val.y = Convert.ToInt32(array2[1]); } val.z = Convert.ToInt32(array2[2]); } num8++; mesh.faceData[num2] = val; list.Add(num2); num2++; } for (num8 = 1; num8 + 2 < array.Length; num8++) { mesh.triangles[num] = list[0]; num++; mesh.triangles[num] = list[num8]; num++; mesh.triangles[num] = list[num8 + 1]; num++; } break; } } text = stringReader.ReadLine(); if (text != null) { text = text.Replace(" ", " "); } } } } namespace SimpleJson { [GeneratedCode("simple-json", "1.0.0")] [EditorBrowsable(EditorBrowsableState.Never)] public class JsonArray : List<object> { public JsonArray() { } public JsonArray(int capacity) : base(capacity) { } public override string ToString() { return SimpleJson.SerializeObject(this) ?? string.Empty; } } [GeneratedCode("simple-json", "1.0.0")] [EditorBrowsable(EditorBrowsableState.Never)] public class JsonObject : IDictionary<string, object>, ICollection<KeyValuePair<string, object>>, IEnumerable<KeyValuePair<string, object>>, IEnumerable { private readonly Dictionary<string, object> _members; public object this[int index] => GetAtIndex(_members, index); public ICollection<string> Keys => _members.Keys; public ICollection<object> Values => _members.Values; public object this[string key] { get { return _members[key]; } set { _members[key] = value; } } public int Count => _members.Count; public bool IsReadOnly => false; public JsonObject() { _members = new Dictionary<string, object>(); } public JsonObject(IEqualityComparer<string> comparer) { _members = new Dictionary<string, object>(comparer); } internal static object GetAtIndex(IDictionary<string, object> obj, int index) { if (obj == null) { throw new ArgumentNullException("obj"); } if (index >= obj.Count) { throw new ArgumentOutOfRangeException("index"); } int num = 0; foreach (KeyValuePair<string, object> item in obj) { if (num++ == index) { return item.Value; } } return null; } public void Add(string key, object value) { _members.Add(key, value); } public bool ContainsKey(string key) { return _members.ContainsKey(key); } public bool Remove(string key) { return _members.Remove(key); } public bool TryGetValue(string key, out object value) { return _members.TryGetValue(key, out value); } public void Add(KeyValuePair<string, object> item) { _members.Add(item.Key, item.Value); } public void Clear() { _members.Clear(); } public bool Contains(KeyValuePair<string, object> item) { if (_members.ContainsKey(item.Key)) { return _members[item.Key] == item.Value; } return false; } public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } int num = Count; using IEnumerator<KeyValuePair<string, object>> enumerator = GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair<string, object> current = enumerator.Current; array[arrayIndex++] = current; if (--num <= 0) { break; } } } public bool Remove(KeyValuePair<string, object> item) { return _members.Remove(item.Key); } public IEnumerator<KeyValuePair<string, object>> GetEnumerator() { return _members.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _members.GetEnumerator(); } public override string ToString() { return SimpleJson.SerializeObject(this); } } [GeneratedCode("simple-json", "1.0.0")] public static class SimpleJson { private const int TOKEN_NONE = 0; private const int TOKEN_CURLY_OPEN = 1; private const int TOKEN_CURLY_CLOSE = 2; private const int TOKEN_SQUARED_OPEN = 3; private const int TOKEN_SQUARED_CLOSE = 4; private const int TOKEN_COLON = 5; private const int TOKEN_COMMA = 6; private const int TOKEN_STRING = 7; private const int TOKEN_NUMBER = 8; private const int TOKEN_TRUE = 9; private const int TOKEN_FALSE = 10; private const int TOKEN_NULL = 11; private const int BUILDER_CAPACITY = 2000; private static readonly char[] EscapeTable; private static readonly char[] EscapeCharacters; private static readonly string EscapeCharactersString; private static IJsonSerializerStrategy _currentJsonSerializerStrategy; private static PocoJsonSerializerStrategy _pocoJsonSerializerStrategy; public static IJsonSerializerStrategy CurrentJsonSerializerStrategy { get { return _currentJsonSerializerStrategy ?? (_currentJsonSerializerStrategy = PocoJsonSerializerStrategy); } set { _currentJsonSerializerStrategy = value; } } [EditorBrowsable(EditorBrowsableState.Advanced)] public static PocoJsonSerializerStrategy PocoJsonSerializerStrategy => _pocoJsonSerializerStrategy ?? (_pocoJsonSerializerStrategy = new PocoJsonSerializerStrategy()); static SimpleJson() { EscapeCharacters = new char[7] { '"', '\\', '\b', '\f', '\n', '\r', '\t' }; EscapeCharactersString = new string(EscapeCharacters); EscapeTable = new char[93]; EscapeTable[34] = '"'; EscapeTable[92] = '\\'; EscapeTable[8] = 'b'; EscapeTable[12] = 'f'; EscapeTable[10] = 'n'; EscapeTable[13] = 'r'; EscapeTable[9] = 't'; } public static object DeserializeObject(string json) { if (TryDeserializeObject(json, out var obj)) { return obj; } throw new SerializationException("Invalid JSON string"); } public static bool TryDeserializeObject(string json, out object obj) { bool success = true; if (json != null) { char[] json2 = json.ToCharArray(); int index = 0; obj = ParseValue(json2, ref index, ref success); } else { obj = null; } return success; } public static object DeserializeObject(string json, Type type, IJsonSerializerStrategy jsonSerializerStrategy) { object obj = DeserializeObject(json); if (!(type == null) && (obj == null || !ReflectionUtils.IsAssignableFrom(obj.GetType(), type))) { return (jsonSerializerStrategy ?? CurrentJsonSerializerStrategy).DeserializeObject(obj, type); } return obj; } public static object DeserializeObject(string json, Type type) { return DeserializeObject(json, type, null); } public static T DeserializeObject<T>(string json, IJsonSerializerStrategy jsonSerializerStrategy) { return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); } public static T DeserializeObject<T>(string json) { return (T)DeserializeObject(json, typeof(T), null); } public static string SerializeObject(object json, IJsonSerializerStrategy jsonSerializerStrategy) { StringBuilder stringBuilder = new StringBuilder(2000); if (!SerializeValue(jsonSerializerStrategy, json, stringBuilder)) { return null; } return stringBuilder.ToString(); } public static string SerializeObject(object json) { return SerializeObject(json, CurrentJsonSerializerStrategy); } public static string EscapeToJavascriptString(string jsonString) { if (string.IsNullOrEmpty(jsonString)) { return jsonString; } StringBuilder stringBuilder = new StringBuilder(); int num = 0; while (num < jsonString.Length) { char c = jsonString[num++]; if (c == '\\') { int num2 = jsonString.Length - num; if (num2 >= 2) { switch (jsonString[num]) { case '\\': stringBuilder.Append('\\'); num++; break; case '"': stringBuilder.Append("\""); num++; break; case 't': stringBuilder.Append('\t'); num++; break; case 'b': stringBuilder.Append('\b'); num++; break; case 'n': stringBuilder.Append('\n'); num++; break; case 'r': stringBuilder.Append('\r'); num++; break; } } } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static IDictionary<string, object> ParseObject(char[] json, ref int index, ref bool success) { IDictionary<string, object> dictionary = new JsonObject(); NextToken(json, ref index); bool flag = false; while (!flag) { switch (LookAhead(json, index)) { case 0: success = false; return null; case 6: NextToken(json, ref index); continue; case 2: NextToken(json, ref index); return dictionary; } string key = ParseString(json, ref index, ref success); if (!success) { success = false; return null; } int num = NextToken(json, ref index); if (num != 5) { success = false; return null; } object value = ParseValue(json, ref index, ref success); if (!success) { success = false; return null; } dictionary[key] = value; } return dictionary; } private static JsonArray ParseArray(char[] json, ref int index, ref bool success) { JsonArray jsonArray = new JsonArray(); NextToken(json, ref index); bool flag = false; while (!flag) { switch (LookAhead(json, index)) { case 0: success = false; return null; case 6: NextToken(json, ref index); continue; case 4: break; default: { object item = ParseValue(json, ref index, ref success); if (!success) { return null; } jsonArray.Add(item); continue; } } NextToken(json, ref index); break; } return jsonArray; } private static object ParseValue(char[] json, ref int index, ref bool success) { switch (LookAhead(json, index)) { case 7: return ParseString(json, ref index, ref success); case 8: return ParseNumber(json, ref index, ref success); case 1: return ParseObject(json, ref index, ref success); case 3: return ParseArray(json, ref index, ref success); case 9: NextToken(json, ref index); return true; case 10: NextToken(json, ref index); return false; case 11: NextToken(json, ref index); return null; default: success = false; return null; } } private static string ParseString(char[] json, ref int index, ref bool success) { StringBuilder stringBuilder = new StringBuilder(2000); EatWhitespace(json, ref index); char c = json[index++]; bool flag = false; while (!flag && index != json.Length) { c = json[index++]; switch (c) { case '"': flag = true; break; case '\\': { if (index == json.Length) { break; } switch (json[index++]) { case '"': stringBuilder.Append('"'); continue; case '\\': stringBuilder.Append('\\'); continue; case '/': stringBuilder.Append('/'); continue; case 'b': stringBuilder.Append('\b'); continue; case 'f': stringBuilder.Append('\f'); continue; case 'n': stringBuilder.Append('\n'); continue; case 'r': stringBuilder.Append('\r'); continue; case 't': stringBuilder.Append('\t'); continue; case 'u': break; default: continue; } int num = json.Length - index; if (num < 4) { break; } if (!(success = uint.TryParse(new string(json, index, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))) { return ""; } if (55296 <= result && result <= 56319) { index += 4; num = json.Length - index; if (num < 6 || !(new string(json, index, 2) == "\\u") || !uint.TryParse(new string(json, index + 2, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result2) || 56320 > result2 || result2 > 57343) { success = false; return ""; } stringBuilder.Append((char)result); stringBuilder.Append((char)result2); index += 6; } else { stringBuilder.Append(ConvertFromUtf32((int)result)); index += 4; } continue; } default: stringBuilder.Append(c); continue; } break; } if (!flag) { success = false; return null; } return stringBuilder.ToString(); } private static string ConvertFromUtf32(int utf32) { if (utf32 < 0 || utf32 > 1114111) { throw new ArgumentOutOfRangeException("utf32", "The argument must be from 0 to 0x10FFFF."); } if (55296 <= utf32 && utf32 <= 57343) { throw new ArgumentOutOfRangeException("utf32", "The argument must not be in surrogate pair range."); } if (utf32 < 65536) { return new string((char)utf32, 1); } utf32 -= 65536; return new string(new char[2] { (char)((utf32 >> 10) + 55296), (char)(utf32 % 1024 + 56320) }); } private static object ParseNumber(char[] json, ref int index, ref bool success) { EatWhitespace(json, ref index); int lastIndexOfNumber = GetLastIndexOfNumber(json, index); int length = lastIndexOfNumber - index + 1; string text = new string(json, index, length); object result2; if (text.IndexOf(".", StringComparison.OrdinalIgnoreCase) != -1 || text.IndexOf("e", StringComparison.OrdinalIgnoreCase) != -1) { success = double.TryParse(new string(json, index, length), NumberStyles.Any, CultureInfo.InvariantCulture, out var result); result2 = result; } else { success = long.TryParse(new string(json, index, length), NumberStyles.Any, CultureInfo.InvariantCulture, out var result3); result2 = result3; } index = lastIndexOfNumber + 1; return result2; } private static int GetLastIndexOfNumber(char[] json, int index) { int i; for (i = index; i < json.Length && "0123456789+-.eE".IndexOf(json[i]) != -1; i++) { } return i - 1; } private static void EatWhitespace(char[] json, ref int index) { while (index < json.Length && " \t\n\r\b\f".IndexOf(json[index]) != -1) { index++; } } private static int LookAhead(char[] json, int index) { int index2 = index; return NextToken(json, ref index2); } private static int NextToken(char[] json, ref int index) { EatWhitespace(json, ref index); if (index == json.Length) { return 0; } char c = json[index]; index++; switch (c) { case '{': return 1; case '}': return 2; case '[': return 3; case ']': return 4; case ',': return 6; case '"': return 7; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return 8; case ':': return 5; default: { index--; int num = json.Length - index; if (num >= 5 && json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') { index += 5; return 10; } if (num >= 4 && json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') { index += 4; return 9; } if (num >= 4 && json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') { index += 4; return 11; } return 0; } } } private static bool SerializeValue(IJsonSerializerStrategy jsonSerializerStrategy, object value, StringBuilder builder) { bool flag = true; if (value is string aString) { flag = SerializeString(aString, builder); } else if (value is IDictionary<string, object> dictionary) { flag = SerializeObject(jsonSerializerStrategy, dictionary.Keys, dictionary.Values, builder); } else if (value is IDictionary<string, string> dictionary2) { flag = SerializeObject(jsonSerializerStrategy, dictionary2.Keys, dictionary2.Values, builder); } else if (value is IEnumerable anArray) { flag = SerializeArray(jsonSerializerStrategy, anArray, builder); } else if (IsNumeric(value)) { flag = SerializeNumber(value, builder); } else if (value is bool) { builder.Append(((bool)value) ? "true" : "false"); } else if (value == null) { builder.Append("null"); } else { flag = jsonSerializerStrategy.TrySerializeNonPrimitiveObject(value, out var output); if (flag) { SerializeValue(jsonSerializerStrategy, output, builder); } } return flag; } private static bool SerializeObject(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable keys, IEnumerable values, StringBuilder builder) { builder.Append("{"); IEnumerator enumerator = keys.GetEnumerator(); IEnumerator enumerator2 = values.GetEnumerator(); bool flag = true; while (enumerator.MoveNext() && enumerator2.MoveNext()) { object current = enumerator.Current; object current2 = enumerator2.Current; if (!flag) { builder.Append(","); } if (current is string aString) { SerializeString(aString, builder); } else if (!SerializeValue(jsonSerializerStrategy, current2, builder)) { return false; } builder.Append(":"); if (!SerializeValue(jsonSerializerStrategy, current2, builder)) { return false; } flag = false; } builder.Append("}"); return true; } private static bool SerializeArray(IJsonSerializerStrategy jsonSerializerStrategy, IEnumerable anArray, StringBuilder builder) { builder.Append("["); bool flag = true; foreach (object item in anArray) { if (!flag) { builder.Append(","); } if (!SerializeValue(jsonSerializerStrategy, item, builder)) { return false; } flag = false; } builder.Append("]"); return true; } private static bool SerializeString(string aString, StringBuilder builder) { if (aString.IndexOfAny(EscapeCharacters) == -1) { builder.Append('"'); builder.Append(aString); builder.Append('"'); return true; } builder.Append('"'); int num = 0; char[] array = aString.ToCharArray(); for (int i = 0; i < array.Length; i++) { char c = array[i]; if (c >= EscapeTable.Length || EscapeTable[(uint)c] == '\0') { num++; continue; } if (num > 0) { builder.Append(array, i - num, num); num = 0; } builder.Append('\\'); builder.Append(EscapeTable[(uint)c]); } if (num > 0) { builder.Append(array, array.Length - num, num); } builder.Append('"'); return true; } private static bool SerializeNumber(object number, StringBuilder builder) { if (number is long) { builder.Append(((long)number).ToString(CultureInfo.InvariantCulture)); } else if (number is ulong) { builder.Append(((ulong)number).ToString(CultureInfo.InvariantCulture)); } else if (number is int) { builder.Append(((int)number).ToString(CultureInfo.InvariantCulture)); } else if (number is uint) { builder.Append(((uint)number).ToString(CultureInfo.InvariantCulture)); } else if (number is decimal) { builder.Append(((decimal)number).ToString(CultureInfo.InvariantCulture)); } else if (number is float) { builder.Append(((float)number).ToString(CultureInfo.InvariantCulture)); } else { builder.Append(Convert.ToDouble(number, CultureInfo.InvariantCulture).ToString("r", CultureInfo.InvariantCulture)); } return true; } private static bool IsNumeric(object value) { if (value is sbyte) { return true; } if (value is byte) { return true; } if (value is short) { return true; } if (value is ushort) { return true; } if (value is int) { return true; } if (value is uint) { return true; } if (value is long) { return true; } if (value is ulong) { return true; } if (value is float) { return true; } if (value is double) { return true; } if (value is decimal) { return true; } return false; } } [GeneratedCode("simple-json", "1.0.0")] public interface IJsonSerializerStrategy { bool TrySerializeNonPrimitiveObject(object input, out object output); object DeserializeObject(object value, Type type); } [GeneratedCode("simple-json", "1.0.0")] public class PocoJsonSerializerStrategy : IJsonSerializerStrategy { internal IDictionary<Type, ReflectionUtils.ConstructorDelegate> ConstructorCache; internal IDictionary<Type, IDictionary<string, ReflectionUtils.GetDelegate>> GetCache; internal IDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>> SetCache; internal static readonly Type[] EmptyTypes = new Type[0]; internal static readonly Type[] ArrayConstructorParameterTypes = new Type[1] { typeof(int) }; private static readonly string[] Iso8601Format = new string[3] { "yyyy-MM-dd\\THH:mm:ss.FFFFFFF\\Z", "yyyy-MM-dd\\THH:mm:ss\\Z", "yyyy-MM-dd\\THH:mm:ssK" }; public PocoJsonSerializerStrategy() { ConstructorCache = new ReflectionUtils.ThreadSafeDictionary<Type, ReflectionUtils.ConstructorDelegate>(ContructorDelegateFactory); GetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, ReflectionUtils.GetDelegate>>(GetterValueFactory); SetCache = new ReflectionUtils.ThreadSafeDictionary<Type, IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>>(SetterValueFactory); } protected virtual string MapClrMemberNameToJsonFieldName(string clrPropertyName) { return clrPropertyName; } internal virtual ReflectionUtils.ConstructorDelegate ContructorDelegateFactory(Type key) { return ReflectionUtils.GetContructor(key, key.IsArray ? ArrayConstructorParameterTypes : EmptyTypes); } internal virtual IDictionary<string, ReflectionUtils.GetDelegate> GetterValueFactory(Type type) { IDictionary<string, ReflectionUtils.GetDelegate> dictionary = new Dictionary<string, ReflectionUtils.GetDelegate>(); foreach (PropertyInfo property in ReflectionUtils.GetProperties(type)) { if (property.CanRead) { MethodInfo getterMethodInfo = ReflectionUtils.GetGetterMethodInfo(property); if (!getterMethodInfo.IsStatic && getterMethodInfo.IsPublic) { dictionary[MapClrMemberNameToJsonFieldName(property.Name)] = ReflectionUtils.GetGetMethod(property); } } } foreach (FieldInfo field in ReflectionUtils.GetFields(type)) { if (!field.IsStatic && field.IsPublic) { dictionary[MapClrMemberNameToJsonFieldName(field.Name)] = ReflectionUtils.GetGetMethod(field); } } return dictionary; } internal virtual IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> SetterValueFactory(Type type) { IDictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> dictionary = new Dictionary<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>>(); foreach (PropertyInfo property in ReflectionUtils.GetProperties(type)) { if (property.CanWrite) { MethodInfo setterMethodInfo = ReflectionUtils.GetSetterMethodInfo(property); if (!setterMethodInfo.IsStatic && setterMethodInfo.IsPublic) { dictionary[MapClrMemberNameToJsonFieldName(property.Name)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(property.PropertyType, ReflectionUtils.GetSetMethod(property)); } } } foreach (FieldInfo field in ReflectionUtils.GetFields(type)) { if (!field.IsInitOnly && !field.IsStatic && field.IsPublic) { dictionary[MapClrMemberNameToJsonFieldName(field.Name)] = new KeyValuePair<Type, ReflectionUtils.SetDelegate>(field.FieldType, ReflectionUtils.GetSetMethod(field)); } } return dictionary; } public virtual bool TrySerializeNonPrimitiveObject(object input, out object output) { if (!TrySerializeKnownTypes(input, out output)) { return TrySerializeUnknownTypes(input, out output); } return true; } public virtual object DeserializeObject(object value, Type type) { if (type == null) { throw new ArgumentNullException("type"); } string text = value as string; if (type == typeof(Guid) && string.IsNullOrEmpty(text)) { return default(Guid); } if (value == null) { return null; } object obj = null; if (text != null) { if (text.Length != 0) { if (type == typeof(DateTime) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTime))) { return DateTime.ParseExact(text, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); } if (type == typeof(DateTimeOffset) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(DateTimeOffset))) { return DateTimeOffset.ParseExact(text, Iso8601Format, CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); } if (type == typeof(Guid) || (ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid))) { return new Guid(text); } if (type == typeof(Uri)) { if (Uri.IsWellFormedUriString(text, UriKind.RelativeOrAbsolute) && Uri.TryCreate(text, UriKind.RelativeOrAbsolute, out Uri result)) { return result; } return null; } if (type == typeof(string)) { return text; } return Convert.ChangeType(text, type, CultureInfo.InvariantCulture); } obj = ((type == typeof(Guid)) ? ((object)default(Guid)) : ((!ReflectionUtils.IsNullableType(type) || !(Nullable.GetUnderlyingType(type) == typeof(Guid))) ? text : null)); if (!ReflectionUtils.IsNullableType(type) && Nullable.GetUnderlyingType(type) == typeof(Guid)) { return text; } } else if (value is bool) { return value; } bool flag = value is long; bool flag2 = value is double; if ((flag && type == typeof(long)) || (flag2 && type == typeof(double))) { return value; } if ((flag2 && type != typeof(double)) || (flag && type != typeof(long))) { obj = ((type == typeof(int) || type == typeof(long) || type == typeof(double) || type == typeof(float) || type == typeof(bool) || type == typeof(decimal) || type == typeof(byte) || type == typeof(short)) ? Convert.ChangeType(value, type, CultureInfo.InvariantCulture) : value); } else { if (!(value is JsonArray) || !ReflectionUtils.IsTypeDictionary(type)) { if (value is IDictionary<string, object> dictionary) { IDictionary<string, object> dictionary2 = dictionary; if (ReflectionUtils.IsTypeDictionary(type)) { Type[] genericTypeArguments = ReflectionUtils.GetGenericTypeArguments(type); Type type2 = genericTypeArguments[0]; Type type3 = genericTypeArguments[1]; Type key = typeof(Dictionary<, >).MakeGenericType(type2, type3); IDictionary dictionary3 = (IDictionary)ConstructorCache[key](); foreach (KeyValuePair<string, object> item in dictionary2) { dictionary3.Add(item.Key, DeserializeObject(item.Value, type3)); } obj = dictionary3; } else if (type == typeof(object)) { obj = value; } else { ReflectionUtils.ConstructorDelegate constructorDelegate = ConstructorCache[type]; if (constructorDelegate == null) { throw new MissingMethodException($"No default constructor found for {type}"); } obj = constructorDelegate(); foreach (KeyValuePair<string, KeyValuePair<Type, ReflectionUtils.SetDelegate>> item2 in SetCache[type]) { if (dictionary2.TryGetValue(item2.Key, out var value2)) { value2 = DeserializeObject(value2, item2.Value.Key); item2.Value.Value(obj, value2); } } } } else if (value is IList<object> list) { IList<object> list2 = list; IList list3 = null; if (type.IsArray) { list3 = (IList)ConstructorCache[type](list2.Count); int num = 0; foreach (object item3 in list2) { list3[num++] = DeserializeObject(item3, type.GetElementType()); } } else if (ReflectionUtils.IsTypeGenericeCollectionInterface(type) || ReflectionUtils.IsAssignableFrom(typeof(IList), type)) { Type genericListElementType = ReflectionUtils.GetGenericListElementType(type); list3 = (IList)(ConstructorCache[type] ?? ConstructorCache[typeof(List<>).MakeGenericType(genericListElementType)])(list2.Count); foreach (object item4 in list2) { list3.Add(DeserializeObject(item4, genericListElementType)); } } obj = list3; } return obj; } JsonArray jsonArray = (JsonArray)value; Type[] genericTypeArguments2 = ReflectionUtils.GetGenericTypeArguments(type); Type type4 = genericTypeArguments2[0]; Type type5 = genericTypeArguments2[1]; Type key2 = typeof(Dictionary<, >).MakeGenericType(type4, type5); IDictionary dictionary4 = (IDictionary)ConstructorCache[key2](); foreach (JsonObject item5 in jsonArray) { dictionary4.Add(DeserializeObject(item5[0], type4), DeserializeObject(item5[1], type5)); } obj = dictionary4; } if (ReflectionUtils.IsNullableType(type)) { return ReflectionUtils.ToNullableType(obj, type); } return obj; } protected virtual object SerializeEnum(Enum p) { return Convert.ToDouble(p, CultureInfo.InvariantCulture); } protected virtual bool TrySerializeKnownTypes(object input, out object output) { bool result = true; if (input is DateTime) { output = ((DateTime)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); } else if (input is DateTimeOffset) { output = ((DateTimeOffset)input).ToUniversalTime().ToString(Iso8601Format[0], CultureInfo.InvariantCulture); } else if (input is Guid) { output = ((Guid)input).ToString("D"); } else if (input is Uri) { output = input.ToString(); } else if (input is Enum p) { output = SerializeEnum(p); } else { result = false; output = null; } return result; } protected virtual bool TrySerializeUnknownTypes(object input, out object output) { if (input == null) { throw new ArgumentNullException("input"); } output = null; Type type = input.GetType(); if (type.FullName == null) { return false; } IDictionary<string, object> dictionary = new JsonObject(); IDictionary<string, ReflectionUtils.GetDelegate> dictionary2 = GetCache[type]; foreach (KeyValuePair<string, ReflectionUtils.GetDelegate> item in dictionary2) { if (item.Value != null) { dictionary.Add(MapClrMemberNameToJsonFieldName(item.Key), item.Value(input)); } } output = dictionary; return true; } } } namespace SimpleJson.Reflection { [GeneratedCode("reflection-utils", "1.0.0")] internal class ReflectionUtils { public delegate object GetDelegate(object source); public delegate void SetDelegate(object source, object value); public delegate object ConstructorDelegate(params object[] args); public delegate TValue ThreadSafeDictionaryValueFactory<TKey, TValue>(TKey key); private static class Assigner<T> { public static T Assign(ref T left, T right) { return left = right; } } public sealed class ThreadSafeDictionary<TKey, TValue> : IDictionary<TKey, TValue>, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IEnumerable { private readonly object _lock = new object(); private readonly ThreadSafeDictionaryValueFactory<TKey, TValue> _valueFactory; private Dictionary<TKey, TValue> _dictionary; public ICollection<TKey> Keys => _dictionary.Keys; public ICollection<TValue> Values => _dictionary.Values; public TValue this[TKey key] { get { return Get(key); } set { throw new NotImplementedException(); } } public int Count => _dictionary.Count; public bool IsReadOnly { get { throw new NotImplementedException(); } } public ThreadSafeDictionary(ThreadSafeDictionaryValueFactory<TKey, TValue> valueFactory) { _valueFactory = valueFactory; } private TValue Get(TKey key) { if (_dictionary == null) { return AddValue(key); } if (!_dictionary.TryGetValue(key, out var value)) { return AddValue(key); } return value; } private TValue AddValue(TKey key) { TValue val = _valueFactory(key); lock (_lock) { if (_dictionary == null) { _dictionary = new Dictionary<TKey, TValue>(); _dictionary[key] = val; } else { if (_dictionary.TryGetValue(key, out var value)) { return value; } Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>(_dictionary); dictionary[key] = val; _dictionary = dictionary; } } return val; } public void Add(TKey key, TValue value) { throw new NotImplementedException(); } public bool ContainsKey(TKey key) { return _dictionary.ContainsKey(key); } public bool Remove(TKey key) { throw new NotImplementedException(); } public bool TryGetValue(TKey key, out TValue value) { value = this[key]; return true; } public void Add(KeyValuePair<TKey, TValue> item) { throw new NotImplementedException(); } public void Clear() { throw new NotImplementedException(); } public bool Contains(KeyValuePair<TKey, TValue> item) { throw new NotImplementedException(); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { throw new NotImplementedException(); } public bool Remove(KeyValuePair<TKey, TValue> item) { throw new NotImplementedException(); } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return _dictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _dictionary.GetEnumerator(); } } private static readonly object[] EmptyObjects = new object[0]; public static Type GetTypeInfo(Type type) { return type; } public static Attribute GetAttribute(MemberInfo info, Type type) { if (info == null || type == null || !Attribute.IsDefined(info, type)) { return null; } return Attribute.GetCustomAttribute(info, type); } public static Type GetGenericListElementType(Type type) { IEnumerable<Type> interfaces = type.GetInterfaces(); foreach (Type item in interfaces) { if (IsTypeGeneric(item) && item.GetGenericTypeDefinition() == typeof(IList<>)) { return GetGenericTypeArguments(item)[0]; } } return GetGenericTypeArguments(type)[0]; } public static Attribute GetAttribute(Type objectType, Type attributeType) { if (objectType == null || attributeType == null || !Attribute.IsDefined(objectType, attributeType)) { return null; } return Attribute.GetCustomAttribute(objectType, attributeType); } public static Type[] GetGenericTypeArguments(Type type) { return type.GetGenericArguments(); } public static bool IsTypeGeneric(Type type) { return GetTypeInfo(type).IsGenericType; } public static bool IsTypeGenericeCollectionInterface(Type type) { if (!IsTypeGeneric(type)) { return false; } Type genericTypeDefinition = type.GetGenericTypeDefinition(); if (!(genericTypeDefinition == typeof(IList<>)) && !(genericTypeDefinition == typeof(ICollection<>))) { return genericTypeDefinition == typeof(IEnumerable<>); } return true; } public static bool IsAssignableFrom(Type type1, Type type2) { return GetTypeInfo(type1).IsAssignableFrom(GetTypeInfo(type2)); } public static bool IsTypeDictionary(Type type) { if (typeof(IDictionary).IsAssignableFrom(type)) { return true; } if (!GetTypeInfo(type).IsGenericType) { return false; } Type genericTypeDefinition = type.GetGenericTypeDefinition(); return genericTypeDefinition == typeof(IDictionary<, >); } public static bool IsNullableType(Type type) { if (GetTypeInfo(type).IsGenericType) { return type.GetGenericTypeDefinition() == typeof(Nullable<>); } return false; } public static object ToNullableType(object obj, Type nullableType) { if (obj != null) { return Convert.ChangeType(obj, Nullable.GetUnderlyingType(nullableType), CultureInfo.InvariantCulture); } return null; } public static bool IsValueType(Type type) { return GetTypeInfo(type).IsValueType; } public static IEnumerable<ConstructorInfo> GetConstructors(Type type) { return type.GetConstructors(); } public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) { IEnumerable<ConstructorInfo> constructors = GetConstructors(type); foreach (ConstructorInfo item in constructors) { ParameterInfo[] parameters = item.GetParameters(); if (argsType.Length != parameters.Length) { continue; } int num = 0; bool flag = true; ParameterInfo[] parameters2 = item.GetParameters(); foreach (ParameterInfo parameterInfo in parameters2) { if (parameterInfo.ParameterType != argsType[num]) { flag = false; break; } } if (flag) { return item; } } return null; } public static IEnumerable<PropertyInfo> GetProperties(Type type) { return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static IEnumerable<FieldInfo> GetFields(Type type) { return type.GetFields(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static MethodInfo GetGetterMethodInfo(PropertyInfo propertyInfo) { return propertyInfo.GetGetMethod(nonPublic: true); } public static MethodInfo GetSetterMethodInfo(PropertyInfo propertyInfo) { return propertyInfo.GetSetMethod(nonPublic: true); } public static ConstructorDelegate GetContructor(ConstructorInfo constructorInfo) { return GetConstructorByExpression(constructorInfo); } public static ConstructorDelegate GetContructor(Type type, params Type[] argsType) { return GetConstructorByExpression(type, argsType); } public static ConstructorDelegate GetConstructorByReflection(ConstructorInfo constructorInfo) { return (object[] args) => constructorInfo.Invoke(args); } public static ConstructorDelegate GetConstructorByReflection(Type type, params Type[] argsType) { ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); if (!(constructorInfo == null)) { return GetConstructorByReflection(constructorInfo); } return null; } public static ConstructorDelegate GetConstructorByExpression(ConstructorInfo constructorInfo) { ParameterInfo[] parameters = constructorInfo.GetParameters(); ParameterExpression parameterExpression = Expression.Parameter(typeof(object[]), "args"); Expression[] array = new Expression[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { Expression index = Expression.Constant(i); Type parameterType = parameters[i].ParameterType; Expression expression = Expression.ArrayIndex(parameterExpression, index); Expression expression2 = Expression.Convert(expression, parameterType); array[i] = expression2; } NewExpression body = Expression.New(constructorInfo, array); Expression<Func<object[], object>> expression3 = Expression.Lambda<Func<object[], object>>(body, new ParameterExpression[1] { parameterExpression }); Func<object[], object> compiledLambda = expression3.Compile(); return (object[] args) => compiledLambda(args); } public static ConstructorDelegate GetConstructorByExpression(Type type, params Type[] argsType) { ConstructorInfo constructorInfo = GetConstructorInfo(type, argsType); if (!(constructorInfo == null)) { return GetConstructorByExpression(constructorInfo); } return null; } public static GetDelegate GetGetMethod(PropertyInfo propertyInfo) { return GetGetMethodByExpression(propertyInfo); } public static GetDelegate GetGetMethod(FieldInfo fieldInfo) { return GetGetMethodByExpression(fieldInfo); } public static GetDelegate GetGetMethodByReflection(PropertyInfo propertyInfo) { MethodInfo methodInfo = GetGetterMethodInfo(propertyInfo); return (object source) => methodInfo.Invoke(source, EmptyObjects); } public static GetDelegate GetGetMethodByReflection(FieldInfo fieldInfo) { return (object source) => fieldInfo.GetValue(source); } public static GetDelegate GetGetMethodByExpression(PropertyInfo propertyInfo) { MethodInfo getterMethodInfo = GetGetterMethodInfo(propertyInfo); ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance"); UnaryExpression instance = ((!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(parameterExpression, propertyInfo.DeclaringType) : Expression.Convert(parameterExpression, propertyInfo.DeclaringType)); Func<object, object> compiled = Expression.Lambda<Func<object, object>>(Expression.TypeAs(Expression.Call(instance, getterMethodInfo), typeof(object)), new ParameterExpression[1] { parameterExpression }).Compile(); return (object source) => compiled(source); } public static GetDelegate GetGetMethodByExpression(FieldInfo fieldInfo) { ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance"); MemberExpression expression = Expression.Field(Expression.Convert(parameterExpression, fieldInfo.DeclaringType), fieldInfo); GetDelegate compiled = Expression.Lambda<GetDelegate>(Expression.Convert(expression, typeof(object)), new ParameterExpression[1] { parameterExpression }).Compile(); return (object source) => compiled(source); } public static SetDelegate GetSetMethod(PropertyInfo propertyInfo) { return GetSetMethodByExpression(propertyInfo); } public static SetDelegate GetSetMethod(FieldInfo fieldInfo) { return GetSetMethodByExpression(fieldInfo); } public static SetDelegate GetSetMethodByReflection(PropertyInfo propertyInfo) { MethodInfo methodInfo = GetSetterMethodInfo(propertyInfo); return delegate(object source, object value) { methodInfo.Invoke(source, new object[1] { value }); }; } public static SetDelegate GetSetMethodByReflection(FieldInfo fieldInfo) { return delegate(object source, object value) { fieldInfo.SetValue(source, value); }; } public static SetDelegate GetSetMethodByExpression(PropertyInfo propertyInfo) { MethodInfo setterMethodInfo = GetSetterMethodInfo(propertyInfo); ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object), "value"); UnaryExpression instance = ((!IsValueType(propertyInfo.DeclaringType)) ? Expression.TypeAs(parameterExpression, propertyInfo.DeclaringType) : Expression.Convert(parameterExpression, propertyInfo.DeclaringType)); UnaryExpression unaryExpression = ((!IsValueType(propertyInfo.PropertyType)) ? Expression.TypeAs(parameterExpression2, propertyInfo.PropertyType) : Expression.Convert(parameterExpression2, propertyInfo.PropertyType)); Action<object, object> compiled = Expression.Lambda<Action<object, object>>(Expression.Call(instance, setterMethodInfo, unaryExpression), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile(); return delegate(object source, object val) { compiled(source, val); }; } public static SetDelegate GetSetMethodByExpression(FieldInfo fieldInfo) { ParameterExpression parameterExpression = Expression.Parameter(typeof(object), "instance"); ParameterExpression parameterExpression2 = Expression.Parameter(typeof(object), "value"); Action<object, object> compiled = Expression.Lambda<Action<object, object>>(Assign(Expression.Field(Expression.Convert(parameterExpression, fieldInfo.DeclaringType), fieldInfo), Expression.Convert(parameterExpression2, fieldInfo.FieldType)), new ParameterExpression[2] { parameterExpression, parameterExpression2 }).Compile(); return delegate(object source, object val) { compiled(source, val); }; } public static BinaryExpression Assign(Expression left, Expression right) { MethodInfo method = typeof(Assigner<>).MakeGenericType(left.Type).GetMethod("Assign"); return Expression.Add(left, right, method); } } } namespace Jotunn { public static class ArrayExtensions { public static T[] Populate<T>(this T[] arr, T value) { for (int i = 0; i < arr.Length; i++) { arr[i] = value; } return arr; } } public static class ConfigEntryBaseExtension { public static bool IsVisible(this ConfigEntryBase configurationEntry) { ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes(); ConfigDescription description = configurationEntry.Description; configurationManagerAttributes.SetFromAttributes((description != null) ? description.Tags : null); return configurationManagerAttributes.Browsable != false; } public static bool IsSyncable(this ConfigEntryBase configurationEntry) { if (configurationEntry.Description.Tags.FirstOrDefault((object x) => x is ConfigurationManagerAttributes) is ConfigurationManagerAttributes configurationManagerAttributes) { return configurationManagerAttributes.IsAdminOnly; } return false; } public static string GetBoundButtonName(this ConfigEntryBase configurationEntry) { if (configurationEntry == null) { throw new ArgumentNullException("configurationEntry"); } if (configurationEntry.SettingType != typeof(KeyCode) && configurationEntry.SettingType != typeof(KeyboardShortcut) && configurationEntry.SettingType != typeof(InputManager.GamepadButton)) { return null; } if (!InputManager.ButtonToConfigDict.TryGetValue(configurationEntry, out var value)) { return null; } return value.Name; } public static ButtonConfig GetButtonConfig(this ConfigEntryBase configurationEntry) { if (configurationEntry == null) { throw new ArgumentNullException("configurationEntry"); } if (configurationEntry.SettingType != typeof(KeyCode) && configurationEntry.SettingType != typeof(KeyboardShortcut) && configurationEntry.SettingType != typeof(InputManager.GamepadButton)) { return null; } InputManager.ButtonToConfigDict.TryGetValue(configurationEntry, out var value); return value; } internal static object GetLocalValue(this ConfigEntryBase configurationEntry) { if (SynchronizationManager.Instance.localValues.TryGetValue(configurationEntry, out var value)) { return value; } return null; } internal static void SetLocalValue(this ConfigEntryBase configurationEntry, object value) { SynchronizationManager.Instance.localValues[configurationEntry] = value; } internal static ConfigurationManagerAttributes GetConfigurationManagerAttributes(this ConfigEntryBase configEntry) { return (ConfigurationManagerAttributes)configEntry.Description.Tags.FirstOrDefault((object x) => x is ConfigurationManagerAttributes); } } internal static class EventExtensions { public static void SafeInvoke(this Action events) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)invocationList[i]; try { action(); } catch (Exception ex) { Logger.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1>(this Action<TArg1> events, TArg1 arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1> action = (Action<TArg1>)invocationList[i]; try { action(arg1); } catch (Exception ex) { Logger.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TArg1, TArg2>(this Action<TArg1, TArg2> events, TArg1 arg1, TArg2 arg2) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action<TArg1, TArg2> action = (Action<TArg1, TArg2>)invocationList[i]; try { action(arg1, arg2); } catch (Exception ex) { Logger.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {action.Method.DeclaringType.Name}.{action.Method.Name}:\n{ex}"); } } } public static void SafeInvoke<TEventArg>(this EventHandler<TEventArg> events, object sender, TEventArg arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler<TEventArg> eventHandler = (EventHandler<TEventArg>)invocationList[i]; try { eventHandler(sender, arg1); } catch (Exception ex) { Logger.LogWarning($"Exception thrown at event {new StackFrame(1).GetMethod().Name} in {eventHandler.Method.DeclaringType.Name}.{eventHandler.Method.Name}:\n{ex}"); } } } } public static class ExposedGameObjectExtension { public static GameObject OrNull(this GameObject @this) { if (!Object.op_Implicit((Object)(object)@this)) { return null; } return @this; } public static T OrNull<T>(this T @this) where T : Object { if (!Object.op_Implicit((Object)(object)@this)) { return default(T); } return @this; } public static T GetOrAddComponent<T>(this GameObject gameObject) where T : Component { T result = default(T); if (!gameObject.TryGetComponent<T>(ref result)) { return gameObject.AddComponent<T>(); } return result; } public static Component AddComponentCopy<T>(this GameObject gameObject, T duplicate) where T : Component { Component val = gameObject.AddComponent(((object)duplicate).GetType()); PropertyInfo[] properties = ((object)duplicate).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { switch (propertyInfo.Name) { case "mesh": if (duplicate is MeshFilter) { continue; } break; case "material": case "materials": if (duplicate is Renderer) { continue; } break; case "bounds": if (duplicate is Renderer) { continue; } break; case "name": case "rayTracingMode": case "tag": continue; } if (propertyInfo.CanWrite && propertyInfo.GetMethod != null) { propertyInfo.SetValue(val, propertyInfo.GetValue(duplicate)); } } FieldInfo[] fields = ((object)duplicate).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (!(fieldInfo.Name == "rayTracingMode")) { fieldInfo.SetValue(val, fieldInfo.GetValue(duplicate)); } } return val; } public static bool HasAnyComponent(this GameObject gameObject, params Type[] components) { foreach (Type type in components) { if (Object.op_Implicit((Object)(object)gameObject.GetComponent(type))) { return true; } } return false; } public static bool HasAnyComponent(this GameObject gameObject, params string[] componentNames) { foreach (string text in componentNames) { if (Object.op_Implicit((Object)(object)gameObject.GetComponent(text))) { return true; } } return false; } public static bool HasAllComponents(this GameObject gameObject, params string[] componentNames) { foreach (string text in componentNames) { if (!Object.op_Implicit((Object)(object)gameObject.GetComponent(text))) { return false; } } return true; } public static bool HasAllComponents(this GameObject gameObject, params Type[] components) { foreach (Type type in components) { if (!Object.op_Implicit((Object)(object)gameObject.GetComponent(type))) { return false; } } return true; } public static bool HasAnyComponentInChildren(this GameObject gameObject, bool includeInactive = false, params Type[] components) { foreach (Type type in components) { if (Object.op_Implicit((Object)(object)gameObject.GetComponentInChildren(type, includeInactive))) { return true; } } return false; } public static Transform FindDeepChild(this GameObject gameObject, string childName, IterativeSearchType searchType = 1) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return gameObject.transform.FindDeepChild(childName, searchType); } public static Transform FindDeepChild(this GameObject gameObject, IEnumerable<string> childNames, IterativeSearchType searchType = 1) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) Transform val = gameObject.transform; foreach (string childName in childNames) { val = val.FindDeepChild(childName, searchType); if (!Object.op_Implicit((Object)(object)val)) { return null; } } return val; } } internal static class GameObjectGUIExtension { internal static GameObject SetToTextHeight(this GameObject go) { go.GetComponent<RectTransform>().SetSizeWithCurrentAnchors((Axis)1, go.GetComponentInChildren<Text>().preferredHeight + 3f); return go; } internal static GameObject SetUpperLeft(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0f, 1f); component.anchorMin = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetMiddleLeft(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0f, 0.5f); component.anchorMin = new Vector2(0f, 0.5f); component.pivot = new Vector2(0f, 0.5f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetBottomLeft(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0f, 0f); component.anchorMin = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetUpperRight(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(1f, 1f); component.anchorMin = new Vector2(1f, 1f); component.pivot = new Vector2(1f, 1f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetMiddleRight(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(1f, 0.5f); component.anchorMin = new Vector2(1f, 0.5f); component.pivot = new Vector2(1f, 0.5f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetBottomRight(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(1f, 0f); component.anchorMin = new Vector2(1f, 0f); component.pivot = new Vector2(1f, 0f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetUpperCenter(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0.5f, 1f); component.anchorMin = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetMiddleCenter(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0.5f, 0.5f); component.anchorMin = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetBottomCenter(this GameObject go) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0051: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); component.anchorMax = new Vector2(0.5f, 0f); component.anchorMin = new Vector2(0.5f, 0f); component.pivot = new Vector2(0.5f, 0f); component.anchoredPosition = new Vector2(0f, 0f); return go; } internal static GameObject SetSize(this GameObject go, float width, float height) { RectTransform component = go.GetComponent<RectTransform>(); component.SetSizeWithCurrentAnchors((Axis)0, width); component.SetSizeWithCurrentAnchors((Axis)1, height); return go; } internal static GameObject SetWidth(this GameObject go, float width) { RectTransform component = go.GetComponent<RectTransform>(); component.SetSizeWithCurrentAnchors((Axis)0, width); return go; } internal static GameObject SetHeight(this GameObject go, float height) { RectTransform component = go.GetComponent<RectTransform>(); component.SetSizeWithCurrentAnchors((Axis)1, height); return go; } internal static float GetWidth(this GameObject go) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); Rect rect = component.rect; return ((Rect)(ref rect)).width; } internal static float GetHeight(this GameObject go) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); Rect rect = component.rect; return ((Rect)(ref rect)).height; } internal static float GetTextHeight(this GameObject go) { return go.GetComponent<Text>().preferredHeight; } internal static GameObject SetText(this GameObject go, string text) { Text component = go.GetComponent<Text>(); if ((Object)(object)component != (Object)null) { component.text = text; } TMP_Text component2 = go.GetComponent<TMP_Text>(); if ((Object)(object)component2 != (Object)null) { component2.text = text; } return go; } } public static class GameObjectExtension { public static bool IsValid(this GameObject self) { string text = ((Object)self).name; if (text.IndexOf('(') > 0) { text = text.Substring(((Object)self).name.IndexOf('(')).Trim(); } if (string.IsNullOrEmpty(text)) { Logger.LogError("GameObject must have a name!"); return false; } if (Object.op_Implicit((Object)(object)self.GetComponent<ZNetView>()) && ((Object)self).name.IndexOfAny(new char[2] { ')', ' ' }) > 0) { Logger.LogError("GameObject name '" + ((Object)self).name + "' must not contain parenthesis or spaces!"); return false; } return true; } } public static class ItemDropExtension { public static string TokenName(this ItemDrop self) { return self.m_itemData.m_shared.m_name; } } public static class ItemDataExtension { public static string TokenName(this ItemData self) { return self.m_shared.m_name; } } public static class RecipeExtension { public static bool IsValid(this Recipe self) { try { string text = ((Object)self).name; if (text.IndexOf('(') > 0) { text = text.Substring(((Object)self).name.IndexOf('(')).Trim(); } if (string.IsNullOrEmpty(text)) { throw new Exception("Recipe must have a name !"); } return true; } catch (Exception data) { Logger.LogError(data); return false; } } } public static class PieceExtension { public static string TokenName(this Piece self) { return self.m_name; } } public static class StatusEffectExtension { public static string TokenName(this StatusEffect self) { return self.m_name; } public static bool IsValid(this StatusEffect self) { try { string text = ((Object)self).name; if (text.IndexOf('(') > 0) { text = text.Substring(((Object)self).name.IndexOf('(')).Trim(); } if (string.IsNullOrEmpty(text)) { throw new Exception("StatusEffect must have a name !"); } return true; } catch (Exception data) { Logger.LogError(data); return false; } } } public static class PrefabExtension { public static void FixReferences(this object objectToFix) { MockResolveFailure.MockResolveFailures.Clear(); MockManager.FixReferences(objectToFix, 0); Object val = (Object)((objectToFix is Object) ? objectToFix : null); string prefabName = (Object.op_Implicit(val) ? val.name : objectToFix.ToString()); MockResolveFailure.PrintMockResolveFailures(prefabName); } public static void FixReferences(this GameObject gameObject) { MockResolveFailure.MockResolveFailures.Clear(); gameObject.FixReferencesInternal(recursive: false); string prefabName = (Object.op_Implicit((Object)(object)gameObject) ? ((Object)gameObject).name : string.Empty); MockResolveFailure.PrintMockResolveFailures(prefabName); } public static void FixReferences(this GameObject gameObject, bool recursive) { MockResolveFailure.MockResolveFailures.Clear(); gameObject.FixReferencesInternal(recursive); string prefabName = (Object.op_Implicit((Object)(object)gameObject) ? ((Object)gameObject).name : string.Empty); MockResolveFailure.PrintMockResolveFailures(prefabName); } private static void FixReferencesInternal(this GameObject gameObject, bool recursive) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown Component[] components = gameObject.GetComponents<Component>(); foreach (Component val in components) { if (!(val is Transform)) { MockManager.FixReferences(val, 0); } } if (!recursive) { return; } List<Tuple<Transform, GameObject>> list = new List<Tuple<Transform, GameObject>>(); foreach (Transform item in gameObject.transform) { Transform val2 = item; GameObject realPrefabFromMock = MockManager.GetRealPrefabFromMock<GameObject>((Object)(object)((Component)val2).gameObject); if (Object.op_Implicit((Object)(object)realPrefabFromMock)) { list.Add(new Tuple<Transform, GameObject>(val2, realPrefabFromMock)); } else { ((Component)val2).gameObject.FixReferencesInternal(recursive: true); } } foreach (Tuple<Transform, GameObject> item2 in list) { MockManager.ReplaceMockGameObject(item2.Item1, item2.Item2, gameObject); } } public static void CloneFields(this GameObject gameObject, GameObject objectToClone) { Dictionary<FieldInfo, object> dictionary = new Dictionary<FieldInfo, object>(); Component[] componentsInChildren = objectToClone.GetComponentsInChildren<Component>(); Component[] array = componentsInChildren; foreach (Component val in array) { FieldInfo[] fields = ((object)val).GetType().GetFields((BindingFlags)(-1)); foreach (FieldInfo fieldInfo in fields) { if (!fieldInfo.IsLiteral && !fieldInfo.IsInitOnly) { dictionary.Add(fieldInfo, fieldInfo.GetValue(val)); } } if (!Object.op_Implicit((Object)(object)gameObject.GetComponent(((object)val).GetType()))) { gameObject.AddComponent(((object)val).GetType()); } } Component[] componentsInChildren2 = gameObject.GetComponentsInChildren<Component>(); Component[] array2 = componentsInChildren2; foreach (Component val2 in array2) { FieldInfo[] fields2 = ((object)val2).GetType().GetFields((BindingFlags)(-1)); foreach (FieldInfo fieldInfo2 in fields2) { if (dictionary.TryGetValue(fieldInfo2, out var value)) { fieldInfo2.SetValue(val2, value); } } } } } internal static class ObjectExtension { public static string GetObjectString(this object obj) { if (obj == null) { return "null"; } string text = $"{obj}"; Type type = obj.GetType(); IEnumerable<FieldInfo> enumerable = from f in type.GetFields() where f.IsPublic select f; foreach (FieldInfo item in enumerable) { object value = item.GetValue(obj); string text2 = ((value == null) ? "null" : value.ToString()); text = text + "\n " + item.Name + ": " + text2; } PropertyInfo[] properties = type.GetProperties(); PropertyInfo[] array = properties; foreach (PropertyInfo propertyInfo in array) { object value2 = propertyInfo.GetValue(obj, null); string text3 = ((value2 == null) ? "null" : value2.ToString()); text = text + "\n " + propertyInfo.Name + ": " + text3; } return text; } } public static class RectTransformExtensions { public static bool Overlaps(this RectTransform a, RectTransform b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Rect val = a.WorldRect(); return ((Rect)(ref val)).Overlaps(b.WorldRect()); } public static bool Overlaps(this RectTransform a, RectTransform b, bool allowInverse) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) Rect val = a.WorldRect(); return ((Rect)(ref val)).Overlaps(b.WorldRect(), allowInverse); } public static Rect WorldRect(this RectTransform rectTransform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector2 sizeDelta = rectTransform.sizeDelta; float num = sizeDelta.x * ((Transform)rectTransform).lossyScale.x; float num2 = sizeDelta.y * ((Transform)rectTransform).lossyScale.y; Vector3 position = ((Transform)rectTransform).position; return new Rect(position.x - num / 2f, position.y - num2 / 2f, num, num2); } } public static class ZNetExtension { public enum ZNetInstanceType { Local, Client, Server } public static bool IsLocalInstance(this ZNet znet) { if (znet.IsServer()) { return !znet.IsDedicated(); } return false; } public static bool IsClientInstance(this ZNet znet) { if (!znet.IsServer()) { return !znet.IsDedicated(); } return false; } public static bool IsServerInstance(this ZNet znet) { if (znet.IsServer()) { return znet.IsDedicated(); } return false; } public static ZNetInstanceType GetInstanceType(this ZNet znet) { if (znet.IsLocalInstance()) { return ZNetInstanceType.Local; } if (znet.IsClientInstance()) { return ZNetInstanceType.Client; } return ZNetInstanceType.Server; } public static bool IsAdmin(this ZNet znet, long uid) { if (!Object.op_Implicit((Object)(object)znet)) { Logger.LogWarning("IsAdmin check failed: ZNet is null"); return false; } if (znet.m_adminList == null) { Logger.LogWarning("IsAdmin check failed: admin list is only available on the server"); return false; } ZNetPeer peer = znet.GetPeer(uid); if (peer == null) { Logger.LogWarning($"IsAdmin check failed: peer not found with id {uid}"); return false; } string hostName = peer.m_socket.GetHostName(); if (!string.IsNullOrEmpty(hostName)) { return znet.ListContainsId(znet.m_adminList, hostName); } return false; } } internal interface IManager { void Init(); } public class Logger { public static bool ShowDate = false; private static Logger instance = new Logger(); private readonly Dictionary<string, ManualLogSource> logger = new Dictionary<string, ManualLogSource>(); internal static void Destroy() { LogDebug("Destroying Logger"); foreach (KeyValuePair<string, ManualLogSource> item in instance.logger) { Logger.Sources.Remove((ILogSource)(object)item.Value); } instance.logger.Clear(); } private ManualLogSource GetLogger() { Type declaringType = new StackFrame(3).GetMethod().DeclaringType; if (!logger.TryGetValue(declaringType.FullName, out var value)) { value = Logger.CreateLogSource(declaringType.FullName); logger.Add(declaringType.FullName, value); } return value; } private static void Log(LogLevel level, BepInPlugin sourceMod, object data) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) string text = string.Empty; if (ShowDate) { text = text + "[" + DateTime.Now.ToString(DateTimeFormatInfo.InvariantInfo) + "] "; } if (sourceMod != null) { text = text + "[" + sourceMod.Name + "] "; } instance.GetLogger().Log(level, (object)$"{text}{data}"); } public static void LogFatal(object data) { Log((LogLevel)1, null, data); } public static void LogFatal(BepInPlugin sourceMod, object data) { Log((LogLevel)1, sourceMod, data); } public static void LogError(object data) { Log((LogLevel)2, null, data); } public static void LogError(BepInPlugin sourceMod, object data) { Log((LogLevel)2, sourceMod, data); } public static void LogWarning(object data) { Log((LogLevel)4, null, data); } public static void LogWarning(BepInPlugin sourceMod, object data) { Log((LogLevel)4, sourceMod, data); } public static void LogMessage(object data) { Log((LogLevel)8, null, data); } public static void LogMessage(BepInPlugin sourceMod, object data) { Log((LogLevel)8, sourceMod, data); } public static void LogInfo(object data) { Log((LogLevel)16, null, data); } public static void LogInfo(BepInPlugin sourceMod, object data) { Log((LogLevel)16, sourceMod, data); } public static void LogDebug(object data) { Log((LogLevel)32, null, data); } public static void LogDebug(BepInPlugin sourceMod, object data) { Log((LogLevel)32, sourceMod, data); } } [BepInPlugin("com.jotunn.jotunn", "Jotunn", "2.28.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(CompatibilityLevel.VersionCheckOnly, VersionStrictness.Patch)] public class Main : BaseUnityPlugin { public const string Version = "2.28.0"; public const string ModName = "Jotunn"; public const string ModGuid = "com.jotunn.jotunn"; internal static Main Instance; internal static Harmony Harmony = new Harmony("com.jotunn.jotunn"); private static GameObject rootObject; internal static GameObject RootObject => GetRootObject(); private void Awake() { Instance = this; GetRootObject(); ModCompatibility.Init(); ((IManager)SynchronizationManager.Instance).Init(); Runtime.MakeAllAssetsLoadable(); Game.isModded = true; } private void Start() { PatchInit.InitializePatches(); AutomaticLocalizationsLoading.Init(); } private void OnApplicationQuit() { AssetBundle.UnloadAllAssetBundles(false); } private static GameObject GetRootObject() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)rootObject)) { return rootObject; } rootObject = new GameObject("_JotunnRoot"); Object.DontDestroyOnLoad((Object)(object)rootObject); return rootObject; } internal static void LogInit(string module) { Logger.LogInfo("Initializing " + module); if (!Object.op_Implicit((Object)(object)Instance)) { string data = module + " was accessed before Jotunn Awake, this can cause unexpected behaviour. Please make sure to add `[BepInDependency(Jotunn.Main.ModGuid)]` next to your BaseUnityPlugin"; Logger.LogWarning(BepInExUtils.GetSourceModMetadata(), data); } } } internal class ClassMember { private static readonly Dictionary<Type, ClassMember> CachedClassMembers = new Dictionary<Type, ClassMember>(); public List<MemberBase> Members { get; private set; } = new List<MemberBase>(); public Type Type { get; private set; } private ClassMember(Type type, IEnumerable<FieldInfo> fieldInfos, IEnumerable<PropertyInfo> propertyInfos) { Type = type; foreach (FieldInfo fieldInfo in fieldInfos) { AddMember(new FieldMember(fieldInfo)); } foreach (PropertyInfo propertyInfo in propertyInfos) { AddMember(new PropertyMember(propertyInfo)); } } private void AddMember(MemberBase member) { if (member.IsClass && !(member.MemberType == typeof(string)) && (!(member.EnumeratedType != null) || (member.IsEnumeratedClass && !(member.EnumeratedType == typeof(string)))) && !member.HasCustomAttribute<NonSerializedAttribute>()) { Members.Add(member); } } private static T[] GetMembersFromType<T>(Type type, Func<Type, T[]> getMembers) { T[] array = getMembers(type); Type baseType = type.BaseType; while (baseType != null) { T[] second = getMembers(baseType); array = array.Union(second).ToArray(); baseType = baseType.BaseType; } return array; } public static ClassMember GetClassMember(Type type) { if (CachedClassMembers.TryGetValue(type, out var value)) { return value; } FieldInfo[] membersFromType = GetMembersFromType(type, (Type t) => t.GetFields(~BindingFlags.Static)); PropertyInfo[] membersFromType2 = GetMembersFromType(type, (Type t) => t.GetProperties(~BindingFlags.Static)); value = new ClassMember(type, membersFromType, membersFromType2); CachedClassMembers[type] = value; return value; } } internal class FieldMember : MemberBase { private readonly FieldInfo fieldInfo; public FieldMember(FieldInfo fieldInfo) { this.fieldInfo = fieldInfo; base.MemberType = fieldInfo.FieldType; base.IsUnityObject = base.MemberType.IsSameOrSubclass(typeof(Object)); base.IsClass = base.MemberType.IsClass; base.HasGetMethod = true; base.HasSetMethod = true; base.EnumeratedType = base.MemberType.GetEnumeratedType(); base.IsEnumerableOfUnityObjects = base.EnumeratedType?.IsSameOrSubclass(typeof(Object)) ?? false; base.IsEnumeratedClass = base.EnumeratedType?.IsClass ?? false; } public override object GetValue(object obj) { try { return fieldInfo.GetValue(obj); } catch { return null; } } public override void SetValue(object obj, object value) { fieldInfo.SetValue(obj, value); } public override bool HasCustomAttribute<T>() { return fieldInfo.GetCustomAttribute<T>() != null; } } internal abstract class MemberBase { public bool HasGetMethod { get; protected set; } public bool HasSetMethod { get; protected set; } public Type MemberType { get; protected set; } public Type EnumeratedType { get; protected set; } public bool IsUnityObject { get; protected set; } public bool IsClass { get; protected set; } public bool IsEnumerableOfUnityObjects { get; protected set; } public bool IsEnumeratedClass { get; protected set; } public abstract object GetValue(object obj); public abstract void SetValue(object obj, object value); public abstract bool HasCustomAttribute<T>() where T : Attribute; } public class MockResolveFailure { public static List<MockResolveFailure> MockResolveFailures { get; } = new List<MockResolveFailure>(); public string Message { get; private set; } public string FailedMockName { get; private set; } public string FailedMockPath { get; private set; } public Type MockType { get; private set; } public MockResolveFailure(string message, string failedMockName, string failedMockPath, Type mockType) { Message = message; FailedMockName = failedMockName; FailedMockPath = failedMockPath; MockType = mockType; } public MockResolveFailure(string message, string failedMockName, IEnumerable<string> failedMockPath, Type mockType) { Message = message; FailedMockName = failedMockName; FailedMockPath = string.Join<string>("->", failedMockPath); MockType = mockType; } private string ConstructMessage() { if (string.IsNullOrEmpty(FailedMockPath)) { return ("Mock '" + FailedMockName + "' " + MockType.Name + " could not be resolved. " + Message).Trim(); } return ("Mock " + MockType.Name + " at '" + FailedMockName + "' with child path '" + FailedMockPath + "' could not be resolved. " + Message).Trim(); } public static void PrintMockResolveFailures(string prefabName) { if (MockResolveFailures.Count == 0) { return; } BepInPlugin sourceMod = ModQuery.GetPrefab(prefabName)?.SourceMod; int num = Math.Min(5, MockResolveFailures.Count); string arg = (string.IsNullOrEmpty(prefabName) ? "" : ("for '" + prefabName + "'")); string arg2 = ((MockResolveFailures.Count > num) ? $"(logging first {num} issues)" : ""); Logger.LogWarning(sourceMod, $"{MockResolveFailures.Count} mocks {arg} could not be resolved. {arg2}".Replace(" ", " ").Trim()); foreach (MockResolveFailure item in MockResolveFailures.GetRange(0, num)) { Logger.LogWarning(sourceMod, item.ConstructMessage()); } } } internal class PropertyMember : MemberBase { private readonly PropertyInfo propertyInfo; public PropertyMember(PropertyInfo propertyInfo) { this.propertyInfo = propertyInfo; base.MemberType = propertyInfo.PropertyType; base.IsUnityObject = base.MemberType.IsSameOrSubclass(typeof(Object)); base.IsClass = base.MemberType.IsClass; base.HasGetMethod = propertyInfo.GetIndexParameters().Length == 0 && propertyInfo.GetMethod != null; base.HasSetMethod = propertyInfo.SetMethod != null; base.EnumeratedType = base.MemberType.GetEnumeratedType(); base.IsEnumerableOfUnityObjects = base.EnumeratedType?.IsSameOrSubclass(typeof(Object)) ?? false; base.IsEnumeratedClass = base.EnumeratedType?.IsClass ?? false; } public override object GetValue(object obj) { try { return propertyInfo.GetValue(obj); } catch { return null; } } public override void SetValue(object obj, object value) { propertyInfo.SetValue(obj, value); } public override bool HasCustomAttribute<T>() { return propertyInfo.GetCustomAttribute<T>() != null; } } } namespace Jotunn.Utils { public static class AssetUtils { public const char AssetBundlePathSeparator = '$'; private static MethodInfo LoadImageMethod { get; } = AccessTools.Method(typeof(ImageConversion), "LoadImage", new Type[2] { typeof(Texture2D), typeof(byte[]) }, (Type[])null); public static Texture2D LoadTexture(string texturePath, bool relativePath = true) { string text = texturePath; if (relativePath) { text = Path.Combine(Paths.PluginPath, texturePath); } if (!File.Exists(text)) { return null; } if (!text.EndsWith(".png") && !text.EndsWith(".jpg")) { throw new Exception("LoadTexture can only load png or jpg textures"); } byte[] data = File.ReadAllBytes(text); return LoadImage(data); } public static Texture2D LoadImage(byte[] data) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown Texture2D val = new Texture2D(2, 2); if (!LoadImage(val, data)) { return null; } return val; } public static bool LoadImage(Texture2D texture, byte[] data) { return (bool)LoadImageMethod.Invoke(null, new object[2] { texture, data }); } public static Text