using System; using System.Collections; using System.Collections.Generic; using System.Text; using UnityEngine; public class OperationTimeHepler : Singleton { public 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; DTC0102_tagCDBPlayer.beforePlayerDataInitializeEvent += BeforePlayerDataInitializeEvent; GlobalTimeEvent.Instance.secondEvent += SecondEvent; TimeMgr.Instance.OnHourEvent += HourEvent; } private void BeforePlayerDataInitializeEvent() { operationDict.Clear(); } private void SecondEvent() { if (!ConfigManager.Instance.isLoadFinished) return; if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin) { return; } for (int i = 0; i < (int)OperationType.max; i++) { if (operationDict.ContainsKey((OperationType)i)) { var operation = operationDict[(OperationType)i]; if (!operation.inDateNotify && operation.SatisfyOpenCondition() && operation.InDay(TimeUtility.ServerNow)) { operation.inDateNotify = true; operation.stepDateNotify = false; Debug.LogFormat("{0} 活动天开始", (OperationType)i); if (operationStartEvent != null) { operationStartEvent((OperationType)i, 1); } } else if (!operation.stepDateNotify && !operation.InDay(TimeUtility.ServerNow)) { operation.inDateNotify = false; operation.stepDateNotify = true; Debug.LogFormat("{0} 活动天结束", (OperationType)i); if (operationEndEvent != null) { operationEndEvent((OperationType)i, 1); } } if (!operation.inTimeNotify && operation.SatisfyOpenCondition() && operation.InTime(TimeUtility.ServerNow)) { operation.inTimeNotify = true; operation.stepTimeNotify = false; Debug.LogFormat("{0} 活动时间开始", (OperationType)i); if (operationStartEvent != null) { operationStartEvent((OperationType)i, 0); } } else if (!operation.stepTimeNotify && !operation.InTime(TimeUtility.ServerNow)) { operation.inTimeNotify = false; operation.stepTimeNotify = true; operation.inAdvanceNotify = false; Debug.LogFormat("{0} 活动时间结束", (OperationType)i); if (operationEndEvent != null) { operationEndEvent((OperationType)i, 0); } } if (!operation.inAdvanceNotify && operation.SatisfyOpenCondition() && operation.InAdvanceTime(TimeUtility.ServerNow)) { operation.inAdvanceNotify = true; Debug.LogFormat("{0} 活动提前开启", (OperationType)i); if (operationAdvanceEvent != null) { operationAdvanceEvent((OperationType)i); } } } } } private void HourEvent() { if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin) { return; } if (TimeUtility.Hour == 0 && dayResetEvent != null) { dayResetEvent(0); } if (TimeUtility.Hour == 5 && dayResetEvent != null) { dayResetEvent(1); } } public void UpdateActLunhuidianInfo(HAA88_tagMCActLunhuidianInfo package) { OperationBase operationBase = null; operationDict.TryGetValue(OperationType.TimeRush, out operationBase); if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(OperationType.TimeRush); } else { if (operationBase == null) { operationBase = new OperationCycleHall(); operationDict.Add(OperationType.TimeRush, operationBase); } OperationCycleHall operation = operationBase as OperationCycleHall; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.resetType = package.ResetType; operation.limitLv = package.LimitLV; operation.ParseCycleHallInfo(package); if (operationTimeUpdateEvent != null) { operationTimeUpdateEvent(OperationType.TimeRush); } } } public void UpdateActHeroAppearInfo(HAA21_tagSCActHeroAppearInfo package) { var opreationType = OperationType.HeroDebut; switch (package.ActNum) { case 10: opreationType = OperationType.HeroDebut; break; case 11: opreationType = OperationType.HeroReturn; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationHeroAppearInfo(); operationDict.Add(opreationType, operationBase); } OperationHeroAppearInfo operation = operationBase as OperationHeroAppearInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActType = package.ActType; operation.CfgID = package.CfgID; operationTimeUpdateEvent?.Invoke(opreationType); } public void UpdateActTotalRechargeInfo(HAA1D_tagSCActTotalRechargeInfo package) { var opreationType = OperationType.TotalRecharge; switch (package.ActNum) { case 10: opreationType = OperationType.TotalRecharge; break; case 30: opreationType = OperationType.FestivalActivity_RechargeTotal; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationTotalRechargeInfo(); operationDict.Add(opreationType, operationBase); } OperationTotalRechargeInfo operation = operationBase as OperationTotalRechargeInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActNum = package.ActNum; operation.CfgID = package.CfgID; var config = ActTotalRechargeConfig.Get(package.CfgID); if (config == null) { SysNotifyMgr.Instance.ShowTip("LoadConfigErr"); return; } operation.dayReset = config.IsDayReset == 1; operationTimeUpdateEvent?.Invoke(opreationType); } public void UpdateActTotDayRechargeInfo(HAA1B_tagSCActTotDayRechargeInfo package) { var opreationType = OperationType.TotDayRecharge; switch (package.ActNum) { case 10: opreationType = OperationType.TotDayRecharge; break; case 30: opreationType = OperationType.FestivalActivity_RechargeTotDay; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationTotDayRechargeInfo(); operationDict.Add(opreationType, operationBase); } OperationTotDayRechargeInfo operation = operationBase as OperationTotDayRechargeInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActNum = package.ActNum; operation.CfgID = package.CfgID; if (ActTotDayRechargeConfig.Get(package.CfgID) == null) { SysNotifyMgr.Instance.ShowTip("LoadConfigErr"); return; } operationTimeUpdateEvent?.Invoke(opreationType); } public void UpdateFlashSaleActivityInfo(HAA10_tagSCActSpecialSaleInfo package) { var opreationType = OperationType.FestivalActivity; switch (package.ActNum) { case 30: opreationType = OperationType.FestivalActivity; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationFlashSaleActivityInfo(); operationDict.Add(opreationType, operationBase); } OperationFlashSaleActivityInfo operation = operationBase as OperationFlashSaleActivityInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActNum = package.ActNum; operation.CfgID = package.CfgID; if (ActSpecialSaleConfig.Get(package.CfgID) == null) { SysNotifyMgr.Instance.ShowTip("LoadConfigErr"); return; } operationTimeUpdateEvent?.Invoke(opreationType); } public void UpdateCheckInActivityInfo(HAA23_tagSCActSignInfo package) { var opreationType = OperationType.FestivalActivity_CheckIn; switch (package.ActNum) { case 30: opreationType = OperationType.FestivalActivity_CheckIn; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationCheckInActivityInfo(); operationDict.Add(opreationType, operationBase); } OperationCheckInActivityInfo operation = operationBase as OperationCheckInActivityInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActType = package.ActNum; operation.CfgID = package.CfgID; if (ActSignConfig.Get(package.CfgID) == null) { SysNotifyMgr.Instance.ShowTip("LoadConfigErr"); return; } operationTimeUpdateEvent?.Invoke(opreationType); } public void UpdateMissionActivityInfo(HAA71_tagSCActTaskInfo package) { var opreationType = OperationType.FestivalActivity_Mission; switch (package.ActNum) { case 30: opreationType = OperationType.FestivalActivity_Mission; break; default: return; } if (string.IsNullOrEmpty(package.StartDate) || string.IsNullOrEmpty(package.EndtDate)) { ForceStopOperation(opreationType); return; } if (!operationDict.TryGetValue(opreationType, out OperationBase operationBase)) { operationBase = new OperationMissionActivityInfo(); operationDict.Add(opreationType, operationBase); } OperationMissionActivityInfo operation = operationBase as OperationMissionActivityInfo; operation.Reset(); operation.startDate = ParseOperationDate(package.StartDate); operation.endDate = ParseOperationDate(package.EndtDate); operation.ActType = package.ActNum; operation.CfgID = package.CfgID; var config = ActTaskConfig.Get(package.CfgID); if (config == null) { SysNotifyMgr.Instance.ShowTip("LoadConfigErr"); return; } operation.dayReset = config.IsDayReset == 1; operationTimeUpdateEvent?.Invoke(opreationType); } public void ForceStopOperation(OperationType 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(OperationType type, out OperationBase operation) { return operationDict.TryGetValue(type, out operation); } public bool TryGetOperation(OperationType type, out T operation) where T : OperationBase { operation = null; if (operationDict.ContainsKey(type)) { operation = operationDict[type] as T; return operation is T; } return false; } public bool InOperationTime(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InTime(TimeUtility.ServerNow); } return false; } public bool InOperationTime(OperationType type, DateTime time) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InTime(time); } return false; } public bool InOperationJoinTime(OperationType type, DateTime time) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InJoinTime(time); } return false; } public bool InOperationDay(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InDay(TimeUtility.ServerNow); } return false; } public int GetOperationSurplusTime(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.GetSurplusTime(TimeUtility.ServerNow); } return 0; } public bool InOperationAdvance(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.InAdvanceTime(TimeUtility.ServerNow); } return false; } public int GetOperationSecondsBeforeStart(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.GetSecondsBeforeStart(TimeUtility.ServerNow); } return 0; } public bool SatisfyOpenCondition(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.SatisfyOpenCondition() && InOperationTime(type); } return false; } public bool SatisfyOpenCondition(OperationType type, DateTime time) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.SatisfyOpenCondition() && InOperationTime(type, time); } return false; } //活动开启中,有参与进行时间段 public bool SatisfyJoinCondition(OperationType type, DateTime time) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return InOperationJoinTime(type, time); } return false; } public bool IsPrepareTime(OperationType type, DateTime time) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.IsPrepareTime(time); } return false; } public bool SatisfyAdvanceCondition(OperationType type) { OperationBase operation; if (TryGetOperationTime(type, out operation)) { return operation.SatisfyOpenCondition() && InOperationAdvance(type); } return false; } public void ProcessConditionError(OperationType 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.Concat("OperationLevelLimit_", type.ToString()), operation.limitLv); } } else { SysNotifyMgr.Instance.ShowTip("InOperationTimeError"); } } public 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))) // { // Debug.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); } private 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.AddTicks(_days * TimeSpan.TicksPerDay); return new OperationDate() { year = d.Year, month = d.Month, day = d.Day, }; } public string ToDisplay(bool showYear = true) { if (showYear) { return $"{year}/{month}/{day}"; } return $"{month}/{day}"; //var yearString = StringUtility.Concat(year, Language.Get("Year")); //return StringUtility.Concat(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.Concat(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 OperationType { TimeRush = 1, //日期型活动 - 轮回殿 HeroDebut = 2, //日期型活动 - 武将登场 HeroReturn = 3, //日期型活动 - 武将返场 TotalRecharge = 4,//累充活动 TotDayRecharge = 5, //累充天活动 FestivalActivity = 6, //节日活动 FestivalActivity_RechargeTotDay = 7, //节日活动-累天充值 FestivalActivity_RechargeTotal = 8, //节日活动-累充值 FestivalActivity_CheckIn = 9, //节日活动-签到 FestivalActivity_Mission = 10, //节日活动-任务 max, }