using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using JetBrains.Annotations;
using MajesticButton.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MajesticButton")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Azumatt")]
[assembly: AssemblyProduct("MajesticButton")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.0.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
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;
}
}
}
namespace MajesticButton
{
[BepInPlugin("Azumatt.MajesticButton", "MajesticButton", "1.0.5")]
public class MajesticButtonPlugin : BaseUnityPlugin
{
private class ConfigurationManagerAttributes
{
[UsedImplicitly]
public int? Order;
[UsedImplicitly]
public bool? Browsable;
[UsedImplicitly]
public string? Category;
[UsedImplicitly]
public Action<ConfigEntryBase>? CustomDrawer;
}
internal const string ModName = "MajesticButton";
internal const string ModVersion = "1.0.5";
internal const string Author = "Azumatt";
private const string ModGUID = "Azumatt.MajesticButton";
private static string ConfigFileName = "Azumatt.MajesticButton.cfg";
private static string ConfigFileFullPath;
private readonly Harmony _harmony = new Harmony("Azumatt.MajesticButton");
public static readonly ManualLogSource MajesticButtonLogger;
internal static GameObject originalButton;
internal static readonly List<GameObject> clonedButtons;
private string currentScene;
internal static GameObject buttonParent;
internal static ConfigEntry<string> ButtonUrls;
internal static ConfigEntry<string> ButtonTexts;
public void Awake()
{
ButtonUrls = TextEntryConfig("1 - General", "ButtonUrls", "url1,url2,url3", "Comma-separated list of button URLs. For each URL a button will be created at the main menu next to the 'Show Player.log' button. The button will open the URL in the browser when clicked.");
ButtonTexts = TextEntryConfig("1 - General", "ButtonTexts", "Text1,Text2,Text3", "Comma-separated list of button texts. This is the text that is on the button. Defaults to the 'Show Player.log'");
ButtonUrls.SettingChanged += Config_OnSettingChanged;
ButtonTexts.SettingChanged += Config_OnSettingChanged;
SceneManager.activeSceneChanged += OnSceneChanged;
Assembly executingAssembly = Assembly.GetExecutingAssembly();
_harmony.PatchAll(executingAssembly);
SetupWatcher();
}
private void OnDestroy()
{
SceneManager.activeSceneChanged -= OnSceneChanged;
CleanupButtons();
((BaseUnityPlugin)this).Config.Save();
}
private void SetupWatcher()
{
FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName);
fileSystemWatcher.Changed += ReadConfigValues;
fileSystemWatcher.Created += ReadConfigValues;
fileSystemWatcher.Renamed += ReadConfigValues;
fileSystemWatcher.IncludeSubdirectories = true;
fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject;
fileSystemWatcher.EnableRaisingEvents = true;
}
private void ReadConfigValues(object sender, FileSystemEventArgs e)
{
if (!File.Exists(ConfigFileFullPath))
{
return;
}
try
{
MajesticButtonLogger.LogDebug((object)"ReadConfigValues called");
((BaseUnityPlugin)this).Config.Reload();
}
catch
{
MajesticButtonLogger.LogError((object)("There was an issue loading your " + ConfigFileName));
MajesticButtonLogger.LogError((object)"Please check your config entries for spelling and format!");
}
}
private void Config_OnSettingChanged(object sender, EventArgs e)
{
//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 == "start")
{
CleanupButtons();
Functions.UpdateButtons();
}
}
private void OnSceneChanged(Scene oldScene, Scene newScene)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
if (((Scene)(ref oldScene)).name == "start")
{
CleanupButtons();
if ((Object)(object)buttonParent != (Object)null)
{
Object.Destroy((Object)(object)buttonParent);
buttonParent = null;
}
}
if (((Scene)(ref newScene)).name == "start")
{
originalButton = GameObject.Find("GuiRoot/GUI/StartGui/Menu/showlog");
if ((Object)(object)originalButton != (Object)null)
{
buttonParent = new GameObject("ButtonParent");
buttonParent.transform.SetParent(originalButton.transform.parent, true);
buttonParent.transform.localPosition = originalButton.transform.localPosition;
if ((Object)(object)buttonParent.GetComponent<RectTransform>() == (Object)null)
{
RectTransform obj = buttonParent.AddComponent<RectTransform>();
obj.sizeDelta = new Vector2(10f, 30f);
obj.anchorMin = new Vector2(0f, 0f);
obj.anchorMax = new Vector2(0f, 0f);
obj.anchoredPosition = originalButton.GetComponent<RectTransform>().anchoredPosition;
}
originalButton.transform.SetParent(buttonParent.transform, false);
HorizontalLayoutGroup obj2 = buttonParent.AddComponent<HorizontalLayoutGroup>();
((HorizontalOrVerticalLayoutGroup)obj2).spacing = 150f;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
Functions.UpdateButtons();
}
}
currentScene = ((Scene)(ref newScene)).name;
}
private void CleanupButtons()
{
foreach (GameObject item in clonedButtons.Where((GameObject button) => (Object)(object)button != (Object)null))
{
Object.Destroy((Object)(object)item);
}
clonedButtons.Clear();
}
private ConfigEntry<T> config<T>(string group, string name, T value, ConfigDescription description)
{
return ((BaseUnityPlugin)this).Config.Bind<T>(group, name, value, description);
}
private ConfigEntry<T> config<T>(string group, string name, T value, string description)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Expected O, but got Unknown
return config(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
}
internal ConfigEntry<T> TextEntryConfig<T>(string group, string name, T value, string desc, bool synchronizedSetting = true)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Expected O, but got Unknown
ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes
{
CustomDrawer = TextAreaDrawer
};
return config(group, name, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes }));
}
internal static void TextAreaDrawer(ConfigEntryBase entry)
{
GUILayout.ExpandHeight(true);
GUILayout.ExpandWidth(true);
entry.BoxedValue = GUILayout.TextArea((string)entry.BoxedValue, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.ExpandWidth(true),
GUILayout.ExpandHeight(true)
});
}
static MajesticButtonPlugin()
{
string configPath = Paths.ConfigPath;
char directorySeparatorChar = Path.DirectorySeparatorChar;
ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName;
MajesticButtonLogger = Logger.CreateLogSource("MajesticButton");
originalButton = null;
clonedButtons = new List<GameObject>();
}
}
}
namespace MajesticButton.Utils
{
public class Functions
{
private static void InstantiateButton(string url, string text, int index, GameObject originalButton, Vector3 originalPos, int spacing, GameObject sourceButton, ButtonSfx sourceButtonSfx, ButtonTextColor sourceButtonTextColor, Image sourceImage)
{
GameObject val = Object.Instantiate<GameObject>(originalButton, MajesticButtonPlugin.buttonParent.transform);
UpdateButtonImage(originalButton, sourceImage);
AddLayoutElement(originalButton);
IncreaseButtonHeight(originalButton);
AddContentSizeFitter(originalButton);
AddClickEvent(val, url);
AddLayoutElement(val);
UpdateButtonText(val, sourceButton, text);
AddComponentButtonSfx(val, sourceButtonSfx);
AddComponentButtonTextColor(val, sourceButtonTextColor);
UpdateButtonImage(val, sourceImage);
IncreaseButtonHeight(val);
AddContentSizeFitter(val);
MajesticButtonPlugin.clonedButtons.Add(val);
}
private static void AddClickEvent(GameObject button, string url)
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Expected O, but got Unknown
string url2 = url;
button.GetComponent<Button>().onClick = new ButtonClickedEvent();
((UnityEvent)button.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
{
Application.OpenURL(url2);
});
}
private static void AddLayoutElement(GameObject button)
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)button.GetComponent<LayoutElement>() == (Object)null)
{
LayoutElement obj = button.AddComponent<LayoutElement>();
obj.preferredWidth = button.GetComponent<RectTransform>().sizeDelta.x;
obj.preferredHeight = button.GetComponent<RectTransform>().sizeDelta.y;
}
}
private static void UpdateButtonText(GameObject button, GameObject sourceButton, string text)
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
TextMeshProUGUI componentInChildren = button.GetComponentInChildren<TextMeshProUGUI>();
if ((Object)(object)componentInChildren != (Object)null)
{
((TMP_Text)componentInChildren).text = text;
((TMP_Text)componentInChildren).outlineColor = ((TMP_Text)sourceButton.GetComponentInChildren<TextMeshProUGUI>()).outlineColor;
((TMP_Text)componentInChildren).outlineWidth = 0.175f;
}
}
private static void AddComponentButtonSfx(GameObject button, ButtonSfx source)
{
if ((Object)(object)button.GetComponent<ButtonSfx>() == (Object)null)
{
ButtonSfx val = button.AddComponent<ButtonSfx>();
if ((Object)(object)source != (Object)null && (Object)(object)val != (Object)null)
{
val.m_sfxPrefab = source.m_sfxPrefab;
val.m_selectable = source.m_selectable;
val.m_selectSfxPrefab = source.m_selectSfxPrefab;
}
}
}
private static void AddComponentButtonTextColor(GameObject button, ButtonTextColor source)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)button.GetComponent<ButtonTextColor>() == (Object)null)
{
ButtonTextColor val = button.AddComponent<ButtonTextColor>();
if ((Object)(object)source != (Object)null && (Object)(object)val != (Object)null)
{
val.m_button = ((Component)val).GetComponent<Button>();
val.m_text = (TMP_Text)(object)((Component)val).GetComponentInChildren<TextMeshProUGUI>();
val.m_defaultColor = new Color(1f, 0.6313726f, 0.23529412f, 1f);
((Graphic)val.m_text).color = new Color(1f, 0.6313726f, 0.23529412f, 1f);
val.m_textMesh = source.m_textMesh;
val.m_disabledColor = source.m_disabledColor;
val.m_defaultMeshColor = source.m_defaultMeshColor;
}
}
}
private static void UpdateButtonImage(GameObject button, Image source)
{
Image component = button.GetComponent<Image>();
if ((Object)(object)source != (Object)null && (Object)(object)component != (Object)null)
{
component.sprite = source.sprite;
}
}
private static void IncreaseButtonHeight(GameObject button)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
RectTransform component = button.GetComponent<RectTransform>();
Vector2 sizeDelta = component.sizeDelta;
sizeDelta.y *= 1.5f;
component.sizeDelta = sizeDelta;
}
private static void AddContentSizeFitter(GameObject button)
{
if ((Object)(object)button.GetComponent<ContentSizeFitter>() == (Object)null)
{
button.AddComponent<ContentSizeFitter>().horizontalFit = (FitMode)2;
}
}
internal static void UpdateButtons()
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
string[] array = MajesticButtonPlugin.ButtonUrls.Value.Split(new char[1] { ',' });
string[] array2 = MajesticButtonPlugin.ButtonTexts.Value.Split(new char[1] { ',' });
Vector3 localPosition = MajesticButtonPlugin.originalButton.transform.localPosition;
int spacing = 150;
GameObject val = GameObject.Find("GuiRoot/GUI/StartGui/CharacterSelection/SelectCharacter/BottomWindow/Start");
Image sourceImage = ((val != null) ? val.GetComponent<Image>() : null);
ButtonSfx sourceButtonSfx = ((val != null) ? val.GetComponent<ButtonSfx>() : null);
ButtonTextColor sourceButtonTextColor = ((val != null) ? val.GetComponent<ButtonTextColor>() : null);
if (array.Length != array2.Length)
{
MajesticButtonPlugin.MajesticButtonLogger.LogError((object)"URLs and texts arrays have different lengths.");
return;
}
for (int i = 0; i < array.Length; i++)
{
if (i >= array.Length || string.IsNullOrEmpty(array[i]))
{
MajesticButtonPlugin.MajesticButtonLogger.LogWarning((object)$"No URL found for button index {i}, skipping button creation.");
}
else
{
InstantiateButton(array[i], array2[i], i, MajesticButtonPlugin.originalButton, localPosition, spacing, val, sourceButtonSfx, sourceButtonTextColor, sourceImage);
}
}
}
}
}