| using System;  | 
| using System.Collections;  | 
| using System.Collections.Generic;  | 
| using UnityEngine;  | 
| //活动时间存在两种  | 
| //  1. 参与时段和领奖时段,每日不重置 如 1月1号 1点 - 1月3号 22点为活动时间,1月3号 22点 - 24点为展示时间  | 
| //                          每日重置 如 1月1号 - 1月3号 中每日 1点- 22点为活动时间, 22点 - 24点为展示时间  | 
| //  2. 每日的时间段,如每日的双倍经验活动是 18点-20点,活动整个周期为 1月1号-1月3号  | 
| public class OperationBase  | 
| {  | 
|     public OperationDate startDate;  | 
|     public OperationDate endDate;  | 
|     public List<OperationTime> times = new List<OperationTime>();   //一定是每日里的活动时间段  | 
|   | 
|     //当本服和跨服为共同活动时,每日开启时间会配置晚几分钟开放,以便于同步跨服不会造成不同服务器的时间差问题  | 
|     public int joinStartHour; //可参与活动的时间段,当每日重置时为每日的时间段;当不重置时,为活动第一天的开始时分和最后一天的结束时分  | 
|     public int joinStartMinute;  | 
|     public int joinEndHour;  | 
|     public int joinEndMinute;  | 
|   | 
|   | 
|     /// <summary>  | 
|     /// 是否每日重置  | 
|     /// </summary>  | 
|     public bool dayReset = false;  | 
|     /// <summary>  | 
|     /// 0-0点重置,1-5点重置  | 
|     /// </summary>  | 
|     public int resetType = 0;  | 
|   | 
|     public const int DayResetHour = 5;  | 
|   | 
|     public bool stepTimeNotify = false;  | 
|     public bool stepDateNotify = false;  | 
|   | 
|     public bool inTimeNotify = false;  | 
|     public bool inDateNotify = false;  | 
|   | 
|     public int inAdvanceMinute = 0;  | 
|     public bool inAdvanceNotify = false;  | 
|   | 
|     public int limitLv;  | 
|     public int ActNum; //活动编号 决定了使用哪个活动界面  | 
|   | 
|     public bool allDay  | 
|     {  | 
|         get { return times.Count <= 0; }  | 
|     }  | 
|   | 
|     public int totalDays  | 
|     {  | 
|         get { return endDate - startDate; }  | 
|     }  | 
|   | 
|     public bool IsLastDay  | 
|     {  | 
|         get  | 
|         {  | 
|             return IndexOfDays(TimeUtility.ServerNow) == totalDays;  | 
|         }  | 
|     }  | 
|   | 
|     public bool InTime(DateTime time)  | 
|     {  | 
|         if (!InDay(time))  | 
|         {  | 
|             return false;  | 
|         }  | 
|         if (allDay)  | 
|         {  | 
|             return InDayResetTime(time);  | 
|         }  | 
|         for (int i = 0; i < times.Count; i++)  | 
|         {  | 
|             if (times[i].InTime(time))  | 
|             {  | 
|                 return true;  | 
|             }  | 
|         }  | 
|         return false;  | 
|     }  | 
|   | 
|     bool InDayResetTime(DateTime time)  | 
|     {  | 
|         if (!InDay(time))  | 
|         {  | 
|             return false;  | 
|         }  | 
|         switch (resetType)  | 
|         {  | 
|             case 0:  | 
|                 {  | 
|                     return true;  | 
|                 }  | 
|             case 1:  | 
|                 {  | 
|                     var indexOfDays = IndexOfDays(time);  | 
|                     if (indexOfDays == 0)  | 
|                     {  | 
|                         return time.Hour >= DayResetHour;  | 
|                     }  | 
|                     if (indexOfDays == totalDays)  | 
|                     {  | 
|                         return time.Hour < DayResetHour;  | 
|                     }  | 
|                     if (indexOfDays < totalDays)  | 
|                     {  | 
|                         return true;  | 
|                     }  | 
|                 }  | 
|                 break;  | 
|             case 2:  | 
|                 {  | 
|                     var indexOfDays = IndexOfDays(time);  | 
|                     if (indexOfDays == 0)  | 
|                     {  | 
|                         return time.Hour >= DayResetHour;  | 
|                     }  | 
|                     return true;  | 
|                 }  | 
|   | 
|         }  | 
|         return false;  | 
|     }  | 
|   | 
|     public bool InDay(DateTime time)  | 
|     {  | 
|         OperationDate date = new OperationDate()  | 
|         {  | 
|             year = time.Year,  | 
|             month = time.Month,  | 
|             day = time.Day,  | 
|         };  | 
|         return date >= startDate && date <= endDate;  | 
|     }  | 
|   | 
|     //日期范围InDay - 时段范围 - 重置时间范围  | 
|     public bool InJoinTime(DateTime time)  | 
|     {  | 
|         if (!InDay(time))  | 
|         {  | 
|             return false;  | 
|         }  | 
|   | 
|         if (!InJoinHourMinute(time))  | 
|         {  | 
|             return false;  | 
|         }  | 
|   | 
|         if (allDay)  | 
|         {  | 
|             return InDayResetTime(time);  | 
|         }  | 
|         for (int i = 0; i < times.Count; i++)  | 
|         {  | 
|             if (times[i].InTime(time))  | 
|             {  | 
|                 return true;  | 
|             }  | 
|         }  | 
|         return false;  | 
|     }  | 
|   | 
|     //日期范围InDay - 时段范围 - 重置时间范围  | 
|     //可参与活动的时间段,当每日重置时为每日的时间段;当不重置时,为活动第一天的开始时分和最后一天的结束时分  | 
|     //属于 时段范围  的判断,在Inday之后  | 
|     public bool InJoinHourMinute(DateTime time)  | 
|     {  | 
|         OperationDate date = new OperationDate()  | 
|         {  | 
|             year = time.Year,  | 
|             month = time.Month,  | 
|             day = time.Day,  | 
|         };  | 
|         if (joinStartHour != 0 || joinStartMinute != 0 || joinEndHour != 0 || joinEndMinute != 0)  | 
|         {  | 
|             if (dayReset)  | 
|             {  | 
|                 //每日重置,判断时分  | 
|                 if (time.Hour * 60 + time.Minute >= joinStartHour * 60 + joinStartMinute &&  | 
|                     time.Hour * 60 + time.Minute < joinEndHour * 60 + joinEndMinute)  | 
|                 {  | 
|                     return true;  | 
|                 }  | 
|                 return false;  | 
|             }  | 
|             else  | 
|             {  | 
|                 //不重置,判断日期  | 
|                 if (date == startDate)  | 
|                 {  | 
|                     if (time.Hour * 60 + time.Minute >= joinStartHour * 60 + joinStartMinute)  | 
|                     {  | 
|                         return true;  | 
|                     }  | 
|                 }  | 
|                 else if (date == endDate)  | 
|                 {  | 
|                     if (time.Hour * 60 + time.Minute < joinEndHour * 60 + joinEndMinute)  | 
|                     {  | 
|                         return true;  | 
|                     }  | 
|                 }  | 
|                 else if (date > startDate && date < endDate)  | 
|                 {  | 
|                     return true;  | 
|                 }  | 
|                 return false;  | 
|             }  | 
|         }  | 
|         return true;  | 
|     }  | 
|   | 
|     //是否准备时间:活动开始到可参与活动的时间段  | 
|     public bool IsPrepareTime(DateTime time)  | 
|     {  | 
|         OperationDate date = new OperationDate()  | 
|         {  | 
|             year = time.Year,  | 
|             month = time.Month,  | 
|             day = time.Day,  | 
|         };  | 
|   | 
|         if (date == startDate)  | 
|         {  | 
|             if (time.Hour * 60 + time.Minute < joinStartHour * 60 + joinStartMinute)  | 
|             {  | 
|                 return true;  | 
|             }  | 
|         }  | 
|   | 
|         return false;  | 
|     }  | 
|   | 
|     public int IndexOfDays(DateTime time)  | 
|     {  | 
|         if (!InDay(time))  | 
|         {  | 
|             return -1;  | 
|         }  | 
|         DateTime s = new DateTime(startDate.year, startDate.month, startDate.day);  | 
|         return (time - s).Days;  | 
|     }  | 
|   | 
|     protected virtual int IndexOfTime(DateTime time, int compare = 0)  | 
|     {  | 
|         if (allDay)  | 
|         {  | 
|             if (!dayReset)  | 
|             {  | 
|                 return 0;  | 
|             }  | 
|             var index = Mathf.Max(0, IndexOfDays(time));  | 
|             switch (resetType)  | 
|             {  | 
|                 case 0:  | 
|                     return index;  | 
|                 case 1:  | 
|                 case 2:  | 
|                     return time.Hour < DayResetHour ? Mathf.Max(0, index - 1) : index;  | 
|                 default:  | 
|                     return index;  | 
|             }  | 
|         }  | 
|         else  | 
|         {  | 
|             var index = 0;  | 
|             bool equalCompare = false;  | 
|             for (int i = 0; i < times.Count; i++)  | 
|             {  | 
|                 if (times[i].InTime(time))  | 
|                 {  | 
|                     index = i;  | 
|                     break;  | 
|                 }  | 
|                 if (!equalCompare && times[i].CompareTime(TimeUtility.ServerNow) == compare)  | 
|                 {  | 
|                     index = i;  | 
|                     equalCompare = true;  | 
|                 }  | 
|             }  | 
|             return index;  | 
|         }  | 
|     }  | 
|   | 
|     public int GetSurplusTime(DateTime time)  | 
|     {  | 
|         var seconds = 0;  | 
|         if (InTime(time))  | 
|         {  | 
|             if (allDay)  | 
|             {  | 
|                 seconds += GetSurplusDayResetTime(time);  | 
|             }  | 
|             else  | 
|             {  | 
|                 for (int i = 0; i < times.Count; i++)  | 
|                 {  | 
|                     if (times[i].InTime(time))  | 
|                     {  | 
|                         seconds += times[i] - time;  | 
|                         break;  | 
|                     }  | 
|                 }  | 
|             }  | 
|         }  | 
|         return seconds;  | 
|     }  | 
|   | 
|     int GetSurplusDayResetTime(DateTime time)  | 
|     {  | 
|         switch (resetType)  | 
|         {  | 
|             case 0:  | 
|             case 2:  | 
|                 return (int)(endDate.AddSeconds(24 * 60 * 60) - time).TotalSeconds;  | 
|             case 1:  | 
|                 var endTime = new DateTime(endDate.year, endDate.month, endDate.day, DayResetHour, 0, 0);  | 
|                 return (int)(endTime - time).TotalSeconds;  | 
|         }  | 
|         return 0;  | 
|     }  | 
|   | 
|     public bool InAdvanceTime(DateTime time)  | 
|     {  | 
|         if (inAdvanceMinute <= 0)  | 
|         {  | 
|             return false;  | 
|         }  | 
|         var advanceSeconds = inAdvanceMinute * 60;  | 
|         var beforeStartSeconds = GetSecondsBeforeStart(time);  | 
|         return beforeStartSeconds > 0 && beforeStartSeconds <= advanceSeconds;  | 
|     }  | 
|   | 
|     public int GetSecondsBeforeStart(DateTime time)  | 
|     {  | 
|         var seconds = 0;  | 
|         if (InTime(time))  | 
|         {  | 
|             return 0;  | 
|         }  | 
|         if (allDay)  | 
|         {  | 
|             var startHour = 0;  | 
|             switch (resetType)  | 
|             {  | 
|                 case 0:  | 
|                     startHour = 0;  | 
|                     break;  | 
|                 case 1:  | 
|                 case 2:  | 
|                     startHour = DayResetHour;  | 
|                     break;  | 
|             }  | 
|             var startTime = new DateTime(startDate.year, startDate.month, startDate.day, startHour, 0, 0);  | 
|             seconds = Mathf.CeilToInt((float)(startTime - time).TotalSeconds);  | 
|         }  | 
|         else  | 
|         {  | 
|             var index = IndexOfDays(time);  | 
|             var date = startDate.AddDays(index);  | 
|             for (int i = 0; i < times.Count; i++)  | 
|             {  | 
|                 var startTime = new DateTime(date.year, date.month, date.day, times[i].startHour, times[i].startMinute, 0);  | 
|                 seconds = Mathf.CeilToInt((float)(startTime - time).TotalSeconds);  | 
|                 if (seconds > 0)  | 
|                 {  | 
|                     break;  | 
|                 }  | 
|             }  | 
|         }  | 
|         return seconds;  | 
|     }  | 
|   | 
|     public int GetResetSurplusTime()  | 
|     {  | 
|         var time = TimeUtility.ServerNow;  | 
|         if (!InTime(time))  | 
|         {  | 
|             return 0;  | 
|         }  | 
|         var seconds = 0;  | 
|         if (allDay)  | 
|         {  | 
|             if (!dayReset)  | 
|             {  | 
|                 return GetSurplusTime(time);  | 
|             }  | 
|             switch (resetType)  | 
|             {  | 
|                 case 0:  | 
|                     {  | 
|                         DateTime endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                                 TimeUtility.Day, 0, 0, 0);  | 
|                         endOperationTime = endOperationTime.AddDays(1);  | 
|                         seconds = (int)(endOperationTime - TimeUtility.ServerNow).TotalSeconds;  | 
|                     }  | 
|                     break;  | 
|                 case 1:  | 
|                     {  | 
|                         DateTime endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                                 TimeUtility.Day, DayResetHour, 0, 0);  | 
|                         if (time.Hour >= DayResetHour)  | 
|                         {  | 
|                             endOperationTime = endOperationTime.AddDays(1);  | 
|                         }  | 
|                         seconds = (int)(endOperationTime - TimeUtility.ServerNow).TotalSeconds;  | 
|                     }  | 
|                     break;  | 
|                 case 2:  | 
|                     {  | 
|                         var indexOfDays = IndexOfDays(time);  | 
|                         DateTime endOperationTime = DateTime.Now;  | 
|                         if (indexOfDays == totalDays)  | 
|                         {  | 
|                             if (time.Hour >= DayResetHour)  | 
|                             {  | 
|                                 endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                                         TimeUtility.Day, 0, 0, 0);  | 
|                                 endOperationTime = endOperationTime.AddDays(1);  | 
|                             }  | 
|                             else  | 
|                             {  | 
|                                 endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                                         TimeUtility.Day, DayResetHour, 0, 0);  | 
|                             }  | 
|                         }  | 
|                         else  | 
|                         {  | 
|                             endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                                     TimeUtility.Day, DayResetHour, 0, 0);  | 
|                             if (time.Hour >= DayResetHour)  | 
|                             {  | 
|                                 endOperationTime = endOperationTime.AddDays(1);  | 
|                             }  | 
|                         }  | 
|                         seconds = (int)(endOperationTime - TimeUtility.ServerNow).TotalSeconds;  | 
|                     }  | 
|                     break;  | 
|             }  | 
|         }  | 
|         else  | 
|         {  | 
|             for (int i = 0; i < times.Count; i++)  | 
|             {  | 
|                 if (times[i].InTime(time))  | 
|                 {  | 
|                     DateTime endOperationTime = new DateTime(TimeUtility.Year, TimeUtility.Month,  | 
|                             TimeUtility.Day, times[i].endHour, times[i].endMinute, 0);  | 
|                     seconds = (int)(endOperationTime - TimeUtility.ServerNow).TotalSeconds;  | 
|                     break;  | 
|                 }  | 
|             }  | 
|         }  | 
|         return seconds;  | 
|     }  | 
|   | 
|     public virtual string ToDisplayTime()  | 
|     {  | 
|         return string.Empty;  | 
|     }  | 
|   | 
|     public virtual void Reset()  | 
|     {  | 
|         stepTimeNotify = false;  | 
|         stepDateNotify = false;  | 
|         inTimeNotify = false;  | 
|         inDateNotify = false;  | 
|         dayReset = false;  | 
|         resetType = 0;  | 
|         limitLv = 0;  | 
|         inAdvanceNotify = false;  | 
|         inAdvanceMinute = 0;  | 
|         ActNum = 0;  | 
|         times.Clear();  | 
|     }  | 
|   | 
|     public virtual bool SatisfyOpenCondition()  | 
|     {  | 
|         return PlayerDatas.Instance.baseData.LV >= limitLv;  | 
|     }  | 
|   | 
|     public void ParseJoinTime(string joinStart, string joinEnd)  | 
|     {  | 
|         joinStart = UIHelper.ServerStringTrim(joinStart);  | 
|         joinEnd = UIHelper.ServerStringTrim(joinEnd);  | 
|   | 
|         if (string.IsNullOrEmpty(joinStart) || string.IsNullOrEmpty(joinEnd))  | 
|             return;  | 
|         var joinStarts = joinStart.Split(':');  | 
|         var joinEnds = joinEnd.Split(':');  | 
|         joinStartHour = int.Parse(joinStarts[0]);  | 
|         joinStartMinute = int.Parse(joinStarts[1]);  | 
|         joinEndHour = int.Parse(joinEnds[0]);  | 
|         joinEndMinute = int.Parse(joinEnds[1]);  | 
|     }  | 
| }  | 
|   | 
|   | 
| //活动排行榜奖励 有积分限制和额外奖励  | 
| public struct ActBillboardAwards  | 
| {  | 
|     public int needScore;        // 上榜所需积分  | 
|     public List<Item> awardItemList;        // 奖励物品列表  | 
|     public int needScoreEx;        // 额外奖励所需积分  | 
|     public List<Item> awardItemListEx;     // 额外奖励列表  | 
| }  | 
|   |