Merge pull request #313 from misternebula/menus

Menus
This commit is contained in:
_nebula 2021-08-27 13:05:39 +01:00 committed by GitHub
commit a443abf3e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 274 additions and 198 deletions

29
QSB/Menus/IMenuAPI.cs Normal file
View File

@ -0,0 +1,29 @@
using UnityEngine;
using UnityEngine.UI;
namespace QSB.Menus
{
public interface IMenuAPI
{
// Title screen
GameObject TitleScreen_MakeMenuOpenButton(string name, Menu menuToOpen);
GameObject TitleScreen_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null);
Button TitleScreen_MakeSimpleButton(string name);
// Pause menu
GameObject PauseMenu_MakeMenuOpenButton(string name, Menu menuToOpen, Menu customMenu = null);
GameObject PauseMenu_MakeSceneLoadButton(string name, SubmitActionLoadScene.LoadableScenes sceneToLoad, PopupMenu confirmPopup = null, Menu customMenu = null);
Button PauseMenu_MakeSimpleButton(string name, Menu customMenu = null);
Menu PauseMenu_MakePauseListMenu(string title);
// Options
Menu OptionsMenu_MakeNonScrollingOptionsTab(string name);
GameObject OptionsMenu_MakeTwoButtonToggle(string label, string trueText, string falseText, string tooltipText, bool savedValue, Menu menuTab);
GameObject OptionsMenu_MakeNonDisplaySliderElement(string label, string tooltipText, float savedValue, Menu menuTab);
void OptionsMenu_MakeSpacer(float minHeight, Menu menuTab);
void OptionsMenu_MakeLabel(string label, Menu menuTab);
void OptionsMenu_MakeTextInput(string label, string tooltipText, string placeholderText, string savedValue, Menu menuTab);
// Misc
PopupMenu MakeTwoChoicePopup(string message, string confirmText, string cancelText);
PopupInputMenu MakeInputFieldPopup(string message, string placeholderMessage, string confirmText, string cancelText);
PopupMenu MakeInfoPopup(string message, string continueButtonText);
}
}

199
QSB/Menus/MenuManager.cs Normal file
View File

