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.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.ConsoleCommands; using Jotunn.Entities; using Jotunn.GUI; using Jotunn.Managers; using Jotunn.Managers.MockSystem; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using SimpleJson; using SimpleJson.Reflection; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.U2D; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: InternalsVisibleTo("JotunnTests")] [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.10.2.0")] [assembly: AssemblyInformationalVersion("2.10.2")] [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.10.2.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? Browsable; public object DefaultValue; public bool? HideDefaultButton; public int? Order; public bool? ReadOnly; public bool? IsAdvanced; private bool isAdminOnly; private bool isUnlocked; 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; IsUnlocked = !value; } } public Color EntryColor { get; set; } public Color DescriptionColor { get; set; } public bool IsUnlocked { get { return isUnlocked; } internal set { ReadOnly = !value; HideDefaultButton = !value; isUnlocked = value; } } internal object LocalValue { get; set; } public ConfigurationManagerAttributes() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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; } DisplayNameAttribute displayNameAttribute = obj as DisplayNameAttribute; if (displayNameAttribute != null) { continue; } CategoryAttribute categoryAttribute = obj as CategoryAttribute; if (categoryAttribute != null) { continue; } DescriptionAttribute descriptionAttribute = obj as DescriptionAttribute; if (descriptionAttribute != null) { continue; } 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 value = item.other.GetValue(obj); if (value != null) { item.my.SetValue(this, value, 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 value2 = item2.other.GetValue(obj); if (value2 != null) { item2.my.SetValue(this, value2); } } 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; } } } } 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_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_03df: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_044e: 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); if (ReflectionUtils.IsNullableType(type)) { return ReflectionUtils.ToNullableType(obj, type); } return obj; } 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 { obj = ConstructorCache[type](); 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; } 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 (configurationEntry.Description.Tags.FirstOrDefault((object x) => x is ConfigurationManagerAttributes) is ConfigurationManagerAttributes configurationManagerAttributes) { return configurationManagerAttributes.LocalValue; } return null; } internal static void SetLocalValue(this ConfigEntryBase configurationEntry, object value) { if (configurationEntry.Description.Tags.FirstOrDefault((object x) => x is ConfigurationManagerAttributes) is ConfigurationManagerAttributes configurationManagerAttributes) { configurationManagerAttributes.LocalValue = value; } } } 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 { return gameObject.GetComponent() ?? gameObject.AddComponent(); } 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) { if (!(propertyInfo.Name == "rayTracingMode") && 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; } } 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) { go.GetComponent().text = text; return go; } } public static class GameObjectExtension { public static bool IsValid(this GameObject 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("GameObject must have a name !"); } if (Object.op_Implicit((Object)(object)self.GetComponent()) && ((Object)self).name.IndexOfAny(new char[2] { ')', ' ' }) > 0) { throw new Exception("GameObject name must not contain parenthesis or spaces!"); } return true; } catch (Exception data) { Logger.LogError(data); return false; } } } 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) { MockManager.FixReferences(objectToFix, 0); } public static void FixReferences(this GameObject gameObject) { gameObject.FixReferences(recursive: false); } public static void FixReferences(this GameObject gameObject, bool recursive) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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; } foreach (Transform item in gameObject.transform) { Transform val2 = item; ((Component)val2).gameObject.FixReferences(recursive: true); } } 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; private static Logger instance; private readonly Dictionary logger = new Dictionary(); internal static void Init() { if (instance == null) { instance = new Logger(); } } 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.10.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(CompatibilityLevel.VersionCheckOnly, VersionStrictness.Minor)] public class Main : BaseUnityPlugin { public const string Version = "2.10.2"; public const string ModName = "Jotunn"; public const string ModGuid = "com.jotunn.jotunn"; internal static Main Instance; internal static Harmony Harmony; internal static GameObject RootObject; private List Managers; private void Awake() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown Instance = this; Harmony = new Harmony("com.jotunn.jotunn"); Harmony.PatchAll(typeof(ModCompatibility)); Logger.Init(); RootObject = new GameObject("_JotunnRoot"); Object.DontDestroyOnLoad((Object)(object)RootObject); Managers = new List { LocalizationManager.Instance, CommandManager.Instance, InputManager.Instance, SkillManager.Instance, PrefabManager.Instance, ItemManager.Instance, PieceManager.Instance, CreatureManager.Instance, ZoneManager.Instance, MockManager.Instance, KitbashManager.Instance, GUIManager.Instance, KeyHintManager.Instance, NetworkManager.Instance, SynchronizationManager.Instance, RenderManager.Instance, MinimapManager.Instance, UndoManager.Instance }; foreach (IManager manager in Managers) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Initializing " + manager.GetType().Name)); manager.Init(); } ModQuery.Init(); ModCompatibility.Init(); Game.isModded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Jötunn v2.10.2 loaded successfully"); } private void Start() { InitializePatches(); } private void OnApplicationQuit() { AssetBundle.UnloadAllAssetBundles(false); } private 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); } } } 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.EnumeratedType = base.MemberType.GetEnumeratedType(); base.IsEnumerableOfUnityObjects = base.EnumeratedType?.IsSameOrSubclass(typeof(Object)) ?? false; base.IsEnumeratedClass = base.EnumeratedType?.IsClass ?? false; } public override object GetValue(object obj) { return fieldInfo.GetValue(obj); } 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 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; } 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.EnumeratedType = base.MemberType.GetEnumeratedType(); base.IsEnumerableOfUnityObjects = base.EnumeratedType?.IsSameOrSubclass(typeof(Object)) ?? false; base.IsEnumeratedClass = base.EnumeratedType?.IsClass ?? false; } public override object GetValue(object obj) { return propertyInfo.GetValue(obj); } 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 = '$'; public static Texture2D LoadTexture(string texturePath, bool relativePath = true) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown 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[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2); ImageConversion.LoadImage(val, array); return val; } 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 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); } } public static class BepInExUtils { private static BaseUnityPlugin[] Plugins; private static Dictionary PluginInfoTypeNameCache { get; } = new Dictionary(); private static Dictionary AssemblyToPluginInfoCache { 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) { foreach (PluginInfo value in Chainloader.PluginInfos.Values) { string privateProperty = ReflectionHelper.GetPrivateProperty(value, "TypeName"); if (privateProperty.Equals(type.FullName)) { return value; } } return null; } private static string GetPluginInfoTypeName(PluginInfo info) { if (PluginInfoTypeNameCache.ContainsKey(info)) { return PluginInfoTypeNameCache[info]; } string privateProperty = ReflectionHelper.GetPrivateProperty(info, "TypeName"); PluginInfoTypeNameCache.Add(info, privateProperty); return privateProperty; } public static PluginInfo GetPluginInfoFromAssembly(Assembly assembly) { if (AssemblyToPluginInfoCache.ContainsKey(assembly)) { return AssemblyToPluginInfoCache[assembly]; } foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (assembly.GetType(GetPluginInfoTypeName(value)) != null) { AssemblyToPluginInfoCache.Add(assembly, value); return value; } } 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), "SetLegEquiped")] [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), "SetHelmetEquiped")] [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), "SetChestEquiped")] [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), "SetShoulderEquiped")] [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), "SetUtilityEquiped")] [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 ConfigurationSynchronizationEventArgs : EventArgs { public bool InitialSynchronization { get; set; } } 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) { ((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), "SetRightHandEquiped")] [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), "SetBackEquiped")] [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), "SetChestEquiped")] [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 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; } } public static class ModCompatibility { private static ZPackage LastServerVersion; private static readonly Dictionary ClientVersions = new Dictionary(); internal static void Init() { 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)); } [HarmonyPatch(typeof(ZNet), "OnNewConnection")] [HarmonyPrefix] [HarmonyPriority(800)] private static void ZNet_OnNewConnection(ZNet __instance, ZNetPeer peer) { LastServerVersion = null; 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 if (LastServerVersion != null && (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() && LastServerVersion == null && GetEnforcableMods().Any((ModModule x) => x.IsNeededOnServer())) { string text = string.Join(Environment.NewLine, from x in GetEnforcableMods() where x.IsNeededOnServer() select x.name); 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()); LastServerVersion = new ModuleVersionData(new List()).ToZPackage(); 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.name); 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 { LastServerVersion = data; } } internal static bool CompareVersionData(ModuleVersionData serverData, ModuleVersionData clientData) { if (serverData == clientData) { return true; } bool result = true; if (!object.Equals(serverData.ValheimVersion, clientData.ValheimVersion)) { Logger.LogWarning($"Version incompatibility: Server {serverData.ValheimVersion}, Client {clientData.ValheimVersion}"); result = false; } foreach (ModModule item in FindNotInstalledMods(serverData, clientData)) { Logger.LogWarning("Missing mod on client: " + item.name); result = false; } foreach (ModModule item2 in FindAdditionalMods(serverData, clientData)) { Logger.LogWarning("Client loaded additional mod: " + item2.name); result = false; } foreach (ModModule item3 in FindLowerVersionMods(serverData, clientData).Union(FindHigherVersionMods(serverData, clientData))) { ModModule modModule = clientData.FindModule(item3.name); Logger.LogWarning($"Mod version mismatch {item3.name}: Server {item3.version}, Client {modModule.version}"); result = false; } return result; } private static CompatibilityWindow LoadCompatWindow() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) 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 = new ModuleVersionData(LastServerVersion); 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; LastServerVersion = null; } 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) + CreateVersionStringErrorMessage(serverData, clientData); } private static string CreateVanillaVersionErrorMessage(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) //IL_006a: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) if (serverData.ValheimVersion > clientData.ValheimVersion) { return ColoredLine(Color.red, "$mod_compat_header_valheim_version") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_valheim_version_error_description", $"{serverData.ValheimVersion}", $"{clientData.ValheimVersion}") + ColoredLine(Color.white, "$mod_compat_valheim_version_upgrade", serverData.ValheimVersion.ToString()) + Environment.NewLine; } if (serverData.ValheimVersion < clientData.ValheimVersion) { return ColoredLine(Color.red, "$mod_compat_header_valheim_version") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_valheim_version_error_description", $"{serverData.ValheimVersion}", $"{clientData.ValheimVersion}") + ColoredLine(Color.white, "$mod_compat_valheim_version_downgrade", $"{serverData.ValheimVersion}") + Environment.NewLine; } return string.Empty; } private static string CreateVersionStringErrorMessage(ModuleVersionData serverData, ModuleVersionData clientData) { //IL_0049: 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_007c: 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) if (serverData.ValheimVersion == clientData.ValheimVersion && !string.IsNullOrEmpty(serverData.VersionString) && serverData.VersionString != clientData.VersionString) { return ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_header_version_string") + ColoredLine(GUIManager.Instance.ValheimOrange, "$mod_compat_version_string_description") + ColoredLine(Color.white, "$mod_compat_version_strong_local", clientData.VersionString ?? "") + ColoredLine(Color.white, "$mod_compat_version_strong_remote", serverData.VersionString ?? "") + 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.name ?? "", $"{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.name, 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.name, 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.name, $"{clientModule.version}"))) + 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) { foreach (ModModule module in baseModules.Modules) { ModModule arg = additionalModules.FindModule(module.name); 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 = ((object)item.Value).GetType().GetCustomAttributes(typeof(NetworkCompatibilityAttribute), inherit: true).Cast() .FirstOrDefault(); if (networkCompatibilityAttribute != null) { yield return new ModModule(item.Value.Info.Metadata, networkCompatibilityAttribute); } } } 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 string name; public Version version; public CompatibilityLevel compatibilityLevel; public VersionStrictness versionStrictness; public ModModule(string name, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness) { this.name = name; this.version = version; this.compatibilityLevel = compatibilityLevel; this.versionStrictness = versionStrictness; } public ModModule(ZPackage pkg) { name = pkg.ReadString(); version = new Version(pkg.ReadInt(), pkg.ReadInt(), pkg.ReadInt()); compatibilityLevel = (CompatibilityLevel)pkg.ReadInt(); versionStrictness = (VersionStrictness)pkg.ReadInt(); } public void WriteToPackage(ZPackage pkg) { pkg.Write(name); 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) { name = plugin.Name; version = plugin.Version; compatibilityLevel = networkAttribute.EnforceModOnClients; versionStrictness = networkAttribute.EnforceSameVersion; } public string GetVersionString() { return $"{version.Major}.{version.Minor}.{version.Build}"; } 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 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; internal ModuleVersionData(List versionData) { ValheimVersion = new Version(Version.m_major, Version.m_minor, Version.m_patch); VersionString = Version.GetVersionString(); Modules = new List(versionData); } internal ModuleVersionData(Version valheimVersion, List versionData) { ValheimVersion = valheimVersion; VersionString = Version.GetVersionString(); Modules = new List(versionData); } 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)); } if (pkg.m_reader.BaseStream.Position != pkg.m_reader.BaseStream.Length) { VersionString = pkg.ReadString(); } } catch (Exception ex) { Logger.LogError("Could not deserialize version message data from zPackage"); Logger.LogError(ex.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); } val.Write(VersionString); 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.name} {module.GetVersionString()} {module.compatibilityLevel} {module.versionStrictness}"); } return stringBuilder.ToString(); } public string ToString(bool showEnforce) { 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.name + " " + module.GetVersionString() + (showEnforce ? $" {module.compatibilityLevel} {module.versionStrictness}" : "")); } return stringBuilder.ToString(); } public ModModule FindModule(string name) { return Modules.FirstOrDefault((ModModule x) => x.name == name); } public bool HasModule(string name) { return FindModule(name) != null; } } 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; } } 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 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.Harmony.PatchAll(typeof(ModQuery)); } public static void Enable() { 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() { if (enabled) { 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), "UpdateItemHashes", (Type[])null, (Type[])null)); } } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPrefix] [HarmonyPriority(1000)] private static void ObjectDBAwake(ObjectDB __instance) { if (enabled) { __instance.UpdateItemHashes(); } } 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 arg) { Logger.LogError($"Failed to patch {patch.PatchMethod} from {patch.owner}: {arg}"); } } } } private static void BeforePatch(object[] __args, ref Tuple __state) { ObjectDB objectDB = GetObjectDB(__args); ZNetScene zNetScene = GetZNetScene(__args); __state = new Tuple(new ZNetSceneState(zNetScene), new ObjectDBState(objectDB)); } private static void AfterPatch(object[] __args, ref Tuple __state) { if (__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 (!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; } 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); } } [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"); } 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.Resize(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 static class UndoActions { private static class UndoHelper { public static void CopyData(ZDO from, ZDO to) { //IL_0074: 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_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_00a9: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) bool flag = to.m_prefab != from.m_prefab; to.m_floats = from.m_floats; to.m_vec3 = from.m_vec3; to.m_quats = from.m_quats; to.m_ints = from.m_ints; to.m_longs = from.m_longs; to.m_strings = from.m_strings; to.m_byteArrays = from.m_byteArrays; to.m_prefab = from.m_prefab; to.m_position = from.m_position; to.m_rotation = from.m_rotation; 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 = 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.IncreseDataRevision(); } 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.Clone(), 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((ZDO zdo) => zdo.Clone()).ToArray(); } public static void RemoveZDO(ZDO zdo) { if (IsValid(zdo)) { if (!zdo.IsOwner()) { zdo.SetOwner(ZDOMan.instance.GetMyID()); } 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 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 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() { } public void Init() { AddConsoleCommand(new ClearCommand()); 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) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_00fb: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) if (!_customCommands.Any()) { return; } Logger.LogInfo($"Adding {_customCommands.Count} commands to the Console"); foreach (ConsoleCommand cmd in _customCommands) { if (((Terminal)self).m_commandList.Contains(cmd.Name)) { Logger.LogWarning(cmd.SourceMod, "Cannot override existing command: " + cmd.Name); return; } string name = cmd.Name; string help = cmd.Help; ConsoleEvent val = delegate(ConsoleEventArgs args) { cmd.Run(args.Args.Skip(1).ToArray()); }; bool isCheat = cmd.IsCheat; bool isNetwork = cmd.IsNetwork; bool onlyServer = cmd.OnlyServer; bool isSecret = cmd.IsSecret; ConsoleCommand consoleCommand = cmd; new ConsoleCommand(name, help, val, isCheat, isNetwork, onlyServer, isSecret, false, new ConsoleOptionsFetcher(consoleCommand.CommandOptionList)); } ((Terminal)self).updateCommandList(); } 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 = LayerMask.NameToLayer("character"); 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() { } public void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown 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()) { return; } 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 (MockResolveException ex) { Logger.LogWarning(creature?.SourceMod, $"Skipping creature {creature}: could not resolve mock {ex.MockType.Name} {ex.FailedMockName}"); list.Add(creature); } 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 GUIManager : IManager { private static class Patches { [HarmonyPatch(typeof(Player), "TakeInput")] [HarmonyPostfix] private static void Player_TakeInput(ref bool __result) { GUIManager.Player_TakeInput(ref __result); } [HarmonyPatch(typeof(PlayerController), "TakeInput")] [HarmonyPostfix] private static void PlayerController_TakeInput(ref bool __result) { GUIManager.PlayerController_TakeInput(ref __result); } [HarmonyPatch(typeof(Menu), "IsVisible")] [HarmonyPostfix] private static void Menu_IsVisible(ref bool __result) { GUIManager.Menu_IsVisible(ref __result); } [HarmonyPatch(typeof(TextInput), "IsVisible")] [HarmonyPostfix] private static void TextInput_IsVisible(ref bool __result) { GUIManager.TextInput_IsVisible(ref __result); } [HarmonyPatch(typeof(FejdStartup), "SetupGui")] [HarmonyPostfix] private static void FejdStartup_SetupGui(FejdStartup __instance) { Instance.FejdStartup_SetupGui(__instance); } [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] private static void Game_Start(Game __instance) { Instance.Game_Start(__instance); } } private static GUIManager _instance; public const int UILayer = 5; public Color ValheimOrange = new Color(1f, 0.631f, 0.235f, 1f); public ColorBlock ValheimScrollbarHandleColorBlock; public ColorBlock ValheimToggleColorBlock; public ColorBlock ValheimButtonColorBlock; public Resources ValheimControlResources; private SpriteAtlas UIAtlas; private SpriteAtlas IconAtlas; private bool GUIInStart; private static bool Headless; 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; } [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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_026f: 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(); } public static bool IsHeadless() { return Headless; } 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 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 PlayerController_TakeInput(ref bool __result) { if (InputBlocked) { __result = false; } } private static void Player_TakeInput(ref bool __result) { if (InputBlocked) { __result = false; } } private static void Menu_IsVisible(ref bool __result) { if (InputBlocked) { __result = true; } } private static void TextInput_IsVisible(ref bool __result) { if (InputBlocked) { __result = true; } } public void Init() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 Headless = (int)SystemInfo.graphicsDeviceType == 4; if (!IsHeadless()) { Main.Harmony.PatchAll(typeof(Patches)); SceneManager.sceneLoaded += InitialLoad; } } internal void InitialLoad(Scene scene, LoadSceneMode loadMode) { //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) if (!(((Scene)(ref scene)).name == "start")) { return; } try { SpriteAtlas[] source = Resources.FindObjectsOfTypeAll(); UIAtlas = ((IEnumerable)source).FirstOrDefault((Func)((SpriteAtlas x) => ((Object)x).name.Equals("UIAtlas"))); if ((Object)(object)UIAtlas == (Object)null) { throw new Exception("UIAtlas not found"); } IconAtlas = ((IEnumerable)source).FirstOrDefault((Func)((SpriteAtlas x) => ((Object)x).name.Equals("IconAtlas"))); if ((Object)(object)IconAtlas == (Object)null) { throw new Exception("IconAtlas not found"); } Font[] source2 = Resources.FindObjectsOfTypeAll(); AveriaSerif = ((IEnumerable)source2).FirstOrDefault((Func)((Font x) => ((Object)x).name == "AveriaSerifLibre-Regular")); AveriaSerifBold = ((IEnumerable)source2).FirstOrDefault((Func)((Font x) => ((Object)x).name == "AveriaSerifLibre-Bold")); if ((Object)(object)AveriaSerifBold == (Object)null || (Object)(object)AveriaSerif == (Object)null) { throw new Exception("Fonts not found"); } 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