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.29.1.0")] [assembly: AssemblyInformationalVersion("2.29.1+ea3b5ce75055888526cf07a8897ba6bbceac4772")] [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.29.1.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 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 ObjToStr; public Func 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 = new meshStruct { 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 list = new List(); 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 { 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, ICollection>, IEnumerable>, IEnumerable { private readonly Dictionary _members; public object this[int index] => GetAtIndex(_members, index); public ICollection Keys => _members.Keys; public ICollection 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(); } public JsonObject(IEqualityComparer comparer) { _members = new Dictionary(comparer); } internal static object GetAtIndex(IDictionary obj, int index) { if (obj == null) { throw new ArgumentNullException("obj"); } if (index >= obj.Count) { throw new ArgumentOutOfRangeException("index"); } int num = 0; foreach (KeyValuePair 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 item) { _members.Add(item.Key, item.Value); } public void Clear() { _members.Clear(); } public bool Contains(KeyValuePair item) { if (_members.ContainsKey(item.Key)) { return _members[item.Key] == item.Value; } return false; } public void CopyTo(KeyValuePair[] array, int arrayIndex) { if (array == null) { throw new ArgumentNullException("array"); } int num = Count; using IEnumerator> enumerator = GetEnumerator(); while (enumerator.MoveNext()) { KeyValuePair current = enumerator.Current; array[arrayIndex++] = current; if (--num <= 0) { break; } } } public bool Remove(KeyValuePair item) { return _members.Remove(item.Key); } public IEnumerator> 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(string json, IJsonSerializerStrategy jsonSerializerStrategy) { return (T)DeserializeObject(json, typeof(T), jsonSerializerStrategy); } public static T DeserializeObject(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 ParseObject(char[] json, ref int index, ref bool success) { IDictionary 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 dictionary) { flag = SerializeObject(jsonSerializerStrategy, dictionary.Keys, dictionary.Values, builder); } else if (value is IDictionary 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 ConstructorCache; internal IDictionary> GetCache; internal IDictionary>> 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(ContructorDelegateFactory); GetCache = new ReflectionUtils.ThreadSafeDictionary>(GetterValueFactory); SetCache = new ReflectionUtils.ThreadSafeDictionary>>(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 GetterValueFactory(Type type) { IDictionary dictionary = new Dictionary(); 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> SetterValueFactory(Type type) { IDictionary> dictionary = new Dictionary>(); 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(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(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 dictionary) { IDictionary 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 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> 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 list) { IList 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 dictionary = new JsonObject(); IDictionary dictionary2 = GetCache[type]; foreach (KeyValuePair 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 key); private static class Assigner { public static T Assign(ref T left, T right) { return left = right; } } public sealed class ThreadSafeDictionary : IDictionary, ICollection>, IEnumerable>, IEnumerable { private readonly object _lock = new object(); private readonly ThreadSafeDictionaryValueFactory _valueFactory; private Dictionary _dictionary; public ICollection Keys => _dictionary.Keys; public ICollection 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 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(); _dictionary[key] = val; } else { if (_dictionary.TryGetValue(key, out var value)) { return value; } Dictionary dictionary = new Dictionary(_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 item) { throw new NotImplementedException(); } public void Clear() { throw new NotImplementedException(); } public bool Contains(KeyValuePair item) { throw new NotImplementedException(); } public void CopyTo(KeyValuePair[] array, int arrayIndex) { throw new NotImplementedException(); } public bool Remove(KeyValuePair item) { throw new NotImplementedException(); } public IEnumerator> 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 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 GetConstructors(Type type) { return type.GetConstructors(); } public static ConstructorInfo GetConstructorInfo(Type type, params Type[] argsType) { IEnumerable 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 GetProperties(Type type) { return type.GetProperties(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } public static IEnumerable 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> expression3 = Expression.Lambda>(body, new ParameterExpression[1] { parameterExpression }); Func 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 compiled = Expression.Lambda>(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(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 compiled = Expression.Lambda>(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 compiled = Expression.Lambda>(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(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(this Action events, TArg1 arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)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(this Action events, TArg1 arg1, TArg2 arg2) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { Action action = (Action)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(this EventHandler events, object sender, TEventArg arg1) { if (events == null) { return; } Delegate[] invocationList = events.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { EventHandler eventHandler = (EventHandler)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(this T @this) where T : Object { if (!Object.op_Implicit((Object)(object)@this)) { return default(T); } return @this; } public static T GetOrAddComponent(this GameObject gameObject) where T : Component { T result = default(T); if (!gameObject.TryGetComponent(ref result)) { return gameObject.AddComponent(); } return result; } public static Component AddComponentCopy(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 = (IterativeSearchType)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 childNames, IterativeSearchType searchType = (IterativeSearchType)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().SetSizeWithCurrentAnchors((Axis)1, go.GetComponentInChildren().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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); component.SetSizeWithCurrentAnchors((Axis)0, width); return go; } internal static GameObject SetHeight(this GameObject go, float height) { RectTransform component = go.GetComponent(); 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(); 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(); Rect rect = component.rect; return ((Rect)(ref rect)).height; } internal static float GetTextHeight(this GameObject go) { return go.GetComponent().preferredHeight; } internal static GameObject SetText(this GameObject go, string text) { Text component = go.GetComponent(); if ((Object)(object)component != (Object)null) { component.text = text; } TMP_Text component2 = go.GetComponent(); 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()) && ((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(); foreach (Component val in components) { if (!(val is Transform)) { MockManager.FixReferences(val, 0); } } if (!recursive) { return; } List> list = new List>(); foreach (Transform item in gameObject.transform) { Transform val2 = item; GameObject realPrefabFromMock = MockManager.GetRealPrefabFromMock((Object)(object)((Component)val2).gameObject); if (Object.op_Implicit((Object)(object)realPrefabFromMock)) { list.Add(new Tuple(val2, realPrefabFromMock)); } else { ((Component)val2).gameObject.FixReferencesInternal(recursive: true); } } foreach (Tuple item2 in list) { MockManager.ReplaceMockGameObject(item2.Item1, item2.Item2, gameObject); } } public static void CloneFields(this GameObject gameObject, GameObject objectToClone) { Dictionary dictionary = new Dictionary(); Component[] componentsInChildren = objectToClone.GetComponentsInChildren(); 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[] 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 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 logger = new Dictionary(); internal static void Destroy() { LogDebug("Destroying Logger"); foreach (KeyValuePair 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.29.1")] [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.29.1"; 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 CachedClassMembers = new Dictionary(); public List Members { get; private set; } = new List(); public Type Type { get; private set; } private ClassMember(Type type, IEnumerable fieldInfos, IEnumerable 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()) { Members.Add(member); } } private static T[] GetMembersFromType(Type type, Func 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() { return fieldInfo.GetCustomAttribute() != 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() where T : Attribute; } public class MockResolveFailure { public static List MockResolveFailures { get; } = new List(); 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 failedMockPath, Type mockType) { Message = message; FailedMockName = failedMockName; FailedMockPath = string.Join("->", 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() { return propertyInfo.GetCustomAttribute() != 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 Texture2D DuplicateTexture(Texture2D texture, Rect textureRect) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)texture)) { return null; } int num = (int)((Rect)(ref textureRect)).width; int num2 = (int)((Rect)(ref textureRect)).height; int num3 = (int)((Rect)(ref textureRect)).x; int num4 = (int)((Rect)(ref textureRect)).y; RenderTexture active = RenderTexture.active; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)2); Graphics.Blit((Texture)(object)texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(num, num2); val.ReadPixels(new Rect((float)num3, (float)num4, (float)num, (float)num2), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); return val; } public static Texture2D DuplicateTexture(Texture2D texture) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) return DuplicateTexture(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height)); } public static Texture2D DuplicateTexture(Sprite sprite) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) return DuplicateTexture(sprite.texture, sprite.textureRect); } public static Sprite DuplicateSprite(Sprite sprite) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Texture2D val = DuplicateTexture(sprite); if (!Object.op_Implicit((Object)(object)val)) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } public static Sprite LoadSpriteFromFile(string spritePath) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return LoadSpriteFromFile(spritePath, Vector2.zero); } public static Sprite LoadSpriteFromFile(string spritePath, Vector2 pivot) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) Texture2D val = LoadTexture(spritePath); if ((Object)(object)val != (Object)null) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), pivot); } return null; } public static Mesh LoadMesh(string meshPath) { string text = Path.Combine(Paths.PluginPath, meshPath); if (!File.Exists(text)) { return null; } return ObjImporter.ImportFile(text); } public static AssetBundle LoadAssetBundle(string bundlePath) { string text = Path.Combine(Paths.PluginPath, bundlePath); if (!File.Exists(text)) { return null; } return AssetBundle.LoadFromFile(text); } public static AssetBundle LoadAssetBundleFromResources(string bundleName, Assembly resourceAssembly) { if (resourceAssembly == null) { throw new ArgumentNullException("Parameter resourceAssembly can not be null."); } string text = null; try { text = resourceAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(bundleName)); } catch (Exception) { } if (text == null) { Logger.LogError("AssetBundle " + bundleName + " not found in assembly manifest"); return null; } using Stream stream = resourceAssembly.GetManifestResourceStream(text); return AssetBundle.LoadFromStream(stream); } public static AssetBundle LoadAssetBundleFromResources(string bundleName) { return LoadAssetBundleFromResources(bundleName, ReflectionHelper.GetCallingAssembly()); } public static string LoadTextFromResources(string fileName, Assembly resourceAssembly) { if (resourceAssembly == null) { throw new ArgumentNullException("Parameter resourceAssembly can not be null."); } string text = null; try { text = resourceAssembly.GetManifestResourceNames().Single((string str) => str.EndsWith(fileName)); } catch (Exception) { } if (text == null) { Logger.LogError("File " + fileName + " not found in assembly manifest"); return null; } using Stream stream = resourceAssembly.GetManifestResourceStream(text); using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } public static string LoadTextFromResources(string fileName) { return LoadTextFromResources(fileName, ReflectionHelper.GetCallingAssembly()); } public static string LoadText(string path) { string text = Path.Combine(Paths.PluginPath, path); if (!File.Exists(text)) { Logger.LogError("Error, failed to load contents from non-existant path: $" + text); return null; } return File.ReadAllText(text); } public static Sprite LoadSprite(string assetPath) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Paths.PluginPath, assetPath); if (!File.Exists(text)) { return null; } if (text.Contains('$'.ToString())) { string[] array = text.Split(new char[1] { '$' }); string text2 = array[0]; string text3 = array[1]; AssetBundle val = AssetBundle.LoadFromFile(text2); Sprite result = val.LoadAsset(text3); val.Unload(false); return result; } Texture2D val2 = LoadTexture(text, relativePath: false); if (!Object.op_Implicit((Object)(object)val2)) { return null; } return Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), Vector2.zero); } internal static bool TryLoadPrefab(BepInPlugin sourceMod, AssetBundle assetBundle, string assetName, out GameObject prefab) { try { prefab = assetBundle.LoadAsset(assetName); } catch (Exception arg) { prefab = null; Logger.LogError(sourceMod, $"Failed to load prefab '{assetName}' from AssetBundle {assetBundle}:\n{arg}"); return false; } if (!Object.op_Implicit((Object)(object)prefab)) { Logger.LogError(sourceMod, $"Failed to load prefab '{assetName}' from AssetBundle {assetBundle}"); return false; } return true; } } internal static class AutomaticLocalizationsLoading { public const string TranslationsFolderName = "Translations"; public const string CommunityTranslationFileName = "community_translation.json"; public static void Init() { HashSet hashSet = new HashSet(); HashSet hashSet2 = new HashSet(); HashSet hashSet3 = new HashSet(); foreach (FileInfo translationFile in GetTranslationFiles(Paths.LanguageTranslationsFolder, "community_translation.json")) { hashSet.Add(translationFile); } foreach (FileInfo translationFile2 in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.json")) { hashSet.Add(translationFile2); } foreach (FileInfo translationFile3 in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.language")) { hashSet2.Add(translationFile3); } foreach (FileInfo translationFile4 in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.yaml")) { hashSet3.Add(translationFile4); } foreach (FileInfo translationFile5 in GetTranslationFiles(Paths.LanguageTranslationsFolder, "*.yml")) { hashSet3.Add(translationFile5); } foreach (FileInfo item in hashSet) { try { PluginInfo pluginInfoFromPath = BepInExUtils.GetPluginInfoFromPath(item); BepInPlugin val = ((pluginInfoFromPath != null) ? pluginInfoFromPath.Metadata : null); LocalizationManager.Instance.GetLocalization(val ?? ((BaseUnityPlugin)Main.Instance).Info.Metadata).AddFileByPath(item.FullName, isJson: true); } catch (Exception arg) { Logger.LogWarning($"Exception caught while loading localization file {item}: {arg}"); } } foreach (FileInfo item2 in hashSet2) { try { PluginInfo pluginInfoFromPath2 = BepInExUtils.GetPluginInfoFromPath(item2); BepInPlugin val2 = ((pluginInfoFromPath2 != null) ? pluginInfoFromPath2.Metadata : null); LocalizationManager.Instance.GetLocalization(val2 ?? ((BaseUnityPlugin)Main.Instance).Info.Metadata).AddFileByPath(item2.FullName); } catch (Exception arg2) { Logger.LogWarning($"Exception caught while loading localization file {item2}: {arg2}"); } } if (hashSet3.Count > 0 && !CustomLocalization.IsYamlDotNetAvailable()) { Logger.LogWarning($"Found {hashSet3.Count} YAML localization file(s) but YamlDotNet is not loaded. " + "Mods using .yaml/.yml localization must include YamlDotNet.dll as a dependency."); return; } foreach (FileInfo item3 in hashSet3) { try { PluginInfo pluginInfoFromPath3 = BepInExUtils.GetPluginInfoFromPath(item3); BepInPlugin val3 = ((pluginInfoFromPath3 != null) ? pluginInfoFromPath3.Metadata : null); LocalizationManager.Instance.GetLocalization(val3 ?? ((BaseUnityPlugin)Main.Instance).Info.Metadata).AddFileByPath(item3.FullName); } catch (Exception arg3) { Logger.LogWarning($"Exception caught while loading localization file {item3}: {arg3}"); } } } private static IEnumerable GetTranslationFiles(string path, string searchPattern) { return GetTranslationFiles(new DirectoryInfo(path), searchPattern); } private static IEnumerable GetTranslationFiles(DirectoryInfo pathDirectoryInfo, string searchPattern) { if (!pathDirectoryInfo.Exists) { yield break; } string[] files = Directory.GetFiles(pathDirectoryInfo.FullName, searchPattern, SearchOption.AllDirectories); foreach (string item in files.Where((string path) => new DirectoryInfo(path).Parent?.Parent?.Name == "Translations")) { yield return new FileInfo(item); } } } public static class BepInExUtils { private static BaseUnityPlugin[] Plugins; private static Dictionary PluginInfoTypeNameCache { get; } = new Dictionary(); private static Dictionary AssemblyToPluginInfoCache { get; } = new Dictionary(); private static Dictionary TypeToPluginInfoCache { get; } = new Dictionary(); private static BaseUnityPlugin[] CacheDependentPlugins() { List list = new List(); foreach (BaseUnityPlugin loadedPlugin in GetLoadedPlugins()) { if (loadedPlugin.Info == null) { Logger.LogWarning("Plugin without Info found: " + ((object)loadedPlugin).GetType().Assembly.FullName); continue; } if (loadedPlugin.Info.Metadata == null) { Logger.LogWarning("Plugin without Metadata found: " + ((object)loadedPlugin).GetType().Assembly.FullName); continue; } if (loadedPlugin.Info.Metadata.GUID == "com.jotunn.jotunn") { list.Add(loadedPlugin); continue; } foreach (BepInDependency item in ((object)loadedPlugin).GetType().GetCustomAttributes(typeof(BepInDependency), inherit: false).Cast()) { if (item.DependencyGUID == "com.jotunn.jotunn") { list.Add(loadedPlugin); } } } return list.ToArray(); } public static Dictionary GetDependentPlugins(bool includeJotunn = false) { if (Plugins == null) { if (!ReflectionHelper.GetPrivateField(typeof(Chainloader), "_loaded")) { return new Dictionary(); } Plugins = CacheDependentPlugins(); } return Plugins.Where((BaseUnityPlugin plugin) => includeJotunn || plugin.Info.Metadata.GUID != "com.jotunn.jotunn").ToDictionary((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID); } public static Dictionary GetPlugins(bool includeJotunn = false) { return (from plugin in GetLoadedPlugins() where includeJotunn || plugin.Info.Metadata.GUID != "com.jotunn.jotunn" select plugin).ToDictionary((BaseUnityPlugin plugin) => plugin.Info.Metadata.GUID); } public static PluginInfo GetPluginInfoFromType(Type type) { if (TypeToPluginInfoCache.TryGetValue(type, out var value)) { return value; } foreach (PluginInfo value2 in Chainloader.PluginInfos.Values) { string privateProperty = ReflectionHelper.GetPrivateProperty(value2, "TypeName"); if (privateProperty.Equals(type.FullName)) { TypeToPluginInfoCache[type] = value2; return value2; } } return null; } private static string GetPluginInfoTypeName(PluginInfo info) { if (PluginInfoTypeNameCache.TryGetValue(info, out var value)) { return value; } value = ReflectionHelper.GetPrivateProperty(info, "TypeName"); PluginInfoTypeNameCache.Add(info, value); return value; } public static PluginInfo GetPluginInfoFromAssembly(Assembly assembly) { if (AssemblyToPluginInfoCache.TryGetValue(assembly, out var value)) { return value; } foreach (PluginInfo value2 in Chainloader.PluginInfos.Values) { if (assembly.GetType(GetPluginInfoTypeName(value2)) != null) { AssemblyToPluginInfoCache[assembly] = value2; return value2; } } AssemblyToPluginInfoCache[assembly] = null; return null; } public static PluginInfo GetPluginInfoFromPath(FileInfo fileInfo) { return Chainloader.PluginInfos.Values.Where((PluginInfo pi) => pi.Location != null).FirstOrDefault((Func)((PluginInfo pi) => fileInfo.DirectoryName != null && fileInfo.DirectoryName.Contains(new FileInfo(pi.Location).DirectoryName) && new FileInfo(pi.Location).DirectoryName != Paths.PluginPath)); } public static BepInPlugin GetSourceModMetadata() { Type callingType = ReflectionHelper.GetCallingType(); PluginInfo pluginInfoFromType = GetPluginInfoFromType(callingType); object obj = ((pluginInfoFromType != null) ? pluginInfoFromType.Metadata : null); if (obj == null) { PluginInfo pluginInfoFromAssembly = GetPluginInfoFromAssembly(callingType.Assembly); obj = ((pluginInfoFromAssembly != null) ? pluginInfoFromAssembly.Metadata : null) ?? ((BaseUnityPlugin)Main.Instance).Info.Metadata; } return (BepInPlugin)obj; } private static IEnumerable GetLoadedPlugins() { return from x in Chainloader.PluginInfos where x.Value != null && (Object)(object)x.Value.Instance != (Object)null select x.Value.Instance; } } public static class BoneReorder { private static bool applied; public static void ApplyOnEquipmentChanged() { if (!applied) { Main.Harmony.PatchAll(typeof(BoneReorder)); applied = true; } } public static bool IsReorderingEnabled() { return applied; } [HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")] [HarmonyPostfix] private static void VisEquipmentOnSetLegEquiped(VisEquipment __instance, int hash, ref bool __result) { if (__result && __instance.m_legItemInstances != null) { ReorderBones(__instance, hash, __instance.m_legItemInstances); } } [HarmonyPatch(typeof(VisEquipment), "SetHelmetEquipped")] [HarmonyPostfix] private static void VisEquipmentOnSetHelmetEquiped(VisEquipment __instance, int hash, int hairHash, ref bool __result) { if (__result && (Object)(object)__instance.m_helmetItemInstance != (Object)null) { ReorderBones(__instance, hash, new List { __instance.m_helmetItemInstance }); } } [HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")] [HarmonyPostfix] private static void VisEquipmentOnSetChestEquiped(VisEquipment __instance, int hash, ref bool __result) { if (__result && __instance.m_chestItemInstances != null) { ReorderBones(__instance, hash, __instance.m_chestItemInstances); } } [HarmonyPatch(typeof(VisEquipment), "SetShoulderEquipped")] [HarmonyPostfix] private static void VisEquipmentOnSetShoulderEquiped(VisEquipment __instance, int hash, int variant, ref bool __result) { if (__result && __instance.m_shoulderItemInstances != null) { ReorderBones(__instance, hash, __instance.m_shoulderItemInstances); } } [HarmonyPatch(typeof(VisEquipment), "SetUtilityEquipped")] [HarmonyPostfix] private static void VisEquipmentOnSetUtilityEquiped(VisEquipment __instance, int hash, ref bool __result) { if (__result && __instance.m_utilityItemInstances != null) { ReorderBones(__instance, hash, __instance.m_utilityItemInstances); } } private static void ReorderBones(VisEquipment visEquipment, int itemPrefabHash, List instancesToFix) { if (!((Object)(object)visEquipment != (Object)null)) { return; } try { Transform val = ((Component)visEquipment).transform.Find("Visual/Armature/Hips"); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemPrefabHash); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)itemPrefab)) { Logger.LogDebug($"Prefab missing components. Skipping {itemPrefab} {val}"); return; } Logger.LogDebug("Reordering bones"); int childCount = itemPrefab.transform.childCount; int num = 0; for (int i = 0; i < childCount; i++) { Transform child = itemPrefab.transform.GetChild(i); if (((Object)child).name.StartsWith("attach_skin")) { int num2 = 0; SkinnedMeshRenderer[] componentsInChildren = instancesToFix[num].GetComponentsInChildren(true); SkinnedMeshRenderer[] componentsInChildren2 = ((Component)child).GetComponentsInChildren(true); foreach (SkinnedMeshRenderer skinnedMeshRenderer in componentsInChildren2) { SkinnedMeshRenderer skinnedMeshRenderer2 = componentsInChildren[num2]; skinnedMeshRenderer2.SetBones(skinnedMeshRenderer.GetBoneNames(), val); num2++; } num++; } } } catch (Exception arg) { Logger.LogWarning($"Exception caught while reordering bones: {arg}"); } } private static void SetBones(this SkinnedMeshRenderer skinnedMeshRenderer, string[] boneNames, Transform skeletonRoot) { Transform[] array = (Transform[])(object)new Transform[skinnedMeshRenderer.bones.Length]; for (int i = 0; i < array.Length; i++) { array[i] = FindInChildren(skeletonRoot, boneNames[i]); } skinnedMeshRenderer.bones = array; skinnedMeshRenderer.rootBone = skeletonRoot; } private static string[] GetBoneNames(this SkinnedMeshRenderer skinnedMeshRenderer) { List list = new List(); Transform[] bones = skinnedMeshRenderer.bones; foreach (Transform val in bones) { list.Add(((Object)val).name); } return list.ToArray(); } private static Transform FindInChildren(Transform transform, string name) { if (((Object)transform).name == name) { return transform; } for (int i = 0; i < transform.childCount; i++) { Transform val = FindInChildren(transform.GetChild(i), name); if ((Object)(object)val != (Object)null) { return val; } } return null; } } public class ConfigFileWatcher { private const long TICKS_PER_MILISEC = 10000L; private DateTime lastReadTime = DateTime.MinValue; private readonly ConfigFile configFile; private readonly BepInPlugin sourceMod; private readonly string configFileDir; private readonly string configFileName; private readonly long reloadDelay; public event Action OnConfigFileReloaded; public ConfigFileWatcher(ConfigFile configFile, long reloadDelay = 1000L) { PluginInfo pluginInfoFromAssembly = BepInExUtils.GetPluginInfoFromAssembly(Assembly.GetCallingAssembly()); sourceMod = ((pluginInfoFromAssembly != null) ? pluginInfoFromAssembly.Metadata : null); if (sourceMod == null || sourceMod.GUID == ((BaseUnityPlugin)Main.Instance).Info.Metadata.GUID) { sourceMod = BepInExUtils.GetSourceModMetadata(); } this.configFile = configFile; this.reloadDelay = reloadDelay * 10000; configFileDir = Directory.GetParent(configFile.ConfigFilePath).FullName; configFileName = Path.GetFileName(configFile.ConfigFilePath); FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(configFileDir, configFileName); fileSystemWatcher.Changed += ReloadConfigFile; fileSystemWatcher.Created += ReloadConfigFile; fileSystemWatcher.Renamed += ReloadConfigFile; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void InvokeOnConfigFileReloaded() { this.OnConfigFileReloaded?.SafeInvoke(); } internal void ReloadConfigFile(object sender, FileSystemEventArgs eventArgs) { DateTime now = DateTime.Now; long num = now.Ticks - lastReadTime.Ticks; if (!File.Exists(configFile.ConfigFilePath) || num < reloadDelay) { return; } try { Logger.LogInfo(sourceMod, "Reloading " + configFileName); bool saveOnConfigSet = configFile.SetSaveOnConfigSet(saveOnConfigSet: false); configFile.Reload(); configFile.SaveOnConfigSet = saveOnConfigSet; lastReadTime = now; InvokeOnConfigFileReloaded(); } catch { Logger.LogError(sourceMod, "There was an issue loading " + configFileName); Logger.LogError(sourceMod, "Please check your config entries for spelling and format!"); } } } public static class ConfigManagerUtils { private static PropertyInfo displayingWindowInfo; private static MethodInfo buildSettingListMethodInfo; public static BaseUnityPlugin Plugin { get; private set; } public static bool DisplayingWindow { get { if (Object.op_Implicit((Object)(object)Plugin)) { return (bool)displayingWindowInfo.GetValue(Plugin); } return false; } set { displayingWindowInfo?.SetValue(Plugin, value); } } static ConfigManagerUtils() { if (Chainloader.PluginInfos.TryGetValue("com.bepis.bepinex.configurationmanager", out var value) && Object.op_Implicit((Object)(object)value.Instance)) { Plugin = value.Instance; displayingWindowInfo = AccessTools.Property(((object)Plugin).GetType(), "DisplayingWindow"); buildSettingListMethodInfo = AccessTools.Method(((object)Plugin).GetType(), "BuildSettingList", (Type[])null, (Type[])null); } else if (Chainloader.PluginInfos.TryGetValue("_shudnal.ConfigurationManager", out value) && Object.op_Implicit((Object)(object)value.Instance)) { Plugin = value.Instance; displayingWindowInfo = AccessTools.Property(((object)Plugin).GetType(), "DisplayingWindow"); buildSettingListMethodInfo = AccessTools.Method(((object)Plugin).GetType(), "BuildSettingList", (Type[])null, (Type[])null); } } public static void BuildSettingList() { if (Object.op_Implicit((Object)(object)Plugin)) { buildSettingListMethodInfo.Invoke(Plugin, null); } } } public class ConfigurationSynchronizationEventArgs : EventArgs { public bool InitialSynchronization { get; set; } public HashSet UpdatedPluginGUIDs { get; set; } } public class DungeonGeneratorTheme : MonoBehaviour { public string m_themeName = ""; } internal class ExtEquipment : MonoBehaviour { private static bool Enabled; private static readonly Dictionary Instances = new Dictionary(); private Humanoid MyHumanoid; private int NewRightItemVariant; private int CurrentRightItemVariant; private int NewRightBackItemVariant; private int CurrentRightBackItemVariant; private int NewChestVariant; private int CurrentChestVariant; public static void Enable() { if (!Enabled) { Enabled = true; Main.Harmony.PatchAll(typeof(ExtEquipment)); } } [HarmonyPatch(typeof(VisEquipment), "Awake")] [HarmonyPostfix] private static void VisEquipment_Awake(VisEquipment __instance) { ExtEquipment extEquipment = default(ExtEquipment); if (!((Component)__instance).gameObject.TryGetComponent(ref extEquipment)) { ((Component)__instance).gameObject.AddComponent(); } } [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] [HarmonyPrefix] private static void VisEquipment_UpdateEquipmentVisuals(VisEquipment __instance) { if (Object.op_Implicit((Object)(object)__instance.m_nview)) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null && Instances.TryGetValue(__instance, out var value)) { value.NewRightItemVariant = zDO.GetInt("RightItemVariant", 0); value.NewChestVariant = zDO.GetInt("ChestItemVariant", 0); value.NewRightBackItemVariant = zDO.GetInt("RightBackItemVariant", 0); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")] [HarmonyILManipulator] private static void VisEquipment_SetRightHandEquiped(ILContext il) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) ExtEquipment instance = null; ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)delegate(int hash, VisEquipment self) { if (Instances.TryGetValue(self, out instance) && hash != 0 && instance.CurrentRightItemVariant != instance.NewRightItemVariant) { instance.CurrentRightItemVariant = instance.NewRightItemVariant; return hash + instance.CurrentRightItemVariant; } return hash; }); } if (val.TryGotoNext((MoveType)2, new Func[4] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0) })) { val.EmitDelegate>((Func)((int variant) => (!((Object)(object)instance != (Object)null)) ? variant : instance.CurrentRightItemVariant)); } } [HarmonyPatch(typeof(VisEquipment), "SetBackEquipped")] [HarmonyILManipulator] private static void VisEquipment_SetBackEquiped(ILContext il) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) ExtEquipment instance = null; ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 2) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)delegate(int hash, VisEquipment self) { if (Instances.TryGetValue(self, out instance) && hash != 0 && instance.CurrentRightBackItemVariant != instance.NewRightBackItemVariant) { instance.CurrentRightBackItemVariant = instance.NewRightBackItemVariant; return hash + instance.CurrentRightBackItemVariant; } return hash; }); } if (val.TryGotoNext((MoveType)2, new Func[4] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 2), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 0) })) { val.EmitDelegate>((Func)((int variant) => (!((Object)(object)instance != (Object)null)) ? variant : instance.CurrentRightBackItemVariant)); } } [HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")] [HarmonyILManipulator] private static void VisEquipment_SetChestEquiped(ILContext il) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) ExtEquipment instance = null; ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)2, new Func[1] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1) })) { val.Emit(OpCodes.Ldarg_0); val.EmitDelegate>((Func)delegate(int hash, VisEquipment self) { if (Instances.TryGetValue(self, out instance) && hash != 0 && instance.CurrentChestVariant != instance.NewChestVariant) { instance.CurrentChestVariant = instance.NewChestVariant; return hash + instance.CurrentChestVariant; } return hash; }); } if (val.TryGotoNext((MoveType)2, new Func[4] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 1), (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, -1) })) { val.EmitDelegate>((Func)((int variant) => (!((Object)(object)instance != (Object)null)) ? variant : instance.CurrentChestVariant)); } } [HarmonyPatch(typeof(VisEquipment), "SetRightItem")] [HarmonyPrefix] private static void VisEquipment_SetRightItem(VisEquipment __instance, string name) { if (!Instances.TryGetValue(__instance, out var value) || !Object.op_Implicit((Object)(object)value.MyHumanoid) || value.MyHumanoid.m_rightItem == null || (__instance.m_rightItem == name && value.MyHumanoid.m_rightItem.m_variant == value.CurrentRightItemVariant)) { return; } value.NewRightItemVariant = value.MyHumanoid.m_rightItem.m_variant; if (Object.op_Implicit((Object)(object)__instance.m_nview)) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { zDO.Set("RightItemVariant", (!string.IsNullOrEmpty(name)) ? value.NewRightItemVariant : 0); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightBackItem")] [HarmonyPrefix] private static void VisEquipment_SetRightBackItem(VisEquipment __instance, string name) { if (!Instances.TryGetValue(__instance, out var value) || !Object.op_Implicit((Object)(object)value.MyHumanoid) || value.MyHumanoid.m_hiddenRightItem == null || (__instance.m_rightBackItem == name && value.MyHumanoid.m_hiddenRightItem.m_variant == value.CurrentRightBackItemVariant)) { return; } value.NewRightBackItemVariant = value.MyHumanoid.m_hiddenRightItem.m_variant; if (Object.op_Implicit((Object)(object)__instance.m_nview)) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { zDO.Set("RightBackItemVariant", (!string.IsNullOrEmpty(name)) ? value.NewRightBackItemVariant : 0); } } } [HarmonyPatch(typeof(VisEquipment), "SetChestItem")] [HarmonyPrefix] private static void VisEquipment_SetChestItem(VisEquipment __instance, string name) { if (!Instances.TryGetValue(__instance, out var value) || !Object.op_Implicit((Object)(object)value.MyHumanoid) || value.MyHumanoid.m_chestItem == null || (__instance.m_chestItem == name && value.MyHumanoid.m_chestItem.m_variant == value.CurrentChestVariant)) { return; } value.NewChestVariant = value.MyHumanoid.m_chestItem.m_variant; if (Object.op_Implicit((Object)(object)__instance.m_nview)) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null) { zDO.Set("ChestItemVariant", (!string.IsNullOrEmpty(name)) ? value.NewChestVariant : 0); } } } private void Awake() { MyHumanoid = ((Component)this).gameObject.GetComponent(); Instances.Add(((Component)this).gameObject.GetComponent(), this); } private void OnDestroy() { Instances.Remove(((Component)this).gameObject.GetComponent()); } } public static class GameConstants { public static class GlobalKey { public static readonly string None = ""; public static readonly string KilledBonemass = "defeated_bonemass"; public static readonly string KilledElder = "defeated_gdking"; public static readonly string KilledYagluth = "defeated_goblinking"; public static readonly string KilledModer = "defeated_dragon"; public static readonly string KilledEikthyr = "defeated_eikthyr"; public static readonly string KilledTroll = "KilledTroll"; public static readonly string KilledSurtling = "killed_surtling"; } public static class Weather { public static readonly string ClearSkies = "Clear"; public static readonly string MeadowsClearSkies = "Heath_clear"; public static readonly string LightRain = "LightRain"; public static readonly string Rain = "Rain"; public static readonly string ThunderStorm = "ThunderStorm"; public static readonly string ClearThunderStorm = "nofogts"; public static readonly string SwampRain = "SwampRain"; public static readonly string MistlandsDark = "Darklands_dark"; public static readonly string AshlandsAshrain = "Ashrain"; public static readonly string MountainSnow = "Snow"; public static readonly string MountainBlizzard = "SnowStorm"; public static readonly string BlackForestFog = "DeepForest Mist"; public static readonly string Fog = "Misty"; public static readonly string DeepNorthSnow = "Twilight_Snow"; public static readonly string DeepNorthSnowStorm = "Twilight_SnowStorm"; public static readonly string DeepNorthClear = "Twilight_Clear"; public static readonly string EikthyrsThunderstorm = "Eikthyr"; public static readonly string EldersHaze = "GDKing"; public static readonly string BonemassDownpour = "Bonemass"; public static readonly string ModersVortex = "Moder"; public static readonly string YagluthsMagicBlizzard = "GoblinKing"; public static readonly string Crypt = "Crypt"; public static readonly string SunkenCrypt = "SunkenCrypt"; } } public static class GameVersions { public static Version ValheimVersion { get; } = GetValheimVersion(); public static uint NetworkVersion { get; } = GetNetworkVersion(); private static Version GetValheimVersion() { //IL_0000: 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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) return new Version(Version.CurrentVersion.m_major, Version.CurrentVersion.m_minor, Version.CurrentVersion.m_patch); } private static uint GetNetworkVersion() { FieldInfo fieldInfo = typeof(Version).GetField("m_networkVersion") ?? typeof(Version).GetField("c_networkVersion") ?? throw new Exception("Could not find network version field in Version class"); return (uint)fieldInfo.GetValue(null); } } internal static class GUIUtils { public static bool IsHeadless { get; } = (int)SystemInfo.graphicsDeviceType == 4; } public static class HashUtils { public static string ComputeSha256Hash(string rawData) { using SHA256 sHA = SHA256.Create(); byte[] array = sHA.ComputeHash(Encoding.UTF8.GetBytes(rawData)); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < array.Length; i++) { stringBuilder.Append(array[i].ToString("x2")); } return stringBuilder.ToString(); } } public interface IModPrefab { GameObject Prefab { get; } BepInPlugin SourceMod { get; } } internal static class InputUtils { public static Key KeyCodeToKey(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected I4, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected I4, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected I4, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 if ((int)key <= 19) { if ((int)key <= 8) { if ((int)key == 0) { return (Key)0; } if ((int)key == 8) { return (Key)65; } } else { if ((int)key == 9) { return (Key)3; } if ((int)key == 13) { return (Key)2; } if ((int)key == 19) { return (Key)76; } } } else if ((int)key <= 32) { if ((int)key == 27) { return (Key)60; } if ((int)key == 32) { return (Key)1; } } else { switch (key - 48) { case 0: return (Key)50; case 1: return (Key)41; case 2: return (Key)42; case 3: return (Key)43; case 4: return (Key)44; case 5: return (Key)45; case 6: return (Key)46; case 7: return (Key)47; case 8: return (Key)48; case 9: return (Key)49; } switch (key - 97) { default: switch (key - 256) { case 0: return (Key)84; case 1: return (Key)85; case 2: return (Key)86; case 3: return (Key)87; case 4: return (Key)88; case 5: return (Key)89; case 6: return (Key)90; case 7: return (Key)91; case 8: return (Key)92; case 9: return (Key)93; case 10: return (Key)82; case 11: return (Key)78; case 12: return (Key)79; case 13: return (Key)81; case 14: return (Key)80; case 15: return (Key)77; case 16: return (Key)83; case 17: return (Key)63; case 18: return (Key)64; case 19: return (Key)62; case 20: return (Key)61; case 21: return (Key)70; case 22: return (Key)68; case 23: return (Key)69; case 24: return (Key)67; case 25: return (Key)66; case 26: return (Key)94; case 27: return (Key)95; case 28: return (Key)96; case 29: return (Key)97; case 30: return (Key)98; case 31: return (Key)99; case 32: return (Key)100; case 33: return (Key)101; case 34: return (Key)102; case 35: return (Key)103; case 36: return (Key)104; case 37: return (Key)105; case 45: return (Key)72; case 46: return (Key)75; case 47: return (Key)52; case 48: return (Key)51; case 49: return (Key)56; case 50: return (Key)55; case 51: return (Key)54; case 52: return (Key)53; case 54: return (Key)57; case 55: return (Key)57; case 53: return (Key)58; case 56: return (Key)58; case 57: return (Key)54; } break; case 30: return (Key)71; case 0: return (Key)15; case 1: return (Key)16; case 2: return (Key)17; case 3: return (Key)18; case 4: return (Key)19; case 5: return (Key)20; case 6: return (Key)21; case 7: return (Key)22; case 8: return (Key)23; case 9: return (Key)24; case 10: return (Key)25; case 11: return (Key)26; case 12: return (Key)27; case 13: return (Key)28; case 14: return (Key)29; case 15: return (Key)30; case 16: return (Key)31; case 17: return (Key)32; case 18: return (Key)33; case 19: return (Key)34; case 20: return (Key)35; case 21: return (Key)36; case 22: return (Key)37; case 23: return (Key)38; case 24: return (Key)39; case 25: return (Key)40; case 26: case 27: case 28: case 29: break; } } Logger.LogWarning($"Key {key} not found in the new input system"); return (Key)0; } public static bool TryKeyCodeToMouseButton(KeyCode key, out MouseButton mouseButton) { //IL_0000: 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_0020: Expected I4, but got Unknown switch (key - 323) { case 0: mouseButton = (MouseButton)0; return true; case 1: mouseButton = (MouseButton)1; return true; case 2: mouseButton = (MouseButton)2; return true; case 3: mouseButton = (MouseButton)3; return true; case 4: mouseButton = (MouseButton)4; return true; default: mouseButton = (MouseButton)0; return false; } } public static KeyCode GetGamepadKeyCode(InputManager.GamepadButton @enum) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_008c: Unknown result type (might be due to invalid IL or missing references) return (KeyCode)(@enum switch { InputManager.GamepadButton.ButtonSouth => 330, InputManager.GamepadButton.ButtonEast => 331, InputManager.GamepadButton.ButtonWest => 332, InputManager.GamepadButton.ButtonNorth => 333, InputManager.GamepadButton.LeftShoulder => 334, InputManager.GamepadButton.RightShoulder => 335, InputManager.GamepadButton.SelectButton => 336, InputManager.GamepadButton.StartButton => 337, InputManager.GamepadButton.LeftStickButton => 338, InputManager.GamepadButton.RightStickButton => 339, _ => 0, }); } public static GamepadInput GetGamepadInput(InputManager.GamepadButton @enum) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_008f: 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_0093: Unknown result type (might be due to invalid IL or missing references) return (GamepadInput)(@enum switch { InputManager.GamepadButton.DPadUp => 4, InputManager.GamepadButton.DPadDown => 3, InputManager.GamepadButton.DPadLeft => 1, InputManager.GamepadButton.DPadRight => 2, InputManager.GamepadButton.ButtonSouth => 5, InputManager.GamepadButton.ButtonEast => 6, InputManager.GamepadButton.ButtonWest => 7, InputManager.GamepadButton.ButtonNorth => 8, InputManager.GamepadButton.LeftShoulder => 15, InputManager.GamepadButton.RightShoulder => 16, InputManager.GamepadButton.LeftTrigger => 17, InputManager.GamepadButton.RightTrigger => 18, InputManager.GamepadButton.SelectButton => 19, InputManager.GamepadButton.StartButton => 20, InputManager.GamepadButton.LeftStickButton => 11, InputManager.GamepadButton.RightStickButton => 14, _ => 0, }); } public static string GetGamepadString(InputManager.GamepadButton @enum) { return @enum switch { InputManager.GamepadButton.None => string.Empty, InputManager.GamepadButton.DPadLeft => "<", InputManager.GamepadButton.DPadUp => ">", InputManager.GamepadButton.DPadRight => ">", InputManager.GamepadButton.DPadDown => "<", InputManager.GamepadButton.ButtonNorth => "Y", InputManager.GamepadButton.ButtonSouth => "A", InputManager.GamepadButton.ButtonWest => "X", InputManager.GamepadButton.ButtonEast => "B", InputManager.GamepadButton.LeftShoulder => "LB", InputManager.GamepadButton.RightShoulder => "RB", InputManager.GamepadButton.LeftTrigger => "LT", InputManager.GamepadButton.RightTrigger => "RT", InputManager.GamepadButton.StartButton => "Menu", InputManager.GamepadButton.SelectButton => "Back", InputManager.GamepadButton.LeftStickButton => "L", InputManager.GamepadButton.RightStickButton => "R", _ => string.Empty, }; } public static InputManager.GamepadButton GetGamepadButton(GamepadInput input) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected I4, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Invalid comparison between Unknown and I4 switch (input - 1) { default: if ((int)input != 17) { if ((int)input == 18) { return InputManager.GamepadButton.RightTrigger; } return InputManager.GamepadButton.None; } return InputManager.GamepadButton.LeftTrigger; case 3: return InputManager.GamepadButton.DPadUp; case 2: return InputManager.GamepadButton.DPadDown; case 0: return InputManager.GamepadButton.DPadLeft; case 1: return InputManager.GamepadButton.DPadRight; } } public static InputManager.GamepadButton GetGamepadButton(string axis) { return axis switch { "JoyAxis 7" => InputManager.GamepadButton.DPadUp, "-JoyAxis 7" => InputManager.GamepadButton.DPadDown, "-JoyAxis 6" => InputManager.GamepadButton.DPadLeft, "JoyAxis 6" => InputManager.GamepadButton.DPadRight, "-JoyAxis 3" => InputManager.GamepadButton.LeftTrigger, "JoyAxis 3" => InputManager.GamepadButton.RightTrigger, _ => InputManager.GamepadButton.None, }; } public static string GetAxisPath(string axis) { return axis switch { "Mouse ScrollWheel" => "/scroll", "JoyAxis 7" => "/dpad/up", "-JoyAxis 7" => "/dpad/down", "-JoyAxis 6" => "/dpad/left", "JoyAxis 6" => "/dpad/right", "-JoyAxis 3" => "/leftTrigger", "JoyAxis 3" => "/rightTrigger", _ => string.Empty, }; } public static string GetGamepadInputPath(GamepadInput input) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected I4, but got Unknown return (input - 1) switch { 0 => "/dpad/left", 1 => "/dpad/right", 2 => "/dpad/down", 3 => "/dpad/up", 4 => "/buttonSouth", 5 => "/buttonEast", 6 => "/buttonWest", 7 => "/buttonNorth", 8 => "/leftStick/x", 9 => "/leftStick/y", 10 => "/leftStickPress", 11 => "/rightStick/x", 12 => "/rightStick/y", 13 => "/rightStickPress", 14 => "/leftShoulder", 15 => "/rightShoulder", 16 => "/leftTrigger", 17 => "/rightTrigger", 18 => "/select", 19 => "/start", 20 => "/touchpadButton", 21 => "/rightStick/up", 22 => "/rightStick/down", 23 => "/rightStick/left", 24 => "/rightStick/right", 25 => "/leftStick/up", 26 => "/leftStick/down", 27 => "/leftStick/left", 28 => "/leftStick/right", 29 => "/rightStick", 30 => "/leftStick", _ => string.Empty, }; } public static InputManager.GamepadButton GetGamepadButton(KeyCode key) { //IL_0000: 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_0034: Expected I4, but got Unknown return (key - 330) switch { 0 => InputManager.GamepadButton.ButtonSouth, 1 => InputManager.GamepadButton.ButtonEast, 2 => InputManager.GamepadButton.ButtonWest, 3 => InputManager.GamepadButton.ButtonNorth, 4 => InputManager.GamepadButton.LeftShoulder, 5 => InputManager.GamepadButton.RightShoulder, 6 => InputManager.GamepadButton.SelectButton, 7 => InputManager.GamepadButton.StartButton, 8 => InputManager.GamepadButton.LeftStickButton, 9 => InputManager.GamepadButton.RightStickButton, _ => InputManager.GamepadButton.None, }; } internal static void SetInputButtons(ConfigEntryBase entry) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) if (ZInput.instance == null) { return; } string boundButtonName = entry.GetBoundButtonName(); if (string.IsNullOrEmpty(boundButtonName)) { return; } if (entry.SettingType == typeof(KeyCode) && ZInput.instance.m_buttons.TryGetValue(boundButtonName, out var value)) { value.Rebind(ZInput.KeyCodeToPath((KeyCode)entry.BoxedValue, false)); } if (entry.SettingType == typeof(KeyboardShortcut) && ZInput.instance.m_buttons.TryGetValue(boundButtonName, out value)) { ButtonDef obj = value; KeyboardShortcut val = (KeyboardShortcut)entry.BoxedValue; obj.Rebind(ZInput.KeyCodeToPath(((KeyboardShortcut)(ref val)).MainKey, false)); } if (entry.SettingType == typeof(InputManager.GamepadButton) && ZInput.instance.m_buttons.TryGetValue("Joy!" + boundButtonName, out value)) { GamepadInput gamepadInput = GetGamepadInput((InputManager.GamepadButton)entry.BoxedValue); KeyCode gamepadKeyCode = GetGamepadKeyCode((InputManager.GamepadButton)entry.BoxedValue); if ((int)gamepadInput != 0) { value.Rebind(GetGamepadInputPath(gamepadInput)); } else { value.Rebind(ZInput.KeyCodeToPath(gamepadKeyCode, false)); } } } } public static class ModCompatibility { private static ServerVersionData LastServerVersionData = new ServerVersionData(); private static readonly Dictionary ClientVersions = new Dictionary(); internal static void Init() { Main.LogInit("ModCompatibility"); Main.Harmony.PatchAll(typeof(ModCompatibility)); } public static bool IsModuleOnServer(BaseUnityPlugin plugin) { return IsModuleOnServer(plugin.Info.Metadata.GUID); } public static bool IsModuleOnServer(string modGUID) { if (Object.op_Implicit((Object)(object)ZNet.instance)) { if (ZNet.instance.IsClientInstance()) { if (LastServerVersionData.IsValid()) { return LastServerVersionData.moduleGUIDs.Contains(modGUID); } return false; } if (ZNet.instance.IsServer()) { return Chainloader.PluginInfos.ContainsKey(modGUID); } } return false; } public static bool IsJotunnOnServer() { return IsModuleOnServer("com.jotunn.jotunn"); } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] [HarmonyPriority(800)] private static void ZNet_OnNewConnection(ZNet __instance, ZNetPeer peer) { LastServerVersionData.Reset(); peer.m_rpc.Register("RPC_Jotunn_ReceiveVersionData", (Action)RPC_Jotunn_ReceiveVersionData); } [HarmonyPatch(typeof(ZNet), "RPC_ClientHandshake")] [HarmonyPrefix] [HarmonyPriority(800)] private static void ZNet_RPC_ClientHandshake(ZNet __instance, ZRpc rpc) { rpc.Invoke("RPC_Jotunn_ReceiveVersionData", new object[1] { new ModuleVersionData(GetEnforcableMods().ToList()).ToZPackage() }); } [HarmonyPatch(typeof(ZNet), "RPC_ServerHandshake")] [HarmonyPrefix] [HarmonyPriority(800)] private static void ZNet_RPC_ServerHandshake(ZNet __instance, ZRpc rpc) { rpc.Invoke("RPC_Jotunn_ReceiveVersionData", new object[1] { new ModuleVersionData(GetEnforcableMods().ToList()).ToZPackage() }); } [HarmonyPatch(typeof(FejdStartup), "ShowConnectError")] [HarmonyPostfix] [HarmonyPriority(0)] private static void FejdStartup_ShowConnectError(FejdStartup __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 if (LastServerVersionData.IsValid() && (int)ZNet.m_connectionStatus == 3) { string text = __instance.m_connectionFailedError.text; ((MonoBehaviour)__instance).StartCoroutine(ShowModCompatibilityErrorMessage(text)); __instance.m_connectionFailedPanel.SetActive(false); } } [HarmonyPatch(typeof(ZNet), "SendPeerInfo")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool ZNet_SendPeerInfo(ZNet __instance, ZRpc rpc, string password) { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsClientInstance() && !LastServerVersionData.IsValid() && GetEnforcableMods().Any((ModModule x) => x.IsNeededOnServer())) { string text = string.Join(Environment.NewLine, from x in GetEnforcableMods() where x.IsNeededOnServer() select x.ModName); Logger.LogWarning("Jötunn is not installed on the server. Client has mandatory mods, cancelling connection. Mods that need to be installed on the server:" + Environment.NewLine + text); rpc.Invoke("Disconnect", Array.Empty()); LastServerVersionData = new ServerVersionData(new List()); ZNet.m_connectionStatus = (ConnectionStatus)3; return false; } return true; } [HarmonyPatch(typeof(ZNet), "RPC_PeerInfo")] [HarmonyPrefix] [HarmonyPriority(800)] private static bool ZNet_RPC_PeerInfo(ZNet __instance, ZRpc rpc, ZPackage pkg) { if (!ZNet.instance.IsClientInstance()) { if (!ClientVersions.ContainsKey(rpc.GetSocket().GetEndPointString())) { if (GetEnforcableMods().Any((ModModule x) => x.IsNeededOnClient())) { string text = string.Join(Environment.NewLine, from x in GetEnforcableMods() where x.IsNeededOnClient() select x.ModName); Logger.LogWarning("Jötunn is not installed on the client. Server has mandatory mods, cancelling connection. Mods that need to be installed on the client:" + Environment.NewLine + text); rpc.Invoke("Error", new object[1] { 3 }); return false; } } else { ModuleVersionData serverData = new ModuleVersionData(GetEnforcableMods().ToList()); ModuleVersionData clientData = new ModuleVersionData(ClientVersions[rpc.m_socket.GetEndPointString()]); if (!CompareVersionData(serverData, clientData)) { Logger.LogWarning("RPC_PeerInfo: Disconnecting modded client with incompatible version message. Mods are not compatible"); rpc.Invoke("Error", new object[1] { 3 }); return false; } } } return true; } private static void RPC_Jotunn_ReceiveVersionData(ZRpc sender, ZPackage data) { Logger.LogDebug("Received Version package from " + sender.m_socket.GetEndPointString()); if (!ZNet.instance.IsClientInstance()) { ClientVersions[sender.m_socket.GetEndPointString()] = data; ModuleVersionData serverData = new ModuleVersionData(GetEnforcableMods().ToList()); ModuleVersionData clientData = new ModuleVersionData(data); if (!CompareVersionData(serverData, clientData)) { Logger.LogWarning("RPC_Jotunn_ReceiveVersionData: Disconnecting modded client with incompatible version message. Mods are not compatible"); sender.Invoke("Error", new object[1] { 3 }); } } else { LastServerVersionData = new ServerVersionData(data); } } internal static bool CompareVersionData(ModuleVersionData serverData, ModuleVersionData clientData) { if (serverData == clientData) { return true; } bool result = true; if (!clientData.IsSupportedDataLayout) { Logger.LogWarning("Jotunn version on client is higher than server version: 2.29.1"); result = false; } if (!serverData.IsSupportedDataLayout) { Logger.LogWarning("Jotunn version on server is higher than client version: 2.29.1"); result = false; } foreach (ModModule item in FindNotInstalledMods(serverData, clientData)) { Logger.LogWarning("Missing mod on client: " + item.ModName); result = false; } foreach (ModModule item2 in FindAdditionalMods(serverData, clientData)) { Logger.LogWarning("Client loaded additional mod: " + item2.ModName); result = false; } bool legacyDataLayout = Mathf.Min(serverData.ModModuleDataLayout, clientData.ModModuleDataLayout) == 0; foreach (ModModule item3 in FindLowerVersionMods(serverData, clientData).Union(FindHigherVersionMods(serverData, clientData))) { ModModule modModule = clientData.FindModule(item3, legacyDataLayout); Logger.LogWarning($"Mod version mismatch {item3.ModName}: Server {item3.Version}, Client {modModule.Version}"); result = false; } return result; } private static CompatibilityWindow LoadCompatWindow() { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_014d: Unknown result type (might be due to invalid IL or missing references) CustomLocalization jotunnLocalization = LocalizationManager.Instance.JotunnLocalization; jotunnLocalization.AddJsonFile("English", AssetUtils.LoadTextFromResources("English.json", typeof(Main).Assembly)); jotunnLocalization.AddJsonFile("German", AssetUtils.LoadTextFromResources("German.json", typeof(Main).Assembly)); AssetBundle val = AssetUtils.LoadAssetBundleFromResources("modcompat", typeof(Main).Assembly); GameObject val2 = Object.Instantiate(val.LoadAsset("CompatibilityWindow"), GUIManager.CustomGUIFront.transform); val.Unload(false); CompatibilityWindow component = val2.GetComponent(); RectTransform val3 = (RectTransform)((Component)component).transform; Text[] componentsInChildren = ((Component)component).GetComponentsInChildren(); foreach (Text val4 in componentsInChildren) { GUIManager.Instance.ApplyTextStyle(val4, 18); val4.text = Localization.instance.Localize(val4.text); } GUIManager.Instance.ApplyWoodpanelStyle(((Component)component).transform); GUIManager.Instance.ApplyScrollRectStyle(component.scrollRect); GUIManager.Instance.ApplyButtonStyle(component.continueButton); GUIManager.Instance.ApplyButtonStyle(component.logFileButton); GUIManager.Instance.ApplyButtonStyle(component.troubleshootingButton); val3.anchoredPosition = new Vector2(25f, 0f); ((Component)component).gameObject.SetWidth(1000f); ((Component)component).gameObject.SetHeight(600f); return component; } private static IEnumerator ShowModCompatibilityErrorMessage(string failedConnectionText) { CompatibilityWindow compatWindow = LoadCompatWindow(); ModuleVersionData moduleVersionData = LastServerVersionData.moduleVersionData; ModuleVersionData moduleVersionData2 = new ModuleVersionData(GetEnforcableMods().ToList()); CompareVersionData(moduleVersionData, moduleVersionData2); compatWindow.failedConnection.text = ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_header_failed_connection") + failedConnectionText.Trim(); compatWindow.localVersion.text = ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_header_local_version") + moduleVersionData2.ToString(showEnforce: false).Trim(); compatWindow.remoteVersion.text = ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_header_remote_version") + moduleVersionData.ToString(showEnforce: false).Trim(); compatWindow.errorMessages.text = CreateErrorMessage(moduleVersionData, moduleVersionData2).Trim(); ((Component)compatWindow).transform.localScale = Vector3.zero; yield return null; ((Component)compatWindow).transform.localScale = Vector3.one; compatWindow.UpdateTextPositions(); ((UnityEvent)compatWindow.continueButton.onClick).AddListener((UnityAction)delegate { Object.Destroy((Object)(object)((Component)compatWindow).gameObject); }); ((UnityEvent)compatWindow.logFileButton.onClick).AddListener(new UnityAction(OpenLogFile)); ((UnityEvent)compatWindow.troubleshootingButton.onClick).AddListener(new UnityAction(OpenTroubleshootingPage)); compatWindow.scrollRect.verticalNormalizedPosition = 1f; LastServerVersionData.Reset(); } private static void OpenLogFile() { Application.OpenURL(Paths.BepInExRootPath); } private static void OpenTroubleshootingPage() { Application.OpenURL("https://github.com/Valheim-Modding/Wiki/wiki/Server-Troubleshooting"); } private static string CreateErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { return CreateVanillaVersionErrorMessage(serverData, clientData) + CreateNotInstalledErrorMessage(serverData, clientData) + CreateLowerVersionErrorMessage(serverData, clientData) + CreateHigherVersionErrorMessage(serverData, clientData) + CreateAdditionalModsErrorMessage(serverData, clientData) + CreateFurtherStepsMessage(); } private static string CreateModModuleLayoutErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (!clientData.IsSupportedDataLayout) { return ColoredLine(Color.red, "Jotunn version on client is higher than server version: 2.29.1"); } if (!serverData.IsSupportedDataLayout) { return ColoredLine(Color.red, "Jotunn version on server is higher than client version: 2.29.1"); } if (serverData.ModModuleDataLayout != clientData.ModModuleDataLayout) { return ColoredLine(Color.red, "Jotunn versions on server and client are not compatible."); } return string.Empty; } private static string CreateVanillaVersionErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_010f: Unknown result type (might be due to invalid IL or missing references) if (serverData.NetworkVersion == 0 || clientData.NetworkVersion == 0) { return string.Empty; } if (serverData.NetworkVersion > clientData.NetworkVersion) { return ColoredLine(Color.red, "$mod_compat_header_valheim_version") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_valheim_version_error_description", $"{serverData.NetworkVersion}", $"{clientData.NetworkVersion}") + ColoredLine(Color.white, "$mod_compat_valheim_version_upgrade") + Environment.NewLine; } if (serverData.NetworkVersion < clientData.NetworkVersion) { return ColoredLine(Color.red, "$mod_compat_header_valheim_version") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_valheim_version_error_description", $"{serverData.NetworkVersion}", $"{clientData.NetworkVersion}") + ColoredLine(Color.white, "$mod_compat_valheim_version_downgrade") + Environment.NewLine; } return string.Empty; } private static string CreateNotInstalledErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) List list = FindNotInstalledMods(serverData, clientData); if (list.Count == 0) { return string.Empty; } return ColoredLine(Color.red, "$mod_compat_header_missing_mods") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_missing_mods_description") + string.Join("", list.Select((ModModule serverModule) => ColoredLine(Color.white, "$mod_compat_missing_mod", serverModule.ModName ?? "", $"{serverModule.Version}"))) + Environment.NewLine; } private static string CreateLowerVersionErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) List list = FindLowerVersionMods(serverData, clientData); if (list.Count == 0) { return string.Empty; } return ColoredLine(Color.red, "$mod_compat_header_update_needed") + string.Join("", list.Select((ModModule serverModule) => ColoredLine(Color.white, "$mod_compat_mod_update", serverModule.ModName, serverModule.GetVersionString()))) + Environment.NewLine; } private static string CreateHigherVersionErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) List list = FindHigherVersionMods(serverData, clientData); if (list.Count == 0) { return string.Empty; } return ColoredLine(Color.red, "$mod_compat_header_downgrade_needed") + string.Join("", list.Select((ModModule serverModule) => ColoredLine(Color.white, "$mod_compat_mod_downgrade", serverModule.ModName, serverModule.GetVersionString()))) + Environment.NewLine; } private static string CreateAdditionalModsErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) List list = FindAdditionalMods(serverData, clientData); if (list.Count == 0) { return string.Empty; } return ColoredLine(Color.red, "$mod_compat_header_additional_mods") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_additional_mods_description") + string.Join("", list.Select((ModModule clientModule) => ColoredLine(Color.white, "$mod_compat_additional_mod", clientModule.ModName, $"{clientModule.Version}"))) + Environment.NewLine; } private static string CreateFurtherStepsMessage() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) return ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_header_further_steps") + ColoredLine(Color.white, "$mod_compat_further_steps_description") + Environment.NewLine; } private static List FindNotInstalledMods(ModuleVersionData serverData, ModuleVersionData clientData) { return FindMods(serverData, clientData, (ModModule serverModule, ModModule clientModule) => serverModule.IsNeededOnClient() && clientModule == null).ToList(); } private static List FindAdditionalMods(ModuleVersionData serverData, ModuleVersionData clientData) { return FindMods(clientData, serverData, (ModModule clientModule, ModModule serverModule) => clientModule.IsNeededOnServer() && serverModule == null).ToList(); } private static List FindLowerVersionMods(ModuleVersionData serverData, ModuleVersionData clientData) { return FindMods(serverData, clientData, (ModModule serverModule, ModModule clientModule) => clientModule != null && ModModule.IsLowerVersion(serverModule, clientModule, serverModule.VersionStrictness)).ToList(); } private static List FindHigherVersionMods(ModuleVersionData serverData, ModuleVersionData clientData) { return FindMods(serverData, clientData, (ModModule serverModule, ModModule clientModule) => clientModule != null && ModModule.IsLowerVersion(clientModule, serverModule, serverModule.VersionStrictness)).ToList(); } private static IEnumerable FindMods(ModuleVersionData baseModules, ModuleVersionData additionalModules, Func predicate) { bool legacyDataLayout = Mathf.Min(baseModules.ModModuleDataLayout, additionalModules.ModModuleDataLayout) == 0; foreach (ModModule module in baseModules.Modules) { ModModule arg = additionalModules.FindModule(module, legacyDataLayout); if (predicate(module, arg)) { yield return module; } } } internal static IEnumerable GetEnforcableMods() { foreach (KeyValuePair item in from x in BepInExUtils.GetDependentPlugins(includeJotunn: true) orderby x.Key select x) { NetworkCompatibilityAttribute networkCompatibilityAttribute = item.Value.GetNetworkCompatibilityAttribute(); if (networkCompatibilityAttribute != null) { yield return new ModModule(item.Value.Info.Metadata, networkCompatibilityAttribute); } else { yield return new ModModule(item.Value.Info.Metadata); } } } private static string ColoredLine(Color color, string inner, params string[] words) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return "" + Localization.instance.Localize(inner, words) + "" + Environment.NewLine; } } internal class ModModule { public const int LegacyDataLayoutVersion = 0; public const int CurrentDataLayoutVersion = 1; public static readonly HashSet SupportedDataLayouts = new HashSet { 0, 1 }; private string guid; public int DataLayoutVersion { get; private set; } public string ModID { get { if (DataLayoutVersion != 0) { return guid; } return ModName; } } public string ModName { get; } public Version Version { get; } public CompatibilityLevel CompatibilityLevel { get; } public VersionStrictness VersionStrictness { get; } public bool IsLegacyDataLayout => false; public ModModule(string guid, string name, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness) { DataLayoutVersion = 1; this.guid = guid; ModName = name; Version = version; CompatibilityLevel = compatibilityLevel; VersionStrictness = versionStrictness; } public ModModule(ZPackage pkg, bool legacy) { if (legacy) { DataLayoutVersion = 0; ModName = pkg.ReadString(); int major = pkg.ReadInt(); int minor = pkg.ReadInt(); int num = pkg.ReadInt(); Version = ((num >= 0) ? new Version(major, minor, num) : new Version(major, minor)); CompatibilityLevel = (CompatibilityLevel)pkg.ReadInt(); VersionStrictness = (VersionStrictness)pkg.ReadInt(); return; } DataLayoutVersion = pkg.ReadInt(); if (!IsSupportedDataLayout()) { throw new NotSupportedException($"{DataLayoutVersion} is not a supported data layout version."); } if (DataLayoutVersion == 1) { guid = pkg.ReadString(); ModName = pkg.ReadString(); int major2 = pkg.ReadInt(); int minor2 = pkg.ReadInt(); int num2 = pkg.ReadInt(); Version = ((num2 >= 0) ? new Version(major2, minor2, num2) : new Version(major2, minor2)); CompatibilityLevel = (CompatibilityLevel)pkg.ReadInt(); VersionStrictness = (VersionStrictness)pkg.ReadInt(); } } public void WriteToPackage(ZPackage pkg, bool legacy) { if (legacy) { pkg.Write(ModName); pkg.Write(Version.Major); pkg.Write(Version.Minor); pkg.Write(Version.Build); pkg.Write((int)CompatibilityLevel); pkg.Write((int)VersionStrictness); } else { pkg.Write(DataLayoutVersion); pkg.Write(guid); pkg.Write(ModName); pkg.Write(Version.Major); pkg.Write(Version.Minor); pkg.Write(Version.Build); pkg.Write((int)CompatibilityLevel); pkg.Write((int)VersionStrictness); } } public ModModule(BepInPlugin plugin, NetworkCompatibilityAttribute networkAttribute) { DataLayoutVersion = 1; guid = plugin.GUID; ModName = plugin.Name; Version = plugin.Version; CompatibilityLevel = networkAttribute.EnforceModOnClients; VersionStrictness = networkAttribute.EnforceSameVersion; } public ModModule(BepInPlugin plugin) { DataLayoutVersion = 1; guid = plugin.GUID; ModName = plugin.Name; Version = plugin.Version; CompatibilityLevel = CompatibilityLevel.NotEnforced; VersionStrictness = VersionStrictness.None; } public string GetVersionString() { if (Version.Build >= 0) { return $"{Version.Major}.{Version.Minor}.{Version.Build}"; } return $"{Version.Major}.{Version.Minor}"; } public bool IsNeededOnServer() { if (CompatibilityLevel != CompatibilityLevel.EveryoneMustHaveMod) { return CompatibilityLevel == CompatibilityLevel.ServerMustHaveMod; } return true; } public bool IsNeededOnClient() { if (CompatibilityLevel != CompatibilityLevel.EveryoneMustHaveMod) { return CompatibilityLevel == CompatibilityLevel.ClientMustHaveMod; } return true; } public bool IsNotEnforced() { if (CompatibilityLevel != CompatibilityLevel.NotEnforced) { return CompatibilityLevel == CompatibilityLevel.NoNeedForSync; } return true; } public bool OnlyVersionCheck() { if (CompatibilityLevel != CompatibilityLevel.OnlySyncWhenInstalled) { return CompatibilityLevel == CompatibilityLevel.VersionCheckOnly; } return true; } public bool IsSupportedDataLayout() { return SupportedDataLayouts.Contains(DataLayoutVersion); } public static bool IsLowerVersion(ModModule baseModule, ModModule compareModule, VersionStrictness strictness) { if (strictness == VersionStrictness.None) { return false; } bool flag = compareModule.Version.Major < baseModule.Version.Major; bool flag2 = compareModule.Version.Minor < baseModule.Version.Minor; bool flag3 = compareModule.Version.Build < baseModule.Version.Build; bool flag4 = compareModule.Version.Major == baseModule.Version.Major; bool flag5 = compareModule.Version.Minor == baseModule.Version.Minor; if (strictness >= VersionStrictness.Major && flag) { return true; } if (strictness >= VersionStrictness.Minor && flag2 && (flag || flag4)) { return true; } if (strictness >= VersionStrictness.Patch && flag3 && (flag2 || flag5) && (flag || flag4)) { return true; } return false; } } internal class ModuleVersionData { public Version ValheimVersion { get; internal set; } public List Modules { get; internal set; } = new List(); public string VersionString { get; internal set; } = string.Empty; public uint NetworkVersion { get; internal set; } public int ModModuleDataLayout { get; private set; } public bool IsSupportedDataLayout => ModModule.SupportedDataLayouts.Contains(ModModuleDataLayout); internal ModuleVersionData(List versionData) { ValheimVersion = GameVersions.ValheimVersion; VersionString = GetVersionString(); NetworkVersion = GameVersions.NetworkVersion; Modules = new List(versionData); ModModuleDataLayout = GetModModuleDataLayoutVersion(Modules); } internal ModuleVersionData(Version valheimVersion, List versionData) { ValheimVersion = valheimVersion; VersionString = GetVersionString(); NetworkVersion = GameVersions.NetworkVersion; Modules = new List(versionData); ModModuleDataLayout = GetModModuleDataLayoutVersion(Modules); } internal ModuleVersionData(ZPackage pkg) { try { pkg.SetPos(0); ValheimVersion = new Version(pkg.ReadInt(), pkg.ReadInt(), pkg.ReadInt()); for (int num = pkg.ReadInt(); num > 0; num--) { Modules.Add(new ModModule(pkg, legacy: true)); } if (pkg.m_reader.BaseStream.Position != pkg.m_reader.BaseStream.Length) { VersionString = pkg.ReadString(); } if (pkg.m_reader.BaseStream.Position != pkg.m_reader.BaseStream.Length) { NetworkVersion = pkg.ReadUInt(); } if (pkg.m_reader.BaseStream.Position == pkg.m_reader.BaseStream.Length) { return; } List list = new List(); int num2 = pkg.ReadInt(); int pos = pkg.GetPos(); while (num2 > 0) { try { ModModule item = new ModModule(pkg, legacy: false); list.Add(item); num2--; } catch (NotSupportedException ex) { pkg.SetPos(pos); ModModuleDataLayout = pkg.ReadInt(); Logger.LogError($"Could not parse unsupported data layout version {ModModuleDataLayout} from zPackage"); Logger.LogError(ex.Message); break; } } Modules = list; ModModuleDataLayout = GetModModuleDataLayoutVersion(Modules); } catch (Exception ex2) { Logger.LogError("Could not deserialize version message data from zPackage"); Logger.LogError(ex2.Message); } } public ZPackage ToZPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(ValheimVersion.Major); val.Write(ValheimVersion.Minor); val.Write(ValheimVersion.Build); val.Write(Modules.Count); foreach (ModModule module in Modules) { module.WriteToPackage(val, legacy: true); } val.Write(VersionString); val.Write(NetworkVersion); val.Write(Modules.Count); foreach (ModModule module2 in Modules) { module2.WriteToPackage(val, legacy: false); } return val; } public override int GetHashCode() { return (((ValheimVersion != null) ? ValheimVersion.GetHashCode() : 0) * 397) ^ ((Modules != null) ? Modules.GetHashCode() : 0); } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); if (string.IsNullOrEmpty(VersionString)) { stringBuilder.AppendLine($"Valheim {ValheimVersion.Major}.{ValheimVersion.Minor}.{ValheimVersion.Build}"); } else { stringBuilder.AppendLine("Valheim " + VersionString); } foreach (ModModule module in Modules) { stringBuilder.AppendLine($"{module.ModName} {module.GetVersionString()} {module.CompatibilityLevel} {module.VersionStrictness}"); } return stringBuilder.ToString(); } public string ToString(bool showEnforce) { StringBuilder stringBuilder = new StringBuilder(); string text = VersionString; if (string.IsNullOrEmpty(text)) { text = $"Valheim {ValheimVersion.Major}.{ValheimVersion.Minor}.{ValheimVersion.Build}"; } if (NetworkVersion != 0) { stringBuilder.AppendLine($"Valheim {text} (n-{NetworkVersion})"); } else { stringBuilder.AppendLine("Valheim " + text); } foreach (ModModule module in Modules) { stringBuilder.AppendLine(module.ModName + " " + module.GetVersionString() + (showEnforce ? $" {module.CompatibilityLevel} {module.VersionStrictness}" : "")); } return stringBuilder.ToString(); } public ModModule FindModule(ModModule modModule, bool legacyDataLayout) { if (legacyDataLayout) { return Modules.FirstOrDefault((ModModule x) => x.ModName == modModule.ModName); } return Modules.FirstOrDefault((ModModule x) => x.ModID == modModule.ModID); } public bool HasModule(ModModule modModule, bool legacyDataLayout) { return FindModule(modModule, legacyDataLayout) != null; } private static string GetVersionString() { return Version.GetVersionString(false).Replace("-ServerCharacters", ""); } private static int GetModModuleDataLayoutVersion(List modules) { if (modules.Any((ModModule x) => x.DataLayoutVersion != modules.FirstOrDefault()?.DataLayoutVersion)) { throw new NotSupportedException("DataVersionLayout is not the same for all ModModule instances."); } return modules.FirstOrDefault()?.DataLayoutVersion ?? 1; } } public enum CompatibilityLevel { [Obsolete("Use NotEnforced instead")] NoNeedForSync, [Obsolete("Use VersionCheckOnly")] OnlySyncWhenInstalled, EveryoneMustHaveMod, ClientMustHaveMod, ServerMustHaveMod, VersionCheckOnly, NotEnforced } public enum VersionStrictness { None, Major, Minor, Patch } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class)] public class NetworkCompatibilityAttribute : Attribute { public CompatibilityLevel EnforceModOnClients { get; set; } public VersionStrictness EnforceSameVersion { get; set; } public NetworkCompatibilityAttribute(CompatibilityLevel enforceMod, VersionStrictness enforceVersion) { EnforceModOnClients = enforceMod; EnforceSameVersion = enforceVersion; } } internal class ServerVersionData { public ModuleVersionData moduleVersionData { get; set; } public HashSet moduleGUIDs { get; set; } internal ServerVersionData() { } internal ServerVersionData(List versionData) { moduleVersionData = new ModuleVersionData(versionData); moduleGUIDs = new HashSet((from x in moduleVersionData.Modules where x.ModID != null select x.ModID).ToList()); } internal ServerVersionData(Version valheimVersion, List versionData) { moduleVersionData = new ModuleVersionData(valheimVersion, versionData); moduleGUIDs = new HashSet((from x in moduleVersionData.Modules where x.ModID != null select x.ModID).ToList()); } internal ServerVersionData(ZPackage pkg) { moduleVersionData = new ModuleVersionData(pkg); moduleGUIDs = new HashSet((from x in moduleVersionData.Modules where x.ModID != null select x.ModID).ToList()); } internal bool IsValid() { if (moduleVersionData != null) { return moduleGUIDs != null; } return false; } internal void Reset() { moduleVersionData = null; moduleGUIDs = null; } } public enum AdminOnlyStrictness { Always, IfOnServer } [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class)] public class SynchronizationModeAttribute : Attribute { public AdminOnlyStrictness EnforceAdminOnly { get; set; } public SynchronizationModeAttribute(AdminOnlyStrictness enforceAdminOnly) { EnforceAdminOnly = enforceAdminOnly; } public bool ShouldAlwaysEnforceAdminOnly() { return EnforceAdminOnly == AdminOnlyStrictness.Always; } } public class ModQuery { private class ModPrefab : IModPrefab { public GameObject Prefab { get; } public BepInPlugin SourceMod { get; } public ModPrefab(GameObject prefab, BepInPlugin mod) { Prefab = prefab; SourceMod = mod; } } private class ZNetSceneState { public bool valid; public readonly Dictionary namedPrefabs; public readonly List prefabs; public ZNetSceneState(ZNetScene zNetScene) { valid = Object.op_Implicit((Object)(object)zNetScene); if (valid) { namedPrefabs = new Dictionary(zNetScene.m_namedPrefabs); prefabs = new List(zNetScene.m_prefabs); } } public void AddNewPrefabs(ZNetScene zNetScene, PluginInfo plugin) { if (valid && Object.op_Implicit((Object)(object)zNetScene)) { AddPrefabs(namedPrefabs, zNetScene.m_namedPrefabs, plugin.Metadata); AddPrefabs(prefabs, zNetScene.m_prefabs, plugin.Metadata); } } } private class ObjectDBState { public bool valid; public List items; public List recipes; public Dictionary itemByHash; public ObjectDBState(ObjectDB objectDB) { valid = Object.op_Implicit((Object)(object)objectDB); if (valid) { items = new List(objectDB.m_items); recipes = new List(objectDB.m_recipes); itemByHash = new Dictionary(objectDB.m_itemByHash); } } public void AddNewPrefabs(ObjectDB objectDB, PluginInfo plugin) { if (valid && Object.op_Implicit((Object)(object)objectDB)) { AddPrefabs(items, objectDB.m_items, plugin.Metadata); AddPrefabs(itemByHash, objectDB.m_itemByHash, plugin.Metadata); AddRecipes(recipes, objectDB.m_recipes, plugin.Metadata); } } } private static readonly Dictionary> Prefabs = new Dictionary>(); private static readonly Dictionary> Recipes = new Dictionary>(); private static Tuple state; private static readonly HashSet PatchedMethods = new HashSet(); private static readonly HarmonyMethod PrePatch = new HarmonyMethod(AccessTools.Method(typeof(ModQuery), "BeforePatch", (Type[])null, (Type[])null)); private static readonly HarmonyMethod PostPatch = new HarmonyMethod(AccessTools.Method(typeof(ModQuery), "AfterPatch", (Type[])null, (Type[])null)); private static bool enabled = false; internal static void Init() { Main.LogInit("ModQuery"); Main.Harmony.PatchAll(typeof(ModQuery)); } public static void Enable() { if (!enabled) { Init(); } enabled = true; } public static IEnumerable GetPrefabs() { List list = new List(); foreach (KeyValuePair> prefab in Prefabs) { list.AddRange(prefab.Value.Values); } list.AddRange(PrefabManager.Instance.Prefabs.Values); return list; } public static IEnumerable GetPrefabs(string modGuid) { List list = new List(); list.AddRange(Prefabs[modGuid].Values); list.AddRange(PrefabManager.Instance.Prefabs.Values.Where((CustomPrefab x) => x.SourceMod.GUID.Equals(modGuid))); return list; } public static IModPrefab GetPrefab(string name) { int stableHashCode = StringExtensionMethods.GetStableHashCode(name); if (PrefabManager.Instance.Prefabs.TryGetValue(name, out var value)) { return value; } foreach (KeyValuePair> prefab in Prefabs) { if (prefab.Value.ContainsKey(stableHashCode)) { return prefab.Value[stableHashCode]; } } return null; } [HarmonyPatch(typeof(ZNetScene), "OnDestroy")] [HarmonyPostfix] private static void ZNetSceneOnDestroy() { Prefabs.Clear(); Recipes.Clear(); } [HarmonyPatch(typeof(FejdStartup), "Awake")] [HarmonyPostfix] private static void FejdStartup_Awake_Postfix() { FindAndPatchPatches(AccessTools.Method(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null)); FindAndPatchPatches(AccessTools.Method(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null)); FindAndPatchPatches(AccessTools.Method(typeof(ObjectDB), "CopyOtherDB", (Type[])null, (Type[])null)); FindAndPatchPatches(AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null)); } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPrefix] [HarmonyPriority(1000)] private static void ObjectDBAwake(ObjectDB __instance) { __instance.UpdateRegisters(); } private static void FindAndPatchPatches(MethodBase methodInfo) { PatchPatches(Harmony.GetPatchInfo(methodInfo)?.Prefixes); PatchPatches(Harmony.GetPatchInfo(methodInfo)?.Postfixes); PatchPatches(Harmony.GetPatchInfo(methodInfo)?.Finalizers); } private static void PatchPatches(ICollection patches) { if (patches == null) { return; } foreach (Patch patch in patches) { if (!(patch.owner == "com.jotunn.jotunn") && !PatchedMethods.Contains(patch.PatchMethod)) { PatchedMethods.Add(patch.PatchMethod); try { Main.Harmony.Patch((MethodBase)patch.PatchMethod, PrePatch, PostPatch, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } catch (Exception) { Logger.LogWarning($"Failed to patch {patch.PatchMethod} from {patch.owner}"); } } } } private static void BeforePatch(object[] __args) { ObjectDB objectDB = GetObjectDB(__args); ZNetScene zNetScene = GetZNetScene(__args); state = new Tuple(new ZNetSceneState(zNetScene), new ObjectDBState(objectDB)); } private static void AfterPatch(object[] __args) { if (state != null && (state.Item1.valid || state.Item2.valid)) { PluginInfo pluginInfoFromAssembly = BepInExUtils.GetPluginInfoFromAssembly(ReflectionHelper.GetCallingAssembly()); if (pluginInfoFromAssembly != null) { state.Item1.AddNewPrefabs(GetZNetScene(__args), pluginInfoFromAssembly); state.Item2.AddNewPrefabs(GetObjectDB(__args), pluginInfoFromAssembly); } } } private static void AddPrefabs(IEnumerable before, IEnumerable after, BepInPlugin plugin) { AddPrefabs(new HashSet(before), new HashSet(after), plugin); } private static void AddPrefabs(Dictionary before, Dictionary after, BepInPlugin plugin) { AddPrefabs(new HashSet(before.Values), new HashSet(after.Values), plugin); } private static void AddPrefabs(HashSet before, HashSet after, BepInPlugin plugin) { if (!Prefabs.ContainsKey(plugin.GUID)) { Prefabs.Add(plugin.GUID, new Dictionary()); } foreach (GameObject item in after) { if (Object.op_Implicit((Object)(object)item) && !before.Contains(item)) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)item).name); if (!Prefabs[plugin.GUID].ContainsKey(stableHashCode)) { Prefabs[plugin.GUID].Add(stableHashCode, new ModPrefab(item, plugin)); } } } } private static void AddRecipes(IEnumerable before, IEnumerable after, BepInPlugin plugin) { AddRecipes(new HashSet(before), new HashSet(after), plugin); } private static void AddRecipes(HashSet before, HashSet after, BepInPlugin plugin) { if (!Recipes.ContainsKey(plugin.GUID)) { Recipes.Add(plugin.GUID, new List()); } foreach (Recipe item in after) { if (!before.Contains(item) && !Recipes[plugin.GUID].Contains(item)) { Recipes[plugin.GUID].Add(item); } } } private static ZNetScene GetZNetScene(object[] __args) { foreach (object obj in __args) { ZNetScene val = (ZNetScene)((obj is ZNetScene) ? obj : null); if (val != null) { return val; } } return ZNetScene.instance; } private static ObjectDB GetObjectDB(object[] __args) { foreach (object obj in __args) { ObjectDB val = (ObjectDB)((obj is ObjectDB) ? obj : null); if (val != null) { return val; } } return ObjectDB.instance; } } public static class ModRegistry { public class ModInfo { public string GUID { get; internal set; } public string Name { get; internal set; } public Version Version { get; internal set; } public IEnumerable Prefabs => GetPrefabs(GUID); public IEnumerable Items => GetItems(GUID); public IEnumerable Recipes => GetRecipes(GUID); public IEnumerable ItemConversions => GetItemConversions(GUID); public IEnumerable StatusEffects => GetStatusEffects(GUID); public IEnumerable PieceTables => GetPieceTables(GUID); public IEnumerable Pieces => GetPieces(GUID); public IEnumerable Locations => GetLocations(GUID); public IEnumerable Vegetation => GetVegetation(GUID); public IEnumerable Clutter => GetClutter(GUID); public IEnumerable Creatures => GetCreatures(GUID); public IEnumerable Commands => GetCommands(GUID); public IEnumerable Translations => GetTranslations(GUID); } public static IEnumerable GetMods(bool includingJotunn = false) { return BepInExUtils.GetDependentPlugins(includingJotunn).Values.Select((BaseUnityPlugin mod) => new ModInfo { GUID = mod.Info.Metadata.GUID, Name = mod.Info.Metadata.Name, Version = mod.Info.Metadata.Version }); } public static IEnumerable GetPrefabs() { return PrefabManager.Instance.Prefabs.Values; } public static IEnumerable GetPrefabs(string modGuid) { return GetPrefabs().FilterByMod(modGuid); } public static IEnumerable GetItems() { return ItemManager.Instance.Items.Values; } public static IEnumerable GetItems(string modGuid) { return GetItems().FilterByMod(modGuid); } public static IEnumerable GetRecipes() { return ItemManager.Instance.Recipes; } public static IEnumerable GetRecipes(string modGuid) { return GetRecipes().FilterByMod(modGuid); } public static IEnumerable GetItemConversions() { return ItemManager.Instance.ItemConversions; } public static IEnumerable GetItemConversions(string modGuid) { return GetItemConversions().FilterByMod(modGuid); } public static IEnumerable GetStatusEffects() { return ItemManager.Instance.StatusEffects; } public static IEnumerable GetStatusEffects(string modGuid) { return GetStatusEffects().FilterByMod(modGuid); } public static IEnumerable GetPieceTables() { return PieceManager.Instance.PieceTables.AsReadOnly(); } public static IEnumerable GetPieceTables(string modGuid) { return GetPieceTables().FilterByMod(modGuid); } public static IEnumerable GetPieces() { return PieceManager.Instance.Pieces.Values; } public static IEnumerable GetPieces(string modGuid) { return GetPieces().FilterByMod(modGuid); } public static IEnumerable GetLocations() { return ZoneManager.Instance.Locations.Values; } public static IEnumerable GetLocations(string modGuid) { return GetLocations().FilterByMod(modGuid); } public static IEnumerable GetVegetation() { return ZoneManager.Instance.Vegetations.Values; } public static IEnumerable GetVegetation(string modGuid) { return ZoneManager.Instance.Vegetations.Values.Where((CustomVegetation x) => x.SourceMod.GUID.Equals(modGuid)); } public static IEnumerable GetClutter() { return ZoneManager.Instance.Clutter.Values; } public static IEnumerable GetClutter(string modGuid) { return GetClutter().FilterByMod(modGuid); } public static IEnumerable GetCreatures() { return CreatureManager.Instance.Creatures.AsReadOnly(); } public static IEnumerable GetCreatures(string modGuid) { return GetCreatures().FilterByMod(modGuid); } public static IEnumerable GetCommands() { return CommandManager.Instance.CustomCommands; } public static IEnumerable GetCommands(string modGuid) { return GetCommands().FilterByMod(modGuid); } public static IEnumerable GetTranslations() { return LocalizationManager.Instance.Localizations.Values; } public static IEnumerable GetTranslations(string modGuid) { return GetTranslations().FilterByMod(modGuid); } private static IEnumerable FilterByMod(this IEnumerable list, string modGuid) where T : CustomEntity { return list.Where((T x) => x.SourceMod.GUID == modGuid); } } internal class PatchInit { [Obsolete] internal static void InitializePatches() { List> list = new List>(); HashSet hashSet = new HashSet(); foreach (BaseUnityPlugin value in BepInExUtils.GetDependentPlugins().Values) { try { Assembly assembly = ((object)value).GetType().Assembly; if (hashSet.Contains(assembly)) { continue; } hashSet.Add(assembly); Type[] types = assembly.GetTypes(); foreach (Type type in types) { try { foreach (MethodInfo item in from x in type.GetMethods(BindingFlags.Static | BindingFlags.Public) where x.GetCustomAttributes(typeof(PatchInitAttribute), inherit: false).Length == 1 select x) { PatchInitAttribute patchInitAttribute = item.GetCustomAttributes(typeof(PatchInitAttribute), inherit: false).FirstOrDefault() as PatchInitAttribute; list.Add(new Tuple(item, patchInitAttribute.Priority)); } } catch (Exception) { } } } catch (Exception) { } } foreach (Tuple item2 in list.OrderBy((Tuple x) => x.Item2)) { Logger.LogDebug("Applying patches in " + item2.Item1.DeclaringType.Name + "." + item2.Item1.Name); item2.Item1.Invoke(null, null); } } } [AttributeUsage(AttributeTargets.Method)] [Obsolete("Use Harmony patches or your Start method instead")] public class PatchInitAttribute : Attribute { public int Priority { get; set; } public PatchInitAttribute(int priority) { Priority = priority; } } public static class Paths { public static string JotunnFolder { get { string saveDataPath = Utils.GetSaveDataPath((FileSource)1); return Path.Combine(saveDataPath, "Jotunn"); } } public static string CustomItemDataFolder => Path.Combine(JotunnFolder, "CustomItemData"); public static string LanguageTranslationsFolder => Paths.PluginPath; public static string IconCachePath => Path.Combine(JotunnFolder, "CachedIcons"); } internal static class PieceUtils { public static PieceCategory VanillaMaxPieceCategory { get; } = GetVanillaPieceCategory("Max", (PieceCategory)8); public static PieceCategory VanillaAllPieceCategory { get; } = GetVanillaPieceCategory("All", (PieceCategory)100); private static PieceCategory GetVanillaPieceCategory(string name, PieceCategory fallback) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: 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) try { return (PieceCategory)Enum.Parse(typeof(PieceCategory), name); } catch (Exception) { Logger.LogWarning($"Could not find Piece.PieceCategory {name}, using fallback value {fallback}"); return fallback; } } } public static class ReflectionHelper { public static class Cache { private static MethodInfo _enumerableToArray; private static MethodInfo _enumerableToList; private static MethodInfo _enumerableCast; public static MethodInfo EnumerableToArray { get { if (_enumerableToArray == null) { _enumerableToArray = typeof(Enumerable).GetMethod("ToArray", (BindingFlags)(-1)); } return _enumerableToArray; } } public static MethodInfo EnumerableToList { get { if (_enumerableToList == null) { _enumerableToList = typeof(Enumerable).GetMethod("ToList", (BindingFlags)(-1)); } return _enumerableToList; } } public static MethodInfo EnumerableCast { get { if (_enumerableCast == null) { _enumerableCast = typeof(Enumerable).GetMethod("Cast", (BindingFlags)(-1)); } return _enumerableCast; } } } public const BindingFlags AllBindingFlags = (BindingFlags)(-1); public static bool IsSameOrSubclass(this Type type, Type @base) { if (!type.IsSubclassOf(@base)) { return type == @base; } return true; } public static bool HasImplementedRawGeneric(this Type type, Type generic) { if (type == null) { throw new ArgumentNullException("type"); } if (generic == null) { throw new ArgumentNullException("generic"); } if (type.GetInterfaces().Any(IsTheRawGenericType)) { return true; } while (type != null && type != typeof(object)) { if (IsTheRawGenericType(type)) { return true; } type = type.BaseType; } return false; bool IsTheRawGenericType(Type test) { return generic == (test.IsGenericType ? test.GetGenericTypeDefinition() : test); } } public static bool IsEnumerable(this Type type) { if (typeof(IEnumerable).IsAssignableFrom(type)) { return type != typeof(string); } return false; } public static Type GetEnumeratedType(this Type type) { object obj = type?.GetElementType(); if (obj == null) { if (!typeof(IEnumerable).IsAssignableFrom(type)) { return null; } obj = type.GetGenericArguments().FirstOrDefault(); } return (Type)obj; } public static Type GetCallingType() { return (new StackTrace().GetFrames() ?? Array.Empty()).First((StackFrame x) => x.GetMethod().ReflectedType?.Assembly != typeof(Main).Assembly).GetMethod().ReflectedType; } public static Assembly GetCallingAssembly() { return (new StackTrace().GetFrames() ?? Array.Empty()).First((StackFrame x) => x.GetMethod().ReflectedType?.Assembly != typeof(Main).Assembly).GetMethod().ReflectedType?.Assembly; } public static object InvokePrivate(object instance, string name, object[] args = null) { MethodInfo method = instance.GetType().GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic); if (method == null) { Type[] types = ((args == null) ? Type.EmptyTypes : args.Select((object arg) => arg.GetType()).ToArray()); method = instance.GetType().GetMethod(name, types); } if (method == null) { Logger.LogError("Method " + name + " does not exist on type: " + instance.GetType()); return null; } return method.Invoke(instance, args); } public static T GetPrivateProperty(object instance, string name) { PropertyInfo property = instance.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic); if (property == null) { Logger.LogError("Property " + name + " does not exist on type: " + instance.GetType()); return default(T); } return (T)property.GetValue(instance); } public static T GetPrivateField(object instance, string name) { FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { Logger.LogError("Variable " + name + " does not exist on type: " + instance.GetType()); return default(T); } return (T)field.GetValue(instance); } public static T GetPrivateField(Type type, string name) { FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.NonPublic); if (field == null) { Logger.LogError("Variable " + name + " does not exist on type: " + type); return default(T); } return (T)field.GetValue(null); } public static void SetPrivateField(object instance, string name, object value) { FieldInfo field = instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { Logger.LogError("Variable " + name + " does not exist on type: " + instance.GetType()); } else { field.SetValue(instance, value); } } } public static class ShaderHelper { public static List GetRenderers(GameObject gameObject) { List list = new List(); list.AddRange((IEnumerable)(object)gameObject.GetComponentsInChildren(true)); list.AddRange((IEnumerable)(object)gameObject.GetComponentsInChildren(true)); return list; } public static List GetRendererMaterials(GameObject gameObject) { List list = new List(); foreach (Renderer renderer in GetRenderers(gameObject)) { list.AddRange(renderer.materials); } return list; } public static List GetRendererSharedMaterials(GameObject gameObject) { List list = new List(); foreach (Renderer renderer in GetRenderers(gameObject)) { list.AddRange(renderer.sharedMaterials); } return list; } public static List GetAllRendererMaterials(GameObject gameObject) { List list = new List(); foreach (Renderer renderer in GetRenderers(gameObject)) { list.AddRange(renderer.materials); list.AddRange(renderer.sharedMaterials); } return list; } public static Texture2D CreateScaledTexture(Texture2D texture, int width) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown Texture2D val = new Texture2D(((Texture)texture).width, ((Texture)texture).height, texture.format, false); val.SetPixels(texture.GetPixels()); val.Apply(); ScaleTexture(val, width); return val; } public static void ScaleTexture(Texture2D texture, int width) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(((Texture)texture).width, ((Texture)texture).height, texture.format, false); val.SetPixels(texture.GetPixels()); val.Apply(); int num = (int)Math.Round((float)width * (float)((Texture)texture).height / (float)((Texture)texture).width); texture.Reinitialize(width, num); texture.Apply(); Color[] pixels = texture.GetPixels(0); float num2 = 1f / (float)width; float num3 = 1f / (float)num; for (int i = 0; i < pixels.Length; i++) { pixels[i] = val.GetPixelBilinear(num2 * ((float)i % (float)width), num3 * Mathf.Floor((float)i / (float)width)); } texture.SetPixels(pixels, 0); texture.Apply(); Object.Destroy((Object)(object)val); } public static void ShaderDump(GameObject gameObject) { List rendererMaterials = GetRendererMaterials(gameObject); foreach (Material item in rendererMaterials) { Logger.LogDebug(((object)item.shader).ToString()); string[] shaderKeywords = item.shaderKeywords; foreach (string data in shaderKeywords) { Logger.LogDebug(data); } string[] texturePropertyNames = item.GetTexturePropertyNames(); foreach (string data2 in texturePropertyNames) { Logger.LogDebug(data2); } for (int k = 0; k < item.shader.GetPropertyCount(); k++) { Logger.LogDebug(item.shader.GetPropertyName(k)); } } } } public class SyncingConfigurationEventArgs : EventArgs { } public static class UndoActions { private static class UndoHelper { private static Dictionary> clonedFloats = new Dictionary>(); private static Dictionary> clonedVec3 = new Dictionary>(); private static Dictionary> clonedQuats = new Dictionary>(); private static Dictionary> clonedInts = new Dictionary>(); private static Dictionary> clonedLongs = new Dictionary>(); private static Dictionary> clonedStrings = new Dictionary>(); private static Dictionary> clonedByteArrays = new Dictionary>(); public static void CopyData(ZDO from, ZDO to) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) bool flag = to.m_prefab != from.m_prefab; to.m_prefab = from.m_prefab; to.m_position = from.m_position; to.m_rotation = from.m_rotation; ApplyZDOExtraData(to.m_uid, from); ZNetScene instance = ZNetScene.instance; if (instance.m_instances.TryGetValue(to, out var value)) { Transform transform = ((Component)value).transform; transform.position = from.m_position; transform.rotation = Quaternion.Euler(from.m_rotation); transform.localScale = from.GetVec3("scale", Vector3.one); if (flag) { GameObject val = ZNetScene.instance.CreateObject(to); if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)((Component)value).gameObject); ZNetScene.instance.m_instances[to] = val.GetComponent(); } } } to.IncreaseDataRevision(); } public static void ApplyZDOExtraData(ZDOID id, ZDO zdo) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) ZDOExtraData.s_floats[id] = CloneBinarySearchDictionary(clonedFloats[zdo]); ZDOExtraData.s_vec3[id] = CloneBinarySearchDictionary(clonedVec3[zdo]); ZDOExtraData.s_quats[id] = CloneBinarySearchDictionary(clonedQuats[zdo]); ZDOExtraData.s_ints[id] = CloneBinarySearchDictionary(clonedInts[zdo]); ZDOExtraData.s_longs[id] = CloneBinarySearchDictionary(clonedLongs[zdo]); ZDOExtraData.s_strings[id] = CloneBinarySearchDictionary(clonedStrings[zdo]); ZDOExtraData.s_byteArrays[id] = CloneBinarySearchDictionary(clonedByteArrays[zdo]); } public static ZDO Place(ZDO zdo) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) GameObject prefab = ZNetScene.instance.GetPrefab(zdo.GetPrefab()); if (!Object.op_Implicit((Object)(object)prefab)) { throw new InvalidOperationException("Invalid prefab"); } GameObject val = Object.Instantiate(prefab, zdo.GetPosition(), zdo.GetRotation()); ZNetView component = val.GetComponent(); if (!Object.op_Implicit((Object)(object)component)) { throw new InvalidOperationException("No view"); } ZDO zDO = component.GetZDO(); component.SetLocalScale(zdo.GetVec3("scale", val.transform.localScale)); CopyData(zdo, zDO); return zDO; } public static ZDO[] Place(ZDO[] data) { return (from obj in data.Select(Place) where obj != null select obj).ToArray(); } public static string Name(ZDO zdo) { return Utils.GetPrefabName(ZNetScene.instance.GetPrefab(zdo.GetPrefab())); } public static string Print(ZDO[] data) { if (data.Length == 1) { return Name(data.First()); } IEnumerable> enumerable = data.GroupBy(Name); IGrouping[] array = (enumerable as IGrouping[]) ?? enumerable.ToArray(); if (array.Length == 1) { return $"{array.First().Key} {array.First().Count()}x"; } return $" objects {data.Length}x"; } public static ZDO[] Remove(ZDO[] toRemove) { ZDO[] result = Clone(toRemove); foreach (ZDO zdo in toRemove) { RemoveZDO(zdo); } return result; } public static ZDO[] Clone(IEnumerable data) { return data.Select(CloneZDO).ToArray(); } private static ZDO CloneZDO(ZDO zdo) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) ZDO val = zdo.Clone(); val.SaveClone = false; clonedFloats[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_floats); clonedVec3[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_vec3); clonedQuats[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_quats); clonedInts[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_ints); clonedLongs[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_longs); clonedStrings[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_strings); clonedByteArrays[val] = CloneBinarySearchDictionary(val.m_uid, ZDOExtraData.s_byteArrays); return val; } public static void RemoveZDO(ZDO zdo) { if (IsValid(zdo)) { if (!zdo.IsOwner()) { zdo.SetOwner(ZDOMan.GetSessionID()); } if (ZNetScene.instance.m_instances.TryGetValue(zdo, out var value)) { ZNetScene.instance.Destroy(((Component)value).gameObject); } else { ZDOMan.instance.DestroyZDO(zdo); } } } public static bool IsValid(ZNetView view) { if (Object.op_Implicit((Object)(object)view)) { return IsValid(view.GetZDO()); } return false; } public static bool IsValid(ZDO zdo) { if (zdo != null) { return zdo.IsValid(); } return false; } public static void ApplyData(Dictionary data, Vector3 pos, float radius) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair datum in data) { TerrainComp val = TerrainComp.FindTerrainCompiler(datum.Key); if (Object.op_Implicit((Object)(object)val)) { HeightUndoData[] heights = datum.Value.Heights; foreach (HeightUndoData heightUndoData in heights) { val.m_smoothDelta[heightUndoData.Index] = heightUndoData.Smooth; val.m_levelDelta[heightUndoData.Index] = heightUndoData.Level; val.m_modifiedHeight[heightUndoData.Index] = heightUndoData.HeightModified; } PaintUndoData[] paints = datum.Value.Paints; foreach (PaintUndoData paintUndoData in paints) { val.m_modifiedPaint[paintUndoData.Index] = paintUndoData.PaintModified; val.m_paintMask[paintUndoData.Index] = paintUndoData.Paint; } Save(val); } } ClutterSystem instance = ClutterSystem.instance; if (instance != null) { instance.ResetGrass(pos, radius); } } public static void Save(TerrainComp compiler) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)compiler).GetComponent(); if (component != null) { component.ClaimOwnership(); } compiler.m_operations++; compiler.m_lastOpPoint = Vector3.zero; compiler.m_lastOpRadius = 0f; compiler.Save(); compiler.m_hmap.Poke(false); } public static BinarySearchDictionary CloneBinarySearchDictionary(BinarySearchDictionary dict) where TKey : IComparable { return dict.Clone() as BinarySearchDictionary; } public static BinarySearchDictionary CloneBinarySearchDictionary(ZDOID id, Dictionary> dict) where TKey : IComparable { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return CloneBinarySearchDictionary(ZDOHelper.GetValueOrDefaultPiktiv>((IDictionary>)dict, id, new BinarySearchDictionary())); } } public class UndoCreate : UndoManager.IUndoAction { public ZDO[] Data; public UndoCreate(IEnumerable data) { Data = UndoHelper.Clone(data); } public string Description() { return "Created " + UndoHelper.Print(Data); } public virtual void Undo() { Data = UndoHelper.Remove(Data); } public string UndoMessage() { return "Undo: Removed " + UndoHelper.Print(Data); } public virtual void Redo() { Data = UndoHelper.Place(Data); } public string RedoMessage() { return "Redo: Restored " + UndoHelper.Print(Data); } } public class UndoRemove : UndoManager.IUndoAction { public ZDO[] Data; public UndoRemove(IEnumerable data) { Data = UndoHelper.Clone(data); } public string Description() { return "Removed " + UndoHelper.Print(Data); } public virtual void Undo() { Data = UndoHelper.Place(Data); } public string UndoMessage() { return "Undo: Restored " + UndoHelper.Print(Data); } public virtual void Redo() { Data = UndoHelper.Remove(Data); } public string RedoMessage() { return "Redo: Removed " + UndoHelper.Print(Data); } } public class HeightUndoData { public float Smooth; public float Level; public int Index = -1; public bool HeightModified; } public class PaintUndoData { public bool PaintModified; public Color Paint = Color.black; public int Index = -1; } public class TerrainUndoData { public HeightUndoData[] Heights = new HeightUndoData[0]; public PaintUndoData[] Paints = new PaintUndoData[0]; } public class UndoTerrain : UndoManager.IUndoAction { private readonly Dictionary Before; private readonly Dictionary After; private readonly Vector3 Position; private readonly float Radius; public UndoTerrain(Dictionary before, Dictionary after, Vector3 position, float radius) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Before = before; After = after; Position = position; Radius = radius; } public string Description() { return "Changed terrain"; } public virtual void Undo() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) UndoHelper.ApplyData(Before, Position, Radius); } public string UndoMessage() { return "Undoing terrain changes"; } public virtual void Redo() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) UndoHelper.ApplyData(After, Position, Radius); } public string RedoMessage() { return "Redoing terrain changes"; } } } public class WeightedList where T : WeightedItem { public readonly List List; public WeightedList() { List = new List(); } public void Add(T item) { List.Add(item); } public bool Remove(T item) { return List.Remove(item); } public ItemType GetRandomItem(List list = null) { if (list == null) { list = List; } float num = 0f; foreach (T item in list) { num += item.Weight; } float num2 = Random.Range(0f, num - 1f); foreach (T item2 in list) { if (num2 < item2.Weight) { return item2.Item; } num2 -= item2.Weight; } throw new Exception("No item in weighted list"); } } public class WeightedItem { public T Item { get; private set; } public virtual float Weight { get; set; } public WeightedItem(T item, float weight = 0f) { Item = item; if (weight != 0f) { Weight = weight; } } } } namespace Jotunn.GUI { public class ColorPicker : MonoBehaviour { public delegate void ColorEvent(Color c); private sealed class HSV { public double H; public double S = 1.0; public double V = 1.0; public byte A = byte.MaxValue; public HSV() { } public HSV(double h, double s, double v) { H = h; S = s; V = v; } public HSV(Color color) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b)); float num2 = Mathf.Min(color.r, Mathf.Min(color.g, color.b)); float num3 = (float)H; if (num2 != num) { num3 = ((num == color.r) ? ((color.g - color.b) / (num - num2)) : ((num != color.g) ? (4f + (color.r - color.g) / (num - num2)) : (2f + (color.b - color.r) / (num - num2)))) * 60f; if (num3 < 0f) { num3 += 360f; } } H = num3; S = ((num == 0f) ? 0.0 : (1.0 - (double)num2 / (double)num)); V = num; A = (byte)(color.a * 255f); } public Color32 ToColor() { //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) int num = Convert.ToInt32(Math.Floor(H / 60.0)) % 6; double num2 = H / 60.0 - Math.Floor(H / 60.0); double num3 = V * 255.0; byte b = (byte)Convert.ToInt32(num3); byte b2 = (byte)Convert.ToInt32(num3 * (1.0 - S)); byte b3 = (byte)Convert.ToInt32(num3 * (1.0 - num2 * S)); byte b4 = (byte)Convert.ToInt32(num3 * (1.0 - (1.0 - num2) * S)); return (Color32)(num switch { 0 => new Color32(b, b4, b2, A), 1 => new Color32(b3, b, b2, A), 2 => new Color32(b2, b, b4, A), 3 => new Color32(b2, b3, b, A), 4 => new Color32(b4, b2, b, A), 5 => new Color32(b, b2, b3, A), _ => default(Color32), }); } } private static ColorPicker instance; public static bool done = true; private static ColorEvent onCC; private static ColorEvent onCS; private static Color32 originalColor; private static Color32 modifiedColor; private static HSV modifiedHsv; private static bool useA; private bool interact; public RectTransform positionIndicator; public Slider mainComponent; public Slider rComponent; public Slider gComponent; public Slider bComponent; public Slider aComponent; public InputField hexaComponent; public RawImage colorComponent; private void Awake() { instance = this; ((Component)this).gameObject.SetActive(false); } public static bool Create(Color original, string message, ColorEvent onColorChanged, ColorEvent onColorSelected, bool useAlpha = false) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) if (instance == null) { Debug.LogError((object)"No Colorpicker prefab active on 'Start' in scene"); return false; } if (done) { done = false; originalColor = Color32.op_Implicit(original); modifiedColor = Color32.op_Implicit(original); onCC = onColorChanged; onCS = onColorSelected; useA = useAlpha; ((Component)instance).gameObject.SetActive(true); ((Component)((Component)instance).transform.GetChild(0)).GetComponent().text = message; ((Component)instance.aComponent).gameObject.SetActive(useAlpha); instance.RecalculateMenu(recalculateHSV: true); ((Component)instance.hexaComponent.placeholder).GetComponent().text = "RRGGBB" + (useAlpha ? "AA" : ""); return true; } Done(); return false; } private void RecalculateMenu(bool recalculateHSV) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_03d9: Unknown result type (might be due to invalid IL or missing references) //IL_03de: Unknown result type (might be due to invalid IL or missing references) //IL_03c8: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) interact = false; if (recalculateHSV) { modifiedHsv = new HSV(Color32.op_Implicit(modifiedColor)); } else { modifiedColor = modifiedHsv.ToColor(); } rComponent.value = (int)modifiedColor.r; ((Component)((Component)rComponent).transform.GetChild(3)).GetComponent().text = modifiedColor.r.ToString(); gComponent.value = (int)modifiedColor.g; ((Component)((Component)gComponent).transform.GetChild(3)).GetComponent().text = modifiedColor.g.ToString(); bComponent.value = (int)modifiedColor.b; ((Component)((Component)bComponent).transform.GetChild(3)).GetComponent().text = modifiedColor.b.ToString(); if (useA) { aComponent.value = (int)modifiedColor.a; ((Component)((Component)aComponent).transform.GetChild(3)).GetComponent().text = modifiedColor.a.ToString(); } mainComponent.value = (float)modifiedHsv.H; ((Graphic)((Component)((Component)rComponent).transform.GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(byte.MaxValue, modifiedColor.g, modifiedColor.b, byte.MaxValue)); ((Graphic)((Component)((Component)rComponent).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32((byte)0, modifiedColor.g, modifiedColor.b, byte.MaxValue)); ((Graphic)((Component)((Component)gComponent).transform.GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(modifiedColor.r, byte.MaxValue, modifiedColor.b, byte.MaxValue)); ((Graphic)((Component)((Component)gComponent).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(modifiedColor.r, (byte)0, modifiedColor.b, byte.MaxValue)); ((Graphic)((Component)((Component)bComponent).transform.GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(modifiedColor.r, modifiedColor.g, byte.MaxValue, byte.MaxValue)); ((Graphic)((Component)((Component)bComponent).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(modifiedColor.r, modifiedColor.g, (byte)0, byte.MaxValue)); if (useA) { ((Graphic)((Component)((Component)aComponent).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color32.op_Implicit(new Color32(modifiedColor.r, modifiedColor.g, modifiedColor.b, byte.MaxValue)); } ((Graphic)((Component)((Transform)positionIndicator).parent.GetChild(0)).GetComponent()).color = Color32.op_Implicit(new HSV(modifiedHsv.H, 1.0, 1.0).ToColor()); positionIndicator.anchorMin = new Vector2((float)modifiedHsv.S, (float)modifiedHsv.V); positionIndicator.anchorMax = positionIndicator.anchorMin; hexaComponent.text = (useA ? ColorUtility.ToHtmlStringRGBA(Color32.op_Implicit(modifiedColor)) : ColorUtility.ToHtmlStringRGB(Color32.op_Implicit(modifiedColor))); ((Graphic)colorComponent).color = Color32.op_Implicit(modifiedColor); onCC?.Invoke(Color32.op_Implicit(modifiedColor)); interact = true; } public void SetChooser() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //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_0062: 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_0079: 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) Transform parent = ((Transform)positionIndicator).parent; Vector2 val = default(Vector2); RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)(object)((parent is RectTransform) ? parent : null), Vector2.op_Implicit(Input.mousePosition), ((Component)this).GetComponentInParent().worldCamera, ref val); Transform parent2 = ((Transform)positionIndicator).parent; val = Rect.PointToNormalized(((RectTransform)((parent2 is RectTransform) ? parent2 : null)).rect, val); if (positionIndicator.anchorMin != val) { positionIndicator.anchorMin = val; positionIndicator.anchorMax = val; modifiedHsv.S = val.x; modifiedHsv.V = val.y; RecalculateMenu(recalculateHSV: false); } } public void SetMain(float value) { if (interact) { modifiedHsv.H = value; RecalculateMenu(recalculateHSV: false); } } public void SetR(float value) { if (interact) { modifiedColor.r = (byte)value; RecalculateMenu(recalculateHSV: true); } } public void SetR(string value) { if (interact) { modifiedColor.r = (byte)Mathf.Clamp(int.Parse(value), 0, 255); RecalculateMenu(recalculateHSV: true); } } public void SetG(float value) { if (interact) { modifiedColor.g = (byte)value; RecalculateMenu(recalculateHSV: true); } } public void SetG(string value) { if (interact) { modifiedColor.g = (byte)Mathf.Clamp(int.Parse(value), 0, 255); RecalculateMenu(recalculateHSV: true); } } public void SetB(float value) { if (interact) { modifiedColor.b = (byte)value; RecalculateMenu(recalculateHSV: true); } } public void SetB(string value) { if (interact) { modifiedColor.b = (byte)Mathf.Clamp(int.Parse(value), 0, 255); RecalculateMenu(recalculateHSV: true); } } public void SetA(float value) { if (interact) { modifiedHsv.A = (byte)value; RecalculateMenu(recalculateHSV: false); } } public void SetA(string value) { if (interact) { modifiedHsv.A = (byte)Mathf.Clamp(int.Parse(value), 0, 255); RecalculateMenu(recalculateHSV: false); } } public void SetHexa(string value) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!interact) { return; } Color val = default(Color); if (ColorUtility.TryParseHtmlString("#" + value, ref val)) { if (!useA) { val.a = 1f; } modifiedColor = Color32.op_Implicit(val); RecalculateMenu(recalculateHSV: true); } else { hexaComponent.text = (useA ? ColorUtility.ToHtmlStringRGBA(Color32.op_Implicit(modifiedColor)) : ColorUtility.ToHtmlStringRGB(Color32.op_Implicit(modifiedColor))); } } public void CCancel() { Cancel(); } public static void Cancel() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) modifiedColor = originalColor; Done(); } public void CDone() { Done(); } public static void Done() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) done = true; onCC?.Invoke(Color32.op_Implicit(modifiedColor)); onCS?.Invoke(Color32.op_Implicit(modifiedColor)); ((Component)((Component)instance).transform).gameObject.SetActive(false); } } public class DragWindowCntrl : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler { private RectTransform window; private Vector2 delta; [Obsolete("Use gameObject.AddComponent() instead")] public static void ApplyDragWindowCntrl(GameObject go) { go.AddComponent(); } private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown window = (RectTransform)((Component)this).transform; } public void OnBeginDrag(PointerEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) delta = Vector2.op_Implicit(Input.mousePosition - ((Transform)window).position); } public void OnDrag(PointerEventData eventData) { //IL_0001: 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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //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_002e: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Vector2 val = eventData.position - delta; Rect rect = window.rect; Vector2 val2 = Vector2.op_Implicit(((Transform)window).lossyScale); float num = ((Rect)(ref rect)).width / 2f * val2.x; float num2 = (float)Screen.width - num; float num3 = ((Rect)(ref rect)).height / 2f * val2.y; float num4 = (float)Screen.height - num3; val.x = Mathf.Clamp(val.x, num, num2); val.y = Mathf.Clamp(val.y, num3, num4); ((Component)this).transform.position = Vector2.op_Implicit(val); } } public class GradientPicker : MonoBehaviour { public delegate void GradientEvent(Gradient g); private static GradientPicker instance; public static bool done = true; private static GradientEvent onGC; private static GradientEvent onGS; private static Gradient originalGradient; private static Gradient modifiedGradient; private GameObject key; private static bool interact; private InputField positionComponent; private Image colorComponent; private Transform alphaComponent; private List colorKeyObjects; private List colorKeys; private int selectedColorKey; private List alphaKeyObjects; private List alphaKeys; private int selectedAlphaKey; private void Awake() { instance = this; key = ((Component)((Component)this).transform.GetChild(2)).gameObject; positionComponent = ((Component)((Component)this).transform.parent.GetChild(3)).GetComponent(); colorComponent = ((Component)((Component)this).transform.parent.GetChild(4)).GetComponent(); alphaComponent = ((Component)this).transform.parent.GetChild(5); ((Component)((Component)this).transform.parent).gameObject.SetActive(false); } public static bool Create(Gradient original, string message, GradientEvent onGradientChanged, GradientEvent onGradientSelected) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if (instance == null) { Debug.LogError((object)"No Gradientpicker prefab active on 'Start' in scene"); return false; } if (done) { done = false; originalGradient = new Gradient(); originalGradient.SetKeys(original.colorKeys, original.alphaKeys); modifiedGradient = new Gradient(); modifiedGradient.SetKeys(original.colorKeys, original.alphaKeys); onGC = onGradientChanged; onGS = onGradientSelected; ((Component)((Component)instance).transform.parent).gameObject.SetActive(true); ((Component)((Component)instance).transform.parent.GetChild(0)).GetComponent().text = message; instance.Setup(); return true; } Done(); return false; } private void Setup() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0075: Unknown result type (might be due to invalid IL or missing references) interact = false; colorKeyObjects = new List(); colorKeys = new List(); alphaKeyObjects = new List(); alphaKeys = new List(); GradientColorKey[] array = originalGradient.colorKeys; foreach (GradientColorKey k in array) { CreateColorKey(k); } GradientAlphaKey[] array2 = originalGradient.alphaKeys; foreach (GradientAlphaKey k2 in array2) { CreateAlphaKey(k2); } CalculateTexture(); interact = true; } private void CreateColorKey(GradientColorKey k) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (colorKeys.Count < 8) { Slider component = Object.Instantiate(key, ((Component)this).transform.position, default(Quaternion), ((Component)this).transform).GetComponent(); ((RectTransform)((Component)component).transform).anchoredPosition = new Vector2(0f, -29f); ((Object)component).name = "ColorKey"; ((Component)component).gameObject.SetActive(true); component.value = k.time; ((Graphic)((Component)((Component)component).transform.GetChild(0).GetChild(0).GetChild(0)).GetComponent()).color = k.color; colorKeyObjects.Add(component); colorKeys.Add(k); ChangeSelectedColorKey(colorKeys.Count - 1); } } public void CreateNewColorKey(float time) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (Input.GetMouseButtonDown(0)) { interact = false; CreateColorKey(new GradientColorKey(modifiedGradient.Evaluate(time), time)); interact = true; } } private void CreateAlphaKey(GradientAlphaKey k) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) if (alphaKeys.Count < 8) { Slider component = Object.Instantiate(key, ((Component)this).transform.position, default(Quaternion), ((Component)this).transform).GetComponent(); ((RectTransform)((Component)component).transform).anchoredPosition = new Vector2(0f, 25f); ((Component)component).transform.GetChild(0).GetChild(0).rotation = default(Quaternion); ((Object)component).name = "AlphaKey"; ((Component)component).gameObject.SetActive(true); component.value = k.time; ((Graphic)((Component)((Component)component).transform.GetChild(0).GetChild(0).GetChild(0)).GetComponent()).color = new Color(k.alpha, k.alpha, k.alpha, 1f); alphaKeyObjects.Add(component); alphaKeys.Add(k); ChangeSelectedAlphaKey(alphaKeys.Count - 1); } } public void CreateNewAlphaKey(float time) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (Input.GetMouseButtonDown(0)) { interact = false; CreateAlphaKey(new GradientAlphaKey(modifiedGradient.Evaluate(time).a, time)); interact = true; } } private void CalculateTexture() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown Color32[] array = (Color32[])(object)new Color32[325]; for (int i = 0; i < array.Length; i++) { array[i] = Color32.op_Implicit(modifiedGradient.Evaluate((float)i / (float)array.Length)); } Texture2D val = new Texture2D(array.Length, 1) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; val.SetPixels32(array); val.Apply(); ((Component)this).GetComponent().texture = (Texture)(object)val; onGC?.Invoke(modifiedGradient); } public void SetAlpha(float value) { //IL_0023: 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) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if (interact) { alphaKeys[selectedAlphaKey] = new GradientAlphaKey(value, alphaKeys[selectedAlphaKey].time); modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); ((Component)alphaComponent.GetChild(4)).GetComponent().text = Mathf.RoundToInt(value * 255f).ToString(); ((Graphic)((Component)((Component)alphaKeyObjects[selectedAlphaKey]).transform.GetChild(0).GetChild(0).GetChild(0)).GetComponent()).color = new Color(value, value, value, 1f); } } public void SetAlpha(string value) { ((Component)alphaComponent).GetComponent().value = (float)Mathf.Clamp(int.Parse(value), 0, 255) / 255f; CalculateTexture(); } private void ChangeSelectedColorKey(int value) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (colorKeyObjects.Count() > selectedColorKey) { ((Graphic)((Component)((Component)colorKeyObjects[selectedColorKey]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.gray; } if (alphaKeyObjects.Count() > 0) { ((Graphic)((Component)((Component)alphaKeyObjects[selectedAlphaKey]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.gray; } ((Graphic)((Component)((Component)colorKeyObjects[value]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.green; if (selectedColorKey != value && !ColorPicker.done) { ColorPicker.Done(); } selectedColorKey = value; ((Selectable)colorKeyObjects[value]).Select(); } private void ChangeSelectedAlphaKey(int value) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (alphaKeyObjects.Count > selectedAlphaKey) { ((Graphic)((Component)((Component)alphaKeyObjects[selectedAlphaKey]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.gray; } if (colorKeyObjects.Count > 0) { ((Graphic)((Component)((Component)colorKeyObjects[selectedColorKey]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.gray; } ((Graphic)((Component)((Component)alphaKeyObjects[value]).transform.GetChild(0).GetChild(0)).GetComponent()).color = Color.green; selectedAlphaKey = value; ((Selectable)alphaKeyObjects[value]).Select(); } public void CheckDeleteKey(Slider s) { if (!Input.GetMouseButtonDown(1)) { return; } if (((Object)s).name == "ColorKey" && colorKeys.Count > 2) { if (!ColorPicker.done) { ColorPicker.Done(); return; } int num = colorKeyObjects.IndexOf(s); Object.Destroy((Object)(object)((Component)colorKeyObjects[num]).gameObject); colorKeyObjects.RemoveAt(num); colorKeys.RemoveAt(num); if (num <= selectedColorKey) { ChangeSelectedColorKey(selectedColorKey - 1); } modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); } if (((Object)s).name == "AlphaKey" && alphaKeys.Count > 2) { int num2 = alphaKeyObjects.IndexOf(s); Object.Destroy((Object)(object)((Component)alphaKeyObjects[num2]).gameObject); alphaKeyObjects.RemoveAt(num2); alphaKeys.RemoveAt(num2); if (num2 <= selectedAlphaKey) { ChangeSelectedAlphaKey(selectedAlphaKey - 1); } modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); } } public void Select() { //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) Slider component = EventSystem.current.currentSelectedGameObject.GetComponent(); ((Component)component).transform.SetAsLastSibling(); if (((Object)component).name == "ColorKey") { ChangeSelectedColorKey(colorKeyObjects.IndexOf(component)); ((Component)alphaComponent).gameObject.SetActive(false); ((Component)colorComponent).gameObject.SetActive(true); positionComponent.text = Mathf.RoundToInt(colorKeys[selectedColorKey].time * 100f).ToString(); ((Graphic)((Component)colorComponent).GetComponent()).color = colorKeys[selectedColorKey].color; } else { ChangeSelectedAlphaKey(alphaKeyObjects.IndexOf(component)); ((Component)colorComponent).gameObject.SetActive(false); ((Component)alphaComponent).gameObject.SetActive(true); positionComponent.text = Mathf.RoundToInt(alphaKeys[selectedAlphaKey].time * 100f).ToString(); ((Component)alphaComponent).GetComponent().value = alphaKeys[selectedAlphaKey].alpha; ((Component)alphaComponent.GetChild(4)).GetComponent().text = Mathf.RoundToInt(alphaKeys[selectedAlphaKey].alpha * 255f).ToString(); } } public void SetTime(float time) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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) if (interact) { Slider component = EventSystem.current.currentSelectedGameObject.GetComponent(); if (((Object)component).name == "ColorKey") { int index = colorKeyObjects.IndexOf(component); colorKeys[index] = new GradientColorKey(colorKeys[index].color, time); } else { int index2 = alphaKeyObjects.IndexOf(component); alphaKeys[index2] = new GradientAlphaKey(alphaKeys[index2].alpha, time); } modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); positionComponent.text = Mathf.RoundToInt(time * 100f).ToString(); } } public void SetTime(string time) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) interact = false; float num = (float)Mathf.Clamp(int.Parse(time), 0, 100) * 0.01f; if (((Component)colorComponent).gameObject.activeSelf) { colorKeyObjects[selectedColorKey].value = num; colorKeys[selectedColorKey] = new GradientColorKey(colorKeys[selectedColorKey].color, num); } else { alphaKeyObjects[selectedAlphaKey].value = num; alphaKeys[selectedAlphaKey] = new GradientAlphaKey(alphaKeys[selectedAlphaKey].alpha, num); } modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); interact = true; } public void ChooseColor() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) ColorPicker.Create(colorKeys[selectedColorKey].color, "Gradient Color Key", delegate(Color c) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) UpdateColor(selectedColorKey, c); }, null); } private void UpdateColor(int index, Color c) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_005d: Unknown result type (might be due to invalid IL or missing references) interact = false; colorKeys[index] = new GradientColorKey(c, colorKeys[index].time); ((Graphic)((Component)((Component)colorKeyObjects[index]).transform.GetChild(0).GetChild(0).GetChild(0)).GetComponent()).color = c; ((Graphic)colorComponent).color = c; modifiedGradient.SetKeys(colorKeys.ToArray(), alphaKeys.ToArray()); CalculateTexture(); interact = true; } public void CCancel() { Cancel(); } public static void Cancel() { modifiedGradient = originalGradient; Done(); } public void CDone() { Done(); } public static void Done() { if (!ColorPicker.done) { ColorPicker.Done(); } foreach (Slider colorKeyObject in instance.colorKeyObjects) { Object.Destroy((Object)(object)((Component)colorKeyObject).gameObject); } foreach (Slider alphaKeyObject in instance.alphaKeyObjects) { Object.Destroy((Object)(object)((Component)alphaKeyObject).gameObject); } instance.colorKeyObjects = null; instance.colorKeys = null; instance.alphaKeyObjects = null; instance.alphaKeys = null; done = true; onGC?.Invoke(modifiedGradient); onGS?.Invoke(modifiedGradient); ((Component)((Component)instance).transform.parent).gameObject.SetActive(false); } } public class MinimapOverlayPanel : MonoBehaviour { public GameObject OverlayGroup; public Button Button; public GameObject BaseMod; public Text BaseModText; public Toggle BaseToggle; private readonly Dictionary Mods = new Dictionary(); public void ToggleOverlayGroup() { OverlayGroup.SetActive(!OverlayGroup.activeSelf); } public Toggle AddOverlayToggle(string modName, string overlayName) { if (!Mods.TryGetValue(modName, out var value)) { value = Object.Instantiate(BaseMod, OverlayGroup.transform); value.SetActive(true); ((Object)value).name = modName; value.GetComponentInChildren().text = modName; Mods.Add(modName, value); } Toggle val = Object.Instantiate(BaseToggle, value.transform); ((Component)val).gameObject.SetActive(true); ((Object)((Component)val).gameObject).name = overlayName; ((Component)val).GetComponentInChildren().text = overlayName; return val; } } } namespace Jotunn.Managers { public class AssetManager : IManager { private static class Patches { [HarmonyPatch(typeof(AssetBundleLoader), "OnInitCompleted")] [HarmonyPostfix] private static void AssetBundleLoader_Load(AssetBundleLoader __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair asset in Instance.assets) { AddAssetToBundleLoader(__instance, asset.Key, asset.Value); } AssetManager.OnSoftReferenceableAssetsReady?.SafeInvoke(); } [HarmonyPatch(typeof(AssetBundleLoader), "InitializeDataSide")] [HarmonyPrefix] private static void AssetBundleLoader_InitializeDataSide(ref bool allAssetsLoadable) { allAssetsLoadable = true; } public static void AddSafe(Dictionary pathsMappedToAssetId, string key, AssetID value) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (key != null && !pathsMappedToAssetId.ContainsKey(key)) { pathsMappedToAssetId.Add(key, value); } } [HarmonyPatch(typeof(AssetBundleLoader), "GetAllAssetPathsMappedToAssetID")] [HarmonyTranspiler] private static IEnumerable AssetBundleLoader_GetAllAssetPathsMappedToAssetID(IEnumerable instructions) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown MethodInfo addMethod = AccessTools.Method(typeof(Dictionary), "Add", (Type[])null, (Type[])null); MethodInfo methodInfo = AccessTools.Method(typeof(Patches), "AddSafe", (Type[])null, (Type[])null); return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, addMethod)), (string)null) }).SetInstruction(new CodeInstruction(OpCodes.Call, (object)methodInfo)).InstructionEnumeration(); } [HarmonyPatch(typeof(AssetLoader), "InvokeCallbacks")] [HarmonyPrefix] private static void SwapResolvedAsset(ref AssetLoader __instance, LoadResult result) { //IL_0000: 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_002f: Unknown result type (might be due to invalid IL or missing references) if ((int)result == 0 && Instance.assetsToResolve.TryGetValue(__instance.m_assetID, out var value)) { if (!Object.op_Implicit(__instance.m_asset)) { Logger.LogWarning($"AssetLoader.m_asset == null for AssetID {__instance.m_assetID} at path {__instance.m_assetPathInBundle}, skipping mocking"); return; } value.InstantiateAndResolveAsset(__instance.m_asset); __instance.m_asset = value.Asset; } } [HarmonyPatch(typeof(AssetLoader), "Release")] [HarmonyPostfix] private static void AssetLoader_Release(ref AssetLoader __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (((AssetLoader)(ref __instance)).ReferenceCount == 0 && Instance.assetsToResolve.TryGetValue(__instance.m_assetID, out var value)) { value.DestroyAsset(); } } } private struct AssetRef { public BepInPlugin sourceMod; public Object asset; public AssetID originalID; public AssetRef(BepInPlugin sourceMod, Object asset, Object original) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) this.sourceMod = sourceMod; this.asset = asset; originalID = (AssetID)((Object.op_Implicit(original) && Instance.IsReady()) ? Instance.GetAssetID(((object)original).GetType(), original.name) : default(AssetID)); } } internal class MockResolutionContext { public Object Asset { get; private set; } public Transform Parent { get; set; } public Action ResolveCallback { get; set; } public bool IsResolved => Object.op_Implicit(Asset); public MockResolutionContext(Transform parent, Action resolveCallback) { Parent = parent; ResolveCallback = (Action)Delegate.Combine(ResolveCallback, resolveCallback); } public void InstantiateAndResolveAsset(Object realAsset) { if (!IsResolved) { Asset = Object.Instantiate(realAsset, Parent); Asset.name = realAsset.name; Object asset = Asset; GameObject val = (GameObject)(object)((asset is GameObject) ? asset : null); if (val != null) { val.FixReferences(recursive: true); } else { ((object)Asset).FixReferences(); } ResolveCallback?.SafeInvoke(Asset); } } public void DestroyAsset() { if (Object.op_Implicit(Asset)) { Object.Destroy(Asset); } Asset = null; } } private static AssetManager instance; private Dictionary assets = new Dictionary(); private Dictionary> mapNameToAssetID; private GameObject ResolvedAssetsContainer; private Dictionary assetsToResolve = new Dictionary(); public static AssetManager Instance => instance ?? (instance = new AssetManager()); internal Dictionary> MapNameToAssetID => mapNameToAssetID ?? (mapNameToAssetID = CreateNameToAssetID()); public static event Action OnSoftReferenceableAssetsReady; private AssetManager() { } static AssetManager() { ((IManager)Instance).Init(); } void IManager.Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Main.LogInit("AssetManager"); ResolvedAssetsContainer = new GameObject("Resolved Assets"); ResolvedAssetsContainer.transform.parent = Main.RootObject.transform; ResolvedAssetsContainer.SetActive(false); Main.Harmony.PatchAll(typeof(Patches)); } public bool IsReady() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (Runtime.s_assetLoader != null) { return ((AssetBundleLoader)Runtime.s_assetLoader).Initialized; } return false; } public AssetID AddAsset(Object asset, Object original) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) AssetID val = GenerateAssetID(asset); if (assets.ContainsKey(val)) { return val; } AssetRef assetRef = new AssetRef(BepInExUtils.GetSourceModMetadata(), asset, original); assets.Add(val, assetRef); if (IsReady() && AssetBundleLoader.Instance != null) { AddAssetToBundleLoader(AssetBundleLoader.Instance, val, assetRef); } return val; } public AssetID AddAsset(Object asset) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) return AddAsset(asset, null); } public void ResolveMocksOnLoad(AssetID assetID) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ResolveMocksOnLoad(assetID, null, null); } public void ResolveMocksOnLoad(AssetID assetID, Transform parent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ResolveMocksOnLoad(assetID, parent, null); } public void ResolveMocksOnLoad(SoftReference softReference, Transform parent, Action resolveCallback) where T : Object { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ResolveMocksOnLoad(softReference.m_assetID, parent, delegate(Object asset) { resolveCallback?.Invoke((T)(object)((asset is T) ? asset : null)); }); } public void ResolveMocksOnLoad(AssetID assetID, Transform parent, Action resolveCallback) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (assetsToResolve.TryGetValue(assetID, out var value)) { value.Parent = parent ?? value.Parent ?? ResolvedAssetsContainer.transform; MockResolutionContext mockResolutionContext = value; mockResolutionContext.ResolveCallback = (Action)Delegate.Combine(mockResolutionContext.ResolveCallback, resolveCallback); } else { assetsToResolve.Add(assetID, new MockResolutionContext(parent ?? ResolvedAssetsContainer.transform, resolveCallback)); } } private static void AddAssetToBundleLoader(AssetBundleLoader assetBundleLoader, AssetID assetID, AssetRef assetRef) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) string text = "JVL_BundleWrapper_" + assetRef.asset.name; string text2 = assetRef.sourceMod.GUID + "/Prefabs/" + assetRef.asset.name; if (assetBundleLoader.m_bundleNameToLoaderIndex.ContainsKey(text)) { return; } AssetLocation val = default(AssetLocation); ((AssetLocation)(ref val))..ctor(text, text2); BundleLoader val2 = default(BundleLoader); ((BundleLoader)(ref val2))..ctor(text, ""); ((BundleLoader)(ref val2)).HoldReference(); assetBundleLoader.m_bundleNameToLoaderIndex.Add(text, assetBundleLoader.m_bundleLoaders.Length); assetBundleLoader.m_bundleLoaders = CollectionExtensions.AddItem((IEnumerable)assetBundleLoader.m_bundleLoaders, val2).ToArray(); int originalBundleLoaderIndex = ((IEnumerable)assetBundleLoader.m_assetLoaders).FirstOrDefault((Func)((AssetLoader l) => l.m_assetID == assetRef.originalID)).m_bundleLoaderIndex; if (((AssetID)(ref assetRef.originalID)).IsValid && originalBundleLoaderIndex > 0) { BundleLoader val3 = assetBundleLoader.m_bundleLoaders[originalBundleLoaderIndex]; val2.m_bundleLoaderIndicesOfThisAndDependencies = (from i in CollectionExtensions.AddItem(val3.m_bundleLoaderIndicesOfThisAndDependencies.Where((int i) => i != originalBundleLoaderIndex), assetBundleLoader.m_bundleNameToLoaderIndex[text]) orderby i select i).ToArray(); } else { ((BundleLoader)(ref val2)).SetDependencies(Array.Empty()); } assetBundleLoader.m_bundleLoaders[assetBundleLoader.m_bundleNameToLoaderIndex[text]] = val2; AssetLoader val4 = default(AssetLoader); ((AssetLoader)(ref val4))..ctor(assetID, val); val4.m_asset = assetRef.asset; ((AssetLoader)(ref val4)).HoldReference(); assetBundleLoader.m_assetIDToLoaderIndex.Add(assetID, assetBundleLoader.m_assetLoaders.Length); assetBundleLoader.m_assetLoaders = CollectionExtensions.AddItem((IEnumerable)assetBundleLoader.m_assetLoaders, val4).ToArray(); Instance.MapNameToAssetID[((object)assetRef.asset).GetType()][assetRef.asset.name] = assetID; } public AssetID GenerateAssetID(Object asset) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) uint stableHashCode = (uint)StringExtensionMethods.GetStableHashCode(asset.name); return new AssetID(stableHashCode, stableHashCode, stableHashCode, stableHashCode); } public AssetID GenerateAssetID(string asset) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) uint stableHashCode = (uint)StringExtensionMethods.GetStableHashCode(asset); return new AssetID(stableHashCode, stableHashCode, stableHashCode, stableHashCode); } public GameObject ClonePrefab(GameObject asset, string newName, Transform parent) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(asset, parent); ((Object)val).name = newName; AddAsset((Object)(object)val, (Object)(object)asset); return val; } public AssetID GetAssetID(Type type, string name) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0054: Unknown result type (might be due to invalid IL or missing references) if (!IsReady()) { throw new InvalidOperationException("The vanilla asset system is not initialized yet"); } if (MapNameToAssetID.TryGetValue(type, out var value) && value.TryGetValue(name, out var value2)) { return value2; } if (MapNameToAssetID.TryGetValue(typeof(Object), out value) && value.TryGetValue(name, out value2)) { return value2; } return default(AssetID); } public AssetID GetAssetID(string name) where T : Object { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return GetAssetID(typeof(T), name); } public SoftReference GetSoftReference(Type type, string name) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) AssetID assetID = GetAssetID(type, name); if (!((AssetID)(ref assetID)).IsValid) { return default(SoftReference); } return new SoftReference(assetID); } public SoftReference GetSoftReference(string name) where T : Object { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) AssetID assetID = GetAssetID(name); if (!((AssetID)(ref assetID)).IsValid) { return default(SoftReference); } return new SoftReference(assetID); } private static Dictionary> CreateNameToAssetID() { //IL_015a: Unknown result type (might be due to invalid IL or missing references) if (!Instance.IsReady()) { throw new InvalidOperationException("The vanilla asset system is not initialized yet"); } Dictionary> dictionary = new Dictionary>(); Dictionary dictionary2 = new Dictionary(); foreach (KeyValuePair item in Runtime.GetAllAssetPathsInBundleMappedToAssetID().ToList()) { string text = item.Key.Split(new char[1] { '/' }).Last(); string text2 = text.Split(new char[1] { '.' }).Last(); string key = text.RemoveSuffix("." + text2); if (!(item.Key == "Assets/UI/prefabs/radials/elements/Hammer.prefab") && !(item.Key == "Assets/UI/prefabs/Radial/elements/Hammer.prefab")) { Type type = Instance.TypeFromExtension(text2); if (type == null && text2 == "asset" && text.StartsWith("Recipe_")) { type = typeof(Recipe); } if (type == null) { type = typeof(Object); } if (!dictionary.ContainsKey(type)) { dictionary.Add(type, new Dictionary()); } if (!dictionary[type].ContainsKey(key) || !SkipAmbiguousPath(dictionary2[key], item.Key, text2)) { dictionary[type][key] = item.Value; dictionary2[key] = item.Key; } } } return dictionary; } private static bool SkipAmbiguousPath(string oldPath, string newPath, string extension) { if (extension == "prefab") { if (oldPath.StartsWith("Assets/world/Locations")) { return false; } if (newPath.StartsWith("Assets/world/Locations")) { return true; } Logger.LogWarning("Ambiguous asset name for path. old: " + oldPath + ", new: " + newPath + ", using old path"); } return true; } private Type TypeFromExtension(string extension) { switch (extension.ToLower()) { case "prefab": return typeof(GameObject); case "mat": return typeof(Material); case "obj": case "fbx": return typeof(Mesh); case "png": case "jpg": case "tga": case "tif": return typeof(Texture2D); case "wav": case "mp3": return typeof(AudioClip); case "controller": return typeof(RuntimeAnimatorController); case "physicmaterial": case "physicsmaterial": return typeof(PhysicsMaterial); case "shader": return typeof(Shader); case "anim": return typeof(AnimationClip); case "mixer": return typeof(AudioMixer); case "txt": return typeof(TextAsset); case "ttf": case "otf": return typeof(TMP_FontAsset); case "rendertexture": return typeof(RenderTexture); case "lighting": return typeof(LightingSettings); default: return null; } } } public class CommandManager : IManager { private static class Patches { [HarmonyPatch(typeof(Console), "Awake")] [HarmonyPostfix] private static void AddCustomCommands(Console __instance) { Instance.AddCustomCommands(__instance); } [HarmonyPatch(typeof(ConsoleCommand), "GetTabOptions")] [HarmonyPostfix] private static void ConsoleCommand_GetTabOptions(ConsoleCommand __instance, ref List __result) { Instance.ConsoleCommand_GetTabOptions(__instance, ref __result); } } private static CommandManager _instance; internal static Action> OnGetTabOptions; private List _customCommands = new List(); public static CommandManager Instance => _instance ?? (_instance = new CommandManager()); public ReadOnlyCollection CustomCommands => _customCommands.AsReadOnly(); private CommandManager() { } static CommandManager() { ((IManager)Instance).Init(); } void IManager.Init() { Main.LogInit("CommandManager"); Main.Harmony.PatchAll(typeof(Patches)); } public void AddConsoleCommand(ConsoleCommand cmd) { if (_customCommands.Exists((ConsoleCommand c) => c.Name == cmd.Name)) { Logger.LogWarning(cmd.SourceMod, "Cannot have two console commands with same name: " + cmd.Name); } else if (cmd.Name.Contains(" ")) { Logger.LogWarning(cmd.SourceMod, "Cannot have command containing space: '" + cmd.Name + "'"); } else { _customCommands.Add(cmd); } } private void AddCustomCommands(Console self) { if (!_customCommands.Any()) { return; } Logger.LogInfo($"Adding {_customCommands.Count} commands to the Console"); foreach (ConsoleCommand customCommand in _customCommands) { if (((Terminal)self).m_commandList.Contains(customCommand.Name)) { Logger.LogWarning(customCommand.SourceMod, "Cannot override existing command: " + customCommand.Name); } else { CreateVanillaCommand(customCommand); } } ((Terminal)self).updateCommandList(); } private ConsoleCommand CreateVanillaCommand(ConsoleCommand command) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown ConstructorInfo constructorInfo = AccessTools.Constructor(typeof(ConsoleCommand), new Type[12] { typeof(string), typeof(string), typeof(ConsoleEvent), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(bool), typeof(ConsoleOptionsFetcher), typeof(bool), typeof(bool), typeof(bool) }, false); if (constructorInfo != null) { object[] obj = new object[12] { command.Name, command.Help, (object)(ConsoleEvent)delegate(ConsoleEventArgs args) { command.Run(args.Args.Skip(1).ToArray(), args.Context); }, command.IsCheat, command.IsNetwork, command.OnlyServer, command.IsSecret, false, null, null, null, null }; ConsoleCommand consoleCommand = command; obj[8] = (object)new ConsoleOptionsFetcher(consoleCommand.CommandOptionList); obj[9] = false; obj[10] = false; obj[11] = false; return (ConsoleCommand)constructorInfo.Invoke(obj); } Logger.LogError("No suitable constructor for Terminal.ConsoleCommand found"); return null; } private void ConsoleCommand_GetTabOptions(ConsoleCommand self, ref List result) { if (self.m_tabOptions == null && self.m_tabOptionsFetcher != null) { OnGetTabOptions?.SafeInvoke(self.Command, result); } } } public class CreatureManager : IManager { private static class Patches { [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPrefix] private static void InvokeOnVanillaCreaturesAvailable() { Instance.InvokeOnVanillaCreaturesAvailable(); } [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPostfix] private static void FixReferences(ZNetScene __instance) { Instance.FixReferences(__instance); } [HarmonyPatch(typeof(SpawnSystem), "Awake")] [HarmonyPrefix] private static void AddSpawnListToSpawnSystem(SpawnSystem __instance) { Instance.AddSpawnListToSpawnSystem(__instance); } [HarmonyPatch(typeof(LevelEffects), "SetupLevelVisualization")] [HarmonyPostfix] private static void EnableCumulativeLevelEffects(LevelEffects __instance, int level) { Instance.EnableCumulativeLevelEffects(__instance, level); } } private static CreatureManager _instance; public static int CharacterLayer; internal readonly List Creatures = new List(); internal GameObject SpawnListContainer; internal SpawnSystemList SpawnList; public static CreatureManager Instance => _instance ?? (_instance = new CreatureManager()); public static event Action OnVanillaCreaturesAvailable; public static event Action OnCreaturesRegistered; private CreatureManager() { } static CreatureManager() { CharacterLayer = LayerMask.NameToLayer("character"); ((IManager)Instance).Init(); } void IManager.Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Main.LogInit("CreatureManager"); SpawnListContainer = new GameObject("Creatures"); SpawnListContainer.transform.parent = Main.RootObject.transform; SpawnListContainer.SetActive(false); SpawnList = SpawnListContainer.AddComponent(); Main.Harmony.PatchAll(typeof(Patches)); } public bool AddCreature(CustomCreature customCreature) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown if (!customCreature.IsValid()) { Logger.LogWarning(customCreature.SourceMod, $"Custom creature '{customCreature}' is not valid"); return false; } if (Creatures.Contains(customCreature)) { Logger.LogWarning(customCreature.SourceMod, $"Custom creature '{customCreature}' already added"); return false; } if (!PrefabManager.Instance.AddPrefab(customCreature.Prefab, customCreature.SourceMod)) { return false; } if (customCreature.Prefab.layer != CharacterLayer) { customCreature.Prefab.layer = CharacterLayer; foreach (Transform item in customCreature.Prefab.transform) { Transform val = item; ((Component)val).gameObject.layer = CharacterLayer; } } customCreature.Prefab.transform.SetParent(SpawnListContainer.transform, false); Creatures.Add(customCreature); SpawnList.m_spawners.AddRange(customCreature.Spawns); return true; } public CustomCreature GetCreature(string creatureName) { return Creatures.FirstOrDefault((CustomCreature x) => ((Object)x.Prefab).name.Equals(creatureName)); } public GameObject GetCreaturePrefab(string creatureName) { CustomCreature creature = GetCreature(creatureName); if (creature != null) { return creature.Prefab; } Character prefab = PrefabManager.Cache.GetPrefab(creatureName); if ((Object)(object)prefab != (Object)null) { return ((Component)prefab).gameObject; } return null; } public void RemoveCreature(string creatureName) { CustomCreature creature = GetCreature(creatureName); if (creature == null) { Logger.LogWarning("Could not remove Creature " + creatureName + ": Not found"); } else { RemoveCreature(creature); } } public void RemoveCreature(CustomCreature creature) { Creatures.Remove(creature); if (Object.op_Implicit((Object)(object)creature.Prefab)) { PrefabManager.Instance.RemovePrefab(((Object)creature.Prefab).name); } } private void InvokeOnVanillaCreaturesAvailable() { CreatureManager.OnVanillaCreaturesAvailable?.SafeInvoke(); } private void FixReferences(ZNetScene self) { if (Creatures.Any()) { Logger.LogInfo($"Adding {Creatures.Count} custom creatures"); List list = new List(); foreach (CustomCreature creature in Creatures) { try { creature.Prefab.GetComponent()?.FixReferences(); if (creature.FixReference | creature.FixConfig) { creature.Prefab.FixReferences(creature.FixReference); creature.FixReference = false; creature.FixConfig = false; } Logger.LogDebug($"Added creature {creature} | Spawns: {creature.Spawns.Count}"); } catch (Exception arg) { Logger.LogWarning(creature?.SourceMod, $"Error caught while adding creature {creature}: {arg}"); list.Add(creature); } } foreach (CustomCreature item in list) { if (Object.op_Implicit((Object)(object)item.Prefab)) { PrefabManager.Instance.DestroyPrefab(((Object)item.Prefab).name); } RemoveCreature(item); } } InvokeOnCreaturesRegistered(); } private void InvokeOnCreaturesRegistered() { CreatureManager.OnCreaturesRegistered?.SafeInvoke(); } private void AddSpawnListToSpawnSystem(SpawnSystem self) { if (!self.m_spawnLists.Contains(SpawnList)) { self.m_spawnLists.Add(SpawnList); } } private void EnableCumulativeLevelEffects(LevelEffects self, int level) { if (level <= 2 || !Creatures.Any((CustomCreature x) => ((Object)x.Prefab).name == self.m_character.m_nview.GetPrefabName() && x.UseCumulativeLevelEffects)) { return; } for (int num = level - 2; num >= 0; num--) { if (num < self.m_levelSetups.Count) { LevelSetup val = self.m_levelSetups[num]; if (Object.op_Implicit((Object)(object)val.m_enableObject)) { Logger.LogDebug($"Enabling {level - 1} star equipment: '{((Object)val.m_enableObject).name}'"); val.m_enableObject.SetActive(true); } } } } } public class DungeonManager : IManager { private static class Patches { [HarmonyPatch(typeof(ZoneSystem), "SetupLocations")] [HarmonyPrefix] private static void OnBeforeZoneSystemSetupLocations() { Instance.OnZoneSystemSetupLocations(); } [HarmonyPatch(typeof(DungeonDB), "Start")] [HarmonyPostfix] private static void OnDungeonDBStarted() { Instance.OnDungeonDBStarted(); } [HarmonyPatch(typeof(DungeonDB), "GetRoom")] [HarmonyPrefix] private static bool OnDungeonDBGetRoom(int hash, ref RoomData __result) { RoomData val = Instance.OnDungeonDBGetRoom(hash); if (val != null) { __result = val; return false; } return true; } [HarmonyPatch(typeof(DungeonGenerator), "SetupAvailableRooms")] [HarmonyPostfix] private static void OnDungeonGeneratorSetupAvailableRooms(DungeonGenerator __instance) { Instance.OnDungeonGeneratorSetupAvailableRooms(__instance); } } private static DungeonManager _instance; internal readonly Dictionary Rooms = new Dictionary(); private readonly Dictionary hashToName = new Dictionary(); private readonly List themeList = new List(); private readonly Dictionary loadedEnvironments = new Dictionary(); internal GameObject DungeonRoomContainer; public static DungeonManager Instance => _instance ?? (_instance = new DungeonManager()); public static event Action OnVanillaRoomsAvailable; public static event Action OnRoomsRegistered; private DungeonManager() { } static DungeonManager() { ((IManager)Instance).Init(); } void IManager.Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Main.LogInit("DungeonManager"); DungeonRoomContainer = new GameObject("DungeonRooms"); DungeonRoomContainer.transform.parent = Main.RootObject.transform; DungeonRoomContainer.SetActive(false); Main.Harmony.PatchAll(typeof(Patches)); } public bool AddCustomRoom(CustomRoom customRoom) { if (customRoom == null) { throw new ArgumentException("Cannot be null", "customRoom"); } if (string.IsNullOrEmpty(customRoom.ThemeName)) { throw new ArgumentException("ThemeName of this room must have a value.", "customRoom"); } if (!CustomRoom.IsVanillaTheme(customRoom.ThemeName) && !themeList.Contains(customRoom.ThemeName)) { throw new ArgumentException("ThemeName of this room (" + customRoom.ThemeName + ") match a vanilla Room.Theme value or must be registered.", "customRoom"); } if (Rooms.ContainsKey(customRoom.Name)) { Logger.LogWarning(customRoom.SourceMod, "Room " + customRoom.Name + " already exists"); return false; } if (!customRoom.SoftReference) { customRoom.Prefab.transform.SetParent(DungeonRoomContainer.transform); customRoom.Prefab.SetActive(true); } Rooms.Add(customRoom.Name, customRoom); return true; } public CustomRoom GetRoom(string name) { if (!Rooms.TryGetValue(name, out var value)) { return null; } return value; } public bool RemoveRoom(string name) { return Rooms.Remove(name); } public bool RegisterDungeonTheme(GameObject prefab, string themeName) { Logger.LogDebug("RegisterDungeonTheme called with prefab " + ((Object)prefab).name + " and themeName " + themeName + "."); if ((Object)(object)prefab == (Object)null) { throw new ArgumentException("Cannot be null", "prefab"); } if (string.IsNullOrEmpty(themeName)) { throw new ArgumentException("Cannot be null or empty", "themeName"); } DungeonGenerator componentInChildren = prefab.GetComponentInChildren(); if ((Object)(object)componentInChildren == (Object)null) { Logger.LogError("Cannot find DungeonGenerator component in prefab " + ((Object)prefab).name + "."); throw new ArgumentException("Prefab must contain a DungeonGenerator component", "prefab"); } DungeonGeneratorTheme dungeonGeneratorTheme = default(DungeonGeneratorTheme); if (((Component)componentInChildren).gameObject.TryGetComponent(ref dungeonGeneratorTheme)) { if (!string.IsNullOrEmpty(dungeonGeneratorTheme.m_themeName) && dungeonGeneratorTheme.m_themeName != themeName) { Logger.LogWarning("Overwriting existing theme name " + dungeonGeneratorTheme.m_themeName + " with " + themeName + "."); } } else { dungeonGeneratorTheme = ((Component)componentInChildren).gameObject.AddComponent(); } dungeonGeneratorTheme.m_themeName = themeName; themeList.Add(themeName); return true; } public void RegisterEnvironment(AssetBundle assetBundle, string prefabName) { if ((Object)(object)assetBundle == (Object)null) { throw new ArgumentException("Cannot be null", "assetBundle"); } if (string.IsNullOrEmpty(prefabName)) { throw new ArgumentException("Cannot be null or empty", "prefabName"); } GameObject value = assetBundle.LoadAsset(prefabName); loadedEnvironments.Add(prefabName, value); } private void GenerateHashes() { hashToName.Clear(); foreach (CustomRoom value in Rooms.Values) { int stableHashCode = StringExtensionMethods.GetStableHashCode(value.Name); if (hashToName.ContainsKey(stableHashCode)) { Logger.LogWarning($"Room {value.Name} is already registered with hash {stableHashCode}"); } else { hashToName.Add(stableHashCode, value.Name); } } } private void OnZoneSystemSetupLocations() { if (loadedEnvironments.Count <= 0) { return; } foreach (KeyValuePair loadedEnvironment in loadedEnvironments) { Logger.LogDebug("Registering environment " + loadedEnvironment.Key + "."); GameObject value = loadedEnvironment.Value; value.FixReferences(recursive: true); Object.Instantiate(value); } } private void OnDungeonDBStarted() { InvokeOnVanillaRoomsAvailable(); if (Rooms.Count > 0) { hashToName.Clear(); List list = new List(); Logger.LogInfo($"Registering {Rooms.Count} custom rooms"); foreach (CustomRoom value in Rooms.Values) { try { Logger.LogDebug("Adding custom room " + value.Name + " with " + value.ThemeName + " theme"); if (value.FixReference && !value.SoftReference) { value.Prefab.FixReferences(recursive: true); value.FixReference = false; } if (CustomRoom.IsVanillaTheme(value.ThemeName)) { RegisterRoomInDungeonDB(value); } } catch (Exception arg) { Logger.LogWarning(value.SourceMod, $"Exception caught while adding Room: {arg}"); list.Add(value.Name); } } foreach (string item in list) { Rooms.Remove(item); } DungeonDB.instance.GenerateHashList(); GenerateHashes(); } InvokeOnRoomsRegistered(); } private void OnDungeonGeneratorSetupAvailableRooms(DungeonGenerator self) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) DungeonGeneratorTheme proxy = ((Component)self).gameObject.GetComponent(); if (DungeonGenerator.m_availableRooms == null) { return; } if ((Object)(object)proxy != (Object)null) { Logger.LogDebug($"Found DungeonGeneratorTheme component in prefab with name {((Component)self).gameObject}"); Logger.LogDebug("This dungeon generator has a custom theme = " + proxy.m_themeName + ", adding available rooms"); IEnumerable enumerable = from r in Rooms.Values where r.RoomData.m_enabled where r.ThemeName == proxy.m_themeName select r; foreach (CustomRoom item in enumerable) { Logger.LogDebug("Adding Room with name " + item.Name + " and theme " + item.ThemeName); DungeonGenerator.m_availableRooms.Add(item.RoomData); } } else if ((int)self.m_themes != 0) { Logger.LogDebug($"No DungeonGeneratorTheme component in prefab with name {((Component)self).gameObject}"); Logger.LogDebug($"Adding additional rooms of type {self.m_themes} to available rooms"); IEnumerable enumerable2 = Rooms.Values.Where((CustomRoom r) => r.RoomData.m_enabled).Where(delegate(CustomRoom r) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!Enum.TryParse(r.ThemeName, ignoreCase: false, out Theme result)) { return false; } return (int)result != 0 && ((Enum)self.m_themes).HasFlag((Enum)(object)result); }); foreach (CustomRoom item2 in enumerable2) { Logger.LogDebug("Adding Room with name " + item2.Name + " and theme " + item2.ThemeName); DungeonGenerator.m_availableRooms.Add(item2.RoomData); } } else { Logger.LogWarning("DungeonManager's SetupAvailableRooms was invoked without a valid DungeonGeneratorTheme or DungeonGenerator.m_themes value. Something may be wrong with " + ((Object)self).name + "'s generator."); } if (DungeonGenerator.m_availableRooms.Count <= 0) { Logger.LogDebug("DungeonManager's SetupAvailableRooms yielded zero rooms."); } } private void InvokeOnVanillaRoomsAvailable() { DungeonManager.OnVanillaRoomsAvailable?.SafeInvoke(); } private void InvokeOnRoomsRegistered() { DungeonManager.OnRoomsRegistered?.SafeInvoke(); } private void RegisterRoomInDungeonDB(CustomRoom room) { DungeonDB.instance.m_rooms.Add(room.RoomData); } private RoomData OnDungeonDBGetRoom(int hash) { if (hashToName.TryGetValue(hash, out var value) && Rooms.TryGetValue(value, out var value2)) { return value2.RoomData; } return null; } } public class GUIManager : IManager { private static class Patches { [HarmonyPostfix] [HarmonyPatch(typeof(PlayerController), "TakeInput")] [HarmonyPatch(typeof(Player), "TakeInput")] private static void TakeInputPatch(ref bool __result) { TakeInput(ref __result); } [HarmonyPatch(typeof(TextInput), "IsVisible")] [HarmonyPostfix] private static void TextInputPatch(ref bool __result) { TextInput_IsVisible(ref __result); } [HarmonyPatch(typeof(InventoryGui), "Update")] [HarmonyPatch(typeof(GameCamera), "UpdateCamera")] [HarmonyTranspiler] [HarmonyWrapSafe] private static IEnumerable BlockUsePatch(IEnumerable instructions) { return BlockUseTranspiler(instructions); } [HarmonyPatch(typeof(FejdStartup), "SetupGui")] [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void CreateCustomGUI() { if (!Instance.TryCreateGUI()) { Logger.LogError("Could not create custom GUI"); } } } private static GUIManager _instance; private bool hasInitializedAssets; public const int UILayer = 5; public Color ValheimBeige = new Color(0.8529f, 0.725f, 0.5331f, 1f); public Color ValheimOrange = new Color(1f, 0.631f, 0.235f, 1f); public Color ValheimYellow = new Color(1f, 0.889f, 0f, 1f); public ColorBlock ValheimScrollbarHandleColorBlock; public ColorBlock ValheimToggleColorBlock; public ColorBlock ValheimButtonColorBlock; public Resources ValheimControlResources; private SpriteAtlas UIAtlas; private SpriteAtlas IconAtlas; private bool GUIInStart; internal static bool InputBlocked; private static int InputBlockRequests; public static GUIManager Instance => _instance ?? (_instance = new GUIManager()); [Obsolete("Use CustomGUIFront or CustomGUIBack")] public static GameObject PixelFix { get; private set; } public static GameObject CustomGUIFront { get; private set; } public static GameObject CustomGUIBack { get; private set; } public Font AveriaSerif { get; private set; } public Font AveriaSerifBold { get; private set; } public Font Norse { get; private set; } public Font NorseBold { get; private set; } public TMP_FontAsset TMP_AveriaSansLibre { get; private set; } public TMP_FontAsset TMP_Norse { get; private set; } [Obsolete("Use OnCustomGUIAvailable")] public static event Action OnPixelFixCreated; public static event Action OnCustomGUIAvailable; private GUIManager() { //IL_0015: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) ColorBlock val = default(ColorBlock); ((ColorBlock)(ref val)).normalColor = new Color(0.926f, 0.645f, 0.34f, 1f); ((ColorBlock)(ref val)).highlightedColor = new Color(1f, 0.786f, 0.088f, 1f); ((ColorBlock)(ref val)).pressedColor = new Color(0.838f, 0.647f, 0.03f, 1f); ((ColorBlock)(ref val)).selectedColor = new Color(1f, 0.786f, 0.088f, 1f); ((ColorBlock)(ref val)).disabledColor = new Color(0.784f, 0.784f, 0.784f, 0.502f); ((ColorBlock)(ref val)).colorMultiplier = 1f; ((ColorBlock)(ref val)).fadeDuration = 0.1f; ValheimScrollbarHandleColorBlock = val; val = default(ColorBlock); ((ColorBlock)(ref val)).normalColor = new Color(0.61f, 0.61f, 0.61f, 1f); ((ColorBlock)(ref val)).highlightedColor = new Color(1f, 1f, 1f, 1f); ((ColorBlock)(ref val)).pressedColor = new Color(0.784f, 0.784f, 0.784f, 1f); ((ColorBlock)(ref val)).selectedColor = new Color(1f, 1f, 1f, 1f); ((ColorBlock)(ref val)).disabledColor = new Color(0.784f, 0.784f, 0.784f, 0.502f); ((ColorBlock)(ref val)).colorMultiplier = 1f; ((ColorBlock)(ref val)).fadeDuration = 0.1f; ValheimToggleColorBlock = val; val = default(ColorBlock); ((ColorBlock)(ref val)).normalColor = new Color(0.824f, 0.824f, 0.824f, 1f); ((ColorBlock)(ref val)).highlightedColor = new Color(1.3f, 1.3f, 1.3f, 1f); ((ColorBlock)(ref val)).pressedColor = new Color(0.537f, 0.556f, 0.556f, 1f); ((ColorBlock)(ref val)).selectedColor = new Color(0.824f, 0.824f, 0.824f, 1f); ((ColorBlock)(ref val)).disabledColor = new Color(0.566f, 0.566f, 0.566f, 0.502f); ((ColorBlock)(ref val)).colorMultiplier = 1f; ((ColorBlock)(ref val)).fadeDuration = 0.1f; ValheimButtonColorBlock = val; base..ctor(); } static GUIManager() { ((IManager)Instance).Init(); } public static bool IsHeadless() { return GUIUtils.IsHeadless; } public static void BlockInput(bool state) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (IsHeadless()) { return; } Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name == "main") { if (state) { InputBlockRequests++; } else { InputBlockRequests = Math.Max(--InputBlockRequests, 0); } if (!InputBlocked && InputBlockRequests > 0) { EnableInputBlock(); } if (InputBlocked && InputBlockRequests == 0) { ResetInputBlock(); } } } private static bool IsInputBlocked() { return InputBlocked; } private static void EnableInputBlock() { InputBlocked = true; if (Object.op_Implicit((Object)(object)GameCamera.instance)) { GameCamera.instance.m_mouseCapture = false; GameCamera.instance.UpdateMouseCapture(); } } private static void ResetInputBlock() { InputBlocked = false; InputBlockRequests = 0; if (Object.op_Implicit((Object)(object)GameCamera.instance)) { GameCamera.instance.m_mouseCapture = true; GameCamera.instance.UpdateMouseCapture(); } } private static void TakeInput(ref bool __result) { if (InputBlocked) { __result = false; } } private static void TextInput_IsVisible(ref bool __result) { if (InputBlocked) { __result = true; } } void IManager.Init() { Main.LogInit("GUIManager"); if (!IsHeadless()) { Instance.TryCreateGUI(); Main.Harmony.PatchAll(typeof(Patches)); InitializeAssets(); SceneManager.sceneLoaded += delegate { InitializeAssets(); }; SceneManager.sceneLoaded += delegate { Instance.TryCreateGUI(); }; } } private static IEnumerable BlockUseTranspiler(IEnumerable instructions) { //IL_0014: 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_0048: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown Label? jumpLabel = null; return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((Func)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, AccessTools.Method(typeof(Menu), "IsVisible", (Type[])null, (Type[])null))), (string)null), new CodeMatch((Func)((CodeInstruction i) => CodeInstructionExtensions.Branches(i, ref jumpLabel)), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(GUIManager), "IsInputBlocked", (Type[])null, (Type[])null)), new CodeInstruction(OpCodes.Brtrue, (object)jumpLabel) }) .InstructionEnumeration(); } internal void InitializeAssets() { //IL_0009: 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_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_03ce: Unknown result type (might be due to invalid IL or missing references) if (hasInitializedAssets) { return; } Scene activeScene = SceneManager.GetActiveScene(); if (!(((Scene)(ref activeScene)).name == "start") && !(((Scene)(ref activeScene)).name == "main")) { return; } try { UIAtlas = PrefabManager.Cache.GetPrefab("UIAtlas"); IconAtlas = PrefabManager.Cache.GetPrefab("IconAtlas"); AssertMissingAsset((Object)(object)UIAtlas, "UIAtlas", "SpriteAtlas"); AssertMissingAsset((Object)(object)IconAtlas, "IconAtlas", "SpriteAtlas"); AveriaSerif = PrefabManager.Cache.GetPrefab("AveriaSerifLibre-Regular"); AveriaSerifBold = PrefabManager.Cache.GetPrefab("AveriaSerifLibre-Bold"); Norse = PrefabManager.Cache.GetPrefab("Norse"); NorseBold = PrefabManager.Cache.GetPrefab("Norsebold"); TMP_AveriaSansLibre = PrefabManager.Cache.GetPrefab("Valheim-AveriaSansLibre"); TMP_Norse = PrefabManager.Cache.GetPrefab("Valheim-Norse"); AssertMissingAsset((Object)(object)AveriaSerif, "AveriaSerif", "Font"); AssertMissingAsset((Object)(object)AveriaSerifBold, "AveriaSerifBold", "Font"); AssertMissingAsset((Object)(object)Norse, "Norse", "Font"); AssertMissingAsset((Object)(object)NorseBold, "NorseBold", "Font"); AssertMissingAsset((Object)(object)TMP_AveriaSansLibre, "TMP_AveriaSansLibre", "TMP_FontAsset"); AssertMissingAsset((Object)(object)TMP_Norse, "TMP_Norse", "TMP_FontAsset"); AssetBundle val = AssetUtils.LoadAssetBundleFromResources("jotunn", typeof(Main).Assembly); GameObject val2 = val.LoadAsset("UIMaskStub"); ValheimControlResources.standard = GetSprite("button"); ValheimControlResources.background = GetSprite("text_field"); ValheimControlResources.inputField = GetSprite("text_field"); ValheimControlResources.knob = GetSprite("checkbox_marker"); ValheimControlResources.checkmark = GetSprite("checkbox_marker"); ValheimControlResources.dropdown = GetSprite("checkbox_marker"); ValheimControlResources.mask = val2.GetComponent().sprite; val.Unload(false); AssetBundle val3 = AssetUtils.LoadAssetBundleFromResources("colorpicker", typeof(Main).Assembly); GameObject val4 = val3.LoadAsset("ColorPicker"); Image component = val4.GetComponent(); component.sprite = GetSprite("woodpanel_settings"); component.type = (Type)1; component.pixelsPerUnitMultiplier = (GUIInStart ? 2f : 1f); ((Graphic)component).material = PrefabManager.Cache.GetPrefab("litpanel"); Text[] componentsInChildren = val4.GetComponentsInChildren(true); foreach (Text val5 in componentsInChildren) { ApplyTextStyle(val5, ValheimOrange, val5.fontSize); } InputField[] componentsInChildren2 = val4.GetComponentsInChildren(true); foreach (InputField field in componentsInChildren2) { ApplyInputFieldStyle(field, 13); } Button[] componentsInChildren3 = val4.GetComponentsInChildren