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,296 @@
|
||||
using asap.core;
|
||||
using game;
|
||||
using GameCore;
|
||||
using System.Text;
|
||||
|
||||
namespace PinballUncountable
|
||||
{
|
||||
public class Manager : IHasMultiplier
|
||||
{
|
||||
readonly game.PlayerDataStorage.IPlayerSaveStore saveStore = GContext.container.Resolve<game.PlayerDataStorage.IPlayerSaveStore>();
|
||||
|
||||
private int _score, _ticketCount, _hitCountLeft, _hitCountRight;
|
||||
private float _inflationRate = 0f;
|
||||
private IEventAggregator _eventAggregator = new EventAggregator();
|
||||
private TableContext _tableContext;
|
||||
public IEventAggregator EventAggregator => _eventAggregator;
|
||||
public TableContext TableContext => _tableContext;
|
||||
public int HitCount1 => _hitCountLeft;
|
||||
public int HitCount2 => _hitCountRight;
|
||||
|
||||
public float InflationRate => _inflationRate;
|
||||
public int Score => _score;
|
||||
public readonly string RedPointKey = "pinball_uncountable";
|
||||
|
||||
#region Initiation
|
||||
public static void InitEvent(cfg.FishingEvent e)
|
||||
{
|
||||
var manager = GContext.container.Resolve<Manager>();
|
||||
if (manager == null)
|
||||
{
|
||||
GContext.container.Register<Manager>().AsSingleton();
|
||||
manager = GContext.container.Resolve<Manager>();
|
||||
}
|
||||
var loadRes = manager.Load();
|
||||
if (!loadRes || e.ID != manager.TableContext.EventId)
|
||||
{
|
||||
manager.Init(e.ID);
|
||||
manager.SavePlayfab();
|
||||
}
|
||||
UITypes.PinballUncountablePanel.SetType(manager.TableContext.GetPanelUrl());
|
||||
UITypes.PinballUncountableNormalPackPanel.SetType(manager.TableContext.GetNormalPackPanelUrl());
|
||||
UITypes.PinballUncountableInfoPanel.SetType(manager.TableContext.GetInfoPanelUrl());
|
||||
}
|
||||
|
||||
public void Init(int eventId)
|
||||
{
|
||||
_tableContext = new TableContext(eventId);
|
||||
_score = 0;
|
||||
_ticketCount = _tableContext.GetInitWelcomeGift();
|
||||
_hitCountLeft = 0;
|
||||
_hitCountRight = 0;
|
||||
_inflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
|
||||
}
|
||||
|
||||
public bool Load()
|
||||
{
|
||||
return Deserialize(saveStore.Read(_playfabKey).ValueOrThrow());
|
||||
}
|
||||
|
||||
public void InitTest()
|
||||
{
|
||||
_eventAggregator = new EventAggregator();
|
||||
_tableContext = TableContext.InitTest();
|
||||
_score = 0;
|
||||
_ticketCount = 5555;
|
||||
_hitCountLeft = 0;
|
||||
_hitCountRight = 0;
|
||||
_inflationRate = GContext.container.Resolve<PlayerData>().InflationRate;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region System
|
||||
|
||||
public void OnBallCreate(int hit1, int hit2, int exitIdx)
|
||||
{
|
||||
int hitCountLeftNew = _hitCountLeft + hit1;
|
||||
int hitCountRightNew = _hitCountRight + hit2;
|
||||
int scoreNew = _score + _tableContext.GetPointMagFromExitIndex(exitIdx);
|
||||
|
||||
TryGrantDiscReward(0, _hitCountLeft, hitCountLeftNew);
|
||||
TryGrantDiscReward(1, _hitCountRight, hitCountRightNew);
|
||||
TryGrantProgressReward(_score, scoreNew);
|
||||
|
||||
|
||||
|
||||
_hitCountLeft = hitCountLeftNew;
|
||||
_hitCountRight = hitCountRightNew;
|
||||
_score = scoreNew;
|
||||
// UnityEngine.Debug.Log($"[PinballUncountable] ScoreRecord @ {exitIdx}: {_hitCountLeft}, {_hitCountRight}, {_score}");
|
||||
SavePlayfab();
|
||||
}
|
||||
|
||||
public void AddScore(int score2Add)
|
||||
{
|
||||
_score += score2Add;
|
||||
SavePlayfab();
|
||||
}
|
||||
|
||||
public bool AddTicket(int ticket2Add)
|
||||
{
|
||||
if (_ticketCount + ticket2Add < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_ticketCount += ticket2Add;
|
||||
EventAggregator.Publish(new PinballUncountable.EventTicketUpdate());
|
||||
RedPointManager.Instance.SetRedPointState(RedPointKey, _ticketCount > 0, _ticketCount);
|
||||
SavePlayfab();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void TryGrantDiscReward(int idx, int hitCountOld, int hitCountNew)
|
||||
{
|
||||
var dropList = TableContext.GetRewardDropIdListFromHitCount(idx, hitCountOld, hitCountNew);
|
||||
var changeSource = new ChangeSource(TableContext.EventId, "PinballUncountable", "Disc", "PinballUncountable");
|
||||
// UnityEngine.Debug.Log($"[PinballUncountable] TryGrantDiscReward @{InflationRate}: {string.Join(",", dropList)}");
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashDropList
|
||||
{
|
||||
DropList = dropList,
|
||||
changeSource = changeSource,
|
||||
Inflate = InflationRate
|
||||
});
|
||||
|
||||
// int evEventId, evRound, evRewardId;
|
||||
// evEventId = TableContext.EventId;
|
||||
// evRound = -1;
|
||||
// for (int i = 0; i < dropList.Count; i++)
|
||||
// {
|
||||
// evRewardId = dropList[i];
|
||||
// UnityEngine.Debug.Log($"[PinballUncountable] EventTrack: Reward {evEventId}, {evRound}, {evRewardId}");
|
||||
// #if AGG
|
||||
// using (var e = GEvent.GameEvent("event_pinballuncountable_reward"))
|
||||
// {
|
||||
// e.AddContent("event_id", evEventId)
|
||||
// .AddContent("round", evRound)
|
||||
// .AddContent("reward_id", evRewardId);
|
||||
// }
|
||||
// #endif
|
||||
// }
|
||||
}
|
||||
|
||||
private void TryGrantProgressReward(int oldScore, int newScore)
|
||||
{
|
||||
var (dropList, roundList) = TableContext.GetRewardDropIdListFromScore(oldScore, newScore);
|
||||
var changeSource = new ChangeSource(TableContext.EventId, "PinballUncountable", "Score", "PinballUncountable");
|
||||
// UnityEngine.Debug.Log($"[PinballUncountable] TryGrantProgressReward @{InflationRate}: {string.Join(",", dropList)}");
|
||||
GContext.Publish(new DeferredRewardStashService.EventStashDropList
|
||||
{
|
||||
DropList = dropList,
|
||||
changeSource = changeSource,
|
||||
Inflate = InflationRate
|
||||
});
|
||||
|
||||
int evEventId, evRound, evRewardId;
|
||||
evEventId = TableContext.EventId;
|
||||
int oldMaxScore = TableContext.GetCurrentMaxScore(oldScore);
|
||||
int newMaxScore = TableContext.GetCurrentMaxScore(newScore);
|
||||
|
||||
for (int i = 0; i < dropList.Count; i++)
|
||||
{
|
||||
evRound = roundList[i];
|
||||
evRewardId = dropList[i];
|
||||
// UnityEngine.Debug.Log($"[PinballUncountable] EventTrack: Reward {evEventId}, {evRound}, {evRewardId}");
|
||||
#if AGG
|
||||
using (var e = GEvent.GameEvent("event_pinballuncountable_reward"))
|
||||
{
|
||||
e.AddContent("event_id", evEventId)
|
||||
.AddContent("round", evRound)
|
||||
.AddContent("reward_id", evRewardId);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Get Data
|
||||
public int GetHitCountByIdx(int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
return _hitCountLeft;
|
||||
else if (idx == 1)
|
||||
return _hitCountRight;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int GetCurrentMaxMultiplier()
|
||||
{
|
||||
var multipliers = _tableContext.GetMultiplierArray();
|
||||
for (int i = multipliers.Length - 1; i >= 0; i--)
|
||||
{
|
||||
if (multipliers[i] > _ticketCount)
|
||||
continue;
|
||||
return multipliers[i];
|
||||
}
|
||||
return multipliers[0];
|
||||
}
|
||||
|
||||
public bool IsWithinTime()
|
||||
{
|
||||
(var startTime, var endTime) = FtUtils.GetEventTimeLimit(TableContext.EventId);
|
||||
return startTime <= ZZTimeHelper.UtcNow() && ZZTimeHelper.UtcNow() <= endTime;
|
||||
}
|
||||
|
||||
public PinballUncountableEntranceButtonData GetEntranceData()
|
||||
{
|
||||
var data = new PinballUncountableEntranceButtonData();
|
||||
data.TimerContext = _tableContext.GetTimerContext();
|
||||
data.IconUrl = _tableContext.GetIconUrl();
|
||||
return data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DataStorage
|
||||
private readonly string _playerPreferencesKey = "PinballUncountable" + GContext.container.Resolve<IUserService>().UserId;
|
||||
private readonly string _playfabKey = "PinballUncountable";
|
||||
private readonly char _separator = ',';
|
||||
|
||||
public string Serialize()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(TableContext.EventId).Append(_separator);
|
||||
sb.Append(_score).Append(_separator);
|
||||
sb.Append(_ticketCount).Append(_separator);
|
||||
sb.Append(_hitCountLeft).Append(_separator);
|
||||
sb.Append(_hitCountRight).Append(_separator);
|
||||
sb.Append(_inflationRate);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public bool Deserialize(string data)
|
||||
{
|
||||
if (data == null || data == "")
|
||||
return false;
|
||||
var arr = data.Trim(_separator).Split(_separator);
|
||||
if (arr.Length != 6)
|
||||
{
|
||||
UnityEngine.Debug.LogError("[PinballUncountable]Data Corrupted.");
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
_tableContext = new TableContext(int.Parse(arr[0]));
|
||||
_score = int.Parse(arr[1]);
|
||||
_ticketCount = int.Parse(arr[2]);
|
||||
_hitCountLeft = int.Parse(arr[3]);
|
||||
_hitCountRight = int.Parse(arr[4]);
|
||||
_inflationRate = float.Parse(arr[5]);
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
UnityEngine.Debug.LogError(e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SavePlayfab()
|
||||
{
|
||||
// UnityEngine.Debug.Log("[PinballUncountable]Save Data.");
|
||||
saveStore.Write(_playfabKey, Serialize()).RequireAccepted();
|
||||
}
|
||||
|
||||
public void SavePlayerPreferences(int multiplier)
|
||||
{
|
||||
UnityEngine.PlayerPrefs.SetInt(_playerPreferencesKey, multiplier);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Multiplier
|
||||
public int GetTicketCount()
|
||||
{
|
||||
return _ticketCount;
|
||||
}
|
||||
|
||||
public int[] GetMultiplierArray()
|
||||
{
|
||||
return _tableContext.GetMultiplierArray();
|
||||
}
|
||||
|
||||
public int GetMultiplier()
|
||||
{
|
||||
return UnityEngine.PlayerPrefs.GetInt(_playerPreferencesKey, -1);
|
||||
}
|
||||
|
||||
public void SetMultiplier(int multiplier)
|
||||
{
|
||||
SavePlayerPreferences(multiplier);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user