@ -0,0 +1,199 @@
using QSB.Player;
using QSB.Utility;
using QuantumUNET;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
namespace QSB.Menus
{
class MenuManager : MonoBehaviour
{
public static MenuManager Instance;
private IMenuAPI MenuApi => QSBCore.MenuApi;
private PopupMenu PopupMenu;
private Button HostButton;
private GameObject ClientButton;
private Button DisconnectButton;
private PopupMenu InfoPopup;
private bool _addedPauseLock;
public void Start()
{
Instance = this;
MakeTitleMenus();
QSBSceneManager.OnSceneLoaded += OnSceneLoaded;
QSBNetworkManager.Instance.OnClientConnected += OnConnected;
QSBNetworkManager.Instance.OnClientDisconnected += OnDisconnected;
}
void OnSceneLoaded(OWScene oldScene, OWScene newScene, bool isUniverse)
{
if (isUniverse)
{
InitPauseMenus();
return;
}
if (newScene == OWScene.TitleScreen)
{
MakeTitleMenus();
}
}
private void OpenInfoPopup(string message, string buttonText)
{
InfoPopup.SetUpPopup(message, InputLibrary.menuConfirm, InputLibrary.cancel, new ScreenPrompt(buttonText), null, true, false);
OWTime.Pause(OWTime.PauseType.System);
OWInput.ChangeInputMode(InputMode.Menu);
var pauseCommandListener = Locator.GetPauseCommandListener();
if (pauseCommandListener != null)
{
pauseCommandListener.AddPauseCommandLock();
_addedPauseLock = true;
}
InfoPopup.EnableMenu(true);
}
private void OnCloseInfoPopup()
{
var pauseCommandListener = Locator.GetPauseCommandListener();
if (pauseCommandListener != null && _addedPauseLock)
{
pauseCommandListener.RemovePauseCommandLock();
_addedPauseLock = false;
}
OWTime.Unpause(OWTime.PauseType.System);
OWInput.RestorePreviousInputs();
}
private void CreateCommonPopups()
{
PopupMenu = MenuApi.MakeInputFieldPopup("IP Address", "IP Address", "Connect", "Cancel");
PopupMenu.OnPopupConfirm += Connect;
InfoPopup = MenuApi.MakeInfoPopup("", "");
InfoPopup.OnDeactivateMenu += OnCloseInfoPopup;
}
private void InitPauseMenus()
{
CreateCommonPopups();
HostButton = MenuApi.PauseMenu_MakeSimpleButton("MULTIPLAYER (HOST)");
HostButton.onClick.AddListener(Host);
ClientButton = MenuApi.PauseMenu_MakeMenuOpenButton("MULTIPLAYER (CONNECT)", PopupMenu);
DisconnectButton = MenuApi.PauseMenu_MakeSimpleButton("DISCONNECT");
DisconnectButton.onClick.AddListener(Disconnect);
DisconnectButton.gameObject.SetActive(false);
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
}
private void MakeTitleMenus()
{
CreateCommonPopups();
HostButton = MenuApi.TitleScreen_MakeSimpleButton("MULTIPLAYER (HOST)");
HostButton.onClick.AddListener(Host);
ClientButton = MenuApi.TitleScreen_MakeMenuOpenButton("MULTIPLAYER (CONNECT)", PopupMenu);
DisconnectButton = MenuApi.TitleScreen_MakeSimpleButton("DISCONNECT");
DisconnectButton.onClick.AddListener(Disconnect);
DisconnectButton.gameObject.SetActive(false);
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
}
private void Disconnect()
{
QSBNetworkManager.Instance.StopHost();
DisconnectButton.gameObject.SetActive(false);
ClientButton.SetActive(true);
HostButton.gameObject.SetActive(true);
}
private void Host()
{
QSBNetworkManager.Instance.StartHost();
DisconnectButton.gameObject.SetActive(true);
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
ClientButton.SetActive(false);
HostButton.gameObject.SetActive(false);
}
private void Connect()
{
QSBNetworkManager.Instance.networkAddress = (PopupMenu as PopupInputMenu).GetInputText();
QSBNetworkManager.Instance.StartClient();
DisconnectButton.transform.GetChild(0).GetChild(1).GetComponent<Text>().text = "CONNECTING... (STOP)";
DisconnectButton.gameObject.SetActive(true);
DisconnectButton.GetComponent<CanvasGroup>().alpha = 1f;
ClientButton.SetActive(false);
HostButton.gameObject.SetActive(false);
}
private void OnConnected()
{
DebugLog.DebugWrite($"ON CONNECTED");
var text = QSBCore.IsHost
? "STOP HOSTING"
: "DISCONNECT";
DisconnectButton.transform.GetChild(0).GetChild(1).GetComponent<Text>().text = text;
}
public void OnKicked(KickReason reason)
{
string text;
switch (reason)
{
case KickReason.QSBVersionNotMatching:
text = "Server refused connection as QSB version does not match.";
break;
case KickReason.GameVersionNotMatching:
text = "Server refused connection as Outer Wilds version does not match.";
break;
default:
text = $"Kicked from server. KickReason:{reason}";
break;
}
OpenInfoPopup(text, "OK");
DisconnectButton.gameObject.SetActive(false);
ClientButton.SetActive(true);
HostButton.gameObject.SetActive(true);
}
private void OnDisconnected(NetworkError error)
{
if (error == NetworkError.Ok)
{
return;
}
string text;
switch (error)
{
case NetworkError.Timeout:
text = "Connection timed out. Either the server does not exist, or it has stopped responding.";
break;
default:
text = $"Disconnected due to error. NetworkError:{error}";
break;
}
OpenInfoPopup(text, "OK");
DisconnectButton.gameObject.SetActive(false);
ClientButton.SetActive(true);
HostButton.gameObject.SetActive(true);
}
}
}

