feat(upserver): 接入认证与KV存档并完成限定钓鱼闭环

This commit is contained in:
Liubing\LB
2026-09-28 18:14:01 +08:00
parent f40a816cc4
commit 0eb43b2b40
129 changed files with 11612 additions and 573 deletions

View File

@@ -32,6 +32,31 @@ public class AchievementDataManager : IDisposable
{
_tables = tables;
}
internal static game.PlayerDataStorage.PlayerKVAchievementState DecodeForKVLoad(
IReadOnlyDictionary<string, string> raw, IReadOnlyDictionary<string, string> modern,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot, game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors)
=> game.PlayerDataStorage.PlayerKVSaveSchema.DecodeAchievements(raw, modern, snapshot, errors);
internal void ResetForKVLoad()
{
_achievementDatas = new Dictionary<ConditionType, AchievementData>();
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVAchievementState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
var replacement = new Dictionary<ConditionType, AchievementData>();
foreach (var entry in state.Values)
replacement.Add((ConditionType)entry.Key, new AchievementData
{ Id = entry.Value.Id, Target = entry.Value.Target, day = entry.Value.Day });
_achievementDatas = replacement;
}
internal bool IsEmptyForKVValidation => _achievementDatas.Count == 0;
internal AchievementData FindForKVValidation(ConditionType key)
=> _achievementDatas.TryGetValue(key, out var value)
? new AchievementData { Id = value.Id, Target = value.Target, day = value.day } : null;
public void LoadAchievementData(string value)
{
_achievementDatas = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<ConditionType, AchievementData>>(value);

View File

@@ -13,6 +13,62 @@ public class BargainPackData
private readonly TbSpecialPack _spp = GContext.container.Resolve<Tables>().TbSpecialPack;
private GeneralEventPackData _data;
private bool _kvLoadPresent;
#if UNITY_EDITOR
internal bool SelectionsAreIndependentForKVValidation()
{
var source = new List<int> { 7, 9 };
var state = new game.PlayerDataStorage.PlayerKVBargainState(true,0,_data.redirectID,0,0,0,0,0,0,0,0,0,false,false,0,source);
ReplaceFromKVDecoded(state);
source.Clear();
if (_data.selections.Count != 2 || ReferenceEquals(_data.selections, source) || ReferenceEquals(_data.selections, state.selections)) return false;
var previous = _data.selections;
_data.selections[0] = 10;
if (state.selections[0] != 7) return false;
ResetForKVLoad();
return _data.selections.Count == 0 && !ReferenceEquals(previous, _data.selections) && !_kvLoadPresent;
}
#endif
internal bool KVLoadPresent => _kvLoadPresent;
internal static game.PlayerDataStorage.PlayerKVBargainState DecodeForKVLoad(
IReadOnlyDictionary<string, string> raw, game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeBargain(raw, snapshot, errors);
internal void ResetForKVLoad()
{
_kvLoadPresent = false;
_data = default(GeneralEventPackData);
_data.selections = new List<int>();
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVBargainState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
if (!state.IsPresent) { ResetForKVLoad(); return; }
var replacement = new GeneralEventPackData
{
currentEventID = state.currentEventID,
redirectID = state.redirectID,
VIPLvlWhenEventActivate = state.VIPLvlWhenEventActivate,
purchaseCount = state.purchaseCount,
savingProgress = state.savingProgress,
discountLvl = state.discountLvl,
visualProgress = state.visualProgress,
visualDiscountLvl = state.visualDiscountLvl,
rodID = state.rodID,
lastPackIDBought = state.lastPackIDBought,
packID = state.packID,
doNeedTrigger = state.doNeedTrigger,
isTriggered = state.isTriggered,
inflation = state.inflation,
selections = state.selections == null ? null : new List<int>(state.selections),
};
_data = replacement;
_kvLoadPresent = true;
}
internal game.PlayerDataStorage.PlayerKVBargainState SnapshotForKVValidation() =>
new game.PlayerDataStorage.PlayerKVBargainState(_kvLoadPresent, _data.currentEventID, _data.redirectID, _data.VIPLvlWhenEventActivate, _data.purchaseCount, _data.savingProgress, _data.discountLvl, _data.visualProgress, _data.visualDiscountLvl, _data.rodID, _data.lastPackIDBought, _data.packID, _data.doNeedTrigger, _data.isTriggered, _data.inflation, _data.selections);
public int CurrentEventID => _data.currentEventID;
public FishingEvent CurrentEvent => _tables.TbFishingEvent[_data.currentEventID];
@@ -25,10 +81,11 @@ public class BargainPackData
{
get
{
if (CurrentEventID == 0) return false;
var fishingEvent = _tables.TbFishingEvent.GetOrDefault(CurrentEventID);
if (!(fishingEvent?.TimeDefinition is LimitedTime time)) return false;
var et = DateTime.Parse((_tables.TbFishingEvent[_data.currentEventID].TimeDefinition as LimitedTime).EndTime);
var st = DateTime.Parse((_tables.TbFishingEvent[_data.currentEventID].TimeDefinition as LimitedTime).StartTime);
var et = DateTime.Parse(time.EndTime);
var st = DateTime.Parse(time.StartTime);
return ZZTimeHelper.UtcNow() >= st && ZZTimeHelper.UtcNow() < et;
}
}
@@ -259,4 +316,4 @@ public class BargainPackProgressEvent
{
public int type; //0: 初始化 1:增加动画
public int addProgress;
}
}

View File

@@ -36,6 +36,29 @@ public class BattlePassData
public BattlePassRecord BattlePassRecord;
public BattleTask BattleTask;
internal static game.PlayerDataStorage.PlayerKVBattlePassState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeBattlePass(raw,snapshot,errors);
internal void ResetForKVLoad()
{
BattlePassRecord=new BattlePassRecord();
BattleTask=new BattleTask();
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVBattlePassState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
var record=new BattlePassRecord {
ID=state.Record.ID,Level=state.Record.Level,Exp=state.Record.Exp,BuyVipToastIndex=state.Record.BuyVipToastIndex,
IsUnlockVip=state.Record.IsUnlockVip,NormalRewardGet=new List<int>(state.Record.Normal),VipRewardGet=new List<int>(state.Record.Vip),
LastDropIDs=new List<int>(state.Record.LastDrops),InflationRate=state.Record.Inflation
};
var task=new BattleTask {
dic_dailyTasks=state.Task.Daily.ToDictionary(p=>p.Key,p=>p.Value),dic_weeklyTasks=state.Task.Weekly.ToDictionary(p=>p.Key,p=>p.Value),
loginDays=new List<int>(state.Task.LoginDays),DailyTaskEndTime=state.Task.DailyEnd,WeeklyTaskEndTime=state.Task.WeeklyEnd
};
BattlePassRecord=record; BattleTask=task;
}
private Tables _tables;
@@ -136,20 +159,16 @@ public class BattlePassData
public void RefreshDaiyTask()
{
var bpMain = _tables.TbBattlePassMain.GetOrDefault(_tables.TbFishingEvent.GetOrDefault(BattlePassRecord.ID).RedirectID);
if (bpMain != null)
var fishingEvent = _tables.TbFishingEvent.GetOrDefault(BattlePassRecord.ID);
if (fishingEvent == null) return;
var bpMain = _tables.TbBattlePassMain.GetOrDefault(fishingEvent.RedirectID);
if (bpMain == null) return;
BattleTask.DailyTaskEndTime = ConvertTools.GetDateTimeYMD(ZZTimeHelper.UtcNow().UtcNowOffset()).AddDays(1);
var dailyTasks = bpMain.DailyTaskList;
BattleTask.dic_dailyTasks.Clear();
foreach (var task in dailyTasks)
{
BattleTask.DailyTaskEndTime = ConvertTools.GetDateTimeYMD(ZZTimeHelper.UtcNow().UtcNowOffset()).AddDays(1);
var dailyTasks = bpMain.DailyTaskList;
BattleTask.dic_dailyTasks.Clear();
foreach (var task in dailyTasks)
{
BattleTask.dic_dailyTasks.Add(task, 0);
}
}
else
{
BattleTask = new BattleTask();
BattleTask.dic_dailyTasks.Add(task, 0);
}
GContext.Publish(new ConditionTypeEvent { type = ConditionType.LoginDays, count = 1 });
SaveBattleTask();
@@ -157,23 +176,17 @@ public class BattlePassData
public void RefreshWeeklyTask()
{
var bpMain = _tables.TbBattlePassMain.GetOrDefault(_tables.TbFishingEvent.GetOrDefault(BattlePassRecord.ID).RedirectID);
if (bpMain != null)
var fishingEvent = _tables.TbFishingEvent.GetOrDefault(BattlePassRecord.ID);
if (fishingEvent == null) return;
var bpMain = _tables.TbBattlePassMain.GetOrDefault(fishingEvent.RedirectID);
if (bpMain == null) return;
var weeklyTasks = bpMain.WeeklyTaskList;
BattleTask.dic_weeklyTasks.Clear();
foreach (var task in weeklyTasks)
{
var weeklyTasks = bpMain.WeeklyTaskList;
BattleTask.dic_weeklyTasks.Clear();
foreach (var task in weeklyTasks)
{
BattleTask.dic_weeklyTasks.Add(task, 0);
}
BattleTask.WeeklyTaskEndTime = ConvertTools.GetDateTimeSunDay(ZZTimeHelper.UtcNow().UtcNowOffset()).AddDays(1);
}
//当前没有战令了
else
{
BattleTask = new BattleTask();
BattleTask.dic_weeklyTasks.Add(task, 0);
}
BattleTask.WeeklyTaskEndTime = ConvertTools.GetDateTimeSunDay(ZZTimeHelper.UtcNow().UtcNowOffset()).AddDays(1);
BattlePassRecord.InflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
GContext.Publish(new ConditionTypeEvent { type = ConditionType.LoginDays, count = 1 });
@@ -207,7 +220,7 @@ public class BattlePassDataProvider : IDisposable
private Tables _tables;
private Dictionary<int, BattlePassLevel> dic_BPLevel;
public bool IsActivating => Data.BattlePassRecord.ID != 0;
public bool IsActivating => Data.BattlePassRecord.ID != 0 && curPassMain != null;
public bool UILockVip = false;
public bool IsUnlockVip => Data.BattlePassRecord.IsUnlockVip == 1;
@@ -249,6 +262,7 @@ public class BattlePassDataProvider : IDisposable
public void CheckIfRefreshBattblePass()
{
if (!IsActivating) return;
DateTime endTime = GContext.container.Resolve<FishingEventData>().GetEventEndTime(Data.BattlePassRecord.ID);
if (ZZTimeHelper.UtcNow().UtcNowOffset() >= endTime && IsActivating)

View File

@@ -16,6 +16,39 @@ public class BuffDataCenter
Dictionary<int, FishBuffTimeData> globalBuffDataList = new Dictionary<int, FishBuffTimeData>();
FishBuffTimeData fishDailyBuff = null;
public List<FishBuffTimeData> showFishBuffIds = new List<FishBuffTimeData>();
internal static game.PlayerDataStorage.PlayerKVBuffState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeBuffs(raw,snapshot,errors);
internal void ResetForKVLoad()
{
mapBuffDataList=new Dictionary<int,FishBuffTimeData>();
targetBuffDataList=new List<FishBuffTimeData>();
globalBuffDataList=new Dictionary<int,FishBuffTimeData>();
showFishBuffIds=new List<FishBuffTimeData>(); fishDailyBuff=null;
}
static FishBuffTimeData MaterializeKVBuff(game.PlayerDataStorage.PlayerKVBuffValue value) => value==null ? null : new FishBuffTimeData
{ SortID=value.SortID,sourceID=value.sourceID,buffID=value.buffID,isEnd=value.isEnd,buffEndTime=value.buffEndTime,isNew=false,addDown=0 };
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVBuffState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
var map=new Dictionary<int,FishBuffTimeData>(); var global=new Dictionary<int,FishBuffTimeData>(); var target=new List<FishBuffTimeData>();
foreach(var item in state.Map) map.Add(item.Key,MaterializeKVBuff(item.Value));
foreach(var item in state.Global) global.Add(item.Key,MaterializeKVBuff(item.Value));
foreach(var item in state.Target) target.Add(MaterializeKVBuff(item));
mapBuffDataList=map; globalBuffDataList=global; targetBuffDataList=target; fishDailyBuff=MaterializeKVBuff(state.Daily);
}
#if UNITY_EDITOR
internal FishBuffTimeData BuffForKVValidation(int kind,int key)
{
if(kind==0) return mapBuffDataList.TryGetValue(key,out var value) ? value : null;
if(kind==1) return targetBuffDataList.Count>key ? targetBuffDataList[key] : null;
if(kind==2) return fishDailyBuff;
return globalBuffDataList.TryGetValue(key,out var global) ? global : null;
}
internal bool IsEmptyForKVValidation => mapBuffDataList.Count==0 && targetBuffDataList.Count==0 &&
globalBuffDataList.Count==0 && showFishBuffIds.Count==0 && fishDailyBuff==null;
#endif
public void InitData(Dictionary<string, string> userDatas)
{
if (userDatas.TryGetValue("BuffDataList", out string buffDataStr))
@@ -558,4 +591,4 @@ public class AddGlobalBuffEvent
{
this.buffID = buffID;
}
}
}

View File

@@ -130,6 +130,46 @@ namespace GameCore
//待释放
IDisposable disposable;
internal static game.PlayerDataStorage.PlayerKVEventBaseState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
IReadOnlyDictionary<string,string> modern,game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors)
=> game.PlayerDataStorage.PlayerKVSaveSchema.DecodeEventBase(raw,modern,snapshot,errors);
internal void ResetForKVLoad()
{
limitedTimeEventDic=new Dictionary<int,LimitedTimeEvent>(); fixedTimeEventDic=new Dictionary<int,FixedTimeEvent>();
ETDropAfterDropDic=new Dictionary<int,int>(); RankTargetCount=new Dictionary<int,int>(); WheelLevelCount=new Dictionary<int,int>();
TurntableCoupon=_tables.TbGlobalConfig.InitWheelTicket; WheelOperateCount=0; AllWheelOperateCount=0; freecount=0; PVPToken=0;
collectingTargetEventID=-1; virtualCollectingTargetEventID=-1; NewPlayerEvent=default;
collectingTargetInit=null; collectingTargetInitTokenID=0; collectingTargetInitTaskID=0;
TargetList=null; collectingTarget=null; preCollectingTarget=null; targetItemDatas=null; preRankTarget=null; rankItemDatas=null;
rankEvent=null; rankInit=null; rankTarget=null; turntableEvent=null; wheelInit=null; wheelLevel=null;
SystemOpen=new Dictionary<int,bool>(); _unlocked=new HashSet<int>(); _isTargetGuidance=true;
IsJoinUsPanelOpen=false; collectingTargetResoure=true; IsAquariumOpen=false; IsOpenDrop=false; OpenAquariumID=0;
requiredCount=0; requiredRankCount=0; curActivateItemId=0;
duelData=null; rankTierChangeState=0; curSolomain=null; Pack1A1Data=null; Pack1A2Data=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVEventBaseState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
limitedTimeEventDic=state.Limited.ToDictionary(p=>p.Key,p=>new LimitedTimeEvent { id=p.Value.Id,duration=p.Value.Duration,startTime=p.Value.StartTime });
fixedTimeEventDic=state.Fixed.ToDictionary(p=>p.Key,p=>new FixedTimeEvent { id=p.Value.id,endTime=p.Value.endTime });
ETDropAfterDropDic=state.Target.ToDictionary(p=>p.Key,p=>p.Value); RankTargetCount=state.Rank.ToDictionary(p=>p.Key,p=>p.Value);
WheelLevelCount=state.Wheel.ToDictionary(p=>p.Key,p=>p.Value); TurntableCoupon=state.Coupon;
WheelOperateCount=state.Operate; AllWheelOperateCount=state.AllOperate; freecount=state.Free; PVPToken=state.PvpToken;
}
#if UNITY_EDITOR
internal game.PlayerDataStorage.PlayerKVEventBaseState SnapshotForKVValidation() => new game.PlayerDataStorage.PlayerKVEventBaseState(
limitedTimeEventDic.ToDictionary(p=>p.Key,p=>new game.PlayerDataStorage.PlayerKVLimitedValue(p.Value.id,p.Value.duration,p.Value.startTime)),
fixedTimeEventDic.ToDictionary(p=>p.Key,p=>new game.PlayerDataStorage.PlayerKVFixedTimeValue(p.Value.id,p.Value.endTime)),
ETDropAfterDropDic,RankTargetCount,WheelLevelCount,TurntableCoupon,WheelOperateCount,AllWheelOperateCount,freecount,PVPToken);
internal void MutateCollectionsForKVValidation()
{ limitedTimeEventDic.Values.First().duration=99; fixedTimeEventDic.Values.First().id=99; ETDropAfterDropDic.Clear(); RankTargetCount.Clear(); WheelLevelCount.Clear(); }
internal bool IsInactiveForKVValidation => collectingTargetEventID==-1 && virtualCollectingTargetEventID==-1 && NewPlayerEvent==default &&
collectingTargetInit==null && collectingTargetInitTokenID==0 && collectingTargetInitTaskID==0 && TargetList==null && collectingTarget==null &&
preCollectingTarget==null && targetItemDatas==null && preRankTarget==null && rankItemDatas==null && rankEvent==null && rankInit==null && rankTarget==null &&
turntableEvent==null && wheelInit==null && wheelLevel==null && SystemOpen.Count==0 && _unlocked.Count==0 && duelData==null && curSolomain==null &&
Pack1A1Data==null && Pack1A2Data==null && !IsJoinUsPanelOpen && !IsAquariumOpen && !IsOpenDrop && OpenAquariumID==0 && requiredCount==0 && requiredRankCount==0 && curActivateItemId==0;
#endif
public void InitData(Dictionary<string, string> userDatas)
{
InitTurntableRoll(_tables.TbGlobalConfig.InitWheelTicket);

View File

@@ -56,6 +56,20 @@ namespace GameCore
public string popupPanelNode;
public GuidanceGroupDefine curGroupDefine;
public GuidanceDefineSetting guidanceDefineSetting;
internal static game.PlayerDataStorage.PlayerKVGuideState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => game.PlayerDataStorage.PlayerKVSaveSchema.DecodeGuides(raw,errors);
internal void ResetForKVLoad()
{
GuideSaveDataDic = new Dictionary<string,GuideSaveData>(StringComparer.Ordinal);
curSaveData = null; curDefine = null; curGroupDefine = null; popupPanelNode = null; CurPanelName = null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVGuideState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
GuideSaveDataDic = state.Values.ToDictionary(p=>p.Key,
p=>new GuideSaveData { guideSubIndex=p.Value.Index, isFinish=p.Value.Finished, groupName=p.Value.Group },StringComparer.Ordinal);
}
//待释放
IDisposable disposable;
IDisposable disposable2;
@@ -101,6 +115,13 @@ namespace GameCore
if (GuideSaveDataDic.TryGetValue(item.groupName.ToString(), out _saveData))
{
#if UNITY_EDITOR && !SERVICE_HOST
if (DeferUnavailablePotionGuide(item, _saveData))
{
keyValuePairs[item.groupName.ToString()] = _saveData;
continue;
}
#endif
if (!_saveData.isFinish && _saveData.guideSubIndex > 0)
{
for (int i = _saveData.guideSubIndex; i < item.guidanceDefines.Length; i++)
@@ -153,6 +174,29 @@ namespace GameCore
}
}
}
#if UNITY_EDITOR && !SERVICE_HOST
private static bool DeferUnavailablePotionGuide(GuidanceGroupDefine group, GuideSaveData saved)
{
if (!game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled || !game.PlayerDataStorage.PlayerKVGameplayLoop.Ready ||
group.groupName != GroupName.EventPotion01 || saved == null || saved.isFinish || saved.guideSubIndex <= 0 ||
group.guidanceDefines == null || saved.guideSubIndex >= group.guidanceDefines.Length ||
group.guidanceDefines[saved.guideSubIndex] == null ||
group.guidanceDefines[saved.guideSubIndex].panelName != "EventPotionPanel")
return false;
try
{
// Existing potion activity classification; availability query does not initialize activity data.
const int potionEventType = 4;
const int potionEventSubType = 5;
return GContext.container.Resolve<FishingEventData>().GetEvent(potionEventType, potionEventSubType) == -1;
}
catch (Exception ex)
{
Debug.LogWarning("Potion guide availability query failed; retaining original guide recovery: " + ex);
return false;
}
}
#endif
public bool GetIsFinish(string groupName)
{
return GuideSaveDataDic.ContainsKey(groupName) && GuideSaveDataDic[groupName].isFinish;

View File

@@ -34,6 +34,42 @@ namespace GameCore
public const string Diamond = "DiamondTrue";
Dictionary<string, string> NewPlayerDataDic = new Dictionary<string, string>();
public IReadOnlyDictionary<string, string> PlayerDataDic => NewPlayerDataDic;
internal static game.PlayerDataStorage.PlayerKVPlayerState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
IReadOnlyDictionary<string,string> modern,game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => game.PlayerDataStorage.PlayerKVSaveSchema.DecodePlayer(raw,modern,snapshot,errors);
internal void ResetForKVLoad()
{
NewPlayerDataDic=new Dictionary<string,string>(StringComparer.Ordinal); vipScoreDic=new Dictionary<int,int>();
newRodList=new List<int>();
lv=vip=vipAllScore=0; vipLastScore=PriceLv=0; priceLevel=null;
energy=pearl=diamond=equipRodID=magnification=seasonId=rewardNewMap=0;
gold=0; goldRM=0; energyRM=0; _currentMapId=_lastMapId=0;
_fishingFrequency=_allFishingFrequency=0; _lastEnergyRecoveryTime=DateTime.MinValue;
IsOpenAppraise=false; InfiniteBuildingData=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVPlayerState state)
{
if(state==null || state.Core==null) throw new ArgumentNullException(nameof(state));
var modern=state.Modern.ToDictionary(p=>p.Key,p=>p.Value,StringComparer.Ordinal);
var scores=state.VipScores.ToDictionary(p=>p.Key,p=>p.Value);
var rods=new List<int>(state.NewRods);
var core=state.Core;
lv=core.Integer(0); gold=core.Unsigned(1); vipAllScore=core.Integer(2); energy=core.Integer(3);
pearl=core.Integer(4); magnification=core.Integer(5); equipRodID=core.Integer(6); _lastEnergyRecoveryTime=core.EnergyTime;
rewardNewMap=core.Integer(8); energyRM=core.Integer(9); goldRM=core.Unsigned(10); diamond=core.Integer(11);
_currentMapId=core.Integer(12); _lastMapId=core.Integer(13); _fishingFrequency=core.Integer(14); _allFishingFrequency=core.Integer(15);
NewPlayerDataDic=modern; vipScoreDic=scores; newRodList=rods;
seasonId=state.Season; IsOpenAppraise=state.Appraise; InfiniteBuildingData=state.Building;
}
#if UNITY_EDITOR
internal game.PlayerDataStorage.PlayerKVPlayerState SnapshotForKVValidation() =>
new game.PlayerDataStorage.PlayerKVPlayerState(new game.PlayerDataStorage.PlayerKVCoreState(new object[] {
(int)lv,(ulong)gold,(int)vipAllScore,(int)energy,(int)pearl,(int)magnification,(int)equipRodID,_lastEnergyRecoveryTime,
(int)rewardNewMap,energyRM,goldRM,(int)diamond,(int)_currentMapId,(int)_lastMapId,_fishingFrequency,_allFishingFrequency,0,0,0
}),NewPlayerDataDic,vipScoreDic,newRodList,seasonId,IsOpenAppraise,InfiniteBuildingData);
internal bool IsDerivedEmptyForKVValidation => (int)vip==0 && vipLastScore==0 && PriceLv==0 && priceLevel==null;
#endif
public ObscuredInt lv { get; set; }
public ObscuredInt vip { get; private set; }
public ObscuredInt vipAllScore { get; private set; }
@@ -1103,6 +1139,57 @@ namespace GameCore
public void SavePlayerData(bool remote = true)
{
GContext.Publish<PlayerData>(this);
SerializeAndSavePlayerData(remote);
}
#if UNITY_EDITOR && !SERVICE_HOST
internal async System.Threading.Tasks.Task ConsumeEnergyForKVLoopAsync(int cost,
game.PlayerDataStorage.PlayerKVGameplayLoop.FishingAction action)
{
if(cost<=0 || Energy<cost) throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Invalid fishing energy cost or insufficient energy.");
int before=Energy;
var batch=game.PlayerDataStorage.PlayerKVGameplayLoop.BeginFishingWrites(action);
game.PlayerDataStorage.PlayerKVEditResult primary;
try
{
using(batch)
{
ReduceEnergy(cost,false);
GContext.Publish(new ConditionTypeEvent(ConditionType.ConsumeEnergy,cost));
primary=SerializeAndSavePlayerData(true);
}
game.PlayerDataStorage.PlayerKVGameplayLoop.Audit("fishing-energy-applied",new{before,cost,after=(int)Energy,writes=batch.Records.Count,localOnly=batch.Records.Count(r=>!r.Remote)});
await game.PlayerDataStorage.PlayerKVGameplayLoop.ConfirmFishingAsync(action,batch,primary);
}
catch(System.Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); throw; }
}
internal async System.Threading.Tasks.Task SetEquipRodIDForKVLoopAsync(int id)
{
var batch=game.PlayerDataStorage.PlayerKVGameplayLoop.BeginEquip();
game.PlayerDataStorage.PlayerKVEditResult primary;
try
{
using(batch)
{
equipRodID=id;
GContext.container.Resolve<PlayerFishData>().SetRedPoint();
GContext.Publish<PlayerData>(this);
primary=SerializeAndSavePlayerData(true);
}
await game.PlayerDataStorage.PlayerKVGameplayLoop.ConfirmEquipAsync(batch,primary);
}
catch(System.Exception e) { game.PlayerDataStorage.PlayerKVGameplayLoop.Fault(e.Message); throw; }
}
#endif
#if UNITY_EDITOR && !SERVICE_HOST
internal game.PlayerDataStorage.PlayerKVEditResult SaveFishingRewardForKVLoop()
{
game.PlayerDataStorage.PlayerKVGameplayLoop.CheckRewardMainSave();
return SerializeAndSavePlayerData(true);
}
#endif
private game.PlayerDataStorage.PlayerKVEditResult SerializeAndSavePlayerData(bool remote)
{
StringBuilder sb = new StringBuilder();
sb.Append(lv).Append(",");
sb.Append(gold).Append(",");
@@ -1143,7 +1230,11 @@ namespace GameCore
NewPlayerDataDic["ct"] = GContext.container.Resolve<FishingEventData>().CTSerialize();
NewPlayerDataDic["rt"] = GContext.container.Resolve<FishingEventData>().RTSerialize(); ;
#if UNITY_EDITOR && !SERVICE_HOST
if(game.PlayerDataStorage.PlayerKVGameplayLoop.Enabled) return game.PlayerDataStorage.PlayerKVGameplayLoop.Write("NewPlayerDataDic",Newtonsoft.Json.JsonConvert.SerializeObject(NewPlayerDataDic),remote);
#endif
PlayFabMgr.Instance.UpdateUserDataValue("NewPlayerDataDic", Newtonsoft.Json.JsonConvert.SerializeObject(NewPlayerDataDic), remote);
return null;
}
public void Init()
{

View File

@@ -85,6 +85,46 @@ namespace GameCore
public Dictionary<string, float> LuckDataDic = new Dictionary<string, float>();
public bool IsOpenPiercing = false;
public int RodSelectedInPack = 0;
internal static game.PlayerDataStorage.PlayerKVFishState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
IReadOnlyDictionary<string,string> modern,game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors)
=> game.PlayerDataStorage.PlayerKVSaveSchema.DecodeFish(raw,modern,snapshot,errors);
internal void ResetForKVLoad()
{
mapFishData=new Dictionary<int,Dictionary<int,FishWeightData>>(); fishData=new Dictionary<int,FishWeightData>(); fishCardData=new Dictionary<int,int>();
mapProgress=new Dictionary<int,int>(); rodData=new Dictionary<int,int>(); rodLevelData=new Dictionary<int,int>();
fishSwimToMap=new Dictionary<int,int>(); fishSwimToMapCount=new Dictionary<int,int>(); _honorlevel=new Dictionary<int,int>();
LuckDataDic=new Dictionary<string,float>(StringComparer.Ordinal); rodAccessoriesData=null;
InitBotLuck=0; InitFishLuck=0; BotCount=0; _isRedPoint_up=false; RodCanUp=false; RodCanUpLevel=false;
MapTipforUnlocked=0; IsOpenMap=false; IsOpenRod=false; IsOpenPiercing=false; RodSelectedInPack=0;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVFishState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
var maps=state.Maps.ToDictionary(m=>m.Key,m=>m.Value.ToDictionary(p=>p.Key,p=>new FishWeightData {
Level=p.Value.Level,MaxG=p.Value.Weight,TotalCard=p.Value.Cards,TotalNum=p.Value.Number,NewFish=p.Value.New }));
var flat=new Dictionary<int,FishWeightData>();
foreach(var map in maps.Values) foreach(var p in map) flat.Add(p.Key,p.Value);
mapFishData=maps; fishData=flat; fishCardData=state.Cards.ToDictionary(p=>p.Key,p=>p.Value);
rodData=state.Rods.ToDictionary(p=>p.Key,p=>p.Value); rodLevelData=state.RodLevels.ToDictionary(p=>p.Key,p=>p.Value);
fishSwimToMap=state.Swim.ToDictionary(p=>p.Key,p=>p.Value); fishSwimToMapCount=state.SwimCount.ToDictionary(p=>p.Key,p=>p.Value);
mapProgress=state.Progress.ToDictionary(p=>p.Key,p=>p.Value); _honorlevel=state.Honor.ToDictionary(p=>p.Key,p=>p.Value);
LuckDataDic=state.Luck.ToDictionary(p=>p.Key,p=>p.Value,StringComparer.Ordinal);
var a=state.Accessories;
rodAccessoriesData=a==null ? null : new RodGSAData { GloveID=a.Glove,RodToSkin=a.RodSkin.ToDictionary(p=>p.Key,p=>p.Value),
GloveIds=new List<int>(a.Gloves),SkinIds=new List<int>(a.Skins),GloveNewIds=new List<int>(a.NewGloves),SkinNewIds=new List<int>(a.NewSkins) };
}
#if UNITY_EDITOR
internal FishWeightData FishForKVValidation(int map,int id) => mapFishData[map][id];
internal bool IndexesMatchForKVValidation(int map,int id,int card) => ReferenceEquals(mapFishData[map][id],fishData[id]) && fishCardData[card]==fishData[id].TotalCard;
internal bool EmptyForKVValidation => mapFishData.Count==0 && fishData.Count==0 && fishCardData.Count==0 && mapProgress.Count==0 && rodData.Count==0 && rodLevelData.Count==0 &&
fishSwimToMap.Count==0 && fishSwimToMapCount.Count==0 && _honorlevel.Count==0 && LuckDataDic.Count==0 && rodAccessoriesData==null &&
InitBotLuck==0 && InitFishLuck==0 && BotCount==0 && !_isRedPoint_up && !RodCanUp && !RodCanUpLevel && !IsOpenMap && !IsOpenRod && !IsOpenPiercing && MapTipforUnlocked==0 && RodSelectedInPack==0;
internal bool DictionariesMatchForKVValidation(game.PlayerDataStorage.PlayerKVFishState s) =>
rodData.OrderBy(p=>p.Key).SequenceEqual(s.Rods.OrderBy(p=>p.Key)) && rodLevelData.OrderBy(p=>p.Key).SequenceEqual(s.RodLevels.OrderBy(p=>p.Key)) &&
fishSwimToMap.OrderBy(p=>p.Key).SequenceEqual(s.Swim.OrderBy(p=>p.Key)) && fishSwimToMapCount.OrderBy(p=>p.Key).SequenceEqual(s.SwimCount.OrderBy(p=>p.Key)) &&
mapProgress.OrderBy(p=>p.Key).SequenceEqual(s.Progress.OrderBy(p=>p.Key)) && _honorlevel.OrderBy(p=>p.Key).SequenceEqual(s.Honor.OrderBy(p=>p.Key));
#endif
public void InitData(Dictionary<string, string> userDatas)
{
string data_value;
@@ -1154,6 +1194,14 @@ namespace GameCore
SetFishData(id, fishData[id]);
}
#if UNITY_EDITOR && !SERVICE_HOST
internal void SaveCaughtFishForKVLoop(int fishId)
{
if(!fishData.TryGetValue(fishId,out var data)) throw game.PlayerDataStorage.PlayerKVGameplayLoop.Stop("Caught fish data is missing.");
game.PlayerDataStorage.PlayerKVGameplayLoop.CheckCaughtFishSave(fishId,data.TotalNum);
SetFishData(fishId,data);
}
#endif
void SetFishData(int id, FishWeightData data)
{
int mapID = _tables.TbFishData.GetOrDefault(id).AreaID;

View File

@@ -126,6 +126,44 @@ namespace GameCore
Dictionary<int, int> advertCount = new Dictionary<int, int>();
#endregion
internal static game.PlayerDataStorage.PlayerKVShopState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors)
=> game.PlayerDataStorage.PlayerKVSaveSchema.DecodeShop(raw,snapshot,errors);
internal void ResetForKVLoad()
{
shopPackDailyBuyCount=new Dictionary<string,int>(StringComparer.Ordinal); shopAllPackBuyCount=new Dictionary<int,int>();
shopGiftBuyCount=new Dictionary<int,int>(); buyData=new List<float>(); advertCount=new Dictionary<int,int>();
Voucher=0; ChainPackData=null; VIPAdPackData=null; TurntableAdData=null;
_diamondShopItemRecords=new Dictionary<int,ItemShopRecord>(); _diamondShopRefreshCount=0; _diamondShopRefreshTime=default;
CouponData.ResetForKVLoad();
}
static DailySignEvent KVDaily(game.PlayerDataStorage.PlayerKVDailyValue value) => value==null ? null :
new DailySignEvent { ID=value.Id,index=value.Index,lastID=value.LastId,time=value.Time };
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVShopState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
shopPackDailyBuyCount=state.Daily.ToDictionary(p=>p.Key,p=>p.Value,StringComparer.Ordinal);
shopAllPackBuyCount=state.All.ToDictionary(p=>p.Key,p=>p.Value); shopGiftBuyCount=state.Gift.ToDictionary(p=>p.Key,p=>p.Value);
advertCount=state.Advert.ToDictionary(p=>p.Key,p=>p.Value); buyData=new List<float>(state.Buy); Voucher=state.Voucher;
ChainPackData=KVDaily(state.Chain); TurntableAdData=KVDaily(state.Turntable);
VIPAdPackData=state.Vip==null ? null : new AdvertData { ID=state.Vip.Id,index=state.Vip.Index,day=state.Vip.Day,cdTime=state.Vip.Time,isOpen=state.Vip.Open };
_diamondShopItemRecords=state.Items.ToDictionary(p=>p.Key,p=>new ItemShopRecord(p.Value.Id,p.Value.Discount,p.Value.Bought));
_diamondShopRefreshCount=state.RefreshCount; _diamondShopRefreshTime=state.RefreshTime; CouponData.ReplaceFromKVDecoded(state.Coupon);
}
#if UNITY_EDITOR
internal game.PlayerDataStorage.PlayerKVShopState SnapshotForKVValidation()
{
game.PlayerDataStorage.PlayerKVDailyValue Daily(DailySignEvent v) => v==null ? null : new game.PlayerDataStorage.PlayerKVDailyValue(v.ID,v.index,v.lastID,v.time);
return new game.PlayerDataStorage.PlayerKVShopState(shopPackDailyBuyCount,shopAllPackBuyCount,shopGiftBuyCount,advertCount,
_diamondShopItemRecords.ToDictionary(p=>p.Key,p=>new game.PlayerDataStorage.PlayerKVShopItemValue(p.Value.ItemID,p.Value.Discount,p.Value.hasBought)),
buyData,Voucher,_diamondShopRefreshCount,_diamondShopRefreshTime,Daily(ChainPackData),Daily(TurntableAdData),
VIPAdPackData==null ? null : new game.PlayerDataStorage.PlayerKVAdvertValue(VIPAdPackData.ID,VIPAdPackData.index,VIPAdPackData.day,VIPAdPackData.cdTime,VIPAdPackData.isOpen),
new game.PlayerDataStorage.PlayerKVCouponState(CouponData.ActivateTime,CouponData.EventId,CouponData.RedirectId,CouponData.IsBought));
}
internal void MutateCollectionsForKVValidation()
{ buyData.Clear(); advertCount.Clear(); _diamondShopItemRecords.Values.First().Discount=99; }
#endif
public void InitData(Dictionary<string, string> userDatas)
{
if (userDatas == null || userDatas.Count < 1)

View File

@@ -37,6 +37,19 @@ namespace GameCore
MonthlySignEvent _monthlySignEvent = null;
internal static game.PlayerDataStorage.PlayerKVMonthlySignState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => game.PlayerDataStorage.PlayerKVSaveSchema.DecodeMonthlySign(raw,errors);
internal void ResetForKVLoad() { _monthlySignEvent = null; }
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVMonthlySignState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
_monthlySignEvent = !state.IsPresent ? null : new MonthlySignEvent
{
index = state.Index,
dailySignEvent = new DailySignEvent { ID=state.DailyId, index=state.DailyIndex, lastID=state.LastId, time=state.Time }
};
}
public DailySignEvent dailySignEvent
{
get => _monthlySignEvent == null ? null : _monthlySignEvent.dailySignEvent;

View File

@@ -47,6 +47,26 @@ namespace GameCore
public int FishHuntGameCount => _fishHuntGameCount;
public int BombGameCount => _bombGameCount;
internal void ResetForKVLoad()
{
_heistGameCount=_bombGameCount=_fishHuntGameCount=0;
opponentItemDatas=new List<OpponentItemData>(); opponentFriendItemDatas=new List<OpponentItemData>();
opponentNotFriendItemDatas=new List<OpponentItemData>(); opponentFriend=new List<OpponentItemData>();
opponentFriendDic=new Dictionary<string,OpponentItemData>(); opponentEnemy=new Dictionary<EnemyType,List<OpponentItemData>>();
opponentItemDatasPre=new List<OpponentItemData>(); opponentFriendItemDatasPre=new List<OpponentItemData>();
opponentNotFriendItemDatasPre=new List<OpponentItemData>(); powerData=new Dictionary<string,float>();
opponentData=null; nextOpponent=null; curEnemyType=EnemyType.Aquarium; RobotMapId=nextRobotMapId=0;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVCoreState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
_heistGameCount=state.Integer(16); _bombGameCount=state.Integer(17); _fishHuntGameCount=state.Integer(18);
}
internal bool IsOpponentEmptyForKVValidation => opponentItemDatas.Count==0 && opponentFriendItemDatas.Count==0 &&
opponentNotFriendItemDatas.Count==0 && opponentFriend.Count==0 && opponentFriendDic.Count==0 && opponentEnemy.Count==0 &&
opponentItemDatasPre.Count==0 && opponentFriendItemDatasPre.Count==0 && opponentNotFriendItemDatasPre.Count==0 &&
powerData.Count==0 && opponentData==null && nextOpponent==null && RobotMapId==0 && nextRobotMapId==0;
//public UnityEngine.Vector3 image_extra_pos { set; get; }
public void SetHeistGameCount(int value)

View File

@@ -52,6 +52,29 @@ namespace GameCore
//VIP 等级叠加
public Dictionary<string, GiftVIPDData> giftVIPDData = new Dictionary<string, GiftVIPDData>();
internal static game.PlayerDataStorage.PlayerKVTriggerState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => game.PlayerDataStorage.PlayerKVSaveSchema.DecodeTriggers(raw,errors);
internal void ResetForKVLoad()
{
triggerPackList=new List<TriggerPackBuyData>();
giftVIPDData=new Dictionary<string,GiftVIPDData>(StringComparer.Ordinal);
fixedTimeShopDic=new Dictionary<int,FixedTimeEvent>();
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVTriggerState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
var packs=state.Packs.Select(p=>new TriggerPackBuyData {
ID=p.ID,index=p.index,lastID=p.lastID,vipLevel=p.vipLevel,mapID=p.mapID,time=p.time }).ToList();
var gifts=state.Gifts.ToDictionary(p=>p.Key,p=>new GiftVIPDData {
oldVipLevel=p.Value.oldVipLevel,curVipLevel=p.Value.curVipLevel,timer=p.Value.timer },StringComparer.Ordinal);
var fixedValues=state.Fixed.ToDictionary(p=>p.Key,p=>new FixedTimeEvent { id=p.Value.id,endTime=p.Value.endTime });
triggerPackList=packs; giftVIPDData=gifts; fixedTimeShopDic=fixedValues;
}
#if UNITY_EDITOR
internal FixedTimeEvent FixedForKVValidation(int key) => fixedTimeShopDic.TryGetValue(key,out var value) ? value : null;
internal bool IsEmptyForKVValidation => triggerPackList.Count==0 && giftVIPDData.Count==0 && fixedTimeShopDic.Count==0;
#endif
public void Init()
{
playerShopData = GContext.container.Resolve<PlayerShopData>();

View File

@@ -19,6 +19,19 @@ public class EventPackData
}
}
private Data _data;
internal static game.PlayerDataStorage.PlayerKVEventPackState DecodeForKVLoad(System.Collections.Generic.IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeEventPack(raw,snapshot,errors);
internal void ResetForKVLoad() { _data=default(Data); }
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVEventPackState state)
{
if (state == null) throw new System.ArgumentNullException(nameof(state));
_data=new Data { currentEventID=state.EventId,purchaseCount=state.PurchaseCount,
VIPLvlWhenEventActivate=state.VipLevel,redirectID=state.RedirectId };
}
internal game.PlayerDataStorage.PlayerKVEventPackState SnapshotForKVValidation() =>
new game.PlayerDataStorage.PlayerKVEventPackState(_data.currentEventID,_data.purchaseCount,_data.VIPLvlWhenEventActivate,_data.redirectID);
public int CurrentEventID { get { return _data.currentEventID; } }
public int PurchaseCount { get { return _data.purchaseCount; } }
public int VIPLvlWhenEventActivated { get { return _data.VIPLvlWhenEventActivate; } }

