feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
This commit is contained in:
@@ -37,14 +37,68 @@ public class LocalNotificationService : ILocalNotificationService
|
||||
#endif
|
||||
bool isInit = false;
|
||||
bool initing = false;
|
||||
DefaultSettingService promptSettings;
|
||||
Task initialization;
|
||||
Task opening;
|
||||
internal bool HasKVPromptOwner => promptSettings != null;
|
||||
public LocalNotificationService()
|
||||
{
|
||||
_notificationList = GContext.container.Resolve<cfg.Tables>().TbNotification.DataList;
|
||||
}
|
||||
|
||||
public async System.Threading.Tasks.Task Init()
|
||||
internal LocalNotificationService(cfg.Tables tables)
|
||||
{
|
||||
if (isInit) return;
|
||||
_notificationList = (tables ?? throw new ArgumentNullException(nameof(tables))).TbNotification.DataList;
|
||||
}
|
||||
|
||||
internal LocalNotificationService(DefaultSettingService settings, cfg.Tables tables)
|
||||
{
|
||||
if (settings == null || !settings.HasKVPromptOwner)
|
||||
throw new ArgumentException("Fixed KV settings required.", nameof(settings));
|
||||
promptSettings = settings;
|
||||
_notificationList = (tables ?? throw new ArgumentNullException(nameof(tables))).TbNotification.DataList;
|
||||
RequirePromptOwner();
|
||||
}
|
||||
|
||||
internal void RequirePromptOwner(ISettingService expected = null)
|
||||
{
|
||||
if (expected != null && (promptSettings != null || expected is DefaultSettingService setting && setting.HasKVPromptOwner)
|
||||
&& !ReferenceEquals(expected, promptSettings))
|
||||
throw DefaultSettingService.PromptFailure("ShowNotice: notification/settings owner mismatch.");
|
||||
promptSettings?.RequirePromptOwner();
|
||||
}
|
||||
|
||||
internal void PreflightFormalPromptSettings(DefaultSettingService settings)
|
||||
{
|
||||
if (settings == null || !isInit || initing ||
|
||||
(initialization != null && !initialization.IsCompleted) ||
|
||||
(opening != null && !opening.IsCompleted) ||
|
||||
(promptSettings != null && !ReferenceEquals(promptSettings, settings)))
|
||||
throw DefaultSettingService.PromptFailure("ShowNotice: notification handoff is not idle.");
|
||||
}
|
||||
internal void BindFormalPromptSettings(DefaultSettingService settings)
|
||||
{
|
||||
PreflightFormalPromptSettings(settings);
|
||||
if (!settings.HasKVPromptOwner)
|
||||
throw DefaultSettingService.PromptFailure("ShowNotice: notification owner not handed off.");
|
||||
settings.RequirePromptOwner();
|
||||
if (promptSettings == null) promptSettings = settings;
|
||||
RequirePromptOwner(settings);
|
||||
}
|
||||
internal bool HasFormalPromptSettings(DefaultSettingService settings) =>
|
||||
ReferenceEquals(promptSettings, settings);
|
||||
|
||||
public Task Init()
|
||||
{
|
||||
RequirePromptOwner();
|
||||
if (isInit) return Task.CompletedTask;
|
||||
if (initialization != null && !initialization.IsCompleted) return initialization;
|
||||
return initialization = InitCoreAsync();
|
||||
}
|
||||
|
||||
async Task InitCoreAsync()
|
||||
{
|
||||
RequirePromptOwner();
|
||||
#if UNITY_EDITOR
|
||||
await System.Threading.Tasks.Task.Yield();
|
||||
#else
|
||||
@@ -59,9 +113,11 @@ public class LocalNotificationService : ILocalNotificationService
|
||||
Debug.Log("[LocalNotificationService::Init] Channel Inited");
|
||||
|
||||
await NotificationCenter.RequestPermission();
|
||||
RequirePromptOwner();
|
||||
ScheduleDefaultNotification();
|
||||
GContext.OnEvent<EventRankData>().Subscribe(ScheduleRankNotification);
|
||||
#endif
|
||||
RequirePromptOwner();
|
||||
isInit = true;
|
||||
}
|
||||
|
||||
@@ -86,14 +142,36 @@ public class LocalNotificationService : ILocalNotificationService
|
||||
|
||||
public async void OpenSettings()
|
||||
{
|
||||
if (initing) return;
|
||||
try { await OpenSettingsAsync(); }
|
||||
catch (Exception ex) { game.DefaultSettingService.LogPromptFailure(ex); }
|
||||
}
|
||||
|
||||
internal Task OpenSettingsAsync()
|
||||
{
|
||||
if (promptSettings == null && GContext.container.Resolve<ISettingService>() is DefaultSettingService pending)
|
||||
pending.RequirePromptOwner();
|
||||
RequirePromptOwner();
|
||||
if (initing && opening == null)
|
||||
throw DefaultSettingService.PromptFailure("ShowNotice: reentrant permission request.");
|
||||
if (opening != null && !opening.IsCompleted) return opening;
|
||||
return opening = OpenSettingsCoreAsync();
|
||||
}
|
||||
|
||||
async Task OpenSettingsCoreAsync()
|
||||
{
|
||||
ISettingService settings = promptSettings ?? GContext.container.Resolve<ISettingService>();
|
||||
RequirePromptOwner(settings);
|
||||
(settings as DefaultSettingService)?.RequirePromptOwner();
|
||||
initing = true;
|
||||
if (!isInit)
|
||||
await Init();
|
||||
else
|
||||
NotificationCenter.OpenNotificationSettings();
|
||||
GContext.container.Resolve<ISettingService>().ShowNotice = true;
|
||||
initing = false;
|
||||
try
|
||||
{
|
||||
if (!isInit) await Init();
|
||||
else NotificationCenter.OpenNotificationSettings();
|
||||
RequirePromptOwner(settings);
|
||||
(settings as DefaultSettingService)?.RequirePromptOwner();
|
||||
settings.ShowNotice = true;
|
||||
}
|
||||
finally { initing = false; }
|
||||
}
|
||||
|
||||
public void ScheduleDailyNotification(int notificationID, DateTime fireTime, string title, string text)
|
||||
@@ -150,6 +228,8 @@ public class LocalNotificationService : ILocalNotificationService
|
||||
|
||||
private void ScheduleRankNotification(EventRankData evt)
|
||||
{
|
||||
try { RequirePromptOwner(); }
|
||||
catch (InvalidOperationException ex) { Debug.LogError(ex.Message); return; }
|
||||
if (rankNotifyScheduled || !IsNoticeOpen || !isInit) return;
|
||||
|
||||
Debug.Log("[LocalNotificationService::SendNotification] RankEvent");
|
||||
@@ -170,4 +250,4 @@ public class LocalNotificationService : ILocalNotificationService
|
||||
rankNotifyScheduled = true;
|
||||
Debug.Log("[LocalNotificationService::SendRankEventNotification] ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user