feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。 保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。 验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。 包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
using game.PlayerDataStorage;
|
||||
using Newtonsoft.Json;
|
||||
using asap.core;
|
||||
using cfg;
|
||||
using game;
|
||||
using GameCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
public class SurveyService
|
||||
{
|
||||
const string SurveyUrl = "https://wesurvey.com/";
|
||||
const string SurveyData = "SurveyData";
|
||||
const string SurveyReadSidData = "SurveyReadSidData";
|
||||
|
||||
readonly IPlayerSaveStore saveStore;
|
||||
readonly HashSet<string> pendingRewards = new HashSet<string>();
|
||||
IUserService userService;
|
||||
cfg.Tables tables;
|
||||
List<string> receivedReward = new List<string>();
|
||||
List<string> readSid = new List<string>();
|
||||
public SurveyData tableData;
|
||||
public SurveyService(IUserService userService, cfg.Tables tables, IPlayerSaveStore saveStore)
|
||||
{
|
||||
this.userService = userService;
|
||||
this.tables = tables;
|
||||
tableData = null;
|
||||
this.saveStore = saveStore;
|
||||
receivedReward = ReadList(SurveyData);
|
||||
readSid = ReadList(SurveyReadSidData);
|
||||
}
|
||||
List<string> ReadList(string key)
|
||||
{
|
||||
var read = saveStore.Read(key);
|
||||
var json = read.ValueOrThrow();
|
||||
if (read.Found == false) return new List<string>();
|
||||
if (string.IsNullOrEmpty(json)) throw new JsonSerializationException("Empty survey save: " + key);
|
||||
return JsonConvert.DeserializeObject<List<string>>(json) ?? throw new JsonSerializationException("Null survey save: " + key);
|
||||
}
|
||||
public bool IsCurrent => saveStore.IsCurrent && !userService.LoginLifetime.IsCancellationRequested;
|
||||
/// <summary>
|
||||
/// 拉取问卷
|
||||
/// </summary>
|
||||
public void GetSurveyMatchlist()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!IsCurrent) return;
|
||||
PlayerData playerData = GContext.container.Resolve<PlayerData>();
|
||||
|
||||
List<SurveyData> surveyDataTable = tables.TbSurveyData.DataList;
|
||||
ulong userId = Convert.ToUInt64(userService.UserId, saveStore is KVPlayerSaveStore ? 10 : 16);
|
||||
tableData = null;
|
||||
if (surveyDataTable.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < surveyDataTable.Count; i++)
|
||||
{
|
||||
if (!receivedReward.Contains(surveyDataTable[i].ID.ToString()))
|
||||
{
|
||||
if (surveyDataTable[i].LevelCondition >= playerData.lv)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
int tailNumber = (int)(userId % 10);
|
||||
if (!surveyDataTable[i].TailNumberList.Contains(tailNumber))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tableData = surveyDataTable[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
////设置红点
|
||||
SetRedPoint();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError("GetSurveyMatchlist:" + e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetRedPoint()
|
||||
{
|
||||
if (tableData == null)
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState("menu.survey", false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RedPointManager.Instance.SetRedPointState("menu.survey", true);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 请求答题的链接
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetSurveyAnswer()
|
||||
{
|
||||
if (!IsCurrent || tableData == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
string url = $"{SurveyUrl}s2/{tableData.ID}/{tableData.Hash}/?&uid={userService.CustomId}";
|
||||
//标记已读
|
||||
var next = new List<string>(readSid);
|
||||
if (!next.Contains(tableData.ID.ToString())) next.Add(tableData.ID.ToString());
|
||||
saveStore.Write(SurveyReadSidData, JsonConvert.SerializeObject(next)).RequireAccepted();
|
||||
readSid = next;
|
||||
GetSurveyMatchlist();
|
||||
return url;
|
||||
}
|
||||
/// <summary>
|
||||
/// 检查是否能领奖
|
||||
/// </summary>
|
||||
public async Task GetSurveyCheckAnswer(SurveyData survey)
|
||||
{
|
||||
if (!IsCurrent) throw new OperationCanceledException();
|
||||
if (survey == null) return;
|
||||
string sid = survey.ID.ToString();
|
||||
if (pendingRewards.Contains(sid)) throw new InvalidOperationException("Survey reward is pending or requires recovery.");
|
||||
if (receivedReward.Contains(sid)) return;
|
||||
pendingRewards.Add(sid);
|
||||
var items = GContext.container.Resolve<PlayerItemData>();
|
||||
var player = GContext.container.Resolve<PlayerData>();
|
||||
await PlayerSaveAction.RunAsync(saveStore, "survey:" + sid, () =>
|
||||
{
|
||||
items.AddItemByDrop(survey.Reward, null);
|
||||
PlayerSaveAction.Present(() => GContext.Publish(new ShowData()));
|
||||
receivedReward.Add(sid);
|
||||
saveStore.Write(SurveyData, JsonConvert.SerializeObject(receivedReward)).RequireAccepted();
|
||||
}, () => player.SavePlayerData(), userService.LoginLifetime);
|
||||
if (!IsCurrent) throw new OperationCanceledException();
|
||||
pendingRewards.Remove(sid);
|
||||
GetSurveyMatchlist();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user