using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using TcgEngine;
using TcgEngine.Gameplay;
using TcgEngine.Client;
using System.Threading.Tasks;
namespace TcgEngine.Gameplay
{
///
/// 任务管理器,负责任务的分配、进度追踪和奖励发放等功能
///
public class TaskManager : MonoBehaviour
{
public static TaskManager Instance;
[Header("Player Data")]
public List playerTasks = new List();
public DateTime lastDailyTaskAssigned;
public int maxTasks = 5; // 玩家最多持有任务数
private GameLogic gameLogic;
private System.Random random = new System.Random();
public Action> refreshTaskUI;
private GameClient gameClient;
public string userID;
private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(gameObject);
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
userID = ApiClient.Get().UserID;
}
private void OnEnable()
{
// 订阅游戏事件
gameClient = FindFirstObjectByType();
gameClient = GameClient.Get();
if (gameClient != null)
{
LoadTasks();
LoadPlayerData();
gameClient.onGameStart += OnGameStart;
gameClient.onGameEnd += OnGameEnd;
// gameClient.onConnectServer?.Invoke();
}
// 移除对GameLogic.Instance的错误引用,改为检查gameLogic变量
if (gameLogic != null)
{
SubscribeToGameEvents();
}
}
private void Update()
{
}
private void OnDisable()
{
// 取消订阅游戏事件
gameClient = FindFirstObjectByType();
gameClient = GameClient.Get();
if (gameClient != null)
{
gameClient.onGameStart -= OnGameStart;
gameClient.onGameEnd -= OnGameEnd;
}
// 移除对GameLogic.Instance的错误引用,改为检查gameLogic变量
if (gameLogic != null)
{
UnsubscribeFromGameEvents();
}
}
public void SetGameLogic(GameLogic logic)
{
gameLogic = logic;
SubscribeToGameEvents();
}
private void SubscribeToGameEvents()
{
if (gameLogic != null)
{
gameLogic.onCardPlayed += OnCardPlayed;
gameLogic.onCardSummoned += OnCardSummoned;
gameLogic.onAbilityStart += OnAbilityUsed;
gameLogic.onCardDiscarded += OnCardDiscarded; // 用于检测击败英雄
}
}
private void UnsubscribeFromGameEvents()
{
if (gameLogic != null)
{
gameLogic.onCardPlayed -= OnCardPlayed;
gameLogic.onCardSummoned -= OnCardSummoned;
gameLogic.onAbilityStart -= OnAbilityUsed;
gameLogic.onCardDiscarded -= OnCardDiscarded;
}
}
private async void LoadTasks()
{
// 从服务器加载所有任务配置
await LoadTasksFromServer();
}
private async Task LoadTasksFromServer()
{
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
{
// 从服务器API获取任务配置
string url = ApiClient.ServerURL + "/api/tasks";
WebResponse res = await ApiClient.Get().SendGetRequest(url);
Debug.LogError("从服务器API获取任务配置" + res.data);
if (res.success)
{
// 解析任务配置数据
try
{
TaskDataResponse[] taskResponses = ApiTool.JsonToObject(res.data);
Debug.Log("Loaded " + taskResponses.Length + " tasks from server");
// 在实际项目中,这里应该将服务器数据转换为TaskData对象并存储在内存中
// 供后续使用,而不是每次都从Resources加载
foreach (var item in taskResponses)
{
Debug.Log($"{item.id}");
}
}
catch (Exception e)
{
Debug.LogError("Failed to parse task data from server: " + e.Message);
}
}
else
{
Debug.LogWarning("Failed to load tasks from server: " + res.error);
}
}
// 如果无法从服务器加载,则使用本地Resources作为后备
TaskData[] localTasks = Resources.LoadAll("Tasks");
Debug.Log("Loaded " + localTasks.Length + " tasks from local resources as fallback");
}
private async void LoadPlayerData()
{
// 从服务器加载玩家任务数据
await LoadPlayerTasksFromServer();
}
private async Task LoadPlayerTasksFromServer()
{
Debug.LogError(ApiClient.Get() + "" + ApiClient.Get().IsLoggedIn());
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
{
// 从服务器获取玩家任务数据
string url = ApiClient.ServerURL + $"/api/tasks/{userID}";
WebResponse res = await ApiClient.Get().SendGetRequest(url);
Debug.Log($"{url}");
Debug.LogWarning($"从服务器获取玩家任务数据res_data--:{res.data},{res.status}");
if (res.success)
{
// 解析玩家任务数据
try
{
PlayerTasksResponse response = ApiTool.JsonToObject(res.data);
lastDailyTaskAssigned = new DateTime(response.lastDailyTaskAssigned);
// 清除现有任务
playerTasks.Clear();
// 转换并添加任务
foreach (var taskResponse in response.tasks)
{
PlayerTask playerTask = new PlayerTask(taskResponse);
playerTasks.Add(playerTask);
Debug.Log(playerTask);
}
Debug.Log("Player tasks loaded from server: " + playerTasks.Count + " tasks");
}
catch (Exception e)
{
Debug.LogError("Failed to parse player tasks from server: " + e.Message);
}
}
else
{
Debug.LogWarning("Failed to load player tasks from server: " + res.error);
}
}
// 简化处理,首次登录时分配任务
if (playerTasks.Count == 0)
{
AssignDailyTaskIfNeeded();
}
}
public async void SavePlayerData()
{
// 将玩家任务数据保存到服务器
if (ApiClient.Get() != null)
{
// 准备要发送的数据
PlayerTasksResponse saveData = new PlayerTasksResponse();
// 转换任务数据
PlayerTaskResponse[] taskResponses = new PlayerTaskResponse[playerTasks.Count];
for (int i = 0; i < playerTasks.Count; i++)
{
taskResponses[i] = playerTasks[i].ToResponse();
}
Debug.Log($"{taskResponses.Length}");
saveData.tasks = taskResponses;
saveData.lastDailyTaskAssigned = lastDailyTaskAssigned.Ticks;
string json = ApiTool.ToJson(saveData);
string url = ApiClient.ServerURL + $"/api/tasks/{userID}";
WebResponse res = await ApiClient.Get().SendPostRequest(url, json);
if (res.success)
{
Debug.Log("玩家任务已保存到服务器");
}
else
{
Debug.LogWarning("未能将玩家任务保存到服务器:" + res.error);
}
}
}
// 每日任务分配
public void AssignDailyTaskIfNeeded()
{
// 检查是否应该分配新任务(每日一次)
DateTime now = DateTime.Now;
if ((now - lastDailyTaskAssigned).TotalHours < 24)
return;
// 检查玩家是否已达到最大任务数
if (playerTasks.Count >= maxTasks)
return;
// 获取所有每日任务
TaskData[] allTasks = Resources.LoadAll("Tasks");
var dailyTasks = allTasks
.Where(t => t.isDailyTask &&
t.condition != 0 &&
!string.IsNullOrEmpty(t.id))
.ToArray();
if (dailyTasks.Length == 0)
return;
// 避免重复分配相同任务
int maxRetries = 3;
TaskData selectedTask = null;
HashSet triedTasks = new HashSet();
while (maxRetries-- > 0 && selectedTask == null)
{
// 随机选择一个任务
TaskData candidateTask = dailyTasks[random.Next(dailyTasks.Length)];
// 如果任务已经尝试过则跳过
if (triedTasks.Contains(candidateTask.id))
continue;
triedTasks.Add(candidateTask.id);
// 检查任务是否有效(未被玩家完成过或未在进度中)
if (!playerTasks.Any(pt => pt.taskId == candidateTask.id))
{
selectedTask = candidateTask;
break;
}
}
// 如果没有找到合适的任务则返回
if (selectedTask == null)
{
Debug.LogWarning("Failed to assign daily task after multiple retries");
return;
}
// 创建玩家任务实例
PlayerTask playerTask = new PlayerTask(selectedTask);
playerTasks.Add(playerTask);
lastDailyTaskAssigned = now;
SavePlayerData();
Debug.Log($"分配任务: {selectedTask.name}");
}
// 检查并更新过期任务
public void CheckExpiredTasks()
{
long now = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); // 当前时间戳(秒)
foreach (var task in playerTasks)
{
if (task.status == TaskStatus.Active && now > task.expireTime)
{
task.status = TaskStatus.Expired;
}
}
}
// 检查任务是否完成
public bool CheckTaskCompletion(PlayerTask task)
{
TaskData taskConfig = GetTaskConfig(task.taskId);
if (taskConfig == null)
return false;
return task.progress >= taskConfig.value1;
}
// 领取任务奖励
public bool ClaimTaskReward(PlayerTask task)
{
if (task.status != TaskStatus.Completed)
return false;
TaskData taskConfig = GetTaskConfig(task.taskId);
if (taskConfig == null)
return false;
// 发放奖励
for (int i = 0; i < taskConfig.rewardTypes.Length && i < taskConfig.rewardNums.Length; i++)
{
GiveReward(taskConfig.rewardTypes[i], taskConfig.rewardNums[i]);
}
task.status = TaskStatus.Claimed;
SavePlayerData();
return true;
}
private void GiveReward(TaskRewardType rewardType, int amount)
{
// 根据奖励类型发放奖励
switch (rewardType)
{
case TaskRewardType.Coins:
// 增加金币(需要与游戏现有金币系统集成)
UserData userData = Authenticator.Get().UserData;
if (userData != null)
{
userData.coins += amount;
Debug.Log($"Gave {amount} coins as reward");
// 保存用户数据更新
if (ApiClient.Get() != null && ApiClient.Get().IsLoggedIn())
{
Authenticator.Get().SaveUserData();
}
}
break;
}
}
private TaskData GetTaskConfig(string taskId)
{
TaskData[] allTasks = Resources.LoadAll("Tasks");
return allTasks.FirstOrDefault(t => t.id == taskId);
}
// 更新任务进度
private void UpdateTaskProgress(TaskConditionType conditionType, string parameter1 = null, string parameter2 = null)
{
bool progressUpdated = false;
refreshTaskUI?.Invoke(playerTasks);
foreach (var task in playerTasks)
{
if (task.status != TaskStatus.Active)
continue;
TaskData taskConfig = GetTaskConfig(task.taskId);
if (taskConfig == null || taskConfig.condition != conditionType)
continue;
bool shouldUpdate = false;
// 根据任务类型检查条件
switch (conditionType)
{
case TaskConditionType.LoginGame:
case TaskConditionType.PlayGames:
case TaskConditionType.WinGames:
// 这些任务类型直接增加进度
shouldUpdate = true;
break;
case TaskConditionType.DefeatHeroWithAttributes:
case TaskConditionType.SummonHeroWithAttributes:
case TaskConditionType.UseHeroSkillWithAttributes:
// 检查参数是否匹配(支持多个参数匹配)
if (!string.IsNullOrEmpty(parameter1) &&
(!string.IsNullOrEmpty(taskConfig.value2) && taskConfig.value2 == parameter1 ||
!string.IsNullOrEmpty(taskConfig.value3) && taskConfig.value3 == parameter1))
{
shouldUpdate = true;
}
else if (!string.IsNullOrEmpty(parameter2) &&
(!string.IsNullOrEmpty(taskConfig.value2) && taskConfig.value2 == parameter2 ||
!string.IsNullOrEmpty(taskConfig.value3) && taskConfig.value3 == parameter2))
{
shouldUpdate = true;
}
break;
}
if (shouldUpdate && task.progress < taskConfig.value1)
{
task.progress++;
progressUpdated = true;
// 检查任务是否完成
if (CheckTaskCompletion(task))
{
task.status = TaskStatus.Completed;
Debug.Log($"Task completed: {taskConfig.name}");
}
}
}
if (progressUpdated)
{
Debug.LogError("读到了");
SavePlayerData();
}
}
// 事件处理方法
private void OnGameStart()
{
// 进行对战任务进度+1
UpdateTaskProgress(TaskConditionType.PlayGames);
}
private void OnGameEnd(int winner)
{
int player_id = GameClient.Get().GetPlayerID();
// 胜利任务进度+1
if (winner == player_id)
{
UpdateTaskProgress(TaskConditionType.WinGames);
}
// 检查是否有任务完成并自动领取奖励
CheckAndClaimCompletedTasks();
}
private void OnCardPlayed(Card card, Slot slot)
{
// 召唤特定属性英雄任务
if (card.CardData.type == CardType.Character)
{
string cardCamp = card.CardData.camp.ToString();
UpdateTaskProgress(TaskConditionType.SummonHeroWithAttributes, cardCamp);
}
}
private void OnCardSummoned(Card card, Slot slot)
{
// 召唤特定属性英雄任务
if (card.CardData.type == CardType.Character)
{
string cardCamp = card.CardData.camp.ToString();
UpdateTaskProgress(TaskConditionType.SummonHeroWithAttributes, cardCamp);
}
}
private void OnAbilityUsed(AbilityData ability, Card caster)
{
// 使用特定属性英雄技能任务
string cardCamp = caster.CardData.camp.ToString();
UpdateTaskProgress(TaskConditionType.UseHeroSkillWithAttributes, cardCamp);
}
private void OnCardDiscarded(Card card)
{
// 击败特定属性英雄任务
if (card.CardData.type == CardType.Character)
{
string cardCamp = card.CardData.camp.ToString();
UpdateTaskProgress(TaskConditionType.DefeatHeroWithAttributes, cardCamp);
}
}
// 检查并自动领取已完成任务的奖励
public void CheckAndClaimCompletedTasks()
{
bool claimedAny = false;
foreach (var task in playerTasks)
{
if (task.status == TaskStatus.Completed)
{
if (ClaimTaskReward(task))
{
claimedAny = true;
}
}
}
if (claimedAny)
{
SavePlayerData();
}
}
// 玩家登录时检查任务
public void OnPlayerLogin()
{
// 检查是否已有登录任务
bool hasLoginTask = playerTasks.Any(t =>
{
TaskData config = GetTaskConfig(t.taskId);
return config != null && config.condition == TaskConditionType.LoginGame;
});
// 如果没有登录任务,就分配一个
if (!hasLoginTask)
{
AssignLoginTask();
}
// 登录任务完成
UpdateTaskProgress(TaskConditionType.LoginGame);
// 检查是否有任务完成并自动领取奖励
CheckAndClaimCompletedTasks();
// 分配每日任务(如果需要)
AssignDailyTaskIfNeeded();
}
///
/// 专门分配一个登录任务
///
private void AssignLoginTask()
{
TaskData[] 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 = DateTime.Now;
SavePlayerData();
Debug.Log($"分配登录任务: {loginTask.name}");
}
else
{
Debug.LogWarning("未找到登录任务配置!");
}
}
// 获取活跃任务
public List GetActiveTasks()
{
return playerTasks.Where(t => t.status == TaskStatus.Active).ToList();
}
// 获取已完成任务
public List GetCompletedTasks()
{
return playerTasks.Where(t => t.status == TaskStatus.Completed).ToList();
}
// 获取所有任务
public List GetAllTasks()
{
return playerTasks;
}
}
// 玩家任务保存数据结构
[Serializable]
public struct PlayerTaskSaveData
{
public PlayerTask[] tasks;
public DateTime lastDailyTaskAssigned;
}
}