View File

@@ -102,6 +102,51 @@ namespace DataCenter
{
private const bool EnableTraceLogs = false;
public const string SaveKey = "EventPartnerGatherData";
internal static game.PlayerDataStorage.PlayerKVPartnerState DecodeForKVLoad(
IReadOnlyDictionary<string,string> raw,game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => game.PlayerDataStorage.PlayerKVSaveSchema.DecodePartner(raw,snapshot,errors);
internal void ResetForKVLoad()
{
// Only a fresh controlled container is admitted. Never detach active gameplay work.
if(_isInit || _act!=null || _disposables!=null || _autoMatchStatusInFlight!=null || PartnerInfoManager.HasSubscriptionsForKVLoad)
throw new InvalidOperationException("Active partner module cannot enter KV load.");
var partner=new PartnerInfoManager();
var robot=new EventPartnerGatherRobotInvitationSystem();
GatherData=null; _isEventDataChanged=false; CurrentBuildPartner=null;
PartnerInfoManager=partner; RobotInvitationSystem=robot;
_fishingEvent=null; EventPartnerMineMainData=null; EventPartnerMineSpinPointList=null; EventPartnerMineInitData=null;
_nodeCumulativeSteps.Clear(); _nodeSteps.Clear(); _stageDropList.Clear(); StartTime=default; EndTime=default;
_isInit=false; _spinId=-1; _userGm=false; BonusPercent=0; BonusExpireDuration=0;
_dateTimeForGetEvent=default; startTime=0; delta=0; _lastAutoMatchStatusUtc=default; _cachedAutoMatchStatus=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVPartnerState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
if(!state.Present) { GatherData=null; return; }
GatherData=new EventPartnerGatherData
{
FirstOpen=state.FirstOpen,EventId=state.EventId,StartTime=state.StartTime,EndTime=state.EndTime,
CurrentPoints=state.CurrentPoints,CurrentMiningProgress=state.CurrentMiningProgress,Token=state.Token,
InvitedCount=state.InvitedCount,TicketCount=state.TicketCount,
CompletedNodesList=state.CompletedNodesList.Select(n=>new List<int>(n)).ToList(),
BuilderPartnerScore=new List<(int,int)>(state.BuilderPartnerScore),PartnerBonus=(state.BonusPercent,state.BonusExpireUtc),
FreeSpinNum=state.FreeSpinNum,Bots=state.Bots.ToDictionary(p=>p.Key,p=>new EventBuildBotInfo
{ Id=p.Value.Id,ScorePlayer=p.Value.ScorePlayer,ScoreBot=p.Value.ScoreBot,Grade=p.Value.Grade,
TargetScore=p.Value.TargetScore,WakeStartTime=p.Value.WakeStartTime,WakingSeconds=p.Value.WakingSeconds }),
IsRecvFinalReward=state.IsRecvFinalReward,UIFinishedPartners=new List<bool>(state.UIFinishedPartners),
IsFinished=state.IsFinished,SpinState=(ESpinState)state.SpinState,InflationRate=state.InflationRate,
IsEnableAutoMatch=state.IsEnableAutoMatch,LastAutoMatchTime=state.LastAutoMatchTime
};
}
#if UNITY_EDITOR
internal bool RuntimeEmptyForKVValidation => !_isInit && !_isEventDataChanged && _act==null && _disposables==null &&
_autoMatchStatusInFlight==null && _cachedAutoMatchStatus==null && _fishingEvent==null && CurrentBuildPartner==null &&
EventPartnerMineMainData==null && EventPartnerMineSpinPointList==null && EventPartnerMineInitData==null &&
_nodeCumulativeSteps.Count==0 && _nodeSteps.Count==0 && _stageDropList.Count==0 && StartTime==default && EndTime==default &&
_spinId==-1 && !_userGm && BonusPercent==0 && BonusExpireDuration==0 && _dateTimeForGetEvent==default &&
startTime==0 && delta==0 && _lastAutoMatchStatusUtc==default && !PartnerInfoManager.HasSubscriptionsForKVLoad;
#endif
[Inject] public Tables _tables { get; set; }
[Inject] public EventPartnerService EventPartnerService { get; set; }

View File

@@ -449,6 +449,38 @@ namespace game
#region 数据相关
private EventPinballData m_PinballData;
internal bool IsInactiveForKVValidation => m_Tables==null && m_TbEventPinballMain==null && m_TbEventPinballPoint==null &&
m_TbEventPinballReward==null && m_UIPanel==null && m_InfoPanel==null && m_RewardList.Count==0 &&
m_PointWeightList.Count==0 && !m_IsSimulatorMode && !m_IsMultipleMax && m_CumulativeResponseNumber==0 &&
m_AccumulatedTriggerCount==0 && m_TemporaryScore==0 && m_TemporaryConsumedToken==0 && m_MagnificationListIndex==0 && m_BonusResponseNumber==10;
internal static game.PlayerDataStorage.PlayerKVPinballState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodePinball(raw,snapshot,errors);
internal void ResetForKVLoad()
{
m_PinballData=null; m_BonusResponseNumber=10; m_CumulativeResponseNumber=m_AccumulatedTriggerCount=m_TemporaryScore=m_TemporaryConsumedToken=m_MagnificationListIndex=0;
m_IsMultipleMax=false; m_IsSimulatorMode=false; m_RewardList=new List<float>(); m_PointWeightList=new List<float>(); m_UIPanel=m_InfoPanel=null;
m_Tables=null; m_TbEventPinballMain=null; m_TbEventPinballPoint=null; m_TbEventPinballReward=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVPinballState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
m_PinballData=!state.IsPresent ? null : new EventPinballData
{
EventID=state.EventID,
PinballMainID=state.PinballMainID,
SpinPoint=state.SpinPoint,
Scores=state.Scores,
Multiple=state.Multiple,
Token=state.Token,
ConsumedToken=state.ConsumedToken,
RewardIndex=state.RewardIndex,
Force=state.Force,
LuckyValue=state.LuckyValue,
InflationRate=state.InflationRate
};
}
public EventPinballData PinballData { get { return m_PinballData; } }
public int RewardMaxIndex
{
@@ -957,4 +989,4 @@ namespace game
public const int MultipleMax = 10;
}
}
}

