From 014b6e3227289cde4cbbe4d9a0af76ff1efc013b Mon Sep 17 00:00:00 2001 From: js6pak Date: Sat, 2 Mar 2024 20:09:18 +0100 Subject: [PATCH] Improve handshake popup (#77) --- Reactor/Networking/HandshakePopup.cs | 35 +++++++++++ .../Networking/MakePublicDisallowedPopup.cs | 34 +++++++++++ Reactor/Networking/Patches/HttpPatches.cs | 16 +---- Reactor/ReactorConfig.cs | 7 +++ Reactor/Utilities/UI/ReactorPopup.cs | 58 +++++++++++++++++++ 5 files changed, 137 insertions(+), 13 deletions(-) create mode 100644 Reactor/Networking/HandshakePopup.cs create mode 100644 Reactor/Networking/MakePublicDisallowedPopup.cs create mode 100644 Reactor/Utilities/UI/ReactorPopup.cs diff --git a/Reactor/Networking/HandshakePopup.cs b/Reactor/Networking/HandshakePopup.cs new file mode 100644 index 0000000..cfdd38b --- /dev/null +++ b/Reactor/Networking/HandshakePopup.cs @@ -0,0 +1,35 @@ +using Reactor.Utilities.UI; +using UnityEngine; + +namespace Reactor.Networking; + +internal static class HandshakePopup +{ + public const string Message = + """ + This server doesn't support Reactor's modded handshake. + The lobbies shown could be incompatible with your current mods. + For more info see reactor.gg/handshake + """; + + private static ReactorPopup? _popup; + + public static void Show() + { + if (_popup == null) + { + _popup = ReactorPopup.Create(nameof(HandshakePopup)); + _popup.Background.transform.localPosition = new Vector3(0, 0.20f, 0); + _popup.Background.size = new Vector2(6.5f, 1.7f); + _popup.BackButton.transform.SetLocalY(-0.2f); + } + + var message = ReactorConfig.HandshakePopupMessage.Value; + if (string.IsNullOrEmpty(message)) + { + message = Message; + } + + _popup.Show(message); + } +} diff --git a/Reactor/Networking/MakePublicDisallowedPopup.cs b/Reactor/Networking/MakePublicDisallowedPopup.cs new file mode 100644 index 0000000..7b81275 --- /dev/null +++ b/Reactor/Networking/MakePublicDisallowedPopup.cs @@ -0,0 +1,34 @@ +using Reactor.Utilities.UI; +using UnityEngine; + +namespace Reactor.Networking; + +internal static class MakePublicDisallowedPopup +{ + public const string Message = + """ + You can't make public lobbies on servers that don't support modded handshake. + For more info see reactor.gg/handshake + """; + + private static ReactorPopup? _popup; + + public static void Show() + { + if (_popup == null) + { + _popup = ReactorPopup.Create(nameof(MakePublicDisallowedPopup)); + _popup.Background.transform.localPosition = new Vector3(0, 0.25f, 0); + _popup.Background.size = new Vector2(7.5f, 1.5f); + _popup.BackButton.transform.SetLocalY(-0.1f); + } + + var message = ReactorConfig.MakePublicDisallowedPopupMessage.Value; + if (string.IsNullOrEmpty(message)) + { + message = Message; + } + + _popup.Show(message); + } +} diff --git a/Reactor/Networking/Patches/HttpPatches.cs b/Reactor/Networking/Patches/HttpPatches.cs index 700a077..a47dd98 100644 --- a/Reactor/Networking/Patches/HttpPatches.cs +++ b/Reactor/Networking/Patches/HttpPatches.cs @@ -5,7 +5,6 @@ using HarmonyLib; using UnityEngine; using UnityEngine.Networking; using UnityEngine.UI; -using Object = UnityEngine.Object; namespace Reactor.Networking.Patches; @@ -85,9 +84,9 @@ internal static class HttpPatches if (__instance.GetMethod() == UnityWebRequest.UnityWebRequestMethod.Get) { - if (responseHeader == null) + if (responseHeader == null && ModList.IsAnyModRequiredOnAllClients) { - DisconnectPopup.Instance.ShowCustom("This region doesn't support modded handshake.\nThe lobbies shown may not be compatible with your current mods.\nFor more info see https://reactor.gg/handshake"); + HandshakePopup.Show(); } } @@ -118,16 +117,7 @@ internal static class HttpPatches __instance.MakePublicButton.sprite = __instance.PrivateGameImage; var onClick = __instance.MakePublicButton.GetComponent().OnClick = new Button.ButtonClickedEvent(); - onClick.AddListener((Action) (() => - { - var popup = Object.Instantiate(DiscordManager.Instance.discordPopup, Camera.main!.transform); - var background = popup.transform.Find("Background").GetComponent(); - var size = background.size; - size.x *= 2.5f; - background.size = size; - popup.TextAreaTMP.fontSizeMin = 2; - popup.Show("You can't make public lobbies on regions that don't support modded handshake.\nFor more info see https://reactor.gg/handshake"); - })); + onClick.AddListener((Action) MakePublicDisallowedPopup.Show); if (AmongUsClient.Instance.AmHost && AmongUsClient.Instance.IsGamePublic) { diff --git a/Reactor/ReactorConfig.cs b/Reactor/ReactorConfig.cs index 922535b..b26b77c 100644 --- a/Reactor/ReactorConfig.cs +++ b/Reactor/ReactorConfig.cs @@ -5,11 +5,18 @@ namespace Reactor; internal static class ReactorConfig { public const string FeaturesSection = "Features"; + public const string MessagesSection = "Messages"; public static ConfigEntry ForceDisableServerAuthority { get; private set; } = null!; + public static ConfigEntry HandshakePopupMessage { get; private set; } = null!; + public static ConfigEntry MakePublicDisallowedPopupMessage { get; private set; } = null!; + public static void Bind(ConfigFile config) { ForceDisableServerAuthority = config.Bind(FeaturesSection, nameof(ForceDisableServerAuthority), false, "Enables the DisableServerAuthority flag even when no mods declare it"); + + HandshakePopupMessage = config.Bind(MessagesSection, nameof(HandshakePopupMessage), string.Empty); + MakePublicDisallowedPopupMessage = config.Bind(MessagesSection, nameof(MakePublicDisallowedPopupMessage), string.Empty); } } diff --git a/Reactor/Utilities/UI/ReactorPopup.cs b/Reactor/Utilities/UI/ReactorPopup.cs new file mode 100644 index 0000000..e69901b --- /dev/null +++ b/Reactor/Utilities/UI/ReactorPopup.cs @@ -0,0 +1,58 @@ +using Il2CppInterop.Runtime.Attributes; +using Reactor.Utilities.Attributes; +using TMPro; +using UnityEngine; + +namespace Reactor.Utilities.UI; + +/// +/// Wrapper over that adds hyperlink and controller support. +/// +[RegisterInIl2Cpp] +internal sealed class ReactorPopup : MonoBehaviour +{ + private readonly Il2CppSystem.Collections.Generic.List _selectableHyperLinks = new(); + + public GenericPopup Popup { get; private set; } = null!; + public TextMeshPro TextArea { get; private set; } = null!; + public PassiveButton BackButton { get; private set; } = null!; + public SpriteRenderer Background { get; private set; } = null!; + + [HideFromIl2Cpp] + public void Show(string text) + { + Popup.Show(text); + + ControllerManager.Instance.OpenOverlayMenu(name, BackButton); + + SelectableHyperLinkHelper.AddSelectableUiForHyperlinks(_selectableHyperLinks, name); + TextArea.text = SelectableHyperLinkHelper.DecomposeAnnouncementText(TextArea, _selectableHyperLinks, name, TextArea.text); + SelectableHyperLinkHelper.UpdateHyperlinkPositions(TextArea, _selectableHyperLinks, name); + + ControllerManager.Instance.AddSelectableUiElement(BackButton, true); + } + + public void OnDisable() + { + ControllerManager.Instance.CloseOverlayMenu(name); + } + + [HideFromIl2Cpp] + public static ReactorPopup Create(string name) + { + var genericPopup = Instantiate(DiscordManager.Instance.discordPopup, Camera.main!.transform); + var gameObject = genericPopup.gameObject; + var reactorPopup = gameObject.AddComponent(); + + reactorPopup.Popup = genericPopup; + reactorPopup.TextArea = genericPopup.TextAreaTMP; + reactorPopup.BackButton = gameObject.transform.Find("ExitGame").GetComponent(); + reactorPopup.Background = gameObject.transform.Find("Background").GetComponent(); + + gameObject.name = name; + genericPopup.destroyOnClose = true; + reactorPopup.TextArea.fontSizeMin = 2; + + return reactorPopup; + } +}