using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; namespace Snxxz.UI { public class OperationTimeHepler : Singleton { private Dictionary operationDict = new Dictionary(); public static StringBuilder textBuilder = new StringBuilder(); public event Action operationTimeUpdateEvent; public event Action operationServerCloseEvent;//特殊情况下触发 public event Action operationEndEvent;//活动结束时间触发 第二个参数0--过活动时间触发 1--过活动天触发 public event Action operationStartEvent;//活动开始时间并且满足开启条件触发 第二个参数0--活动时间触发 1--活动天触发 public event Action dayResetEvent;//活动重置事件0-0点 1-5点 public event Action operationAdvanceEvent;//活动在提前开启的时间内 public OperationTimeHepler() { DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerDataInitializeEvent; GlobalTimeEvent.Instance.secondEvent += SecondEvent; TimeMgr.Instance.OnHourEvent += HourEvent; } private void BeforePlayerDataInitializeEvent() { operationDict.Clear(); } private void SecondEvent() { if (!(StageManager.Instance.CurrentStage is DungeonStage)) { return; } for (int i = 0; i < (int)Operation.max; i++) { if (operationDict.ContainsKey((Operation)i)) { var operation = operationDict[(Operation)i]; if (!operation.inDateNotify && operation.SatisfyOpenCondition() && operation.InDay(TimeUtility.ServerNow)) { operation.inDateNotify = true; operation.stepDateNotify = false; DebugEx.LogFormat("{0} 活动天开始", (Operation)i); if (operationStartEvent != null) { operationStartEvent((Operation)i, 1); } } else if (!operation.stepDateNotify && !operation.InDay(TimeUtility.ServerNow)) { operation.inDateNotify = false; operation.stepDateNotify = true; DebugEx.LogFormat("{0} 活动天结束", (Operation)i); if (operationEndEvent != null) { operationEndEvent((Operation)i, 1); } } if (!operation.inTimeNotify && operation.SatisfyOpenCondition() && operation.InTime(TimeUtility.ServerNow)) { operation.inTimeNotify = true; operation.stepTimeNotify = false; DebugEx.LogFormat("{0} 活动时间开始", (Operation)i); if (operationStartEvent != null) { operationStartEvent((Operation)i, 0); } } else if (!operation.stepTimeNotify && !operation.InTime(TimeUtility.ServerNow)) { operation.inTimeNotify = false; operation.stepTimeNotify = true; operation.inAdvanceNotify = false; DebugEx.LogFormat("{0} 活动时间结束", (Operation)i); if (operationEndEvent != null) { operationEndEvent((Operation)i, 0); } } if (!operation.inAdvanceNotify && operation.SatisfyOpenCondition() && operation.InAdvanceTime(TimeUtility.ServerNow)) { operation.inAdvanceNotify = true; DebugEx.LogFormat("{0} 活动提前开启", (Operation)i); if (operationAdvanceEvent != null) { operationAdvanceEvent((Operation)i); } } } } } private void HourEvent() { if (!(StageManager.Instance.CurrentStage is DungeonStage)) { return; } if (TimeUtility.Hour == 0 && dayResetEvent != null) { dayResetEvent(0); } if (TimeUtility.Hour == 5 && dayResetEvent != null) { dayResetEvent(1); } } /// /// 多倍经验 /// /// public void UpdateMultipleExp(HAC06_tagGCMultiExpRateInfo package) { OperationBase operation = null; operationDict.TryGetValue(Operation.MultipleExp, out operation); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.MultipleExp); } else { if (operation == null) { operation = new OperationMultiExp(); operationDict.Add(Operation.MultipleExp, operation); } operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.limitLv = package.LimitLV; (operation as OperationMultiExp).multiple = (int)package.AddExpRate + 10000; for (int i = 0; i < package.ActivityTimeCount; i++) { operation.times.Add(ParseOperationTime(package.ActivityTime[i].StartTime, package.ActivityTime[i].EndtTime)); } if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.MultipleExp); } } } /// /// 消费返利 /// /// public void UpdateConsumeRebate(HAA09_tagMCCostRebateInfo package) { OperationBase operationBase = null; operationDict.TryGetValue(Operation.ConsumeRebate, out operationBase); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.ConsumeRebate); } else { if (operationBase == null) { operationBase = new OperationConsumeRebate(); operationDict.Add(Operation.ConsumeRebate, operationBase); } OperationConsumeRebate operation = operationBase as OperationConsumeRebate; operation.Reset(); operation.limitLv = package.LimitLV; operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.dayReset = package.IsDayReset == 1; operation.ParseRebate(package); if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.ConsumeRebate); } } } /// /// 限时特惠 /// /// public void UpdateFlashSale(HAA11_tagMCSpringSaleInfo package) { OperationBase operationBase = null; operationDict.TryGetValue(Operation.FlashSale, out operationBase); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.FlashSale); } else { if (operationBase == null) { operationBase = new OperationFlashSale(); operationDict.Add(Operation.FlashSale, operationBase); } OperationFlashSale operation = operationBase as OperationFlashSale; operation.Reset(); operation.limitLv = package.LimitLV; operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.dayReset = package.IsDayReset == 1; operation.inAdvanceMinute = package.AdvanceMinutes; for (int i = 0; i < package.ActivityTimeCount; i++) { operation.times.Add(ParseOperationTime(package.ActivityTime[i].StartTime, package.ActivityTime[i].EndtTime)); } operation.ParsePackage(package); if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.FlashSale); } } } /// /// 限时礼包 /// /// public void UpdateGiftPackage(HAA12_tagMCFlashGiftbagInfo package) { OperationBase operationBase = null; operationDict.TryGetValue(Operation.GiftPackage, out operationBase); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.GiftPackage); } else { if (operationBase == null) { operationBase = new GiftPackageClass(); operationDict.Add(Operation.GiftPackage, operationBase); } GiftPackageClass operation = operationBase as GiftPackageClass; operation.Reset(); operation.limitLv = package.LimitLV; operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.dayReset = package.IsDayReset == 1; operation.inAdvanceMinute = package.AdvanceMinutes; for (int i = 0; i < package.ActivityTimeCount; i++) { operation.times.Add(ParseOperationTime(package.ActivityTime[i].StartTime, package.ActivityTime[i].EndtTime)); } operation.ParsePackage(package); if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.GiftPackage); } } } public void UpdateBossReborn(HAB04_tagMCBossRebornInfo package) { if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.BossReborn); } else { OperationBase operationBase = null; operationDict.TryGetValue(Operation.BossReborn, out operationBase); if (operationBase == null) { operationDict[Operation.BossReborn] = operationBase = new OperationBossReborn(); } operationBase.Reset(); operationBase.limitLv = package.LimitLV; operationBase.startDate = ParseOperationDate(package.StartDate); operationBase.endDate = ParseOperationDate(package.EndtDate); operationBase.resetType = package.ResetType; ModelCenter.Instance.GetModel().UpdateTaskBaseInfos(package.TaskInfo); } } /// /// 仙界盛典 /// /// public void RefreshFairyCeremonyInfo(HAC09_tagGCFairyCeremonyInfo package) { OperationBase operation = null; operationDict.TryGetValue(Operation.FairyCeremony, out operation); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.FairyCeremony); } else { if (operation == null) { operation = new OperationBase(); operationDict.Add(Operation.FairyCeremony, operation); } operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.limitLv = package.LimitLV; if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.FairyCeremony); } } } /// /// N倍修行点 /// /// public void RefreshNTimesPractice(HAC0A_tagGCMultiRealmPointInfo package) { OperationBase operation = null; operationDict.TryGetValue(Operation.MultipRealmPoint, out operation); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(Operation.MultipRealmPoint); } else { if (operation == null) { operation = new OperationMultipleRealmPoint(); operationDict.Add(Operation.MultipRealmPoint, operation); } operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.limitLv = package.LimitLV; (operation as OperationMultipleRealmPoint).multiplePractice = package.Multiple; if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(Operation.MultipRealmPoint); } } } void ForceStopOperation(Operation operationType) { if (operationDict.ContainsKey(operationType)) { operationDict.Remove(operationType); } if (operationServerCloseEvent != null) { operationServerCloseEvent(operationType); } if (operationEndEvent != null) { operationEndEvent(operationType, 0); operationEndEvent(operationType, 1); } } public bool TryGetOperationTime(Operation type, out OperationBase operation) { return operationDict.TryGetValue(type, out operation); } public bool InOperationTime(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InTime(TimeUtility.ServerNow); } return false; } public bool InOperationDay(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InDay(TimeUtility.ServerNow); } return false; } public int GetOperationSurplusTime(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.GetSurplusTime(TimeUtility.ServerNow); } return 0; } public bool InOperationAdvance(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InAdvanceTime(TimeUtility.ServerNow); } return false; } public int GetOperationSecondsBeforeStart(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.GetSecondsBeforeStart(TimeUtility.ServerNow); } return 0; } public bool SatisfyOpenCondition(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.SatisfyOpenCondition() && InOperationTime(type); } return false; } public bool SatisfyAdvanceCondition(Operation type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.SatisfyOpenCondition() && InOperationAdvance(type); } return false; } public void ProcessConditionError(Operation type) { if (SatisfyOpenCondition(type)) { return; } OperationBase operation; if (TryGetOperationTime(type, out operation)) { if (!InOperationTime(type)) { SysNotifyMgr.Instance.ShowTip("InOperationTimeError"); } else if (!operation.SatisfyOpenCondition()) { SysNotifyMgr.Instance.ShowTip(StringUtility.Contact("OperationLevelLimit_", type), operation.limitLv); } } else { SysNotifyMgr.Instance.ShowTip("InOperationTimeError"); } } OperationDate ParseOperationDate(string date) { string[] dateArray = date.Split('-'); if (dateArray != null && dateArray.Length == 3) { return new OperationDate() { year = int.Parse(dateArray[0].Trim()), month = int.Parse(dateArray[1].Trim()), day = int.Parse(dateArray[2].Trim()) }; } else if (dateArray != null && dateArray.Length == 1) { var time = TimeUtility.openServerTime; if (time.Equals(default(DateTime))) { DebugEx.Log("服务期开服时间下发顺序有问题"); } var days = 0; int.TryParse(date, out days); days = Mathf.Max(1, days); time = time.AddDays(days - 1); return new OperationDate() { year = time.Year, month = time.Month, day = time.Day, }; } return default(OperationDate); } OperationTime ParseOperationTime(string startTime, string endTime) { var startTimeArray = startTime.Split(':'); var endTimeArray = endTime.Split(':'); if (startTimeArray != null && startTimeArray.Length == 2 && endTimeArray != null && endTimeArray.Length == 2) { return new OperationTime() { startHour = int.Parse(startTimeArray[0].Trim()), startMinute = int.Parse(startTimeArray[1].Trim()), endHour = int.Parse(endTimeArray[0].Trim()), endMinute = int.Parse(endTimeArray[1].Trim()), }; } return default(OperationTime); } } public struct OperationDate { public int year; public int month; public int day; public static bool operator ==(OperationDate x, OperationDate y) { return x.year == y.year && x.month == y.month && x.day == y.day; } public static bool operator !=(OperationDate x, OperationDate y) { return !(x == y); } public static bool operator >(OperationDate x, OperationDate y) { if (x.year > y.year) { return true; } if (x.year == y.year) { if (x.month > y.month) { return true; } if (x.month == y.month) { return x.day > y.day; } } return false; } public static bool operator <(OperationDate x, OperationDate y) { return !(x > y) && x != y; } public static bool operator >=(OperationDate x, OperationDate y) { return x > y || x == y; } public static bool operator <=(OperationDate x, OperationDate y) { return x < y || x == y; } public DateTime AddSeconds(int _seconds) { DateTime d = new DateTime(year, month, day); return d.AddTicks(_seconds * TimeSpan.TicksPerSecond); } public OperationDate AddDays(int _days) { DateTime d = new DateTime(year, month, day); d = d.AddDays(_days); return new OperationDate() { year = d.Year, month = d.Month, day = d.Day, }; } public string ToDisplay(bool showYear = true) { var yearString = StringUtility.Contact(year, Language.Get("Year")); return StringUtility.Contact(showYear ? yearString : string.Empty, month, Language.Get("Month"), day, Language.Get("Day")); } public static int operator -(OperationDate x, OperationDate y) { DateTime _x = new DateTime(x.year, x.month, x.day); DateTime _y = new DateTime(y.year, y.month, y.day); return (int)(_x - _y).TotalDays; } } public struct OperationTime { public int startHour; public int startMinute; public int endHour; public int endMinute; public bool InTime(DateTime time) { return CompareTime(time) == 0; } public int CompareTime(DateTime time) { if (time.Hour < startHour || (time.Hour == startHour && time.Minute < startMinute)) { return -1; } if (time.Hour > endHour || (time.Hour == endHour && time.Minute >= endMinute)) { return 1; } return 0; } public override string ToString() { return StringUtility.Contact(startHour.ToString("D2"), ":", startMinute.ToString("D2"), "-", endHour.ToString("D2"), ":", endMinute.ToString("D2")); } public static int operator -(OperationTime x, DateTime y) { DateTime d = new DateTime(y.Year, y.Month, y.Day, x.endHour, x.endMinute, 0); return Mathf.Max(0, (int)(d - y).TotalSeconds); } } public enum Operation { MultipleExp, ConsumeRebate, FlashSale, BossReborn, GiftPackage, FairyCeremony, //仙界盛典 MultipRealmPoint, //N倍修行点 max, } }