View File

@@ -125,6 +125,55 @@ namespace game
#region 数据相关
private EventPotionData m_PotionData;
internal static PlayerDataStorage.PlayerKVPotionState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
PlayerDataStorage.PlayerKVSchemaDiagnostics errors) => PlayerDataStorage.PlayerKVSaveSchema.DecodePotion(raw,errors);
internal void ResetForKVLoad()
{
m_PotionData=null; m_PendingFirstPlayedEventId=0; m_SpriteAtlas=null; m_Tables=null;
m_TbEventPotionMain=null; m_TbEventPotionStage=null; m_TbEventPotionBlock=null; m_TbEventPotionBottle=null;
m_PotionResDict=new Dictionary<int,EventPotionResource>(); m_WallsBefore=new List<PotionItemData>(); m_WallsAfter=new List<PotionItemData>();
m_UIPanel=m_InfoPanel=m_RewardPopupPanel=null; m_ScrollerDataList=new List<PotionItemData>();
}
static PotionItemData MaterializeKVPotionItem(PlayerDataStorage.PlayerKVPotionItem value) => new PotionItemData {
name=value.Name,index=value.Index,isOver=value.IsOver,DataType=(EventPotionDataType)value.DataType,
ColorTypeList=new List<int>(value.Colors),ShelfTypeList=value.Shelves.Select(n=>(EventPotionShelfType)n).ToList(),
GridStateList=value.Grids.Select(n=>(EventPotionGridState)n).ToList(),FromDisplayAreaIndexList=new List<int>(value.FromDisplay)
};
internal void ReplaceFromKVDecoded(PlayerDataStorage.PlayerKVPotionState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
m_PotionData=!state.IsPresent ? null : new EventPotionData {
EventID=state.EventID,
PotionID=state.PotionID,
StageID=state.StageID,
Stage1TotalLevel=state.Stage1TotalLevel,
Stage2TotalLevel=state.Stage2TotalLevel,
LevelID=state.LevelID,
LevelIndex=state.LevelIndex,
CorrectNum=state.CorrectNum,
SubmitNum=state.SubmitNum,
Token=state.Token,
ConsumedToken=state.ConsumedToken,
Rule=state.Rule,
PreEventID=state.PreEventID,
PrePotionID=state.PrePotionID,
PreStageID=state.PreStageID,
PreLevelID=state.PreLevelID,
Round=state.Round,
FirstPlayedEventId=state.FirstPlayedEventId,
IsOver=state.IsOver,
Name=state.Name,
InflationRate=state.InflationRate,
LevelTargetData=MaterializeKVPotionItem(state.LevelTargetData),
LevelDisplayData=MaterializeKVPotionItem(state.LevelDisplayData),
LevelProcessedList=state.LevelProcessedList.Select(MaterializeKVPotionItem).ToList()
};
}
internal bool IsInactiveForKVValidation => m_PendingFirstPlayedEventId==0 && m_SpriteAtlas==null && m_Tables==null &&
m_TbEventPotionMain==null && m_TbEventPotionStage==null && m_TbEventPotionBlock==null && m_TbEventPotionBottle==null &&
m_PotionResDict.Count==0 && m_WallsBefore.Count==0 && m_WallsAfter.Count==0 && m_ScrollerDataList.Count==0 &&
m_UIPanel==null && m_InfoPanel==null && m_RewardPopupPanel==null;
public EventPotionData PotionData { get { return m_PotionData; } }
public void InitLevel()

