Add MainHUD gameplay UI, net handshake updates, and server maintenance mode.
Introduce UiManager/MainHUD prefab flow, strengthen GameNet/WsClient, and add AIServer maintenance endpoint support. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
using AOT.Boot;
|
||||
using HotUpdate.Net;
|
||||
using HotUpdate.UI;
|
||||
using UnityEngine;
|
||||
|
||||
namespace HotUpdate.Gameplay
|
||||
{
|
||||
/// <summary>
|
||||
/// M4 玩法骨架:挂 HUD、角色、网络状态;处理公告与断线重连提示。
|
||||
/// </summary>
|
||||
public sealed class GameplayBootstrap : MonoBehaviour
|
||||
{
|
||||
BootContext _ctx;
|
||||
GameNet _net;
|
||||
MainHudView _hud;
|
||||
ConfirmDialogView _dialog;
|
||||
bool _maintenanceLock;
|
||||
|
||||
public void Bind(BootContext ctx, GameNet net)
|
||||
{
|
||||
_ctx = ctx;
|
||||
_net = net;
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
EnsureUi();
|
||||
WireNet();
|
||||
MaybeShowBootNotice();
|
||||
|
||||
var spawner = gameObject.AddComponent<CharacterSpawner>();
|
||||
spawner.Bind(_ctx);
|
||||
spawner.Spawn();
|
||||
}
|
||||
|
||||
void EnsureUi()
|
||||
{
|
||||
var uiRoot = new GameObject("UiRoot");
|
||||
DontDestroyOnLoad(uiRoot);
|
||||
var mgr = uiRoot.AddComponent<UiManager>();
|
||||
mgr.Init(uiRoot.transform, new UiPrefabLoader());
|
||||
|
||||
var hudGo = mgr.Open(MainHudView.PrefabName);
|
||||
_hud = hudGo != null ? hudGo.GetComponent<MainHudView>() : null;
|
||||
if (_hud == null && hudGo != null)
|
||||
_hud = hudGo.AddComponent<MainHudView>();
|
||||
_hud?.Bind();
|
||||
_hud?.SetStatus("启动中…");
|
||||
if (_hud != null)
|
||||
_hud.OnReconnectClicked += () => _net?.RequestReconnect();
|
||||
|
||||
var dlgGo = mgr.Open(ConfirmDialogView.PrefabName);
|
||||
if (dlgGo != null)
|
||||
{
|
||||
dlgGo.SetActive(false);
|
||||
_dialog = dlgGo.GetComponent<ConfirmDialogView>();
|
||||
if (_dialog == null) _dialog = dlgGo.AddComponent<ConfirmDialogView>();
|
||||
_dialog.Bind();
|
||||
}
|
||||
}
|
||||
|
||||
void WireNet()
|
||||
{
|
||||
if (_net == null) return;
|
||||
_net.OnStatus += s => _hud?.SetStatus(s);
|
||||
_net.OnAuthed += session => _hud?.SetPid(session != null ? session.Pid : 0);
|
||||
_net.OnWsReady += () =>
|
||||
{
|
||||
if (_maintenanceLock) return;
|
||||
_hud?.ShowReconnect(false);
|
||||
_hud?.SetStatus("已连接");
|
||||
};
|
||||
_net.OnWsDisconnected += reason =>
|
||||
{
|
||||
if (_maintenanceLock) return;
|
||||
_hud?.ShowReconnect(true, $"网络已断开({reason}),正在重连…");
|
||||
};
|
||||
_net.OnReconnecting += attempt =>
|
||||
{
|
||||
if (_maintenanceLock) return;
|
||||
_hud?.ShowReconnect(true, $"正在重连…(第 {attempt} 次)");
|
||||
};
|
||||
_net.OnMaintenance += msg =>
|
||||
{
|
||||
_maintenanceLock = true;
|
||||
_hud?.ShowReconnect(false);
|
||||
_hud?.SetStatus("服务器维护中");
|
||||
_dialog?.Show("维护公告", string.IsNullOrEmpty(msg) ? "服务器维护中,请稍后再试。" : msg);
|
||||
};
|
||||
_net.OnWsMessage += TryHandleProtocol;
|
||||
}
|
||||
|
||||
void MaybeShowBootNotice()
|
||||
{
|
||||
if (_ctx == null || string.IsNullOrEmpty(_ctx.Notice)) return;
|
||||
_dialog?.Show("公告", _ctx.Notice);
|
||||
}
|
||||
|
||||
void TryHandleProtocol(string json)
|
||||
{
|
||||
if (string.IsNullOrEmpty(json)) return;
|
||||
// 轻量解析,避免引入完整 JSON 库依赖
|
||||
if (json.IndexOf("\"op\":\"maintenance\"", System.StringComparison.Ordinal) >= 0 ||
|
||||
json.IndexOf("\"op\": \"maintenance\"", System.StringComparison.Ordinal) >= 0)
|
||||
{
|
||||
var msg = ExtractJsonString(json, "message");
|
||||
_net?.NotifyMaintenance(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static string ExtractJsonString(string json, string key)
|
||||
{
|
||||
var token = $"\"{key}\"";
|
||||
var i = json.IndexOf(token, System.StringComparison.Ordinal);
|
||||
if (i < 0) return null;
|
||||
i = json.IndexOf(':', i);
|
||||
if (i < 0) return null;
|
||||
i = json.IndexOf('"', i + 1);
|
||||
if (i < 0) return null;
|
||||
var j = json.IndexOf('"', i + 1);
|
||||
if (j < 0) return null;
|
||||
return json.Substring(i + 1, j - i - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ad4b87bb9c63c5c47a24a609988b37b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user