using System; using System.Text; using System.Collections; using UnityEngine; using UnityEngine.Networking; public class NetworkManager : MonoBehaviour { public static NetworkManager Instance { get; private set; } [Header("服务器配置")] public string baseUrl = "http://38.12.23.48:8080/api"; public float timeout = 30f; [Header("调试选项")] public bool enableDebugLog = true; private string authToken; private void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); if (baseUrl.Contains("localhost") || baseUrl.Contains("127.0.0.1")) { baseUrl = "http://38.12.23.48:8080/api"; Debug.Log($"[NetworkManager] baseUrl已更新为: {baseUrl}"); } } else { Destroy(gameObject); } } public void SetAuthToken(string token) { authToken = token; } public void ClearAuthToken() { authToken = null; } public IEnumerator PostRequest(string endpoint, object data, Action onSuccess, Action onError) { string url = baseUrl + endpoint; string jsonData = JsonUtility.ToJson(data); if (enableDebugLog) { Debug.Log($"[NetworkManager] POST 请求: {url}"); Debug.Log($"[NetworkManager] 请求数据: {jsonData}"); } UnityWebRequest request = new UnityWebRequest(url, "POST"); byte[] bodyRaw = Encoding.UTF8.GetBytes(jsonData); request.uploadHandler = new UploadHandlerRaw(bodyRaw); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.SetRequestHeader("Accept", "application/json"); if (!string.IsNullOrEmpty(authToken)) { request.SetRequestHeader("Authorization", $"Bearer {authToken}"); } request.timeout = (int)timeout; yield return request.SendWebRequest(); if (enableDebugLog) { Debug.Log($"[NetworkManager] 响应码: {request.responseCode}"); Debug.Log($"[NetworkManager] 响应内容: {request.downloadHandler?.text ?? "无内容"}"); Debug.Log($"[NetworkManager] 错误: {request.error ?? "无错误"}"); Debug.Log($"[NetworkManager] 结果类型: {request.result}"); } if (request.result == UnityWebRequest.Result.Success) { string responseText = request.downloadHandler.text; Debug.Log($"[NetworkManager] POST {endpoint} 成功: {responseText}"); try { T response = JsonUtility.FromJson(responseText); onSuccess?.Invoke(response); } catch (Exception e) { Debug.LogError($"[NetworkManager] 解析响应失败: {e.Message}, 原始响应: {responseText}"); onError?.Invoke($"解析响应失败: {e.Message}"); } } else { string errorMessage = request.error ?? "网络请求失败"; string responseText = request.downloadHandler?.text ?? ""; Debug.LogError($"[NetworkManager] POST {endpoint} 失败: {errorMessage}, 响应码: {request.responseCode}, 响应: {responseText}"); onError?.Invoke($"{errorMessage} (Code: {request.responseCode})"); } request.Dispose(); } public IEnumerator GetRequest(string endpoint, Action onSuccess, Action onError) { string url = baseUrl + endpoint; using (UnityWebRequest request = UnityWebRequest.Get(url)) { request.SetRequestHeader("Content-Type", "application/json"); if (!string.IsNullOrEmpty(authToken)) { request.SetRequestHeader("Authorization", $"Bearer {authToken}"); } request.timeout = (int)timeout; yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string responseText = request.downloadHandler.text; Debug.Log($"GET {endpoint} 响应: {responseText}"); try { T response = JsonUtility.FromJson(responseText); onSuccess?.Invoke(response); } catch (Exception e) { Debug.LogError($"解析响应失败: {e.Message}"); onError?.Invoke($"解析响应失败: {e.Message}"); } } else { string errorMessage = request.error ?? "网络请求失败"; Debug.LogError($"GET {endpoint} 失败: {errorMessage}"); onError?.Invoke(errorMessage); } } } public IEnumerator PutRequest(string endpoint, object data, Action onSuccess, Action onError) { string url = baseUrl + endpoint; string jsonData = JsonUtility.ToJson(data); using (UnityWebRequest request = UnityWebRequest.Put(url, jsonData)) { request.SetRequestHeader("Content-Type", "application/json"); if (!string.IsNullOrEmpty(authToken)) { request.SetRequestHeader("Authorization", $"Bearer {authToken}"); } request.timeout = (int)timeout; yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { string responseText = request.downloadHandler.text; Debug.Log($"PUT {endpoint} 响应: {responseText}"); try { T response = JsonUtility.FromJson(responseText); onSuccess?.Invoke(response); } catch (Exception e) { Debug.LogError($"解析响应失败: {e.Message}"); onError?.Invoke($"解析响应失败: {e.Message}"); } } else { string errorMessage = request.error ?? "网络请求失败"; Debug.LogError($"PUT {endpoint} 失败: {errorMessage}"); onError?.Invoke(errorMessage); } } } public void SaveGameSession(float playTime, int progress, int difficulty, System.Action onSuccess, System.Action onError) { GameSessionRequest request = new GameSessionRequest { playTime = playTime, progress = progress, difficulty = difficulty }; StartCoroutine(PostRequest("/game/session", request, onSuccess, onError)); } public void GetDifficultyConfig(System.Action onSuccess, System.Action onError) { StartCoroutine(GetRequest("/game/difficulty", onSuccess, onError)); } public void GetQuestionsByDifficulty(int difficulty, System.Action onSuccess, System.Action onError) { StartCoroutine(GetRequest($"/game/questions?difficulty={difficulty}", onSuccess, onError)); } public void SaveGameResult(GameResultRequest result, System.Action onSuccess, System.Action onError) { StartCoroutine(PostRequest("/game/result", result, onSuccess, onError)); } public void UpdateStudyAbility(int studyAbility, System.Action onSuccess, System.Action onError) { StudyAbilityRequest request = new StudyAbilityRequest { studyAbility = studyAbility }; StartCoroutine(PutRequest("/user/study-ability", request, onSuccess, onError)); } public void SyncAchievements(AchievementSyncRequest request, System.Action onSuccess, System.Action onError) { StartCoroutine(PostRequest("/achievements/sync", request, onSuccess, onError)); } public void GetAchievements(System.Action onSuccess, System.Action onError) { StartCoroutine(GetRequest("/achievements", onSuccess, onError)); } public void GetUserProfile(System.Action onSuccess, System.Action onError) { StartCoroutine(GetRequest("/user/profile", onSuccess, onError)); } public void ReportQuestionStats(int questionId, bool isCorrect, int difficulty, System.Action onSuccess, System.Action onError) { QuestionAttemptRequest request = new QuestionAttemptRequest { questionId = questionId, isCorrect = isCorrect, difficulty = difficulty, sourceType = "GAME" }; StartCoroutine(PostRequest("/questions/attempts", request, onSuccess, onError)); } public void UpdatePlayerLevel(int currentLevel, int experience, System.Action onSuccess, System.Action onError) { LevelUpRequest request = new LevelUpRequest { currentLevel = currentLevel, experience = experience }; StartCoroutine(PutRequest("/user/level", request, onSuccess, onError)); } public void GetReviewQuestions(int difficulty, System.Action onSuccess, System.Action onError) { StartCoroutine(GetRequest($"/game/review-questions?difficulty={difficulty}", onSuccess, onError)); } public void AddQuestionToReview(int questionId, System.Action onSuccess, System.Action onError) { AddReviewQuestionRequest request = new AddReviewQuestionRequest { questionId = questionId }; StartCoroutine(PostRequest("/game/review-questions/add", request, onSuccess, onError)); } }