View File

@@ -94,6 +94,45 @@ namespace game
#region 数据相关
private EventScratchTicketData m_ScratchTicketData;
internal bool IsInactiveForKVValidation => m_Tables==null && m_TbEventScratchMain==null && m_TbEventScratchCard==null &&
m_TbEventScratchReward==null && m_ChainPackData==null && m_NormalPackData==null && m_SpriteAtlas==null && m_SpriteDict==null &&
m_UIPanel==null && m_InfoPanel==null && m_RewardPanel==null && m_ChainPackPanel==null && m_PackPanel==null &&
m_RecordList.Count==0 && m_PointWeightList.Count==0 && m_ScratchStampList.Count==0 &&
TempRecordRewardTaskID==0 && TempRecordRewardTaskConsumedToken==0;
internal static game.PlayerDataStorage.PlayerKVScratchState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeScratch(raw,snapshot,errors);
internal void ResetForKVLoad()
{
m_ScratchTicketData=null; TempRecordRewardTaskID=TempRecordRewardTaskConsumedToken=0; m_RecordList=new List<EventScratchTicketRecordData>();
m_PointWeightList=new List<float>(); m_ScratchStampList=new List<int>(); m_ChainPackData=null; m_NormalPackData=null;
m_UIPanel=m_InfoPanel=m_RewardPanel=m_ChainPackPanel=m_PackPanel=null; m_SpriteAtlas=null; m_SpriteDict=null;
m_Tables=null; m_TbEventScratchMain=null; m_TbEventScratchCard=null; m_TbEventScratchReward=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVScratchState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
m_ScratchTicketData=!state.IsPresent ? null : new EventScratchTicketData
{
EventID=state.EventID,
ScratchMainID=state.ScratchMainID,
ChainPackID=state.ChainPackID,
Token=state.Token,
ConsumedToken=state.ConsumedToken,
RewardTaskConsumedToken=state.RewardTaskConsumedToken,
EventScratchRewardTaskID=state.EventScratchRewardTaskID,
EventScratchCardID=state.EventScratchCardID,
TotalConsumedToken=state.TotalConsumedToken,
ChainPackProgress=state.ChainPackProgress,
magIndex=state.magIndex,
IsOver=state.IsOver,
LuckyValue=state.LuckyValue,
InflationRate=state.InflationRate,
StampRewardList=new List<int>(state.StampRewardList),
StampRewardDict=state.StampRewardDict.ToDictionary(p=>p.Key,p=>new EventScratchTicketOwnedStampRewardData { EventScratchCardID=p.Value.EventScratchCardID,Count=p.Value.Count })
};
}
public EventScratchTicketData ScratchTicketData { get { return m_ScratchTicketData; } }
public EventScratchMain GetFreshScratchTicketData()
{

View File

@@ -13,6 +13,20 @@ public class FishingBoxData
public Dictionary<int, int> FishingNewBoxs = new();
public Dictionary<int, int> FishingBoxOpenNum = new();
internal static game.PlayerDataStorage.PlayerKVIntMapState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
IReadOnlyDictionary<string,string> modern, game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeFishingBox(raw,modern,errors);
internal void ResetForKVLoad()
{
FishingNewBoxs = new Dictionary<int,int>();
FishingBoxOpenNum = new Dictionary<int,int>();
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVIntMapState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
FishingBoxOpenNum = state.Values.ToDictionary(p=>p.Key,p=>p.Value);
}
public void InitData(string data)
{
if (string.IsNullOrEmpty(data) == false)

View File

@@ -61,6 +61,40 @@ public class FishingChallengeManager
private DateTime EndTime;
//
public FishingChallengeData fishingChallengeData { get; private set; }
internal bool IsInactiveForKVValidation => !IsInit && CurFishingEventData==null && eventChallengeMain==null &&
eventChallengeConfig==null && challengeMapData==null && _stageDropList.Count==0 && _eliminateListScore.Count==0;
internal static game.PlayerDataStorage.PlayerKVChallengeState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeChallenge(raw,snapshot,errors);
internal void ResetForKVLoad()
{
fishingChallengeData=null; IsInit=false; PrefabName=null; TopRankTier=Rank=FullStep=PlayerFullNumber=PreScore=_cheatingScore=0;
CurFishingEventData=null; StartTime=EndTime=default; eventChallengeMain=null; eventChallengeConfig=null; challengeMapData=null; itemDataList=null;
_stageDropList.Clear(); _eliminateListScore.Clear(); _eventTrackStageList=new List<int>(); _eventTrackNormalRewardList=new List<int>(); InVisibleReason=string.Empty;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVChallengeState state)
{
if(state==null) throw new ArgumentNullException(nameof(state));
fishingChallengeData=!state.IsPresent || state.IsExplicitNull ? null : new FishingChallengeData
{
FirstOpen=state.FirstOpen,
EventId=state.EventId,
RankTierLevel=state.RankTierLevel,
Finished=state.Finished,
RedirectID=state.RedirectID,
Score=state.Score,
ProcessedScore=state.ProcessedScore,
step=state.step,
uiStep=state.uiStep,
index=state.index,
StartTime=state.StartTime,
EndTime=state.EndTime,
eliminateNumber=new List<int>(state.eliminateNumber),
robotAccountList=new List<int>(state.robotAccountList),
InflationRate=state.InflationRate
};
}
public EventChallengeMain eventChallengeMain { get; private set; }
public EventChallengeConfig eventChallengeConfig { get; private set; }
public MapData challengeMapData { get; private set; }
@@ -1071,4 +1105,4 @@ public class FishingChallengeManager
_stageDropList.Clear();
_eventTrackStageList = new();
}
}
}