View File

@ -1,4 +1,5 @@
using QSB.Events;
using QSB.Menus;
using QSB.Messaging;
using QSB.Utility;
using QuantumUNET;
@ -49,6 +50,7 @@ namespace QSB.Player.Events
}
DebugLog.ToAll($"Kicked from server. Reason : {message.EnumValue}");
MenuManager.Instance.OnKicked(message.EnumValue);
}
}
}

View File

@ -9,7 +9,6 @@ namespace QSB.ProbeSync
public OWAudioSource _flightLoopAudio;
public OWAudioSource _anchorAudio;
public ParticleSystem _anchorParticles;
public ParticleSystem _underwaterAnchorParticles;
private QSBProbe _probe;

View File

@ -12,7 +12,6 @@ namespace QSB.ProbeSync
private QSBProbe _probe;
private OWLight2 _light;
private bool _inFlight;
private float _timer;
private void Awake()
@ -64,15 +63,12 @@ namespace QSB.ProbeSync
{
StartFadeIn();
}
_inFlight = true;
}
private void OnAnchorOrRetrieve()
{
_light.GetLight().enabled = false;
enabled = false;
_inFlight = false;
}
}
}

View File

@ -170,6 +170,8 @@
<Compile Include="Instruments\QSBCamera\CameraManager.cs" />
<Compile Include="Instruments\QSBCamera\CameraMode.cs" />
<Compile Include="Instruments\InstrumentsManager.cs" />
<Compile Include="Menus\IMenuAPI.cs" />
<Compile Include="Menus\MenuManager.cs" />
<Compile Include="Messaging\BoolMessage.cs" />
<Compile Include="OrbSync\TransformSync\NomaiOrbTransformSync.cs" />
<Compile Include="Player\Events\PlayerInformationEvent.cs" />
@ -228,7 +230,6 @@
<Compile Include="ProbeSync\QSBProbeEffects.cs" />
<Compile Include="ProbeSync\QSBProbeLantern.cs" />
<Compile Include="ProbeSync\QSBProbeSpotlight.cs" />
<Compile Include="QSBNetworkLobby.cs" />
<Compile Include="Patches\QSBPatch.cs" />
<Compile Include="Patches\QSBPatchTypes.cs" />
<Compile Include="QSBSceneManager.cs" />
@ -432,4 +433,9 @@ copy /y "$(ProjectDir)\manifest.json" "$(OwmlDir)\Mods\$(ProjectName)"
copy /y "$(SolutionDir)\WeavedFiles\QSB.dll" "$(OwmlDir)\Mods\$(ProjectName)"</PostBuildEvent>
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties manifest_1json__JsonSchema="" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<GameDir>E:\Epic\Epic Games\OuterWilds</GameDir>
<GameDir>D:\EpicGames\OuterWilds</GameDir>
<OwmlDir>C:\Users\Henry\AppData\Roaming\OuterWildsModManager\OWML</OwmlDir>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>

View File

