using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using System.Text;
|
using UnityEngine;
|
|
public class OperationTimeHepler : Singleton<OperationTimeHepler>
|
{
|
public Dictionary<OperationType, OperationBase> operationDict = new Dictionary<OperationType, OperationBase>();
|
|
public static StringBuilder textBuilder = new StringBuilder();
|
|
public event Action<OperationType> operationTimeUpdateEvent;
|
public event Action<OperationType> operationServerCloseEvent;//特殊情况下触发
|
public event Action<OperationType, int> operationEndEvent;//活动结束时间触发 第二个参数0--过活动时间触发 1--过活动天触发
|
public event Action<OperationType, int> operationStartEvent;//活动开始时间并且满足开启条件触发 第二个参数0--活动时间触发 1--活动天触发
|
public event Action<int> dayResetEvent;//活动重置事件0-0点 1-5点
|
public event Action<OperationType> 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 10:
|
opreationType = OperationType.HeroSkinFlashSale;
|
break;
|
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<T>(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, //节日活动-任务
|
HeroSkinFlashSale = 11, //时装特卖
|
max,
|
}
|