using System.Linq; using UnityEngine; using SystemRandom = System.Random; using System.Text; using System; using UnityEngine.Assertions; using GameCore; using cfg; using System.Collections.Generic; using asap.core; public class DrillBlockData { public ItemData Item { get; set; } public bool IsEmpty => Item == null || Item.id == -1 || (int)Item.count == 0; public static DrillBlockData CreateEmpty() { return new DrillBlockData(); } } public class DrillJobModel { public int Cost { get; set; } public DrillBlockData[] Blocks { get; set; } } public class EventBreakTaskGenerationInfo { public int TableId { get; set; } public int CurrentGemProgress { get; set; } public int TargetItemId { get; set; } } public class EventBreakTaskInfo { public int TaskId { get; set; } public int TargetItemId { get; set; } public ItemData Reward { get; set; } public int TotalGemRequired { get; set; } public int CurrentGemProgress { get; set; } } public class DrillModel : IHasChainPack { public int EventId { get; set; } public int TicketCount { get; private set; } public DrillJobModel[] DrillJobList { get; set; } public EventBreakTaskInfo[] TaskInfoList { get; set; } public int[] DrillJobSeeds { get; set; } public int ChainPackProgress; public void Update(int eventId, EventBreakPfData pfData = null) // new event { if (pfData == null || pfData.EventId != eventId) { GenSeeds(); EventBreakAct.Ctx.GetFreshNewModelData(DrillJobSeeds, out var welcomeGift, out var drillJobs, out var taskInfoList); EventId = eventId; TicketCount = welcomeGift; TaskInfoList = taskInfoList; DrillJobList = drillJobs; ChainPackProgress = 0; ToPlayfabData().Save(); return; } // var playerPreferenceData = EventBreakPlayerPreferenceData.Get(EventBreakAct.Ctx.TunnelCount); EventId = eventId; TicketCount = pfData.TicketCount; DrillJobSeeds = pfData.DrillJobSeeds; TaskInfoList = EventBreakAct.Ctx.GetTaskInfoArray(pfData.TaskData); DrillJobList = EventBreakAct.Ctx.GetDrillJobModels(pfData.DrillJobSeeds); ChainPackProgress = pfData.ChainPackProgress; return; } private void GenSeeds() { DrillJobSeeds ??= new int[EventBreakAct.Ctx.TunnelCount]; for (int i = 0; i < DrillJobSeeds.Length; i++) DrillJobSeeds[i] = 0; // ToPlayfabData().Save(); } public void UpdateSeed(int idx) { // DrillJobSeeds ??= new int[EventBreakAct.Ctx.TunnelCount]; if (EventBreakAct.Ctx.DoesSeedNeedInc(idx, DrillJobSeeds[idx])) { DrillJobSeeds[idx]++; ToPlayfabData().Save(); return; } Assert.IsTrue(idx >= 0 && idx < DrillJobSeeds.Length, $"[EventBreak] Cannot genenrate seed, idx {idx} is out of range [0, {DrillJobSeeds.Length}]"); var seed = DateTime.Now.Millisecond; DrillJobSeeds[idx] = new SystemRandom(seed).Next(); ToPlayfabData().Save(); } public bool AddTicket(int add) { if (TicketCount + add < 0) return false; TicketCount += add; ToPlayfabData().Save(); GContext.container.Resolve().SaveTransitionData(EventId, TicketCount); EventBreakAct.EventAggregator.Publish(new EventTicketUpdate()); return true; } public EventBreakPfData ToPlayfabData() { return new EventBreakPfData { EventId = EventId, TicketCount = TicketCount, TaskData = TaskInfoList.Select(i => (i.TaskId, i.CurrentGemProgress)).ToArray(), ChainPackProgress = ChainPackProgress, DrillJobSeeds = DrillJobSeeds }; } public void SetChainProgress(int p) { ChainPackProgress = p; } public int GetChainProgress() { return ChainPackProgress; } public void Save() { ToPlayfabData().Save(); } public GenericChainPackData ToChainPackData() { return GenericChainPackData.Create(this, EventBreakAct.Ctx.GetPackData()); } } public class EventBreakPfData { public int EventId { get; set; } public int TicketCount { get; set; } public int ChainPackProgress { get; set; } public (int id, int progress)[] TaskData { get; set; } public int[] DrillJobSeeds { get; set; } private const string Splitter = ","; public const string PfKey = "EventBreak"; /// /// Temporary stash. /// // public static EventBreakPfData Stash = null; private const int TokenCount = 12; public string Serialize() { var s = new StringBuilder(); s.Append(EventId + Splitter); s.Append(TicketCount + Splitter); s.Append(ChainPackProgress + Splitter); foreach (var (id, progress) in TaskData) s.Append(id + Splitter + progress + Splitter); foreach (var seed in DrillJobSeeds) s.Append(seed + Splitter); return s.ToString(); } public static EventBreakPfData Deserialize(string s) { if (s == null) { Debug.Log($"[EventBreak]Null string."); return null; } var res = new EventBreakPfData(); var tokens = s.Trim(Splitter[0]).Split(Splitter); if (tokens.Length != TokenCount) { Debug.Log($"[EventBreak]Wrong string format: string \"{s}\" has {tokens.Length} tokens, and the expected number is {TokenCount}"); return null; } try { res.EventId = int.Parse(tokens[0]); res.TicketCount = int.Parse(tokens[1]); res.ChainPackProgress = int.Parse(tokens[2]); res.TaskData = new (int id, int progress)[3]; int i = 3; while (i < 9) { res.TaskData[i / 2 - 1] = (int.Parse(tokens[i]), int.Parse(tokens[i + 1])); i += 2; } res.DrillJobSeeds = new int[3]; while (i < TokenCount) { res.DrillJobSeeds[i - 9] = int.Parse(tokens[i]); i++; } } catch (Exception e) { Debug.Log($"[EventBreak]Possible parse error: {e.Message}\n{e.StackTrace}"); return null; } return res; } public void Save() { var s = Serialize(); PlayFabMgr.Instance.UpdateUserDataValue(PfKey, s); } } [Obsolete] public class EventBreakPlayerPreferenceDataLegacy { public int[] Seeds { get; set; } private const string Splitter = ",", PpKey = "EventBreakCache"; public static EventBreakPlayerPreferenceDataLegacy Get(int seedCount = 3) { var s = PlayerPrefs.GetString(PpKey); if (s == "") return GenSeeds(seedCount); var res = Deserialize(s); if (res == null) return GenSeeds(seedCount); return res; } private static EventBreakPlayerPreferenceDataLegacy GenSeeds(int count) { var seeds = new int[count]; var rng = new SystemRandom(DateTime.Now.Millisecond); for (int i = 0; i < count; i++) seeds[i] = rng.Next(); return new EventBreakPlayerPreferenceDataLegacy { Seeds = seeds }; } private static EventBreakPlayerPreferenceDataLegacy Deserialize(string s) { var tokens = s.Trim(Splitter[0]).Split(Splitter); var seeds = new int[tokens.Length]; try { for (int i = 0; i < tokens.Length; i++) seeds[i] = int.Parse(tokens[i]); return new EventBreakPlayerPreferenceDataLegacy { Seeds = seeds }; } catch (Exception e) { Debug.Log($"[EventBreak]Possible parse error: {e.Message}\n{e.StackTrace}"); return null; } } private string Serialize() { var sb = new StringBuilder(); foreach (var seed in Seeds) { sb.Append(seed + Splitter); } return sb.ToString(); } public void Save() { var s = Serialize(); PlayerPrefs.SetString(PpKey, s); } } public class EventBreakUIData { public string MainPanelUrl { get; set; } public string InfoPanelUrl { get; set; } public string ChainPackPanelUrl { get; set; } public string NormalPackPanelUrl { get; set; } public string RewardPanelUrl { get; set; } } public class EventBreakChainPackGenerationInfo { public List ChainList { get; set; } public DateTime ExpireTime { get; set; } public Pack[] Packs { get; set; } } // public class EventBreakChainPackData : IChainPackData // { // private const int SlotCount = 6; // private List ChainList { get; set; } // private Pack[] Packs { get; set; } // public bool IsEndGame => ChainProgress > ChainList.Count - SlotCount; // public int ChainListCount => ChainList.Count; // public int ChainProgress { get; set; } // public int EventId { get; set; } // private DateTime ExpireTime { get; set; } // public TimeSpan RemainingTime => ExpireTime - ZZTimeHelper.UtcNow(); // public bool IsChainPackDepleted => ChainProgress >= ChainListCount; // public bool DoNeedPackRedPoint // { // get // { // if (!IsChainPackDepleted && ChainProgress < ChainListCount) // return Packs[ChainProgress].IAPID == 0; // return false; // } // } // public string RedPointKey => "eventbreak.pack"; // public EventBreakChainPackData(EventBreakChainPackGenerationInfo info, int eventId, ref int chainProgress) // { // ChainList = info.ChainList; // ChainProgress = chainProgress; // EventId = eventId; // ExpireTime = info.ExpireTime; // Packs = info.Packs; // } // public Pack GetChainPackByChainProgress(int chainProgress) // { // // Debug.Log($"[EventBreak] chainProgress: {chainProgress}"); // return Packs[chainProgress]; // } // public int GetChainProgressBySlotIdx(int slotIdx) // { // int res; // if (ChainProgress > ChainList.Count - SlotCount) // res = ChainList.Count - SlotCount + slotIdx; // else // res = ChainProgress + slotIdx; // Assert.IsTrue(res < ChainList.Count, $"Progress {res} out of range: {ChainListCount}"); // // Debug.Log($"[EventBreak] slotIdx: {slotIdx}, chainProgress: {res}"); // return res; // } // // Is this needed or what? // public List GetTokenProgressRewardAfterAddingToken(int tokenAdded) // { // throw new NotImplementedException(); // } // public void UploadData() // { // EventBreakAct.DrillModel.ChainPackProgress = ChainProgress; // EventBreakAct.DrillModel.ToPlayfabData().Save(); // } // public void OnBuySuccess() // { // ChainProgress++; // UploadData(); // } // public List GetItemsByPackDropId(int dropId) // { // throw new NotImplementedException(); // } // }