修正任务时间转换

This commit is contained in:
YiHan0621
2025-09-10 15:23:49 +08:00
parent 601ec86256
commit bf13498f86
4 changed files with 130 additions and 94 deletions

View File

@@ -229,8 +229,8 @@ namespace TcgEngine
public struct PlayerTaskResponse public struct PlayerTaskResponse
{ {
public string taskId; public string taskId;
public long assignedTime; public string assignedTime;
public long expireTime; public string expireTime;
public int status; public int status;
public int progress; public int progress;
} }
@@ -239,14 +239,14 @@ namespace TcgEngine
public struct PlayerTasksResponse public struct PlayerTasksResponse
{ {
public PlayerTaskResponse[] tasks; public PlayerTaskResponse[] tasks;
public long lastDailyTaskAssigned; public string lastDailyTaskAssigned;
} }
[Serializable] [Serializable]
public struct PlayerTaskSaveRequest public struct PlayerTaskSaveRequest
{ {
public PlayerTaskResponse[] tasks; public PlayerTaskResponse[] tasks;
public long lastDailyTaskAssigned; public string lastDailyTaskAssigned;
} }
} }

View File

@@ -62,8 +62,6 @@ namespace TcgEngine
{ {
int currentLeve = GetLevel(); int currentLeve = GetLevel();
int baseXp = (currentLeve - 1) * 1000; int baseXp = (currentLeve - 1) * 1000;
Debug.LogError(xp);
// 距离下一级还需多少经验值
int xpIntoCurrentLevel = xp - baseXp; int xpIntoCurrentLevel = xp - baseXp;
return (float)xpIntoCurrentLevel / 1000f; return (float)xpIntoCurrentLevel / 1000f;

View File

@@ -47,6 +47,39 @@ namespace TcgEngine
return taskData; return taskData;
} }
// 本地读取的缓存存储处
// 还没改
public TaskData LoadFromResponse(TaskDataResponse response)
{
TaskData task = ScriptableObject.CreateInstance<TaskData>();
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 public enum TaskConditionType
@@ -78,11 +111,7 @@ namespace TcgEngine
{ {
taskId = taskConfig.id; taskId = taskConfig.id;
assignedTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); assignedTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
expireTime = DateTimeOffset.UtcNow.AddHours(taskConfig.durationHours).ToUnixTimeSeconds(); expireTime = DateTimeOffset.FromUnixTimeSeconds(assignedTime).AddDays(1).ToUnixTimeSeconds();
Debug.Log($"<color=red>" +
$"任务获取时间=={assignedTime}" +
$"任务结束时间=={expireTime}" +
$"</color>");
status = TaskStatus.Active; status = TaskStatus.Active;
progress = 0; progress = 0;
} }
@@ -92,27 +121,48 @@ namespace TcgEngine
public PlayerTask(PlayerTaskResponse response) public PlayerTask(PlayerTaskResponse response)
{ {
taskId = response.taskId; taskId = response.taskId;
assignedTime = response.assignedTime; assignedTime = Iso8601ToTimestamp(response.assignedTime);
expireTime = response.expireTime; expireTime = Iso8601ToTimestamp(response.expireTime);
Debug.Log($"<color=red>" +
$"任务获取时间=={assignedTime}" +
$"任务结束时间=={expireTime}" +
$"</color>");
status = (TaskStatus)response.status; status = (TaskStatus)response.status;
progress = response.progress; progress = response.progress;
} }
// 转换为服务器响应数据 // 转换为服务器响应数据,传递向服务器
public PlayerTaskResponse ToResponse() public PlayerTaskResponse ToResponse()
{ {
PlayerTaskResponse response = new PlayerTaskResponse(); PlayerTaskResponse response = new PlayerTaskResponse();
response.taskId = taskId; response.taskId = taskId;
response.assignedTime = assignedTime; response.assignedTime = TimestampToIso8601(assignedTime);
response.expireTime = expireTime; response.expireTime = TimestampToIso8601(expireTime);
response.status = (int)status; response.status = (int)status;
response.progress = progress; response.progress = progress;
return response; return response;
} }
// 时间戳(秒)转 ISO 8601 格式字符串
public static string TimestampToIso8601(long timestampSeconds)
{
// 从 Unix 时间戳(秒)创建 DateTimeOffsetUTC 时间)
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 public enum TaskStatus
@@ -122,4 +172,6 @@ namespace TcgEngine
Expired = 2, // 过期 Expired = 2, // 过期
Claimed = 3 // 已领取 Claimed = 3 // 已领取
} }
} }

