using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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 BiggerBazaar; using HG; using HG.Reflection; using IL.RoR2; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour.HookGen; using On.RoR2; using On.RoR2.UI; using PSTinyJson; using ProperSave.Components; using ProperSave.Data; using ProperSave.Old; using ProperSave.Old.Data; using ProperSave.Old.SaveData; using ProperSave.Old.SaveData.Artifacts; using ProperSave.Old.SaveData.Runs; using ProperSave.SaveData; using ProperSave.SaveData.Artifacts; using ProperSave.SaveData.Runs; using ProperSave.TinyJson; using ProperSave.Utils; using R2API; using RoR2; using RoR2.Artifacts; using RoR2.CharacterAI; using RoR2.ContentManagement; using RoR2.ExpansionManagement; using RoR2.Networking; using RoR2.Skills; using RoR2.Stats; using RoR2.UI; using ShareSuite; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.SceneManagement; using UnityEngine.UI; using Zio; using Zio.FileSystems; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: OptIn] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.0.7.0")] namespace PSTinyJson { public static class JSONParser { [ThreadStatic] private static Stack> splitArrayPool; [ThreadStatic] private static StringBuilder stringBuilder; [ThreadStatic] private static Dictionary> fieldInfoCache; [ThreadStatic] private static Dictionary> propertyInfoCache; public static T FromJson(this string json) { return (T)json.FromJson(typeof(T)); } public static object FromJson(this string json, Type type) { if (propertyInfoCache == null) { propertyInfoCache = new Dictionary>(); } if (fieldInfoCache == null) { fieldInfoCache = new Dictionary>(); } if (stringBuilder == null) { stringBuilder = new StringBuilder(); } if (splitArrayPool == null) { splitArrayPool = new Stack>(); } stringBuilder.Length = 0; for (int i = 0; i < json.Length; i++) { char c = json[i]; if (c == '"') { i = AppendUntilStringEnd(appendEscapeCharacter: true, i, json); } else if (!char.IsWhiteSpace(c)) { stringBuilder.Append(c); } } return ParseValue(type, stringBuilder.ToString()); } private static int AppendUntilStringEnd(bool appendEscapeCharacter, int startIdx, string json) { stringBuilder.Append(json[startIdx]); for (int i = startIdx + 1; i < json.Length; i++) { if (json[i] == '\\') { if (appendEscapeCharacter) { stringBuilder.Append(json[i]); } stringBuilder.Append(json[i + 1]); i++; } else { if (json[i] == '"') { stringBuilder.Append(json[i]); return i; } stringBuilder.Append(json[i]); } } return json.Length - 1; } private static List Split(string json) { List list = ((splitArrayPool.Count > 0) ? splitArrayPool.Pop() : new List()); list.Clear(); if (json.Length == 2) { return list; } int num = 0; stringBuilder.Length = 0; for (int i = 1; i < json.Length - 1; i++) { switch (json[i]) { case '[': case '{': num++; break; case ']': case '}': num--; break; case '"': i = AppendUntilStringEnd(appendEscapeCharacter: true, i, json); continue; case ',': case ':': if (num == 0) { list.Add(stringBuilder.ToString()); stringBuilder.Length = 0; continue; } break; } stringBuilder.Append(json[i]); } list.Add(stringBuilder.ToString()); return list; } internal static object ParseValue(Type type, string json) { if (type == typeof(string)) { if (json.Length <= 2) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(json.Length); for (int i = 1; i < json.Length - 1; i++) { if (json[i] == '\\' && i + 1 < json.Length - 1) { int num = "\"\\nrtbf/".IndexOf(json[i + 1]); if (num >= 0) { stringBuilder.Append("\"\\\n\r\t\b\f/"[num]); i++; continue; } if (json[i + 1] == 'u' && i + 5 < json.Length - 1) { uint result = 0u; if (uint.TryParse(json.Substring(i + 2, 4), NumberStyles.AllowHexSpecifier, null, out result)) { stringBuilder.Append((char)result); i += 5; continue; } } } stringBuilder.Append(json[i]); } return stringBuilder.ToString(); } if (type.IsPrimitive) { return Convert.ChangeType(json, type, CultureInfo.InvariantCulture); } if (type == typeof(decimal)) { decimal.TryParse(json, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2); return result2; } if (json == "null") { return null; } if (type.IsEnum) { if (json[0] == '"') { json = json.Substring(1, json.Length - 2); try { return Enum.Parse(type, json, ignoreCase: false); } catch { return 0; } } return Convert.ChangeType(json, Enum.GetUnderlyingType(type)); } if (type.IsArray) { Type elementType = type.GetElementType(); if (json[0] != '[' || json[json.Length - 1] != ']') { return null; } List list = Split(json); Array array = Array.CreateInstance(elementType, list.Count); for (int j = 0; j < list.Count; j++) { array.SetValue(ParseValue(elementType, list[j]), j); } splitArrayPool.Push(list); return array; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) { Type type2 = type.GetGenericArguments()[0]; if (json[0] != '[' || json[json.Length - 1] != ']') { return null; } List list2 = Split(json); IList list3 = (IList)type.GetConstructor(new Type[1] { typeof(int) }).Invoke(new object[1] { list2.Count }); for (int k = 0; k < list2.Count; k++) { list3.Add(ParseValue(type2, list2[k])); } splitArrayPool.Push(list2); return list3; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { Type[] genericArguments = type.GetGenericArguments(); Type type3 = genericArguments[0]; Type type4 = genericArguments[1]; if (type3 != typeof(string)) { return null; } if (json[0] != '{' || json[json.Length - 1] != '}') { return null; } List list4 = Split(json); if (list4.Count % 2 != 0) { return null; } IDictionary dictionary = (IDictionary)type.GetConstructor(new Type[1] { typeof(int) }).Invoke(new object[1] { list4.Count / 2 }); for (int l = 0; l < list4.Count; l += 2) { if (list4[l].Length > 2) { string key = list4[l].Substring(1, list4[l].Length - 2); object value = ParseValue(type4, list4[l + 1]); dictionary.Add(key, value); } } return dictionary; } if (type == typeof(object)) { return ParseAnonymousValue(json); } if (json[0] == '{' && json[json.Length - 1] == '}') { return ParseObject(type, json); } return null; } private static object ParseAnonymousValue(string json) { if (json.Length == 0) { return null; } if (json[0] == '{' && json[json.Length - 1] == '}') { List list = Split(json); if (list.Count % 2 != 0) { return null; } Dictionary dictionary = new Dictionary(list.Count / 2); for (int i = 0; i < list.Count; i += 2) { dictionary.Add(list[i].Substring(1, list[i].Length - 2), ParseAnonymousValue(list[i + 1])); } return dictionary; } if (json[0] == '[' && json[json.Length - 1] == ']') { List list2 = Split(json); List list3 = new List(list2.Count); for (int j = 0; j < list2.Count; j++) { list3.Add(ParseAnonymousValue(list2[j])); } return list3; } if (json[0] == '"' && json[json.Length - 1] == '"') { return json.Substring(1, json.Length - 2).Replace("\\", string.Empty); } if (char.IsDigit(json[0]) || json[0] == '-') { if (json.Contains(".")) { double.TryParse(json, NumberStyles.Float, CultureInfo.InvariantCulture, out var result); return result; } int.TryParse(json, out var result2); return result2; } if (json == "true") { return true; } if (json == "false") { return false; } return null; } private static Dictionary CreateMemberNameDictionary(T[] members) where T : MemberInfo { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (T val in members) { if (val.IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true)) { continue; } string name = val.Name; if (val.IsDefined(typeof(DataMemberAttribute), inherit: true)) { DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)Attribute.GetCustomAttribute(val, typeof(DataMemberAttribute), inherit: true); if (!string.IsNullOrEmpty(dataMemberAttribute.Name)) { name = dataMemberAttribute.Name; } } dictionary.Add(name, val); } return dictionary; } private static object ParseObject(Type type, string json) { object uninitializedObject = FormatterServices.GetUninitializedObject(type); List list = Split(json); if (list.Count % 2 != 0) { return uninitializedObject; } if (!fieldInfoCache.TryGetValue(type, out var value)) { value = CreateMemberNameDictionary(type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)); fieldInfoCache.Add(type, value); } if (!propertyInfoCache.TryGetValue(type, out var value2)) { value2 = CreateMemberNameDictionary(type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy)); propertyInfoCache.Add(type, value2); } for (int i = 0; i < list.Count; i += 2) { if (list[i].Length > 2) { string key = list[i].Substring(1, list[i].Length - 2); string json2 = list[i + 1]; PropertyInfo value4; if (value.TryGetValue(key, out var value3)) { DiscoverObjectTypeAttribute customAttribute = value3.GetCustomAttribute(); value3.SetValue(uninitializedObject, ParseValue(customAttribute?.GetObjectType(uninitializedObject) ?? value3.FieldType, json2)); } else if (value2.TryGetValue(key, out value4)) { DiscoverObjectTypeAttribute customAttribute2 = value4.GetCustomAttribute(); value4.SetValue(uninitializedObject, ParseValue(customAttribute2?.GetObjectType(uninitializedObject) ?? value4.PropertyType, json2), null); } } } return uninitializedObject; } } } namespace ProperSave { public static class Extensions { [StructLayout(LayoutKind.Explicit)] private struct Union { [FieldOffset(0)] public ushort @ushort; [FieldOffset(0)] public uint @uint; [FieldOffset(0)] public ulong @ulong; [FieldOffset(8)] public bool negative; public readonly short @short { get { if (!negative) { return (short)@ushort; } return (short)(-@ushort); } } public readonly int @int { get { if (!negative) { return (int)@uint; } return (int)(0 - @uint); } } public readonly long @long { get { if (!negative) { return (long)@ulong; } return (long)(0L - @ulong); } } public Union(ulong value, bool negative) { @ushort = 0; @uint = 0u; @ulong = value; this.negative = negative; } public static implicit operator Union(short value) { return new Union { @ushort = (ushort)Math.Abs(value), negative = (value < 0) }; } public static implicit operator Union(ushort value) { return new Union { @ushort = value }; } public static implicit operator Union(int value) { return new Union { @uint = (uint)Math.Abs(value), negative = (value < 0) }; } public static implicit operator Union(uint value) { return new Union { @uint = value }; } public static implicit operator Union(long value) { return new Union { @ulong = (ulong)Math.Abs(value), negative = (value < 0) }; } public static implicit operator Union(ulong value) { return new Union { @ulong = value }; } } public static int DifferenceCount(this IEnumerable collection, IEnumerable second) { List list = second.ToList(); int num = 0; foreach (T item in collection) { if (!list.Remove(item)) { num++; } } return num + list.Count; } public static string GetSafe(this string[] list, int index) { if ((uint)index > list.Length) { return null; } return list[index]; } public static int AddOrIndexOf(this List list, string value) { if (value == null) { return -1; } int num = list.IndexOf(value); if (num < 0) { list.Add(value); return list.Count - 1; } return num; } public static T GetSafe(this List list, int index) { if (list == null || list.Count < (uint)index) { return default(T); } return list[index]; } public static void WritePacked(this BinaryWriter writer, short value) { WritePackedSigned(writer, value); } public static void WritePacked(this BinaryWriter writer, ushort value) { WritePacked(writer, (Union)value); } public static void WritePacked(this BinaryWriter writer, int value) { WritePackedSigned(writer, value); } public static void WritePacked(this BinaryWriter writer, uint value) { WritePacked(writer, (Union)value); } public static void WritePacked(this BinaryWriter writer, long value) { WritePackedSigned(writer, value); } public static void WritePacked(this BinaryWriter writer, ulong value) { WritePacked(writer, (Union)value); } private static void WritePackedSigned(BinaryWriter writer, Union union) { ulong num = (ulong)(union.negative ? 0 : 128); ulong num2 = union.@ulong; if (num2 <= 112) { writer.Write((byte)(num2 | num)); } else if (num2 <= 2159) { writer.Write((byte)(((num2 - 112) / 256 + 113) | num)); writer.Write((byte)((num2 - 112) % 256)); } else if (num2 <= 67694) { writer.Write((byte)(0x79 | num)); writer.Write((byte)((num2 - 2160) / 256)); writer.Write((byte)((num2 - 2160) % 256)); } else if (num2 <= 16777215) { writer.Write((byte)(0x7A | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); } else if (num2 <= uint.MaxValue) { writer.Write((byte)(0x7B | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); writer.Write((byte)((num2 >> 24) & 0xFF)); } else if (num2 <= 1099511627775L) { writer.Write((byte)(0x7C | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); writer.Write((byte)((num2 >> 24) & 0xFF)); writer.Write((byte)((num2 >> 32) & 0xFF)); } else if (num2 <= 281474976710655L) { writer.Write((byte)(0x7D | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); writer.Write((byte)((num2 >> 24) & 0xFF)); writer.Write((byte)((num2 >> 32) & 0xFF)); writer.Write((byte)((num2 >> 40) & 0xFF)); } else if (num2 <= 72057594037927935L) { writer.Write((byte)(0x7E | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); writer.Write((byte)((num2 >> 24) & 0xFF)); writer.Write((byte)((num2 >> 32) & 0xFF)); writer.Write((byte)((num2 >> 40) & 0xFF)); writer.Write((byte)((num2 >> 48) & 0xFF)); } else { writer.Write((byte)(0x7F | num)); writer.Write((byte)(num2 & 0xFF)); writer.Write((byte)((num2 >> 8) & 0xFF)); writer.Write((byte)((num2 >> 16) & 0xFF)); writer.Write((byte)((num2 >> 24) & 0xFF)); writer.Write((byte)((num2 >> 32) & 0xFF)); writer.Write((byte)((num2 >> 40) & 0xFF)); writer.Write((byte)((num2 >> 48) & 0xFF)); writer.Write((byte)((num2 >> 56) & 0xFF)); } } private static void WritePacked(BinaryWriter writer, Union union) { ulong num = union.@ulong; if (num <= 240) { writer.Write((byte)num); } else if (num <= 2287) { writer.Write((byte)((num - 240) / 256 + 241)); writer.Write((byte)((num - 240) % 256)); } else if (num <= 67823) { writer.Write((byte)249); writer.Write((byte)((num - 2288) / 256)); writer.Write((byte)((num - 2288) % 256)); } else if (num <= 16777215) { writer.Write((byte)250); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); } else if (num <= uint.MaxValue) { writer.Write((byte)251); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); writer.Write((byte)((num >> 24) & 0xFF)); } else if (num <= 1099511627775L) { writer.Write((byte)252); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); writer.Write((byte)((num >> 24) & 0xFF)); writer.Write((byte)((num >> 32) & 0xFF)); } else if (num <= 281474976710655L) { writer.Write((byte)253); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); writer.Write((byte)((num >> 24) & 0xFF)); writer.Write((byte)((num >> 32) & 0xFF)); writer.Write((byte)((num >> 40) & 0xFF)); } else if (num <= 72057594037927935L) { writer.Write((byte)254); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); writer.Write((byte)((num >> 24) & 0xFF)); writer.Write((byte)((num >> 32) & 0xFF)); writer.Write((byte)((num >> 40) & 0xFF)); writer.Write((byte)((num >> 48) & 0xFF)); } else { writer.Write(byte.MaxValue); writer.Write((byte)(num & 0xFF)); writer.Write((byte)((num >> 8) & 0xFF)); writer.Write((byte)((num >> 16) & 0xFF)); writer.Write((byte)((num >> 24) & 0xFF)); writer.Write((byte)((num >> 32) & 0xFF)); writer.Write((byte)((num >> 40) & 0xFF)); writer.Write((byte)((num >> 48) & 0xFF)); writer.Write((byte)((num >> 56) & 0xFF)); } } public static short ReadPackedInt16(this BinaryReader reader) { return ReadPackedSigned(reader).@short; } public static ushort ReadPackedUInt16(this BinaryReader reader) { return ReadPacked(reader).@ushort; } public static int ReadPackedInt32(this BinaryReader reader) { return ReadPackedSigned(reader).@int; } public static uint ReadPackedUInt32(this BinaryReader reader) { return ReadPacked(reader).@uint; } public static long ReadPackedInt64(this BinaryReader reader) { return ReadPackedSigned(reader).@long; } public static ulong ReadPackedUInt64(this BinaryReader reader) { return ReadPacked(reader).@ulong; } private static Union ReadPacked(BinaryReader reader) { byte b = reader.ReadByte(); if (b < 241) { return (ulong)b; } byte b2 = reader.ReadByte(); if (b >= 241 && b <= 248) { return (ulong)(240 + 256 * ((long)b - 241L) + b2); } byte b3 = reader.ReadByte(); if (b == 249) { return (ulong)(2288 + 256L * (long)b2 + b3); } byte b4 = reader.ReadByte(); if (b == 250) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16); } byte b5 = reader.ReadByte(); if (b == 251) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24); } byte b6 = reader.ReadByte(); if (b == 252) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32); } byte b7 = reader.ReadByte(); if (b == 253) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40); } byte b8 = reader.ReadByte(); if (b == 254) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40) + ((ulong)b8 << 48); } byte b9 = reader.ReadByte(); if (b == byte.MaxValue) { return b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40) + ((ulong)b8 << 48) + ((ulong)b9 << 56); } throw new IndexOutOfRangeException("ReadPacked() failure: " + b); } private static Union ReadPackedSigned(BinaryReader reader) { byte b = reader.ReadByte(); bool negative = (b & 0x80) == 0; b &= 0x7F; if (b <= 112) { return new Union(b, negative); } byte b2 = reader.ReadByte(); if (b >= 113 && b <= 120) { return new Union((ulong)(112 + 256 * ((long)b - 113L) + b2), negative); } byte b3 = reader.ReadByte(); if (b == 121) { return new Union((ulong)(2160 + 256L * (long)b2 + b3), negative); } byte b4 = reader.ReadByte(); if (b == 122) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16), negative); } byte b5 = reader.ReadByte(); if (b == 123) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24), negative); } byte b6 = reader.ReadByte(); if (b == 124) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32), negative); } byte b7 = reader.ReadByte(); if (b == 125) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40), negative); } byte b8 = reader.ReadByte(); if (b == 126) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40) + ((ulong)b8 << 48), negative); } byte b9 = reader.ReadByte(); if (b == 127) { return new Union(b2 + ((ulong)b3 << 8) + ((ulong)b4 << 16) + ((ulong)b5 << 24) + ((ulong)b6 << 32) + ((ulong)b7 << 40) + ((ulong)b8 << 48) + ((ulong)b9 << 56), negative); } throw new IndexOutOfRangeException("ReadPackedSigned() failure: " + b); } } public static class LanguageConsts { public static readonly string PROPER_SAVE_TITLE_CONTINUE_DESC = "PROPER_SAVE_TITLE_CONTINUE_DESC"; public static readonly string PROPER_SAVE_TITLE_CONTINUE = "PROPER_SAVE_TITLE_CONTINUE"; public static readonly string PROPER_SAVE_TITLE_LOAD = "PROPER_SAVE_TITLE_LOAD"; public static readonly string PROPER_SAVE_CHAT_SAVE = "PROPER_SAVE_CHAT_SAVE"; public static readonly string PROPER_SAVE_QUIT_DIALOG_SAVED = "PROPER_SAVE_QUIT_DIALOG_SAVED"; public static readonly string PROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE = "PROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE"; public static readonly string PROPER_SAVE_QUIT_DIALOG_NOT_SAVED = "PROPER_SAVE_QUIT_DIALOG_NOT_SAVED"; public static readonly string PROPER_SAVE_TOOLTIP_LOAD_TITLE = "PROPER_SAVE_TOOLTIP_LOAD_TITLE"; public static readonly string PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_BODY = "PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_BODY"; public static readonly string PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_CHARACTER = "PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_CHARACTER"; public static readonly string PROPER_SAVE_TOOLTIP_LOAD_CONTENT_MISMATCH = "PROPER_SAVE_TOOLTIP_LOAD_CONTENT_MISMATCH"; public static readonly string PROPER_SAVE_CHAT_SAVE_FAILED = "PROPER_SAVE_CHAT_SAVE_FAILED"; } public static class Loading { private static bool isLoading; public static bool IsLoading { get { return isLoading; } internal set { if (isLoading == value) { return; } isLoading = value; SaveFile currentSave = CurrentSave; Delegate[] array = ((!isLoading) ? Loading.OnLoadingEnded?.GetInvocationList() : Loading.OnLoadingStarted?.GetInvocationList()); if (array == null) { return; } Delegate[] array2 = array; foreach (Delegate obj in array2) { try { ((Action)obj)(currentSave); } catch (Exception ex) { if (ex is MissingMemberException) { ProperSavePlugin.InstanceLogger.LogError((object)("Method " + obj.Method?.DeclaringType.FullName + "." + obj.Method.Name)); } ProperSavePlugin.InstanceLogger.LogError((object)ex); } } } } public static bool FirstRunStage { get; internal set; } public static SaveFile CurrentSave => ProperSavePlugin.CurrentSave?.Body; public static event Action OnLoadingStarted; public static event Action OnLoadingEnded; internal static void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Run.Start += new Manipulator(RunStart); TeamManager.Start += new hook_Start(TeamManagerStart); } internal static void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown Run.Start -= new Manipulator(RunStart); TeamManager.Start -= new hook_Start(TeamManagerStart); } private static void TeamManagerStart(orig_Start orig, TeamManager self) { orig.Invoke(self); if (IsLoading) { CurrentSave.LoadTeam(); IsLoading = false; } } private static void RunStart(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002e: 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) ILCursor val = new ILCursor(il); val.EmitDelegate>((Func)delegate { FirstRunStage = true; if (IsLoading) { ProperSavePlugin.InstanceLogger.LogInfo((object)("Loading save file " + ProperSavePlugin.CurrentSave.FileName)); CurrentSave.LoadRun(); CurrentSave.LoadArtifacts(); CurrentSave.LoadPlayers(); } else { ProperSavePlugin.CurrentSave = null; } return IsLoading; }); val.Emit(OpCodes.Brfalse, val.Next); val.Emit(OpCodes.Ret); } internal static IEnumerator LoadLobby() { if ((Object)(object)PreGameController.instance == (Object)null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"PreGameController instance not found"); yield break; } NetworkManagerSystem singleton = NetworkManagerSystem.singleton; if (singleton != null && singleton.desiredHost.hostingParameters.listen && !PlatformSystems.lobbyManager.ownsLobby) { ProperSavePlugin.InstanceLogger.LogInfo((object)"You must be a lobby leader to load the game"); yield break; } SaveFileMetadata currentLobbySaveMetadata = SaveFileMetadata.GetCurrentLobbySaveMetadata(); if (currentLobbySaveMetadata == null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Save file for current users is not found"); yield break; } UPath? filePath = currentLobbySaveMetadata.FilePath; if (!filePath.HasValue) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Metadata doesn't contain file name for the save file"); yield break; } if (!ProperSavePlugin.SavesFileSystem.FileExists(filePath.Value)) { ProperSavePlugin.InstanceLogger.LogInfo((object)$"File \"{filePath}\" is not found"); yield break; } try { currentLobbySaveMetadata.ReadBody(); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to read save file body"); ProperSavePlugin.InstanceLogger.LogError((object)ex); yield break; } finally { ObjectBuffer.Clear(); } ProperSavePlugin.CurrentSave = currentLobbySaveMetadata; IsLoading = true; if (currentLobbySaveMetadata.Header.ContentHash != ProperSavePlugin.ContentHash) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Loading run but content mismatch detected which may result in errors"); } PreGameController.instance.StartRun(); } [ConCommand(/*Could not decode attribute arguments.*/)] internal static void LoadForce(ConCommandArgs args) { string text = ((ConCommandArgs)(ref args)).TryGetArgString(0); if (string.IsNullOrWhiteSpace(text) || !File.Exists(text)) { Debug.LogError((object)"Incorrect path"); return; } SaveFileMetadata saveFileMetadata = new SaveFileMetadata(); try { saveFileMetadata.ReadForce(text); ProperSavePlugin.CurrentSave = saveFileMetadata; IsLoading = true; } catch (Exception ex) { Debug.LogWarning((object)("Failed to load save file at path \"" + text + "\"")); ProperSavePlugin.InstanceLogger.LogError((object)ex); ResetLoading(); } if (saveFileMetadata.Header.ContentHash != ProperSavePlugin.ContentHash) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Loading run but content mismatch detected which may result in errors"); } if (Object.op_Implicit((Object)(object)PreGameController.instance)) { if (NetworkUser.readOnlyInstancesList.Count > 0) { Debug.LogWarning((object)"Force loading only allowed for 1 player in lobby"); ResetLoading(); } else { PreGameController.instance.StartRun(); } } else { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(LoadForceCoroutine()); } static void ResetLoading() { ProperSavePlugin.CurrentSave = null; IsLoading = false; } } private static IEnumerator LoadForceCoroutine() { Console.instance.SubmitCmd((NetworkUser)null, "host 0", false); yield return (object)new WaitUntil((Func)(() => (Object)(object)PreGameController.instance != (Object)null)); PreGameController.instance.StartRun(); } } internal static class LobbyUI { private static GameObject lobbyButton; private static GameObject lobbySubmenuLegend; private static GameObject lobbyGlyphAndDescription; private static TooltipProvider tooltipProvider; private static GamepadTooltipProvider gamepadTooltipProvider; private static SaveFileMetadata lastFileMetadata; private static TooltipContent lastTooltipContent; public static void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown CharacterSelectController.Awake += new hook_Awake(CharacterSelectControllerAwake); NetworkUser.onPostNetworkUserStart += new NetworkUserGenericDelegate(NetworkUserOnPostNetworkUserStart); NetworkUser.onNetworkUserLost += new NetworkUserGenericDelegate(NetworkUserOnNetworkUserLost); } public static void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown CharacterSelectController.Awake -= new hook_Awake(CharacterSelectControllerAwake); NetworkUser.onPostNetworkUserStart -= new NetworkUserGenericDelegate(NetworkUserOnPostNetworkUserStart); NetworkUser.onNetworkUserLost -= new NetworkUserGenericDelegate(NetworkUserOnNetworkUserLost); } private static void NetworkUserOnNetworkUserLost(NetworkUser networkUser) { UpdateLobbyControls(networkUser); } private static void NetworkUserOnPostNetworkUserStart(NetworkUser networkUser) { UpdateLobbyControls(); } private static void CharacterSelectControllerAwake(orig_Awake orig, CharacterSelectController self) { //IL_0048: 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_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Invalid comparison between Unknown and I4 //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Expected O, but got Unknown //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Expected O, but got Unknown try { GameObject gameObject = ((Component)((Component)self).transform.GetChild(2).GetChild(4).GetChild(0)).gameObject; lobbyButton = Object.Instantiate(gameObject, gameObject.transform.parent); InputSourceFilter[] components = ((Component)self).GetComponents(); foreach (InputSourceFilter val in components) { if ((int)val.requiredInputSource == 0) { Array.Resize(ref val.objectsToFilter, val.objectsToFilter.Length + 1); val.objectsToFilter[val.objectsToFilter.Length - 1] = lobbyButton; break; } } ((Object)lobbyButton).name = "[ProperSave] Load"; tooltipProvider = lobbyButton.AddComponent(); RectTransform component = lobbyButton.GetComponent(); component.anchorMin = new Vector2(1f, 1.5f); component.anchorMax = new Vector2(1f, 1.5f); HGButton component2 = lobbyButton.GetComponent(); component2.hoverToken = LanguageConsts.PROPER_SAVE_TITLE_CONTINUE_DESC; lobbyButton.GetComponent().token = LanguageConsts.PROPER_SAVE_TITLE_LOAD; ((Button)component2).onClick = new ButtonClickedEvent(); ((UnityEvent)((Button)component2).onClick).AddListener(new UnityAction(LoadOnInputEvent)); GameObject gameObject2 = ((Component)((Component)self).transform.GetChild(2).GetChild(4).GetChild(1)).gameObject; lobbySubmenuLegend = Object.Instantiate(gameObject2, gameObject2.transform.parent); components = ((Component)self).GetComponents(); foreach (InputSourceFilter val2 in components) { if ((int)val2.requiredInputSource == 1) { Array.Resize(ref val2.objectsToFilter, val2.objectsToFilter.Length + 1); val2.objectsToFilter[val2.objectsToFilter.Length - 1] = lobbySubmenuLegend; break; } } ((Object)lobbySubmenuLegend).name = "[ProperSave] SubmenuLegend"; UIJuice component3 = lobbySubmenuLegend.GetComponent(); OnEnableEvent component4 = lobbySubmenuLegend.GetComponent(); ((UnityEventBase)component4.action).RemoveAllListeners(); component4.action.AddListener(new UnityAction(component3.TransitionPanFromTop)); component4.action.AddListener(new UnityAction(component3.TransitionAlphaFadeIn)); RectTransform component5 = lobbySubmenuLegend.GetComponent(); component5.anchorMin = new Vector2(1f, 1f); component5.anchorMax = new Vector2(1f, 2f); lobbyGlyphAndDescription = ((Component)lobbySubmenuLegend.transform.GetChild(0)).gameObject; lobbyGlyphAndDescription.SetActive(true); InputBindingDisplayController component6 = ((Component)lobbyGlyphAndDescription.transform.GetChild(0)).GetComponent(); component6.actionName = "UISubmitTertiary"; Transform child = lobbyGlyphAndDescription.transform.GetChild(1); LanguageTextMeshController component7 = ((Component)lobbyGlyphAndDescription.transform.GetChild(2)).GetComponent(); Object.Destroy((Object)(object)((Component)child).gameObject); component7.token = LanguageConsts.PROPER_SAVE_TITLE_LOAD; for (int j = 1; j < lobbySubmenuLegend.transform.childCount; j++) { Object.Destroy((Object)(object)((Component)lobbySubmenuLegend.transform.GetChild(j)).gameObject); } HoldGamepadInputEvent holdGamepadInputEvent = ((Component)self).gameObject.AddComponent(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionName = "UISubmitTertiary"; ((HGGamepadInputEvent)holdGamepadInputEvent).enabledObjectsIfActive = Array.Empty(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionEvent = new UnityEvent(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionEvent.AddListener(new UnityAction(LoadOnInputEvent)); gamepadTooltipProvider = ((Component)component6).gameObject.AddComponent(); gamepadTooltipProvider.inputEvent = holdGamepadInputEvent; UpdateLobbyControls(); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed while adding lobby buttons"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } orig.Invoke(self); } private static void LoadOnInputEvent() { if ((Object)(object)Run.instance != (Object)null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Can't load while run is active"); } else if (Loading.IsLoading) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Already loading"); } else { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(Loading.LoadLobby()); } } private static void UpdateLobbyControls(NetworkUser exceptUser = null) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_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_0092: 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_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) SaveFileMetadata currentLobbySaveMetadata = SaveFileMetadata.GetCurrentLobbySaveMetadata(exceptUser); bool flag = PlatformSystems.lobbyManager.isInLobby == PlatformSystems.lobbyManager.ownsLobby && currentLobbySaveMetadata != null && currentLobbySaveMetadata.FilePath.HasValue && ProperSavePlugin.SavesFileSystem.FileExists(currentLobbySaveMetadata.FilePath.Value); if (currentLobbySaveMetadata != lastFileMetadata) { lastFileMetadata = currentLobbySaveMetadata; try { if (currentLobbySaveMetadata != null) { lastTooltipContent = new TooltipContent { titleToken = LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_TITLE, overrideBodyText = GetSaveDescription(currentLobbySaveMetadata), titleColor = Color.black, disableBodyRichText = false }; } else { lastTooltipContent = default(TooltipContent); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to get information about save file"); ProperSavePlugin.InstanceLogger.LogError((object)ex); flag = false; } } try { if (Object.op_Implicit((Object)(object)lobbyButton)) { HGButton component = lobbyButton.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { ((Selectable)component).interactable = flag; } } if (Object.op_Implicit((Object)(object)tooltipProvider)) { tooltipProvider.SetContent(lastTooltipContent); } } catch { } try { if (Object.op_Implicit((Object)(object)lobbyGlyphAndDescription)) { Color color = (Color)(flag ? Color.white : new Color(0.3f, 0.3f, 0.3f)); ((Graphic)((Component)lobbyGlyphAndDescription.transform.GetChild(0)).GetComponent()).color = color; ((Graphic)((Component)lobbyGlyphAndDescription.transform.GetChild(1)).GetComponent()).color = color; } if (Object.op_Implicit((Object)(object)gamepadTooltipProvider)) { ((TooltipProvider)gamepadTooltipProvider).SetContent(lastTooltipContent); } } catch { } } private static string GetSaveDescription(SaveFileMetadata saveMetadata) { //IL_0050: 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) SaveFileHeader header = saveMetadata.Header; StringBuilder stringBuilder = new StringBuilder(); HeaderUserData[] users = header.Users; foreach (HeaderUserData userData in users) { NetworkUser val = ((IEnumerable)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func)delegate(NetworkUser user) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) NetworkUserId val3 = userData.UserId.Load(); return ((NetworkUserId)(ref val3)).Equals(user.id); }); SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(BodyCatalog.GetBodyPrefab(userData.Body)); stringBuilder.Append(Language.GetStringFormatted(LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_CHARACTER, new object[2] { val?.userName, ((Object)(object)val2 != (Object)null) ? Language.GetString(val2.displayNameToken) : "" })); } SceneDef sceneDefFromSceneName = SceneCatalog.GetSceneDefFromSceneName(header.SceneName); DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(header.Difficulty); int time = header.Time; int stageClearCount = header.StageClearCount; return Language.GetStringFormatted(LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_DESCRIPTION_BODY, new object[6] { stringBuilder.ToString(), Object.op_Implicit((Object)(object)sceneDefFromSceneName) ? Language.GetString(sceneDefFromSceneName.nameToken) : "", (stageClearCount + 1).ToString(), $"{time / 60:00}:{time % 60:00}", (difficultyDef != null) ? Language.GetString(difficultyDef.nameToken) : "", (header.ContentHash != ProperSavePlugin.ContentHash) ? Language.GetString(LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_CONTENT_MISMATCH) : "" }); } } internal class LostNetworkUser : MonoBehaviour { private static readonly Dictionary lostUsers = new Dictionary(); private CharacterMaster master; public uint lunarCoins; public NetworkUserId userID; public BodyIndex bodyIndexPreference; private void Awake() { master = ((Component)this).GetComponent(); lostUsers[master] = this; } private void OnDestroy() { lostUsers.Remove(master); } public static bool TryGetUser(CharacterMaster master, out LostNetworkUser lostUser) { if (!Object.op_Implicit((Object)(object)master) || !lostUsers.TryGetValue(master, out lostUser)) { lostUser = null; return false; } return true; } public static void Subscribe() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown NetworkUser.onNetworkUserLost += new NetworkUserGenericDelegate(OnNetworkUserLost); } public static void Unsubscribe() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown NetworkUser.onNetworkUserLost -= new NetworkUserGenericDelegate(OnNetworkUserLost); } private static void OnNetworkUserLost(NetworkUser networkUser) { //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) //IL_0036: 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) if (Object.op_Implicit((Object)(object)networkUser.master)) { LostNetworkUser lostNetworkUser = ((Component)networkUser.master).gameObject.AddComponent(); lostNetworkUser.lunarCoins = networkUser.lunarCoins; lostNetworkUser.userID = networkUser.id; lostNetworkUser.bodyIndexPreference = networkUser.bodyIndexPreference; } } } internal static class ModCompat { public const string BiggerBazaarGUID = "com.MagnusMagnuson.BiggerBazaar"; public const string ShareSuiteGUID = "com.funkfrog_sipondo.sharesuite"; public static bool IsBBLoaded { get; private set; } public static bool IsSSLoaded { get; private set; } public static bool IsR2APIDifficultyLoaded { get; private set; } private static Dictionary> RegisteredILHooks { get; } = new Dictionary>(); public static void GatherLoadedPlugins() { IsBBLoaded = Chainloader.PluginInfos.ContainsKey("com.MagnusMagnuson.BiggerBazaar"); IsSSLoaded = Chainloader.PluginInfos.ContainsKey("com.funkfrog_sipondo.sharesuite"); IsR2APIDifficultyLoaded = Chainloader.PluginInfos.ContainsKey("com.bepis.r2api.difficulty"); } public static void RegisterHooks() { if (IsBBLoaded) { try { RegisterBBHooks(); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)"Failed to add support for BiggerBazaar"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } } public static void UnregisterHooks() { foreach (KeyValuePair> registeredILHook in RegisteredILHooks) { HookEndpointManager.Unmodify((MethodBase)registeredILHook.Key, (Delegate)registeredILHook.Value); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void RegisterBBHooks() { MethodInfo method = typeof(BiggerBazaar).Assembly.GetType("BiggerBazaar.Bazaar").GetMethod("StartBazaar", BindingFlags.Instance | BindingFlags.Public); Action action = BBHook; HookEndpointManager.Modify((MethodBase)method, (Delegate)action); RegisteredILHooks.Add(method, action); } private static void BBHook(ILContext il) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_0069: 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_0075: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) Type type = typeof(BiggerBazaar).Assembly.GetType("BiggerBazaar.Bazaar"); ILCursor val = new ILCursor(il); int index = val.Index; val.Index = index + 1; Instruction next = val.Next; val.Emit(OpCodes.Call, (MethodBase)typeof(Loading).GetProperty("FirstRunStage").GetGetMethod()); val.Emit(OpCodes.Brfalse, next); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Call, (MethodBase)type.GetMethod("ResetBazaarPlayers")); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Call, (MethodBase)type.GetMethod("CalcDifficultyCoefficient")); } public static void LoadShareSuiteMoney(uint money) { try { if (IsSSLoaded) { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(LoadShareSuiteMoneyInternal(money)); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)ex); } } [MethodImpl(MethodImplOptions.NoInlining)] private static IEnumerator LoadShareSuiteMoneyInternal(uint money) { yield return (object)new WaitUntil((Func)(() => !MoneySharingHooks.MapTransitionActive)); MoneySharingHooks.SharedMoneyValue = (int)money; } public static void ShareSuiteMapTransition() { try { if (IsSSLoaded) { ShareSuiteMapTransitionInternal(); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)ex); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ShareSuiteMapTransitionInternal() { MoneySharingHooks.MapTransitionActive = true; } [MethodImpl(MethodImplOptions.NoInlining)] internal static DifficultyIndex FindR2APIDifficultyIndex(string nameToken) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) foreach (var (result, val3) in DifficultyAPI.difficultyDefinitions) { if (val3.nameToken == nameToken) { return result; } } return (DifficultyIndex)(-1); } } public enum ObjectType : byte { Sbyte, Byte, Short, UShort, Int, UInt, Long, ULong, Float, Double, Boolean, String, Array, Collection, Class, Object, ValueType, KeyValuePair } [BepInPlugin("com.KingEnderBrine.ProperSave", "Proper Save", "3.0.7")] public class ProperSavePlugin : BaseUnityPlugin { public const string GUID = "com.KingEnderBrine.ProperSave"; public const string Name = "Proper Save"; public const string Version = "3.0.7"; private static readonly char[] invalidSubDirectoryCharacters = new char[3] { '\\', '/', '.' }; internal static ProperSavePlugin Instance { get; private set; } internal static ManualLogSource InstanceLogger { get { ProperSavePlugin instance = Instance; if (instance == null) { return null; } return ((BaseUnityPlugin)instance).Logger; } } internal static FileSystem SavesFileSystem { get; private set; } internal static UPath SavesPath { get; private set; } = UPath.op_Implicit("/ProperSave") / UPath.op_Implicit("Saves"); private static string SavesDirectory { get; set; } internal static SaveFileMetadata CurrentSave { get; set; } internal static string ContentHash { get; private set; } internal static ConfigEntry UseCloudStorage { get; private set; } internal static ConfigEntry CloudStorageSubDirectory { get; private set; } internal static ConfigEntry UserSavesDirectory { get; private set; } internal static ConfigEntry Resilient { get; private set; } private void Start() { Instance = this; UseCloudStorage = ((BaseUnityPlugin)this).Config.Bind("Main", "UseCloudStorage", false, "Store files in Steam/EpicGames cloud. Enabling this feature would not preserve current saves and disabling it wouldn't clear the cloud."); CloudStorageSubDirectory = ((BaseUnityPlugin)this).Config.Bind("Main", "CloudStorageSubDirectory", "", "Sub directory name for cloud storage. Changing it allows to use different save files for different mod profiles."); UserSavesDirectory = ((BaseUnityPlugin)this).Config.Bind("Main", "SavesDirectory", "", "Directory where save files will be stored. \"ProperSave\" directory will be created in the directory you have specified. If the directory doesn't exist the default one will be used."); Resilient = ((BaseUnityPlugin)this).Config.Bind("Main", "Resilient", true, "Save file type. True - entries from catalogs will be saved by name instead of index, which should have less issue on mod list change, but has bigger save file size. False - the old way, entries from catalogs are saved by index, which works for non-changing mod list, save file size is much lower."); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate { InitSaveFileSystem(); ProperSave.Old.SaveFileMetadata.MigrateAll(); SaveFileMetadata.PopulateSavesMetadata(); }); ModCompat.GatherLoadedPlugins(); ModCompat.RegisterHooks(); Saving.RegisterHooks(); Loading.RegisterHooks(); LobbyUI.RegisterHooks(); LostNetworkUser.Subscribe(); Language.collectLanguageRootFolders += CollectLanguageRootFolders; ContentManager.onContentPacksAssigned += ContentManagerOnContentPacksAssigned; } private void InitSaveFileSystem() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown if (UseCloudStorage.Value) { SavesFileSystem = RoR2Application.cloudStorage; if (!string.IsNullOrWhiteSpace(CloudStorageSubDirectory.Value)) { if (CloudStorageSubDirectory.Value.IndexOfAny(invalidSubDirectoryCharacters) != -1) { ((BaseUnityPlugin)this).Logger.LogError((object)"Config entry \"CloudStorageSubDirectory\" contains invalid characters. Falling back to default location."); } else { SavesPath /= UPath.op_Implicit(CloudStorageSubDirectory.Value); } } return; } if (!string.IsNullOrWhiteSpace(UserSavesDirectory.Value)) { if (!Directory.Exists(UserSavesDirectory.Value)) { ((BaseUnityPlugin)this).Logger.LogError((object)"SavesDirectory from the config doesn't exists, using Application.persistentDataPath"); SavesDirectory = Application.persistentDataPath; } else { SavesDirectory = UserSavesDirectory.Value; } } else { SavesDirectory = Application.persistentDataPath; } if (string.IsNullOrWhiteSpace(SavesDirectory)) { ((BaseUnityPlugin)this).Logger.LogError((object)"Application.persistentDataPath is empty. Use SavesDirectory config option to specify a folder."); } PhysicalFileSystem val = new PhysicalFileSystem(); SavesFileSystem = (FileSystem)new SubFileSystem((IFileSystem)(object)val, ((FileSystem)val).ConvertPathFromInternal(SavesDirectory), true); } private void Destroy() { Instance = null; ModCompat.UnregisterHooks(); Saving.UnregisterHooks(); Loading.UnregisterHooks(); LobbyUI.UnregisterHooks(); LostNetworkUser.Unsubscribe(); Language.collectLanguageRootFolders -= CollectLanguageRootFolders; ContentManager.onContentPacksAssigned -= ContentManagerOnContentPacksAssigned; } public void CollectLanguageRootFolders(List folders) { folders.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language")); } private void ContentManagerOnContentPacksAssigned(ReadOnlyArray contentPacks) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_0048: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: 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_00f3: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) MD5 mD = MD5.Create(); StringWriter writer = new StringWriter(); try { Enumerator enumerator = contentPacks.GetEnumerator(); try { while (enumerator.MoveNext()) { ReadOnlyContentPack current = enumerator.Current; writer.Write(((ReadOnlyContentPack)(ref current)).identifier); writer.Write(';'); WriteCollection(((ReadOnlyContentPack)(ref current)).artifactDefs, "artifactDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).bodyPrefabs, "bodyPrefabs"); WriteCollection(((ReadOnlyContentPack)(ref current)).equipmentDefs, "equipmentDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).droneDefs, "droneDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).expansionDefs, "expansionDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).gameModePrefabs, "gameModePrefabs"); WriteCollection(((ReadOnlyContentPack)(ref current)).itemDefs, "itemDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).itemTierDefs, "itemTierDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).masterPrefabs, "masterPrefabs"); WriteCollection(((ReadOnlyContentPack)(ref current)).sceneDefs, "sceneDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).skillDefs, "skillDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).skillFamilies, "skillFamilies"); WriteCollection(((ReadOnlyContentPack)(ref current)).survivorDefs, "survivorDefs"); WriteCollection(((ReadOnlyContentPack)(ref current)).unlockableDefs, "unlockableDefs"); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } ContentHash = Convert.ToBase64String(mD.ComputeHash(Encoding.UTF8.GetBytes(writer.ToString()))); } finally { if (writer != null) { ((IDisposable)writer).Dispose(); } } void WriteCollection(ReadOnlyNamedAssetCollection collection, string collectionName) { //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) writer.Write(collectionName); int num = 0; AssetEnumerator enumerator2 = collection.GetEnumerator(); try { while (enumerator2.MoveNext()) { T current2 = enumerator2.Current; writer.Write(num); writer.Write('_'); writer.Write(collection.GetAssetName(current2) ?? string.Empty); writer.Write(';'); num++; } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } } } public class SaveFile { internal static readonly int currentVersion = 2; public ProperSave.SaveData.RunData RunData { get; set; } public ProperSave.SaveData.TeamData TeamData { get; set; } public ProperSave.SaveData.RunArtifactsData RunArtifactsData { get; set; } public ProperSave.SaveData.ArtifactsData ArtifactsData { get; set; } public List PlayersData { get; set; } = new List(); [Obsolete("Use TryGetModdedData() or GetModdedData() instead of directly referencing this field")] public Dictionary ModdedData { get; set; } = new Dictionary(); public Dictionary ModdedObjectsData { get; set; } = new Dictionary(); public static event Action> OnGatherSaveData; internal SaveFile() { } internal void FillFromCurrentRun() { RunData = ProperSave.SaveData.RunData.Create(); TeamData = ProperSave.SaveData.TeamData.Create(); RunArtifactsData = ProperSave.SaveData.RunArtifactsData.Create(); ArtifactsData = ProperSave.SaveData.ArtifactsData.Create(); foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances) { LostNetworkUser lostUser = null; if (Object.op_Implicit((Object)(object)instance.networkUser) || LostNetworkUser.TryGetUser(instance.master, out lostUser)) { PlayersData.Add(ProperSave.SaveData.PlayerData.Create(instance, lostUser)); } } Dictionary dictionary = new Dictionary(); Delegate[] array = SaveFile.OnGatherSaveData?.GetInvocationList(); if (array != null) { Delegate[] array2 = array; foreach (Delegate obj in array2) { try { ((Action>)obj)(dictionary); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)ex); } } } ModdedObjectsData = dictionary; ModdedData = ModdedObjectsData.ToDictionary((KeyValuePair el) => el.Key, (KeyValuePair el) => new ProperSave.Data.ModdedData { ObjectType = el.Value?.GetType().AssemblyQualifiedName, Value = el.Value }); } internal void LoadRun() { try { LegacyResourcesAPI.Load("Prefabs/PositionIndicators/TeleporterChargingPositionIndicator", true); } catch { } RunData.LoadData(); } internal void LoadArtifacts() { RunArtifactsData.LoadData(); ArtifactsData.LoadData(); } internal void LoadTeam() { TeamData.LoadData(); } internal void LoadPlayers() { if (NetworkUser.readOnlyInstancesList.Count == 1) { ProperSave.SaveData.PlayerData playerData = PlayersData.FirstOrDefault(); if (playerData != null) { NetworkUser player = NetworkUser.readOnlyInstancesList.FirstOrDefault(); playerData.LoadPlayer(player); } return; } List list = PlayersData.ToList(); foreach (NetworkUser user in NetworkUser.readOnlyInstancesList) { ProperSave.SaveData.PlayerData playerData2 = list.FirstOrDefault(delegate(ProperSave.SaveData.PlayerData el) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) NetworkUserId val = el.userId.Load(); return ((NetworkUserId)(ref val)).Equals(user.id); }); if (playerData2 != null) { list.Remove(playerData2); playerData2.LoadPlayer(user); } } } public T GetModdedData(string key) { return (T)ModdedObjectsData[key]; } public T TryGetModdedData(string key) { if (ModdedObjectsData.TryGetValue(key, out var value)) { return (T)value; } return default(T); } internal static SaveFile Read(BinaryReader reader) { SaveFile saveFile = new SaveFile(); ReaderContext readerContext = new ReaderContext { Reader = reader }; int num = (readerContext.Version = reader.ReadInt32()); int num3 = num; bool flag = (readerContext.Resilient = reader.ReadBoolean()); long offset = 0L; if (num3 > 1) { offset = reader.ReadInt64(); } long offset2 = reader.ReadInt64(); long position = reader.BaseStream.Position; reader.BaseStream.Seek(offset2, SeekOrigin.Begin); string[] array = (readerContext.SharedStrings = new string[(num3 > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()]); string[] array3 = array; for (int i = 0; i < array3.Length; i++) { array3[i] = reader.ReadString(); } long position2 = reader.BaseStream.Position; if (num3 > 1) { reader.BaseStream.Seek(offset, SeekOrigin.Begin); GenericObjectsHelper.ReadTypesAndObjects(readerContext); } reader.BaseStream.Seek(position, SeekOrigin.Begin); saveFile.ArtifactsData = ProperSave.SaveData.ArtifactsData.Read(readerContext); saveFile.RunData = ProperSave.SaveData.RunData.Read(readerContext); saveFile.RunArtifactsData = ProperSave.SaveData.RunArtifactsData.Read(readerContext); saveFile.TeamData = ProperSave.SaveData.TeamData.Read(readerContext); int num4 = ((num3 > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); for (int j = 0; j < num4; j++) { saveFile.PlayersData.Add(ProperSave.SaveData.PlayerData.Read(readerContext)); } saveFile.ModdedObjectsData = ReadModdedData(readerContext); saveFile.ModdedData = saveFile.ModdedObjectsData.ToDictionary((KeyValuePair el) => el.Key, (KeyValuePair el) => new ProperSave.Data.ModdedData { ObjectType = el.Value?.GetType().AssemblyQualifiedName, Value = el.Value }); reader.BaseStream.Seek(position2, SeekOrigin.Begin); return saveFile; } private static Dictionary ReadModdedData(ReaderContext context) { BinaryReader reader = context.Reader; if (context.Version > 1) { GenericObjectsHelper.ReadObjectsData(context); return context.Objects[0].obj as Dictionary; } return reader.ReadString().FromJson>().ToDictionary((KeyValuePair e) => e.Key, (KeyValuePair e) => e.Value.Value); } internal void Write(BinaryWriter writer, bool resilient) { WriterContext writerContext = new WriterContext { Writer = writer, Resilient = resilient }; writer.Write(currentVersion); writer.Write(resilient); long position = writer.BaseStream.Position; writer.Write(0L); writer.Write(0L); ArtifactsData.Write(writerContext); RunData.Write(writerContext); RunArtifactsData.Write(writerContext); TeamData.Write(writerContext); writer.WritePacked(PlayersData.Count); for (int i = 0; i < PlayersData.Count; i++) { PlayersData[i].Write(writerContext); } GenericObjectsHelper.GetReferenceIndex(ModdedObjectsData, writerContext); GenericObjectsHelper.WriteObjectsData(writerContext); long position2 = writer.BaseStream.Position; GenericObjectsHelper.WriteTypesAndObjects(writerContext); long position3 = writer.BaseStream.Position; writer.WritePacked(writerContext.SharedStrings.Count); for (int j = 0; j < writerContext.SharedStrings.Count; j++) { writer.Write(writerContext.SharedStrings[j]); } writer.BaseStream.Seek(position, SeekOrigin.Begin); writer.Write(position2); writer.Write(position3); writer.BaseStream.Seek(writer.BaseStream.Length, SeekOrigin.Begin); } } public class SaveFileHeader { internal static readonly int currentVersion = 1; public DateTime SaveDate { get; internal set; } public string UserProfileId { get; internal set; } public HeaderUserData[] Users { get; internal set; } public GameModeIndex GameMode { get; internal set; } public string SceneName { get; internal set; } public DifficultyIndex Difficulty { get; internal set; } public int Time { get; internal set; } public int StageClearCount { get; internal set; } public string ContentHash { get; internal set; } public void FillFromCurrentRun() { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) Users = (from el in PlayerCharacterMasterController.instances.Select(HeaderUserData.Create) where el != null select el).ToArray(); UserProfileId = LocalUserManager.readOnlyLocalUsersList[0].userProfile.fileName; GameMode = Run.instance.gameModeIndex; ContentHash = ProperSavePlugin.ContentHash; Difficulty = Run.instance.selectedDifficulty; Scene activeScene = SceneManager.GetActiveScene(); SceneName = ((Scene)(ref activeScene)).name; StageClearCount = Run.instance.stageClearCount; RunStopwatch runStopwatch = Run.instance.runStopwatch; Time = (runStopwatch.isPaused ? ((int)runStopwatch.offsetFromFixedTime) : ((int)(Run.instance.fixedTime + runStopwatch.offsetFromFixedTime))); } internal static SaveFileHeader Read(BinaryReader reader) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) SaveFileHeader saveFileHeader = new SaveFileHeader(); int version = reader.ReadInt32(); bool resilient = reader.ReadBoolean(); long offset = reader.ReadInt64(); long position = reader.BaseStream.Position; reader.BaseStream.Seek(offset, SeekOrigin.Begin); string[] array = new string[reader.ReadInt32()]; for (int i = 0; i < array.Length; i++) { array[i] = reader.ReadString(); } long position2 = reader.BaseStream.Position; reader.BaseStream.Seek(position, SeekOrigin.Begin); ReaderContext context = new ReaderContext { Reader = reader, Resilient = resilient, SharedStrings = array, Version = version }; saveFileHeader.SaveDate = new DateTime(reader.ReadInt64(), DateTimeKind.Utc); saveFileHeader.UserProfileId = reader.ReadString(); saveFileHeader.Users = new HeaderUserData[reader.ReadInt32()]; for (int j = 0; j < saveFileHeader.Users.Length; j++) { saveFileHeader.Users[j] = HeaderUserData.Read(context); } saveFileHeader.GameMode = SharedIndexHelpers.ResolveGameMode(reader.ReadInt32(), context); saveFileHeader.SceneName = reader.ReadString(); saveFileHeader.Difficulty = SharedIndexHelpers.ResolveDifficulty(reader.ReadInt32(), context); saveFileHeader.Time = reader.ReadInt32(); saveFileHeader.StageClearCount = reader.ReadInt32(); saveFileHeader.ContentHash = reader.ReadString(); reader.BaseStream.Seek(position2, SeekOrigin.Begin); return saveFileHeader; } internal void Write(BinaryWriter writer, bool resilient) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) WriterContext writerContext = new WriterContext { Writer = writer, Resilient = resilient }; writer.Write(currentVersion); writer.Write(resilient); long position = writer.BaseStream.Position; writer.Write(0L); writer.Write(DateTime.UtcNow.Ticks); writer.Write(UserProfileId); writer.Write(Users.Length); for (int i = 0; i < Users.Length; i++) { Users[i].Write(writerContext); } writer.Write(SharedIndexHelpers.FromGameMode(GameMode, writerContext)); writer.Write(SceneName); writer.Write(SharedIndexHelpers.FromDifficulty(Difficulty, writerContext)); writer.Write(Time); writer.Write(StageClearCount); writer.Write(ContentHash); long position2 = writer.BaseStream.Position; writer.Write(writerContext.SharedStrings.Count); for (int j = 0; j < writerContext.SharedStrings.Count; j++) { writer.Write(writerContext.SharedStrings[j]); } writer.BaseStream.Seek(position, SeekOrigin.Begin); writer.Write(position2); writer.BaseStream.Seek(writer.BaseStream.Length, SeekOrigin.Begin); } } public class SaveFileMetadata { public string FileName { get; internal set; } public bool ForceLoad { get; internal set; } public SaveFileHeader Header { get; internal set; } public long BodyOffset { get; internal set; } public SaveFile Body { get; internal set; } public UPath? FilePath => string.IsNullOrEmpty(FileName) ? UPath.op_Implicit((string)null) : (ProperSavePlugin.SavesPath / UPath.op_Implicit(FileName + ".bin")); internal static List SavesMetadata { get; } = new List(); internal void FillMetadataForCurrentLobby() { //IL_006a: Unknown result type (might be due to invalid IL or missing references) ForceLoad = false; Header = new SaveFileHeader(); Body = new SaveFile(); BodyOffset = 0L; Header.FillFromCurrentRun(); Body.FillFromCurrentRun(); if (FileName == null) { do { FileName = Guid.NewGuid().ToString(); } while (ProperSavePlugin.SavesFileSystem.FileExists(FilePath.Value)); } } internal static SaveFileMetadata GetCurrentLobbySaveMetadata(NetworkUser exceptUser = null) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 //IL_008a: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 try { List users = NetworkUser.readOnlyInstancesList.Select((NetworkUser el) => el.id).ToList(); if ((Object)(object)exceptUser != (Object)null) { users.Remove(exceptUser.id); } if (users.Count == 0) { return null; } GameModeIndex gameMode = (GameModeIndex)((!Object.op_Implicit((Object)(object)PreGameController.instance)) ? ((!Object.op_Implicit((Object)(object)Run.instance)) ? (-1) : ((int)Run.instance.gameModeIndex)) : ((int)PreGameController.instance.gameModeIndex)); if ((int)gameMode == -1) { return null; } if (users.Count == 1) { string profile = Path.GetFileNameWithoutExtension(LocalUserManager.readOnlyLocalUsersList[0].userProfile.fileName); return SavesMetadata.FirstOrDefault((SaveFileMetadata el) => el.Header.UserProfileId == profile && el.Header.Users.Length == 1 && el.Header.GameMode == gameMode); } return SavesMetadata.FirstOrDefault((SaveFileMetadata el) => el.Header.Users.Length == users.Count && el.Header.GameMode == gameMode && users.DifferenceCount(el.Header.Users.Select((HeaderUserData e) => (e?.UserId?.Load()).GetValueOrDefault())) == 0); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Couldn't get save metadata for current lobby"); ProperSavePlugin.InstanceLogger.LogError((object)ex.ToString()); return null; } } internal static void PopulateSavesMetadata() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if (!ProperSavePlugin.SavesFileSystem.DirectoryExists(ProperSavePlugin.SavesPath)) { ProperSavePlugin.SavesFileSystem.CreateDirectory(ProperSavePlugin.SavesPath); return; } SavesMetadata.Clear(); List list = new List(); foreach (UPath item in FileSystemExtensions.EnumerateFiles((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, ProperSavePlugin.SavesPath, "*.bin")) { try { SaveFileMetadata saveFileMetadata = new SaveFileMetadata(); saveFileMetadata.FileName = UPathExtensions.GetNameWithoutExtension(item); saveFileMetadata.ReadHeader(); list.Add(saveFileMetadata); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Failed to load save file \"" + UPathExtensions.GetName(item) + "\"")); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } SavesMetadata.AddRange(from el in list orderby el.Header.ContentHash == ProperSavePlugin.ContentHash descending, el.Header.SaveDate descending select el); } internal static void Replace(SaveFileMetadata metadata, SaveFileMetadata oldMetadata) { if (oldMetadata != null) { SavesMetadata.Remove(oldMetadata); } SavesMetadata.Insert(0, metadata); } internal void Write(bool resilient) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) using MemoryStream memoryStream = new MemoryStream(); using BinaryWriter writer = new BinaryWriter(memoryStream); Header.Write(writer, resilient); Body.Write(writer, resilient); using Stream destination = ProperSavePlugin.SavesFileSystem.OpenFile(FilePath.Value, FileMode.Create, FileAccess.Write, FileShare.None); memoryStream.Seek(0L, SeekOrigin.Begin); memoryStream.CopyTo(destination); } internal void ReadBody() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Body != null) { return; } using Stream stream = ProperSavePlugin.SavesFileSystem.OpenFile(FilePath.Value, FileMode.Open, FileAccess.Read, FileShare.None); stream.Seek(BodyOffset, SeekOrigin.Begin); using BinaryReader reader = new BinaryReader(stream); Body = SaveFile.Read(reader); } internal void ReadHeader() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Header != null) { return; } using Stream stream = ProperSavePlugin.SavesFileSystem.OpenFile(FilePath.Value, FileMode.Open, FileAccess.Read, FileShare.None); using BinaryReader reader = new BinaryReader(stream); Header = SaveFileHeader.Read(reader); BodyOffset = stream.Position; ForceLoad = false; } internal void ReadForce(string path) { using FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read); using BinaryReader reader = new BinaryReader(fileStream); Header = SaveFileHeader.Read(reader); BodyOffset = fileStream.Position; Body = SaveFile.Read(reader); ForceLoad = true; } } internal static class Saving { internal static ProperSave.SaveData.RunRngData PreStageRng { get; private set; } internal static ProperSave.Data.RngData PreStageInfiniteTowerSafeWardRng { get; private set; } internal static string PreStageSceneName { get; private set; } internal static void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Run.BeginStage += new hook_BeginStage(StageOnStageStartGlobal); Run.onServerGameOver += RunOnServerGameOver; Run.AdvanceStage += new hook_AdvanceStage(RunAdvanceStage); QuitConfirmationHelper.IssueQuitCommand_Action += new Manipulator(IssueQuitCommandIL); } internal static void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Run.BeginStage -= new hook_BeginStage(StageOnStageStartGlobal); Run.onServerGameOver -= RunOnServerGameOver; Run.AdvanceStage -= new hook_AdvanceStage(RunAdvanceStage); QuitConfirmationHelper.IssueQuitCommand_Action -= new Manipulator(IssueQuitCommandIL); } private static void RunAdvanceStage(orig_AdvanceStage orig, Run self, SceneDef sceneDef) { PreStageSceneName = SceneCatalog.GetSceneDefForCurrentScene().cachedName; PreStageRng = ProperSave.SaveData.RunRngData.Create(Run.instance); InfiniteTowerRun val = (InfiniteTowerRun)(object)((self is InfiniteTowerRun) ? self : null); if (val != null) { PreStageInfiniteTowerSafeWardRng = ProperSave.Data.RngData.Create(val.safeWardRng); } orig.Invoke(self, sceneDef); } private static void RunOnServerGameOver(Run run, GameEndingDef ending) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) try { SaveFileMetadata currentSave = ProperSavePlugin.CurrentSave; if (currentSave != null && currentSave.FilePath.HasValue) { if (ProperSavePlugin.SavesFileSystem.FileExists(currentSave.FilePath.Value)) { ProperSavePlugin.SavesFileSystem.DeleteFile(currentSave.FilePath.Value); } ProperSavePlugin.CurrentSave = null; SaveFileMetadata.SavesMetadata.Remove(currentSave); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to delete save file"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } private static void StageOnStageStartGlobal(orig_BeginStage orig, Run self) { //IL_001f: 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_002d: Invalid comparison between Unknown and I4 try { if (!NetworkServer.active) { return; } if (Loading.FirstRunStage) { Loading.FirstRunStage = false; return; } SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene(); if ((int)sceneDefForCurrentScene.sceneType != 0 && (int)sceneDefForCurrentScene.sceneType != 3) { SaveFileMetadata currentSave = ProperSavePlugin.CurrentSave; if (currentSave == null || !currentSave.ForceLoad) { SaveGame(); } } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)ex); } finally { orig.Invoke(self); } } private static void SaveGame() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_0042: 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_0070: Expected O, but got Unknown SaveFileMetadata currentLobbySaveMetadata = SaveFileMetadata.GetCurrentLobbySaveMetadata(); SaveFileMetadata saveFileMetadata = new SaveFileMetadata { FileName = currentLobbySaveMetadata?.FileName }; saveFileMetadata.FillMetadataForCurrentLobby(); try { saveFileMetadata.Write(ProperSavePlugin.Resilient.Value); ProperSavePlugin.CurrentSave = saveFileMetadata; SaveFileMetadata.Replace(saveFileMetadata, currentLobbySaveMetadata); Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = string.Format(Language.GetString(LanguageConsts.PROPER_SAVE_CHAT_SAVE), Language.GetString(SceneCatalog.currentSceneDef.nameToken)) }); } catch (Exception ex) { Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = string.Format(Language.GetString(LanguageConsts.PROPER_SAVE_CHAT_SAVE_FAILED), Language.GetString(SceneCatalog.currentSceneDef.nameToken)) }); ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to save the game"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } finally { ObjectBuffer.Clear(); } } private static void IssueQuitCommandIL(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodReference val2 = default(MethodReference); string text = default(string); val.GotoNext(new Func[4] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdftn(x, ref val2), (Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref val2), (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, ref text) }); val.Emit(OpCodes.Dup); val.EmitDelegate>((Action)AddQuitText); } private static void AddQuitText(SimpleDialogBox simpleDialogBox) { if (NetworkServer.active || NetworkUser.readOnlyInstancesList.Count == NetworkUser.readOnlyLocalPlayersList.Count) { if (ProperSavePlugin.CurrentSave == null) { TextMeshProUGUI descriptionLabel = simpleDialogBox.descriptionLabel; ((TMP_Text)descriptionLabel).text = ((TMP_Text)descriptionLabel).text + Language.GetString(LanguageConsts.PROPER_SAVE_QUIT_DIALOG_NOT_SAVED); return; } if (ProperSavePlugin.CurrentSave.Header.StageClearCount == Run.instance.stageClearCount) { TextMeshProUGUI descriptionLabel2 = simpleDialogBox.descriptionLabel; ((TMP_Text)descriptionLabel2).text = ((TMP_Text)descriptionLabel2).text + Language.GetString(LanguageConsts.PROPER_SAVE_QUIT_DIALOG_SAVED); return; } TextMeshProUGUI descriptionLabel3 = simpleDialogBox.descriptionLabel; string text = ((TMP_Text)descriptionLabel3).text; string pROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE = LanguageConsts.PROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE; object[] array = new string[1] { (Run.instance.stageClearCount - ProperSavePlugin.CurrentSave.Header.StageClearCount).ToString() }; ((TMP_Text)descriptionLabel3).text = text + Language.GetStringFormatted(pROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE, array); } } } } namespace ProperSave.Utils { public static class CatalogHelpers { private static Dictionary DroneNameToIndex { get; set; } public static DifficultyIndex FindDifficultyIndex(string nameToken) { //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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) try { if (ModCompat.IsR2APIDifficultyLoaded) { return ModCompat.FindR2APIDifficultyIndex(nameToken); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogError((object)ex); } for (int i = 0; i < DifficultyCatalog.difficultyDefs.Length; i++) { if (DifficultyCatalog.difficultyDefs[i].nameToken == nameToken) { return (DifficultyIndex)i; } } return (DifficultyIndex)(-1); } public static DroneIndex FindDroneIndex(string name) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (DroneNameToIndex == null) { DroneNameToIndex = DroneCatalog.droneDefs.ToDictionary((DroneDef d) => ((Object)d).name, (DroneDef d) => d.droneIndex); } if (DroneNameToIndex.TryGetValue(name, out var value)) { return value; } return (DroneIndex)(-1); } } internal static class GenericObjectsHelper { public static void ReadTypesAndObjects(ReaderContext context) { BinaryReader reader = context.Reader; TypeData[] array = (context.Types = new TypeData[reader.ReadPackedInt32()]); TypeData[] array3 = array; for (int i = 0; i < array3.Length; i++) { array3[i] = new TypeData { TypeIndex = i }; } for (int j = 0; j < array3.Length; j++) { array3[j].Read(context); } foreach (TypeData typeData in array3) { if (typeData.IsPrimitive) { typeData.Type = GetPrimitiveType(typeData.ObjectType); continue; } string text = typeData.Name.Build(); typeData.Type = Type.GetType(text, throwOnError: false); if ((object)typeData.Type == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Type " + text + " was not found")); } else if (typeData.ObjectType == ObjectType.ValueType || typeData.ObjectType == ObjectType.Object || typeData.ObjectType == ObjectType.Class) { for (int l = 0; l < typeData.Fields.Count; l++) { FieldData fieldData = typeData.Fields[l]; fieldData.Field = typeData.Type.GetField(fieldData.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (fieldData.Field == null) { fieldData.Property = typeData.Type.GetProperty(fieldData.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); if (fieldData.Property != null && !fieldData.Property.CanRead && !fieldData.Property.CanWrite) { fieldData.Property = null; } } } } else if (typeData.ObjectType == ObjectType.Collection) { typeData.AddCollectionElementMethod = typeData.Type.GetInterfaces().FirstOrDefault((Type type3) => type3.IsGenericType && type3.GetGenericTypeDefinition() == typeof(ICollection<>))?.GetMethod("Add"); } else if (typeData.ObjectType == ObjectType.KeyValuePair) { typeData.Constructor = typeData.Type.GetConstructors()[0]; } } (object, TypeData)[] array4 = (context.Objects = new(object, TypeData)[reader.ReadPackedInt32()]); (object, TypeData)[] array6 = array4; for (int num = 0; num < array6.Length; num++) { TypeData typeData2 = array3[reader.ReadPackedInt32()]; Type type = typeData2.Type; if (typeData2.ObjectType == ObjectType.Array) { int[] array7 = new int[typeData2.ArrayRank]; for (int num2 = 0; num2 < typeData2.ArrayRank; num2++) { array7[num2] = reader.ReadPackedInt32(); } Type type2 = typeData2.CollectionArgumentType.Type; if (type != null && type2 != null) { array6[num] = (Array.CreateInstance(type2, array7), typeData2); } else { array6[num] = (null, typeData2); } } else if (type != null) { if (typeData2.IsCollection) { try { array6[num] = (Activator.CreateInstance(type), typeData2); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)ex); array6[num] = (null, typeData2); } } else { array6[num] = (RuntimeHelpers.GetUninitializedObject(type), typeData2); } } else { array6[num] = (null, typeData2); } } } internal static void ReadObjectsData(ReaderContext context) { for (int i = 0; i < context.Objects.Length; i++) { var (obj, type) = context.Objects[i]; ReadObject(obj, type, context); } } private static void ReadObject(object obj, TypeData type, ReaderContext context) { if (type.IsCollection) { ReadCollection(obj, type, context); return; } foreach (FieldData field in type.Fields) { field.SetValue(obj, ReadValue(field.Type.ObjectType, context)); } } private static object ReadValue(ObjectType objectType, ReaderContext context) { BinaryReader reader = context.Reader; if (objectType == ObjectType.Object) { objectType = (ObjectType)reader.ReadByte(); } switch (objectType) { case ObjectType.Sbyte: return reader.ReadSByte(); case ObjectType.Byte: return reader.ReadByte(); case ObjectType.Short: return reader.ReadPackedInt16(); case ObjectType.UShort: return reader.ReadPackedUInt16(); case ObjectType.Int: return reader.ReadPackedInt32(); case ObjectType.UInt: return reader.ReadPackedUInt32(); case ObjectType.Long: return reader.ReadPackedInt64(); case ObjectType.ULong: return reader.ReadPackedUInt64(); case ObjectType.Float: return reader.ReadSingle(); case ObjectType.Double: return reader.ReadDouble(); case ObjectType.Boolean: return reader.ReadBoolean(); case ObjectType.String: return context.SharedStrings.GetSafe(reader.ReadPackedInt32()); case ObjectType.KeyValuePair: { int num3 = reader.ReadPackedInt32(); TypeData typeData2 = context.Types[num3]; object[] array = ObjectBuffer.Buffers[2]; for (int i = 0; i < typeData2.Fields.Count; i++) { FieldData fieldData = typeData2.Fields[i]; array[i] = ReadValue(fieldData.Type.ObjectType, context); } return typeData2.CreateObject(array); } case ObjectType.ValueType: { int num2 = reader.ReadPackedInt32(); TypeData typeData = context.Types[num2]; object obj = (((object)typeData.Type == null) ? null : RuntimeHelpers.GetUninitializedObject(typeData.Type)); { foreach (FieldData field in typeData.Fields) { field.SetValue(obj, ReadValue(field.Type.ObjectType, context)); } return obj; } } case ObjectType.Array: case ObjectType.Collection: case ObjectType.Class: case ObjectType.Object: { int num = reader.ReadPackedInt32(); if (num == -1) { return null; } return context.Objects[num].obj; } default: throw new NotSupportedException(); } } private static void ReadCollection(object obj, TypeData type, ReaderContext context) { BinaryReader reader = context.Reader; switch (type.ObjectType) { case ObjectType.Array: { Array array = obj as Array; int num2 = reader.ReadPackedInt32(); TypeData collectionArgumentType2 = type.CollectionArgumentType; if (array == null) { for (int j = 0; j < num2; j++) { ReadValue(collectionArgumentType2.ObjectType, context); } break; } int arrayRank = type.ArrayRank; int[] array2 = new int[arrayRank]; int[] indices = new int[arrayRank]; for (int k = 0; k < arrayRank; k++) { array2[k] = array.GetLength(k); } if (array2.All((int l) => l > 0)) { do { array.SetValue(ReadValue(collectionArgumentType2.ObjectType, context), indices); } while (IncrementIndices(indices, array2)); } break; } case ObjectType.Collection: { TypeData collectionArgumentType = type.CollectionArgumentType; int num = reader.ReadPackedInt32(); for (int i = 0; i < num; i++) { object value = ReadValue(collectionArgumentType.ObjectType, context); type.AddCollectionElement(obj, value); } break; } } } private static bool IncrementIndices(int[] indices, int[] lengths) { int num = lengths.Length - 1; while (num >= 0) { if (++indices[num] == lengths[num]) { indices[num] = 0; num--; continue; } return true; } return false; } private static Type GetPrimitiveType(ObjectType objectType) { return objectType switch { ObjectType.Sbyte => typeof(sbyte), ObjectType.Byte => typeof(byte), ObjectType.Short => typeof(short), ObjectType.UShort => typeof(ushort), ObjectType.Int => typeof(int), ObjectType.UInt => typeof(uint), ObjectType.Long => typeof(long), ObjectType.ULong => typeof(ulong), ObjectType.Float => typeof(float), ObjectType.Double => typeof(double), ObjectType.Boolean => typeof(bool), ObjectType.String => typeof(string), _ => throw new NotSupportedException(), }; } internal static void WriteObjectsData(WriterContext context) { while (context.ObjectsQueue.Count > 0) { WriteObject(context.ObjectsQueue.Dequeue(), context); } } internal static void WriteTypesAndObjects(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(context.Types.Count); foreach (KeyValuePair item2 in context.Types.OrderBy((KeyValuePair kvp) => kvp.Value.TypeIndex)) { item2.Deconstruct(out var _, out var value); value.Write(context); } writer.WritePacked(context.Objects.Count); foreach (KeyValuePair item3 in context.Objects.OrderBy((KeyValuePair kvp) => kvp.Value.index)) { item3.Deconstruct(out var key2, out var value2); (int, TypeData) tuple = value2; object obj = key2; TypeData item = tuple.Item2; writer.WritePacked(item.TypeIndex); if (item.ObjectType == ObjectType.Array) { for (int num = 0; num < item.ArrayRank; num++) { writer.WritePacked(((Array)obj).GetLength(num)); } } } } private static TypeData GetTypeData(Type type, WriterContext context) { if (!context.Types.TryGetValue(type, out var value)) { Dictionary types = context.Types; TypeData obj = new TypeData { Type = type, Name = TypeName.FromType(type), TypeIndex = context.Types.Count }; value = obj; types[type] = obj; if (type == typeof(sbyte)) { value.ObjectType = ObjectType.Sbyte; } else if (type == typeof(byte)) { value.ObjectType = ObjectType.Byte; } else if (type == typeof(short)) { value.ObjectType = ObjectType.Short; } else if (type == typeof(ushort)) { value.ObjectType = ObjectType.UShort; } else if (type == typeof(int)) { value.ObjectType = ObjectType.Int; } else if (type == typeof(uint)) { value.ObjectType = ObjectType.UInt; } else if (type == typeof(long)) { value.ObjectType = ObjectType.Long; } else if (type == typeof(ulong)) { value.ObjectType = ObjectType.ULong; } else if (type == typeof(float)) { value.ObjectType = ObjectType.Float; } else if (type == typeof(double)) { value.ObjectType = ObjectType.Double; } else if (type == typeof(bool)) { value.ObjectType = ObjectType.Boolean; } else if (type == typeof(string)) { value.ObjectType = ObjectType.String; } else if (type == typeof(object)) { value.ObjectType = ObjectType.Object; value.Fields = new List(); } else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<, >)) { value.ObjectType = ObjectType.KeyValuePair; value.Fields = new List(); PropertyInfo property = type.GetProperty("Key"); value.Fields.Add(new FieldData { Name = property.Name, Property = property, Type = GetTypeData(property.PropertyType, context) }); PropertyInfo property2 = type.GetProperty("Value"); value.Fields.Add(new FieldData { Name = property2.Name, Property = property2, Type = GetTypeData(property2.PropertyType, context) }); } else if (type.IsArray) { TypeData typeData = GetTypeData(type.GetElementType(), context); value.ArrayRank = type.GetArrayRank(); value.CollectionArgumentType = typeData; value.ObjectType = ObjectType.Array; } else { Type type2 = type.GetInterfaces().FirstOrDefault((Type i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(ICollection<>)); if (type2 != null) { TypeData typeData2 = GetTypeData(type2.GetGenericArguments()[0], context); value.CollectionArgumentType = typeData2; value.CollectionCountProperty = type2.GetProperty("Count"); value.ObjectType = ObjectType.Collection; } else { if (type.IsValueType) { value.ObjectType = ObjectType.ValueType; } else { value.ObjectType = ObjectType.Class; } IEnumerable source = from i in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy) where !i.IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true) select i; IEnumerable source2 = from i in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy) where i.CanRead && i.CanWrite && !i.IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true) select i; value.Fields = new List(); value.Fields.AddRange(source.Select((FieldInfo f) => new FieldData { Name = f.Name, Field = f, Type = GetTypeData(f.FieldType, context) })); value.Fields.AddRange(source2.Select((PropertyInfo p) => new FieldData { Name = p.Name, Property = p, Type = GetTypeData(p.PropertyType, context) })); } } } return value; } internal static int GetReferenceIndex(object data, WriterContext context) { if (data == null) { return -1; } if (!context.Objects.TryGetValue(data, out (int, TypeData) value)) { TypeData typeData = GetTypeData(data.GetType(), context); value = (context.Objects[data] = (context.Objects.Count, typeData)); context.ObjectsQueue.Enqueue(data); } return value.Item1; } private static void WriteObject(object obj, WriterContext context) { if (obj == null) { throw new NotSupportedException("Null written as object"); } TypeData typeData = GetTypeData(obj.GetType(), context); if (typeData.IsCollection) { WriteCollection(obj, typeData, context); return; } foreach (FieldData field in typeData.Fields) { WriteValue(field.GetValue(obj), field.Type, context); } } private static void WriteValue(object value, TypeData type, WriterContext context) { BinaryWriter writer = context.Writer; if (type.ObjectType == ObjectType.Object) { type = GetTypeData(value?.GetType() ?? typeof(object), context); writer.Write((byte)type.ObjectType); } switch (type.ObjectType) { case ObjectType.Sbyte: writer.Write((sbyte)value); break; case ObjectType.Byte: writer.Write((byte)value); break; case ObjectType.Short: writer.WritePacked((short)value); break; case ObjectType.UShort: writer.WritePacked((ushort)value); break; case ObjectType.Int: writer.WritePacked((int)value); break; case ObjectType.UInt: writer.WritePacked((uint)value); break; case ObjectType.Long: writer.WritePacked((long)value); break; case ObjectType.ULong: writer.WritePacked((ulong)value); break; case ObjectType.Float: writer.Write((float)value); break; case ObjectType.Double: writer.Write((double)value); break; case ObjectType.Boolean: writer.Write((bool)value); break; case ObjectType.String: writer.WritePacked(context.SharedStrings.AddOrIndexOf((string)value)); break; case ObjectType.ValueType: case ObjectType.KeyValuePair: writer.WritePacked(type.TypeIndex); { foreach (FieldData field in type.Fields) { WriteValue(field.GetValue(value), field.Type, context); } break; } case ObjectType.Array: case ObjectType.Collection: case ObjectType.Class: case ObjectType.Object: writer.WritePacked(GetReferenceIndex(value, context)); break; } } private static void WriteCollection(object value, TypeData type, WriterContext context) { BinaryWriter writer = context.Writer; switch (type.ObjectType) { case ObjectType.Array: { Array array = (Array)value; writer.WritePacked(array.Length); TypeData collectionArgumentType2 = type.CollectionArgumentType; { foreach (object item in array) { WriteValue(item, collectionArgumentType2, context); } break; } } case ObjectType.Collection: { IEnumerable obj = (IEnumerable)value; TypeData collectionArgumentType = type.CollectionArgumentType; writer.WritePacked(type.CollectionCount(value)); { foreach (object item2 in obj) { WriteValue(item2, collectionArgumentType, context); } break; } } } } } public class ObjectBuffer { public static readonly int maxLength; public static readonly object[][] Buffers; static ObjectBuffer() { maxLength = 5; Buffers = new object[maxLength][]; for (int i = 0; i < maxLength; i++) { Buffers[i] = new object[i]; } } public static void Clear() { for (int i = 0; i < Buffers.Length; i++) { object[] array = Buffers[i]; for (int j = 0; j < array.Length; j++) { array[j] = null; } } } } public class ReaderContext { public BinaryReader Reader { get; set; } public string[] SharedStrings { get; set; } public TypeData[] Types { get; set; } public (object obj, TypeData type)[] Objects { get; set; } public bool Resilient { get; set; } public int Version { get; set; } } public static class SharedIndexHelpers { public static int FromDifficulty(DifficultyIndex difficultyIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((int)difficultyIndex == -1) { return -1; } if (!context.Resilient) { return (int)difficultyIndex; } DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(difficultyIndex); if (difficultyDef == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find difficulty with index \"{difficultyIndex}\" in DifficultyCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(difficultyDef.nameToken); } public static DifficultyIndex ResolveDifficulty(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (DifficultyIndex)(-1); } if (!context.Resilient) { return (DifficultyIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); DifficultyIndex val = CatalogHelpers.FindDifficultyIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find difficulty \"" + safe + "\" in DifficultyCatalog")); return (DifficultyIndex)(-1); } return val; } public static int FromRule(int ruleIndex, WriterContext context) { if (!context.Resilient || ruleIndex == -1) { return ruleIndex; } RuleDef ruleDef = RuleCatalog.GetRuleDef(ruleIndex); if (ruleDef == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find rule with index \"{ruleIndex}\" in RuleCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(ruleDef.globalName); } public static int ResolveRule(int sharedIndex, ReaderContext context) { if (sharedIndex == -1) { return -1; } if (!context.Resilient) { return sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); RuleDef val = RuleCatalog.FindRuleDef(safe); if (val == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find rule \"" + safe + "\" in RuleCatalog")); return -1; } return val.globalIndex; } public static int FromArtifact(ArtifactIndex artifactIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)artifactIndex == -1) { return -1; } if (!context.Resilient) { return (int)artifactIndex; } ArtifactDef artifactDef = ArtifactCatalog.GetArtifactDef(artifactIndex); if ((Object)(object)artifactDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find artifact with index \"{artifactIndex}\" in ArtifactCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(artifactDef.cachedName); } public static ArtifactIndex ResolveArtifact(int sharedIndex, ReaderContext context) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (ArtifactIndex)(-1); } if (!context.Resilient) { return (ArtifactIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); ArtifactDef val = ArtifactCatalog.FindArtifactDef(safe); if ((Object)(object)val == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find artifact \"" + safe + "\" in ArtifactCatalog")); return (ArtifactIndex)(-1); } return val.artifactIndex; } public static int FromBody(BodyIndex bodyIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((int)bodyIndex == -1) { return -1; } if (!context.Resilient) { return (int)bodyIndex; } string bodyName = BodyCatalog.GetBodyName(bodyIndex); if (string.IsNullOrEmpty(bodyName)) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find body with index \"{bodyIndex}\" in BodyCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(bodyName); } public static BodyIndex ResolveBody(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (BodyIndex)(-1); } if (!context.Resilient) { return (BodyIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); BodyIndex val = BodyCatalog.FindBodyIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find body \"" + safe + "\" in BodyCatalog")); return (BodyIndex)(-1); } return val; } public static int FromStatField(int statIndex, WriterContext context) { if (!context.Resilient || statIndex == -1) { return statIndex; } StatDef safe = StatDef.allStatDefs.GetSafe(statIndex); if (safe == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find stat with index \"{statIndex}\" in StatDef"); return -1; } return context.SharedStrings.AddOrIndexOf(safe.name); } public static int ResolveStatField(int sharedIndex, ReaderContext context) { if (sharedIndex == -1) { return -1; } if (!context.Resilient) { return sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); StatDef val = StatDef.Find(safe); if (val == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find stat \"" + safe + "\" in StatDef")); return -1; } return val.index; } public static int FromUnlockable(UnlockableIndex unlockableIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)unlockableIndex == -1) { return -1; } if (!context.Resilient) { return (int)unlockableIndex; } UnlockableDef unlockableDef = UnlockableCatalog.GetUnlockableDef(unlockableIndex); if ((Object)(object)unlockableDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find unlockable with index \"{unlockableIndex}\" in UnlockableCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(unlockableDef.cachedName); } public static UnlockableIndex ResolveUnlockable(int sharedIndex, ReaderContext context) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (UnlockableIndex)(-1); } if (!context.Resilient) { return (UnlockableIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); UnlockableDef unlockableDef = UnlockableCatalog.GetUnlockableDef(safe); if ((Object)(object)unlockableDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find unlockable \"" + safe + "\" in UnlockableCatalog")); return (UnlockableIndex)(-1); } return unlockableDef.index; } public static int FromMaster(MasterIndex masterIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (masterIndex == MasterIndex.none) { return -1; } if (!context.Resilient) { return masterIndex.i; } string masterName = MasterCatalog.GetMasterName(masterIndex); if (string.IsNullOrEmpty(masterName)) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find master with index \"{masterIndex}\" in MasterCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(masterName); } public static MasterIndex ResolveMaster(int sharedIndex, ReaderContext context) { //IL_0004: 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_002c: 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_002e: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return MasterIndex.none; } if (!context.Resilient) { return new MasterIndex(sharedIndex); } string safe = context.SharedStrings.GetSafe(sharedIndex); MasterIndex val = MasterCatalog.FindMasterIndex(safe); if (val == MasterIndex.none) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find master \"" + safe + "\" in MasterCatalog")); return MasterIndex.none; } return val; } public static int FromItem(ItemIndex itemIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)itemIndex == -1) { return -1; } if (!context.Resilient) { return (int)itemIndex; } ItemDef itemDef = ItemCatalog.GetItemDef(itemIndex); if ((Object)(object)itemDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find item with index \"{itemIndex}\" in ItemCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(((Object)itemDef).name); } public static ItemIndex ResolveItem(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (ItemIndex)(-1); } if (!context.Resilient) { return (ItemIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); ItemIndex val = ItemCatalog.FindItemIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find item \"" + safe + "\" in ItemCatalog")); return (ItemIndex)(-1); } return val; } public static int FromEquipment(EquipmentIndex equipmentIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)equipmentIndex == -1) { return -1; } if (!context.Resilient) { return (int)equipmentIndex; } EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(equipmentIndex); if ((Object)(object)equipmentDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find equipment with index \"{equipmentIndex}\" in EquipmentCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(((Object)equipmentDef).name); } public static EquipmentIndex ResolveEquipment(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (EquipmentIndex)(-1); } if (!context.Resilient) { return (EquipmentIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); EquipmentIndex val = EquipmentCatalog.FindEquipmentIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find equipment \"" + safe + "\" in EquipmentCatalog")); return (EquipmentIndex)(-1); } return val; } public static int FromDrone(DroneIndex droneIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) if ((int)droneIndex == -1) { return -1; } if (!context.Resilient) { return (int)droneIndex; } DroneDef droneDef = DroneCatalog.GetDroneDef(droneIndex); if ((Object)(object)droneDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find drone with index \"{droneIndex}\" in DroneCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(((Object)droneDef).name); } public static DroneIndex ResolveDrone(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (DroneIndex)(-1); } if (!context.Resilient) { return (DroneIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); DroneIndex val = CatalogHelpers.FindDroneIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find drone \"" + safe + "\" in DroneCatalog")); return (DroneIndex)(-1); } return val; } public static int FromBodySkin(BodyIndex bodyIndex, uint skinIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((int)bodyIndex == -1) { return -1; } if (!context.Resilient) { return (int)skinIndex; } SkinDef bodySkinDef = SkinCatalog.GetBodySkinDef(bodyIndex, (int)skinIndex); if ((Object)(object)bodySkinDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find skin with index \"{skinIndex}\" on body index \"{bodyIndex}\" in SkinCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(((Object)bodySkinDef).name); } public static uint ResolveBodySkin(int sharedIndex, BodyIndex bodyIndex, ReaderContext context) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return 0u; } if (!context.Resilient) { return (uint)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(bodyIndex); for (uint num = 0u; num < bodySkinDefs.Length; num++) { if (((Object)bodySkinDefs[num]).name == safe) { return num; } } ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find skin \"" + safe + "\" in SkinCatalog")); return 0u; } public static int FromGameMode(GameModeIndex gameModeIndex, WriterContext context) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: 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_0010: Expected I4, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((int)gameModeIndex == -1) { return -1; } if (!context.Resilient) { return (int)gameModeIndex; } string gameModeName = GameModeCatalog.GetGameModeName(gameModeIndex); if (string.IsNullOrEmpty(gameModeName)) { ProperSavePlugin.InstanceLogger.LogWarning((object)$"Couldn't find game mode with index \"{gameModeIndex}\" in GameModeCatalog"); return -1; } return context.SharedStrings.AddOrIndexOf(gameModeName); } public static GameModeIndex ResolveGameMode(int sharedIndex, ReaderContext context) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0026: Invalid comparison between Unknown and I4 //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return (GameModeIndex)(-1); } if (!context.Resilient) { return (GameModeIndex)sharedIndex; } string safe = context.SharedStrings.GetSafe(sharedIndex); GameModeIndex val = GameModeCatalog.FindGameModeIndex(safe); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find game mode \"" + safe + "\" in GameModeCatalog")); return (GameModeIndex)(-1); } return val; } public static int FromString(string str, WriterContext context) { return context.SharedStrings.AddOrIndexOf(str); } public static string ResolveString(int sharedIndex, ReaderContext context) { return context.SharedStrings.GetSafe(sharedIndex); } } public class WriterContext { public BinaryWriter Writer { get; set; } public List SharedStrings { get; } = new List(); public Dictionary Types { get; } = new Dictionary(); public Dictionary Objects { get; } = new Dictionary(); public Queue ObjectsQueue { get; } = new Queue(); public bool Resilient { get; set; } } } namespace ProperSave.SaveData { public class ArtifactsData { public ProperSave.SaveData.Artifacts.EnigmaData enigmaData; public ProperSave.SaveData.Artifacts.PrestigeData prestigeData; internal static ArtifactsData Create() { return new ArtifactsData { enigmaData = ProperSave.SaveData.Artifacts.EnigmaData.Create(), prestigeData = ProperSave.SaveData.Artifacts.PrestigeData.Create() }; } internal void LoadData() { enigmaData.LoadData(); prestigeData.LoadData(); } internal static ArtifactsData Read(ReaderContext context) { return new ArtifactsData { enigmaData = ProperSave.SaveData.Artifacts.EnigmaData.Read(context), prestigeData = ProperSave.SaveData.Artifacts.PrestigeData.Read(context) }; } internal void Write(WriterContext context) { enigmaData.Write(context); prestigeData.Write(context); } } public class MinionData { public MasterIndex masterIndex; public ProperSave.Data.CharacterMasterData master; public ProperSave.Data.DevotedLemurianData devotedLemurianData; public ProperSave.Data.DroneRepairData droneRepairData; internal static MinionData Create(CharacterMaster master) { //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) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) MinionData minionData = new MinionData(); minionData.masterIndex = master.masterIndex; minionData.master = ProperSave.Data.CharacterMasterData.Create(master); DevotedLemurianController controller = default(DevotedLemurianController); if (((Component)master).TryGetComponent(ref controller)) { minionData.devotedLemurianData = ProperSave.Data.DevotedLemurianData.Create(controller); } DroneRepairMaster val = default(DroneRepairMaster); if (((Component)master).TryGetComponent(ref val)) { minionData.droneRepairData = ProperSave.Data.DroneRepairData.Create(val); minionData.master.bodyIndex = val.defaultBodyIndex; } return minionData; } internal void LoadMinion(CharacterMaster playerMaster) { //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) if (!(masterIndex == MasterIndex.none)) { SceneDirector.onPostPopulateSceneServer += SpawnMinion; } void SpawnMinion(SceneDirector obj) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) SceneDirector.onPostPopulateSceneServer -= SpawnMinion; GameObject obj2 = Object.Instantiate(MasterCatalog.GetMasterPrefab(masterIndex)); CharacterMaster component = obj2.GetComponent(); component.teamIndex = (TeamIndex)1; master.LoadMaster(component, delayedInventory: true); CharacterMaster val = playerMaster; if ((Object)(object)val.minionOwnership.ownerMaster != (Object)null) { val = val.minionOwnership.ownerMaster; } component.minionOwnership.SetOwner(val); obj2.GetComponent().ownerMaster = playerMaster; obj2.GetComponent().leader.gameObject = ((Component)playerMaster).gameObject; if (devotedLemurianData != null) { DevotedLemurianController component2 = ((Component)component).GetComponent(); devotedLemurianData.LoadData(component2); component2._lemurianMaster = component; component2._devotionInventoryController = ProperSave.Data.CharacterMasterData.GetDevotionInventoryController(playerMaster); } if (droneRepairData != null) { DroneRepairMaster component3 = ((Component)component).GetComponent(); droneRepairData.LoadData(component3); } NetworkServer.Spawn(obj2); } } internal static MinionData Read(ReaderContext context) { //IL_0028: 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) MinionData minionData = new MinionData(); BinaryReader reader = context.Reader; int version = context.Version; minionData.masterIndex = SharedIndexHelpers.ResolveMaster((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); minionData.master = ProperSave.Data.CharacterMasterData.Read(context); if (reader.ReadBoolean()) { minionData.devotedLemurianData = ProperSave.Data.DevotedLemurianData.Read(context); } if (reader.ReadBoolean()) { minionData.droneRepairData = ProperSave.Data.DroneRepairData.Read(context); } return minionData; } internal void Write(WriterContext context) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromMaster(masterIndex, context)); master.Write(context); writer.Write(devotedLemurianData != null); devotedLemurianData?.Write(context); writer.Write(droneRepairData != null); droneRepairData?.Write(context); } } public class PlayerData { public ProperSave.Data.UserIDData userId; public List statsFields = new List(); public List statsUnlockables = new List(); public uint lunarCoins; public float lunarCoinChanceMultiplier; public BodyIndex preferredBodyIndex; public ProperSave.Data.CharacterMasterData master; internal static PlayerData Create(PlayerCharacterMasterController player, LostNetworkUser lostNetworkUser = null) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0035: 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_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) PlayerData playerData = new PlayerData(); NetworkUser networkUser = player.networkUser; if ((Object)(object)lostNetworkUser != (Object)null) { playerData.userId = ProperSave.Data.UserIDData.Create(lostNetworkUser.userID); playerData.lunarCoins = lostNetworkUser.lunarCoins; playerData.preferredBodyIndex = lostNetworkUser.bodyIndexPreference; } else { playerData.userId = ProperSave.Data.UserIDData.Create(networkUser.id); playerData.lunarCoins = networkUser.lunarCoins; playerData.preferredBodyIndex = networkUser.bodyIndexPreference; } playerData.lunarCoinChanceMultiplier = player.lunarCoinChanceMultiplier; playerData.master = ProperSave.Data.CharacterMasterData.Create(player.master); StatSheet currentStats = ((Component)player).GetComponent().currentStats; for (int i = 0; i < currentStats.fields.Length; i++) { StatField val = currentStats.fields[i]; if (!((StatField)(ref val)).IsDefault()) { playerData.statsFields.Add(new StatFieldData { index = val.statDef.index, value = ((StatField)(ref val)).ulongValue }); } } for (int j = 0; j < currentStats.unlockables.Length; j++) { UnlockableIndex unlockableIndex = currentStats.GetUnlockableIndex(j); playerData.statsUnlockables.Add(unlockableIndex); } return playerData; } internal void LoadPlayer(NetworkUser player) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Invalid comparison between Unknown and I4 //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((int)preferredBodyIndex != -1) { player.SetBodyPreference(preferredBodyIndex); } master.LoadMaster(player.master, delayedInventory: false); player.masterController.lunarCoinChanceMultiplier = lunarCoinChanceMultiplier; StatSheet currentStats = ((Component)player.masterController).GetComponent().currentStats; foreach (StatFieldData statsField in statsFields) { int index = statsField.index; if (index != -1) { ((StatField)(ref currentStats.fields[index])).ulongValue = statsField.value; } } foreach (UnlockableIndex statsUnlockable in statsUnlockables) { if ((int)statsUnlockable != -1) { currentStats.AddUnlockable(statsUnlockable); } } } internal static PlayerData Read(ReaderContext context) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) PlayerData playerData = new PlayerData(); BinaryReader reader = context.Reader; int version = context.Version; playerData.userId = ProperSave.Data.UserIDData.Read(context); int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); playerData.statsFields = new List(num); for (int i = 0; i < num; i++) { playerData.statsFields.Add(StatFieldData.Read(context)); } int num2 = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); playerData.statsUnlockables = new List(num2); for (int j = 0; j < num2; j++) { playerData.statsUnlockables.Add(SharedIndexHelpers.ResolveUnlockable((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context)); } playerData.lunarCoins = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); playerData.lunarCoinChanceMultiplier = reader.ReadSingle(); playerData.preferredBodyIndex = SharedIndexHelpers.ResolveBody((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); playerData.master = ProperSave.Data.CharacterMasterData.Read(context); return playerData; } internal void Write(WriterContext context) { //IL_0069: 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) BinaryWriter writer = context.Writer; userId.Write(context); writer.WritePacked(statsFields.Count); for (int i = 0; i < statsFields.Count; i++) { statsFields[i].Write(context); } writer.WritePacked(statsUnlockables.Count); for (int j = 0; j < statsUnlockables.Count; j++) { writer.WritePacked(SharedIndexHelpers.FromUnlockable(statsUnlockables[j], context)); } writer.WritePacked(lunarCoins); writer.Write(lunarCoinChanceMultiplier); writer.WritePacked(SharedIndexHelpers.FromBody(preferredBodyIndex, context)); master.Write(context); } } public class RunArtifactsData { public List artifacts = new List(); internal unsafe static RunArtifactsData Create() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) RunArtifactsData runArtifactsData = new RunArtifactsData(); ArtifactTrialMissionController val = Object.FindObjectOfType(); ArtifactIndex val2 = (ArtifactIndex)(val?.currentArtifactIndex ?? (-1)); RunEnabledArtifacts enumerator = RunArtifactManager.enabledArtifactsEnumerable.GetEnumerator(); try { while (((RunEnabledArtifacts)(ref enumerator)).MoveNext()) { ArtifactDef current = ((RunEnabledArtifacts)(ref enumerator)).Current; if (val2 != current.artifactIndex || val.artifactWasEnabled) { runArtifactsData.artifacts.Add(current.artifactIndex); } } return runArtifactsData; } finally { ((IDisposable)(*(RunEnabledArtifacts*)(&enumerator))/*cast due to .constrained prefix*/).Dispose(); } } internal void LoadData() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < ArtifactCatalog.artifactCount; i++) { ArtifactDef artifactDef = ArtifactCatalog.GetArtifactDef((ArtifactIndex)i); RunArtifactManager.instance.SetArtifactEnabled(artifactDef, false); } foreach (ArtifactIndex artifact in artifacts) { if ((int)artifact != -1) { RunArtifactManager.instance.SetArtifactEnabled(ArtifactCatalog.GetArtifactDef(artifact), true); } } } internal static RunArtifactsData Read(ReaderContext context) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) RunArtifactsData runArtifactsData = new RunArtifactsData(); BinaryReader reader = context.Reader; int version = context.Version; int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runArtifactsData.artifacts = new List(num); for (int i = 0; i < num; i++) { runArtifactsData.artifacts.Add(SharedIndexHelpers.ResolveArtifact((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context)); } return runArtifactsData; } internal void Write(WriterContext context) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(artifacts.Count); for (int i = 0; i < artifacts.Count; i++) { writer.WritePacked(SharedIndexHelpers.FromArtifact(artifacts[i], context)); } } } public class RunData { public ulong seed; public DifficultyIndex difficultyIndex; public float fixedTime; public float time; public bool isPaused; public float offsetFromFixedTime; public int stageClearCount; public int stageClearCountAtLoopStart; public int loopClearCount; public string sceneName; public string nextSceneName; public string previousSceneName; public int prestigeArtifactMountainValue; public ProperSave.Data.ItemMaskData itemMask; public ProperSave.Data.EquipmentMaskData equipmentMask; public ProperSave.Data.DroneMaskData droneMask; public int shopPortalCount; public string[] eventFlags; public RunRngData runRng; public ArtifactIndex trialArtifactIndex; public ProperSave.Data.RuleBookData ruleBook; public ProperSave.SaveData.Runs.ITypedRunData typedRunData; private static readonly FieldInfo onRunStartGlobalDelegate = typeof(Run).GetField("onRunStartGlobal", BindingFlags.Static | BindingFlags.NonPublic); internal static RunData Create() { //IL_001a: 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_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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_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_0129: Unknown result type (might be due to invalid IL or missing references) RunData runData = new RunData(); Run instance = Run.instance; runData.seed = instance.seed; runData.difficultyIndex = instance.selectedDifficulty; RunStopwatch runStopwatch = instance.runStopwatch; runData.isPaused = runStopwatch.isPaused; runData.offsetFromFixedTime = runStopwatch.offsetFromFixedTime; runData.fixedTime = instance.fixedTime; runData.time = instance.time; runData.stageClearCount = instance.stageClearCount; runData.stageClearCountAtLoopStart = instance.stageClearCountAtLoopStart; runData.loopClearCount = instance._loopClearCount; Scene activeScene = SceneManager.GetActiveScene(); runData.sceneName = ((Scene)(ref activeScene)).name; runData.nextSceneName = instance.nextStageScene.cachedName; runData.previousSceneName = Saving.PreStageSceneName; runData.shopPortalCount = instance.shopPortalCount; runData.prestigeArtifactMountainValue = instance.prestiegeArtifactMountainValue; runData.itemMask = ProperSave.Data.ItemMaskData.Create(instance.availableItems); runData.equipmentMask = ProperSave.Data.EquipmentMaskData.Create(instance.availableEquipment); runData.droneMask = ProperSave.Data.DroneMaskData.Create(instance.availableDrones); runData.runRng = Saving.PreStageRng; runData.eventFlags = instance.eventFlags.ToArray(); runData.trialArtifactIndex = (ArtifactIndex)(Object.FindObjectOfType()?.currentArtifactIndex ?? (-1)); runData.ruleBook = ProperSave.Data.RuleBookData.Create(instance.ruleBook); if (instance is InfiniteTowerRun) { runData.typedRunData = ProperSave.SaveData.Runs.InfiniteTowerTypedRunData.Create(); } return runData; } internal void LoadData() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Unknown result type (might be due to invalid IL or missing references) ModCompat.ShareSuiteMapTransition(); if ((int)trialArtifactIndex != -1) { ArtifactTrialMissionController.trialArtifact = ArtifactCatalog.GetArtifactDef(trialArtifactIndex); } Run instance = Run.instance; instance.SetRuleBook(ruleBook.Load()); instance.OnRuleBookUpdated(instance.networkRuleBookComponent); instance.seed = seed; if ((int)difficultyIndex == -1) { instance.selectedDifficulty = (DifficultyIndex)0; } else { instance.selectedDifficulty = difficultyIndex; } instance.shopPortalCount = shopPortalCount; instance.prestiegeArtifactMountainValue = prestigeArtifactMountainValue; runRng.LoadData(instance); typedRunData?.Load(); instance.allowNewParticipants = true; Object.DontDestroyOnLoad((Object)(object)((Component)instance).gameObject); ReadOnlyCollection readOnlyInstancesList = NetworkUser.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { instance.OnUserAdded(readOnlyInstancesList[i]); } instance.allowNewParticipants = false; instance.stageClearCount = stageClearCount; instance.stageClearCountAtLoopStart = stageClearCountAtLoopStart; instance._loopClearCount = loopClearCount; instance.RecalculateDifficultyCoefficent(); instance.nextStageScene = SceneCatalog.GetSceneDefFromSceneName(nextSceneName); if (stageClearCount == stageClearCountAtLoopStart) { instance.OnLoopBeginServer(SceneCatalog.GetSceneDefFromSceneName(previousSceneName)); } instance.GenerateStageRNG(); NetworkManager.singleton.ServerChangeScene(sceneName); itemMask.LoadData(instance.availableItems); equipmentMask.LoadData(instance.availableEquipment); droneMask.LoadData(instance.availableDrones); instance.BuildUnlockAvailability(); instance.BuildDropTable(); string[] array = eventFlags; foreach (string eventFlag in array) { instance.SetEventFlag(eventFlag); } instance.isRunning = true; if (onRunStartGlobalDelegate.GetValue(null) is Action action) { action(instance); } instance.fixedTime = fixedTime; instance.time = time; instance.runStopwatch = new RunStopwatch { offsetFromFixedTime = offsetFromFixedTime, isPaused = isPaused }; } internal static RunData Read(ReaderContext context) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) RunData runData = new RunData(); BinaryReader reader = context.Reader; int version = context.Version; runData.seed = reader.ReadUInt64(); runData.difficultyIndex = SharedIndexHelpers.ResolveDifficulty((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); runData.fixedTime = reader.ReadSingle(); runData.time = reader.ReadSingle(); runData.isPaused = reader.ReadBoolean(); runData.offsetFromFixedTime = reader.ReadSingle(); runData.stageClearCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runData.stageClearCountAtLoopStart = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runData.loopClearCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runData.sceneName = reader.ReadString(); runData.nextSceneName = reader.ReadString(); runData.previousSceneName = reader.ReadString(); runData.prestigeArtifactMountainValue = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runData.itemMask = ProperSave.Data.ItemMaskData.Read(context); runData.equipmentMask = ProperSave.Data.EquipmentMaskData.Read(context); runData.droneMask = ProperSave.Data.DroneMaskData.Read(context); runData.shopPortalCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); runData.eventFlags = new string[(version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()]; for (int i = 0; i < runData.eventFlags.Length; i++) { runData.eventFlags[i] = reader.ReadString(); } runData.runRng = RunRngData.Read(context); runData.trialArtifactIndex = SharedIndexHelpers.ResolveArtifact((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); runData.ruleBook = ProperSave.Data.RuleBookData.Read(context); string text = reader.ReadString(); if (text != "") { Type type = Type.GetType(text, throwOnError: false); runData.typedRunData = (ProperSave.SaveData.Runs.ITypedRunData)type.GetMethod("Read", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Invoke(null, new object[1] { context }); } return runData; } internal void Write(WriterContext context) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.Write(seed); writer.WritePacked(SharedIndexHelpers.FromDifficulty(difficultyIndex, context)); writer.Write(fixedTime); writer.Write(time); writer.Write(isPaused); writer.Write(offsetFromFixedTime); writer.WritePacked(stageClearCount); writer.WritePacked(stageClearCountAtLoopStart); writer.WritePacked(loopClearCount); writer.Write(sceneName); writer.Write(nextSceneName); writer.Write(previousSceneName); writer.WritePacked(prestigeArtifactMountainValue); itemMask.Write(context); equipmentMask.Write(context); droneMask.Write(context); writer.WritePacked(shopPortalCount); writer.WritePacked(eventFlags.Length); for (int i = 0; i < eventFlags.Length; i++) { writer.Write(eventFlags[i]); } runRng.Write(context); writer.WritePacked(SharedIndexHelpers.FromArtifact(trialArtifactIndex, context)); ruleBook.Write(context); writer.Write(typedRunData?.GetType().AssemblyQualifiedName ?? ""); if (typedRunData != null) { typedRunData.Write(context); } } } public class RunRngData { public ProperSave.Data.RngData runRng; public ProperSave.Data.RngData nextStageRng; public ProperSave.Data.RngData stageRngGenerator; public ProperSave.Data.RngData loopRngGenerator; internal static RunRngData Create(Run run) { return new RunRngData { runRng = ProperSave.Data.RngData.Create(run.runRNG), nextStageRng = ProperSave.Data.RngData.Create(run.nextStageRng), stageRngGenerator = ProperSave.Data.RngData.Create(run.stageRngGenerator), loopRngGenerator = ProperSave.Data.RngData.Create(run.loopRngGenerator) }; } internal void LoadData(Run run) { runRng.LoadDataOut(out run.runRNG); nextStageRng.LoadDataOut(out run.nextStageRng); stageRngGenerator.LoadDataOut(out run.stageRngGenerator); loopRngGenerator.LoadDataOut(out run.loopRngGenerator); } internal static RunRngData Read(ReaderContext context) { return new RunRngData { runRng = ProperSave.Data.RngData.Read(context), nextStageRng = ProperSave.Data.RngData.Read(context), stageRngGenerator = ProperSave.Data.RngData.Read(context), loopRngGenerator = ProperSave.Data.RngData.Read(context) }; } internal void Write(WriterContext context) { runRng.Write(context); nextStageRng.Write(context); stageRngGenerator.Write(context); loopRngGenerator.Write(context); } } public class TeamData { public long experience; internal static TeamData Create() { return new TeamData { experience = (long)TeamManager.instance.GetTeamExperience((TeamIndex)1) }; } internal void LoadData() { TeamManager.instance.GiveTeamExperience((TeamIndex)1, (ulong)experience); } internal static TeamData Read(ReaderContext context) { BinaryReader reader = context.Reader; int version = context.Version; return new TeamData { experience = ((version > 1) ? reader.ReadPackedInt64() : reader.ReadInt64()) }; } internal void Write(WriterContext context) { context.Writer.WritePacked(experience); } } } namespace ProperSave.SaveData.Runs { public class InfiniteTowerTypedRunData : ITypedRunData { public int waveIndex; public ProperSave.Data.RngData waveRng; public ProperSave.Data.RngData enemyItemRng; public ProperSave.Data.RngData safeWardRng; public int enemyItemPatternIndex; public ProperSave.Data.InventoryData enemyInventory; internal static InfiniteTowerTypedRunData Create() { Run instance = Run.instance; InfiniteTowerRun val = (InfiniteTowerRun)(object)((instance is InfiniteTowerRun) ? instance : null); return new InfiniteTowerTypedRunData { waveIndex = val.waveIndex, waveRng = ProperSave.Data.RngData.Create(val.waveRng), enemyItemRng = ProperSave.Data.RngData.Create(val.enemyItemRng), safeWardRng = Saving.PreStageInfiniteTowerSafeWardRng, enemyItemPatternIndex = val.enemyItemPatternIndex, enemyInventory = ProperSave.Data.InventoryData.Create(val.enemyInventory) }; } void ITypedRunData.Load() { Run instance = Run.instance; InfiniteTowerRun val = (InfiniteTowerRun)(object)((instance is InfiniteTowerRun) ? instance : null); val._waveIndex = waveIndex; waveRng.LoadDataRef(ref val.waveRng); enemyItemRng.LoadDataRef(ref val.enemyItemRng); safeWardRng.LoadDataRef(ref val.safeWardRng); val.enemyItemPatternIndex = enemyItemPatternIndex; enemyInventory.LoadInventory(val.enemyInventory); } internal static InfiniteTowerTypedRunData Read(ReaderContext context) { InfiniteTowerTypedRunData infiniteTowerTypedRunData = new InfiniteTowerTypedRunData(); BinaryReader reader = context.Reader; int version = context.Version; infiniteTowerTypedRunData.waveIndex = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); infiniteTowerTypedRunData.waveRng = ProperSave.Data.RngData.Read(context); infiniteTowerTypedRunData.enemyItemRng = ProperSave.Data.RngData.Read(context); infiniteTowerTypedRunData.safeWardRng = ProperSave.Data.RngData.Read(context); infiniteTowerTypedRunData.enemyItemPatternIndex = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); infiniteTowerTypedRunData.enemyInventory = ProperSave.Data.InventoryData.Read(context); return infiniteTowerTypedRunData; } void ITypedRunData.Write(WriterContext context) { Write(context); } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(waveIndex); waveRng.Write(context); enemyItemRng.Write(context); safeWardRng.Write(context); writer.WritePacked(enemyItemPatternIndex); enemyInventory.Write(context); } } public interface ITypedRunData { void Load(); void Write(WriterContext context); } } namespace ProperSave.SaveData.Artifacts { public class EnigmaData { public ProperSave.Data.RngData serverInitialEquipmentRng; public ProperSave.Data.RngData serverActivationEquipmentRng; internal static EnigmaData Create() { return new EnigmaData { serverInitialEquipmentRng = ProperSave.Data.RngData.Create(EnigmaArtifactManager.serverInitialEquipmentRng), serverActivationEquipmentRng = ProperSave.Data.RngData.Create(EnigmaArtifactManager.serverActivationEquipmentRng) }; } internal void LoadData() { serverInitialEquipmentRng.LoadDataRef(ref EnigmaArtifactManager.serverInitialEquipmentRng); serverActivationEquipmentRng.LoadDataRef(ref EnigmaArtifactManager.serverActivationEquipmentRng); } internal static EnigmaData Read(ReaderContext context) { return new EnigmaData { serverInitialEquipmentRng = ProperSave.Data.RngData.Read(context), serverActivationEquipmentRng = ProperSave.Data.RngData.Read(context) }; } internal void Write(WriterContext context) { serverInitialEquipmentRng.Write(context); serverActivationEquipmentRng.Write(context); } } public class PrestigeData { public int mountainShrineCount; internal static PrestigeData Create() { PrestigeData prestigeData = new PrestigeData(); PrestigeBulwarkManager val = default(PrestigeBulwarkManager); if (((Component)Run.instance).TryGetComponent(ref val)) { prestigeData.mountainShrineCount = val.mountainShrineCount; } return prestigeData; } internal void LoadData() { PrestigeBulwarkManager val = default(PrestigeBulwarkManager); if (((Component)Run.instance).TryGetComponent(ref val)) { val.mountainShrineCount = mountainShrineCount; } } internal static PrestigeData Read(ReaderContext context) { PrestigeData prestigeData = new PrestigeData(); BinaryReader reader = context.Reader; int version = context.Version; prestigeData.mountainShrineCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); return prestigeData; } internal void Write(WriterContext context) { context.Writer.WritePacked(mountainShrineCount); } } } namespace ProperSave.TinyJson { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] internal sealed class DiscoverObjectTypeAttribute : Attribute { private string MemberName { get; } public DiscoverObjectTypeAttribute(string memberName) { MemberName = memberName; } public Type GetObjectType(object instance) { if (string.IsNullOrEmpty(MemberName) || instance == null) { return null; } MemberInfo memberInfo = instance?.GetType()?.GetMember(MemberName)?.FirstOrDefault(); string typeName; if (!(memberInfo is FieldInfo fieldInfo)) { if (!(memberInfo is PropertyInfo propertyInfo)) { throw new NotSupportedException(); } typeName = propertyInfo.GetValue(instance) as string; } else { typeName = fieldInfo.GetValue(instance) as string; } return Type.GetType(typeName, throwOnError: false); } } } namespace ProperSave.Old { public class SaveFile { [DataMember(Name = "r")] public ProperSave.Old.SaveData.RunData RunData { get; set; } [DataMember(Name = "t")] public ProperSave.Old.SaveData.TeamData TeamData { get; set; } [DataMember(Name = "ra")] public ProperSave.Old.SaveData.RunArtifactsData RunArtifactsData { get; set; } [DataMember(Name = "a")] public ProperSave.Old.SaveData.ArtifactsData ArtifactsData { get; set; } [DataMember(Name = "p")] public List PlayersData { get; set; } [DataMember(Name = "md")] public Dictionary ModdedData { get; set; } [DataMember(Name = "ch")] public string ContentHash { get; set; } [IgnoreDataMember] public SaveFileMetadata SaveFileMeta { get; set; } internal ProperSave.SaveFile Migrate() { return new ProperSave.SaveFile { ArtifactsData = ArtifactsData.Migrate(), TeamData = TeamData.Migrate(), RunArtifactsData = RunArtifactsData.Migrate(), ModdedData = ModdedData.ToDictionary((KeyValuePair kvp) => kvp.Key, (KeyValuePair kvp) => kvp.Value.Migrate()), ModdedObjectsData = ModdedData.ToDictionary((KeyValuePair kvp) => kvp.Key, (KeyValuePair kvp) => kvp.Value.Migrate().Value), PlayersData = PlayersData.Select((ProperSave.Old.SaveData.PlayerData d) => d.Migrate()).ToList(), RunData = RunData.Migrate() }; } } public class SaveFileMetadata { [DataMember(Name = "fn")] public string FileName { get; set; } [DataMember(Name = "upi")] public string UserProfileId { get; set; } [DataMember(Name = "si")] public ProperSave.Old.Data.UserIDData[] UserIds { get; set; } [DataMember(Name = "gm")] public GameModeIndex GameMode { get; set; } [IgnoreDataMember] public UPath? FilePath => string.IsNullOrEmpty(FileName) ? UPath.op_Implicit((string)null) : (ProperSavePlugin.SavesPath / UPath.op_Implicit(FileName + ".json")); internal static void MigrateAll() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_023c: 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_011f: 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_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) if (!ProperSavePlugin.SavesFileSystem.DirectoryExists(ProperSavePlugin.SavesPath)) { return; } UPath val = ProperSavePlugin.SavesPath / UPath.op_Implicit("SavesMetadata.json"); if (!ProperSavePlugin.SavesFileSystem.FileExists(val)) { return; } ProperSavePlugin.InstanceLogger.LogInfo((object)"Found Saves.Metadata.json, migrating to new format"); try { SaveFileMetadata[] array = FileSystemExtensions.ReadAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, val).FromJson(); foreach (SaveFileMetadata saveFileMetadata in array) { if (!ProperSavePlugin.SavesFileSystem.FileExists(saveFileMetadata.FilePath.Value)) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Save file " + saveFileMetadata.FileName + " doesn't exist and will not be migrated")); continue; } try { SaveFile saveFile = FileSystemExtensions.ReadAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, saveFileMetadata.FilePath.Value).Replace("ProperSave.SaveData", "ProperSave.Old.SaveData").Replace("ProperSave.Data", "ProperSave.Old.Data") .FromJson(); ProperSave.SaveFile body = saveFile.Migrate(); ProperSave.SaveFileMetadata saveFileMetadata2 = new ProperSave.SaveFileMetadata(); saveFileMetadata2.FileName = saveFileMetadata.FileName; saveFileMetadata2.Header = new SaveFileHeader { ContentHash = saveFile.ContentHash, Difficulty = (DifficultyIndex)saveFile.RunData.difficulty, GameMode = saveFileMetadata.GameMode, SaveDate = ProperSavePlugin.SavesFileSystem.GetLastWriteTime(saveFileMetadata.FilePath.Value), SceneName = saveFile.RunData.sceneName, StageClearCount = saveFile.RunData.stageClearCount, Time = (saveFile.RunData.isPaused ? ((int)saveFile.RunData.offsetFromFixedTime) : ((int)(saveFile.RunData.fixedTime + saveFile.RunData.offsetFromFixedTime))), UserProfileId = saveFileMetadata.UserProfileId, Users = saveFile.PlayersData.Select((ProperSave.Old.SaveData.PlayerData d) => new HeaderUserData { Body = BodyCatalog.FindBodyIndex(d.master.bodyName), UserId = d.userId.Migrate() }).ToArray() }; saveFileMetadata2.Body = body; saveFileMetadata2.Write(resilient: false); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Failed to migrate " + saveFileMetadata.FileName)); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } foreach (UPath item in FileSystemExtensions.EnumerateFiles((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, ProperSavePlugin.SavesPath, "*.json")) { ProperSavePlugin.SavesFileSystem.DeleteFile(item); } } catch (Exception ex2) { ProperSavePlugin.InstanceLogger.LogWarning((object)"An error occurred during migration"); ProperSavePlugin.InstanceLogger.LogError((object)ex2); } } } } namespace ProperSave.Old.SaveData { public class ArtifactsData { [DataMember(Name = "ed")] public ProperSave.Old.SaveData.Artifacts.EnigmaData enigmaData; [DataMember(Name = "pd")] public ProperSave.Old.SaveData.Artifacts.PrestigeData prestigeData; internal ProperSave.SaveData.ArtifactsData Migrate() { return new ProperSave.SaveData.ArtifactsData { enigmaData = enigmaData?.Migrate(), prestigeData = prestigeData?.Migrate() }; } } public class MinionData { [DataMember(Name = "mi")] public int masterIndex; [DataMember(Name = "m")] public ProperSave.Old.Data.CharacterMasterData master; [DataMember(Name = "dld")] public ProperSave.Old.Data.DevotedLemurianData devotedLemurianData; [DataMember(Name = "drd")] public ProperSave.Old.Data.DroneRepairData droneRepairData; internal ProperSave.SaveData.MinionData Migrate() { //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) return new ProperSave.SaveData.MinionData { devotedLemurianData = devotedLemurianData?.Migrate(), droneRepairData = droneRepairData?.Migrate(), master = master.Migrate(), masterIndex = (MasterIndex)masterIndex }; } } public class PlayerData { [DataMember(Name = "si")] public ProperSave.Old.Data.UserIDData userId; [DataMember(Name = "sf")] public string[] statsFields; [DataMember(Name = "su")] public int[] statsUnlockables; [DataMember(Name = "lc")] public uint lunarCoins; [DataMember(Name = "lccm")] public float lunarCoinChanceMultiplier; [DataMember(Name = "pbi")] public int preferredBodyIndex; [DataMember(Name = "m")] public ProperSave.Old.Data.CharacterMasterData master; internal ProperSave.SaveData.PlayerData Migrate() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.SaveData.PlayerData { userId = userId.Migrate(), master = master.Migrate(), lunarCoinChanceMultiplier = lunarCoinChanceMultiplier, lunarCoins = lunarCoins, preferredBodyIndex = (BodyIndex)preferredBodyIndex, statsFields = (from d in statsFields.Select(delegate(string f, int i) { //IL_0002: 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_001b: Unknown result type (might be due to invalid IL or missing references) StatField val = new StatField { statDef = StatDef.allStatDefs[i] }; ((StatField)(ref val)).SetFromString(f); return ((StatField)(ref val)).IsDefault() ? null : new StatFieldData { index = i, value = ((StatField)(ref val)).ulongValue }; }) where d != null select d).ToList(), statsUnlockables = statsUnlockables.Select((int u) => (UnlockableIndex)u).ToList() }; } } public class RunArtifactsData { [DataMember(Name = "a")] public bool[] artifacts; internal ProperSave.SaveData.RunArtifactsData Migrate() { return new ProperSave.SaveData.RunArtifactsData { artifacts = (from a in artifacts.Select((bool a, int i) => a ? ((ArtifactIndex)i) : ((ArtifactIndex)(-1))) where (int)a != -1 select a).ToList() }; } } public class RunData { [DataMember(Name = "s")] public ulong seed; [DataMember(Name = "d")] public int difficulty; [DataMember(Name = "ft")] public float fixedTime; [DataMember(Name = "t")] public float time; [DataMember(Name = "ip")] public bool isPaused; [DataMember(Name = "offt")] public float offsetFromFixedTime; [DataMember(Name = "scc")] public int stageClearCount; [DataMember(Name = "sccls")] public int stageClearCountAtLoopStart; [DataMember(Name = "lcc")] public int loopClearCount; [DataMember(Name = "sn")] public string sceneName; [DataMember(Name = "nsn")] public string nextSceneName; [DataMember(Name = "psn")] public string previousSceneName; [DataMember(Name = "pamv")] public int prestigeArtifactMountainValue; [DataMember(Name = "im")] public ProperSave.Old.Data.ItemMaskData itemMask; [DataMember(Name = "em")] public ProperSave.Old.Data.EquipmentMaskData equipmentMask; [DataMember(Name = "dm")] public ProperSave.Old.Data.DroneMaskData droneMask; [DataMember(Name = "spc")] public int shopPortalCount; [DataMember(Name = "ef")] public string[] eventFlags; [DataMember(Name = "rr")] public RunRngData runRng; [DataMember(Name = "ta")] public int trialArtifact; [DataMember(Name = "rb")] public ProperSave.Old.Data.RuleBookData ruleBook; [DataMember(Name = "trdt")] public string typeRunDataType; [DataMember(Name = "trd")] [DiscoverObjectType("typeRunDataType")] public ProperSave.Old.SaveData.Runs.ITypedRunData typedRunData; internal ProperSave.SaveData.RunData Migrate() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.SaveData.RunData { difficultyIndex = (DifficultyIndex)difficulty, droneMask = droneMask.Migrate(), equipmentMask = equipmentMask.Migrate(), eventFlags = eventFlags, fixedTime = fixedTime, isPaused = isPaused, itemMask = itemMask.Migrate(), loopClearCount = loopClearCount, nextSceneName = nextSceneName, offsetFromFixedTime = offsetFromFixedTime, prestigeArtifactMountainValue = prestigeArtifactMountainValue, previousSceneName = previousSceneName, ruleBook = ruleBook.Migrate(), runRng = runRng.Migrate(), sceneName = sceneName, seed = seed, shopPortalCount = shopPortalCount, stageClearCount = stageClearCount, stageClearCountAtLoopStart = stageClearCountAtLoopStart, time = time, trialArtifactIndex = (ArtifactIndex)trialArtifact, typedRunData = typedRunData?.Migrate() }; } } public class RunRngData { [DataMember(Name = "rr")] public ProperSave.Old.Data.RngData runRng; [DataMember(Name = "nsr")] public ProperSave.Old.Data.RngData nextStageRng; [DataMember(Name = "srg")] public ProperSave.Old.Data.RngData stageRngGenerator; [DataMember(Name = "lrg")] public ProperSave.Old.Data.RngData loopRngGenerator; internal ProperSave.SaveData.RunRngData Migrate() { return new ProperSave.SaveData.RunRngData { runRng = runRng.Migrate(), nextStageRng = nextStageRng.Migrate(), stageRngGenerator = stageRngGenerator.Migrate(), loopRngGenerator = loopRngGenerator.Migrate() }; } } public class TeamData { [DataMember(Name = "e")] public long expirience; internal ProperSave.SaveData.TeamData Migrate() { return new ProperSave.SaveData.TeamData { experience = expirience }; } } } namespace ProperSave.Old.SaveData.Runs { public class InfiniteTowerTypedRunData : ITypedRunData { [DataMember(Name = "wi")] public int waveIndex; [DataMember(Name = "wr")] public ProperSave.Old.Data.RngData waveRng; [DataMember(Name = "eir")] public ProperSave.Old.Data.RngData enemyItemRng; [DataMember(Name = "swr")] public ProperSave.Old.Data.RngData safeWardRng; [DataMember(Name = "eipi")] public int enemyItemPatternIndex; [DataMember(Name = "ei")] public ProperSave.Old.Data.InventoryData enemyInventory; public ProperSave.SaveData.Runs.ITypedRunData Migrate() { return new ProperSave.SaveData.Runs.InfiniteTowerTypedRunData { enemyInventory = enemyInventory.Migrate(), enemyItemPatternIndex = enemyItemPatternIndex, enemyItemRng = enemyItemRng.Migrate(), safeWardRng = safeWardRng.Migrate(), waveIndex = waveIndex, waveRng = waveRng.Migrate() }; } } public interface ITypedRunData { ProperSave.SaveData.Runs.ITypedRunData Migrate(); } } namespace ProperSave.Old.SaveData.Artifacts { public class EnigmaData { [DataMember(Name = "sier")] public ProperSave.Old.Data.RngData serverInitialEquipmentRng; [DataMember(Name = "saer")] public ProperSave.Old.Data.RngData serverActivationEquipmentRng; internal ProperSave.SaveData.Artifacts.EnigmaData Migrate() { return new ProperSave.SaveData.Artifacts.EnigmaData { serverInitialEquipmentRng = serverInitialEquipmentRng.Migrate(), serverActivationEquipmentRng = serverActivationEquipmentRng.Migrate() }; } } public class PrestigeData { [DataMember(Name = "msc")] public int mountainShrineCount; internal ProperSave.SaveData.Artifacts.PrestigeData Migrate() { return new ProperSave.SaveData.Artifacts.PrestigeData { mountainShrineCount = mountainShrineCount }; } } } namespace ProperSave.Old.Data { public class CharacterMasterData { [DataMember(Name = "bn")] public string bodyName; [DataMember(Name = "m")] public uint money; [DataMember(Name = "i")] public InventoryData inventory; [DataMember(Name = "l")] public LoadoutData loadout; [DataMember(Name = "vc")] public uint voidCoins; [DataMember(Name = "cvrng")] public RngData cloverVoidRng; [DataMember(Name = "di")] public InventoryData devotionInventory; [DataMember(Name = "be")] public ulong beadExpirience; [DataMember(Name = "nobsg")] public int numberOfBeadStatsGained; [DataMember(Name = "obl")] public uint oldBeadLevel; [DataMember(Name = "nbl")] public uint newBeadLevel; [DataMember(Name = "bxpnfcl")] public ulong beadXPNeededForCurrentLevel; [DataMember(Name = "tfu")] public uint trackedFreeUnlocks; [DataMember(Name = "tmc")] public int trackedMissileCount; [DataMember(Name = "ebmmr")] public uint extraBossMissileMoneyRemainder; [DataMember(Name = "ms")] public ProperSave.Old.SaveData.MinionData[] minions; internal ProperSave.Data.CharacterMasterData Migrate() { //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) return new ProperSave.Data.CharacterMasterData { beadExperience = beadExpirience, beadXPNeededForCurrentLevel = beadXPNeededForCurrentLevel, bodyIndex = BodyCatalog.FindBodyIndex(bodyName), cloverVoidRng = cloverVoidRng?.Migrate(), devotionInventory = devotionInventory?.Migrate(), extraBossMissileMoneyRemainder = extraBossMissileMoneyRemainder, inventory = inventory.Migrate(), loadout = loadout.Migrate(), minions = minions.Select((ProperSave.Old.SaveData.MinionData m) => m.Migrate()).ToList(), money = money, newBeadLevel = newBeadLevel, numberOfBeadStatsGained = numberOfBeadStatsGained, oldBeadLevel = oldBeadLevel, trackedFreeUnlocks = trackedFreeUnlocks, trackedMissileCount = trackedMissileCount, voidCoins = voidCoins }; } } public class DevotedLemurianData { [DataMember(Name = "ii")] public int itemIndex; [DataMember(Name = "dev")] public int devotedEvolutionLevel; internal ProperSave.Data.DevotedLemurianData Migrate() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.Data.DevotedLemurianData { devotedEvolutionLevel = devotedEvolutionLevel, itemIndex = (ItemIndex)itemIndex }; } } public class DroneMaskData { public bool[] array; internal ProperSave.Data.DroneMaskData Migrate() { return new ProperSave.Data.DroneMaskData { enabledItems = (from i in array.Select((bool e, int i) => e ? ((DroneIndex)i) : ((DroneIndex)(-1))) where (int)i != -1 select i).ToList() }; } } public class DroneRepairData { [DataMember(Name = "rbsl")] public string requestedBySlotName; internal ProperSave.Data.DroneRepairData Migrate() { return new ProperSave.Data.DroneRepairData { requestedBySlotName = requestedBySlotName }; } } public class EquipmentData { [DataMember(Name = "i")] public int index; [DataMember(Name = "c")] public byte charges; [DataMember(Name = "cft")] public float chargeFinishTime; internal ProperSave.Data.EquipmentData Migrate() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.Data.EquipmentData { chargeFinishTime = chargeFinishTime, charges = charges, index = (EquipmentIndex)index }; } } public class EquipmentMaskData { public bool[] array; internal ProperSave.Data.EquipmentMaskData Migrate() { return new ProperSave.Data.EquipmentMaskData { enabledItems = (from i in array.Select((bool e, int i) => e ? ((EquipmentIndex)i) : ((EquipmentIndex)(-1))) where (int)i != -1 select i).ToList() }; } } public class InventoryData { [DataMember(Name = "ib")] public uint infusionBonus; [DataMember(Name = "ed")] public bool equipmentDisabled; [DataMember(Name = "bah")] public float beadAppliedHealth; [DataMember(Name = "bas")] public float beadAppliedShield; [DataMember(Name = "bar")] public float beadAppliedRegen; [DataMember(Name = "bad")] public float beadAppliedDamage; [DataMember(Name = "i")] public List items; [DataMember(Name = "tsdd")] public float tempStorageDecayDuration; [DataMember(Name = "tsidd")] public float tempStorageInvDecayDuration; [DataMember(Name = "e")] public EquipmentData[][] equipments; [DataMember(Name = "aesl")] public byte activeEquipmentSlot; [DataMember(Name = "aese")] public byte[] activeEquipmentSet; [DataMember(Name = "leec")] public int lastExtraEquipmentCount; internal ProperSave.Data.InventoryData Migrate() { return new ProperSave.Data.InventoryData { activeEquipmentSet = activeEquipmentSet, activeEquipmentSlot = activeEquipmentSlot, beadAppliedDamage = beadAppliedDamage, beadAppliedHealth = beadAppliedHealth, beadAppliedShield = beadAppliedShield, beadAppliedRegen = beadAppliedRegen, equipmentDisabled = equipmentDisabled, equipments = equipments.Select((EquipmentData[] e) => e.Select((EquipmentData equipmentData) => equipmentData.Migrate()).ToArray()).ToArray(), infusionBonus = infusionBonus, items = items.Select((ItemData i) => i.Migrate()).ToList(), lastExtraEquipmentCount = lastExtraEquipmentCount, tempStorageDecayDuration = tempStorageDecayDuration, tempStorageInvDecayDuration = tempStorageInvDecayDuration }; } } public class ItemData { [DataMember(Name = "i")] public int itemIndex; [DataMember(Name = "c")] public int count; [DataMember(Name = "cc")] public int channeledCount; [DataMember(Name = "tc")] public int tempCount; [DataMember(Name = "tft")] public float tempFixedTime; internal ProperSave.Data.ItemData Migrate() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.Data.ItemData { channeledCount = channeledCount, tempCount = tempCount, tempFixedTime = tempFixedTime, count = count, itemIndex = (ItemIndex)itemIndex }; } } public class ItemMaskData { public bool[] array; internal ProperSave.Data.ItemMaskData Migrate() { return new ProperSave.Data.ItemMaskData { enabledItems = (from i in array.Select((bool e, int i) => e ? ((ItemIndex)i) : ((ItemIndex)(-1))) where (int)i != -1 select i).ToList() }; } } public class LoadoutBodyData { [DataMember(Name = "bi")] public int bodyIndex; [DataMember(Name = "sp")] public uint skinPreference; [DataMember(Name = "sps")] public uint[] skillPreferences; internal ProperSave.Data.LoadoutBodyData Migrate() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new ProperSave.Data.LoadoutBodyData { bodyIndex = (BodyIndex)bodyIndex, skinPreference = skinPreference, skillPreferences = skillPreferences }; } } public class LoadoutData { [DataMember(Name = "ml")] public LoadoutBodyData[] modifiedLoadouts; internal ProperSave.Data.LoadoutData Migrate() { return new ProperSave.Data.LoadoutData { modifiedLoadouts = modifiedLoadouts.Select((LoadoutBodyData l) => l.Migrate()).ToList() }; } } public class ModdedData { [DataMember(Name = "ot")] public string ObjectType { get; set; } [DataMember(Name = "v")] [DiscoverObjectType("ObjectType")] public object Value { get; set; } internal ProperSave.Data.ModdedData Migrate() { return new ProperSave.Data.ModdedData { ObjectType = ObjectType, Value = Value }; } } public class RngData { [DataMember(Name = "s0")] public ulong state0; [DataMember(Name = "s1")] public ulong state1; internal ProperSave.Data.RngData Migrate() { return new ProperSave.Data.RngData { state0 = state0, state1 = state1 }; } } public class RuleBookData { [DataMember(Name = "rv")] public byte[] ruleValues; internal ProperSave.Data.RuleBookData Migrate() { return new ProperSave.Data.RuleBookData { ruleValues = ruleValues.Select((byte v, int i) => new RuleValueData { index = i, value = v }).ToList() }; } } public class UserIDData { [DataMember(Name = "s")] public ulong steam; [DataMember(Name = "e")] public string egs; [DataMember(Name = "si")] public byte subId; internal ProperSave.Data.UserIDData Migrate() { return new ProperSave.Data.UserIDData { steam = steam, subId = subId, egs = egs }; } } } namespace ProperSave.Data { public class CharacterMasterData { public BodyIndex bodyIndex; public uint money; public InventoryData inventory; public LoadoutData loadout; public uint voidCoins; public RngData cloverVoidRng; public InventoryData devotionInventory; public ulong beadExperience; public int numberOfBeadStatsGained; public uint oldBeadLevel; public uint newBeadLevel; public ulong beadXPNeededForCurrentLevel; public uint trackedFreeUnlocks; public int trackedMissileCount; public uint extraBossMissileMoneyRemainder; public List minions = new List(); internal static CharacterMasterData Create(CharacterMaster master) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) CharacterMasterData characterMasterData = new CharacterMasterData(); characterMasterData.money = master.money; characterMasterData.voidCoins = master.voidCoins; characterMasterData.beadExperience = master.beadExperience; characterMasterData.numberOfBeadStatsGained = master.numberOfBeadStatsGained_XPGainNerf; characterMasterData.oldBeadLevel = master.oldBeadLevel; characterMasterData.newBeadLevel = master.newBeadLevel; characterMasterData.beadXPNeededForCurrentLevel = master.beadXPNeededForCurrentLevel; characterMasterData.trackedFreeUnlocks = master.trackedFreeUnlocks; characterMasterData.trackedMissileCount = master.trackedMissileCount; characterMasterData.extraBossMissileMoneyRemainder = master.ExtraBossMissileMoneyRemainder; characterMasterData.inventory = InventoryData.Create(master.inventory); characterMasterData.loadout = LoadoutData.Create(master.loadout); characterMasterData.bodyIndex = master.bodyPrefab.GetComponent().bodyIndex; if (master.cloverVoidRng != null) { characterMasterData.cloverVoidRng = RngData.Create(master.cloverVoidRng); } if (RunArtifactManager.instance.IsArtifactEnabled(Artifacts.Devotion)) { DevotionInventoryController devotionInventoryController = GetDevotionInventoryController(master); if (Object.op_Implicit((Object)(object)devotionInventoryController)) { characterMasterData.devotionInventory = InventoryData.Create(devotionInventoryController._devotionMinionInventory); } } foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { CharacterMaster ownerMaster = readOnlyInstances.minionOwnership.ownerMaster; if ((Object)(object)ownerMaster != (Object)null && ((NetworkBehaviour)ownerMaster).netId == ((NetworkBehaviour)master).netId) { characterMasterData.minions.Add(ProperSave.SaveData.MinionData.Create(readOnlyInstances)); } } return characterMasterData; } internal void LoadMaster(CharacterMaster master, bool delayedInventory) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_005d: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (devotionInventory != null) { DevotionInventoryController val = CreateDevotionInventoryController(master); devotionInventory.LoadInventory(val._devotionMinionInventory); } foreach (ProperSave.SaveData.MinionData minion in minions) { minion.LoadMinion(master); } BodyIndex val2 = bodyIndex; if ((int)val2 != -1) { GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(val2); if (Object.op_Implicit((Object)(object)bodyPrefab)) { master.bodyPrefab = bodyPrefab; } } ModCompat.LoadShareSuiteMoney(money); master.money = money; master.voidCoins = voidCoins; master.beadExperience = beadExperience; master.numberOfBeadStatsGained_XPGainNerf = numberOfBeadStatsGained; master.oldBeadLevel = oldBeadLevel; master.newBeadLevel = newBeadLevel; master.beadXPNeededForCurrentLevel = beadXPNeededForCurrentLevel; master.trackedFreeUnlocks = trackedFreeUnlocks; master.trackedMissileCount = trackedMissileCount; master.ExtraBossMissileMoneyRemainder = extraBossMissileMoneyRemainder; loadout.LoadData(master.loadout); cloverVoidRng?.LoadDataOut(out master.cloverVoidRng); if (delayedInventory) { ((MonoBehaviour)master).StartCoroutine(LoadInventoryCoroutine(master, inventory)); } else { inventory.LoadInventory(master.inventory); } } internal static DevotionInventoryController GetDevotionInventoryController(CharacterMaster master) { foreach (DevotionInventoryController instance in DevotionInventoryController.InstanceList) { if ((Object)(object)instance.SummonerMaster == (Object)(object)master) { return instance; } } return null; } private static DevotionInventoryController CreateDevotionInventoryController(CharacterMaster master) { //IL_0005: 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) GameObject val = Object.Instantiate(Addressables.LoadAssetAsync((object)"RoR2/CU8/LemurianEgg/DevotionMinionInventory.prefab").WaitForCompletion()); DevotionInventoryController component = val.GetComponent(); ((Component)component).GetComponent().teamIndex = (TeamIndex)1; component._summonerMaster = master; NetworkServer.Spawn(val); return component; } private static IEnumerator LoadInventoryCoroutine(CharacterMaster minionMaster, InventoryData inventory) { yield return (object)new WaitForEndOfFrame(); yield return (object)new WaitForEndOfFrame(); inventory.LoadInventory(minionMaster.inventory); } internal static CharacterMasterData Read(ReaderContext context) { //IL_0028: 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) CharacterMasterData characterMasterData = new CharacterMasterData(); BinaryReader reader = context.Reader; int version = context.Version; characterMasterData.bodyIndex = SharedIndexHelpers.ResolveBody((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); characterMasterData.money = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); characterMasterData.inventory = InventoryData.Read(context); characterMasterData.loadout = LoadoutData.Read(context); characterMasterData.voidCoins = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); if (reader.ReadBoolean()) { characterMasterData.cloverVoidRng = RngData.Read(context); } if (reader.ReadBoolean()) { characterMasterData.devotionInventory = InventoryData.Read(context); } characterMasterData.beadExperience = ((version > 1) ? reader.ReadPackedUInt64() : reader.ReadUInt64()); characterMasterData.numberOfBeadStatsGained = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); characterMasterData.oldBeadLevel = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); characterMasterData.newBeadLevel = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); characterMasterData.beadXPNeededForCurrentLevel = ((version > 1) ? reader.ReadPackedUInt64() : reader.ReadUInt64()); characterMasterData.trackedFreeUnlocks = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); characterMasterData.trackedMissileCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); characterMasterData.extraBossMissileMoneyRemainder = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); characterMasterData.minions = new List(num); for (int i = 0; i < num; i++) { characterMasterData.minions.Add(ProperSave.SaveData.MinionData.Read(context)); } return characterMasterData; } internal void Write(WriterContext context) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromBody(bodyIndex, context)); writer.WritePacked(money); inventory.Write(context); loadout.Write(context); writer.WritePacked(voidCoins); writer.Write(cloverVoidRng != null); cloverVoidRng?.Write(context); writer.Write(devotionInventory != null); devotionInventory?.Write(context); writer.WritePacked(beadExperience); writer.WritePacked(numberOfBeadStatsGained); writer.WritePacked(oldBeadLevel); writer.WritePacked(newBeadLevel); writer.WritePacked(beadXPNeededForCurrentLevel); writer.WritePacked(trackedFreeUnlocks); writer.WritePacked(trackedMissileCount); writer.WritePacked(extraBossMissileMoneyRemainder); writer.WritePacked(minions.Count); for (int i = 0; i < minions.Count; i++) { minions[i].Write(context); } } } public class DevotedLemurianData { public ItemIndex itemIndex; public int devotedEvolutionLevel; public static DevotedLemurianData Create(DevotedLemurianController controller) { //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) return new DevotedLemurianData { itemIndex = controller.DevotionItem, devotedEvolutionLevel = controller.DevotedEvolutionLevel }; } public void LoadData(DevotedLemurianController controller) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) controller._devotionItem = itemIndex; controller._devotedEvolutionLevel = devotedEvolutionLevel; } internal static DevotedLemurianData Read(ReaderContext context) { //IL_0027: 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) DevotedLemurianData devotedLemurianData = new DevotedLemurianData(); BinaryReader reader = context.Reader; int version = context.Version; devotedLemurianData.itemIndex = SharedIndexHelpers.ResolveItem((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); devotedLemurianData.devotedEvolutionLevel = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); return devotedLemurianData; } internal void Write(WriterContext context) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromItem(itemIndex, context)); writer.WritePacked(devotedEvolutionLevel); } } public class DroneMaskData { public List enabledItems = new List(); public static DroneMaskData Create(DroneMask mask) { DroneMaskData droneMaskData = new DroneMaskData(); for (int i = 0; i < mask.array.Length; i++) { if (mask.array[i]) { droneMaskData.enabledItems.Add((DroneIndex)i); } } return droneMaskData; } public void LoadData(DroneMask mask) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < mask.array.Length; i++) { mask.array[i] = false; } foreach (DroneIndex enabledItem in enabledItems) { if ((int)enabledItem != -1) { mask.array[enabledItem] = true; } } } internal static DroneMaskData Read(ReaderContext context) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) DroneMaskData droneMaskData = new DroneMaskData(); BinaryReader reader = context.Reader; int version = context.Version; int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); droneMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { droneMaskData.enabledItems.Add(SharedIndexHelpers.ResolveDrone((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context)); } return droneMaskData; } internal void Write(WriterContext context) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.WritePacked(SharedIndexHelpers.FromDrone(enabledItems[i], context)); } } } public class DroneRepairData { public string requestedBySlotName; public static DroneRepairData Create(DroneRepairMaster droneRepairMaster) { return new DroneRepairData { requestedBySlotName = droneRepairMaster.requestedBySlotName }; } internal void LoadData(DroneRepairMaster droneRepairMaster) { droneRepairMaster.requestedBySlotName = requestedBySlotName; } internal static DroneRepairData Read(ReaderContext context) { return new DroneRepairData { requestedBySlotName = context.Reader.ReadString() }; } internal void Write(WriterContext context) { context.Writer.Write(requestedBySlotName); } } public class EquipmentData { public EquipmentIndex index; public byte charges; public float chargeFinishTime; public static EquipmentData Create(EquipmentState state) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: 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) return new EquipmentData { index = state.equipmentIndex, charges = state.charges, chargeFinishTime = state.chargeFinishTime.t }; } public void LoadEquipment(Inventory inventory, uint equipmentSlot, uint equipmentSet) { //IL_0003: 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_0020: Unknown result type (might be due to invalid IL or missing references) EquipmentState val = default(EquipmentState); ((EquipmentState)(ref val))..ctor(index, new FixedTimeStamp(chargeFinishTime), charges, false); inventory.SetEquipment(val, equipmentSlot, equipmentSet); } internal static EquipmentData Read(ReaderContext context) { //IL_0027: 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) EquipmentData equipmentData = new EquipmentData(); BinaryReader reader = context.Reader; int version = context.Version; equipmentData.index = SharedIndexHelpers.ResolveEquipment((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); equipmentData.charges = reader.ReadByte(); equipmentData.chargeFinishTime = reader.ReadSingle(); return equipmentData; } internal void Write(WriterContext context) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromEquipment(index, context)); writer.Write(charges); writer.Write(chargeFinishTime); } } public class EquipmentMaskData { public List enabledItems = new List(); public static EquipmentMaskData Create(EquipmentMask mask) { EquipmentMaskData equipmentMaskData = new EquipmentMaskData(); for (int i = 0; i < mask.array.Length; i++) { if (mask.array[i]) { equipmentMaskData.enabledItems.Add((EquipmentIndex)i); } } return equipmentMaskData; } public void LoadData(EquipmentMask mask) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < mask.array.Length; i++) { mask.array[i] = false; } foreach (EquipmentIndex enabledItem in enabledItems) { if ((int)enabledItem != -1) { mask.array[enabledItem] = true; } } } internal static EquipmentMaskData Read(ReaderContext context) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) EquipmentMaskData equipmentMaskData = new EquipmentMaskData(); BinaryReader reader = context.Reader; int version = context.Version; int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); equipmentMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { equipmentMaskData.enabledItems.Add(SharedIndexHelpers.ResolveEquipment((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context)); } return equipmentMaskData; } internal void Write(WriterContext context) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.WritePacked(SharedIndexHelpers.FromEquipment(enabledItems[i], context)); } } } public class FieldData { public string Name { get; set; } public TypeData Type { get; set; } public PropertyInfo Property { get; set; } public FieldInfo Field { get; set; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(context.SharedStrings.AddOrIndexOf(Name)); writer.WritePacked(Type.TypeIndex); } internal static FieldData Read(ReaderContext context) { FieldData fieldData = new FieldData(); BinaryReader reader = context.Reader; fieldData.Name = context.SharedStrings.GetSafe(reader.ReadPackedInt32()); fieldData.Type = context.Types[reader.ReadPackedInt32()]; return fieldData; } internal object GetValue(object obj) { if (Field != null) { return Field.GetValue(obj); } if (Property != null) { return Property.GetValue(obj); } throw new NotSupportedException("GetValue on invalid type"); } internal void SetValue(object obj, object value) { if (Field != null) { Field.SetValue(obj, value); } else if (Property != null) { Property.SetValue(obj, value); } } } public class HeaderUserData { public BodyIndex Body { get; set; } public UserIDData UserId { get; set; } public static HeaderUserData Create(PlayerCharacterMasterController master) { //IL_001a: 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_0060: Unknown result type (might be due to invalid IL or missing references) HeaderUserData headerUserData = new HeaderUserData(); if (Object.op_Implicit((Object)(object)master.networkUser)) { headerUserData.UserId = UserIDData.Create(master.networkUser.id); } else { if (!LostNetworkUser.TryGetUser(master.master, out var lostUser)) { return null; } headerUserData.UserId = UserIDData.Create(lostUser.userID); } headerUserData.Body = master.master.bodyPrefab.GetComponent().bodyIndex; return headerUserData; } internal static HeaderUserData Read(ReaderContext context) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new HeaderUserData { Body = SharedIndexHelpers.ResolveBody(context.Reader.ReadInt32(), context), UserId = UserIDData.Read(context) }; } internal void Write(WriterContext context) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) context.Writer.Write(SharedIndexHelpers.FromBody(Body, context)); UserId.Write(context); } } public class InventoryData { public uint infusionBonus; public bool equipmentDisabled; public float beadAppliedHealth; public float beadAppliedShield; public float beadAppliedRegen; public float beadAppliedDamage; public List items = new List(); public float tempStorageDecayDuration; public float tempStorageInvDecayDuration; public EquipmentData[][] equipments; public byte activeEquipmentSlot; public byte[] activeEquipmentSet; public int lastExtraEquipmentCount; public static InventoryData Create(Inventory inventory) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0078: 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_0092: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) InventoryData inventoryData = new InventoryData(); inventoryData.infusionBonus = inventory.infusionBonus; inventoryData.equipmentDisabled = inventory.equipmentDisabled; inventoryData.beadAppliedDamage = inventory.beadAppliedDamage; inventoryData.beadAppliedHealth = inventory.beadAppliedHealth; inventoryData.beadAppliedRegen = inventory.beadAppliedRegen; inventoryData.beadAppliedShield = inventory.beadAppliedShield; foreach (ItemIndex item in inventory.itemAcquisitionOrder) { inventoryData.items.Add(new ItemData { itemIndex = item, count = inventory.GetItemCountPermanent(item), channeledCount = inventory.GetItemCountChanneled(item), tempCount = inventory.GetItemCountTemp(item), tempFixedTime = inventory.tempItemsStorage.decayToZeroTimeStamps.GetValue((SparseIndex)item).t }); } inventoryData.tempStorageDecayDuration = inventory.tempItemsStorage.decayDuration; inventoryData.tempStorageInvDecayDuration = inventory.tempItemsStorage.invDecayDuration; inventoryData.equipments = new EquipmentData[inventory.GetEquipmentSlotCount()][]; for (int i = 0; i < inventoryData.equipments.Length; i++) { EquipmentData[] array = (inventoryData.equipments[i] = new EquipmentData[inventory.GetEquipmentSetCount((uint)i)]); for (int j = 0; j < array.Length; j++) { array[j] = EquipmentData.Create(inventory.GetEquipment((uint)i, (uint)j)); } } inventoryData.activeEquipmentSlot = inventory.activeEquipmentSlot; inventoryData.activeEquipmentSet = inventory.activeEquipmentSet.ToArray(); inventoryData.lastExtraEquipmentCount = inventory._lastExtraEquipmentCount; return inventoryData; } public void LoadInventory(Inventory inventory) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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_00a7: Invalid comparison between Unknown and I4 //IL_00af: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_0105: Unknown result type (might be due to invalid IL or missing references) inventory.beadAppliedShield = beadAppliedShield; inventory.beadAppliedRegen = beadAppliedRegen; inventory.beadAppliedHealth = beadAppliedHealth; inventory.beadAppliedDamage = beadAppliedDamage; inventory.equipmentDisabled = equipmentDisabled; inventory.itemAcquisitionOrder.Clear(); for (int i = 0; i < inventory.itemAcquisitionSet.Length; i++) { inventory.itemAcquisitionSet[i] = false; } inventory.tempItemsStorage.decayDuration = tempStorageDecayDuration; inventory.tempItemsStorage.invDecayDuration = tempStorageInvDecayDuration; foreach (ItemData item in items) { ItemIndex itemIndex = item.itemIndex; if ((int)itemIndex != -1) { ((ItemCollection)(ref inventory.permanentItemStacks)).SetStackValue(itemIndex, item.count); ((ItemCollection)(ref inventory.channeledItemStacks)).SetStackValue(itemIndex, item.channeledCount); if (item.tempFixedTime > 0f) { ref SparseArrayStruct decayToZeroTimeStamps = ref inventory.tempItemsStorage.decayToZeroTimeStamps; FixedTimeStamp val = new FixedTimeStamp(item.tempFixedTime); decayToZeroTimeStamps.SetValue((SparseIndex)itemIndex, ref val); ((ItemCollection)(ref inventory.tempItemsStorage.tempItemStacks)).SetStackValue(itemIndex, item.tempCount); } inventory.UpdateEffectiveItemStacks(itemIndex); } } inventory._lastExtraEquipmentCount = lastExtraEquipmentCount; inventory.HandleInventoryChanged(); inventory.AddInfusionBonus(infusionBonus); for (uint num = 0u; num < equipments.Length; num++) { EquipmentData[] array = equipments[num]; for (uint num2 = 0u; num2 < array.Length; num2++) { array[num2].LoadEquipment(inventory, num, num2); } } inventory.activeEquipmentSet = activeEquipmentSet; if (activeEquipmentSlot > 0) { inventory.SetActiveEquipmentSlot(activeEquipmentSlot); } ((NetworkBehaviour)inventory).SetDirtyBit(uint.MaxValue); } internal static InventoryData Read(ReaderContext context) { InventoryData inventoryData = new InventoryData(); BinaryReader reader = context.Reader; int version = context.Version; inventoryData.infusionBonus = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); inventoryData.equipmentDisabled = reader.ReadBoolean(); inventoryData.beadAppliedHealth = reader.ReadSingle(); inventoryData.beadAppliedShield = reader.ReadSingle(); inventoryData.beadAppliedRegen = reader.ReadSingle(); inventoryData.beadAppliedDamage = reader.ReadSingle(); int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); inventoryData.items = new List(num); for (int i = 0; i < num; i++) { inventoryData.items.Add(ItemData.Read(context)); } inventoryData.tempStorageDecayDuration = reader.ReadSingle(); inventoryData.tempStorageInvDecayDuration = reader.ReadSingle(); inventoryData.equipments = new EquipmentData[(version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()][]; for (int j = 0; j < inventoryData.equipments.Length; j++) { EquipmentData[] array = (inventoryData.equipments[j] = new EquipmentData[(version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()]); for (int k = 0; k < array.Length; k++) { array[k] = EquipmentData.Read(context); } } inventoryData.activeEquipmentSlot = reader.ReadByte(); inventoryData.activeEquipmentSet = new byte[(version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()]; for (int l = 0; l < inventoryData.activeEquipmentSet.Length; l++) { inventoryData.activeEquipmentSet[l] = reader.ReadByte(); } inventoryData.lastExtraEquipmentCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); return inventoryData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(infusionBonus); writer.Write(equipmentDisabled); writer.Write(beadAppliedHealth); writer.Write(beadAppliedShield); writer.Write(beadAppliedRegen); writer.Write(beadAppliedDamage); writer.WritePacked(items.Count); for (int i = 0; i < items.Count; i++) { items[i].Write(context); } writer.Write(tempStorageDecayDuration); writer.Write(tempStorageInvDecayDuration); writer.WritePacked(equipments.Length); for (int j = 0; j < equipments.Length; j++) { EquipmentData[] array = equipments[j]; writer.WritePacked(array.Length); for (int k = 0; k < array.Length; k++) { array[k].Write(context); } } writer.Write(activeEquipmentSlot); writer.WritePacked(activeEquipmentSet.Length); for (int l = 0; l < activeEquipmentSet.Length; l++) { writer.Write(activeEquipmentSet[l]); } writer.WritePacked(lastExtraEquipmentCount); } } public class ItemData { public ItemIndex itemIndex; public int count; public int channeledCount; public int tempCount; public float tempFixedTime; internal static ItemData Read(ReaderContext context) { //IL_0027: 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) ItemData itemData = new ItemData(); BinaryReader reader = context.Reader; int version = context.Version; itemData.itemIndex = SharedIndexHelpers.ResolveItem((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); itemData.count = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); itemData.channeledCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); itemData.tempCount = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); itemData.tempFixedTime = reader.ReadSingle(); return itemData; } internal void Write(WriterContext context) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromItem(itemIndex, context)); writer.WritePacked(count); writer.WritePacked(channeledCount); writer.WritePacked(tempCount); writer.Write(tempFixedTime); } } public class ItemMaskData { public List enabledItems = new List(); public static ItemMaskData Create(ItemMask mask) { ItemMaskData itemMaskData = new ItemMaskData(); for (int i = 0; i < mask.array.Length; i++) { if (mask.array[i]) { itemMaskData.enabledItems.Add((ItemIndex)i); } } return itemMaskData; } public void LoadData(ItemMask mask) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < mask.array.Length; i++) { mask.array[i] = false; } foreach (ItemIndex enabledItem in enabledItems) { if ((int)enabledItem != -1) { mask.array[enabledItem] = true; } } } internal static ItemMaskData Read(ReaderContext context) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) ItemMaskData itemMaskData = new ItemMaskData(); BinaryReader reader = context.Reader; int version = context.Version; int num = ((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); itemMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { itemMaskData.enabledItems.Add(SharedIndexHelpers.ResolveItem((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context)); } return itemMaskData; } internal void Write(WriterContext context) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.WritePacked(SharedIndexHelpers.FromItem(enabledItems[i], context)); } } } public class LoadoutBodyData { public BodyIndex bodyIndex; public uint skinPreference; public uint[] skillPreferences; public static LoadoutBodyData Create(BodyLoadout bodyLoadout) { //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) return new LoadoutBodyData { bodyIndex = bodyLoadout.bodyIndex, skinPreference = bodyLoadout.skinPreference, skillPreferences = bodyLoadout.skillPreferences }; } public BodyLoadout Load() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if ((int)bodyIndex == -1) { return null; } return new BodyLoadout { bodyIndex = bodyIndex, skinPreference = skinPreference, skillPreferences = skillPreferences }; } internal static LoadoutBodyData Read(ReaderContext context) { //IL_0028: 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) LoadoutBodyData loadoutBodyData = new LoadoutBodyData(); BinaryReader reader = context.Reader; int version = context.Version; loadoutBodyData.bodyIndex = SharedIndexHelpers.ResolveBody((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); loadoutBodyData.skinPreference = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); loadoutBodyData.skillPreferences = new uint[(version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()]; for (int i = 0; i < loadoutBodyData.skillPreferences.Length; i++) { loadoutBodyData.skillPreferences[i] = ((version > 1) ? reader.ReadPackedUInt32() : reader.ReadUInt32()); } return loadoutBodyData; } internal void Write(WriterContext context) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromBody(bodyIndex, context)); writer.WritePacked(skinPreference); writer.WritePacked(skillPreferences.Length); for (int i = 0; i < skillPreferences.Length; i++) { writer.WritePacked(skillPreferences[i]); } } } public class LoadoutData { public List modifiedLoadouts = new List(); public static LoadoutData Create(Loadout loadout) { LoadoutData loadoutData = new LoadoutData(); BodyLoadout[] modifiedBodyLoadouts = loadout.bodyLoadoutManager.modifiedBodyLoadouts; loadoutData.modifiedLoadouts.AddRange(modifiedBodyLoadouts.Select(LoadoutBodyData.Create)); return loadoutData; } public void LoadData(Loadout loadout) { loadout.Clear(); loadout.bodyLoadoutManager.modifiedBodyLoadouts = (from el in modifiedLoadouts select el.Load() into l where l != null select l).ToArray(); } internal static LoadoutData Read(ReaderContext context) { LoadoutData loadoutData = new LoadoutData(); BinaryReader reader = context.Reader; int num = ((context.Version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); loadoutData.modifiedLoadouts = new List(num); for (int i = 0; i < num; i++) { loadoutData.modifiedLoadouts.Add(LoadoutBodyData.Read(context)); } return loadoutData; } internal void Write(WriterContext context) { context.Writer.WritePacked(modifiedLoadouts.Count); for (int i = 0; i < modifiedLoadouts.Count; i++) { modifiedLoadouts[i].Write(context); } } } public class ModdedData { public string ObjectType { get; set; } [DiscoverObjectType("ObjectType")] public object Value { get; set; } } public class RngData { public ulong state0; public ulong state1; public static RngData Create(Xoroshiro128Plus rng) { return new RngData { state0 = rng.state0, state1 = rng.state1 }; } public void LoadDataOut(out Xoroshiro128Plus rng) { object uninitializedObject = FormatterServices.GetUninitializedObject(typeof(Xoroshiro128Plus)); rng = (Xoroshiro128Plus)((uninitializedObject is Xoroshiro128Plus) ? uninitializedObject : null); LoadDataRef(ref rng); } public void LoadDataRef(ref Xoroshiro128Plus rng) { rng.state0 = state0; rng.state1 = state1; } internal static RngData Read(ReaderContext context) { return new RngData { state0 = context.Reader.ReadUInt64(), state1 = context.Reader.ReadUInt64() }; } internal void Write(WriterContext context) { context.Writer.Write(state0); context.Writer.Write(state1); } } public class RuleBookData { public List ruleValues = new List(); public static RuleBookData Create(RuleBook ruleBook) { RuleBookData ruleBookData = new RuleBookData(); for (int i = 0; i < ruleBook.ruleValues.Length; i++) { RuleDef ruleDef = RuleCatalog.GetRuleDef(i); if (ruleDef.defaultChoiceIndex != ruleBook.ruleValues[i]) { ruleBookData.ruleValues.Add(new RuleValueData { index = ruleDef.globalIndex, value = ruleBook.ruleValues[i] }); } } return ruleBookData; } public RuleBook Load() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown RuleBook val = new RuleBook(); foreach (RuleValueData ruleValue in ruleValues) { int index = ruleValue.index; if (index != -1) { val.ruleValues[index] = ruleValue.value; } } return val; } internal static RuleBookData Read(ReaderContext context) { RuleBookData ruleBookData = new RuleBookData(); BinaryReader reader = context.Reader; int num = ((context.Version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32()); ruleBookData.ruleValues = new List(num); for (int i = 0; i < num; i++) { ruleBookData.ruleValues.Add(RuleValueData.Read(context)); } return ruleBookData; } internal void Write(WriterContext context) { context.Writer.WritePacked(ruleValues.Count); for (int i = 0; i < ruleValues.Count; i++) { ruleValues[i].Write(context); } } } public class RuleValueData { public int index; public byte value; internal static RuleValueData Read(ReaderContext context) { RuleValueData ruleValueData = new RuleValueData(); BinaryReader reader = context.Reader; int version = context.Version; ruleValueData.index = SharedIndexHelpers.ResolveRule((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); ruleValueData.value = reader.ReadByte(); return ruleValueData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromRule(index, context)); writer.Write(value); } } public class StatFieldData { public int index; public ulong value; internal static StatFieldData Read(ReaderContext context) { StatFieldData statFieldData = new StatFieldData(); BinaryReader reader = context.Reader; int version = context.Version; statFieldData.index = SharedIndexHelpers.ResolveStatField((version > 1) ? reader.ReadPackedInt32() : reader.ReadInt32(), context); statFieldData.value = reader.ReadUInt64(); return statFieldData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(SharedIndexHelpers.FromStatField(index, context)); writer.Write(value); } } public class TypeData { public int Version { get; set; } public TypeName Name { get; set; } public int TypeIndex { get; set; } public ObjectType ObjectType { get; set; } public List Fields { get; set; } public TypeData CollectionArgumentType { get; set; } public Type Type { get; set; } public MethodInfo AddCollectionElementMethod { get; set; } public PropertyInfo CollectionCountProperty { get; set; } public ConstructorInfo Constructor { get; set; } public int ArrayRank { get; set; } public bool IsPrimitive => (int)ObjectType < 12; public bool IsCollection { get { if (11 < (int)ObjectType) { return (int)ObjectType < 14; } return false; } } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.Write((byte)ObjectType); if (IsPrimitive) { return; } writer.WritePacked(Version); Name.Write(context); switch (ObjectType) { case ObjectType.Array: writer.WritePacked(CollectionArgumentType.TypeIndex); writer.WritePacked(ArrayRank); break; case ObjectType.Collection: writer.WritePacked(CollectionArgumentType.TypeIndex); break; case ObjectType.Class: case ObjectType.Object: case ObjectType.ValueType: case ObjectType.KeyValuePair: { writer.WritePacked(Fields.Count); for (int i = 0; i < Fields.Count; i++) { Fields[i].Write(context); } break; } } } internal void Read(ReaderContext context) { BinaryReader reader = context.Reader; ObjectType = (ObjectType)reader.ReadByte(); if (IsPrimitive) { return; } Version = reader.ReadPackedInt32(); Name = TypeName.Read(context); switch (ObjectType) { case ObjectType.Array: CollectionArgumentType = context.Types[reader.ReadPackedInt32()]; ArrayRank = reader.ReadPackedInt32(); break; case ObjectType.Collection: CollectionArgumentType = context.Types[reader.ReadPackedInt32()]; break; case ObjectType.Class: case ObjectType.Object: case ObjectType.ValueType: case ObjectType.KeyValuePair: { int num = reader.ReadPackedInt32(); Fields = new List(num); for (int i = 0; i < num; i++) { Fields.Add(FieldData.Read(context)); } break; } } } internal void AddCollectionElement(object obj, object value) { object[] array = ObjectBuffer.Buffers[1]; array[0] = value; AddCollectionElementMethod?.Invoke(obj, array); } internal int CollectionCount(object obj) { return (int)CollectionCountProperty.GetValue(obj); } internal object CreateObject(object[] parameters) { return Constructor?.Invoke(parameters); } } public struct TypeName { public string Namespace; public string Name; public string AssemblyName; public TypeName[] GenereicArguments; public readonly void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.WritePacked(context.SharedStrings.AddOrIndexOf(Namespace)); writer.WritePacked(context.SharedStrings.AddOrIndexOf(Name)); writer.WritePacked(context.SharedStrings.AddOrIndexOf(AssemblyName)); writer.WritePacked(GenereicArguments.Length); for (int i = 0; i < GenereicArguments.Length; i++) { GenereicArguments[i].Write(context); } } public static TypeName Read(ReaderContext context) { TypeName result = default(TypeName); BinaryReader reader = context.Reader; result.Namespace = context.SharedStrings.GetSafe(reader.ReadPackedInt32()); result.Name = context.SharedStrings.GetSafe(reader.ReadPackedInt32()); result.AssemblyName = context.SharedStrings.GetSafe(reader.ReadPackedInt32()); int num = reader.ReadPackedInt32(); result.GenereicArguments = new TypeName[num]; for (int i = 0; i < num; i++) { result.GenereicArguments[i] = Read(context); } return result; } internal static TypeName FromType(Type type) { TypeName result = default(TypeName); StringBuilder stringBuilder = new StringBuilder(); GetNamespace(type, stringBuilder); result.Namespace = stringBuilder.ToString(); result.Name = type.Name; if (type.IsGenericType) { Type[] genericTypeArguments = type.GenericTypeArguments; result.GenereicArguments = new TypeName[genericTypeArguments.Length]; for (int i = 0; i < genericTypeArguments.Length; i++) { result.GenereicArguments[i] = FromType(genericTypeArguments[i]); } } else { result.GenereicArguments = Array.Empty(); } string fullName = type.Assembly.FullName; result.AssemblyName = fullName.Substring(0, fullName.IndexOf(',')); return result; } internal readonly string Build() { StringBuilder stringBuilder = new StringBuilder(); Build(stringBuilder); return stringBuilder.ToString(); } private readonly void Build(StringBuilder builder) { builder.Append(Namespace); builder.Append(Name); if (GenereicArguments.Length != 0) { builder.Append('['); for (int i = 0; i < GenereicArguments.Length; i++) { if (i > 0) { builder.Append(','); } builder.Append('['); GenereicArguments[i].Build(builder); builder.Append(']'); } builder.Append(']'); } builder.Append(", ").Append(AssemblyName); } private static void GetNamespace(Type type, StringBuilder builder) { if ((object)type.DeclaringType == null) { if (!string.IsNullOrEmpty(type.Namespace)) { builder.Append(type.Namespace).Append('.'); } } else { GetNamespace(type.DeclaringType, builder); builder.Append(type.DeclaringType.Name); builder.Append('+'); } } } public class UserIDData { public ulong steam; public string egs; public byte subId; public static UserIDData Create(NetworkUserId userID) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) return new UserIDData { egs = userID.strValue, steam = userID.value, subId = userID.subId }; } public NetworkUserId Load() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_002e: Unknown result type (might be due to invalid IL or missing references) if (steam != 0L) { return new NetworkUserId(steam, subId); } if (egs != null) { return new NetworkUserId(egs, subId); } return default(NetworkUserId); } internal static UserIDData Read(ReaderContext context) { UserIDData userIDData = new UserIDData(); BinaryReader reader = context.Reader; if (reader.ReadBoolean()) { userIDData.steam = reader.ReadUInt64(); } else { userIDData.egs = reader.ReadString(); } userIDData.subId = reader.ReadByte(); return userIDData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; if (egs == null) { writer.Write(value: true); writer.Write(steam); } else { writer.Write(value: false); writer.Write(egs); } writer.Write(subId); } } } namespace ProperSave.Components { public class GamepadTooltipProvider : TooltipProvider { public HoldGamepadInputEvent inputEvent; private RectTransform rectTransform; private InputBindingDisplayController inputBindingDisplayController; public void Awake() { rectTransform = ((Component)this).GetComponent(); inputBindingDisplayController = ((Component)this).GetComponent(); } public void Start() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown inputBindingDisplayController.useExplicitInputSource = false; inputEvent.holdStartEvent.AddListener(new UnityAction(HoldStart)); inputEvent.holdEndEvent.AddListener(new UnityAction(HoldEnd)); } private void HoldStart() { //IL_0029: 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_0096: Unknown result type (might be due to invalid IL or missing references) EventSystem current = EventSystem.current; MPEventSystem val = (MPEventSystem)(object)((current is MPEventSystem) ? current : null); if (!((Object)(object)val == (Object)null) && ((TooltipProvider)this).tooltipIsAvailable) { TooltipController.SetTooltip(val, (TooltipProvider)(object)this, new Vector2(2.1474836E+09f, 0f), rectTransform); if (Object.op_Implicit((Object)(object)val.currentTooltip) && (Object)(object)val.currentTooltipProvider == (Object)(object)this) { val.currentTooltip.owner = null; RectTransform tooltipCenterTransform = val.currentTooltip.tooltipCenterTransform; UICamera uiCamera = val.currentTooltip.uiCamera; ((Transform)tooltipCenterTransform).position = (((uiCamera != null) ? uiCamera.camera : null) ?? Camera.main).WorldToScreenPoint(((Transform)rectTransform).position); } } } private void HoldEnd() { EventSystem current = EventSystem.current; MPEventSystem val = (MPEventSystem)(object)((current is MPEventSystem) ? current : null); if (!((Object)(object)val == (Object)null) && ((TooltipProvider)this).tooltipIsAvailable) { TooltipController.RemoveTooltip(val, (TooltipProvider)(object)this); } } } public class HoldGamepadInputEvent : HGGamepadInputEvent { public UnityEvent holdStartEvent = new UnityEvent(); public UnityEvent holdEndEvent = new UnityEvent(); protected void Update() { bool flag = ((HGGamepadInputEvent)this).CanAcceptInput(); if (base.couldAcceptInput != flag) { GameObject[] enabledObjectsIfActive = base.enabledObjectsIfActive; for (int i = 0; i < enabledObjectsIfActive.Length; i++) { enabledObjectsIfActive[i].SetActive(flag); } } if (((HGGamepadInputEvent)this).CanAcceptInput()) { if (((HGGamepadInputEvent)this).eventSystem.player.GetButtonShortPressDown(base.actionName)) { UnityEvent obj = holdStartEvent; if (obj != null) { obj.Invoke(); } } else if (((HGGamepadInputEvent)this).eventSystem.player.GetButtonShortPressUp(base.actionName)) { UnityEvent obj2 = holdEndEvent; if (obj2 != null) { obj2.Invoke(); } } else if (((HGGamepadInputEvent)this).eventSystem.player.GetButtonUp(base.actionName)) { UnityEvent actionEvent = base.actionEvent; if (actionEvent != null) { actionEvent.Invoke(); } } } base.couldAcceptInput = flag; } } }