修正任务时间转换
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -47,6 +47,39 @@ namespace TcgEngine
|
||||
|
||||
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
|
||||
@@ -78,11 +111,7 @@ namespace TcgEngine
|
||||
{
|
||||
taskId = taskConfig.id;
|
||||
assignedTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
expireTime = DateTimeOffset.UtcNow.AddHours(taskConfig.durationHours).ToUnixTimeSeconds();
|
||||
Debug.Log($"<color=red>" +
|
||||
$"任务获取时间=={assignedTime}" +
|
||||
$"任务结束时间=={expireTime}" +
|
||||
$"</color>");
|
||||
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($"<color=red>" +
|
||||
$"任务获取时间=={assignedTime}" +
|
||||
$"任务结束时间=={expireTime}" +
|
||||
$"</color>");
|
||||
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 // 已领取
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -15,7 +15,6 @@ namespace TcgEngine.Gameplay
|
||||
public class TaskManager : MonoBehaviour
|
||||
{
|
||||
public static TaskManager Instance;
|
||||
|
||||
[Header("Player Data")]
|
||||
public List<PlayerTask> playerTasks = new List<PlayerTask>();
|
||||
public bool isClearPlayerTasks = false;
|
||||
@@ -34,6 +33,8 @@ namespace TcgEngine.Gameplay
|
||||
|
||||
// 任务缓存处
|
||||
public Dictionary<string,TaskData> taskConfigs = new Dictionary<string,TaskData>();
|
||||
// 玩家任务快速索引
|
||||
private Dictionary<string, PlayerTask> assignedTaskDict = new Dictionary<string, PlayerTask>();
|
||||
|
||||
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处<color=pink>{item.id}</color>");
|
||||
taskConfigs[item.id] =
|
||||
CreateFromResponse(item);
|
||||
TaskData.CreateFromResponse(item);
|
||||
}
|
||||
|
||||
Debug.Log("共储存:" + taskConfigs.Count + "条信息");
|
||||
@@ -174,38 +177,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()
|
||||
{
|
||||
// 从服务器加载玩家任务数据
|
||||
@@ -228,17 +199,19 @@ namespace TcgEngine.Gameplay
|
||||
try
|
||||
{
|
||||
PlayerTasksResponse response = ApiTool.JsonToObject<PlayerTasksResponse>(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($"<color=red>id:{item.taskId}" +
|
||||
$"开始时间:{item.assignedTime}" +
|
||||
$"结束时间:{item.expireTime}" +
|
||||
$"状态:{item.status}" +
|
||||
$"进度:{item.progress}" +
|
||||
$"</color>");
|
||||
}
|
||||
|
||||
|
||||
Debug.Log($"<color=red>{taskResponses.Length}</color>");
|
||||
|
||||
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($"<color=red>SavePlayerData:{url}</color>");
|
||||
if (isClearPlayerTasks)
|
||||
{
|
||||
Debug.Log($"数据清除后<color=red>SavePlayerData:{url}</color>");
|
||||
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<PlayerTask> 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<TaskData>("Tasks");
|
||||
TaskData[] allTasks;
|
||||
if (taskConfigs!=null)
|
||||
{
|
||||
allTasks = taskConfigs.Values.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
allTasks = Resources.LoadAll<TaskData>("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
|
||||
/// </summary>
|
||||
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);
|
||||
|
||||
if (loginTask != null)
|
||||
{
|
||||
PlayerTask playerTask = new PlayerTask(loginTask);
|
||||
playerTasks.Add(playerTask);
|
||||
lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
lastDailyTaskAssigned = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
SavePlayerData();
|
||||
Debug.Log($"分配登录任务: {loginTask.name}");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user