687 lines
14 KiB
C#
687 lines
14 KiB
C#
// ***********************************************************************
|
|
// Assembly : Game
|
|
// Author : Kimch
|
|
// Created : 2021-04-29
|
|
// Description :
|
|
// Last Modified By :
|
|
// Last Modified On :
|
|
// ***********************************************************************
|
|
// <copyright file= "TimeProxy" company="Kunpo"></copyright>
|
|
// <summary></summary>
|
|
// ***********************************************************************
|
|
|
|
using CodeStage.AntiCheat.ObscuredTypes;
|
|
using F;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace G
|
|
{
|
|
/// <summary>
|
|
/// 次数
|
|
/// </summary>
|
|
partial class TimeProxy : F.GameProxy
|
|
{
|
|
/// <summary>
|
|
/// 次数信息
|
|
/// </summary>
|
|
class TimeInfo
|
|
{
|
|
public readonly ItemTime item;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
private ObscuredVector2Int _data;
|
|
private readonly int _intervalSeconds;
|
|
private readonly int _timeLimit;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int interval => _intervalSeconds;
|
|
/// <summary>
|
|
/// 极限
|
|
/// </summary>
|
|
public int limit => _timeLimit;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int cur
|
|
{
|
|
get => _data.x;
|
|
set => _data.x = Math.Max(0, value);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int max
|
|
{
|
|
get => _data.y;
|
|
set
|
|
{
|
|
if (value > 0)
|
|
_data.y = value;
|
|
else
|
|
_data.y = item.maxCount;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int free
|
|
{
|
|
get => item.freeCount;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 余量
|
|
/// </summary>
|
|
public int remain
|
|
{
|
|
get => Math.Max(0, _data.y - _data.x);
|
|
set => _data.x = Math.Max(0, _data.y - value);
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public TimeInfo2 simpleInfo2
|
|
{
|
|
get => new TimeInfo2 { remain = remain, max = max };
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public TimeInfo3 simpleInfo3
|
|
{
|
|
get => new TimeInfo3 { remain = remain, max = max, free = freeRemain };
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int freeRemain
|
|
{
|
|
get => item.freeCount - _data.x;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 恢复
|
|
/// </summary>
|
|
public bool recoverKey
|
|
{
|
|
get { return Launch.Timestamp - _data.x > 0; }
|
|
set { _data.x = Launch.Timestamp + _intervalSeconds; }
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int recoverTimestamp
|
|
{
|
|
get => _data.x;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int recoverSeconds
|
|
{
|
|
get => recoverTimestamp - Launch.Timestamp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得恢复的次数
|
|
/// </summary>
|
|
public int recharge
|
|
{
|
|
get
|
|
{
|
|
int maxTime = this.max;
|
|
int curTime = this.cur;
|
|
if (curTime >= maxTime && curTime <= _timeLimit)
|
|
{
|
|
return curTime;
|
|
}
|
|
else
|
|
{
|
|
// 时间差值
|
|
float secondTime = (curTime - Launch.Timestamp) / (float)_intervalSeconds;
|
|
return Mathf.Clamp((int)(maxTime - secondTime), 0, maxTime);
|
|
}
|
|
}
|
|
set
|
|
{
|
|
int maxTime = this.max;
|
|
if (value >= maxTime)
|
|
{
|
|
this.cur = Mathf.Min(_timeLimit, value);
|
|
return;
|
|
}
|
|
|
|
if (value >= 0)
|
|
{
|
|
var curTime = this.cur;
|
|
int second = 0;
|
|
if (curTime > _timeLimit)
|
|
{
|
|
second = Mathf.Max(0, curTime - Launch.Timestamp);
|
|
second %= _intervalSeconds;
|
|
if (second != 0)
|
|
second = _intervalSeconds - second;
|
|
}
|
|
this.cur = Launch.Timestamp + Mathf.Max(0, (maxTime - value) * _intervalSeconds - second);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 充能时间
|
|
/// </summary>
|
|
public int rechargeTimestamp
|
|
{
|
|
get
|
|
{
|
|
int result = _data.x;
|
|
if (result >= _data.y && result <= _timeLimit)
|
|
return 0;
|
|
return result;
|
|
}
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public int rechargeSeconds
|
|
{
|
|
get => rechargeTimestamp - Launch.Timestamp;
|
|
}
|
|
/// <summary>
|
|
/// 充能信息
|
|
/// </summary>
|
|
public string rechargeText
|
|
{
|
|
get
|
|
{
|
|
int second = rechargeSeconds;
|
|
if (second > 0)
|
|
{
|
|
int temp = second % _intervalSeconds;
|
|
return $"{temp / 60}:{(temp % 60).ToString("00")}";
|
|
}
|
|
return "";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="timeItem"></param>
|
|
public TimeInfo(ItemTime timeItem)
|
|
{
|
|
this.item = timeItem;
|
|
|
|
int maxCount = item.maxCount;
|
|
_data = new ObscuredVector2Int(0, maxCount);
|
|
|
|
if (item.type == 4)//恢复
|
|
{
|
|
if (item.typeArgs != null && item.typeArgs.Length > 0)
|
|
{
|
|
_intervalSeconds = item.typeArgs[0];
|
|
_timeLimit = 1;
|
|
}
|
|
}
|
|
else if (item.type == 5)//充能
|
|
{
|
|
if (item.typeArgs != null && item.typeArgs.Length > 1)
|
|
{
|
|
_intervalSeconds = item.typeArgs[0];
|
|
_timeLimit = Mathf.Max(1, maxCount, item.typeArgs[1]);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int GetStatus()
|
|
{
|
|
return _data.x;
|
|
}
|
|
|
|
public void SetStatus(int status)
|
|
{
|
|
_data.x = status;
|
|
}
|
|
}
|
|
|
|
public struct TimeInfo2
|
|
{
|
|
public int remain;
|
|
public int max;
|
|
}
|
|
|
|
public struct TimeInfo3
|
|
{
|
|
public int remain;
|
|
public int max;
|
|
public int free;
|
|
}
|
|
|
|
#region FIELD
|
|
|
|
/// <summary>
|
|
/// 数据结构
|
|
/// </summary>
|
|
Dictionary<int, TimeInfo> _timeInfos;
|
|
/// <summary>
|
|
/// 存日期
|
|
/// </summary>
|
|
DateTime _saveDate;
|
|
|
|
#endregion
|
|
|
|
#region METHOD
|
|
|
|
/// <summary>
|
|
/// 取得bool值
|
|
/// </summary>
|
|
/// <param name="id">0:每日任务,1:每日活动,2:7日签到,3:每日免费加速,4 每日离线奖励</param>
|
|
/// <returns></returns>
|
|
public bool GetTimeKey(int id)
|
|
{
|
|
CheckTimes(true);
|
|
return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < 1;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool TryTimeKey(int id)
|
|
{
|
|
CheckTimes(true);
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < 1)
|
|
{
|
|
timeInfo.cur = 1;
|
|
SaveTimes();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得剩余次数
|
|
/// </summary>
|
|
/// <param name="id">0 每日免费宝箱次数 ,1 每日免费体力,2每日免费金币 ,3 碎片,4宠物,5无尽</param>
|
|
/// <returns></returns>
|
|
public int GetTimes(int id)
|
|
{
|
|
CheckTimes(true);
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.remain;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得剩余次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public TimeInfo2 GetTimeInfo2(int id)
|
|
{
|
|
CheckTimes(true);
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.simpleInfo2;
|
|
return default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得剩余次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public TimeInfo3 GetTimeInfo3(int id)
|
|
{
|
|
CheckTimes(true);
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.simpleInfo3;
|
|
return default;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获得
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="value"></param>
|
|
public void SetTimes(int id, int value)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
{
|
|
if (timeInfo.remain != value)
|
|
{
|
|
timeInfo.remain = Mathf.Max(0, value);
|
|
SaveTimes();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 0 shop ,1体力,2金币,3 碎片,4宠物,5无尽
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public int GetMaxTimes(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.max;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="index"></param>
|
|
/// <param name="value"></param>
|
|
public void SetMaxTimes(int id, int value, bool increment = false)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
timeInfo.max = value;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="value"></param>
|
|
/// <param name="increment"></param>
|
|
public void AddMaxTimes(int id, int value, bool increment = false)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
timeInfo.max += value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 重置所有次数
|
|
/// </summary>
|
|
public void ResetAllMaxTimes()
|
|
{
|
|
foreach (var timeInfo in _timeInfos)
|
|
{
|
|
timeInfo.Value.max = 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CheckTimes(int id)
|
|
{
|
|
return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < timeInfo.max;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 免费次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CheckFreeTimes(int id)
|
|
{
|
|
return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < timeInfo.free;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 免费次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public int GetFreeTimes(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.free - timeInfo.cur;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CostTimes(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
{
|
|
int curTimes = timeInfo.cur;
|
|
if (curTimes < timeInfo.max)
|
|
{
|
|
timeInfo.cur = curTimes + 1;
|
|
SaveTimes();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CheckRecoverKey(int id)
|
|
{
|
|
return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recoverKey;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CostRecoverKey(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recoverKey)
|
|
{
|
|
timeInfo.recoverKey = false;
|
|
SaveTimes();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public int GetRecoverInterval(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.interval;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public int GetRecoverSeconds(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.recoverSeconds;
|
|
return 0;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public int GetRechargeTimes(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
return timeInfo.recharge;
|
|
return 0;
|
|
}
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <param name="value"></param>
|
|
public void SetRechargeTimes(int id, int value)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
timeInfo.recharge = value;
|
|
}
|
|
/// <summary>
|
|
/// 检查充能次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CheckRechargeTimes(int id)
|
|
{
|
|
return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recharge < timeInfo.max;
|
|
}
|
|
/// <summary>
|
|
/// 消耗充能次数
|
|
/// </summary>
|
|
/// <param name="id"></param>
|
|
/// <returns></returns>
|
|
public bool CostRechargeTimes(int id)
|
|
{
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
{
|
|
int rechargeTimes = timeInfo.recharge;
|
|
if (rechargeTimes < timeInfo.max)
|
|
{
|
|
timeInfo.recharge = rechargeTimes - 1;
|
|
SaveTimes();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="sendNotification"></param>
|
|
/// <returns></returns>
|
|
bool CheckTimes(bool sendNotification)
|
|
{
|
|
if (AntiCheatProxy.Instance.isCheat)
|
|
return false;
|
|
|
|
var today5h = Launch.ServerNow.AddHours(-5).Date;
|
|
if (_saveDate < today5h)
|
|
{
|
|
if (_saveDate != default)
|
|
{
|
|
var newDay = ArchiveProxy.Instance.GetInt(GlobalDefine.KEY_NEW);
|
|
if (newDay > 0 && newDay < int.MaxValue)
|
|
{
|
|
ArchiveProxy.Instance.SetInt(GlobalDefine.KEY_NEW, newDay + 1);
|
|
}
|
|
}
|
|
|
|
var sameWeek = F.Utils.Time.IsInSameWeek(_saveDate, today5h);
|
|
foreach (var timeInfo in _timeInfos.Values)
|
|
{
|
|
int tmpType = timeInfo.item.type;
|
|
if (tmpType == 2)
|
|
timeInfo.cur = 0;
|
|
else if (tmpType == 3 && !sameWeek)
|
|
timeInfo.cur = 0;
|
|
}
|
|
|
|
_saveDate = today5h;
|
|
SaveTimes();
|
|
|
|
if (sendNotification)
|
|
{
|
|
PostNotification(GlobalDefine.EVENT_DAILY_LOGIN);
|
|
if (!sameWeek)
|
|
PostNotification(GlobalDefine.EVENT_WEEKLY_LOGIN);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
void InitTimes()
|
|
{
|
|
var timeItems = ItemProxy.Instance.GetStaticItems<ItemTime>();
|
|
if (timeItems != null && timeItems.Count > 0)
|
|
{
|
|
_timeInfos = new Dictionary<int, TimeInfo>(timeItems.Count);
|
|
foreach (var item in timeItems)
|
|
{
|
|
_timeInfos.Add(item.id, new TimeInfo(item));
|
|
}
|
|
}
|
|
}
|
|
|
|
const string TIME_KEY_V1 = "times_v1";
|
|
void LoadTimes()
|
|
{
|
|
var dataList = ArchiveProxy.Instance.GetIntList(TIME_KEY_V1);
|
|
if (dataList != null && dataList.Count > 0)
|
|
{
|
|
int index = 0;
|
|
_saveDate = F.Utils.Time.ToDataTime(dataList[index++]);
|
|
|
|
for (int i = 2; i < dataList.Count; i += 2)
|
|
{
|
|
int id = dataList[i - 1];
|
|
int status = dataList[i];
|
|
if (_timeInfos.TryGetValue(id, out var timeInfo))
|
|
timeInfo.SetStatus(status);
|
|
}
|
|
}
|
|
|
|
CheckTimes(false);
|
|
}
|
|
|
|
private void SaveTimes()
|
|
{
|
|
var dataList = ArchiveProxy.Instance.GetIntList(TIME_KEY_V1);
|
|
if (dataList != null)
|
|
{
|
|
dataList.Clear();
|
|
|
|
dataList.Add(Utils.Time.ToUnixTime(_saveDate));
|
|
|
|
foreach (var item in _timeInfos)
|
|
{
|
|
dataList.Add(item.Key);
|
|
dataList.Add(item.Value.GetStatus());
|
|
}
|
|
|
|
ArchiveProxy.Instance.SetIntList(TIME_KEY_V1, dataList);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Proxy
|
|
|
|
public static TimeProxy Instance => GetInstance<TimeProxy>();
|
|
|
|
public override int priority => 997;
|
|
|
|
public override void ReadArchive()
|
|
{
|
|
InitTimes();
|
|
LoadTimes();
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
} |