2025-05-18 01:04:31 +08:00

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
}
}