feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
This commit is contained in:
@@ -3,6 +3,8 @@ using System.Threading.Tasks;
|
||||
using asap.core;
|
||||
using Game;
|
||||
using UnityEngine;
|
||||
using System;
|
||||
using game.PlayerDataStorage;
|
||||
|
||||
namespace game
|
||||
{
|
||||
@@ -27,6 +29,61 @@ namespace game
|
||||
int _unitOfWeight = 1;
|
||||
bool? _showNotice;
|
||||
|
||||
readonly bool requiresFormalKV;
|
||||
PlayerKVGameSessionHandle promptOwner;
|
||||
internal PlayerKVEditResult LastPromptEdit { get; private set; }
|
||||
internal bool HasKVPromptOwner => promptOwner != null;
|
||||
|
||||
// Preserve only our key/owner/error metadata across void UI boundaries, never platform payloads.
|
||||
internal static InvalidOperationException PromptFailure(string message)
|
||||
{
|
||||
var error = new InvalidOperationException(message);
|
||||
error.Data["B01PromptDiagnostic"] = message;
|
||||
return error;
|
||||
}
|
||||
internal static void LogPromptFailure(Exception error) => Debug.LogError(
|
||||
error.Data["B01PromptDiagnostic"] as string ?? "Notification prompt stopped: " + error.GetType().Name);
|
||||
|
||||
public DefaultSettingService() : this(false) { }
|
||||
internal DefaultSettingService(bool formalKV) { requiresFormalKV = formalKV; }
|
||||
internal DefaultSettingService(PlayerKVGameSessionHandle owner) : this(true)
|
||||
{
|
||||
promptOwner = owner ?? throw new ArgumentNullException(nameof(owner));
|
||||
RequirePromptOwner();
|
||||
}
|
||||
|
||||
// The frozen startup selection is supplied before login; this instance can never change owners.
|
||||
internal void PreflightFormalPromptOwner(PlayerKVGameSessionHandle owner)
|
||||
{
|
||||
if (!requiresFormalKV || owner == null || (promptOwner != null && !ReferenceEquals(promptOwner, owner)))
|
||||
throw PromptFailure("ShowNotice: formal owner mismatch.");
|
||||
var read = KVMgr.ReadKV(owner, "ShowNotice");
|
||||
if (!read.Success) throw PromptFailure($"ShowNotice owner={owner.OwnerInstanceId}: {read.Error}");
|
||||
}
|
||||
internal void BindFormalPromptOwner(PlayerKVGameSessionHandle owner)
|
||||
{
|
||||
PreflightFormalPromptOwner(owner);
|
||||
if (promptOwner == null) promptOwner = owner;
|
||||
RequirePromptOwner();
|
||||
}
|
||||
internal bool HasFormalPromptOwner(PlayerKVGameSessionHandle owner) =>
|
||||
requiresFormalKV && ReferenceEquals(promptOwner, owner);
|
||||
internal void RequirePromptOwner()
|
||||
{
|
||||
if (promptOwner != null) ReadPrompt();
|
||||
else if (requiresFormalKV) throw PromptFailure("ShowNotice: formal owner not handed off.");
|
||||
}
|
||||
|
||||
PlayerKVKeyReadResult ReadPrompt()
|
||||
{
|
||||
if (LastPromptEdit != null && !LastPromptEdit.Accepted)
|
||||
throw PromptFailure($"ShowNotice owner={promptOwner.OwnerInstanceId}: {LastPromptEdit.StateResult.Error}; uncertain={LastPromptEdit.StateResult.LocalCommitMayHaveSucceeded}");
|
||||
var read = KVMgr.ReadKV(promptOwner, "ShowNotice");
|
||||
if (!read.Success)
|
||||
throw PromptFailure($"ShowNotice owner={promptOwner.OwnerInstanceId}: {read.Error}");
|
||||
return read;
|
||||
}
|
||||
|
||||
public bool Music
|
||||
{
|
||||
set
|
||||
@@ -105,11 +162,33 @@ namespace game
|
||||
{
|
||||
get
|
||||
{
|
||||
if (requiresFormalKV && promptOwner == null) RequirePromptOwner();
|
||||
if (promptOwner != null)
|
||||
{
|
||||
var read = ReadPrompt();
|
||||
_showNotice = read.Found == true && read.Value == "1";
|
||||
return _showNotice.Value;
|
||||
}
|
||||
_showNotice ??= PlayFabMgr.Instance.GetLocalData("ShowNotice") == "1";
|
||||
return _showNotice.Value;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (requiresFormalKV && promptOwner == null) RequirePromptOwner();
|
||||
if (promptOwner != null)
|
||||
{
|
||||
var read = ReadPrompt();
|
||||
var serialized = value ? "1" : "0";
|
||||
if (read.Found != true || read.Value != serialized)
|
||||
{
|
||||
LastPromptEdit = KVMgr.WriteKV(promptOwner, "ShowNotice", serialized);
|
||||
if (!LastPromptEdit.Accepted)
|
||||
throw PromptFailure($"ShowNotice owner={promptOwner.OwnerInstanceId}: {LastPromptEdit.StateResult.Error}; uncertain={LastPromptEdit.StateResult.LocalCommitMayHaveSucceeded}");
|
||||
}
|
||||
RequirePromptOwner();
|
||||
_showNotice = value;
|
||||
return;
|
||||
}
|
||||
if (value != _showNotice)
|
||||
{
|
||||
_showNotice = value;
|
||||
@@ -156,7 +235,9 @@ namespace game
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (GContext.container.Resolve<ILocalNotificationService>().IsNoticeOpen)
|
||||
var notification = GContext.container.Resolve<ILocalNotificationService>();
|
||||
if (notification is LocalNotificationService local) local.RequirePromptOwner(this);
|
||||
if (notification.IsNoticeOpen)
|
||||
{
|
||||
ShowNotice = true;
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user