diff --git a/Assets/TcgEngine/Scripts/Api/ApiMsg.cs b/Assets/TcgEngine/Scripts/Api/ApiMsg.cs index 49ab989..ee45522 100644 --- a/Assets/TcgEngine/Scripts/Api/ApiMsg.cs +++ b/Assets/TcgEngine/Scripts/Api/ApiMsg.cs @@ -229,8 +229,8 @@ namespace TcgEngine public struct PlayerTaskResponse { public string taskId; - public long assignedTime; - public long expireTime; + public string assignedTime; + public string expireTime; public int status; public int progress; } @@ -239,14 +239,14 @@ namespace TcgEngine public struct PlayerTasksResponse { public PlayerTaskResponse[] tasks; - public long lastDailyTaskAssigned; + public string lastDailyTaskAssigned; } [Serializable] public struct PlayerTaskSaveRequest { public PlayerTaskResponse[] tasks; - public long lastDailyTaskAssigned; + public string lastDailyTaskAssigned; } } diff --git a/Assets/TcgEngine/Scripts/Api/UserData.cs b/Assets/TcgEngine/Scripts/Api/UserData.cs index 93f0953..b39d410 100644 --- a/Assets/TcgEngine/Scripts/Api/UserData.cs +++ b/Assets/TcgEngine/Scripts/Api/UserData.cs @@ -62,8 +62,6 @@ namespace TcgEngine { int currentLeve = GetLevel(); int baseXp = (currentLeve - 1) * 1000; - Debug.LogError(xp); - // 距离下一级还需多少经验值 int xpIntoCurrentLevel = xp - baseXp; return (float)xpIntoCurrentLevel / 1000f; diff --git a/Assets/TcgEngine/Scripts/Data/TaskData.cs b/Assets/TcgEngine/Scripts/Data/TaskData.cs index 57a222c..eee2582 100644 --- a/Assets/TcgEngine/Scripts/Data/TaskData.cs +++ b/Assets/TcgEngine/Scripts/Data/TaskData.cs @@ -47,6 +47,39 @@ namespace TcgEngine return taskData; } + + // 本地读取的缓存存储处 + // 还没改 + public TaskData LoadFromResponse(TaskDataResponse response) + { + TaskData task = ScriptableObject.CreateInstance(); + task.id = response.id; + task.name = response.name; + task.desc = response.desc; + task.condition = (TaskConditionType)response.condition; + task.value1 = response.value1; + task.value2 = response.value2; + task.value3 = response.value3; + + if (response.rewardTypes != null) + { + task.rewardTypes = new TaskRewardType[response.rewardTypes.Length]; + for (int i = 0; i < response.rewardTypes.Length; i++) + { + task.rewardTypes[i] = (TaskRewardType)response.rewardTypes[i]; + } + } + else + { + task.rewardTypes = new TaskRewardType[0]; + } + + task.rewardNums = response.rewardNums != null ? response.rewardNums : new int[0]; + task.isDailyTask = response.isDailyTask; + task.durationHours = response.durationHours; + + return task; + } } public enum TaskConditionType @@ -78,11 +111,7 @@ namespace TcgEngine { taskId = taskConfig.id; assignedTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - expireTime = DateTimeOffset.UtcNow.AddHours(taskConfig.durationHours).ToUnixTimeSeconds(); - Debug.Log($"" + - $"任务获取时间=={assignedTime}" + - $"任务结束时间=={expireTime}" + - $""); + expireTime = DateTimeOffset.FromUnixTimeSeconds(assignedTime).AddDays(1).ToUnixTimeSeconds(); status = TaskStatus.Active; progress = 0; } @@ -92,27 +121,48 @@ namespace TcgEngine public PlayerTask(PlayerTaskResponse response) { taskId = response.taskId; - assignedTime = response.assignedTime; - expireTime = response.expireTime; - Debug.Log($"" + - $"任务获取时间=={assignedTime}" + - $"任务结束时间=={expireTime}" + - $""); + assignedTime = Iso8601ToTimestamp(response.assignedTime); + expireTime = Iso8601ToTimestamp(response.expireTime); status = (TaskStatus)response.status; progress = response.progress; } - // 转换为服务器响应数据 + // 转换为服务器响应数据,传递向服务器 public PlayerTaskResponse ToResponse() { PlayerTaskResponse response = new PlayerTaskResponse(); response.taskId = taskId; - response.assignedTime = assignedTime; - response.expireTime = expireTime; + response.assignedTime = TimestampToIso8601(assignedTime); + response.expireTime = TimestampToIso8601(expireTime); response.status = (int)status; response.progress = progress; return response; } + + // 时间戳(秒)转 ISO 8601 格式字符串 + public static string TimestampToIso8601(long timestampSeconds) + { + // 从 Unix 时间戳(秒)创建 DateTimeOffset(UTC 时间) + DateTimeOffset dateTimeOffset = DateTimeOffset.FromUnixTimeSeconds(timestampSeconds); + // 转换为带毫秒的 ISO 8601 格式(UTC+0 时区,带 Z 标识) + return dateTimeOffset.ToString("yyyy-MM-ddTHH:mm:ss.fffZ"); + } + + public static long Iso8601ToTimestamp(string iso8601String) + { + // 清除字符串前后的空白字符和可能的隐藏字符 + string cleaned = iso8601String?.Trim() ?? string.Empty; + + if (DateTimeOffset.TryParse(cleaned, out DateTimeOffset dateTimeOffset)) + { + return dateTimeOffset.ToUnixTimeSeconds(); + } + + // 输出错误信息便于排查(实际运行可删除) + Debug.LogError($"解析失败,原始字符串: [{iso8601String}], 清理后: [{cleaned}]"); + throw new ArgumentException("无效的 ISO 8601 格式字符串"); + } + } public enum TaskStatus @@ -122,4 +172,6 @@ namespace TcgEngine Expired = 2, // 过期 Claimed = 3 // 已领取 } + + } \ No newline at end of file diff --git a/Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs b/Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs index 2efd831..d389a1b 100644 --- a/Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs +++ b/Assets/TcgEngine/Scripts/GameLogic/TaskManager.cs @@ -15,7 +15,6 @@ namespace TcgEngine.Gameplay public class TaskManager : MonoBehaviour { public static TaskManager Instance; - [Header("Player Data")] public List playerTasks = new List(); public bool isClearPlayerTasks = false; @@ -34,7 +33,9 @@ namespace TcgEngine.Gameplay // 任务缓存处 public Dictionary taskConfigs = new Dictionary(); - + // 玩家任务快速索引 + private Dictionary assignedTaskDict = new Dictionary(); + private void Awake() { @@ -47,6 +48,7 @@ namespace TcgEngine.Gameplay { Destroy(gameObject); } + } private void Start() @@ -65,6 +67,7 @@ namespace TcgEngine.Gameplay LoadPlayerData(); gameClient.onGameStart += OnGameStart; gameClient.onGameEnd += OnGameEnd; + refreshTaskUI += CheckExpiredTasks; // gameClient.onConnectServer?.Invoke(); } @@ -149,7 +152,7 @@ namespace TcgEngine.Gameplay { Debug.Log($"缓存ID处{item.id}"); taskConfigs[item.id] = - CreateFromResponse(item); + TaskData.CreateFromResponse(item); } Debug.Log("共储存:" + taskConfigs.Count + "条信息"); @@ -173,38 +176,6 @@ namespace TcgEngine.Gameplay } } } - - // 服务器下发的缓存存储处 - public TaskData CreateFromResponse(TaskDataResponse response) - { - TaskData task = ScriptableObject.CreateInstance(); - task.id = response.id; - task.name = response.name; - task.desc = response.desc; - task.condition = (TaskConditionType)response.condition; - task.value1 = response.value1; - task.value2 = response.value2; - task.value3 = response.value3; - - if (response.rewardTypes != null) - { - task.rewardTypes = new TaskRewardType[response.rewardTypes.Length]; - for (int i = 0; i < response.rewardTypes.Length; i++) - { - task.rewardTypes[i] = (TaskRewardType)response.rewardTypes[i]; - } - } - else - { - task.rewardTypes = new TaskRewardType[0]; - } - - task.rewardNums = response.rewardNums != null ? response.rewardNums : new int[0]; - task.isDailyTask = response.isDailyTask; - task.durationHours = response.durationHours; - - return task; - } private async void LoadPlayerData() { @@ -228,17 +199,19 @@ namespace TcgEngine.Gameplay try { PlayerTasksResponse response = ApiTool.JsonToObject(res.data); - lastDailyTaskAssigned = response.lastDailyTaskAssigned; + lastDailyTaskAssigned = PlayerTask.Iso8601ToTimestamp(response.lastDailyTaskAssigned); // 清除现有任务 playerTasks.Clear(); + assignedTaskDict.Clear(); // 转换并添加任务 foreach (var taskResponse in response.tasks) { PlayerTask playerTask = new PlayerTask(taskResponse); playerTasks.Add(playerTask); - Debug.Log(playerTask); + assignedTaskDict[playerTask.taskId] = playerTask; + Debug.Log($"已分配任务: {playerTask.taskId}"); } Debug.Log("Player tasks loaded from server: " + playerTasks.Count + " tasks"); @@ -260,31 +233,26 @@ namespace TcgEngine.Gameplay // 将玩家任务数据保存到服务器 if (ApiClient.Get() != null) { + + if (isClearPlayerTasks) + { + playerTasks.Clear(); + isClearPlayerTasks = false; + } + // 准备要发送的数据 - PlayerTasksResponse saveData = new PlayerTasksResponse(); + PlayerTaskSaveRequest saveData = new PlayerTaskSaveRequest(); // 转换任务数据 PlayerTaskResponse[] taskResponses = new PlayerTaskResponse[playerTasks.Count]; for (int i = 0; i < playerTasks.Count; i++) { taskResponses[i] = playerTasks[i].ToResponse(); - Debug.Log($"数据[{i}]:{taskResponses[i].taskId}"); } - foreach (PlayerTaskResponse item in taskResponses) - { - Debug.Log($"id:{item.taskId}" + - $"开始时间:{item.assignedTime}" + - $"结束时间:{item.expireTime}" + - $"状态:{item.status}" + - $"进度:{item.progress}" + - $""); - } - - Debug.Log($"{taskResponses.Length}"); saveData.tasks = taskResponses; - saveData.lastDailyTaskAssigned = lastDailyTaskAssigned; + saveData.lastDailyTaskAssigned = PlayerTask.TimestampToIso8601(lastDailyTaskAssigned); Debug.Log($"saveData.tasks---{saveData.tasks.Length}"); @@ -295,11 +263,7 @@ namespace TcgEngine.Gameplay Debug.Log(json); Debug.Log($"SavePlayerData:{url}"); - if (isClearPlayerTasks) - { - Debug.Log($"数据清除后SavePlayerData:{url}"); - isClearPlayerTasks = false; - } + if (res.success) { @@ -318,6 +282,11 @@ namespace TcgEngine.Gameplay { ClearAllSaveData(); } + + if (Input.GetKeyDown(KeyCode.S)) + { + SavePlayerData(); + } } private void ClearAllSaveData() @@ -328,6 +297,7 @@ namespace TcgEngine.Gameplay return; } playerTasks.Clear(); + assignedTaskDict.Clear(); SavePlayerData(); Debug.Log("清除成功"); @@ -337,12 +307,12 @@ namespace TcgEngine.Gameplay public void AssignDailyTaskIfNeeded() { long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - long secondsSinceLastTask = now - lastDailyTaskAssigned; + long secondsSinceLastTask = now - lastDailyTaskAssigned; // 转换为小时 double hoursSinceLastTask = secondsSinceLastTask / 3600.0; - - if (hoursSinceLastTask < 24) + Debug.Log($"当前时间:{now},最后下发时间:{lastDailyTaskAssigned},减去时间{secondsSinceLastTask},小时时间:{hoursSinceLastTask}"); + if (hoursSinceLastTask < 24 && assignedTaskDict.Count == 5) return; // 检查玩家是否已达到最大任务数 @@ -388,8 +358,8 @@ namespace TcgEngine.Gameplay triedTasks.Add(candidateTask.id); - // 检查任务是否有效(未被玩家完成过或未在进度中) - if (!playerTasks.Any(pt => pt.taskId == candidateTask.id)) + // 用字典判断是否已分配过 + if (!assignedTaskDict.ContainsKey(candidateTask.id)) { selectedTask = candidateTask; break; @@ -414,12 +384,14 @@ namespace TcgEngine.Gameplay } // 检查并更新过期任务 - public void CheckExpiredTasks() + public void CheckExpiredTasks(List tasksList) { long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); // 当前时间戳(秒) - foreach (var task in playerTasks) + + foreach (var task in tasksList) { - if (task.status == TaskStatus.Active && now > task.expireTime) + long unixTime = task.expireTime; + if (task.status == TaskStatus.Active && now > unixTime) { task.status = TaskStatus.Expired; } @@ -482,7 +454,15 @@ namespace TcgEngine.Gameplay private TaskData GetTaskConfig(string taskId) { - TaskData[] allTasks = Resources.LoadAll("Tasks"); + TaskData[] allTasks; + if (taskConfigs!=null) + { + allTasks = taskConfigs.Values.ToArray(); + } + else + { + allTasks = Resources.LoadAll("Tasks"); + } return allTasks.FirstOrDefault(t => t.id == taskId); } @@ -547,7 +527,6 @@ namespace TcgEngine.Gameplay if (progressUpdated) { - Debug.LogError("读到了"); SavePlayerData(); } } @@ -555,7 +534,6 @@ namespace TcgEngine.Gameplay // 事件处理方法 private void OnGameStart() { - // 进行对战任务进度+1 UpdateTaskProgress(TaskConditionType.PlayGames); } @@ -636,12 +614,14 @@ namespace TcgEngine.Gameplay public void OnPlayerLogin() { // 检查是否已有登录任务 - bool hasLoginTask = playerTasks.Any(t => + bool hasLoginTask = assignedTaskDict.Values.Any(t => { TaskData config = GetTaskConfig(t.taskId); return config != null && config.condition == TaskConditionType.LoginGame; }); - + + Debug.Log("hasLoginTask:"+hasLoginTask); + // 如果没有登录任务,就分配一个 if (!hasLoginTask) { @@ -656,9 +636,6 @@ namespace TcgEngine.Gameplay // 登录任务完成 UpdateTaskProgress(TaskConditionType.LoginGame); - // 检查是否有任务完成并自动领取奖励 - CheckAndClaimCompletedTasks(); - } @@ -667,14 +644,23 @@ namespace TcgEngine.Gameplay /// private void AssignLoginTask() { - TaskData[] allTasks = Resources.LoadAll("Tasks"); + TaskData[] allTasks; + if (taskConfigs != null) + { + allTasks = taskConfigs.Values.ToArray(); + } + else + { + allTasks = Resources.LoadAll("Tasks"); + } + var loginTask = allTasks.FirstOrDefault(t => t.isDailyTask && t.condition == TaskConditionType.LoginGame); if (loginTask != null) { PlayerTask playerTask = new PlayerTask(loginTask); playerTasks.Add(playerTask); - lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); + lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); SavePlayerData(); Debug.Log($"分配登录任务: {loginTask.name}"); }