View File

@@ -51,6 +51,28 @@ namespace DataCenter
public List<EventOfferChainsChestRewards> OfferChainsChestRewards { get; set; }
// 当前可保存数据
public TOfferChainsData OfferChainsData { get; private set; }
internal static game.PlayerDataStorage.PlayerKVOfferState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeOffer(raw,false,snapshot,errors);
internal void ResetForKVLoad()
{
OfferChainsData=null; ValidIds=new List<int>(); _fishingEvent=null; _isInit=false;
OfferChainsChestMain=null; OfferChainsChestRewards=null;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVOfferState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
OfferChainsData=!state.IsPresent ? null : new TOfferChainsData
{
FirstOpen=state.FirstOpen,EventId=state.EventId,StartTime=state.StartTime,EndTime=state.EndTime,
ItemId=state.ItemId,LotteryNum=state.LotteryNum,
Items=state.Items.Select(item=>new TOfferChainsData.TItem {
Id=item.Id,Item=item.Item,Number=item.Number,Status=item.Status }).ToList(),
RewardList=new List<int>(state.RewardList),Finished=state.Finished,ChestReward=state.ChestReward
};
}
internal bool IsInactiveForKVValidation => !_isInit && _fishingEvent == null;
public List<int> ValidIds;
public bool IsFirstOpen
@@ -546,4 +568,4 @@ namespace DataCenter
return iAPItemList;
}
}
}
}