View File

@@ -15,7 +15,6 @@ namespace TcgEngine.Gameplay
public class TaskManager : MonoBehaviour public class TaskManager : MonoBehaviour
{ {
public static TaskManager Instance; public static TaskManager Instance;
[Header("Player Data")] [Header("Player Data")]
public List<PlayerTask> playerTasks = new List<PlayerTask>(); public List<PlayerTask> playerTasks = new List<PlayerTask>();
public bool isClearPlayerTasks = false; public bool isClearPlayerTasks = false;
@@ -34,7 +33,9 @@ namespace TcgEngine.Gameplay
// 任务缓存处 // 任务缓存处
public Dictionary<string,TaskData> taskConfigs = new Dictionary<string,TaskData>(); public Dictionary<string,TaskData> taskConfigs = new Dictionary<string,TaskData>();
// 玩家任务快速索引
private Dictionary<string, PlayerTask> assignedTaskDict = new Dictionary<string, PlayerTask>();
private void Awake() private void Awake()
{ {
@@ -47,6 +48,7 @@ namespace TcgEngine.Gameplay
{ {
Destroy(gameObject); Destroy(gameObject);
} }
} }
private void Start() private void Start()
@@ -65,6 +67,7 @@ namespace TcgEngine.Gameplay
LoadPlayerData(); LoadPlayerData();
gameClient.onGameStart += OnGameStart; gameClient.onGameStart += OnGameStart;
gameClient.onGameEnd += OnGameEnd; gameClient.onGameEnd += OnGameEnd;
refreshTaskUI += CheckExpiredTasks;
// gameClient.onConnectServer?.Invoke(); // gameClient.onConnectServer?.Invoke();
} }
@@ -149,7 +152,7 @@ namespace TcgEngine.Gameplay
{ {
Debug.Log($"缓存ID处<color=pink>{item.id}</color>"); Debug.Log($"缓存ID处<color=pink>{item.id}</color>");
taskConfigs[item.id] = taskConfigs[item.id] =
CreateFromResponse(item); TaskData.CreateFromResponse(item);
} }
Debug.Log("共储存:" + taskConfigs.Count + "条信息"); Debug.Log("共储存:" + taskConfigs.Count + "条信息");
@@ -173,38 +176,6 @@ namespace TcgEngine.Gameplay
} }
} }
} }
// 服务器下发的缓存存储处
public TaskData CreateFromResponse(TaskDataResponse response)
{
TaskData task = ScriptableObject.CreateInstance<TaskData>();
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() private async void LoadPlayerData()
{ {
@@ -228,17 +199,19 @@ namespace TcgEngine.Gameplay
try try
{ {
PlayerTasksResponse response = ApiTool.JsonToObject<PlayerTasksResponse>(res.data); PlayerTasksResponse response = ApiTool.JsonToObject<PlayerTasksResponse>(res.data);
lastDailyTaskAssigned = response.lastDailyTaskAssigned; lastDailyTaskAssigned = PlayerTask.Iso8601ToTimestamp(response.lastDailyTaskAssigned);
// 清除现有任务 // 清除现有任务
playerTasks.Clear(); playerTasks.Clear();
assignedTaskDict.Clear();
// 转换并添加任务 // 转换并添加任务
foreach (var taskResponse in response.tasks) foreach (var taskResponse in response.tasks)
{ {
PlayerTask playerTask = new PlayerTask(taskResponse); PlayerTask playerTask = new PlayerTask(taskResponse);
playerTasks.Add(playerTask); playerTasks.Add(playerTask);
Debug.Log(playerTask); assignedTaskDict[playerTask.taskId] = playerTask;
Debug.Log($"已分配任务: {playerTask.taskId}");
} }
Debug.Log("Player tasks loaded from server: " + playerTasks.Count + " tasks"); Debug.Log("Player tasks loaded from server: " + playerTasks.Count + " tasks");
@@ -260,31 +233,26 @@ namespace TcgEngine.Gameplay
// 将玩家任务数据保存到服务器 // 将玩家任务数据保存到服务器
if (ApiClient.Get() != null) if (ApiClient.Get() != null)
{ {
if (isClearPlayerTasks)
{
playerTasks.Clear();
isClearPlayerTasks = false;
}
// 准备要发送的数据 // 准备要发送的数据
PlayerTasksResponse saveData = new PlayerTasksResponse(); PlayerTaskSaveRequest saveData = new PlayerTaskSaveRequest();
// 转换任务数据 // 转换任务数据
PlayerTaskResponse[] taskResponses = new PlayerTaskResponse[playerTasks.Count]; PlayerTaskResponse[] taskResponses = new PlayerTaskResponse[playerTasks.Count];
for (int i = 0; i < playerTasks.Count; i++) for (int i = 0; i < playerTasks.Count; i++)
{ {
taskResponses[i] = playerTasks[i].ToResponse(); taskResponses[i] = playerTasks[i].ToResponse();
Debug.Log($"数据[{i}]:{taskResponses[i].taskId}");
} }
foreach (PlayerTaskResponse item in taskResponses)
{
Debug.Log($"<color=red>id:{item.taskId}" +
$"开始时间:{item.assignedTime}" +
$"结束时间:{item.expireTime}" +
$"状态:{item.status}" +
$"进度:{item.progress}" +
$"</color>");
}
Debug.Log($"<color=red>{taskResponses.Length}</color>"); Debug.Log($"<color=red>{taskResponses.Length}</color>");
saveData.tasks = taskResponses; saveData.tasks = taskResponses;
saveData.lastDailyTaskAssigned = lastDailyTaskAssigned; saveData.lastDailyTaskAssigned = PlayerTask.TimestampToIso8601(lastDailyTaskAssigned);
Debug.Log($"saveData.tasks---{saveData.tasks.Length}"); Debug.Log($"saveData.tasks---{saveData.tasks.Length}");
@@ -295,11 +263,7 @@ namespace TcgEngine.Gameplay
Debug.Log(json); Debug.Log(json);
Debug.Log($"<color=red>SavePlayerData:{url}</color>"); Debug.Log($"<color=red>SavePlayerData:{url}</color>");
if (isClearPlayerTasks)
{
Debug.Log($"数据清除后<color=red>SavePlayerData:{url}</color>");
isClearPlayerTasks = false;
}
if (res.success) if (res.success)
{ {
@@ -318,6 +282,11 @@ namespace TcgEngine.Gameplay
{ {
ClearAllSaveData(); ClearAllSaveData();
} }
if (Input.GetKeyDown(KeyCode.S))
{
SavePlayerData();
}
} }
private void ClearAllSaveData() private void ClearAllSaveData()
@@ -328,6 +297,7 @@ namespace TcgEngine.Gameplay
return; return;
} }
playerTasks.Clear(); playerTasks.Clear();
assignedTaskDict.Clear();
SavePlayerData(); SavePlayerData();
Debug.Log("清除成功"); Debug.Log("清除成功");
@@ -337,12 +307,12 @@ namespace TcgEngine.Gameplay
public void AssignDailyTaskIfNeeded() public void AssignDailyTaskIfNeeded()
{ {
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long secondsSinceLastTask = now - lastDailyTaskAssigned;
long secondsSinceLastTask = now - lastDailyTaskAssigned;
// 转换为小时 // 转换为小时
double hoursSinceLastTask = secondsSinceLastTask / 3600.0; double hoursSinceLastTask = secondsSinceLastTask / 3600.0;
Debug.Log($"当前时间:{now},最后下发时间:{lastDailyTaskAssigned},减去时间{secondsSinceLastTask},小时时间:{hoursSinceLastTask}");
if (hoursSinceLastTask < 24) if (hoursSinceLastTask < 24 && assignedTaskDict.Count == 5)
return; return;
// 检查玩家是否已达到最大任务数 // 检查玩家是否已达到最大任务数
@@ -388,8 +358,8 @@ namespace TcgEngine.Gameplay
triedTasks.Add(candidateTask.id); triedTasks.Add(candidateTask.id);
// 检查任务是否有效(未被玩家完成过或未在进度中) // 用字典判断是否已分配过
if (!playerTasks.Any(pt => pt.taskId == candidateTask.id)) if (!assignedTaskDict.ContainsKey(candidateTask.id))
{ {
selectedTask = candidateTask; selectedTask = candidateTask;
break; break;
@@ -414,12 +384,14 @@ namespace TcgEngine.Gameplay
} }
// 检查并更新过期任务 // 检查并更新过期任务
public void CheckExpiredTasks() public void CheckExpiredTasks(List<PlayerTask> tasksList)
{ {
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); // 当前时间戳(秒) 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; task.status = TaskStatus.Expired;
} }
@@ -482,7 +454,15 @@ namespace TcgEngine.Gameplay
private TaskData GetTaskConfig(string taskId) private TaskData GetTaskConfig(string taskId)
{ {
TaskData[] allTasks = Resources.LoadAll<TaskData>("Tasks"); TaskData[] allTasks;
if (taskConfigs!=null)
{
allTasks = taskConfigs.Values.ToArray();
}
else
{
allTasks = Resources.LoadAll<TaskData>("Tasks");
}
return allTasks.FirstOrDefault(t => t.id == taskId); return allTasks.FirstOrDefault(t => t.id == taskId);
} }
@@ -547,7 +527,6 @@ namespace TcgEngine.Gameplay
if (progressUpdated) if (progressUpdated)
{ {
Debug.LogError("读到了");
SavePlayerData(); SavePlayerData();
} }
} }
@@ -555,7 +534,6 @@ namespace TcgEngine.Gameplay
// 事件处理方法 // 事件处理方法
private void OnGameStart() private void OnGameStart()
{ {
// 进行对战任务进度+1 // 进行对战任务进度+1
UpdateTaskProgress(TaskConditionType.PlayGames); UpdateTaskProgress(TaskConditionType.PlayGames);
} }
@@ -636,12 +614,14 @@ namespace TcgEngine.Gameplay
public void OnPlayerLogin() public void OnPlayerLogin()
{ {
// 检查是否已有登录任务 // 检查是否已有登录任务
bool hasLoginTask = playerTasks.Any(t => bool hasLoginTask = assignedTaskDict.Values.Any(t =>
{ {
TaskData config = GetTaskConfig(t.taskId); TaskData config = GetTaskConfig(t.taskId);
return config != null && config.condition == TaskConditionType.LoginGame; return config != null && config.condition == TaskConditionType.LoginGame;
}); });
Debug.Log("hasLoginTask:"+hasLoginTask);
// 如果没有登录任务,就分配一个 // 如果没有登录任务,就分配一个
if (!hasLoginTask) if (!hasLoginTask)
{ {
@@ -656,9 +636,6 @@ namespace TcgEngine.Gameplay
// 登录任务完成 // 登录任务完成
UpdateTaskProgress(TaskConditionType.LoginGame); UpdateTaskProgress(TaskConditionType.LoginGame);
// 检查是否有任务完成并自动领取奖励
CheckAndClaimCompletedTasks();
} }
@@ -667,14 +644,23 @@ namespace TcgEngine.Gameplay
/// </summary> /// </summary>
private void AssignLoginTask() private void AssignLoginTask()
{ {
TaskData[] allTasks = Resources.LoadAll<TaskData>("Tasks"); TaskData[] allTasks;
if (taskConfigs != null)
{
allTasks = taskConfigs.Values.ToArray();
}
else
{
allTasks = Resources.LoadAll<TaskData>("Tasks");
}
var loginTask = allTasks.FirstOrDefault(t => t.isDailyTask && t.condition == TaskConditionType.LoginGame); var loginTask = allTasks.FirstOrDefault(t => t.isDailyTask && t.condition == TaskConditionType.LoginGame);
if (loginTask != null) if (loginTask != null)
{ {
PlayerTask playerTask = new PlayerTask(loginTask); PlayerTask playerTask = new PlayerTask(loginTask);
playerTasks.Add(playerTask); playerTasks.Add(playerTask);
lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
SavePlayerData(); SavePlayerData();
Debug.Log($"分配登录任务: {loginTask.name}"); Debug.Log($"分配登录任务: {loginTask.name}");
} }