// *********************************************************************** // Assembly : Game // Author : Kimch // Created : 2021-04-29 // Description : // Last Modified By : // Last Modified On : // *********************************************************************** // // // *********************************************************************** using CodeStage.AntiCheat.ObscuredTypes; using F; using System; using System.Collections.Generic; using UnityEngine; namespace G { /// /// 次数 /// partial class TimeProxy : F.GameProxy { /// /// 次数信息 /// class TimeInfo { public readonly ItemTime item; /// /// /// private ObscuredVector2Int _data; private readonly int _intervalSeconds; private readonly int _timeLimit; /// /// /// public int interval => _intervalSeconds; /// /// 极限 /// public int limit => _timeLimit; /// /// /// public int cur { get => _data.x; set => _data.x = Math.Max(0, value); } /// /// /// public int max { get => _data.y; set { if (value > 0) _data.y = value; else _data.y = item.maxCount; } } /// /// /// public int free { get => item.freeCount; } /// /// 余量 /// public int remain { get => Math.Max(0, _data.y - _data.x); set => _data.x = Math.Max(0, _data.y - value); } /// /// /// public TimeInfo2 simpleInfo2 { get => new TimeInfo2 { remain = remain, max = max }; } /// /// /// public TimeInfo3 simpleInfo3 { get => new TimeInfo3 { remain = remain, max = max, free = freeRemain }; } /// /// /// public int freeRemain { get => item.freeCount - _data.x; } /// /// 恢复 /// public bool recoverKey { get { return Launch.Timestamp - _data.x > 0; } set { _data.x = Launch.Timestamp + _intervalSeconds; } } /// /// /// public int recoverTimestamp { get => _data.x; } /// /// /// public int recoverSeconds { get => recoverTimestamp - Launch.Timestamp; } /// /// 获得恢复的次数 /// 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); } } } /// /// 充能时间 /// public int rechargeTimestamp { get { int result = _data.x; if (result >= _data.y && result <= _timeLimit) return 0; return result; } } /// /// /// public int rechargeSeconds { get => rechargeTimestamp - Launch.Timestamp; } /// /// 充能信息 /// public string rechargeText { get { int second = rechargeSeconds; if (second > 0) { int temp = second % _intervalSeconds; return $"{temp / 60}:{(temp % 60).ToString("00")}"; } return ""; } } /// /// /// /// 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 /// /// 数据结构 /// Dictionary _timeInfos; /// /// 存日期 /// DateTime _saveDate; #endregion #region METHOD /// /// 取得bool值 /// /// 0:每日任务,1:每日活动,2:7日签到,3:每日免费加速,4 每日离线奖励 /// public bool GetTimeKey(int id) { CheckTimes(true); return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < 1; } /// /// /// /// /// 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; } /// /// 获得剩余次数 /// /// 0 每日免费宝箱次数 ,1 每日免费体力,2每日免费金币 ,3 碎片,4宠物,5无尽 /// public int GetTimes(int id) { CheckTimes(true); if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.remain; return 0; } /// /// 获得剩余次数 /// /// /// public TimeInfo2 GetTimeInfo2(int id) { CheckTimes(true); if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.simpleInfo2; return default; } /// /// 获得剩余次数 /// /// /// public TimeInfo3 GetTimeInfo3(int id) { CheckTimes(true); if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.simpleInfo3; return default; } /// /// 获得 /// /// /// 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(); } } } /// /// 0 shop ,1体力,2金币,3 碎片,4宠物,5无尽 /// /// /// public int GetMaxTimes(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.max; return 0; } /// /// /// /// /// public void SetMaxTimes(int id, int value, bool increment = false) { if (_timeInfos.TryGetValue(id, out var timeInfo)) timeInfo.max = value; } /// /// /// /// /// /// public void AddMaxTimes(int id, int value, bool increment = false) { if (_timeInfos.TryGetValue(id, out var timeInfo)) timeInfo.max += value; } /// /// 重置所有次数 /// public void ResetAllMaxTimes() { foreach (var timeInfo in _timeInfos) { timeInfo.Value.max = 0; } } /// /// /// /// /// public bool CheckTimes(int id) { return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < timeInfo.max; } /// /// 免费次数 /// /// /// public bool CheckFreeTimes(int id) { return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.cur < timeInfo.free; } /// /// 免费次数 /// /// /// public int GetFreeTimes(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.free - timeInfo.cur; return 0; } /// /// /// /// /// 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; } /// /// /// /// /// public bool CheckRecoverKey(int id) { return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recoverKey; } /// /// /// /// /// public bool CostRecoverKey(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recoverKey) { timeInfo.recoverKey = false; SaveTimes(); return true; } return false; } /// /// /// /// /// public int GetRecoverInterval(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.interval; return 0; } /// /// /// /// /// public int GetRecoverSeconds(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.recoverSeconds; return 0; } /// /// /// /// /// public int GetRechargeTimes(int id) { if (_timeInfos.TryGetValue(id, out var timeInfo)) return timeInfo.recharge; return 0; } /// /// /// /// /// public void SetRechargeTimes(int id, int value) { if (_timeInfos.TryGetValue(id, out var timeInfo)) timeInfo.recharge = value; } /// /// 检查充能次数 /// /// /// public bool CheckRechargeTimes(int id) { return _timeInfos.TryGetValue(id, out var timeInfo) && timeInfo.recharge < timeInfo.max; } /// /// 消耗充能次数 /// /// /// 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; } /// /// /// /// /// 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; } /// /// /// void InitTimes() { var timeItems = ItemProxy.Instance.GetStaticItems(); if (timeItems != null && timeItems.Count > 0) { _timeInfos = new Dictionary(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(); public override int priority => 997; public override void ReadArchive() { InitTimes(); LoadTimes(); } #endregion } }