using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 HarmonyLib;
using I2.Loc;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using NineSolsAPI.Menu;
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("[email protected]")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Nine Sols Modding API")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: AssemblyInformationalVersion("0.4.1+66a8d3a7094ed5e84aff6a8f477efba25dd4a724")]
[assembly: AssemblyProduct("NineSolsAPI")]
[assembly: AssemblyTitle("NineSolsAPI")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/nine-sols-modding/NineSolsAPI")]
[assembly: AssemblyVersion("0.4.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
{
internal class KeyBind
{
public MonoBehaviour Owner;
public Func<KeyboardShortcut> Shortcut;
public Action Action;
}
[PublicAPI]
public class KeybindManager
{
private List<KeyBind> keybindings = new List<KeyBind>();
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<KeyboardShortcut>)(() => shortcut));
}
public static void Add(MonoBehaviour owner, Action action, Func<KeyboardShortcut> shortcut)
{
NineSolsAPICore.Instance.KeybindManager.AddKeybind(owner, action, shortcut);
}
private void AddKeybind(MonoBehaviour owner, Action action, Func<KeyboardShortcut> shortcut)
{
keybindings.Add(new KeyBind
{
Owner = owner,
Action = action,
Shortcut = shortcut
});
}
internal void Update()
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: 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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
bool flag = false;
foreach (KeyBind keybinding in keybindings)
{
if (!Object.op_Implicit((Object)(object)keybinding.Owner))
{
flag = true;
continue;
}
KeyboardShortcut val = keybinding.Shortcut();
bool flag2 = Input.GetKeyDown(((KeyboardShortcut)(ref val)).MainKey);
foreach (KeyCode modifier in ((KeyboardShortcut)(ref val)).Modifiers)
{
flag2 = flag2 && Input.GetKey(modifier);
}
if (flag2)
{
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));
}
}
}
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.0.0")]
public class NineSolsAPICore : BaseUnityPlugin
{
public const string PluginGUID = "ninesolsapi";
public const string PluginName = "NineSolsAPI";
public const string PluginVersion = "1.0.0";
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 const int ProgressWidth = 600;
private const int ProgressHeight = 30;
public static Canvas FullscreenCanvas => Instance.fullscreenCanvas;
private float LoadProgress
{
set
{
SetProgress(value);
if (value >= 1f)
{
OnLoadDone();
}
}
}
public static Preloader Preloader => Instance.preloader;
private void Awake()
{
Instance = this;
Log.Init(((BaseUnityPlugin)this).Logger);
try
{
LoadProgress = 0f;
fullscreenCanvas = CreateFullscreenCanvas();
preloader = new Preloader(delegate(float progress)
{
LoadProgress = progress;
});
ToastManager = new ToastManager();
titlescreenModifications.Load();
SceneManager.sceneLoaded += OnSceneLoaded;
RCGLifeCycle.DontDestroyForever(((Component)this).gameObject);
harmony = Harmony.CreateAndPatchAll(typeof(NineSolsAPICore).Assembly, "ninesolsapi");
}
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");
Canvas obj = val.AddComponent<Canvas>();
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_005d: 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_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Expected O, but got Unknown
//IL_0102: 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_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject();
val.SetActive(false);
val.transform.SetParent(((Component)FullscreenCanvas).transform);
Image val2 = val.AddComponent<Image>();
val2.sprite = NullSprite(new byte[4] { 255, 255, 255, 255 });
val2.useSpriteMesh = true;
RectTransform component = val.GetComponent<RectTransform>();
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<Image>();
val4.sprite = NullSprite(new byte[4] { 52, 52, 235, 255 });
val4.useSpriteMesh = true;
RectTransform component2 = val3.GetComponent<RectTransform>();
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<ToastMessage> toasts = new List<ToastMessage>();
private TMP_Text toastText;
private float Now => Time.realtimeSinceStartup;
public ToastManager()
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("Toast");
val.transform.SetParent(((Component)NineSolsAPICore.FullscreenCanvas).transform);
toastText = (TMP_Text)(object)val.AddComponent<TextMeshProUGUI>();
toastText.alignment = (TextAlignmentOptions)1028;
toastText.fontSize = 20f;
((Graphic)toastText).color = Color.white;
RectTransform component = ((Component)toastText).GetComponent<RectTransform>();
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);
}
[PublicAPI]
public static void Toast(object message)
{
Log.Info($"Toast: {message}");
NineSolsAPICore.Instance.ToastManager.AddToastMessage(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));
}
}
}
public static class PluginInfo
{
public const string PLUGIN_GUID = "NineSolsAPI";
public const string PLUGIN_NAME = "NineSolsAPI";
public const string PLUGIN_VERSION = "0.4.1";
}
}
namespace NineSolsAPI.Utils
{
[PublicAPI]
public static class AssemblyUtils
{
private static Stream? GetEmbeddedResource(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<string>((IEnumerable<string>)manifestResourceNames, (Func<string, string>)null, ", ") + "?"));
return null;
}
return manifestResourceStream;
}
public static AssetBundle? GetEmbeddedAssetBundle(string name)
{
Stream embeddedResource = GetEmbeddedResource(Assembly.GetCallingAssembly(), name);
if (embeddedResource == null)
{
return null;
}
using MemoryStream memoryStream = new MemoryStream();
embeddedResource.CopyTo(memoryStream);
return AssetBundle.LoadFromMemory(memoryStream.ToArray());
}
public static T? GetEmbeddedJson<T>(string name)
{
Stream embeddedResource = GetEmbeddedResource(Assembly.GetCallingAssembly(), name);
if (embeddedResource == null)
{
return default(T);
}
using StreamReader streamReader = new StreamReader(embeddedResource);
return JsonConvert.DeserializeObject<T>(streamReader.ReadToEnd());
}
}
[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<T>(string value)
{
return JsonConvert.DeserializeObject<T>(value);
}
public static T? DeserializeStream<T>(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<T>((JsonReader)(object)val);
}
finally
{
((IDisposable)val)?.Dispose();
}
}
}
[PublicAPI]
public static class ObjectUtils
{
public static GameObject InstantiateAutoReference(GameObject orig, Transform? parent, bool autoReferenceChildren = true)
{
GameObject val = Object.Instantiate<GameObject>(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<GameObject>(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<ILevelAwake>(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<ILevelAwakeReverse>(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<ILevelStart>(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<IResetter>(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_0005: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < SceneManager.sceneCount; i++)
{
GameObject val = LookupPath(SceneManager.GetSceneAt(i), path);
if (val != null)
{
return val;
}
}
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<GameObject>)objects).FirstOrDefault((Func<GameObject, bool>)((GameObject o) => ((Object)o).name == rootName));
if (val == null)
{
Log.Warning("root does not exist: " + rootName);
return null;
}
if (text == null)
{
return val;
}
Transform val2 = val.transform.Find(text);
if (!Object.op_Implicit((Object)(object)val2))
{
Log.Warning("does not exist: " + text + " in " + rootName);
return null;
}
return ((Component)val2).gameObject;
}
public static T? FindDisabledByName<T>(string name) where T : Object
{
string name2 = name;
T? val = Object.FindObjectsOfType<T>(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<string> list = new List<string>();
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<string>((IEnumerable<string>)list, (Func<string, string>)null, "/");
}
}
public static class StringExtensions
{
public static ReadOnlySpan<char> TrimEndMatches(this string str, ReadOnlySpan<char> substr)
{
ReadOnlySpan<char> readOnlySpan = str.AsSpan();
int num = readOnlySpan.LastIndexOf(substr);
if (num != -1)
{
return readOnlySpan.Slice(0, num);
}
return readOnlySpan;
}
public static ReadOnlySpan<char> TrimEndMatches(this ReadOnlySpan<char> span, ReadOnlySpan<char> substr)
{
int num = span.LastIndexOf(substr);
if (num != -1)
{
return span.Slice(0, num);
}
return span;
}
public static ReadOnlySpan<char> TrimStartMatches(this string str, ReadOnlySpan<char> substr)
{
ReadOnlySpan<char> 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<char> TrimStartMatches(this ReadOnlySpan<char> span, ReadOnlySpan<char> substr)
{
int num = span.LastIndexOf(substr);
if (num != -1)
{
int num2 = num + substr.Length;
return span.Slice(num2, span.Length - num2);
}
return span;
}
}
}
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 <instance>P;
[CompilerGenerated]
private FieldInfo <field>P;
public ReflectionPreloadTarget(object instance, FieldInfo field)
{
<instance>P = instance;
<field>P = field;
base..ctor();
}
public void Set(GameObject? preloaded, string scene, string path)
{
<field>P.SetValue(<instance>P, preloaded);
}
public void Unset(GameObject preloaded)
{
<field>P.SetValue(<instance>P, null);
}
}
public class ListPreloadTarget : IPreloadTarget
{
[CompilerGenerated]
private List<GameObject?> <preloads>P;
public ListPreloadTarget(List<GameObject?> preloads)
{
<preloads>P = preloads;
base..ctor();
}
public void Set(GameObject? preloaded, string scene, string path)
{
<preloads>P.Add(preloaded);
}
public void Unset(GameObject preloaded)
{
<preloads>P.Clear();
}
}
void Set(GameObject? preloaded, string scene, string path);
void Unset(GameObject preloaded);
}
[PublicAPI]
public class Preloader
{
[CompilerGenerated]
private Action<float> <onProgress>P;
private const int PreloadBatchSize = 4;
public static bool IsPreloading;
private Dictionary<string, List<(string, IPreloadTarget)>> preloadTypes;
private bool preloaded;
private List<(GameObject, IPreloadTarget)> preloadObjs;
private List<AsyncOperation> preloadOperationQueue;
private List<AsyncOperation> inProgressLoads;
private List<AsyncOperation> inProgressUnloads;
private int target;
public Preloader(Action<float> onProgress)
{
<onProgress>P = onProgress;
preloadTypes = new Dictionary<string, List<(string, IPreloadTarget)>>();
preloadObjs = new List<(GameObject, IPreloadTarget)>();
preloadOperationQueue = new List<AsyncOperation>();
inProgressLoads = new List<AsyncOperation>();
inProgressUnloads = new List<AsyncOperation>();
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<GameObject?> outList)
{
IPreloadTarget.ListPreloadTarget listPreloadTarget = new IPreloadTarget.ListPreloadTarget(outList);
foreach (var (scene, path) in paths)
{
AddPreload(scene, path, listPreloadTarget);
}
}
public void AddPreloadClass<T>(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<PreloadAttribute>();
if (customAttribute != null)
{
AddPreload(customAttribute.Scene, customAttribute.Path, new IPreloadTarget.ReflectionPreloadTarget(obj, fieldInfo));
}
}
}
private IEnumerator DoPreloadScene(string sceneName, List<(string, IPreloadTarget)> scenePreloads)
{
AsyncOperation loadOp = SceneManager.LoadSceneAsync(sceneName, (LoadSceneMode)1);
if (loadOp == null)
{
ToastManager.Toast("Error loading scene: " + sceneName);
target--;
yield break;
}
preloadOperationQueue.Add(loadOp);
inProgressLoads.Add(loadOp);
yield return loadOp;
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<GameObject>(gameObjectFromArray);
val.SetActive(false);
Object.DontDestroyOnLoad((Object)(object)val);
AutoAttributeManager.AutoReference(val);
preloadObjs.Add((val, item2));
item2.Set(val, sceneName, item);
}
}
catch (Exception data)
{
Log.Error(data);
}
AsyncOperation val2 = SceneManager.UnloadSceneAsync(sceneName);
inProgressUnloads.Add(val2);
yield return val2;
preloadOperationQueue.Remove(loadOp);
}
private IEnumerator DoPreload()
{
Log.Info($"Preloading {preloadTypes.Count} scenes");
if (preloadTypes.Count == 0)
{
yield break;
}
Stopwatch watch = Stopwatch.StartNew();
IsPreloading = true;
DestroyAllGameObjects.DestroyingAll = true;
try
{
target = preloadTypes.Count;
Dictionary<string, List<(string, IPreloadTarget)>>.Enumerator preloadsToDo = preloadTypes.GetEnumerator();
float num = 0f;
while (num < 1f)
{
while (preloadOperationQueue.Count < 4 && preloadsToDo.MoveNext())
{
var (sceneName, scenePreloads) = (KeyValuePair<string, List<(string, IPreloadTarget)>>)(ref preloadsToDo.Current);
((MonoBehaviour)NineSolsAPICore.Instance).StartCoroutine(DoPreloadScene(sceneName, scenePreloads));
if (inProgressLoads.Count % 4 == 0)
{
Stopwatch watchRes = Stopwatch.StartNew();
yield return Resources.UnloadUnusedAssets();
watchRes.Stop();
Log.Info($"collecting resources in ${watchRes.ElapsedMilliseconds}");
}
}
yield return null;
float num2 = inProgressLoads.Sum((AsyncOperation loadOp) => loadOp.progress * 0.5f);
num2 += inProgressUnloads.Sum((AsyncOperation loadOp) => loadOp.progress * 0.5f);
num = ((target == 0) ? 1f : (num2 / (float)target));
<onProgress>P(num);
Log.Info($"progress {num}/1, in flight {preloadOperationQueue.Count}");
}
}
finally
{
Preloader preloader = this;
DestroyAllGameObjects.DestroyingAll = false;
IsPreloading = false;
preloader.preloaded = true;
preloader.inProgressLoads.Clear();
preloader.inProgressUnloads.Clear();
preloader.preloadOperationQueue.Clear();
}
watch.Stop();
Log.Info($"Preloading done with {preloadObjs.Count} objects in {watch.ElapsedMilliseconds}ms");
}
internal IEnumerator Preload()
{
if (preloaded)
{
Scene activeScene = SceneManager.GetActiveScene();
if (!(((Scene)(ref activeScene)).name == "TitleScreenMenu"))
{
goto IL_005b;
}
}
yield return DoPreload();
goto IL_005b;
IL_005b:
<onProgress>P(1f);
}
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
{
private const string BUILDGUID_SPEEDRUNPATCH = "d4c12f4d7e8442e79988244014fb92d2";
[HarmonyPatch(typeof(AchievementData), "OnAcquired")]
[HarmonyPrefix]
private static bool AchievementAcquired(ref AchievementData __instance)
{
Log.Info("Prevented Achievement '" + ((Object)__instance).name + "' from activating.");
return false;
}
[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 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<Localize>());
obj.GetComponentInChildren<TMP_Text>().text = "Mod Options";
obj.gameObject.transform.SetSiblingIndex(val.transform.GetSiblingIndex() + 1);
return obj.GetComponentInChildren<UIControlButton>();
}
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<StartMenuLogic>.Instance).gameObject.GetComponentInChildren<UICursorProvider>();
GameObject val = new GameObject("ModOptions Panel");
val.transform.SetParent(((Component)componentInChildren).transform, false);
RectTransform val2 = val.AddComponent<RectTransform>();
UIControlGroup val3 = val.AddComponent<UIControlGroup>();
RCGUIPanel component = val.GetComponent<RCGUIPanel>();
val.AddComponent<CanvasRenderer>();
val.AddComponent<SelectableNavigationProvider>();
val.AddComponent<Animator>();
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<RectTransform>();
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<VerticalLayoutGroup>()).spacing = 20f;
val4.transform.SetParent(((Component)val3).transform, false);
GameObject val5 = new GameObject();
((TMP_Text)val5.AddComponent<TextMeshProUGUI>()).text = "Mod options";
val5.AddComponent<LayoutElement>();
val5.transform.SetParent(val4.transform, false);
GameObject val6 = new GameObject();
val6.AddComponent<CanvasRenderer>();
val6.AddComponent<RectTransform>();
val6.AddComponent<LayoutElement>().minHeight = 0f;
val6.transform.SetParent(val4.transform, false);
Button val7 = ObjectUtils.FindDisabledByName<Button>("Show HUD");
foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
{
ObjectUtils.InstantiateAutoReference(((Component)val7).gameObject, val4.transform).GetComponentInChildren<TMP_Text>().text = $"{pluginInfo.Key} {pluginInfo.Value.Metadata.Version}";
FlagFieldEntryInt val8 = new FlagFieldEntryInt();
GameFlagInt val9 = ScriptableObject.CreateInstance<GameFlagInt>();
((AbstractScriptableData<FlagFieldInt, int>)(object)val9).field = new FlagFieldInt();
((FlagFieldEntry<int>)val8).flagBase = (GameFlagBase)(object)val9;
((FlagFieldEntry<int>)val8).fieldName = "field";
}
val3.defaultSelectable = val4.GetComponentInChildren<Selectable>();
return val3;
}
}
}