View File

@@ -61,6 +61,28 @@ namespace DataCenter
public TOfferDiscoPartyData OfferDiscoPartyData { get; private set; }
internal static game.PlayerDataStorage.PlayerKVOfferState DecodeForKVLoad(IReadOnlyDictionary<string,string> raw,
game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodeOffer(raw,true,snapshot,errors);
internal void ResetForKVLoad()
{
OfferDiscoPartyData=null; ValidIds=new List<int>(); _fishingEvent=null; _isInit=false;
OfferDiscoParty=null; OfferDiscoPartyRewards=null; FreeTime=1;
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVOfferState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
OfferDiscoPartyData=!state.IsPresent ? null : new TOfferDiscoPartyData
{
FirstOpen=state.FirstOpen,EventId=state.EventId,StartTime=state.StartTime,EndTime=state.EndTime,
ItemId=state.ItemId,LotteryNum=state.LotteryNum,
Items=state.Items.Select(item=>new TOfferDiscoPartyData.TItem {
Id=item.Id,Item=item.Item,Number=item.Number,Status=(TItemStatues) item.Status }).ToList(),
RewardList=new List<int>(state.RewardList)
};
}
internal bool IsInactiveForKVValidation => !_isInit && _fishingEvent == null;
public List<int> ValidIds; //
@@ -561,4 +583,4 @@ namespace DataCenter
return iAPItemList;
}
}
}
}