@ -10,6 +10,7 @@ using QSB.ElevatorSync;
using QSB.GeyserSync;
using QSB.Inputs;
using QSB.ItemSync;
using QSB.Menus;
using QSB.OrbSync;
using QSB.Patches;
using QSB.Player;
@ -64,6 +65,7 @@ namespace QSB
public static bool IsInMultiplayer => QNetworkManager.singleton.isNetworkActive;
public static string QSBVersion => Helper.Manifest.Version;
public static string GameVersion => Application.version;
public static IMenuAPI MenuApi { get; private set; }
public void Awake()
{
@ -77,6 +79,8 @@ namespace QSB
Helper = ModHelper;
DebugLog.ToConsole($"* Start of QSB version {QSBVersion} - authored by {Helper.Manifest.Author}", MessageType.Info);
MenuApi = ModHelper.Interaction.GetModApi<IMenuAPI>("_nebula.MenuFramework");
NetworkAssetBundle = Helper.Assets.LoadBundle("assets/network");
InstrumentAssetBundle = Helper.Assets.LoadBundle("assets/instruments");
ConversationAssetBundle = Helper.Assets.LoadBundle("assets/conversation");
@ -84,7 +88,6 @@ namespace QSB
QSBPatchManager.Init();
gameObject.AddComponent<QSBNetworkManager>();
gameObject.AddComponent<QNetworkManagerHUD>();
gameObject.AddComponent<DebugActions>();
gameObject.AddComponent<ConversationManager>();
gameObject.AddComponent<QSBInputManager>();
@ -92,6 +95,7 @@ namespace QSB
gameObject.AddComponent<RepeatingManager>();
gameObject.AddComponent<PlayerEntanglementWatcher>();
gameObject.AddComponent<DebugGUI>();
gameObject.AddComponent<MenuManager>();
gameObject.AddComponent<RespawnManager>();
// WorldObject managers
@ -113,9 +117,6 @@ namespace QSB
Helper.HarmonyHelper.EmptyMethod<ModCommandListener>("Update");
// Stop players being able to pause
Helper.HarmonyHelper.EmptyMethod(typeof(OWTime).GetMethod("Pause"));
QSBPatchManager.OnPatchType += OnPatchType;
QSBPatchManager.OnUnpatchType += OnUnpatchType;
}

View File

@ -1,71 +0,0 @@
using OWML.Utils;
using QuantumUNET;
using System;
using System.Linq;
using UnityEngine;
namespace QSB
{
public class QSBNetworkLobby : QNetworkBehaviour
{
public bool CanEditName { get; set; }
public string PlayerName { get; private set; }
// TODO : Could delete a lot of this - shouldnt be possible to not have a profile and still play
private readonly string[] _defaultNames = {
"Arkose",
"Chert",
"Esker",
"Hal",
"Hornfels",
"Feldspar",
"Gabbro",
"Galena",
"Gneiss",
"Gossan",
"Marl",
"Mica",
"Moraine",
"Porphy",
"Riebeck",
"Rutile",
"Slate",
"Spinel",
"Tektite",
"Tephra",
"Tuff",
"Jinha"
};
public void Awake()
{
PlayerName = GetPlayerName();
CanEditName = true;
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile?.profileName;
return !string.IsNullOrEmpty(profileName)
? profileName
: _defaultNames.OrderBy(x => Guid.NewGuid()).First();
}
public void OnGUI()
{
GUI.Label(new Rect(10, 10, 200f, 20f), "Name:");
if (CanEditName)
{
PlayerName = GUI.TextField(new Rect(60, 10, 145, 20f), PlayerName);
}
else
{
GUI.Label(new Rect(60, 10, 145, 20f), PlayerName);
}
}
}
}

View File

