Files
ft/CodexOutput/upserver/B3BatchMigration/M2/C2d修改前快照/066-SurveyService.cs.txt
Liubing\LB 6813da149a feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。
保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。

验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。
包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
2026-09-30 19:19:05 +08:00

140 lines
5.0 KiB
Plaintext

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();
}
}