View File

@@ -34,14 +34,47 @@ public class PiggyBankPackData
}
}
private Data _data;
private bool _kvLoadPresent;
internal bool KVLoadPresent => _kvLoadPresent;
internal static game.PlayerDataStorage.PlayerKVPiggyBankState DecodeForKVLoad(
IReadOnlyDictionary<string, string> raw, game.PlayerDataStorage.PlayerKVSchemaSnapshot snapshot,
game.PlayerDataStorage.PlayerKVSchemaDiagnostics errors) =>
game.PlayerDataStorage.PlayerKVSaveSchema.DecodePiggyBank(raw, snapshot, errors);
internal void ResetForKVLoad()
{
_kvLoadPresent = false;
_data = default(Data);
}
internal void ReplaceFromKVDecoded(game.PlayerDataStorage.PlayerKVPiggyBankState state)
{
if (state == null) throw new ArgumentNullException(nameof(state));
if (!state.IsPresent) { ResetForKVLoad(); return; }
var replacement = new Data
{
currentEventID = state.currentEventID,
purchaseCount = state.purchaseCount,
VIPLvlWhenEventActivate = state.VIPLvlWhenEventActivate,
savingProgress = state.savingProgress,
redirectID = state.redirectID,
doNeedTrigger = state.doNeedTrigger,
isTriggered = state.isTriggered,
inflation = state.inflation,
};
_data = replacement;
_kvLoadPresent = true;
}
internal game.PlayerDataStorage.PlayerKVPiggyBankState SnapshotForKVValidation() =>
new game.PlayerDataStorage.PlayerKVPiggyBankState(_kvLoadPresent, _data.currentEventID, _data.purchaseCount, _data.VIPLvlWhenEventActivate, _data.savingProgress, _data.redirectID, _data.doNeedTrigger, _data.isTriggered, _data.inflation);
public bool IsWithinEventTime
{
get
{
if (!_tables.TbFishingEvent.DataMap.Keys.Contains(_data.currentEventID))
return false;
var et = DateTime.Parse((_tables.TbFishingEvent[_data.currentEventID].TimeDefinition as LimitedTime).EndTime);
var st = DateTime.Parse((_tables.TbFishingEvent[_data.currentEventID].TimeDefinition as LimitedTime).StartTime);
var fishingEvent = _tables.TbFishingEvent.GetOrDefault(_data.currentEventID);
if (!(fishingEvent?.TimeDefinition is LimitedTime time)) return false;
var et = DateTime.Parse(time.EndTime);
var st = DateTime.Parse(time.StartTime);
return ZZTimeHelper.UtcNow() >= st && ZZTimeHelper.UtcNow() < et;
}
}