Decompiled source of ProperSave v2.11.2
plugins/ProperSave/ProperSave.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.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 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.SaveData; using ProperSave.SaveData.Artifacts; using ProperSave.SaveData.Runs; using ProperSave.TinyJson; 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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.11.2.0")] namespace PSTinyJson { public static class JSONParser { [ThreadStatic] private static Stack<List<string>> splitArrayPool; [ThreadStatic] private static StringBuilder stringBuilder; [ThreadStatic] private static Dictionary<Type, Dictionary<string, FieldInfo>> fieldInfoCache; [ThreadStatic] private static Dictionary<Type, Dictionary<string, PropertyInfo>> propertyInfoCache; public static T FromJson<T>(this string json) { return (T)json.FromJson(typeof(T)); } public static object FromJson(this string json, Type type) { if (propertyInfoCache == null) { propertyInfoCache = new Dictionary<Type, Dictionary<string, PropertyInfo>>(); } if (fieldInfoCache == null) { fieldInfoCache = new Dictionary<Type, Dictionary<string, FieldInfo>>(); } if (stringBuilder == null) { stringBuilder = new StringBuilder(); } if (splitArrayPool == null) { splitArrayPool = new Stack<List<string>>(); } 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<string> Split(string json) { List<string> list = ((splitArrayPool.Count > 0) ? splitArrayPool.Pop() : new List<string>()); 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; } } if (type.IsArray) { Type elementType = type.GetElementType(); if (json[0] != '[' || json[json.Length - 1] != ']') { return null; } List<string> 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<string> 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<string> 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<string> list = Split(json); if (list.Count % 2 != 0) { return null; } Dictionary<string, object> dictionary = new Dictionary<string, object>(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<string> list2 = Split(json); List<object> list3 = new List<object>(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<string, T> CreateMemberNameDictionary<T>(T[] members) where T : MemberInfo { Dictionary<string, T> dictionary = new Dictionary<string, T>(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<string> 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<DiscoverObjectTypeAttribute>(); value3.SetValue(uninitializedObject, ParseValue(customAttribute?.GetObjectType(uninitializedObject) ?? value3.FieldType, json2)); } else if (value2.TryGetValue(key, out value4)) { DiscoverObjectTypeAttribute customAttribute2 = value4.GetCustomAttribute<DiscoverObjectTypeAttribute>(); 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<T>(this IEnumerable<T> collection, IEnumerable<T> second) { List<T> list = second.ToList(); int num = 0; foreach (T item in collection) { if (!list.Remove(item)) { num++; } } return num + list.Count; } } 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 class Loading { private static bool isLoading; public static bool IsLoading { get { return isLoading; } private 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; public static event Action<SaveFile> OnLoadingStarted; public static event Action<SaveFile> 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) { ProperSavePlugin.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<bool>>((Func<bool>)delegate { FirstRunStage = true; if (IsLoading) { CurrentSave.LoadRun(); CurrentSave.LoadArtifacts(); CurrentSave.LoadPlayers(); } else { ProperSavePlugin.CurrentSave = null; } return IsLoading; }); val.Emit(OpCodes.Brfalse, val.Next); val.Emit(OpCodes.Ret); } internal static IEnumerator LoadLobby() { if ((Object)(object)PreGameController.instance == (Object)null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"PreGameController instance not found"); yield break; } NetworkManagerSystem singleton = NetworkManagerSystem.singleton; if (singleton != null && singleton.desiredHost.hostingParameters.listen && !PlatformSystems.lobbyManager.ownsLobby) { ProperSavePlugin.InstanceLogger.LogInfo((object)"You must be a lobby leader to load the game"); yield break; } SaveFileMetadata currentLobbySaveMetadata = SaveFileMetadata.GetCurrentLobbySaveMetadata(); if (currentLobbySaveMetadata == null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Save file for current users is not found"); yield break; } UPath? filePath = currentLobbySaveMetadata.FilePath; if (!filePath.HasValue) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Metadata doesn't contain file name for the save file"); yield break; } if (!ProperSavePlugin.SavesFileSystem.FileExists(filePath.Value)) { ProperSavePlugin.InstanceLogger.LogInfo((object)$"File \"{filePath}\" is not found"); yield break; } ProperSavePlugin.CurrentSave = FileSystemExtensions.ReadAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, filePath.Value).FromJson<SaveFile>(); ProperSavePlugin.CurrentSave.SaveFileMeta = currentLobbySaveMetadata; IsLoading = true; if (ProperSavePlugin.CurrentSave.ContentHash != null && ProperSavePlugin.CurrentSave.ContentHash != ProperSavePlugin.ContentHash) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Loading run but content mismatch detected which may result in errors"); } PreGameController.instance.StartRun(); } } internal static class LobbyUI { private static GameObject lobbyButton; private static GameObject lobbySubmenuLegend; private static GameObject lobbyGlyphAndDescription; private static TooltipProvider tooltipProvider; private static GamepadTooltipProvider gamepadTooltipProvider; 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, gameObject.transform.parent); InputSourceFilter[] components = ((Component)self).GetComponents<InputSourceFilter>(); foreach (InputSourceFilter val in components) { if ((int)val.requiredInputSource == 0) { Array.Resize(ref val.objectsToFilter, val.objectsToFilter.Length + 1); val.objectsToFilter[val.objectsToFilter.Length - 1] = lobbyButton; break; } } ((Object)lobbyButton).name = "[ProperSave] Load"; tooltipProvider = lobbyButton.AddComponent<TooltipProvider>(); RectTransform component = lobbyButton.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 1.5f); component.anchorMax = new Vector2(1f, 1.5f); HGButton component2 = lobbyButton.GetComponent<HGButton>(); component2.hoverToken = LanguageConsts.PROPER_SAVE_TITLE_CONTINUE_DESC; lobbyButton.GetComponent<LanguageTextMeshController>().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<GameObject>(gameObject2, gameObject2.transform.parent); components = ((Component)self).GetComponents<InputSourceFilter>(); foreach (InputSourceFilter val2 in components) { if ((int)val2.requiredInputSource == 1) { Array.Resize(ref val2.objectsToFilter, val2.objectsToFilter.Length + 1); val2.objectsToFilter[val2.objectsToFilter.Length - 1] = lobbySubmenuLegend; break; } } ((Object)lobbySubmenuLegend).name = "[ProperSave] SubmenuLegend"; UIJuice component3 = lobbySubmenuLegend.GetComponent<UIJuice>(); OnEnableEvent component4 = lobbySubmenuLegend.GetComponent<OnEnableEvent>(); ((UnityEventBase)component4.action).RemoveAllListeners(); component4.action.AddListener(new UnityAction(component3.TransitionPanFromTop)); component4.action.AddListener(new UnityAction(component3.TransitionAlphaFadeIn)); RectTransform component5 = lobbySubmenuLegend.GetComponent<RectTransform>(); 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<InputBindingDisplayController>(); component6.actionName = "UISubmitTertiary"; Transform child = lobbyGlyphAndDescription.transform.GetChild(1); LanguageTextMeshController component7 = ((Component)lobbyGlyphAndDescription.transform.GetChild(2)).GetComponent<LanguageTextMeshController>(); 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<HoldGamepadInputEvent>(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionName = "UISubmitTertiary"; ((HGGamepadInputEvent)holdGamepadInputEvent).enabledObjectsIfActive = Array.Empty<GameObject>(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionEvent = new UnityEvent(); ((HGGamepadInputEvent)holdGamepadInputEvent).actionEvent.AddListener(new UnityAction(LoadOnInputEvent)); gamepadTooltipProvider = ((Component)component6).gameObject.AddComponent<GamepadTooltipProvider>(); gamepadTooltipProvider.inputEvent = holdGamepadInputEvent; UpdateLobbyControls(); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed while adding lobby buttons"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } orig.Invoke(self); } private static void LoadOnInputEvent() { if ((Object)(object)Run.instance != (Object)null) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Can't load while run is active"); } else if (Loading.IsLoading) { ProperSavePlugin.InstanceLogger.LogInfo((object)"Already loading"); } else { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(Loading.LoadLobby()); } } private static void UpdateLobbyControls(NetworkUser exceptUser = null) { //IL_004e: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_0156: 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); TooltipContent content = default(TooltipContent); try { if (currentLobbySaveMetadata != null) { TooltipContent val = default(TooltipContent); val.titleToken = LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_TITLE; val.overrideBodyText = GetSaveDescription(currentLobbySaveMetadata); val.titleColor = Color.black; val.disableBodyRichText = false; content = val; } } 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<HGButton>(); if (Object.op_Implicit((Object)(object)component)) { ((Selectable)component).interactable = flag; } } if (Object.op_Implicit((Object)(object)tooltipProvider)) { tooltipProvider.SetContent(content); } } 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<HGTextMeshProUGUI>()).color = color; ((Graphic)((Component)lobbyGlyphAndDescription.transform.GetChild(1)).GetComponent<HGTextMeshProUGUI>()).color = color; } if (Object.op_Implicit((Object)(object)gamepadTooltipProvider)) { ((TooltipProvider)gamepadTooltipProvider).SetContent(content); } } catch { } } private static string GetSaveDescription(SaveFileMetadata saveMetadata) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) SaveFile saveFile = FileSystemExtensions.ReadAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, saveMetadata.FilePath.Value).FromJson<SaveFile>(); StringBuilder stringBuilder = new StringBuilder(); foreach (PlayerData playerData in saveFile.PlayersData) { NetworkUser val = ((IEnumerable<NetworkUser>)NetworkUser.readOnlyInstancesList).FirstOrDefault((Func<NetworkUser, bool>)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 = playerData.userId.Load(); return ((NetworkUserId)(ref val3)).Equals(user.id); }); SurvivorDef val2 = SurvivorCatalog.FindSurvivorDefFromBody(BodyCatalog.FindBodyPrefab(playerData.master.bodyName)); 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(saveFile.RunData.sceneName); DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef((DifficultyIndex)saveFile.RunData.difficulty); int num = (saveFile.RunData.isPaused ? ((int)saveFile.RunData.offsetFromFixedTime) : ((int)(saveFile.RunData.fixedTime + saveFile.RunData.offsetFromFixedTime))); 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) : "", (saveFile.RunData.stageClearCount + 1).ToString(), $"{num / 60:00}:{num % 60:00}", (difficultyDef != null) ? Language.GetString(difficultyDef.nameToken) : "", (saveFile.ContentHash != null && saveFile.ContentHash != ProperSavePlugin.ContentHash) ? Language.GetString(LanguageConsts.PROPER_SAVE_TOOLTIP_LOAD_CONTENT_MISMATCH) : "" }); } } internal class LostNetworkUser : MonoBehaviour { private static readonly Dictionary<CharacterMaster, LostNetworkUser> lostUsers = new Dictionary<CharacterMaster, LostNetworkUser>(); private CharacterMaster master; public uint lunarCoins; public NetworkUserId userID; private void Awake() { master = ((Component)this).GetComponent<CharacterMaster>(); 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)networkUser.master)) { LostNetworkUser lostNetworkUser = ((Component)networkUser.master).gameObject.AddComponent<LostNetworkUser>(); lostNetworkUser.lunarCoins = networkUser.lunarCoins; lostNetworkUser.userID = networkUser.id; } } } internal static class ModSupport { 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; } private static Dictionary<MethodInfo, Action<ILContext>> RegisteredILHooks { get; } = new Dictionary<MethodInfo, Action<ILContext>>(); public static void GatherLoadedPlugins() { IsBBLoaded = Chainloader.PluginInfos.ContainsKey("com.MagnusMagnuson.BiggerBazaar"); IsSSLoaded = Chainloader.PluginInfos.ContainsKey("com.funkfrog_sipondo.sharesuite"); } public static void RegisterHooks() { if (IsBBLoaded = Chainloader.PluginInfos.ContainsKey("com.MagnusMagnuson.BiggerBazaar")) { 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<MethodInfo, Action<ILContext>> 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<ILContext> 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) { if (IsSSLoaded) { ((MonoBehaviour)ProperSavePlugin.Instance).StartCoroutine(LoadShareSuiteMoneyInternal(money)); } } [MethodImpl(MethodImplOptions.NoInlining)] private static IEnumerator LoadShareSuiteMoneyInternal(uint money) { yield return (object)new WaitUntil((Func<bool>)(() => !MoneySharingHooks.MapTransitionActive)); MoneySharingHooks.SharedMoneyValue = (int)money; } public static void ShareSuiteMapTransition() { if (IsSSLoaded) { ShareSuiteMapTransionInternal(); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ShareSuiteMapTransionInternal() { MoneySharingHooks.MapTransitionActive = true; } } [BepInPlugin("com.KingEnderBrine.ProperSave", "Proper Save", "2.11.2")] public class ProperSavePlugin : BaseUnityPlugin { public const string GUID = "com.KingEnderBrine.ProperSave"; public const string Name = "Proper Save"; public const string Version = "2.11.2"; 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 SaveFile CurrentSave { get; set; } internal static string ContentHash { get; private set; } internal static ConfigEntry<bool> UseCloudStorage { get; private set; } internal static ConfigEntry<string> CloudStorageSubDirectory { get; private set; } internal static ConfigEntry<string> UserSavesDirectory { get; private set; } private void Start() { Instance = this; UseCloudStorage = ((BaseUnityPlugin)this).Config.Bind<bool>("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<string>("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<string>("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."); RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_00fb: 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) //IL_010b: 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); } } } else { 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); } SaveFileMetadata.PopulateSavesMetadata(); }); ModSupport.GatherLoadedPlugins(); ModSupport.RegisterHooks(); Saving.RegisterHooks(); Loading.RegisterHooks(); LobbyUI.RegisterHooks(); LostNetworkUser.Subscribe(); Language.collectLanguageRootFolders += CollectLanguageRootFolders; ContentManager.onContentPacksAssigned += ContentManagerOnContentPacksAssigned; } private void Destroy() { Instance = null; ModSupport.UnregisterHooks(); Saving.UnregisterHooks(); Loading.UnregisterHooks(); LobbyUI.UnregisterHooks(); LostNetworkUser.Unsubscribe(); Language.collectLanguageRootFolders -= CollectLanguageRootFolders; ContentManager.onContentPacksAssigned -= ContentManagerOnContentPacksAssigned; } public void CollectLanguageRootFolders(List<string> folders) { folders.Add(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "Language")); } private void ContentManagerOnContentPacksAssigned(ReadOnlyArray<ReadOnlyContentPack> 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) MD5 mD = MD5.Create(); StringWriter writer = new StringWriter(); try { Enumerator<ReadOnlyContentPack> enumerator = contentPacks.GetEnumerator(); try { while (enumerator.MoveNext()) { ReadOnlyContentPack current = enumerator.Current; writer.Write(((ReadOnlyContentPack)(ref current)).identifier); writer.Write(';'); WriteCollection<ArtifactDef>(((ReadOnlyContentPack)(ref current)).artifactDefs, "artifactDefs"); WriteCollection<GameObject>(((ReadOnlyContentPack)(ref current)).bodyPrefabs, "bodyPrefabs"); WriteCollection<EquipmentDef>(((ReadOnlyContentPack)(ref current)).equipmentDefs, "equipmentDefs"); WriteCollection<ExpansionDef>(((ReadOnlyContentPack)(ref current)).expansionDefs, "expansionDefs"); WriteCollection<GameObject>(((ReadOnlyContentPack)(ref current)).gameModePrefabs, "gameModePrefabs"); WriteCollection<ItemDef>(((ReadOnlyContentPack)(ref current)).itemDefs, "itemDefs"); WriteCollection<ItemTierDef>(((ReadOnlyContentPack)(ref current)).itemTierDefs, "itemTierDefs"); WriteCollection<GameObject>(((ReadOnlyContentPack)(ref current)).masterPrefabs, "masterPrefabs"); WriteCollection<SceneDef>(((ReadOnlyContentPack)(ref current)).sceneDefs, "sceneDefs"); WriteCollection<SkillDef>(((ReadOnlyContentPack)(ref current)).skillDefs, "skillDefs"); WriteCollection<SkillFamily>(((ReadOnlyContentPack)(ref current)).skillFamilies, "skillFamilies"); WriteCollection<SurvivorDef>(((ReadOnlyContentPack)(ref current)).survivorDefs, "survivorDefs"); WriteCollection<UnlockableDef>(((ReadOnlyContentPack)(ref current)).unlockableDefs, "unlockableDefs"); } } finally { ((IDisposable)enumerator).Dispose(); } ContentHash = Convert.ToBase64String(mD.ComputeHash(Encoding.UTF8.GetBytes(writer.ToString()))); } finally { if (writer != null) { ((IDisposable)writer).Dispose(); } } void WriteCollection<T>(ReadOnlyNamedAssetCollection<T> 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<T> 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).Dispose(); } } } } public class SaveFile { [DataMember(Name = "r")] public RunData RunData { get; set; } [DataMember(Name = "t")] public TeamData TeamData { get; set; } [DataMember(Name = "ra")] public RunArtifactsData RunArtifactsData { get; set; } [DataMember(Name = "a")] public ArtifactsData ArtifactsData { get; set; } [DataMember(Name = "p")] public List<PlayerData> PlayersData { get; set; } [DataMember(Name = "md")] public Dictionary<string, ModdedData> ModdedData { get; set; } [DataMember(Name = "ch")] public string ContentHash { get; set; } [IgnoreDataMember] public SaveFileMetadata SaveFileMeta { get; set; } public static event Action<Dictionary<string, object>> OnGatherSaveData; [EditorBrowsable(EditorBrowsableState.Never)] [Obsolete("Use OnGatherSaveData without a typo", true)] public static event Action<Dictionary<string, object>> OnGatgherSaveData { add { OnGatherSaveData += value; } remove { OnGatherSaveData -= value; } } internal SaveFile() { RunData = new RunData(); TeamData = new TeamData(); RunArtifactsData = new RunArtifactsData(); ArtifactsData = new ArtifactsData(); PlayersData = new List<PlayerData>(); 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(new PlayerData(instance, lostUser)); } } Dictionary<string, object> dictionary = new Dictionary<string, object>(); SaveFile.OnGatherSaveData?.Invoke(dictionary); ModdedData = dictionary.ToDictionary((KeyValuePair<string, object> el) => el.Key, (KeyValuePair<string, object> el) => new ModdedData { ObjectType = el.Value.GetType().AssemblyQualifiedName, Value = el.Value }); ContentHash = ProperSavePlugin.ContentHash; } internal void LoadRun() { RunData.LoadData(); } internal void LoadArtifacts() { RunArtifactsData.LoadData(); ArtifactsData.LoadData(); } internal void LoadTeam() { TeamData.LoadData(); } internal void LoadPlayers() { List<PlayerData> list = PlayersData.ToList(); foreach (NetworkUser user in NetworkUser.readOnlyInstancesList) { PlayerData playerData = list.FirstOrDefault(delegate(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 (playerData != null) { list.Remove(playerData); playerData.LoadPlayer(user); } } } public T GetModdedData<T>(string key) { return (T)ModdedData[key].Value; } } public class SaveFileMetadata { [CompilerGenerated] private sealed class <>c__DisplayClass22_0 { public List<NetworkUserId> users; public GameModeIndex gameMode; internal bool <GetCurrentLobbySaveMetadata>b__1(SaveFileMetadata el) { //IL_0016: 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) if (el.UserIds.Length != users.Count || el.GameMode != gameMode) { return false; } return users.DifferenceCount(el.UserIds.Select((UserIDData e) => (NetworkUserId)(((??)e?.Load()) ?? default(NetworkUserId)))) == 0; } } [DataMember(Name = "fn")] public string FileName { get; set; } [DataMember(Name = "upi")] public string UserProfileId { get; set; } [DataMember(Name = "si")] public 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")); private static List<SaveFileMetadata> SavesMetadata { get; } = new List<SaveFileMetadata>(); internal static SaveFileMetadata CreateMetadataForCurrentLobby() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) LostNetworkUser lostUser; return new SaveFileMetadata { UserIds = (from el in PlayerCharacterMasterController.instances select (!Object.op_Implicit((Object)(object)el.networkUser)) ? ((!LostNetworkUser.TryGetUser(el.master, out lostUser)) ? null : new UserIDData(lostUser.userID)) : new UserIDData(el.networkUser.id) into el where el != null select el).ToArray(), UserProfileId = LocalUserManager.readOnlyLocalUsersList[0].userProfile.fileName, GameMode = Run.instance.gameModeIndex }; } internal static SaveFileMetadata GetCurrentLobbySaveMetadata(NetworkUser exceptUser = null) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got I4 //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Invalid comparison between Unknown and I4 //IL_009b->IL009b: Incompatible stack types: O vs I4 //IL_0091->IL009b: Incompatible stack types: O vs I4 //IL_0085->IL009b: Incompatible stack types: I4 vs O //IL_0085->IL009b: Incompatible stack types: O vs I4 try { <>c__DisplayClass22_0 CS$<>8__locals0 = new <>c__DisplayClass22_0(); CS$<>8__locals0.users = NetworkUser.readOnlyInstancesList.Select((NetworkUser el) => el.id).ToList(); if ((Object)(object)exceptUser != (Object)null) { CS$<>8__locals0.users.Remove(exceptUser.id); } if (CS$<>8__locals0.users.Count == 0) { return null; } object obj = CS$<>8__locals0; int num; if (Object.op_Implicit((Object)(object)PreGameController.instance)) { obj = PreGameController.instance.gameModeIndex; num = (int)obj; } else if (Object.op_Implicit((Object)(object)Run.instance)) { obj = Run.instance.gameModeIndex; num = (int)obj; } else { num = -1; obj = num; num = (int)obj; } ((<>c__DisplayClass22_0)num).gameMode = (GameModeIndex)obj; if ((int)CS$<>8__locals0.gameMode == -1) { return null; } if (CS$<>8__locals0.users.Count == 1) { <>c__DisplayClass22_0 <>c__DisplayClass22_ = CS$<>8__locals0; string profile = LocalUserManager.readOnlyLocalUsersList[0].userProfile.fileName.Replace(".xml", ""); return SavesMetadata.FirstOrDefault(delegate(SaveFileMetadata el) { //IL_002d: 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_0041: 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_0059: Unknown result type (might be due to invalid IL or missing references) if (el.UserProfileId == profile && el.UserIds.Length == 1) { UserIDData obj2 = el.UserIds[0]; if (obj2 != null) { NetworkUserId val = obj2.Load(); if (((NetworkUserId)(ref val)).Equals(<>c__DisplayClass22_.users[0])) { return el.GameMode == <>c__DisplayClass22_.gameMode; } } } return false; }); } return SavesMetadata.FirstOrDefault((SaveFileMetadata el) => el.UserIds.Length == CS$<>8__locals0.users.Count && el.GameMode == CS$<>8__locals0.gameMode && CS$<>8__locals0.users.DifferenceCount(el.UserIds.Select((UserIDData e) => (NetworkUserId)(((??)e?.Load()) ?? default(NetworkUserId)))) == 0); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Couldn't get save metadata for current lobby"); ProperSavePlugin.InstanceLogger.LogError((object)ex.ToString()); return null; } } internal static void PopulateSavesMetadata() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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) if (!ProperSavePlugin.SavesFileSystem.DirectoryExists(ProperSavePlugin.SavesPath)) { ProperSavePlugin.SavesFileSystem.CreateDirectory(ProperSavePlugin.SavesPath); return; } UPath val = ProperSavePlugin.SavesPath / UPath.op_Implicit("SavesMetadata.json"); if (!ProperSavePlugin.SavesFileSystem.FileExists(val)) { return; } try { SaveFileMetadata[] collection = FileSystemExtensions.ReadAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, val).FromJson<SaveFileMetadata[]>(); SavesMetadata.Clear(); SavesMetadata.AddRange(collection); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"SavesMetadata file corrupted."); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } internal static void AddIfNotExists(SaveFileMetadata metadata) { if (!SavesMetadata.Contains(metadata)) { SavesMetadata.Add(metadata); UpdateSaveMetadata(); } } internal static void Remove(SaveFileMetadata metadata) { if (SavesMetadata.Remove(metadata)) { UpdateSaveMetadata(); } } private static void UpdateSaveMetadata() { //IL_0005: 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_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_0035: 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_003b: Unknown result type (might be due to invalid IL or missing references) if (!ProperSavePlugin.SavesFileSystem.DirectoryExists(ProperSavePlugin.SavesPath)) { ProperSavePlugin.SavesFileSystem.CreateDirectory(ProperSavePlugin.SavesPath); return; } UPath val = ProperSavePlugin.SavesPath / UPath.op_Implicit("SavesMetadata.json"); try { FileSystemExtensions.WriteAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, val, SavesMetadata.ToJson()); } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Can't update SavesMetadata file"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } } internal static class Saving { internal static RunRngData PreStageRng { get; private set; } internal static RngData PreStageInfiniteTowerSafeWardRng { 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.GenerateStageRNG += new hook_GenerateStageRNG(RunGenerateStageRNG); 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.GenerateStageRNG -= new hook_GenerateStageRNG(RunGenerateStageRNG); QuitConfirmationHelper.IssueQuitCommand_Action -= new Manipulator(IssueQuitCommandIL); } private static void RunGenerateStageRNG(orig_GenerateStageRNG orig, Run self) { PreStageRng = new RunRngData(Run.instance); InfiniteTowerRun val = (InfiniteTowerRun)(object)((self is InfiniteTowerRun) ? self : null); if (val != null) { PreStageInfiniteTowerSafeWardRng = new RngData(val.safeWardRng); } orig.Invoke(self); } private static void RunOnServerGameOver(Run run, GameEndingDef ending) { //IL_0033: 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) try { SaveFileMetadata saveFileMetadata = ProperSavePlugin.CurrentSave?.SaveFileMeta; if (saveFileMetadata != null && saveFileMetadata.FilePath.HasValue) { if (ProperSavePlugin.SavesFileSystem.FileExists(saveFileMetadata.FilePath.Value)) { ProperSavePlugin.SavesFileSystem.DeleteFile(saveFileMetadata.FilePath.Value); } SaveFileMetadata.Remove(saveFileMetadata); } } catch (Exception ex) { ProperSavePlugin.InstanceLogger.LogWarning((object)"Failed to delete save file"); ProperSavePlugin.InstanceLogger.LogError((object)ex); } } private static void StageOnStageStartGlobal(orig_BeginStage orig, Run self) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Invalid comparison between Unknown and I4 try { if (!NetworkServer.active) { return; } if (Loading.FirstRunStage) { Loading.FirstRunStage = false; return; } SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene(); if ((int)sceneDefForCurrentScene.sceneType != 0 && (int)sceneDefForCurrentScene.sceneType != 3) { SaveGame(); } } finally { orig.Invoke(self); } } private static void SaveGame() { //IL_005e: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Expected O, but got Unknown SaveFile saveFile = new SaveFile { SaveFileMeta = (SaveFileMetadata.GetCurrentLobbySaveMetadata() ?? SaveFileMetadata.CreateMetadataForCurrentLobby()) }; if (string.IsNullOrEmpty(saveFile.SaveFileMeta.FileName)) { do { saveFile.SaveFileMeta.FileName = Guid.NewGuid().ToString(); } while (ProperSavePlugin.SavesFileSystem.FileExists(saveFile.SaveFileMeta.FilePath.Value)); } try { string text = saveFile.ToJson(); FileSystemExtensions.WriteAllText((IFileSystem)(object)ProperSavePlugin.SavesFileSystem, saveFile.SaveFileMeta.FilePath.Value, text); ProperSavePlugin.CurrentSave = saveFile; SaveFileMetadata.AddIfNotExists(saveFile.SaveFileMeta); Chat.SendBroadcastChat((ChatMessageBase)new SimpleChatMessage { baseToken = string.Format(Language.GetString(LanguageConsts.PROPER_SAVE_CHAT_SAVE), Language.GetString(SceneCatalog.currentSceneDef.nameToken)) }); } catch (Exception ex) { 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 val3 = default(MethodReference); MethodReference val2 = default(MethodReference); string text = default(string); val.GotoNext(new Func<Instruction, bool>[4] { (Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 0), (Instruction x) => ILPatternMatchingExt.MatchLdftn(x, ref val3), (Instruction x) => ILPatternMatchingExt.MatchNewobj(x, ref val2), (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, ref text) }); val.Emit(OpCodes.Dup); val.EmitDelegate<Action<SimpleDialogBox>>((Action<SimpleDialogBox>)AddQuitText); } private static void AddQuitText(SimpleDialogBox simpleDialogBox) { if (NetworkServer.active || NetworkUser.readOnlyInstancesList.Count == NetworkUser.readOnlyLocalPlayersList.Count) { if (ProperSavePlugin.CurrentSave == null) { TextMeshProUGUI descriptionLabel = simpleDialogBox.descriptionLabel; ((TMP_Text)descriptionLabel).text = ((TMP_Text)descriptionLabel).text + Language.GetString(LanguageConsts.PROPER_SAVE_QUIT_DIALOG_NOT_SAVED); return; } if (ProperSavePlugin.CurrentSave.RunData.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.RunData.stageClearCount).ToString() }; ((TMP_Text)descriptionLabel3).text = text + Language.GetStringFormatted(pROPER_SAVE_QUIT_DIALOG_SAVED_BEFORE, array); } } } } namespace ProperSave.SaveData { public class ArtifactsData { [DataMember(Name = "ed")] public EnigmaData EnigmaData; internal ArtifactsData() { EnigmaData = new EnigmaData(); } internal void LoadData() { EnigmaData.LoadData(); } } public class MinionData { [DataMember(Name = "mi")] public int masterIndex; [DataMember(Name = "m")] public CharacterMasterData master; [DataMember(Name = "dld")] public DevotedLemurianData devotedLemurianData; internal MinionData(CharacterMaster master) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) masterIndex = (int)master.masterIndex; this.master = new CharacterMasterData(master); DevotedLemurianController controller = default(DevotedLemurianController); if (((Component)master).TryGetComponent<DevotedLemurianController>(ref controller)) { devotedLemurianData = new DevotedLemurianData(controller); } } internal void LoadMinion(CharacterMaster playerMaster) { SceneDirector.onPostPopulateSceneServer += SpawnMinion; void SpawnMinion(SceneDirector obj) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) SceneDirector.onPostPopulateSceneServer -= SpawnMinion; GameObject obj2 = Object.Instantiate<GameObject>(MasterCatalog.GetMasterPrefab((MasterIndex)masterIndex)); CharacterMaster component = obj2.GetComponent<CharacterMaster>(); 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<AIOwnership>().ownerMaster = playerMaster; obj2.GetComponent<BaseAI>().leader.gameObject = ((Component)playerMaster).gameObject; if (devotedLemurianData != null) { DevotedLemurianController component2 = ((Component)component).GetComponent<DevotedLemurianController>(); devotedLemurianData.LoadData(component2); component2._lemurianMaster = component; component2._devotionInventoryController = CharacterMasterData.GetDevotionInventoryController(playerMaster); } NetworkServer.Spawn(obj2); } } } public class PlayerData { [DataMember(Name = "si")] public 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 = "m")] public CharacterMasterData master; internal PlayerData(PlayerCharacterMasterController player, LostNetworkUser lostNetworkUser = null) { //IL_0037: 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_0099: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected I4, but got Unknown NetworkUser networkUser = player.networkUser; if ((Object)(object)lostNetworkUser != (Object)null) { userId = new UserIDData(lostNetworkUser.userID); lunarCoins = lostNetworkUser.lunarCoins; } else { userId = new UserIDData(networkUser.id); lunarCoins = networkUser.lunarCoins; } lunarCoinChanceMultiplier = player.lunarCoinChanceMultiplier; master = new CharacterMasterData(player.master); StatSheet currentStats = ((Component)player).GetComponent<PlayerStatsComponent>().currentStats; statsFields = new string[currentStats.fields.Length]; for (int i = 0; i < currentStats.fields.Length; i++) { StatField val = currentStats.fields[i]; statsFields[i] = ((object)(StatField)(ref val)).ToString(); } statsUnlockables = new int[currentStats.GetUnlockableCount()]; for (int j = 0; j < currentStats.GetUnlockableCount(); j++) { UnlockableIndex unlockableIndex = currentStats.GetUnlockableIndex(j); statsUnlockables[j] = (int)unlockableIndex; } } internal void LoadPlayer(NetworkUser player) { master.LoadMaster(player.master, delayedInventory: false); player.masterController.lunarCoinChanceMultiplier = lunarCoinChanceMultiplier; StatSheet currentStats = ((Component)player.masterController).GetComponent<PlayerStatsComponent>().currentStats; for (int i = 0; i < statsFields.Length; i++) { string text = statsFields[i]; currentStats.SetStatValueFromString(StatDef.allStatDefs[i], text); } for (int j = 0; j < statsUnlockables.Length; j++) { int num = statsUnlockables[j]; currentStats.AddUnlockable((UnlockableIndex)num); } } } public class RunArtifactsData { [DataMember(Name = "a")] public bool[] artifacts; internal RunArtifactsData() { //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_0032: Unknown result type (might be due to invalid IL or missing references) artifacts = new bool[ArtifactCatalog.artifactCount]; RunEnabledArtifacts enumerator = RunArtifactManager.enabledArtifactsEnumerable.GetEnumerator(); try { while (((RunEnabledArtifacts)(ref enumerator)).MoveNext()) { ArtifactDef current = ((RunEnabledArtifacts)(ref enumerator)).Current; artifacts[current.artifactIndex] = true; } } finally { ((IDisposable)(RunEnabledArtifacts)(ref enumerator)).Dispose(); } ArtifactTrialMissionController val = Object.FindObjectOfType<ArtifactTrialMissionController>(); int num = val?.currentArtifactIndex ?? (-1); if (num != -1) { artifacts[num] = val.artifactWasEnabled; } } internal void LoadData() { for (int i = 0; i < ArtifactCatalog.artifactCount; i++) { ArtifactDef artifactDef = ArtifactCatalog.GetArtifactDef((ArtifactIndex)i); RunArtifactManager.instance.SetArtifactEnabled(artifactDef, artifacts.ElementAtOrDefault(i)); } } } 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 = "sn")] public string sceneName; [DataMember(Name = "nsn")] public string nextSceneName; [DataMember(Name = "im")] public ItemMaskData itemMask; [DataMember(Name = "em")] public EquipmentMaskData equipmentMask; [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 RuleBookData ruleBook; [DataMember(Name = "trdt")] public string typeRunDataType; [DataMember(Name = "trd")] [DiscoverObjectType("typeRunDataType")] public ITypedRunData typedRunData; private static readonly FieldInfo onRunStartGlobalDelegate = typeof(Run).GetField("onRunStartGlobal", BindingFlags.Static | BindingFlags.NonPublic); internal RunData() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown //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_0068: 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) Run instance = Run.instance; seed = instance.seed; difficulty = (int)instance.selectedDifficulty; RunStopwatch runStopwatch = instance.runStopwatch; isPaused = runStopwatch.isPaused; offsetFromFixedTime = runStopwatch.offsetFromFixedTime; fixedTime = instance.fixedTime; time = instance.time; stageClearCount = instance.stageClearCount; Scene activeScene = SceneManager.GetActiveScene(); sceneName = ((Scene)(ref activeScene)).name; nextSceneName = instance.nextStageScene.cachedName; shopPortalCount = instance.shopPortalCount; itemMask = new ItemMaskData(instance.availableItems); equipmentMask = new EquipmentMaskData(instance.availableEquipment); runRng = Saving.PreStageRng; eventFlags = instance.eventFlags.ToArray(); trialArtifact = Object.FindObjectOfType<ArtifactTrialMissionController>()?.currentArtifactIndex ?? (-1); ruleBook = new RuleBookData(instance.ruleBook); if (instance is InfiniteTowerRun) { typedRunData = new InfiniteTowerTypedRunData(); typeRunDataType = typeof(InfiniteTowerTypedRunData).AssemblyQualifiedName; } } internal void LoadData() { //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) ModSupport.ShareSuiteMapTransition(); if (trialArtifact != -1) { ArtifactTrialMissionController.trialArtifact = ArtifactCatalog.GetArtifactDef((ArtifactIndex)trialArtifact); } Run instance = Run.instance; if (ruleBook.ruleValues.Length != RuleCatalog.ruleCount) { ProperSavePlugin.InstanceLogger.LogError((object)"RuleCatalog mismatch with saved ruleBook data, fallback to starting Run ruleBook"); } else { instance.SetRuleBook(ruleBook.Load()); } instance.OnRuleBookUpdated(instance.networkRuleBookComponent); instance.seed = seed; instance.selectedDifficulty = (DifficultyIndex)difficulty; instance.shopPortalCount = shopPortalCount; runRng.LoadData(instance); instance.GenerateStageRNG(); typedRunData?.Load(); instance.allowNewParticipants = true; Object.DontDestroyOnLoad((Object)(object)((Component)instance).gameObject); ReadOnlyCollection<NetworkUser> readOnlyInstancesList = NetworkUser.readOnlyInstancesList; for (int i = 0; i < readOnlyInstancesList.Count; i++) { instance.OnUserAdded(readOnlyInstancesList[i]); } instance.allowNewParticipants = false; instance.stageClearCount = stageClearCount; instance.RecalculateDifficultyCoefficent(); instance.nextStageScene = SceneCatalog.GetSceneDefFromSceneName(nextSceneName); NetworkManager.singleton.ServerChangeScene(sceneName); itemMask.LoadDataOut(out instance.availableItems); equipmentMask.LoadDataOut(out instance.availableEquipment); 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 @delegate in invocationList) { @delegate.Method.Invoke(@delegate.Target, new object[1] { instance }); } } instance.fixedTime = fixedTime; instance.time = time; instance.runStopwatch = new RunStopwatch { offsetFromFixedTime = offsetFromFixedTime, isPaused = isPaused }; } } public class RunRngData { [DataMember(Name = "rr")] public RngData runRng; [DataMember(Name = "nsr")] public RngData nextStageRng; [DataMember(Name = "srg")] public RngData stageRngGenerator; internal RunRngData(Run run) { runRng = new RngData(run.runRNG); nextStageRng = new RngData(run.nextStageRng); stageRngGenerator = new RngData(run.stageRngGenerator); } internal void LoadData(Run run) { runRng.LoadDataOut(out run.runRNG); nextStageRng.LoadDataOut(out run.nextStageRng); stageRngGenerator.LoadDataOut(out run.stageRngGenerator); } } public class TeamData { [DataMember(Name = "e")] public long expirience; internal TeamData() { expirience = (long)TeamManager.instance.GetTeamExperience((TeamIndex)1); } internal void LoadData() { TeamManager.instance.GiveTeamExperience((TeamIndex)1, (ulong)expirience); } } } namespace ProperSave.SaveData.Runs { public class InfiniteTowerTypedRunData : ITypedRunData { [DataMember(Name = "wi")] public int waveIndex; [DataMember(Name = "wr")] public RngData waveRng; [DataMember(Name = "eir")] public RngData enemyItemRng; [DataMember(Name = "swr")] public RngData safeWardRng; [DataMember(Name = "eipi")] public int enemyItemPatternIndex; [DataMember(Name = "ei")] public InventoryData enemyInventory; internal InfiniteTowerTypedRunData() { Run instance = Run.instance; InfiniteTowerRun val = (InfiniteTowerRun)(object)((instance is InfiniteTowerRun) ? instance : null); waveIndex = val.waveIndex; waveRng = new RngData(val.waveRng); enemyItemRng = new RngData(val.enemyItemRng); safeWardRng = Saving.PreStageInfiniteTowerSafeWardRng; enemyItemPatternIndex = val.enemyItemPatternIndex; enemyInventory = new InventoryData(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); } } public interface ITypedRunData { void Load(); } } namespace ProperSave.SaveData.Artifacts { public class EnigmaData { [DataMember(Name = "sier")] public RngData serverInitialEquipmentRng; [DataMember(Name = "saer")] public RngData serverActivationEquipmentRng; internal EnigmaData() { serverInitialEquipmentRng = new RngData(EnigmaArtifactManager.serverInitialEquipmentRng); serverActivationEquipmentRng = new RngData(EnigmaArtifactManager.serverActivationEquipmentRng); } internal void LoadData() { serverInitialEquipmentRng.LoadDataRef(ref EnigmaArtifactManager.serverInitialEquipmentRng); serverActivationEquipmentRng.LoadDataRef(ref EnigmaArtifactManager.serverActivationEquipmentRng); } } } 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.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 = "lssme")] public uint lssMoneyExp; [DataMember(Name = "ms")] public MinionData[] minions; internal CharacterMasterData(CharacterMaster master) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) money = master.money; voidCoins = master.voidCoins; beadExpirience = master.beadExperience; numberOfBeadStatsGained = master.numberOfBeadStatsGained; oldBeadLevel = master.oldBeadLevel; newBeadLevel = master.newBeadLevel; beadXPNeededForCurrentLevel = master.beadXPNeededForCurrentLevel; lssMoneyExp = master.lssMoneyExp; inventory = new InventoryData(master.inventory); loadout = new LoadoutData(master.loadout); bodyName = ((Object)master.bodyPrefab).name; if (master.cloverVoidRng != null) { cloverVoidRng = new RngData(master.cloverVoidRng); } if (RunArtifactManager.instance.IsArtifactEnabled(Artifacts.Devotion)) { DevotionInventoryController devotionInventoryController = GetDevotionInventoryController(master); if (Object.op_Implicit((Object)(object)devotionInventoryController)) { devotionInventory = new InventoryData(devotionInventoryController._devotionMinionInventory); } } List<MinionData> list = new List<MinionData>(); foreach (CharacterMaster readOnlyInstances in CharacterMaster.readOnlyInstancesList) { CharacterMaster ownerMaster = readOnlyInstances.minionOwnership.ownerMaster; if ((Object)(object)ownerMaster != (Object)null && ((NetworkBehaviour)ownerMaster).netId == ((NetworkBehaviour)master).netId) { list.Add(new MinionData(readOnlyInstances)); } } minions = new MinionData[list.Count]; for (int i = 0; i < list.Count; i++) { minions[i] = list[i]; } } internal void LoadMaster(CharacterMaster master, bool delayedInventory) { if (devotionInventory != null) { DevotionInventoryController val = CreateDevotionInventoryController(master); devotionInventory.LoadInventory(val._devotionMinionInventory); } MinionData[] array = minions; for (int i = 0; i < array.Length; i++) { array[i].LoadMinion(master); } GameObject val2 = BodyCatalog.FindBodyPrefab(bodyName); if (Object.op_Implicit((Object)(object)val2)) { master.bodyPrefab = val2; } ModSupport.LoadShareSuiteMoney(money); master.money = money; master.voidCoins = voidCoins; master.beadExperience = beadExpirience; master.numberOfBeadStatsGained = numberOfBeadStatsGained; master.oldBeadLevel = oldBeadLevel; master.newBeadLevel = newBeadLevel; master.beadXPNeededForCurrentLevel = beadXPNeededForCurrentLevel; master.lssMoneyExp = lssMoneyExp; 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<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)"RoR2/CU8/LemurianEgg/DevotionMinionInventory.prefab").WaitForCompletion()); DevotionInventoryController component = val.GetComponent<DevotionInventoryController>(); ((Component)component).GetComponent<TeamFilter>().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); } } public class DevotedLemurianData { [DataMember(Name = "ii")] public int itemIndex; [DataMember(Name = "dev")] public int devotedEvolutionLevel; public DevotedLemurianData(DevotedLemurianController controller) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown itemIndex = (int)controller.DevotionItem; devotedEvolutionLevel = controller.DevotedEvolutionLevel; } public void LoadData(DevotedLemurianController controller) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) controller._devotionItem = (ItemIndex)itemIndex; controller._devotedEvolutionLevel = devotedEvolutionLevel; } } public class EquipmentData { [DataMember(Name = "i")] public int index; [DataMember(Name = "c")] public byte charges; [DataMember(Name = "cft")] public float chargeFinishTime; public EquipmentData(EquipmentState state) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown //IL_0013: 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) index = (int)state.equipmentIndex; charges = state.charges; chargeFinishTime = state.chargeFinishTime.t; } public void LoadEquipment(Inventory inventory, byte equipmentSlot) { //IL_0015: 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) FixedTimeStamp val = default(FixedTimeStamp); ((FixedTimeStamp)(ref val))..ctor(chargeFinishTime); EquipmentState val2 = default(EquipmentState); ((EquipmentState)(ref val2))..ctor((EquipmentIndex)index, val, charges, false); inventory.SetEquipment(val2, (uint)equipmentSlot); } } public class EquipmentMaskData { public bool[] array; public EquipmentMaskData(EquipmentMask mask) { array = mask.array.ToArray(); } public void LoadDataOut(out EquipmentMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown mask = new EquipmentMask { array = array.ToArray() }; } } 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<ItemData> items; [DataMember(Name = "e")] public EquipmentData[] equipments; [DataMember(Name = "aes")] public byte activeEquipmentSlot; public InventoryData(Inventory inventory) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected I4, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) infusionBonus = inventory.infusionBonus; equipmentDisabled = inventory.equipmentDisabled; beadAppliedDamage = inventory.beadAppliedDamage; beadAppliedHealth = inventory.beadAppliedHealth; beadAppliedRegen = inventory.beadAppliedRegen; beadAppliedShield = inventory.beadAppliedShield; items = new List<ItemData>(); foreach (ItemIndex item in inventory.itemAcquisitionOrder) { items.Add(new ItemData { itemIndex = (int)item, count = inventory.GetItemCount(item) }); } equipments = new EquipmentData[inventory.GetEquipmentSlotCount()]; for (int i = 0; i < equipments.Length; i++) { equipments[i] = new EquipmentData(inventory.GetEquipment((uint)i)); } activeEquipmentSlot = inventory.activeEquipmentSlot; } public void LoadInventory(Inventory inventory) { inventory.beadAppliedShield = beadAppliedShield; inventory.beadAppliedRegen = beadAppliedRegen; inventory.beadAppliedHealth = beadAppliedHealth; inventory.beadAppliedDamage = beadAppliedDamage; inventory.equipmentDisabled = equipmentDisabled; inventory.itemAcquisitionOrder.Clear(); foreach (ItemData item in items) { inventory.itemStacks[item.itemIndex] = item.count; inventory.itemAcquisitionOrder.Add((ItemIndex)item.itemIndex); } inventory.HandleInventoryChanged(); for (byte b = 0; b < equipments.Length; b++) { equipments[b].LoadEquipment(inventory, b); } inventory.SetActiveEquipmentSlot(activeEquipmentSlot); inventory.AddInfusionBonus(infusionBonus); } } public class ItemData { [DataMember(Name = "i")] public int itemIndex; [DataMember(Name = "c")] public int count; } public class ItemMaskData { public bool[] array; public ItemMaskData(ItemMask mask) { array = mask.array.ToArray(); } public void LoadDataOut(out ItemMask mask) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown mask = new ItemMask { array = array.ToArray() }; } } public class LoadoutData { public class LoadoutBodyData { [DataMember(Name = "bi")] public int bodyIndex; [DataMember(Name = "sp")] public uint skinPreference; [DataMember(Name = "sps")] public uint[] skillPreferences; public LoadoutBodyData(BodyLoadout bodyLoadout) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown bodyIndex = (int)bodyLoadout.bodyIndex; skinPreference = bodyLoadout.skinPreference; skillPreferences = bodyLoadout.skillPreferences; } public BodyLoadout Load() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown return new BodyLoadout { bodyIndex = (BodyIndex)bodyIndex, skinPreference = skinPreference, skillPreferences = skillPreferences }; } } [DataMember(Name = "ml")] public LoadoutBodyData[] modifiedLoadouts; public LoadoutData(Loadout loadout) { BodyLoadout[] modifiedBodyLoadouts = loadout.bodyLoadoutManager.modifiedBodyLoadouts; modifiedLoadouts = modifiedBodyLoadouts.Select((BodyLoadout el) => new LoadoutBodyData(el)).ToArray(); } public void LoadData(Loadout loadout) { loadout.Clear(); loadout.bodyLoadoutManager.modifiedBodyLoadouts = modifiedLoadouts.Select((LoadoutBodyData el) => el.Load()).ToArray(); } } public class ModdedData { [DataMember(Name = "ot")] public string ObjectType { get; set; } [DataMember(Name = "v")] [DiscoverObjectType("ObjectType")] public object Value { get; set; } } public class RngData { [DataMember(Name = "s0")] public ulong state0; [DataMember(Name = "s1")] public ulong state1; public RngData(Xoroshiro128Plus rng) { 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; } } public class RuleBookData { [DataMember(Name = "rv")] public byte[] ruleValues; public RuleBookData(RuleBook ruleBook) { ruleValues = ruleBook.ruleValues.ToArray(); } public RuleBook Load() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown return new RuleBook { ruleValues = ruleValues.ToArray() }; } } public class UserIDData { [DataMember(Name = "s")] public ulong steam; [DataMember(Name = "e")] public string egs; [DataMember(Name = "si")] public byte subId; public UserIDData(NetworkUserId userID) { //IL_0007: 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_001f: Unknown result type (might be due to invalid IL or missing references) 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (steam != 0L) { return new NetworkUserId(steam, subId); } if (!string.IsNullOrWhiteSpace(egs)) { return new NetworkUserId(egs, subId); } return default(NetworkUserId); } } } namespace ProperSave.Components { public class GamepadTooltipProvider : TooltipProvider { public HoldGamepadInputEvent inputEvent; private RectTransform rectTransform; private InputBindingDisplayController inputBindingDisplayController; public void Awake() { rectTransform = ((Component)this).GetComponent<RectTransform>(); inputBindingDisplayController = ((Component)this).GetComponent<InputBindingDisplayController>(); } 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));