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.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("1.0.0.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; } } public static class JSONWriter { public static string ToJson(this object item) { StringBuilder stringBuilder = new StringBuilder(); AppendValue(stringBuilder, item); return stringBuilder.ToString(); } private static void AppendValue(StringBuilder stringBuilder, object item) { if (item == null) { stringBuilder.Append("null"); return; } Type type = item.GetType(); if (type == typeof(string)) { stringBuilder.Append('"'); string text = (string)item; for (int i = 0; i < text.Length; i++) { if (text[i] < ' ' || text[i] == '"' || text[i] == '\\') { stringBuilder.Append('\\'); int num = "\"\\\n\r\t\b\f".IndexOf(text[i]); if (num >= 0) { stringBuilder.Append("\"\\nrtbf"[num]); } else { stringBuilder.AppendFormat("u{0:X4}", (uint)text[i]); } } else { stringBuilder.Append(text[i]); } } stringBuilder.Append('"'); return; } if (type == typeof(byte) || type == typeof(int) || type == typeof(long) || type == typeof(uint) || type == typeof(ulong)) { stringBuilder.Append(item.ToString()); return; } if (type == typeof(float)) { stringBuilder.Append(((float)item).ToString(CultureInfo.InvariantCulture)); return; } if (type == typeof(double)) { stringBuilder.Append(((double)item).ToString(CultureInfo.InvariantCulture)); return; } if (type == typeof(bool)) { stringBuilder.Append(((bool)item) ? "true" : "false"); return; } if (type.IsEnum) { stringBuilder.Append('"'); stringBuilder.Append(item.ToString()); stringBuilder.Append('"'); return; } if (item is IList) { stringBuilder.Append('['); bool flag = true; IList list = item as IList; for (int j = 0; j < list.Count; j++) { if (flag) { flag = false; } else { stringBuilder.Append(','); } AppendValue(stringBuilder, list[j]); } stringBuilder.Append(']'); return; } if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >)) { if (type.GetGenericArguments()[0] != typeof(string)) { stringBuilder.Append("{}"); return; } stringBuilder.Append('{'); IDictionary dictionary = item as IDictionary; bool flag2 = true; foreach (object key in dictionary.Keys) { if (flag2) { flag2 = false; } else { stringBuilder.Append(','); } stringBuilder.Append('"'); stringBuilder.Append((string)key); stringBuilder.Append("\":"); AppendValue(stringBuilder, dictionary[key]); } stringBuilder.Append('}'); return; } stringBuilder.Append('{'); bool flag3 = true; FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); for (int k = 0; k < fields.Length; k++) { if (fields[k].IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true)) { continue; } object value = fields[k].GetValue(item); if (value != null) { if (flag3) { flag3 = false; } else { stringBuilder.Append(','); } stringBuilder.Append('"'); stringBuilder.Append(GetMemberName(fields[k])); stringBuilder.Append("\":"); AppendValue(stringBuilder, value); } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy); for (int l = 0; l < properties.Length; l++) { if (!properties[l].CanRead || properties[l].IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true)) { continue; } object value2 = properties[l].GetValue(item, null); if (value2 != null) { if (flag3) { flag3 = false; } else { stringBuilder.Append(','); } stringBuilder.Append('"'); stringBuilder.Append(GetMemberName(properties[l])); stringBuilder.Append("\":"); AppendValue(stringBuilder, value2); } } stringBuilder.Append('}'); } private static string GetMemberName(MemberInfo member) { if (member.IsDefined(typeof(DataMemberAttribute), inherit: true)) { DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)Attribute.GetCustomAttribute(member, typeof(DataMemberAttribute), inherit: true); if (!string.IsNullOrEmpty(dataMemberAttribute.Name)) { return dataMemberAttribute.Name; } } return member.Name; } } } namespace ProperSave { public static class Extensions { 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 int AddOrIndexOf(this List list, T value) { 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 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 readonly string PROPER_SAVE_SELECT_SAVE_TITLE = "PROPER_SAVE_SELECT_SAVE_TITLE"; public static readonly string PROPER_SAVE_SELECT_SAVE_DESCRIPTION = "PROPER_SAVE_SELECT_SAVE_DESCRIPTION"; public static readonly string PROPER_SAVE_SELECT_SAVE_BUTTON = "PROPER_SAVE_SELECT_SAVE_BUTTON"; public static readonly string PROPER_SAVE_SELECT_SAVE_CANCEL = "PROPER_SAVE_SELECT_SAVE_CANCEL"; public static readonly string PROPER_SAVE_DELETE_SAVE = "PROPER_SAVE_DELETE_SAVE"; public static readonly string PROPER_SAVE_DELETE_SAVE_TITLE = "PROPER_SAVE_DELETE_SAVE_TITLE"; public static readonly string PROPER_SAVE_DELETE_SAVE_DESCRIPTION = "PROPER_SAVE_DELETE_SAVE_DESCRIPTION"; public static readonly string PROPER_SAVE_DELETE_CONFIRM_TITLE = "PROPER_SAVE_DELETE_CONFIRM_TITLE"; public static readonly string PROPER_SAVE_DELETE_CONFIRM_DESCRIPTION = "PROPER_SAVE_DELETE_CONFIRM_DESCRIPTION"; public static readonly string PROPER_SAVE_DELETE_CONFIRM_YES = "PROPER_SAVE_DELETE_CONFIRM_YES"; public static readonly string PROPER_SAVE_SELECT_HINT = "PROPER_SAVE_SELECT_HINT"; public static readonly string PROPER_SAVE_BACK_HINT = "PROPER_SAVE_BACK_HINT"; public static readonly string PROPER_SAVE_MOUSE_SELECT_HINT = "PROPER_SAVE_MOUSE_SELECT_HINT"; public static readonly string PROPER_SAVE_ESC_HINT = "PROPER_SAVE_ESC_HINT"; } public static class Loading { private static bool isLoading; public static bool IsLoading { get { return isLoading; } internal set { if (isLoading != value) { isLoading = value; if (isLoading) { Loading.OnLoadingStarted?.Invoke(CurrentSave); } else { Loading.OnLoadingEnded?.Invoke(CurrentSave); } } } } 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() { SaveFileMetadata currentLobbySaveMetadata = SaveFileMetadata.GetCurrentLobbySaveMetadata(); yield return LoadLobby(currentLobbySaveMetadata); } internal static IEnumerator LoadLobby(SaveFileMetadata metadata) { 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; } if (metadata == null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Save file for current users is not found"); yield break; } UPath? filePath = metadata.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; } metadata.ReadBody(); ProperSavePlugin.CurrentSave = metadata; IsLoading = true; if (metadata.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 class SaveDialogCloseWatcher : MonoBehaviour { public SimpleDialogBox dialog; public Action onCancel; private float delay = 0.4f; private bool closing; private void Update() { if (!closing) { delay -= Time.unscaledDeltaTime; if (!(delay > 0f) && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)331))) { closing = true; GameObject obj = (((Object)(object)dialog.rootObject != (Object)null) ? dialog.rootObject : ((Component)dialog).gameObject); onCancel?.Invoke(); Object.Destroy((Object)(object)obj); } } } } private class CompactSaveDialogButton : MonoBehaviour { } private class SaveDialogInputLegendController : MonoBehaviour { public MPEventSystem eventSystem; public InputBindingDisplayController selectGlyph; public InputBindingDisplayController backGlyph; private void Update() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 bool visible = (Object)(object)eventSystem != (Object)null && (int)eventSystem.currentInputSource == 1; SetGlyphVisible(selectGlyph, visible); SetGlyphVisible(backGlyph, visible); } private static void SetGlyphVisible(InputBindingDisplayController glyph, bool visible) { if (!((Object)(object)glyph == (Object)null)) { HGTextMeshProUGUI component = ((Component)glyph).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = visible; } Transform val = ((Component)glyph).transform.parent.Find("KeyFallback"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(!visible); } } } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__24_1; public static UnityAction <>9__25_0; public static UnityAction <>9__26_1; public static Action <>9__26_2; public static Func <>9__33_0; public static Func <>9__33_1; public static Func <>9__34_0; internal void b__24_1() { } internal void b__25_0() { } internal void b__26_1() { ShowSaveSelectionDialog(SaveFileMetadata.GetCurrentLobbySaveMetadatas()); } internal void b__26_2() { ShowSaveSelectionDialog(SaveFileMetadata.GetCurrentLobbySaveMetadatas()); } internal bool b__33_0(MPButton button) { return (Object)(object)((Component)button).GetComponentInParent() == (Object)null; } internal Transform b__33_1(MPButton button) { return ((Component)button).transform; } internal bool b__34_0(MPButton button) { return (Object)(object)((Component)button).GetComponentInParent() == (Object)null; } } 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; private const float DialogWidth = 640f; private const float SaveButtonHeight = 86f; private const float CompactButtonHeight = 52f; private const float LegendHeight = 42f; private const float ConfirmRowHeight = 56f; private const float ConfirmButtonWidth = 230f; private const float ConfirmButtonHeight = 48f; private const float LegendItemWidth = 260f; private const float LegendItemHeight = 30f; 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 = "[CENI] 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 = "[CENI] 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"); return; } if (Loading.IsLoading) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Already loading"); return; } List currentLobbySaveMetadatas = SaveFileMetadata.GetCurrentLobbySaveMetadatas(); if (currentLobbySaveMetadatas.Count == 0) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Save file for current users is not found"); } else { ShowSaveSelectionDialog(currentLobbySaveMetadatas); } } 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) : "" }); } private static void ShowSaveSelectionDialog(List saves) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown EventSystem current = EventSystem.current; SimpleDialogBox val = SimpleDialogBox.Create((MPEventSystem)(object)((current is MPEventSystem) ? current : null)); if ((Object)(object)val == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to create save selection dialog"); return; } val.headerToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_SELECT_SAVE_TITLE }; val.descriptionToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_SELECT_SAVE_DESCRIPTION }; foreach (SaveFileMetadata safe in saves) { SaveFileMetadata captured = safe; val.AddActionButton((UnityAction)delegate { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(Loading.LoadLobby(captured)); }, LanguageConsts.PROPER_SAVE_TITLE_LOAD, true, Array.Empty()); SetLastButtonContent(val, GetSaveButtonDescription(safe), GetSavePortrait(safe)); } val.AddActionButton((UnityAction)delegate { ShowDeleteSaveDialog(saves); }, LanguageConsts.PROPER_SAVE_DELETE_SAVE, true, Array.Empty()); MarkLastButtonCompact(val); object obj = <>c.<>9__24_1; if (obj == null) { UnityAction val2 = delegate { }; <>c.<>9__24_1 = val2; obj = (object)val2; } val.AddActionButton((UnityAction)obj, LanguageConsts.PROPER_SAVE_SELECT_SAVE_CANCEL, true, Array.Empty()); MarkLastButtonCompact(val); AddCloseWatcher(val); ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(DelayedSaveDialogLayout(val)); } private static void ShowDeleteSaveDialog(List saves) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown EventSystem current = EventSystem.current; SimpleDialogBox val = SimpleDialogBox.Create((MPEventSystem)(object)((current is MPEventSystem) ? current : null)); if ((Object)(object)val == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to create delete save dialog"); return; } val.headerToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_DELETE_SAVE_TITLE }; val.descriptionToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_DELETE_SAVE_DESCRIPTION }; foreach (SaveFileMetadata safe in saves) { SaveFileMetadata captured = safe; val.AddActionButton((UnityAction)delegate { ShowDeleteConfirmDialog(captured); }, LanguageConsts.PROPER_SAVE_DELETE_SAVE, true, Array.Empty()); SetLastButtonContent(val, GetSaveButtonDescription(safe), GetSavePortrait(safe)); } object obj = <>c.<>9__25_0; if (obj == null) { UnityAction val2 = delegate { }; <>c.<>9__25_0 = val2; obj = (object)val2; } val.AddActionButton((UnityAction)obj, LanguageConsts.PROPER_SAVE_SELECT_SAVE_CANCEL, true, Array.Empty()); MarkLastButtonCompact(val); AddCloseWatcher(val); ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(DelayedSaveDialogLayout(val)); } private static void ShowDeleteConfirmDialog(SaveFileMetadata save) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown //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_00aa: Expected O, but got Unknown EventSystem current = EventSystem.current; SimpleDialogBox val = SimpleDialogBox.Create((MPEventSystem)(object)((current is MPEventSystem) ? current : null)); if ((Object)(object)val == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to create delete confirmation dialog"); return; } val.headerToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_DELETE_CONFIRM_TITLE }; val.descriptionToken = new TokenParamsPair { token = LanguageConsts.PROPER_SAVE_DELETE_CONFIRM_DESCRIPTION }; val.AddActionButton((UnityAction)delegate { SaveFileMetadata.DeleteSave(save); UpdateLobbyControls(); }, LanguageConsts.PROPER_SAVE_DELETE_CONFIRM_YES, true, Array.Empty()); object obj = <>c.<>9__26_1; if (obj == null) { UnityAction val2 = delegate { ShowSaveSelectionDialog(SaveFileMetadata.GetCurrentLobbySaveMetadatas()); }; <>c.<>9__26_1 = val2; obj = (object)val2; } val.AddActionButton((UnityAction)obj, LanguageConsts.PROPER_SAVE_SELECT_SAVE_CANCEL, true, Array.Empty()); AddCloseWatcher(val, delegate { ShowSaveSelectionDialog(SaveFileMetadata.GetCurrentLobbySaveMetadatas()); }); ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(DelayedSaveDialogLayout(val, confirmLayout: true)); } private static string GetSaveButtonDescription(SaveFileMetadata saveMetadata) { //IL_005a: 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) SaveFileHeader header = saveMetadata.Header; string text = ""; if (header.Users.Length != 0) { SurvivorDef val = SurvivorCatalog.FindSurvivorDefFromBody(BodyCatalog.GetBodyPrefab(header.Users[0].Body)); text = (((Object)(object)val != (Object)null) ? Language.GetString(val.displayNameToken) : ""); } SceneDef sceneDefFromSceneName = SceneCatalog.GetSceneDefFromSceneName(header.SceneName); DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(header.Difficulty); int time = header.Time; return Language.GetStringFormatted(LanguageConsts.PROPER_SAVE_SELECT_SAVE_BUTTON, new object[6] { text, Object.op_Implicit((Object)(object)sceneDefFromSceneName) ? Language.GetString(sceneDefFromSceneName.nameToken) : header.SceneName, (header.StageClearCount + 1).ToString(), $"{time / 60:00}:{time % 60:00}", (difficultyDef != null) ? Language.GetString(difficultyDef.nameToken) : "", "" }); } private static Texture GetSavePortrait(SaveFileMetadata saveMetadata) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) try { SaveFileHeader header = saveMetadata.Header; if (header.Users.Length == 0) { return null; } GameObject bodyPrefab = BodyCatalog.GetBodyPrefab(header.Users[0].Body); CharacterBody val = (Object.op_Implicit((Object)(object)bodyPrefab) ? bodyPrefab.GetComponent() : null); return Object.op_Implicit((Object)(object)val) ? val.portraitIcon : null; } catch { return null; } } private static void SetLastButtonContent(SimpleDialogBox dialog, string text, Texture portrait) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) try { RectTransform buttonContainer = dialog.buttonContainer; if ((Object)(object)buttonContainer == (Object)null || ((Transform)buttonContainer).childCount == 0) { return; } Transform child = ((Transform)buttonContainer).GetChild(((Transform)buttonContainer).childCount - 1); if ((Object)(object)portrait != (Object)null) { AddPortraitToButton(child, portrait); } LanguageTextMeshController[] componentsInChildren = ((Component)child).GetComponentsInChildren(); for (int i = 0; i < componentsInChildren.Length; i++) { ((Behaviour)componentsInChildren[i]).enabled = false; } HGTextMeshProUGUI componentInChildren = ((Component)child).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { ((TMP_Text)componentInChildren).text = text; ((TMP_Text)componentInChildren).enableWordWrapping = true; ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)4097; ((TMP_Text)componentInChildren).fontSize = 18f; RectTransform component = ((Component)componentInChildren).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)portrait != (Object)null) { component.offsetMin = new Vector2(component.offsetMin.x + 78f, component.offsetMin.y); } } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to set save button content"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } private static void AddPortraitToButton(Transform button, Texture portrait) { //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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_00ad: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("[CENI] Portrait", new Type[2] { typeof(RectTransform), typeof(RawImage) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent(button, false); component.anchorMin = new Vector2(0f, 0.5f); component.anchorMax = new Vector2(0f, 0.5f); component.pivot = new Vector2(0f, 0.5f); component.anchoredPosition = new Vector2(12f, 0f); component.sizeDelta = new Vector2(64f, 64f); RawImage component2 = val.GetComponent(); component2.texture = portrait; ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = false; } private static IEnumerator DelayedSaveDialogLayout(SimpleDialogBox dialog, bool confirmLayout = false) { yield return null; if (confirmLayout) { ApplyConfirmDialogLayout(dialog); } else { ApplySaveDialogLayout(dialog); } } private static void ApplySaveDialogLayout(SimpleDialogBox dialog) { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) try { RectTransform buttonContainer = dialog.buttonContainer; if ((Object)(object)buttonContainer == (Object)null) { return; } AddInputLegend(dialog); LayoutGroup[] components = ((Component)buttonContainer).GetComponents(); foreach (LayoutGroup obj in components) { ((Behaviour)obj).enabled = false; Object.DestroyImmediate((Object)(object)obj, true); } VerticalLayoutGroup obj2 = ((Component)buttonContainer).gameObject.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 8f; ((LayoutGroup)obj2).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; for (int j = 0; j < ((Transform)buttonContainer).childCount; j++) { Transform child = ((Transform)buttonContainer).GetChild(j); if ((Object)(object)((Component)child).GetComponent() != (Object)null) { ConfigureInputLegendLayout(child); continue; } float num = (((Object)(object)((Component)child).GetComponent() != (Object)null) ? 52f : 86f); RectTransform component = ((Component)child).GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(640f, num); } SetLayoutElement(((Component)child).gameObject, 640f, num); } ContentSizeFitter obj3 = ((Component)buttonContainer).GetComponent() ?? ((Component)buttonContainer).gameObject.AddComponent(); obj3.verticalFit = (FitMode)2; obj3.horizontalFit = (FitMode)2; WrapSaveDialogNavigation(buttonContainer); LayoutRebuilder.ForceRebuildLayoutImmediate(buttonContainer); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to apply save selection layout"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } private static void ApplyConfirmDialogLayout(SimpleDialogBox dialog) { //IL_00eb: Unknown result type (might be due to invalid IL or missing references) try { RectTransform buttonContainer = dialog.buttonContainer; if ((Object)(object)buttonContainer == (Object)null) { return; } AddInputLegend(dialog); LayoutGroup[] components = ((Component)buttonContainer).GetComponents(); foreach (LayoutGroup obj in components) { ((Behaviour)obj).enabled = false; Object.DestroyImmediate((Object)(object)obj, true); } List list = (from button in ((Component)buttonContainer).GetComponentsInChildren(true) where (Object)(object)((Component)button).GetComponentInParent() == (Object)null select ((Component)button).transform).Distinct().ToList(); Transform obj2 = ((Transform)buttonContainer).Find("[CENI] Confirm Button Row"); RectTransform val = (RectTransform)(object)((obj2 is RectTransform) ? obj2 : null); if ((Object)(object)val == (Object)null) { val = new GameObject("[CENI] Confirm Button Row", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }).GetComponent(); ((Transform)val).SetParent((Transform)(object)buttonContainer, false); ((Transform)val).SetSiblingIndex(0); } SetCenteredRect(val, 640f, 56f); foreach (Transform item in list) { item.SetParent((Transform)(object)val, false); } HorizontalLayoutGroup component = ((Component)val).GetComponent(); ((HorizontalOrVerticalLayoutGroup)component).spacing = 96f; ((LayoutGroup)component).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)component).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false; SetLayoutElement(((Component)val).gameObject, 640f, 56f); foreach (Transform item2 in list) { RectTransform component2 = ((Component)item2).GetComponent(); if ((Object)(object)component2 != (Object)null) { SetCenteredRect(component2, 230f, 48f); } SetLayoutElement(((Component)item2).gameObject, 230f, 48f); } VerticalLayoutGroup obj3 = ((Component)buttonContainer).gameObject.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 8f; ((LayoutGroup)obj3).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ConfigureInputLegendLayout(((Transform)buttonContainer).Find("[CENI] Save Input Legend")); ContentSizeFitter obj4 = ((Component)buttonContainer).GetComponent() ?? ((Component)buttonContainer).gameObject.AddComponent(); obj4.verticalFit = (FitMode)2; obj4.horizontalFit = (FitMode)2; WrapSaveDialogNavigation(buttonContainer); LayoutRebuilder.ForceRebuildLayoutImmediate(buttonContainer); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to apply delete confirmation layout"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } private static void WrapSaveDialogNavigation(RectTransform container) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) List list = (from button in ((Component)container).GetComponentsInChildren() where (Object)(object)((Component)button).GetComponentInParent() == (Object)null select button).ToList(); if (list.Count != 0) { for (int num = 0; num < list.Count; num++) { Navigation val = default(Navigation); ((Navigation)(ref val)).mode = (Mode)4; Navigation navigation = val; ((Navigation)(ref navigation)).selectOnUp = (Selectable)(object)list[(num - 1 + list.Count) % list.Count]; ((Navigation)(ref navigation)).selectOnDown = (Selectable)(object)list[(num + 1) % list.Count]; ((Navigation)(ref navigation)).selectOnLeft = ((Navigation)(ref navigation)).selectOnUp; ((Navigation)(ref navigation)).selectOnRight = ((Navigation)(ref navigation)).selectOnDown; ((Selectable)list[num]).navigation = navigation; } } } private static void AddInputLegend(SimpleDialogBox dialog) { //IL_005c: 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_007b: 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_0090: 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_00b1: Expected O, but got Unknown RectTransform val = dialog?.buttonContainer; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Transform)val).Find("[CENI] Save Input Legend") != (Object)null)) { GameObject val2 = new GameObject("[CENI] Save Input Legend", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(SaveDialogInputLegendController) }); RectTransform component = val2.GetComponent(); ((Transform)component).SetParent((Transform)(object)val, false); component.sizeDelta = new Vector2(640f, 42f); ConfigureInputLegendLayout(val2.transform); HorizontalLayoutGroup component2 = val2.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 74f; ((LayoutGroup)component2).padding = new RectOffset(10, 0, 8, 0); ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; SaveDialogInputLegendController component3 = val2.GetComponent(); ref MPEventSystem eventSystem = ref component3.eventSystem; EventSystem current = EventSystem.current; eventSystem = (MPEventSystem)(object)((current is MPEventSystem) ? current : null); component3.selectGlyph = AddLegendItem(component, "UISubmit", LanguageConsts.PROPER_SAVE_MOUSE_SELECT_HINT, LanguageConsts.PROPER_SAVE_SELECT_HINT); component3.backGlyph = AddLegendItem(component, "UICancel", LanguageConsts.PROPER_SAVE_ESC_HINT, LanguageConsts.PROPER_SAVE_BACK_HINT); } } private static void ConfigureInputLegendLayout(Transform legend) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)legend == (Object)null)) { RectTransform component = ((Component)legend).GetComponent(); if ((Object)(object)component != (Object)null) { component.sizeDelta = new Vector2(640f, 42f); } SetLayoutElement(((Component)legend).gameObject, 640f, 42f); } } private static InputBindingDisplayController AddLegendItem(RectTransform parent, string actionName, string keyToken, string textToken) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: 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_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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: 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) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(actionName + " Legend", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)parent, false); component.sizeDelta = new Vector2(260f, 30f); HorizontalLayoutGroup component2 = val.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 7f; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; ConfigureLayoutElement(val.GetComponent(), 260f, 30f); GameObject val2 = new GameObject("Glyph", new Type[1] { typeof(RectTransform) }); val2.SetActive(false); RectTransform component3 = val2.GetComponent(); ((Transform)component3).SetParent((Transform)(object)component, false); component3.sizeDelta = new Vector2(28f, 28f); HGTextMeshProUGUI obj = val2.AddComponent(); ((TMP_Text)obj).fontSize = 18f; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; InputBindingDisplayController val3 = val2.AddComponent(); val3.actionName = actionName; val3.useExplicitInputSource = true; val3.explicitInputSource = (InputSource)1; val2.SetActive(true); GameObject val4 = new GameObject("KeyFallback", new Type[1] { typeof(RectTransform) }); val4.SetActive(false); RectTransform component4 = val4.GetComponent(); ((Transform)component4).SetParent((Transform)(object)component, false); component4.sizeDelta = new Vector2(160f, 28f); HGTextMeshProUGUI obj2 = val4.AddComponent(); ((TMP_Text)obj2).fontSize = 14f; ((TMP_Text)obj2).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj2).enableWordWrapping = false; val4.AddComponent().token = keyToken; val4.SetActive(true); GameObject val5 = new GameObject("Label", new Type[1] { typeof(RectTransform) }); val5.SetActive(false); RectTransform component5 = val5.GetComponent(); ((Transform)component5).SetParent((Transform)(object)component, false); component5.sizeDelta = new Vector2(90f, 28f); HGTextMeshProUGUI obj3 = val5.AddComponent(); ((TMP_Text)obj3).fontSize = 14f; ((TMP_Text)obj3).alignment = (TextAlignmentOptions)4097; ((TMP_Text)obj3).enableWordWrapping = false; val5.AddComponent().token = textToken; val5.SetActive(true); return val3; } private static SaveDialogCloseWatcher AddCloseWatcher(SimpleDialogBox dialog, Action onCancel = null) { SaveDialogCloseWatcher saveDialogCloseWatcher = GetDialogRoot(dialog).AddComponent(); saveDialogCloseWatcher.dialog = dialog; saveDialogCloseWatcher.onCancel = onCancel; return saveDialogCloseWatcher; } private static GameObject GetDialogRoot(SimpleDialogBox dialog) { if (!((Object)(object)dialog.rootObject != (Object)null)) { return ((Component)dialog).gameObject; } return dialog.rootObject; } private static void SetCenteredRect(RectTransform rect, float width, float height) { //IL_000b: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = new Vector2(0.5f, 0.5f); rect.anchorMax = new Vector2(0.5f, 0.5f); rect.pivot = new Vector2(0.5f, 0.5f); rect.anchoredPosition = Vector2.zero; rect.sizeDelta = new Vector2(width, height); } private static void SetLayoutElement(GameObject target, float width, float height) { ConfigureLayoutElement(target.GetComponent() ?? target.AddComponent(), width, height); } private static void ConfigureLayoutElement(LayoutElement element, float width, float height) { element.minWidth = width; element.preferredWidth = width; element.minHeight = height; element.preferredHeight = height; element.flexibleWidth = 0f; element.flexibleHeight = 0f; } private static void MarkLastButtonCompact(SimpleDialogBox dialog) { RectTransform val = dialog?.buttonContainer; if (!((Object)(object)val == (Object)null) && ((Transform)val).childCount != 0) { Transform child = ((Transform)val).GetChild(((Transform)val).childCount - 1); if ((Object)(object)((Component)child).GetComponent() == (Object)null) { ((Component)child).gameObject.AddComponent(); } } } } 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); } } [BepInPlugin("com.Jaosnake.CENI", "C.E.N.I", "1.0.0")] public class ProperSavePlugin : BaseUnityPlugin { public const string GUID = "com.Jaosnake.CENI"; public const string Name = "C.E.N.I"; public const string Version = "1.0.0"; internal const int MaxSaveSlotsPerCharacter = 5; 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 = 1; 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(); public Dictionary ModdedData { 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); } } } ModdedData = dictionary.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)ModdedData[key].Value; } internal static SaveFile Read(BinaryReader reader) { SaveFile saveFile = new SaveFile(); 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 }; saveFile.ArtifactsData = ProperSave.SaveData.ArtifactsData.Read(context); saveFile.RunData = ProperSave.SaveData.RunData.Read(context); saveFile.RunArtifactsData = ProperSave.SaveData.RunArtifactsData.Read(context); saveFile.TeamData = ProperSave.SaveData.TeamData.Read(context); int num = reader.ReadInt32(); for (int j = 0; j < num; j++) { saveFile.PlayersData.Add(ProperSave.SaveData.PlayerData.Read(context)); } saveFile.ModdedData = ReadModdedData(context); reader.BaseStream.Seek(position2, SeekOrigin.Begin); return saveFile; } private static Dictionary ReadModdedData(ReaderContext context) { return context.Reader.ReadString().FromJson>(); } internal void Write(BinaryWriter writer, bool resilient) { WriterContext writerContext = new WriterContext { Writer = writer, SharedStrings = new List(), Resilient = resilient }; writer.Write(currentVersion); writer.Write(resilient); long position = writer.BaseStream.Position; writer.Write(0L); ArtifactsData.Write(writerContext); RunData.Write(writerContext); RunArtifactsData.Write(writerContext); TeamData.Write(writerContext); writer.Write(PlayersData.Count); for (int i = 0; i < PlayersData.Count; i++) { PlayersData[i].Write(writerContext); } WriteModdedData(writerContext); 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); } private void WriteModdedData(WriterContext context) { context.Writer.Write(ModdedData.ToJson()); } } 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_009a: 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) WriterContext writerContext = new WriterContext { Writer = writer, SharedStrings = new List(), 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) { return GetCurrentLobbySaveMetadatas(exceptUser).FirstOrDefault(); } internal static List GetCurrentLobbySaveMetadatas(NetworkUser exceptUser = null) { try { if (!TryGetCurrentLobbyIdentity(exceptUser, out var users, out var bodies, out var profile, out var gameMode)) { return new List(); } return (from el in SavesMetadata where IsSameSaveGroup(el, users, bodies, profile, gameMode) orderby el.Header.StageClearCount descending, el.Header.Time descending, el.Header.SaveDate descending select el).Take(5).ToList(); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Couldn't get save metadata for current lobby"); ProperSavePlugin.InstanceLogger.LogError((object)ex.ToString()); return new List(); } } internal static void PruneCurrentSaveGroup(SaveFileMetadata keepMetadata) { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (keepMetadata?.Header == null) { return; } HashSet keep = (from el in SavesMetadata where IsSameSaveGroup(el, keepMetadata) orderby el.Header.SaveDate descending select el).Take(5).ToHashSet(); foreach (SaveFileMetadata item in SavesMetadata.Where((SaveFileMetadata el) => IsSameSaveGroup(el, keepMetadata) && !keep.Contains(el)).ToList()) { try { if (item.FilePath.HasValue && ProperSavePlugin.SavesFileSystem.FileExists(item.FilePath.Value)) { ProperSavePlugin.SavesFileSystem.DeleteFile(item.FilePath.Value); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Failed to delete old save file \"" + item.FileName + "\"")); ProperSavePlugin.InstanceLogger.LogError((object)ex); } SavesMetadata.Remove(item); } } internal static bool DeleteSave(SaveFileMetadata metadata) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (metadata == null) { return false; } try { if (metadata.FilePath.HasValue && ProperSavePlugin.SavesFileSystem.FileExists(metadata.FilePath.Value)) { ProperSavePlugin.SavesFileSystem.DeleteFile(metadata.FilePath.Value); } SavesMetadata.Remove(metadata); if (ProperSavePlugin.CurrentSave == metadata) { ProperSavePlugin.CurrentSave = null; } return true; } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Failed to delete save file \"" + metadata.FileName + "\"")); ProperSavePlugin.InstanceLogger.LogError((object)ex); return false; } } private static bool TryGetCurrentLobbyIdentity(NetworkUser exceptUser, out List users, out List bodies, out string profile, out GameModeIndex gameMode) { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Expected I4, but got Unknown //IL_00a9: 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) users = NetworkUser.readOnlyInstancesList.Select((NetworkUser el) => el.id).ToList(); bodies = (from el in PlayerCharacterMasterController.instances select (BodyIndex)((!Object.op_Implicit((Object)(object)el.master?.bodyPrefab)) ? ((BodyIndex)(-1)) : (((??)el.master.bodyPrefab.GetComponent()?.bodyIndex) ?? (-1))) into el where (int)el != -1 select el).ToList(); profile = null; 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 ((Object)(object)exceptUser != (Object)null) { users.Remove(exceptUser.id); } if (users.Count == 0 || (int)gameMode == -1) { return false; } if (users.Count == 1 && LocalUserManager.readOnlyLocalUsersList.Count > 0) { profile = Path.GetFileNameWithoutExtension(LocalUserManager.readOnlyLocalUsersList[0].userProfile.fileName); } return true; } private static bool IsSameSaveGroup(SaveFileMetadata metadata, List users, List bodies, string profile, GameModeIndex gameMode) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (metadata?.Header == null || metadata.Header.Users == null) { return false; } if (metadata.Header.Users.Length != users.Count || metadata.Header.GameMode != gameMode) { return false; } if (users.Count == 1) { if (metadata.Header.UserProfileId == profile && metadata.Header.Users.Length == 1) { if (bodies.Count != 0) { return metadata.Header.Users[0].Body == bodies[0]; } return true; } return false; } if (users.DifferenceCount(metadata.Header.Users.Select((HeaderUserData e) => (e?.UserId?.Load()).GetValueOrDefault())) == 0) { if (bodies.Count != 0) { return bodies.DifferenceCount(metadata.Header.Users.Select((HeaderUserData e) => (BodyIndex)(((??)e?.Body) ?? (-1)))) == 0; } return true; } return false; } private static bool IsSameSaveGroup(SaveFileMetadata left, SaveFileMetadata right) { //IL_0024: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (left?.Header == null || right?.Header == null) { return false; } if (left.Header.GameMode != right.Header.GameMode || left.Header.Users.Length != right.Header.Users.Length) { return false; } if (left.Header.Users.Length == 1) { if (left.Header.UserProfileId == right.Header.UserProfileId) { return left.Header.Users[0].Body == right.Header.Users[0].Body; } return false; } if (left.Header.Users.Select((HeaderUserData e) => (e?.UserId?.Load()).GetValueOrDefault()).DifferenceCount(right.Header.Users.Select((HeaderUserData e) => (e?.UserId?.Load()).GetValueOrDefault())) == 0) { return left.Header.Users.Select((HeaderUserData e) => (BodyIndex)(((??)e?.Body) ?? (-1))).DifferenceCount(right.Header.Users.Select((HeaderUserData e) => (BodyIndex)(((??)e?.Body) ?? (-1)))) == 0; } return false; } 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 { private class QuitCancelWatcher : MonoBehaviour { public SimpleDialogBox dialog; private float delay = 0.25f; private bool closing; private void Update() { if (!closing) { delay -= Time.unscaledDeltaTime; if (!(delay > 0f) && (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown((KeyCode)331))) { closing = true; Object.Destroy((Object)(object)(((Object)(object)dialog.rootObject != (Object)null) ? dialog.rootObject : ((Component)dialog).gameObject)); } } } } 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) { try { ProperSavePlugin.CurrentSave = null; } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to clear current save state"); 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //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) //IL_0064: Expected O, but got Unknown SaveFileMetadata saveFileMetadata = new SaveFileMetadata { FileName = null }; saveFileMetadata.FillMetadataForCurrentLobby(); try { saveFileMetadata.Write(ProperSavePlugin.Resilient.Value); ProperSavePlugin.CurrentSave = saveFileMetadata; SaveFileMetadata.Replace(saveFileMetadata, null); SaveFileMetadata.PruneCurrentSaveGroup(saveFileMetadata); 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); } } 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) { AddQuitCancelWatcher(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); } } private static void AddQuitCancelWatcher(SimpleDialogBox simpleDialogBox) { GameObject val = (((Object)(object)simpleDialogBox.rootObject != (Object)null) ? simpleDialogBox.rootObject : ((Component)simpleDialogBox).gameObject); if (!((Object)(object)val.GetComponent() != (Object)null)) { val.AddComponent().dialog = simpleDialogBox; } } } } 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); } } public class ReaderContext { public BinaryReader Reader { get; set; } public string[] SharedStrings { 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; DifficultyIndex val = CatalogHelpers.FindDifficultyIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find difficulty \"" + text + "\" 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 text = context.SharedStrings[sharedIndex]; RuleDef val = RuleCatalog.FindRuleDef(text); if (val == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find rule \"" + text + "\" 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_0046: 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 text = context.SharedStrings[sharedIndex]; ArtifactDef val = ArtifactCatalog.FindArtifactDef(text); if ((Object)(object)val == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find artifact \"" + text + "\" 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; BodyIndex val = BodyCatalog.FindBodyIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find body \"" + text + "\" 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 text = context.SharedStrings[sharedIndex]; StatDef val = StatDef.Find(text); if (val == null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find stat \"" + text + "\" 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_0046: 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 text = context.SharedStrings[sharedIndex]; UnlockableDef unlockableDef = UnlockableCatalog.GetUnlockableDef(text); if ((Object)(object)unlockableDef == (Object)null) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find unlockable \"" + text + "\" 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_0023: 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_0029: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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 text = context.SharedStrings[sharedIndex]; MasterIndex val = MasterCatalog.FindMasterIndex(text); if (val == MasterIndex.none) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find master \"" + text + "\" 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; ItemIndex val = ItemCatalog.FindItemIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find item \"" + text + "\" 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; EquipmentIndex val = EquipmentCatalog.FindEquipmentIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find equipment \"" + text + "\" 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; DroneIndex val = CatalogHelpers.FindDroneIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find drone \"" + text + "\" 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_0019: Unknown result type (might be due to invalid IL or missing references) if (sharedIndex == -1) { return 0u; } if (!context.Resilient) { return (uint)sharedIndex; } string text = context.SharedStrings[sharedIndex]; SkinDef[] bodySkinDefs = SkinCatalog.GetBodySkinDefs(bodyIndex); for (uint num = 0u; num < bodySkinDefs.Length; num++) { if (((Object)bodySkinDefs[num]).name == text) { return num; } } ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find skin \"" + text + "\" 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_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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0040: 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 text = context.SharedStrings[sharedIndex]; GameModeIndex val = GameModeCatalog.FindGameModeIndex(text); if ((int)val == -1) { ProperSavePlugin.InstanceLogger.LogWarning((object)("Couldn't find game mode \"" + text + "\" 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[sharedIndex]; } } public class WriterContext { public BinaryWriter Writer { get; set; } public List SharedStrings { get; set; } 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_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) MinionData minionData = new MinionData(); BinaryReader reader = context.Reader; minionData.masterIndex = SharedIndexHelpers.ResolveMaster(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.Write(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_0072: 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_00ac: Unknown result type (might be due to invalid IL or missing references) PlayerData playerData = new PlayerData(); BinaryReader reader = context.Reader; playerData.userId = ProperSave.Data.UserIDData.Read(context); int num = reader.ReadInt32(); playerData.statsFields = new List(num); for (int i = 0; i < num; i++) { playerData.statsFields.Add(StatFieldData.Read(context)); } int num2 = reader.ReadInt32(); playerData.statsUnlockables = new List(num2); for (int j = 0; j < num2; j++) { playerData.statsUnlockables.Add(SharedIndexHelpers.ResolveUnlockable(reader.ReadInt32(), context)); } playerData.lunarCoins = reader.ReadUInt32(); playerData.lunarCoinChanceMultiplier = reader.ReadSingle(); playerData.preferredBodyIndex = SharedIndexHelpers.ResolveBody(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.Write(statsFields.Count); for (int i = 0; i < statsFields.Count; i++) { statsFields[i].Write(context); } writer.Write(statsUnlockables.Count); for (int j = 0; j < statsUnlockables.Count; j++) { writer.Write(SharedIndexHelpers.FromUnlockable(statsUnlockables[j], context)); } writer.Write(lunarCoins); writer.Write(lunarCoinChanceMultiplier); writer.Write(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_0031: Unknown result type (might be due to invalid IL or missing references) RunArtifactsData runArtifactsData = new RunArtifactsData(); BinaryReader reader = context.Reader; int num = reader.ReadInt32(); runArtifactsData.artifacts = new List(num); for (int i = 0; i < num; i++) { runArtifactsData.artifacts.Add(SharedIndexHelpers.ResolveArtifact(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.Write(artifacts.Count); for (int i = 0; i < artifacts.Count; i++) { writer.Write(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_022f: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0251: 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 MulticastDelegate multicastDelegate && (object)multicastDelegate != null) { Delegate[] invocationList = multicastDelegate.GetInvocationList(); foreach (Delegate obj in invocationList) { obj.Method.Invoke(obj.Target, new object[1] { instance }); } } instance.fixedTime = fixedTime; instance.time = time; instance.runStopwatch = new RunStopwatch { offsetFromFixedTime = offsetFromFixedTime, isPaused = isPaused }; } internal static RunData Read(ReaderContext context) { //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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) RunData runData = new RunData(); BinaryReader reader = context.Reader; runData.seed = reader.ReadUInt64(); runData.difficultyIndex = SharedIndexHelpers.ResolveDifficulty(reader.ReadInt32(), context); runData.fixedTime = reader.ReadSingle(); runData.time = reader.ReadSingle(); runData.isPaused = reader.ReadBoolean(); runData.offsetFromFixedTime = reader.ReadSingle(); runData.stageClearCount = reader.ReadInt32(); runData.stageClearCountAtLoopStart = reader.ReadInt32(); runData.loopClearCount = reader.ReadInt32(); runData.sceneName = reader.ReadString(); runData.nextSceneName = reader.ReadString(); runData.previousSceneName = reader.ReadString(); runData.prestigeArtifactMountainValue = 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 = reader.ReadInt32(); runData.eventFlags = new string[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(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.Write(SharedIndexHelpers.FromDifficulty(difficultyIndex, context)); writer.Write(fixedTime); writer.Write(time); writer.Write(isPaused); writer.Write(offsetFromFixedTime); writer.Write(stageClearCount); writer.Write(stageClearCountAtLoopStart); writer.Write(loopClearCount); writer.Write(sceneName); writer.Write(nextSceneName); writer.Write(previousSceneName); writer.Write(prestigeArtifactMountainValue); itemMask.Write(context); equipmentMask.Write(context); droneMask.Write(context); writer.Write(shopPortalCount); writer.Write(eventFlags.Length); for (int i = 0; i < eventFlags.Length; i++) { writer.Write(eventFlags[i]); } runRng.Write(context); writer.Write(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) { return new TeamData { experience = context.Reader.ReadInt64() }; } internal void Write(WriterContext context) { context.Writer.Write(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; infiniteTowerTypedRunData.waveIndex = 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 = 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.Write(waveIndex); waveRng.Write(context); enemyItemRng.Write(context); safeWardRng.Write(context); writer.Write(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) { return new PrestigeData { mountainShrineCount = context.Reader.ReadInt32() }; } internal void Write(WriterContext context) { context.Writer.Write(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 (MemberName == 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()), 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_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) CharacterMasterData characterMasterData = new CharacterMasterData(); BinaryReader reader = context.Reader; characterMasterData.bodyIndex = SharedIndexHelpers.ResolveBody(reader.ReadInt32(), context); characterMasterData.money = reader.ReadUInt32(); characterMasterData.inventory = InventoryData.Read(context); characterMasterData.loadout = LoadoutData.Read(context); characterMasterData.voidCoins = reader.ReadUInt32(); if (reader.ReadBoolean()) { characterMasterData.cloverVoidRng = RngData.Read(context); } if (reader.ReadBoolean()) { characterMasterData.devotionInventory = InventoryData.Read(context); } characterMasterData.beadExperience = reader.ReadUInt64(); characterMasterData.numberOfBeadStatsGained = reader.ReadInt32(); characterMasterData.oldBeadLevel = reader.ReadUInt32(); characterMasterData.newBeadLevel = reader.ReadUInt32(); characterMasterData.beadXPNeededForCurrentLevel = reader.ReadUInt64(); characterMasterData.trackedFreeUnlocks = reader.ReadUInt32(); characterMasterData.trackedMissileCount = reader.ReadInt32(); characterMasterData.extraBossMissileMoneyRemainder = reader.ReadUInt32(); int num = 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.Write(SharedIndexHelpers.FromBody(bodyIndex, context)); writer.Write(money); inventory.Write(context); loadout.Write(context); writer.Write(voidCoins); writer.Write(cloverVoidRng != null); cloverVoidRng?.Write(context); writer.Write(devotionInventory != null); devotionInventory?.Write(context); writer.Write(beadExperience); writer.Write(numberOfBeadStatsGained); writer.Write(oldBeadLevel); writer.Write(newBeadLevel); writer.Write(beadXPNeededForCurrentLevel); writer.Write(trackedFreeUnlocks); writer.Write(trackedMissileCount); writer.Write(extraBossMissileMoneyRemainder); writer.Write(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_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) DevotedLemurianData devotedLemurianData = new DevotedLemurianData(); BinaryReader reader = context.Reader; devotedLemurianData.itemIndex = SharedIndexHelpers.ResolveItem(reader.ReadInt32(), context); devotedLemurianData.devotedEvolutionLevel = 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.Write(SharedIndexHelpers.FromItem(itemIndex, context)); writer.Write(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_0031: Unknown result type (might be due to invalid IL or missing references) DroneMaskData droneMaskData = new DroneMaskData(); BinaryReader reader = context.Reader; int num = reader.ReadInt32(); droneMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { droneMaskData.enabledItems.Add(SharedIndexHelpers.ResolveDrone(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.Write(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.Write(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_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) EquipmentData equipmentData = new EquipmentData(); BinaryReader reader = context.Reader; equipmentData.index = SharedIndexHelpers.ResolveEquipment(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.Write(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_0031: Unknown result type (might be due to invalid IL or missing references) EquipmentMaskData equipmentMaskData = new EquipmentMaskData(); BinaryReader reader = context.Reader; int num = reader.ReadInt32(); equipmentMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { equipmentMaskData.enabledItems.Add(SharedIndexHelpers.ResolveEquipment(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.Write(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.Write(SharedIndexHelpers.FromEquipment(enabledItems[i], context)); } } } 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; inventoryData.infusionBonus = reader.ReadUInt32(); inventoryData.equipmentDisabled = reader.ReadBoolean(); inventoryData.beadAppliedHealth = reader.ReadSingle(); inventoryData.beadAppliedShield = reader.ReadSingle(); inventoryData.beadAppliedRegen = reader.ReadSingle(); inventoryData.beadAppliedDamage = reader.ReadSingle(); int num = 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[reader.ReadInt32()][]; for (int j = 0; j < inventoryData.equipments.Length; j++) { EquipmentData[] array = (inventoryData.equipments[j] = new EquipmentData[reader.ReadInt32()]); for (int k = 0; k < array.Length; k++) { array[k] = EquipmentData.Read(context); } } inventoryData.activeEquipmentSlot = reader.ReadByte(); inventoryData.activeEquipmentSet = new byte[reader.ReadInt32()]; for (int l = 0; l < inventoryData.activeEquipmentSet.Length; l++) { inventoryData.activeEquipmentSet[l] = reader.ReadByte(); } inventoryData.lastExtraEquipmentCount = reader.ReadInt32(); return inventoryData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.Write(infusionBonus); writer.Write(equipmentDisabled); writer.Write(beadAppliedHealth); writer.Write(beadAppliedShield); writer.Write(beadAppliedRegen); writer.Write(beadAppliedDamage); writer.Write(items.Count); for (int i = 0; i < items.Count; i++) { items[i].Write(context); } writer.Write(tempStorageDecayDuration); writer.Write(tempStorageInvDecayDuration); writer.Write(equipments.Length); for (int j = 0; j < equipments.Length; j++) { EquipmentData[] array = equipments[j]; writer.Write(array.Length); for (int k = 0; k < array.Length; k++) { array[k].Write(context); } } writer.Write(activeEquipmentSlot); writer.Write(activeEquipmentSet.Length); for (int l = 0; l < activeEquipmentSet.Length; l++) { writer.Write(activeEquipmentSet[l]); } writer.Write(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_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) ItemData itemData = new ItemData(); BinaryReader reader = context.Reader; itemData.itemIndex = SharedIndexHelpers.ResolveItem(reader.ReadInt32(), context); itemData.count = reader.ReadInt32(); itemData.channeledCount = reader.ReadInt32(); itemData.tempCount = 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.Write(SharedIndexHelpers.FromItem(itemIndex, context)); writer.Write(count); writer.Write(channeledCount); writer.Write(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_0031: Unknown result type (might be due to invalid IL or missing references) ItemMaskData itemMaskData = new ItemMaskData(); BinaryReader reader = context.Reader; int num = reader.ReadInt32(); itemMaskData.enabledItems = new List(num); for (int i = 0; i < num; i++) { itemMaskData.enabledItems.Add(SharedIndexHelpers.ResolveItem(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.Write(enabledItems.Count); for (int i = 0; i < enabledItems.Count; i++) { writer.Write(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_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) LoadoutBodyData loadoutBodyData = new LoadoutBodyData(); BinaryReader reader = context.Reader; loadoutBodyData.bodyIndex = SharedIndexHelpers.ResolveBody(reader.ReadInt32(), context); loadoutBodyData.skinPreference = reader.ReadUInt32(); loadoutBodyData.skillPreferences = new uint[reader.ReadInt32()]; for (int i = 0; i < loadoutBodyData.skillPreferences.Length; i++) { loadoutBodyData.skillPreferences[i] = 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.Write(SharedIndexHelpers.FromBody(bodyIndex, context)); writer.Write(skinPreference); writer.Write(skillPreferences.Length); for (int i = 0; i < skillPreferences.Length; i++) { writer.Write(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(); int num = context.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.Write(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(); int num = context.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.Write(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; ruleValueData.index = SharedIndexHelpers.ResolveRule(reader.ReadInt32(), context); ruleValueData.value = reader.ReadByte(); return ruleValueData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.Write(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; statFieldData.index = SharedIndexHelpers.ResolveStatField(reader.ReadInt32(), context); statFieldData.value = reader.ReadUInt64(); return statFieldData; } internal void Write(WriterContext context) { BinaryWriter writer = context.Writer; writer.Write(SharedIndexHelpers.FromStatField(index, context)); writer.Write(value); } } 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; } } }