@ -30,15 +30,17 @@ namespace QSB
public static QSBNetworkManager Instance { get; private set; }
public event Action OnNetworkManagerReady;
public event Action OnClientConnected;
public event Action<NetworkError> OnClientDisconnected;
public bool IsReady { get; private set; }
public GameObject OrbPrefab { get; private set; }
public GameObject ShipPrefab { get; private set; }
public string PlayerName { get; private set; }
private const int MaxConnections = 128;
private const int MaxBufferedPackets = 64;
private QSBNetworkLobby _lobby;
private AssetBundle _assetBundle;
private GameObject _probePrefab;
private bool _everConnected;
@ -48,7 +50,7 @@ namespace QSB
base.Awake();
Instance = this;
_lobby = gameObject.AddComponent<QSBNetworkLobby>();
PlayerName = GetPlayerName();
_assetBundle = QSBCore.NetworkAssetBundle;
playerPrefab = _assetBundle.LoadAsset<GameObject>("assets/NETWORK_Player_Body.prefab");
@ -82,6 +84,15 @@ namespace QSB
ConfigureNetworkManager();
}
private string GetPlayerName()
{
var profileManager = StandaloneProfileManager.SharedInstance;
profileManager.Initialize();
var profile = profileManager.GetValue<StandaloneProfileManager.ProfileData>("_currentProfile");
var profileName = profile.profileName;
return profileName;
}
private void SetupNetworkId(GameObject go)
{
var ident = go.AddComponent<QNetworkIdentity>();
@ -148,6 +159,8 @@ namespace QSB
DebugLog.DebugWrite("OnClientConnect", MessageType.Info);
base.OnClientConnect(connection);
OnClientConnected?.SafeInvoke();
QSBEventManager.Init();
gameObject.AddComponent<RespawnOnDeath>();
@ -163,13 +176,11 @@ namespace QSB
QSBPatchManager.DoPatchType(specificType);
QSBPatchManager.DoPatchType(QSBPatchTypes.OnClientConnect);
_lobby.CanEditName = false;
OnNetworkManagerReady?.SafeInvoke();
IsReady = true;
QSBCore.UnityEvents.RunWhen(() => QSBEventManager.Ready && PlayerTransformSync.LocalInstance != null,
() => QSBEventManager.FireEvent(EventNames.QSBPlayerJoin, _lobby.PlayerName));
() => QSBEventManager.FireEvent(EventNames.QSBPlayerJoin, PlayerName));
if (!QSBCore.IsHost)
{
@ -201,12 +212,16 @@ namespace QSB
QSBPatchManager.DoUnpatchType(QSBPatchTypes.OnClientConnect);
}
_lobby.CanEditName = true;
IsReady = false;
_everConnected = false;
}
public override void OnClientDisconnect(QNetworkConnection conn)
{
base.OnClientDisconnect(conn);
OnClientDisconnected?.SafeInvoke(conn.LastError);
}
public override void OnServerDisconnect(QNetworkConnection connection) // Called on the server when any client disconnects
{
base.OnServerDisconnect(connection);

View File

@ -7,7 +7,10 @@ namespace QSB.TimeSync.Patches
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
public override void DoPatches()
=> Prefix(nameof(PlayerCameraEffectController_OnStartOfTimeLoop));
{
Prefix(nameof(PlayerCameraEffectController_OnStartOfTimeLoop));
Empty("OWTime_Pause");
}
public static bool PlayerCameraEffectController_OnStartOfTimeLoop()
=> false;

View File

@ -31,7 +31,6 @@ namespace QSB.TimeSync
private float _sendTimer;
private float _serverTime;
private bool _isFirstFastForward = true;
private int _serverLoopCount;
private bool _hasWokenUp;
@ -46,7 +45,6 @@ namespace QSB.TimeSync
if (QSBSceneManager.IsInUniverse)
{
_isFirstFastForward = false;
Init();
}
@ -203,7 +201,6 @@ namespace QSB.TimeSync
CurrentReason = null;
DebugLog.DebugWrite($"RESET TIMESCALE", MessageType.Info);
_isFirstFastForward = false;
Physics.SyncTransforms();
SpinnerUI.Hide();
TimeSyncUI.Stop();

View File

@ -5,9 +5,10 @@
"description": "Adds online multiplayer to the game.",
"warning": {
"title": "Follow these steps before playing multiplayer :",
"body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications.\n- Make sure you have forwarded/opened the correct ports. (See the GitHub readme.)"
"body": "- Disable *all* other mods. (Can heavily affect performance)\n- Make sure you are not running any other network-intensive applications.\n- Make sure you have forwarded/opened the correct ports. (See the GitHub readme.)"
},
"uniqueName": "Raicuparta.QuantumSpaceBuddies",
"version": "0.12.0-pr2",
"owmlVersion": "1.1.8"
"owmlVersion": "1.1.8",
"dependencies": [ "_nebula.MenuFramework" ]
}

