mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-03-11 10:14:17 +00:00
Merge pull request #541 from misternebula/multiplayer-saves
Multiplayer saves
This commit is contained in:
commit
fdd979fd89
@ -16,6 +16,7 @@ public class Translation
|
||||
public string HostExistingOrNew;
|
||||
public string ExistingSave;
|
||||
public string NewSave;
|
||||
public string CopySave;
|
||||
public string DisconnectAreYouSure;
|
||||
public string Yes;
|
||||
public string No;
|
||||
|
381
QSB/Menus/FourChoicePopupMenu.cs
Normal file
381
QSB/Menus/FourChoicePopupMenu.cs
Normal file
@ -0,0 +1,381 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QSB.Menus;
|
||||
|
||||
[RequireComponent(typeof(Canvas))]
|
||||
public class FourChoicePopupMenu : Menu
|
||||
{
|
||||
public Text _labelText;
|
||||
public SubmitAction _cancelAction;
|
||||
public SubmitAction _ok1Action;
|
||||
public SubmitAction _ok2Action;
|
||||
public SubmitAction _ok3Action;
|
||||
public ButtonWithHotkeyImageElement _cancelButton;
|
||||
public ButtonWithHotkeyImageElement _confirmButton1;
|
||||
public ButtonWithHotkeyImageElement _confirmButton2;
|
||||
public ButtonWithHotkeyImageElement _confirmButton3;
|
||||
public Canvas _rootCanvas;
|
||||
|
||||
protected Canvas _popupCanvas;
|
||||
protected GameObject _blocker;
|
||||
protected bool _closeMenuOnOk = true;
|
||||
protected IInputCommands _ok1Command;
|
||||
protected IInputCommands _ok2Command;
|
||||
protected IInputCommands _ok3Command;
|
||||
protected IInputCommands _cancelCommand;
|
||||
protected bool _usingGamepad;
|
||||
|
||||
public event PopupConfirmEvent OnPopupConfirm1;
|
||||
public event PopupConfirmEvent OnPopupConfirm2;
|
||||
public event PopupConfirmEvent OnPopupConfirm3;
|
||||
public event PopupValidateEvent OnPopupValidate;
|
||||
public event PopupCancelEvent OnPopupCancel;
|
||||
|
||||
public override Selectable GetSelectOnActivate()
|
||||
{
|
||||
_usingGamepad = OWInput.UsingGamepad();
|
||||
return _usingGamepad ? null : _selectOnActivate;
|
||||
}
|
||||
|
||||
public virtual void SetUpPopup(
|
||||
string message,
|
||||
IInputCommands ok1Command,
|
||||
IInputCommands ok2Command,
|
||||
IInputCommands ok3Command,
|
||||
IInputCommands cancelCommand,
|
||||
ScreenPrompt ok1Prompt,
|
||||
ScreenPrompt ok2Prompt,
|
||||
ScreenPrompt ok3Prompt,
|
||||
ScreenPrompt cancelPrompt,
|
||||
bool closeMenuOnOk = true,
|
||||
bool setCancelButtonActive = true)
|
||||
{
|
||||
_labelText.text = message;
|
||||
SetUpPopupCommands(ok1Command, ok2Command, ok3Command, cancelCommand, ok1Prompt, ok2Prompt, ok3Prompt, cancelPrompt);
|
||||
if (!(_cancelAction != null))
|
||||
{
|
||||
Debug.LogWarning("PopupMenu.SetUpPopup Cancel button not set!");
|
||||
return;
|
||||
}
|
||||
|
||||
_cancelAction.gameObject.SetActive(setCancelButtonActive);
|
||||
if (setCancelButtonActive)
|
||||
{
|
||||
_selectOnActivate = _cancelAction.GetRequiredComponent<Selectable>();
|
||||
return;
|
||||
}
|
||||
|
||||
_selectOnActivate = _ok1Action.GetRequiredComponent<Selectable>();
|
||||
}
|
||||
|
||||
public virtual void SetUpPopupCommands(
|
||||
IInputCommands ok1Command,
|
||||
IInputCommands ok2Command,
|
||||
IInputCommands ok3Command,
|
||||
IInputCommands cancelCommand,
|
||||
ScreenPrompt ok1Prompt,
|
||||
ScreenPrompt ok2Prompt,
|
||||
ScreenPrompt ok3Prompt,
|
||||
ScreenPrompt cancelPrompt)
|
||||
{
|
||||
_ok1Command = ok1Command;
|
||||
_ok2Command = ok2Command;
|
||||
_ok3Command = ok3Command;
|
||||
_cancelCommand = cancelCommand;
|
||||
_confirmButton1.SetPrompt(ok1Prompt, InputMode.Menu);
|
||||
_confirmButton2.SetPrompt(ok2Prompt, InputMode.Menu);
|
||||
_confirmButton3.SetPrompt(ok3Prompt, InputMode.Menu);
|
||||
_cancelButton.SetPrompt(cancelPrompt, InputMode.Menu);
|
||||
}
|
||||
|
||||
public virtual void ResetPopup()
|
||||
{
|
||||
_labelText.text = "";
|
||||
_ok1Command = null;
|
||||
_ok2Command = null;
|
||||
_ok3Command = null;
|
||||
_cancelCommand = null;
|
||||
_cancelButton.SetPrompt(null, InputMode.Menu);
|
||||
_confirmButton1.SetPrompt(null, InputMode.Menu);
|
||||
_confirmButton2.SetPrompt(null, InputMode.Menu);
|
||||
_confirmButton3.SetPrompt(null, InputMode.Menu);
|
||||
_selectOnActivate = null;
|
||||
}
|
||||
|
||||
public virtual void CloseMenuOnOk(bool value)
|
||||
{
|
||||
_closeMenuOnOk = value;
|
||||
}
|
||||
|
||||
public virtual bool EventsHaveListeners()
|
||||
{
|
||||
return OnPopupCancel != null
|
||||
|| OnPopupConfirm1 != null
|
||||
|| OnPopupConfirm2 != null
|
||||
|| OnPopupConfirm3 != null;
|
||||
}
|
||||
|
||||
public override void InitializeMenu()
|
||||
{
|
||||
base.InitializeMenu();
|
||||
if (_cancelAction != null)
|
||||
{
|
||||
_cancelAction.OnSubmitAction += InvokeCancel;
|
||||
}
|
||||
|
||||
_ok1Action.OnSubmitAction += InvokeOk1;
|
||||
_ok2Action.OnSubmitAction += InvokeOk2;
|
||||
_ok3Action.OnSubmitAction += InvokeOk3;
|
||||
_popupCanvas = gameObject.GetAddComponent<Canvas>();
|
||||
_popupCanvas.overrideSorting = true;
|
||||
_popupCanvas.sortingOrder = 30000;
|
||||
gameObject.GetAddComponent<GraphicRaycaster>();
|
||||
gameObject.GetAddComponent<CanvasGroup>();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (_cancelCommand != null && OWInput.IsNewlyPressed(_cancelCommand, InputMode.All))
|
||||
{
|
||||
InvokeCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ok1Command != null && OWInput.IsNewlyPressed(_ok1Command, InputMode.All))
|
||||
{
|
||||
InvokeOk1();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ok2Command != null && OWInput.IsNewlyPressed(_ok2Command, InputMode.All))
|
||||
{
|
||||
InvokeOk2();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_ok3Command != null && OWInput.IsNewlyPressed(_ok3Command, InputMode.All))
|
||||
{
|
||||
InvokeOk3();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_usingGamepad != OWInput.UsingGamepad())
|
||||
{
|
||||
_usingGamepad = OWInput.UsingGamepad();
|
||||
if (_usingGamepad)
|
||||
{
|
||||
Locator.GetMenuInputModule().SelectOnNextUpdate(null);
|
||||
return;
|
||||
}
|
||||
|
||||
Locator.GetMenuInputModule().SelectOnNextUpdate(_selectOnActivate);
|
||||
}
|
||||
}
|
||||
|
||||
public override void EnableMenu(bool value)
|
||||
{
|
||||
if (value == _enabledMenu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_enabledMenu = value;
|
||||
if (_enabledMenu && !_initialized)
|
||||
{
|
||||
InitializeMenu();
|
||||
}
|
||||
|
||||
if (!_addToMenuStackManager)
|
||||
{
|
||||
if (_enabledMenu)
|
||||
{
|
||||
Activate();
|
||||
if (_selectOnActivate != null)
|
||||
{
|
||||
var component = _selectOnActivate.GetComponent<SelectableAudioPlayer>();
|
||||
if (component != null)
|
||||
{
|
||||
component.SilenceNextSelectEvent();
|
||||
}
|
||||
|
||||
Locator.GetMenuInputModule().SelectOnNextUpdate(_selectOnActivate);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Deactivate(false);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_enabledMenu)
|
||||
{
|
||||
MenuStackManager.SharedInstance.Push(this, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (MenuStackManager.SharedInstance.Peek() == this)
|
||||
{
|
||||
MenuStackManager.SharedInstance.Pop(false);
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.LogError("Cannot disable Menu unless it is on the top the MenuLayerManager stack. Current menu on top: " + MenuStackManager.SharedInstance.Peek().gameObject.name);
|
||||
}
|
||||
|
||||
public override void Activate()
|
||||
{
|
||||
base.Activate();
|
||||
if (_rootCanvas != null)
|
||||
{
|
||||
_blocker = CreateBlocker(_rootCanvas);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deactivate(bool keepPreviousMenuVisible = false)
|
||||
{
|
||||
if (_rootCanvas != null)
|
||||
{
|
||||
DestroyBlocker(_blocker);
|
||||
}
|
||||
|
||||
var component = _cancelAction.GetComponent<UIStyleApplier>();
|
||||
if (component != null)
|
||||
{
|
||||
component.ChangeState(UIElementState.NORMAL, true);
|
||||
}
|
||||
|
||||
component = _ok1Action.GetComponent<UIStyleApplier>();
|
||||
if (component != null)
|
||||
{
|
||||
component.ChangeState(UIElementState.NORMAL, true);
|
||||
}
|
||||
|
||||
component = _ok2Action.GetComponent<UIStyleApplier>();
|
||||
if (component != null)
|
||||
{
|
||||
component.ChangeState(UIElementState.NORMAL, true);
|
||||
}
|
||||
|
||||
component = _ok3Action.GetComponent<UIStyleApplier>();
|
||||
if (component != null)
|
||||
{
|
||||
component.ChangeState(UIElementState.NORMAL, true);
|
||||
}
|
||||
|
||||
base.Deactivate(keepPreviousMenuVisible);
|
||||
}
|
||||
|
||||
public override void OnCancelEvent(GameObject selectedObj, BaseEventData eventData)
|
||||
{
|
||||
base.OnCancelEvent(selectedObj, eventData);
|
||||
OnPopupCancel?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void InvokeCancel()
|
||||
{
|
||||
EnableMenu(false);
|
||||
OnPopupCancel?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual bool Validate()
|
||||
{
|
||||
var flag = true;
|
||||
if (OnPopupValidate != null)
|
||||
{
|
||||
var invocationList = OnPopupValidate.GetInvocationList();
|
||||
for (var i = 0; i < invocationList.Length; i++)
|
||||
{
|
||||
var flag2 = (bool)invocationList[i].DynamicInvoke(Array.Empty<object>());
|
||||
flag = flag && flag2;
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
protected virtual void InvokeOk1()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_closeMenuOnOk)
|
||||
{
|
||||
EnableMenu(false);
|
||||
}
|
||||
|
||||
OnPopupConfirm1?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void InvokeOk2()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_closeMenuOnOk)
|
||||
{
|
||||
EnableMenu(false);
|
||||
}
|
||||
|
||||
OnPopupConfirm2?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual void InvokeOk3()
|
||||
{
|
||||
if (!Validate())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_closeMenuOnOk)
|
||||
{
|
||||
EnableMenu(false);
|
||||
}
|
||||
|
||||
OnPopupConfirm3?.Invoke();
|
||||
}
|
||||
|
||||
protected virtual GameObject CreateBlocker(Canvas rootCanvas)
|
||||
{
|
||||
var gameObject = new GameObject("Blocker");
|
||||
var rectTransform = gameObject.AddComponent<RectTransform>();
|
||||
rectTransform.SetParent(rootCanvas.transform, false);
|
||||
rectTransform.anchorMin = Vector3.zero;
|
||||
rectTransform.anchorMax = Vector3.one;
|
||||
rectTransform.sizeDelta = Vector2.zero;
|
||||
var canvas = gameObject.AddComponent<Canvas>();
|
||||
canvas.overrideSorting = true;
|
||||
canvas.sortingLayerID = _popupCanvas.sortingLayerID;
|
||||
canvas.sortingOrder = _popupCanvas.sortingOrder - 1;
|
||||
gameObject.AddComponent<GraphicRaycaster>();
|
||||
var image = gameObject.AddComponent<Image>();
|
||||
if (Locator.GetUIStyleManager() != null)
|
||||
{
|
||||
image.color = Locator.GetUIStyleManager().GetPopupBlockerColor();
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
image.color = Color.clear;
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
protected virtual void DestroyBlocker(GameObject blocker)
|
||||
{
|
||||
Destroy(blocker);
|
||||
}
|
||||
|
||||
public delegate void PopupConfirmEvent();
|
||||
|
||||
public delegate bool PopupValidateEvent();
|
||||
|
||||
public delegate void PopupCancelEvent();
|
||||
}
|
@ -3,6 +3,7 @@ using Mirror;
|
||||
using QSB.Localization;
|
||||
using QSB.Messaging;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.SaveSync;
|
||||
using QSB.SaveSync.Messages;
|
||||
using QSB.Utility;
|
||||
using QSB.WorldSync;
|
||||
@ -33,7 +34,7 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
private Button HostButton;
|
||||
private GameObject ConnectButton;
|
||||
private PopupInputMenu ConnectPopup;
|
||||
private ThreeChoicePopupMenu HostGameTypePopup;
|
||||
private FourChoicePopupMenu HostGameTypePopup;
|
||||
private Text _loadingText;
|
||||
private StringBuilder _nowLoadingSB;
|
||||
private const int _titleButtonIndex = 2;
|
||||
@ -131,9 +132,11 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
HostGameTypePopup.SetUpPopup(QSBLocalization.Current.HostExistingOrNew,
|
||||
InputLibrary.menuConfirm,
|
||||
InputLibrary.confirm2,
|
||||
InputLibrary.signalscope,
|
||||
InputLibrary.cancel,
|
||||
new ScreenPrompt(QSBLocalization.Current.ExistingSave),
|
||||
new ScreenPrompt(QSBLocalization.Current.NewSave),
|
||||
new ScreenPrompt(QSBLocalization.Current.CopySave),
|
||||
new ScreenPrompt(QSBLocalization.Current.Cancel));
|
||||
}
|
||||
|
||||
@ -207,6 +210,67 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
return popup;
|
||||
}
|
||||
|
||||
public FourChoicePopupMenu CreateFourChoicePopup(string message, string confirm1Text, string confirm2Text, string confirm3Text, string cancelText)
|
||||
{
|
||||
var newPopup = Instantiate(_threeChoicePopupBase);
|
||||
|
||||
switch (LoadManager.GetCurrentScene())
|
||||
{
|
||||
case OWScene.TitleScreen:
|
||||
newPopup.transform.parent = GameObject.Find("/TitleMenu/PopupCanvas").transform;
|
||||
break;
|
||||
case OWScene.SolarSystem:
|
||||
case OWScene.EyeOfTheUniverse:
|
||||
newPopup.transform.parent = GameObject.Find("/PauseMenu/PopupCanvas").transform;
|
||||
break;
|
||||
}
|
||||
|
||||
newPopup.transform.localPosition = Vector3.zero;
|
||||
newPopup.transform.localScale = Vector3.one;
|
||||
newPopup.GetComponentsInChildren<LocalizedText>().ToList().ForEach(x => Destroy(x));
|
||||
|
||||
var originalPopup = newPopup.GetComponent<PopupMenu>();
|
||||
|
||||
var ok1Button = originalPopup._confirmButton.gameObject;
|
||||
|
||||
var ok2Button = Instantiate(ok1Button, ok1Button.transform.parent);
|
||||
ok2Button.transform.SetSiblingIndex(1);
|
||||
|
||||
var ok3Button = Instantiate(ok1Button, ok1Button.transform.parent);
|
||||
ok3Button.transform.SetSiblingIndex(2);
|
||||
|
||||
var popup = newPopup.AddComponent<FourChoicePopupMenu>();
|
||||
popup._labelText = originalPopup._labelText;
|
||||
popup._cancelAction = originalPopup._cancelAction;
|
||||
popup._ok1Action = originalPopup._okAction;
|
||||
popup._ok2Action = ok2Button.GetComponent<SubmitAction>();
|
||||
popup._ok3Action = ok3Button.GetComponent<SubmitAction>();
|
||||
popup._cancelButton = originalPopup._cancelButton;
|
||||
popup._confirmButton1 = originalPopup._confirmButton;
|
||||
popup._confirmButton2 = ok2Button.GetComponent<ButtonWithHotkeyImageElement>();
|
||||
popup._confirmButton3 = ok3Button.GetComponent<ButtonWithHotkeyImageElement>();
|
||||
popup._rootCanvas = originalPopup._rootCanvas;
|
||||
popup._menuActivationRoot = originalPopup._menuActivationRoot;
|
||||
popup._startEnabled = originalPopup._startEnabled;
|
||||
popup._selectOnActivate = originalPopup._selectOnActivate;
|
||||
popup._selectableItemsRoot = originalPopup._selectableItemsRoot;
|
||||
popup._subMenus = originalPopup._subMenus;
|
||||
popup._menuOptions = originalPopup._menuOptions;
|
||||
popup.SetUpPopup(
|
||||
message,
|
||||
InputLibrary.menuConfirm,
|
||||
InputLibrary.confirm2,
|
||||
InputLibrary.signalscope,
|
||||
InputLibrary.cancel,
|
||||
new ScreenPrompt(confirm1Text),
|
||||
new ScreenPrompt(confirm2Text),
|
||||
new ScreenPrompt(confirm3Text),
|
||||
new ScreenPrompt(cancelText),
|
||||
true,
|
||||
true);
|
||||
return popup;
|
||||
}
|
||||
|
||||
public void LoadGame(bool inEye)
|
||||
{
|
||||
var sceneToLoad = inEye ? OWScene.EyeOfTheUniverse : OWScene.SolarSystem;
|
||||
@ -289,9 +353,16 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
TwoButtonInfoPopup.OnPopupConfirm += () => OnCloseInfoPopup(true);
|
||||
TwoButtonInfoPopup.OnPopupCancel += () => OnCloseInfoPopup(false);
|
||||
|
||||
HostGameTypePopup = CreateThreeChoicePopup(QSBLocalization.Current.HostExistingOrNew, QSBLocalization.Current.ExistingSave, QSBLocalization.Current.NewSave, QSBLocalization.Current.Cancel);
|
||||
HostGameTypePopup = CreateFourChoicePopup(QSBLocalization.Current.HostExistingOrNew, QSBLocalization.Current.ExistingSave, QSBLocalization.Current.NewSave, QSBLocalization.Current.CopySave, QSBLocalization.Current.Cancel);
|
||||
HostGameTypePopup.OnPopupConfirm1 += () => Host(false);
|
||||
HostGameTypePopup.OnPopupConfirm2 += () => Host(true);
|
||||
HostGameTypePopup.OnPopupConfirm3 += () =>
|
||||
{
|
||||
DebugLog.DebugWrite($"Replacing multiplayer save with singleplayer save");
|
||||
QSBCore.IsInMultiplayer = true;
|
||||
StandaloneProfileManager.SharedInstance.SaveGame(QSBProfileManager._currentProfile.gameSave, null, null, null);
|
||||
Host(false);
|
||||
};
|
||||
}
|
||||
|
||||
private static void SetButtonActive(Button button, bool active)
|
||||
@ -421,23 +492,46 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
private void PreHost()
|
||||
{
|
||||
var doesSaveExist = PlayerData.LoadLoopCount() > 1;
|
||||
var profile = QSBProfileManager._currentProfile;
|
||||
var doesSingleplayerSaveExist = profile.gameSave.loopCount > 1;
|
||||
var doesMultiplayerSaveExist = profile.multiplayerGameSave.loopCount > 1;
|
||||
|
||||
if (!doesSaveExist)
|
||||
if (!doesSingleplayerSaveExist)
|
||||
{
|
||||
Host(true);
|
||||
return;
|
||||
DebugLog.DebugWrite($"No singleplayer save exists.");
|
||||
if (!doesMultiplayerSaveExist)
|
||||
{
|
||||
DebugLog.DebugWrite($"No saves exist.");
|
||||
Host(true);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"Multiplayer save exists.");
|
||||
Host(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DebugLog.DebugWrite($"A singleplayer save exists.");
|
||||
HostGameTypePopup.EnableMenu(true);
|
||||
}
|
||||
|
||||
private void Host(bool newSave)
|
||||
private void Host(bool newMultiplayerSave)
|
||||
{
|
||||
if (newSave)
|
||||
QSBCore.IsInMultiplayer = true;
|
||||
|
||||
if (newMultiplayerSave)
|
||||
{
|
||||
DebugLog.DebugWrite($"Resetting game...");
|
||||
PlayerData.ResetGame();
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugLog.DebugWrite($"Loading multiplayer game...");
|
||||
var profile = QSBProfileManager._currentProfile;
|
||||
PlayerData.Init(profile.multiplayerGameSave, profile.settingsSave, profile.graphicsSettings, profile.inputJSON);
|
||||
}
|
||||
|
||||
_intentionalDisconnect = false;
|
||||
|
||||
@ -474,8 +568,12 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
private void Connect()
|
||||
{
|
||||
QSBCore.IsInMultiplayer = true;
|
||||
_intentionalDisconnect = false;
|
||||
|
||||
var profile = QSBProfileManager._currentProfile;
|
||||
PlayerData.Init(profile.multiplayerGameSave, profile.settingsSave, profile.graphicsSettings, profile.inputJSON);
|
||||
|
||||
var address = ConnectPopup.GetInputText();
|
||||
if (address == string.Empty)
|
||||
{
|
||||
@ -506,6 +604,7 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
public void OnKicked(string reason)
|
||||
{
|
||||
QSBCore.IsInMultiplayer = false;
|
||||
_intentionalDisconnect = true;
|
||||
|
||||
PopupClose += _ =>
|
||||
@ -521,6 +620,8 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
|
||||
private void OnDisconnected(string error)
|
||||
{
|
||||
QSBCore.IsInMultiplayer = false;
|
||||
|
||||
if (_intentionalDisconnect)
|
||||
{
|
||||
DebugLog.DebugWrite("intentional disconnect. dont show popup");
|
||||
|
@ -48,7 +48,7 @@ public class QSBCore : ModBehaviour
|
||||
public static AssetBundle ConversationAssetBundle { get; private set; }
|
||||
public static AssetBundle DebugAssetBundle { get; private set; }
|
||||
public static bool IsHost => NetworkServer.active;
|
||||
public static bool IsInMultiplayer => QSBNetworkManager.singleton.isNetworkActive;
|
||||
public static bool IsInMultiplayer;
|
||||
public static string QSBVersion => Helper.Manifest.Version;
|
||||
public static string GameVersion =>
|
||||
// ignore the last patch numbers like the title screen does
|
||||
|
@ -21,6 +21,7 @@ using QSB.Patches;
|
||||
using QSB.Player;
|
||||
using QSB.Player.Messages;
|
||||
using QSB.Player.TransformSync;
|
||||
using QSB.SaveSync;
|
||||
using QSB.ShipSync;
|
||||
using QSB.ShipSync.TransformSync;
|
||||
using QSB.Syncs.Occasional;
|
||||
@ -164,7 +165,7 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
|
||||
}
|
||||
else
|
||||
{
|
||||
PlayerName = StandaloneProfileManager.SharedInstance.currentProfile.profileName;
|
||||
PlayerName = QSBProfileManager._currentProfile.profileName;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
1053
QSB/SaveSync/Patches/ProfileManagerPatches.cs
Normal file
1053
QSB/SaveSync/Patches/ProfileManagerPatches.cs
Normal file
File diff suppressed because it is too large
Load Diff
78
QSB/SaveSync/QSBProfileData.cs
Normal file
78
QSB/SaveSync/QSBProfileData.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace QSB.SaveSync;
|
||||
|
||||
[Serializable]
|
||||
public class QSBProfileData
|
||||
{
|
||||
public string profileName;
|
||||
public DateTime lastModifiedTime;
|
||||
public bool brokenSaveData;
|
||||
public bool brokenMultSaveData;
|
||||
public bool brokenSettingsData;
|
||||
public bool brokenGfxSettingsData;
|
||||
public bool brokenRebindingData;
|
||||
private GameSave _gameSave;
|
||||
private GameSave _multiplayerGameSave;
|
||||
private SettingsSave _settingsSave;
|
||||
private GraphicSettings _graphicsSettings;
|
||||
private string _inputJSON;
|
||||
|
||||
[JsonIgnore]
|
||||
public GameSave gameSave
|
||||
{
|
||||
get => _gameSave;
|
||||
set => _gameSave = value;
|
||||
}
|
||||
|
||||
|
||||
[JsonIgnore]
|
||||
public GameSave multiplayerGameSave
|
||||
{
|
||||
get => _multiplayerGameSave;
|
||||
set => _multiplayerGameSave = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public SettingsSave settingsSave
|
||||
{
|
||||
get => _settingsSave;
|
||||
set => _settingsSave = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public GraphicSettings graphicsSettings
|
||||
{
|
||||
get => _graphicsSettings;
|
||||
set => _graphicsSettings = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public string inputJSON
|
||||
{
|
||||
get => _inputJSON;
|
||||
set => _inputJSON = value;
|
||||
}
|
||||
|
||||
[OnDeserializing]
|
||||
private void SetDefaultValuesOnDeserializing(StreamingContext context)
|
||||
{
|
||||
brokenSaveData = false;
|
||||
brokenMultSaveData = false;
|
||||
brokenSettingsData = false;
|
||||
brokenGfxSettingsData = false;
|
||||
brokenRebindingData = false;
|
||||
}
|
||||
|
||||
[OnDeserialized]
|
||||
private void SetDefaultValuesOnDeserialized(StreamingContext context)
|
||||
{
|
||||
brokenSaveData = false;
|
||||
brokenMultSaveData = false;
|
||||
brokenSettingsData = false;
|
||||
brokenGfxSettingsData = false;
|
||||
brokenRebindingData = false;
|
||||
}
|
||||
}
|
12
QSB/SaveSync/QSBProfileManager.cs
Normal file
12
QSB/SaveSync/QSBProfileManager.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using QSB.Utility;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace QSB.SaveSync;
|
||||
|
||||
public static class QSBProfileManager
|
||||
{
|
||||
public static readonly List<QSBProfileData> _profiles = new();
|
||||
public static QSBProfileData _currentProfile;
|
||||
public static QSBProfileData mostRecentProfile
|
||||
=> _profiles.MaxBy(x => x.lastModifiedTime);
|
||||
}
|
@ -8,9 +8,10 @@
|
||||
"ProductUserID": "Product User ID\n\n(YOUR SAVE DATA WILL BE OVERWRITTEN)",
|
||||
"Connect": "CONNECT",
|
||||
"Cancel": "CANCEL",
|
||||
"HostExistingOrNew": "Do you want to host an existing expedition, or host a new expedition?",
|
||||
"HostExistingOrNew": "Do you want to host an existing multiplayer expedition, host a new expedition, or copy the existing singleplayer expedition to multiplayer?",
|
||||
"ExistingSave": "EXISTING SAVE",
|
||||
"NewSave": "NEW SAVE",
|
||||
"CopySave": "COPY SAVE",
|
||||
"DisconnectAreYouSure": "Are you sure you want to disconnect?\nThis will send you back to the main menu.",
|
||||
"Yes": "YES",
|
||||
"No": "NO",
|
||||
|
@ -8,9 +8,10 @@
|
||||
"ProductUserID": "ID игрока\n\n(ВАШИ СОХРАНЁННЫЕ ДАННЫЕ БУДУТ ПЕРЕЗАПИСАНЫ)",
|
||||
"Connect": "Подключиться",
|
||||
"Cancel": "Отмена",
|
||||
"HostExistingOrNew": "Вы желаете хостить сервер на существующем сохранении, или создать новое?",
|
||||
"HostExistingOrNew": "Вы хотите продолжить существующую мультиплеерную экспедицию, начать новую мультиплеерную экспедицию, или скопировать прогресс из одиночной экспедиции?",
|
||||
"ExistingSave": "СУЩЕСТВУЮЩЕЕ СОХРАНЕНИЕ",
|
||||
"NewSave": "НОВОЕ СОХРАНЕНИЕ",
|
||||
"CopySave" : "СКОПИРОВАТЬ СОХРАНЕНИЕ",
|
||||
"DisconnectAreYouSure": "Вы уверены, что хотите отсоедениться?\nЭто отправит вас обратно в главное меню.",
|
||||
"Yes": "ДА",
|
||||
"No": "НЕТ",
|
||||
|
Loading…
x
Reference in New Issue
Block a user