using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Cysharp.Threading.Tasks; using HarmonyLib; using I2.Loc; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using NineSolsAPI.Menu; using NineSolsAPI.Patches; using NineSolsAPI.Preload; using NineSolsAPI.Utils; using TMPro; using UnityEngine; using UnityEngine.Device; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("jakobhellermann@protonmail.com")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Nine Sols Modding API")] [assembly: AssemblyFileVersion("1.3.1.0")] [assembly: AssemblyInformationalVersion("1.3.1+2e117c05653cd96e395df8dc3e9a4cbf6b7fa66d")] [assembly: AssemblyProduct("NineSolsAPI")] [assembly: AssemblyTitle("NineSolsAPI")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/nine-sols-modding/NineSolsAPI")] [assembly: AssemblyVersion("1.3.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NineSolsAPI { [PublicAPI] public static class GameVersions { public const string SpeedrunPatch = "d4c12f4d7e8442e79988244014fb92d2"; public static T Select(string version, T yes, T no) { if (!IsVersion(version)) { return no; } return yes; } public static bool IsVersion(string version) { return Application.buildGUID == version; } } internal class KeyBind { public required MonoBehaviour Owner; public required Func Shortcut; public required Action Action; } [PublicAPI] public class KeybindManager { private List keybindings = new List(); internal void Unload() { keybindings.Clear(); } public static void Add(MonoBehaviour owner, Action action, params KeyCode[] keys) { //IL_0007: 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_0026: Unknown result type (might be due to invalid IL or missing references) KeyCode val = keys[^1]; KeyCode[] subArray = keys[..^1]; KeyboardShortcut shortcut = default(KeyboardShortcut); ((KeyboardShortcut)(ref shortcut))..ctor(val, subArray); Add(owner, action, shortcut); } public static void Add(MonoBehaviour owner, Action action, KeyboardShortcut shortcut) { //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) Add(owner, action, (Func)(() => shortcut)); } public static void Add(MonoBehaviour owner, Action action, Func shortcut) { NineSolsAPICore.Instance.KeybindManager.AddKeybind(owner, action, shortcut); } public static void Add(MonoBehaviour owner, Action action, ConfigEntry shortcut) { ConfigEntry shortcut2 = shortcut; Add(owner, action, (Func)(() => shortcut2.Value)); } private void AddKeybind(MonoBehaviour owner, Action action, Func shortcut) { keybindings.Add(new KeyBind { Owner = owner, Action = action, Shortcut = shortcut }); } internal void Update() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) bool flag = false; foreach (KeyBind keybinding in keybindings) { if (!Object.op_Implicit((Object)(object)keybinding.Owner)) { flag = true; } else if (CheckShortcutOnly(keybinding.Shortcut())) { try { keybinding.Action(); } catch (Exception arg) { Log.Error($"Failed to run action: {arg}"); } } } if (flag) { keybindings.RemoveAll((KeyBind keybinding) => !Object.op_Implicit((Object)(object)keybinding.Owner)); } } public static bool CheckShortcutOnly(KeyboardShortcut shortcut) { //IL_0002: 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_0022: 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) bool flag = Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey); foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { flag = flag && Input.GetKey(modifier); } return flag; } } internal static class Log { private static ManualLogSource logSource; internal static void Init(ManualLogSource logSource) { Log.logSource = logSource; } internal static void Debug(object data) { logSource.LogDebug(data); } internal static void Error(object data) { logSource.LogError(data); } internal static void Fatal(object data) { logSource.LogFatal(data); } internal static void Info(object data) { logSource.LogInfo(data); } internal static void Message(object data) { logSource.LogMessage(data); } internal static void Warning(object data) { logSource.LogWarning(data); } } [PublicAPI] [BepInPlugin("ninesolsapi", "NineSolsAPI", "1.3.1")] public class NineSolsAPICore : BaseUnityPlugin { public const string PluginGUID = "ninesolsapi"; public const string PluginName = "NineSolsAPI"; public const string PluginVersion = "1.3.1"; internal static NineSolsAPICore Instance; private Canvas fullscreenCanvas; private Preloader preloader; internal ToastManager ToastManager; internal KeybindManager KeybindManager = new KeybindManager(); private TitlescreenModifications titlescreenModifications = new TitlescreenModifications(); private Harmony harmony; private RectTransform? progressBar; private ConfigEntry configDisableAchievements; private const int ProgressWidth = 600; private const int ProgressHeight = 30; public static Canvas FullscreenCanvas => Instance.fullscreenCanvas; internal static bool AchivementsEnabled { get { NineSolsAPICore instance = Instance; if (instance == null) { return false; } return !instance.configDisableAchievements.Value; } } private float LoadProgress { set { SetProgress(value); if (value >= 1f) { OnLoadDone(); } } } public static Preloader Preloader => Instance.preloader; private void Awake() { //IL_0039: 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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown Instance = this; Log.Init(((BaseUnityPlugin)this).Logger); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; if (!TomlTypeConverter.CanConvert(typeof(KeyboardShortcut))) { TomlTypeConverter.AddConverter(typeof(KeyboardShortcut), new TypeConverter { ConvertToString = delegate(object o, Type _) { //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) KeyboardShortcut val = (KeyboardShortcut)o; return ((KeyboardShortcut)(ref val)).Serialize(); }, ConvertToObject = (string s, Type _) => KeyboardShortcut.Deserialize(s) }); } try { LoadProgress = 0f; fullscreenCanvas = CreateFullscreenCanvas(); preloader = new Preloader(delegate(float progress) { LoadProgress = progress; }); ToastManager = new ToastManager(); titlescreenModifications.Load(); configDisableAchievements = ((BaseUnityPlugin)this).Config.Bind("Achievements", "Disable achievements", true, (ConfigDescription)null); SceneManager.sceneLoaded += OnSceneLoaded; RCGLifeCycle.DontDestroyForever(((Component)this).gameObject); harmony = new Harmony($"harmony-auto-{Guid.NewGuid()}"); harmony.PatchAll(typeof(NineSolsAPI.Patches.Patches)); harmony.PatchAll(typeof(SteamAPI)); if (GameVersions.IsVersion("d4c12f4d7e8442e79988244014fb92d2")) { harmony.PatchAll(typeof(PatchesSpeedrunpatch)); } } catch (Exception arg) { Log.Error($"Failed to initialized modding API: {arg}"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Nine Sols API loaded"); } private void Start() { ((MonoBehaviour)this).Invoke("AfterStart", 0f); ((MonoBehaviour)this).StartCoroutine(preloader.Preload()); } private void AfterStart() { //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) Scene activeScene = SceneManager.GetActiveScene(); if (((Scene)(ref activeScene)).name == "Logo") { progressBar = CreateProgressBar(); } } private void OnLoadDone() { if (!((Object)(object)progressBar == (Object)null)) { Object.Destroy((Object)(object)((Component)((Transform)progressBar).parent).gameObject); progressBar = null; SceneManager.LoadScene("TitleScreenMenu"); } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; KeybindManager.Unload(); titlescreenModifications.Unload(); Object.Destroy((Object)(object)((Component)FullscreenCanvas).gameObject); preloader.Unload(); harmony.UnpatchSelf(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Nine Sols API unloaded"); } private void Update() { ToastManager?.Update(); KeybindManager?.Update(); } private void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) titlescreenModifications.MaybeExtendMainMenu(scene); } private Canvas CreateFullscreenCanvas() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("NineSolsAPI-FullscreenCanvas"); ((Object)val).hideFlags = (HideFlags)61; Canvas obj = val.AddComponent(); obj.renderMode = (RenderMode)0; RCGLifeCycle.DontDestroyForever(val); return obj; } private RectTransform CreateProgressBar() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown //IL_0109: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(); val.SetActive(false); Transform transform = val.transform; Canvas obj = FullscreenCanvas; transform.SetParent((obj != null) ? ((Component)obj).transform : null); Image val2 = val.AddComponent(); val2.sprite = NullSprite(new byte[4] { 255, 255, 255, 255 }); val2.useSpriteMesh = true; RectTransform component = val.GetComponent(); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(600f, 30f); component.anchoredPosition = Vector2.zero; component.anchorMin = new Vector2(0.5f, 0.2f); component.anchorMax = new Vector2(0.5f, 0.2f); GameObject val3 = new GameObject(); val3.transform.SetParent(val.transform); Image val4 = val3.AddComponent(); val4.sprite = NullSprite(new byte[4] { 52, 52, 235, 255 }); val4.useSpriteMesh = true; RectTransform component2 = val3.GetComponent(); component2.pivot = new Vector2(0f, 0.5f); component2.sizeDelta = new Vector2(0f, 30f); component2.anchoredPosition = Vector2.zero; component2.anchorMin = new Vector2(0f, 0.5f); component2.anchorMax = new Vector2(0f, 0.5f); return component2; static Sprite NullSprite(byte[]? data = null) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) Texture2D val5 = new Texture2D(1, 1); if (data == null) { data = new byte[4]; } val5.LoadRawTextureData(data); val5.Apply(); return Sprite.Create(val5, new Rect(0f, 0f, 1f, 1f), Vector2.zero); } } private void SetProgress(float progress) { //IL_0058: 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_006c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)progressBar == (Object)null)) { if (!((Component)progressBar).gameObject.activeSelf && progress != 0f && (double)progress < 1.0) { ((Component)((Transform)progressBar).parent).gameObject.SetActive(true); } RectTransform? obj = progressBar; Vector2 sizeDelta = progressBar.sizeDelta; sizeDelta.x = 600f * progress; obj.sizeDelta = sizeDelta; } } } internal record struct ToastMessage(float StartTime, string Text); public class ToastManager { private const float MaxToastAge = 5f; private bool toastsDirty; private List toasts = new List(); private TMP_Text toastText; private static float Now => Time.time; public ToastManager() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Toast"); Transform transform = val.transform; Canvas fullscreenCanvas = NineSolsAPICore.FullscreenCanvas; transform.SetParent((fullscreenCanvas != null) ? ((Component)fullscreenCanvas).transform : null); toastText = (TMP_Text)(object)val.AddComponent(); toastText.alignment = (TextAlignmentOptions)1028; toastText.fontSize = 20f; ((Graphic)toastText).color = Color.white; RCGLifeCycle.DontDestroyForever(val); RectTransform component = ((Component)toastText).GetComponent(); component.anchorMin = new Vector2(1f, 0f); component.anchorMax = new Vector2(1f, 0f); component.pivot = new Vector2(1f, 0f); component.anchoredPosition = new Vector2(-10f, 10f); component.sizeDelta = new Vector2((float)Screen.width, 0f); } private static void ToastInner(string message) { Log.Info("Toast: " + message); NineSolsAPICore.Instance.ToastManager.AddToastMessage(message?.ToString() ?? "null"); } private static string SimpleTypeName(Type type) { if (type.IsGenericType) { string text = (from x in type.GetGenericArguments() select x.Name).Aggregate((string x1, string x2) => x1 + ", " + x2); return type.Name.Substring(0, type.Name.IndexOf("`", StringComparison.Ordinal)) + "<" + text + ">"; } return type.Name; } [PublicAPI] public static void Toast(object? message) { if (message is IEnumerable enumerable && !(enumerable is string)) { ToastInner(SimpleTypeName(enumerable.GetType())); bool flag = true; foreach (object item in enumerable) { flag = false; ToastInner(item?.ToString() + " -"); } if (flag) { ToastInner("(empty)"); } } else { ToastInner(message?.ToString() ?? "null"); } } private void AddToastMessage(string message) { toasts.Add(new ToastMessage(Now, message)); toastsDirty = true; } internal void Update() { float now = Now; toastsDirty |= toasts.RemoveAll((ToastMessage toast) => now - toast.StartTime > 5f) > 0; if (toastsDirty) { toastText.text = string.Join('\n', toasts.Select((ToastMessage toast) => toast.Text)); } } } [PublicAPI] public static class VersionCompatExtensions { private static MethodBase? gameCoreChangeScene2 = typeof(GameCore).GetMethod("ChangeScene", new Type[3] { typeof(ChangeSceneData), typeof(bool), typeof(bool) }); private static MethodBase? gameCoreChangeScene3 = typeof(GameCore).GetMethod("ChangeScene", new Type[4] { typeof(ChangeSceneData), typeof(bool), typeof(bool), typeof(float) }); private static MethodBase? applicationCoreChangeScene = typeof(ApplicationCore).GetMethod("ChangeScene"); private static MethodBase? applicationCoreChangeSceneClean = typeof(ApplicationCore).GetMethod("ChangeSceneClean"); public static void ChangeSceneCompat(this GameCore gameCore, ChangeSceneData changeSceneData, bool showTip, bool captureLastImage = false, float delayTime = 0f) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (gameCoreChangeScene2 != null) { gameCoreChangeScene2.Invoke(gameCore, new object[3] { changeSceneData, showTip, captureLastImage }); return; } if (gameCoreChangeScene3 != null) { gameCoreChangeScene3.Invoke(gameCore, new object[4] { changeSceneData, showTip, captureLastImage, delayTime }); return; } throw new Exception("No candidate for GameCore.ChangeScene found"); } public static UniTask ChangeSceneCompat(this ApplicationCore applicationCore, string sceneName, bool showTip = true, bool showLoading = false, bool forceSpawnFromSavePoint = false, int savePointIndex = 0) { //IL_004a: 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) object[] parameters = new object[5] { sceneName, showTip, showLoading, forceSpawnFromSavePoint, savePointIndex }; if (applicationCoreChangeScene != null) { return (UniTask)applicationCoreChangeScene.Invoke(applicationCore, parameters); } if (applicationCoreChangeSceneClean != null) { return (UniTask)applicationCoreChangeSceneClean.Invoke(applicationCore, parameters); } throw new Exception("No candidate for ApplicationCode.ChangeScene[Clean] found"); } public static MonsterStat MonsterStatCompat(this MonsterBase monsterBase) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown return (MonsterStat)(typeof(MonsterBase).GetField("_monsterStat") ?? typeof(MonsterBase).GetField("monsterStat")).GetValue(monsterBase); } public static IEnumerable AttackSensorsCompat(this MonsterBase monsterBase) { FieldInfo field = typeof(MonsterBase).GetField("attackSensors", BindingFlags.Instance | BindingFlags.Public); if (field != null) { return (List)field.GetValue(monsterBase); } return (AttackSensor[])typeof(MonsterBase).GetField("_attackSensors", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(monsterBase); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "NineSolsAPI"; public const string PLUGIN_NAME = "NineSolsAPI"; public const string PLUGIN_VERSION = "1.3.1"; } } namespace NineSolsAPI.Utils { [PublicAPI] public static class AssemblyUtils { private static Stream? GetEmbeddedResourceInner(Assembly assembly, string fileName) { Stream manifestResourceStream = assembly.GetManifestResourceStream(fileName); if (manifestResourceStream == null) { string[] manifestResourceNames = assembly.GetManifestResourceNames(); Log.Error((manifestResourceNames.Length == 0) ? ("Could not load embedded resource '" + fileName + "', the assembly " + assembly.GetName().Name + " contains no resources") : ("Could not load embedded resource '" + fileName + "', did you mean one of " + GeneralExtensions.Join((IEnumerable)manifestResourceNames, (Func)null, ", ") + "?")); return null; } return manifestResourceStream; } private static byte[]? GetEmbeddedResourceBytesInner(Assembly assembly, string fileName) { Stream embeddedResourceInner = GetEmbeddedResourceInner(assembly, fileName); if (embeddedResourceInner == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); embeddedResourceInner.CopyTo(memoryStream); return memoryStream.ToArray(); } public static byte[]? GetEmbeddedResource(string name) { return GetEmbeddedResourceBytesInner(Assembly.GetCallingAssembly(), name); } public static Texture2D? GetEmbeddedTexture(string name) { //IL_0013: 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_001f: Expected O, but got Unknown //IL_0021: Expected O, but got Unknown byte[] embeddedResourceBytesInner = GetEmbeddedResourceBytesInner(Assembly.GetCallingAssembly(), name); if (embeddedResourceBytesInner == null) { return null; } Texture2D val = new Texture2D(1, 1); ImageConversion.LoadImage(val, embeddedResourceBytesInner); return val; } public static AssetBundle? GetEmbeddedAssetBundle(string name) { Stream embeddedResourceInner = GetEmbeddedResourceInner(Assembly.GetCallingAssembly(), name); if (embeddedResourceInner == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); embeddedResourceInner.CopyTo(memoryStream); return AssetBundle.LoadFromMemory(memoryStream.ToArray()); } public static T? GetEmbeddedJson(string name) { Stream embeddedResourceInner = GetEmbeddedResourceInner(Assembly.GetCallingAssembly(), name); if (embeddedResourceInner == null) { return default(T); } using StreamReader streamReader = new StreamReader(embeddedResourceInner); return JsonConvert.DeserializeObject(streamReader.ReadToEnd()); } } [PublicAPI] public static class CollectionExtensions { public static T? GetValueOrDefault(this T[] array, int index) where T : class { if (array.Length <= index) { return null; } return array[index]; } public static void AddRange(this HashSet hashSet, params T[] items) { foreach (T item in items) { hashSet.Add(item); } } public static void AddToKey(this IDictionary> dict, TKey key, TValue value) { if (dict.TryGetValue(key, out ICollection value2)) { value2.Add(value); return; } dict[key] = new List(1) { value }; } } [PublicAPI] public static class JsonUtils { public static string Serialize(object? value, bool indent = false) { return JsonConvert.SerializeObject(value, (Formatting)(indent ? 1 : 0)); } public static T? Deserialize(string value) { return JsonConvert.DeserializeObject(value); } public static T? DeserializeStream(Stream stream) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown using StreamReader streamReader = new StreamReader(stream); JsonTextReader val = new JsonTextReader((TextReader)streamReader); try { return JsonSerializer.CreateDefault().Deserialize((JsonReader)(object)val); } finally { ((IDisposable)val)?.Dispose(); } } } [PublicAPI] public static class ModDirs { public static string DataDir(BaseUnityPlugin mod, params string[] subDirs) { return DataDir(mod.Info.Metadata.GUID, subDirs); } private static string DataDir(string modGuid, params string[] subDirs) { DirectoryInfo parent = Directory.GetParent(Application.dataPath); if (parent == null) { throw new Exception(Application.dataPath + " is not a valid game directory?"); } string text = subDirs.Aggregate(Path.Combine(parent.FullName, "ModData", modGuid), Path.Combine); Directory.CreateDirectory(text); return text; } } [PublicAPI] public static class ObjectUtils { public static GameObject InstantiateAutoReference(GameObject orig, Transform? parent, bool autoReferenceChildren = true) { GameObject val = Object.Instantiate(orig, parent, false); if (!Object.op_Implicit((Object)(object)val)) { return val; } AutoAttributeManager.AutoReference(val); if (autoReferenceChildren) { AutoAttributeManager.AutoReferenceAllChildren(val); } return val; } public static GameObject InstantiateAutoReference(GameObject orig, bool autoReferenceChildren = true) { GameObject val = Object.Instantiate(orig); if (!Object.op_Implicit((Object)(object)val)) { return val; } AutoAttributeManager.AutoReference(val); if (autoReferenceChildren) { AutoAttributeManager.AutoReferenceAllChildren(val); } return val; } public static GameObject InstantiateInit(GameObject orig, Transform? parent = null) { GameObject val = InstantiateAutoReference(orig, parent); ILevelAwake[] componentsInChildren = val.GetComponentsInChildren(true); for (int num = componentsInChildren.Length - 1; num >= 0; num--) { ILevelAwake val2 = componentsInChildren[num]; try { val2.EnterLevelAwake(); } catch (Exception ex) { Log.Error(ex.StackTrace); } } ILevelAwakeReverse[] componentsInChildren2 = val.GetComponentsInChildren(true); for (int num2 = componentsInChildren2.Length - 1; num2 >= 0; num2--) { ILevelAwakeReverse val3 = componentsInChildren2[num2]; try { val3.EnterLevelAwakeReverse(); } catch (Exception ex2) { Log.Error(ex2.StackTrace); } } ILevelStart[] componentsInChildren3 = val.GetComponentsInChildren(true); for (int num3 = componentsInChildren3.Length - 1; num3 >= 0; num3--) { ILevelStart val4 = componentsInChildren3[num3]; try { val4.EnterLevelStart(); } catch (Exception ex3) { Log.Error(ex3.StackTrace); } } IResetter[] componentsInChildren4 = val.GetComponentsInChildren(true); for (int num4 = componentsInChildren4.Length - 1; num4 >= 0; num4--) { IResetter val5 = componentsInChildren4[num4]; try { val5.EnterLevelReset(); } catch (Exception ex4) { Log.Error(ex4.StackTrace); } } return val; } public static GameObject? LookupPath(Scene scene, string path) { return GetGameObjectFromArray(((Scene)(ref scene)).GetRootGameObjects(), path); } public static GameObject? LookupPath(string path) { //IL_000a: 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) GameObject val = LookupPath(((Component)SingletonBehaviour.Instance).gameObject.scene, path); if (val != null) { return val; } for (int i = 0; i < SceneManager.sceneCount; i++) { GameObject val2 = LookupPath(SceneManager.GetSceneAt(i), path); if (val2 != null) { return val2; } } return null; } internal static GameObject? GetGameObjectFromArray(GameObject[] objects, string objName) { string text = null; int num = objName.IndexOf('/'); string rootName; if (num == -1) { rootName = objName; } else { if (num == 0 || num == objName.Length - 1) { throw new ArgumentException("Invalid GameObject path"); } rootName = objName.Substring(0, num); int num2 = num + 1; text = objName.Substring(num2, objName.Length - num2); } GameObject val = ((IEnumerable)objects).FirstOrDefault((Func)((GameObject o) => ((Object)o).name == rootName)); if (val == null) { return null; } if (text == null) { return val; } Transform val2 = val.transform.Find(text); if (Object.op_Implicit((Object)(object)val2)) { return ((Component)val2).gameObject; } return null; } public static T? FindDisabledByName(string name) where T : Object { string name2 = name; T? val = Object.FindObjectsOfType(true).FirstOrDefault((T x) => ((Object)x).name == name2); if (!Object.op_Implicit((Object)(object)val)) { Log.Warning("FindDisabledByName(" + name2 + ") not found"); } return val; } public static string ObjectPath(GameObject obj) { List list = new List(); GameObject val = obj; while ((Object)(object)val != (Object)null) { list.Add(((Object)val).name); Transform parent = val.transform.parent; val = ((parent != null) ? ((Component)parent).gameObject : null); } list.Reverse(); return GeneralExtensions.Join((IEnumerable)list, (Func)null, "/"); } [return: NotNullIfNotNull("component")] public static string? ObjectComponentPath(Component? component) { if (!Object.op_Implicit((Object)(object)component)) { return null; } return ObjectPath(component.gameObject) + "@" + ((object)component).GetType().Name; } public static Component? LookupObjectComponentPath(string path) { (string, string) tuple = path.SplitOnce('@') ?? throw new Exception("Object-Component path contains no component: " + path); string item = tuple.Item1; string componentName = tuple.Item2; GameObject val = LookupPath(item); if ((Object)(object)val == (Object)null) { return null; } return ((IEnumerable)val.GetComponents()).FirstOrDefault((Func)((Component c) => ((object)c).GetType().Name == componentName)); } } [Obsolete] public static class ReflectionUtils { [Obsolete] public static FieldInfo AccessFieldInfo(this object val, string fieldName) { FieldInfo? field = val.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { throw new Exception(string.Format(arg2: GeneralExtensions.Join(from x in val.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) select x.Name, (Func)null, ",\n"), format: "Field {0} was not found in type {1} or base types \n{2}", arg0: fieldName, arg1: val.GetType())); } return field; } [Obsolete] public static T AccessField(this object val, string fieldName) { return (T)val.AccessFieldInfo(fieldName).GetValue(val); } [Obsolete] public static T? AccessProperty(this object val, string propertyName) { return (T)val.GetType().GetProperty(propertyName).GetValue(val); } } [PublicAPI] public static class ReflectionExtension { private readonly record struct MemberKey(Type Type, string Name); private readonly record struct AllMemberKey(Type Type, BindingFlags BindingFlags); private readonly record struct MethodKey(Type Type, string Name, long ParameterHash); internal const BindingFlags InstanceAnyVisibility = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; internal const BindingFlags StaticAnyVisibility = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; internal const BindingFlags StaticInstanceAnyVisibility = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; internal const BindingFlags InstanceAnyVisibilityDeclaredOnly = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static readonly ConcurrentDictionary CachedMemberInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedFieldInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedPropertyInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedMethodInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedEventInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedGetMethodInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary CachedSetMethodInfos = new ConcurrentDictionary(); private static readonly ConcurrentDictionary> CachedAllFieldInfos = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary> CachedAllPropertyInfos = new ConcurrentDictionary>(); private static readonly ConcurrentDictionary> CachedAllMethodInfos = new ConcurrentDictionary>(); public static MemberInfo? GetMemberInfo(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, bool logFailure = true) { MemberKey key = new MemberKey(type, name); if (CachedMemberInfos.TryGetValue(key, out MemberInfo value)) { return value; } Type type2 = type; do { value = type2.GetMember(name, bindingFlags).FirstOrDefault(); type2 = type2.BaseType; } while (value == null && type2 != null); if (value == null && logFailure) { Log.Error($"Failed to find member '{name}' on type '{type}'"); } return CachedMemberInfos[key] = value; } public static FieldInfo? GetFieldInfo(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, bool logFailure = true) { MemberKey key = new MemberKey(type, name); if (CachedFieldInfos.TryGetValue(key, out FieldInfo value)) { return value; } Type type2 = type; do { value = type2.GetField(name, bindingFlags); type2 = type2.BaseType; } while (value == null && type2 != null); if (value == null && logFailure) { Log.Error($"Failed to find field '{name}' on type '{type}'"); } return CachedFieldInfos[key] = value; } public static PropertyInfo? GetPropertyInfo(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, bool logFailure = true) { MemberKey key = new MemberKey(type, name); if (CachedPropertyInfos.TryGetValue(key, out PropertyInfo value)) { return value; } Type type2 = type; do { value = type2.GetProperty(name, bindingFlags); type2 = type2.BaseType; } while (value == null && type2 != null); if (value == null && logFailure) { Log.Error($"Failed to find property '{name}' on type '{type}'"); } return CachedPropertyInfos[key] = value; } public static MethodInfo? GetMethodInfo(this Type type, string name, Type?[]? parameterTypes = null, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, bool logFailure = true) { MethodKey key = new MethodKey(type, name, parameterTypes.GetCustomHashCode()); if (CachedMethodInfos.TryGetValue(key, out MethodInfo value)) { return value; } Type type2 = type; do { if (parameterTypes != null) { foreach (MethodInfo allMethodInfo in type2.GetAllMethodInfos(bindingFlags)) { if (allMethodInfo.Name != name) { continue; } ParameterInfo[] parameters = allMethodInfo.GetParameters(); if (parameters.Length != parameterTypes.Length) { continue; } int num = 0; while (true) { if (num < parameters.Length) { if (parameterTypes[num] != null && parameterTypes[num] != parameters[num].ParameterType) { break; } num++; continue; } if (value != null) { if (!(value.DeclaringType != null) || !(value.DeclaringType != allMethodInfo.DeclaringType)) { if (logFailure) { Log.Error(string.Format("Method '{0}' with parameters ({1}) on type '{2}' is ambiguous between '{3}' and '{4}'", name, string.Join(", ", (IEnumerable)parameterTypes), type, value, allMethodInfo)); } value = null; goto end_IL_0123; } if (allMethodInfo.DeclaringType.IsSubclassOf(value.DeclaringType)) { value = allMethodInfo; } } else { value = allMethodInfo; } break; } continue; end_IL_0123: break; } } else { value = type2.GetMethod(name, bindingFlags); } type2 = type2.BaseType; } while (value == null && type2 != null); if (value == null && logFailure) { if (parameterTypes == null) { Log.Error($"Failed to find method '{name}' on type '{type}'"); } else { Log.Error(string.Format("Failed to find method '{0}' with parameters ({1}) on type '{2}'", name, string.Join(", ", (IEnumerable)parameterTypes), type)); } } return CachedMethodInfos[key] = value; } public static EventInfo? GetEventInfo(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { MemberKey key = new MemberKey(type, name); if (CachedEventInfos.TryGetValue(key, out EventInfo value)) { return value; } Type type2 = type; do { value = type2.GetEvent(name, bindingFlags); type2 = type2.BaseType; } while (value == null && type2 != null); if (value == null) { Log.Error($"Failed to find event '{name}' on type '{type}'"); } return CachedEventInfos[key] = value; } public static MethodInfo? GetGetMethod(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { MemberKey key = new MemberKey(type, name); if (CachedGetMethodInfos.TryGetValue(key, out MethodInfo value)) { return value; } value = type.GetPropertyInfo(name, bindingFlags)?.GetGetMethod(nonPublic: true); if (value == null) { Log.Error($"Failed to find get-method of property '{name}' on type '{type}'"); } return CachedGetMethodInfos[key] = value; } public static MethodInfo? GetSetMethod(this Type type, string name, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) { MemberKey key = new MemberKey(type, name); if (CachedSetMethodInfos.TryGetValue(key, out MethodInfo value)) { return value; } value = type.GetPropertyInfo(name, bindingFlags)?.GetSetMethod(nonPublic: true); if (value == null) { Log.Error($"Failed to find set-method of property '{name}' on type '{type}'"); } return CachedSetMethodInfos[key] = value; } public static IEnumerable GetAllFieldInfos(this Type type, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { bindingFlags |= BindingFlags.DeclaredOnly; AllMemberKey key = new AllMemberKey(type, bindingFlags); if (CachedAllFieldInfos.TryGetValue(key, out IEnumerable value)) { return value; } HashSet hashSet = new HashSet(); Type type2 = type; while (type2 != null && type2.IsSubclassOf(typeof(object))) { hashSet.AddRange(type2.GetFields(bindingFlags)); type2 = type2.BaseType; } return CachedAllFieldInfos[key] = hashSet; } public static IEnumerable GetAllPropertyInfos(this Type type, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { bindingFlags |= BindingFlags.DeclaredOnly; AllMemberKey key = new AllMemberKey(type, bindingFlags); if (CachedAllPropertyInfos.TryGetValue(key, out IEnumerable value)) { return value; } HashSet hashSet = new HashSet(); Type type2 = type; while (type2 != null && type2.IsSubclassOf(typeof(object))) { hashSet.AddRange(type2.GetProperties(bindingFlags)); type2 = type2.BaseType; } return CachedAllPropertyInfos[key] = hashSet; } public static IEnumerable GetAllMethodInfos(this Type type, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) { bindingFlags |= BindingFlags.DeclaredOnly; AllMemberKey key = new AllMemberKey(type, bindingFlags); if (CachedAllMethodInfos.TryGetValue(key, out IEnumerable value)) { return value; } HashSet hashSet = new HashSet(); Type type2 = type; while (type2 != null && type2.IsSubclassOf(typeof(object))) { hashSet.AddRange(type2.GetMethods(bindingFlags)); type2 = type2.BaseType; } return CachedAllMethodInfos[key] = hashSet; } public static T? GetFieldValue(this object obj, string name) { FieldInfo fieldInfo = obj.GetType().GetFieldInfo(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)fieldInfo == null) { return default(T); } return (T)fieldInfo.GetValue(obj); } public static T? GetFieldValue(this Type type, string name) { FieldInfo fieldInfo = type.GetFieldInfo(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if ((object)fieldInfo == null) { return default(T); } return (T)fieldInfo.GetValue(null); } public static void SetFieldValue(this object obj, string name, object? value) { obj.GetType().GetFieldInfo(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(obj, value); } public static void SetFieldValue(this Type type, string name, object? value) { type.GetFieldInfo(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(null, value); } public static T? GetPropertyValue(this object obj, string name) { PropertyInfo propertyInfo = obj.GetType().GetPropertyInfo(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)propertyInfo == null) { return default(T); } if (!propertyInfo.CanRead) { Log.Error($"Property '{name}' on type '{obj.GetType()}' is not readable"); return default(T); } return (T)propertyInfo.GetValue(obj); } public static T? GetPropertyValue(this Type type, string name) { PropertyInfo propertyInfo = type.GetPropertyInfo(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if ((object)propertyInfo == null) { return default(T); } if (!propertyInfo.CanRead) { Log.Error($"Property '{name}' on type '{type}' is not readable"); return default(T); } return (T)propertyInfo.GetValue(null); } public static void SetPropertyValue(this object obj, string name, object? value) { PropertyInfo propertyInfo = obj.GetType().GetPropertyInfo(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)propertyInfo != null) { if (!propertyInfo.CanWrite) { Log.Error($"Property '{name}' on type '{obj.GetType()}' is not writable"); } else { propertyInfo.SetValue(obj, value); } } } public static void SetPropertyValue(this Type type, string name, object? value) { PropertyInfo propertyInfo = type.GetPropertyInfo(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if ((object)propertyInfo != null) { if (!propertyInfo.CanWrite) { Log.Error($"Property '{name}' on type '{type}' is not writable"); } else { propertyInfo.SetValue(null, value); } } } public static void InvokeMethod(this object obj, string name, params object?[]? parameters) { obj.GetType().GetMethodInfo(name, parameters?.Select((object param) => param?.GetType()).ToArray(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(obj, parameters); } public static void InvokeMethod(this Type type, string name, params object?[]? parameters) { type.GetMethodInfo(name, parameters?.Select((object param) => param?.GetType()).ToArray(), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(null, parameters); } public static T? InvokeMethod(this object obj, string name, params object?[]? parameters) { MethodInfo methodInfo = obj.GetType().GetMethodInfo(name, parameters?.Select((object param) => param?.GetType()).ToArray(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)methodInfo == null) { return default(T); } return (T)methodInfo.Invoke(obj, parameters); } public static T? InvokeMethod(this Type type, string name, params object?[]? parameters) { MethodInfo methodInfo = type.GetMethodInfo(name, parameters?.Select((object param) => param?.GetType()).ToArray(), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if ((object)methodInfo == null) { return default(T); } return (T)methodInfo.Invoke(null, parameters); } } internal static class HashCodeExtensions { public static long GetCustomHashCode(this IEnumerable? enumerable) { if (enumerable == null) { return 0L; } long num = 17L; foreach (T item in enumerable) { num = num * -1521134295 + EqualityComparer.Default.GetHashCode(item); } return num; } } public static class StringExtensions { public static ReadOnlySpan TrimEndMatches(this string str, ReadOnlySpan substr) { ReadOnlySpan readOnlySpan = str.AsSpan(); int num = readOnlySpan.LastIndexOf(substr); if (num != str.Length - substr.Length) { return readOnlySpan; } return readOnlySpan.Slice(0, num); } public static ReadOnlySpan TrimEndMatches(this ReadOnlySpan span, ReadOnlySpan substr) { int num = span.LastIndexOf(substr); if (num != -1) { return span.Slice(0, num); } return span; } public static ReadOnlySpan TrimStartMatches(this string str, ReadOnlySpan substr) { ReadOnlySpan readOnlySpan = str.AsSpan(); int num = readOnlySpan.LastIndexOf(substr); if (num != -1) { int num2 = num + substr.Length; return readOnlySpan.Slice(num2, readOnlySpan.Length - num2); } return readOnlySpan; } public static ReadOnlySpan TrimStartMatches(this ReadOnlySpan span, ReadOnlySpan substr) { if (span.LastIndexOf(substr) != 0) { return span; } int length = substr.Length; return span.Slice(length, span.Length - length); } public static (string, string)? SplitOnce(this string str, char sep) { int num = str.LastIndexOf(sep); string item = str.Substring(0, num); int num2 = num + 1; string item2 = str.Substring(num2, str.Length - num2); return (item, item2); } } [PublicAPI] public static class TextureUtils { public static void WritePNGToDisk(string path, Texture2D source) { Texture2D val = (((Texture)source).isReadable ? source : Duplicate(source)); File.WriteAllBytes(path, ImageConversion.EncodeToPNG(val)); } public static Texture2D GetColorTexture(Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0017: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1); val.SetPixel(0, 0, color); val.Apply(); return val; } public static Texture2D Duplicate(Texture2D source) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)7, (RenderTextureReadWrite)1); Graphics.Blit((Texture)(object)source, temporary); RenderTexture active = RenderTexture.active; RenderTexture.active = temporary; Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height); val.ReadPixels(new Rect(0f, 0f, (float)((Texture)temporary).width, (float)((Texture)temporary).height), 0, 0); val.Apply(); RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); return val; } } } namespace NineSolsAPI.Preload { [AttributeUsage(AttributeTargets.Field)] [MeansImplicitUse] [PublicAPI] public class PreloadAttribute : Attribute { public string Scene; public string Path; public PreloadAttribute(string scene, string path) { Scene = scene; Path = path; base..ctor(); } } public interface IPreloadTarget { public class ReflectionPreloadTarget : IPreloadTarget { [CompilerGenerated] private object P; [CompilerGenerated] private FieldInfo P; public ReflectionPreloadTarget(object instance, FieldInfo field) { P = instance; P = field; base..ctor(); } public void Set(GameObject? preloaded, string scene, string path) { P.SetValue(P, preloaded); } public void Unset(GameObject preloaded) { P.SetValue(P, null); } } public class ListPreloadTarget : IPreloadTarget { [CompilerGenerated] private List P; public ListPreloadTarget(List preloads) { P = preloads; base..ctor(); } public void Set(GameObject? preloaded, string scene, string path) { P.Add(preloaded); } public void Unset(GameObject preloaded) { P.Clear(); } } void Set(GameObject? preloaded, string scene, string path); void Unset(GameObject preloaded); } [PublicAPI] public class Preloader { [CompilerGenerated] private sealed class d__15 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Preloader <>4__this; private Stopwatch 5__2; private Dictionary>.Enumerator 5__3; private Stopwatch 5__4; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { int num = <>1__state; if (num == -3 || (uint)(num - 1) <= 1u) { try { } finally { <>m__Finally1(); } } 5__2 = null; 5__3 = default(Dictionary>.Enumerator); 5__4 = null; <>1__state = -2; } private bool MoveNext() { try { int num = <>1__state; Preloader preloader = <>4__this; float num3; switch (num) { default: return false; case 0: <>1__state = -1; if (preloader.preloadTypes.Count == 0) { return false; } Log.Info($"Preloading {preloader.preloadTypes.Count} scenes"); 5__2 = Stopwatch.StartNew(); IsPreloading = true; DestroyAllGameObjects.DestroyingAll = true; <>1__state = -3; preloader.target = preloader.preloadTypes.Count; 5__3 = preloader.preloadTypes.GetEnumerator(); num3 = 0f; goto IL_022f; case 1: <>1__state = -3; 5__4.Stop(); Log.Info($"collecting resources in ${5__4.ElapsedMilliseconds}"); 5__4 = null; goto IL_014e; case 2: { <>1__state = -3; float num2 = preloader.inProgressLoads.Sum((AsyncOperation loadOp) => loadOp.progress * 0.5f); num2 += preloader.inProgressUnloads.Sum((AsyncOperation loadOp) => loadOp.progress * 0.5f); num3 = ((preloader.target == 0) ? 1f : (num2 / (float)preloader.target)); preloader.P(num3); Log.Info($"progress {num3}/1, in flight {preloader.preloadOperationQueue.Count}"); goto IL_022f; } IL_022f: if (!(num3 < 1f)) { 5__3 = default(Dictionary>.Enumerator); <>m__Finally1(); 5__2.Stop(); Log.Info($"Preloading done with {preloader.preloadObjs.Count} objects in {5__2.ElapsedMilliseconds}ms"); return false; } goto IL_014e; IL_014e: while (preloader.preloadOperationQueue.Count < 4 && 5__3.MoveNext()) { var (sceneName, scenePreloads) = (KeyValuePair>)(ref 5__3.Current); ((MonoBehaviour)NineSolsAPICore.Instance).StartCoroutine(preloader.DoPreloadScene(sceneName, scenePreloads)); if (preloader.inProgressLoads.Count % 4 == 0) { 5__4 = Stopwatch.StartNew(); <>2__current = Resources.UnloadUnusedAssets(); <>1__state = 1; return true; } } <>2__current = null; <>1__state = 2; return true; } } catch { //try-fault ((IDisposable)this).Dispose(); throw; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } private void <>m__Finally1() { <>1__state = -1; Preloader preloader = <>4__this; DestroyAllGameObjects.DestroyingAll = false; IsPreloading = false; preloader.preloaded = true; preloader.inProgressLoads.Clear(); preloader.inProgressUnloads.Clear(); preloader.preloadOperationQueue.Clear(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__14 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public string sceneName; public Preloader <>4__this; public List<(string, IPreloadTarget)> scenePreloads; private AsyncOperation 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; Preloader preloader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = SceneManager.LoadSceneAsync(sceneName, (LoadSceneMode)1); if (5__2 == null) { ToastManager.Toast("Error loading scene: " + sceneName); preloader.target--; return false; } preloader.preloadOperationQueue.Add(5__2); preloader.inProgressLoads.Add(5__2); <>2__current = 5__2; <>1__state = 1; return true; case 1: { <>1__state = -1; Scene sceneByName = SceneManager.GetSceneByName(sceneName); try { GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); GameObject[] array = rootGameObjects; for (int i = 0; i < array.Length; i++) { array[i].SetActive(false); } foreach (var scenePreload in scenePreloads) { string item = scenePreload.Item1; IPreloadTarget item2 = scenePreload.Item2; GameObject gameObjectFromArray = ObjectUtils.GetGameObjectFromArray(rootGameObjects, item); if (gameObjectFromArray == null) { Log.Error("could not preload " + item + " in " + sceneName); item2.Set(null, sceneName, item); continue; } GameObject val = Object.Instantiate(gameObjectFromArray); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); AutoAttributeManager.AutoReference(val); preloader.preloadObjs.Add((val, item2)); item2.Set(val, sceneName, item); } } catch (Exception data) { Log.Error(data); } AsyncOperation item3 = SceneManager.UnloadSceneAsync(sceneName); preloader.inProgressUnloads.Add(item3); <>2__current = item3; <>1__state = 2; return true; } case 2: <>1__state = -1; preloader.preloadOperationQueue.Remove(5__2); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__16 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Preloader <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: 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) int num = <>1__state; Preloader preloader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (preloader.preloaded) { Scene activeScene = SceneManager.GetActiveScene(); if (!(((Scene)(ref activeScene)).name == "TitleScreenMenu")) { break; } } <>2__current = preloader.DoPreload(); <>1__state = 1; return true; case 1: <>1__state = -1; break; } preloader.P(1f); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private Action P; private const int PreloadBatchSize = 4; public static bool IsPreloading; private Dictionary> preloadTypes; private bool preloaded; private List<(GameObject, IPreloadTarget)> preloadObjs; private List preloadOperationQueue; private List inProgressLoads; private List inProgressUnloads; private int target; public Preloader(Action onProgress) { P = onProgress; preloadTypes = new Dictionary>(); preloadObjs = new List<(GameObject, IPreloadTarget)>(); preloadOperationQueue = new List(); inProgressLoads = new List(); inProgressUnloads = new List(); base..ctor(); } public void AddPreload(string scene, string path, IPreloadTarget target) { if (!preloadTypes.TryGetValue(scene, out List<(string, IPreloadTarget)> value)) { value = new List<(string, IPreloadTarget)>(); preloadTypes.Add(scene, value); } value.Add((path, target)); } public void AddPreloadList(IEnumerable<(string, string)> paths, List outList) { IPreloadTarget.ListPreloadTarget listPreloadTarget = new IPreloadTarget.ListPreloadTarget(outList); foreach (var (scene, path) in paths) { AddPreload(scene, path, listPreloadTarget); } } public void AddPreloadClass(T obj) { if (IsPreloading) { Log.Error("tried to call AddPreloadClass during preloading"); return; } FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { PreloadAttribute customAttribute = fieldInfo.GetCustomAttribute(); if (customAttribute != null) { AddPreload(customAttribute.Scene, customAttribute.Path, new IPreloadTarget.ReflectionPreloadTarget(obj, fieldInfo)); } } } [IteratorStateMachine(typeof(d__14))] private IEnumerator DoPreloadScene(string sceneName, List<(string, IPreloadTarget)> scenePreloads) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__14(0) { <>4__this = this, sceneName = sceneName, scenePreloads = scenePreloads }; } [IteratorStateMachine(typeof(d__15))] private IEnumerator DoPreload() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__15(0) { <>4__this = this }; } [IteratorStateMachine(typeof(d__16))] internal IEnumerator Preload() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__16(0) { <>4__this = this }; } internal void Unload() { foreach (var (val, preloadTarget) in preloadObjs) { if (Object.op_Implicit((Object)(object)val)) { Object.Destroy((Object)(object)val); } preloadTarget.Unset(val); } preloadObjs.Clear(); } } } namespace NineSolsAPI.Patches { [HarmonyPatch] public class Patches { [HarmonyPatch(typeof(AchievementData), "OnAcquired")] [HarmonyPrefix] private static bool AchievementAcquired(ref AchievementData __instance) { return NineSolsAPICore.AchivementsEnabled; } [HarmonyPatch(typeof(LogoLogic), "Start")] [HarmonyPostfix] private static void Start(ref LogoLogic __instance) { if (!(Application.buildGUID == "d4c12f4d7e8442e79988244014fb92d2")) { RuntimeInitHandler.LoadCore(); SceneManager.LoadScene(__instance.NextScene); } } [HarmonyPatch(typeof(GameLevel), "Awake")] [HarmonyPrefix] private static bool GameLevelAwake() { return !Preloader.IsPreloading; } } [HarmonyPatch] public class PatchesSpeedrunpatch { [HarmonyPatch(typeof(GameFlagManager), "LoadFlags")] [HarmonyPrefix] private static void LoadFlagsPre(out bool __state) { __state = Debug.unityLogger.logEnabled; Debug.unityLogger.logEnabled = false; } [HarmonyPatch(typeof(GameFlagManager), "LoadFlags")] [HarmonyPostfix] private static void LoadFlagsPost(bool __state) { Debug.unityLogger.logEnabled = __state; } [HarmonyPatch(typeof(StatDataCollection), "ClearStats")] [HarmonyPrefix] private static void ClearFlagsPre(out bool __state) { Debug.Log((object)"Clear All Stats"); __state = Debug.unityLogger.logEnabled; Debug.unityLogger.logEnabled = false; } [HarmonyPatch(typeof(StatDataCollection), "ClearStats")] [HarmonyPostfix] private static void ClearFlagsPost(bool __state) { Debug.unityLogger.logEnabled = __state; } } [HarmonyPatch] public class SteamAPI { private const bool ENABLE_STEAM_API = true; [HarmonyPatch(typeof(SteamManager), "Awake")] [HarmonyPrefix] private static bool SteamApiAwake() { return true; } } } namespace NineSolsAPI.Menu { internal class TitlescreenModifications { private UIControlGroup? group; private UIControlButton? button; private const bool Enable = false; public void Load() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) MaybeExtendMainMenu(SceneManager.GetActiveScene()); } public void Unload() { if ((Object)(object)button != (Object)null) { Object.Destroy((Object)(object)((Component)button).gameObject); } if ((Object)(object)group != (Object)null) { Object.Destroy((Object)(object)((Component)group).gameObject); } } public void MaybeExtendMainMenu(Scene scene) { } private UIControlButton CreateOptionsButton() { GameObject val = GameObject.Find("MainMenuButton_Option"); GameObject obj = ObjectUtils.InstantiateAutoReference(val, val.transform.parent, autoReferenceChildren: false); Object.Destroy((Object)(object)obj.GetComponentInChildren()); obj.GetComponentInChildren().text = "Mod Options"; obj.gameObject.transform.SetSiblingIndex(val.transform.GetSiblingIndex() + 1); return obj.GetComponentInChildren(); } private UIControlGroup CreateUiControlGroup() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Expected O, but got Unknown //IL_01fd: Expected O, but got Unknown UICursorProvider componentInChildren = ((Component)SingletonBehaviour.Instance).gameObject.GetComponentInChildren(); GameObject val = new GameObject("ModOptions Panel"); val.transform.SetParent(((Component)componentInChildren).transform, false); RectTransform val2 = val.AddComponent(); UIControlGroup val3 = val.AddComponent(); RCGUIPanel component = val.GetComponent(); val.AddComponent(); val.AddComponent(); val.AddComponent(); AutoAttributeManager.AutoReference(val); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; component.OnShowInit = new UnityEvent(); component.OnHideInit = new UnityEvent(); component.OnShowComplete = new UnityEvent(); component.OnHideComplete = new UnityEvent(); GameObject val4 = new GameObject(); RectTransform obj = val4.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.sizeDelta = new Vector2(600f, 800f); ((HorizontalOrVerticalLayoutGroup)val4.AddComponent()).spacing = 20f; val4.transform.SetParent(((Component)val3).transform, false); GameObject val5 = new GameObject(); ((TMP_Text)val5.AddComponent()).text = "Mod options"; val5.AddComponent(); val5.transform.SetParent(val4.transform, false); GameObject val6 = new GameObject(); val6.AddComponent(); val6.AddComponent(); val6.AddComponent().minHeight = 0f; val6.transform.SetParent(val4.transform, false); Button val7 = ObjectUtils.FindDisabledByName