View File

@ -1,100 +0,0 @@
using UnityEngine;
namespace QuantumUNET.Components
{
public class QNetworkManagerHUD : MonoBehaviour
{
public QNetworkManager Manager;
public bool ShowGUI = true;
private void Awake()
=> Manager = GetComponent<QNetworkManager>();
private void OnGUI()
{
if (ShowGUI)
{
var xOffset = 10;
var yOffset = 30;
var flag = Manager.client == null || Manager.client.connection == null || Manager.client.connection.connectionId == -1;
if (!Manager.IsClientConnected() && !QNetworkServer.active)
{
if (flag)
{
if (Application.platform != RuntimePlatform.WebGLPlayer)
{
if (GUI.Button(new Rect(xOffset, yOffset, 200f, 20f), "Host"))
{
Manager.StartHost();
}
yOffset += 20;
}
if (GUI.Button(new Rect(xOffset, yOffset, 105f, 20f), "Connect"))
{
Manager.StartClient();
}
Manager.networkAddress = GUI.TextField(new Rect(xOffset + 100, yOffset, 95f, 20f), Manager.networkAddress);
yOffset += 20;
}
else
{
GUI.Label(new Rect(xOffset, yOffset, 200f, 20f),
$"Connecting to {Manager.networkAddress}:{Manager.networkPort}..");
yOffset += 24;
if (GUI.Button(new Rect(xOffset, yOffset, 200f, 20f), "Cancel Connection Attempt"))
{
Manager.StopClient();
}
}
}
else
{
if (QNetworkServer.active)
{
var text = $"Hosting on port {Manager.networkPort}";
if (Manager.useWebSockets)
{
text += " (using WebSockets)";
}
GUI.Label(new Rect(xOffset, yOffset, 300f, 20f), text);
yOffset += 20;
}
if (Manager.IsClientConnected())
{
GUI.Label(new Rect(xOffset, yOffset, 300f, 20f), $"Connected to {Manager.networkAddress}, port {Manager.networkPort}");
yOffset += 20;
}
}
if (Manager.IsClientConnected() && !QClientScene.ready)
{
if (GUI.Button(new Rect(xOffset, yOffset, 200f, 20f), "Client Ready"))
{
QClientScene.Ready(Manager.client.connection);
if (QClientScene.localPlayers.Count == 0)
{
QClientScene.AddPlayer(0);
}
}
yOffset += 20;
}
if (QNetworkServer.active || Manager.IsClientConnected())
{
if (GUI.Button(new Rect(xOffset, yOffset, 200f, 20f), "Stop"))
{
Manager.StopHost();
}
yOffset += 20;
}
}
}
}
}

View File

@ -57,7 +57,7 @@
</Reference>
<Reference Include="UnityEngine.PhysicsModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>E:\Epic\Epic Games\OuterWilds\OuterWilds_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
<HintPath>$(GameDir)\OuterWilds_Data\Managed\UnityEngine.PhysicsModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UNETModule, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@ -90,7 +90,6 @@
<Compile Include="QNetworkConnection.cs" />
<Compile Include="QNetworkCRC.cs" />
<Compile Include="Components\QNetworkIdentity.cs" />
<Compile Include="Components\QNetworkManagerHUD.cs" />
<Compile Include="Components\QNetworkManager.cs" />
<Compile Include="Messages\QNetworkMessage.cs" />
<Compile Include="Messages\QNetworkMessageDelegate.cs" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<GameDir>E:\Epic\Epic Games\OuterWilds</GameDir>
<GameDir>D:\EpicGames\OuterWilds</GameDir>
<OwmlDir>C:\Users\Henry\AppData\Roaming\OuterWildsModManager\OWML</OwmlDir>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>