mirror of
https://github.com/nolen777/eagle0.git
synced 2026-07-29 07:15:58 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b73bb5e5de |
+14
@@ -5,6 +5,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using common;
|
||||
using common.UpdateNotification;
|
||||
using Grpc.Core;
|
||||
using Net.Eagle0.Eagle.Api;
|
||||
using static Net.Eagle0.Eagle.Api.UpdateStreamRequest.Types;
|
||||
@@ -1213,6 +1214,19 @@ namespace eagle {
|
||||
// UNKNOWN is benign (old servers that don't set status)
|
||||
|
||||
break;
|
||||
|
||||
case UpdateStreamResponse.ResponseDetailsOneofCase
|
||||
.ClientUpdateAvailable:
|
||||
var updateNotification = current.ClientUpdateAvailable;
|
||||
_remoteEagleClientLogger.LogLine(
|
||||
$"[UPDATE] Client update available: platform={updateNotification.Platform} " +
|
||||
$"version={updateNotification.Version} required={updateNotification.Required}");
|
||||
// Dispatch to main thread for UI handling
|
||||
MainQueue.Q.Enqueue(() => {
|
||||
UpdateNotificationManager.Instance?.OnClientUpdateAvailable(
|
||||
updateNotification);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
sc = _streamingCall;
|
||||
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
using Net.Eagle0.Eagle.Api;
|
||||
using UnityEngine;
|
||||
|
||||
namespace common.UpdateNotification {
|
||||
/// <summary>
|
||||
/// Manages client update notifications received from the server.
|
||||
/// Shows appropriate UI based on whether the update is required or optional.
|
||||
/// Singleton that persists across scene loads.
|
||||
/// </summary>
|
||||
public class UpdateNotificationManager : MonoBehaviour {
|
||||
public static UpdateNotificationManager Instance { get; private set; }
|
||||
|
||||
[SerializeField]
|
||||
private UpdateNotificationPanel optionalPanel;
|
||||
|
||||
[SerializeField]
|
||||
private UpdateRequiredModal requiredModal;
|
||||
|
||||
private string CurrentPlatform =>
|
||||
Application.platform == RuntimePlatform.OSXPlayer ? "mac" : "windows";
|
||||
|
||||
void Awake() {
|
||||
if (Instance != null && Instance != this) {
|
||||
Debug.LogWarning("[UpdateNotificationManager] Duplicate instance destroyed");
|
||||
Destroy(gameObject);
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
void OnDestroy() {
|
||||
if (Instance == this) { Instance = null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the optional update panel reference.
|
||||
/// </summary>
|
||||
public void SetOptionalPanel(UpdateNotificationPanel panel) { optionalPanel = panel; }
|
||||
|
||||
/// <summary>
|
||||
/// Set the required update modal reference.
|
||||
/// </summary>
|
||||
public void SetRequiredModal(UpdateRequiredModal modal) { requiredModal = modal; }
|
||||
|
||||
/// <summary>
|
||||
/// Handle a ClientUpdateAvailable message from the server.
|
||||
/// Shows the appropriate UI based on platform match and required flag.
|
||||
/// </summary>
|
||||
public void OnClientUpdateAvailable(ClientUpdateAvailable update) {
|
||||
if (update == null) {
|
||||
Debug.LogWarning("[UpdateNotificationManager] Received null update notification");
|
||||
return;
|
||||
}
|
||||
|
||||
// Only show if update is for our platform (or platform is empty = all platforms)
|
||||
if (!string.IsNullOrEmpty(update.Platform) && update.Platform != CurrentPlatform) {
|
||||
Debug.Log(
|
||||
$"[UpdateNotificationManager] Ignoring update for platform '{update.Platform}' " +
|
||||
$"(current: '{CurrentPlatform}')");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log(
|
||||
$"[UpdateNotificationManager] Showing update notification: version={update.Version} " +
|
||||
$"required={update.Required} message={update.Message}");
|
||||
|
||||
string message = string.IsNullOrEmpty(update.Message) ? "A new version is available!"
|
||||
: update.Message;
|
||||
|
||||
if (update.Required) {
|
||||
ShowRequiredUpdate(update.Version, message);
|
||||
} else {
|
||||
ShowOptionalUpdate(update.Version, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowOptionalUpdate(string version, string message) {
|
||||
if (optionalPanel == null) {
|
||||
Debug.LogWarning(
|
||||
"[UpdateNotificationManager] No optional panel assigned, cannot show notification");
|
||||
// Fall back to required modal if optional panel is not available
|
||||
ShowRequiredUpdate(version, message);
|
||||
return;
|
||||
}
|
||||
optionalPanel.Show(version, message);
|
||||
}
|
||||
|
||||
private void ShowRequiredUpdate(string version, string message) {
|
||||
if (requiredModal == null) {
|
||||
Debug.LogWarning(
|
||||
"[UpdateNotificationManager] No required modal assigned, showing log message only");
|
||||
Debug.LogError(
|
||||
$"[CRITICAL] Required client update to version {version}: {message}. Please restart the game.");
|
||||
return;
|
||||
}
|
||||
requiredModal.Show(version, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Quits the application to allow the user to get the update.
|
||||
/// On Mac, Sparkle handles auto-update on relaunch.
|
||||
/// On Windows, the launcher handles updates.
|
||||
/// </summary>
|
||||
public void RestartNow() {
|
||||
Debug.Log("[UpdateNotificationManager] User requested restart for update");
|
||||
#if UNITY_EDITOR
|
||||
UnityEditor.EditorApplication.isPlaying = false;
|
||||
#else
|
||||
Application.Quit();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace common.UpdateNotification {
|
||||
/// <summary>
|
||||
/// Dismissible notification panel for optional updates.
|
||||
/// Shows a small notification bar/toast that the user can dismiss or act on.
|
||||
/// </summary>
|
||||
public class UpdateNotificationPanel : MonoBehaviour {
|
||||
[Header("Panel Elements")]
|
||||
public GameObject panel;
|
||||
|
||||
[Header("Content")]
|
||||
public TextMeshProUGUI versionText;
|
||||
|
||||
public TextMeshProUGUI messageText;
|
||||
|
||||
[Header("Buttons")]
|
||||
public Button restartButton;
|
||||
|
||||
public Button laterButton;
|
||||
|
||||
void Awake() {
|
||||
if (panel != null) panel.SetActive(false);
|
||||
|
||||
if (restartButton != null) restartButton.onClick.AddListener(OnRestartClicked);
|
||||
if (laterButton != null) laterButton.onClick.AddListener(OnLaterClicked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show the optional update notification.
|
||||
/// </summary>
|
||||
public void Show(string version, string message) {
|
||||
if (versionText != null) versionText.text = $"Version {version} available";
|
||||
if (messageText != null) messageText.text = message;
|
||||
|
||||
if (panel != null) panel.SetActive(true);
|
||||
|
||||
Debug.Log($"[UpdateNotificationPanel] Showing optional update: {version}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hide the notification panel.
|
||||
/// </summary>
|
||||
public void Hide() {
|
||||
if (panel != null) panel.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnRestartClicked() {
|
||||
Debug.Log("[UpdateNotificationPanel] Restart button clicked");
|
||||
UpdateNotificationManager.Instance?.RestartNow();
|
||||
}
|
||||
|
||||
private void OnLaterClicked() {
|
||||
Debug.Log("[UpdateNotificationPanel] Later button clicked");
|
||||
Hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace common.UpdateNotification {
|
||||
/// <summary>
|
||||
/// Blocking modal for required updates.
|
||||
/// Cannot be dismissed - user must restart to continue.
|
||||
/// </summary>
|
||||
public class UpdateRequiredModal : MonoBehaviour {
|
||||
[Header("Panel Elements")]
|
||||
public GameObject panel;
|
||||
|
||||
public GameObject modalBlocker;
|
||||
|
||||
[Header("Content")]
|
||||
public TextMeshProUGUI titleText;
|
||||
|
||||
public TextMeshProUGUI versionText;
|
||||
public TextMeshProUGUI messageText;
|
||||
|
||||
[Header("Buttons")]
|
||||
public Button restartButton;
|
||||
|
||||
void Awake() {
|
||||
if (panel != null) panel.SetActive(false);
|
||||
if (modalBlocker != null) modalBlocker.SetActive(false);
|
||||
|
||||
if (restartButton != null) restartButton.onClick.AddListener(OnRestartClicked);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Show the required update modal.
|
||||
/// This modal cannot be dismissed by the user.
|
||||
/// </summary>
|
||||
public void Show(string version, string message) {
|
||||
if (titleText != null) titleText.text = "Update Required";
|
||||
if (versionText != null) versionText.text = $"Version {version}";
|
||||
if (messageText != null) messageText.text = message;
|
||||
|
||||
if (panel != null) panel.SetActive(true);
|
||||
if (modalBlocker != null) modalBlocker.SetActive(true);
|
||||
|
||||
Debug.Log($"[UpdateRequiredModal] Showing required update: {version}");
|
||||
}
|
||||
|
||||
private void OnRestartClicked() {
|
||||
Debug.Log("[UpdateRequiredModal] Restart button clicked");
|
||||
UpdateNotificationManager.Instance?.RestartNow();
|
||||
}
|
||||
|
||||
// Note: No Hide() method intentionally - this modal cannot be dismissed
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user