using System; using System.Collections; using System.IO; using UnityEngine; using UnityEngine.Networking; public class AvatarDataUploader : MonoBehaviour { [Header("Server Configuration")] [SerializeField] private string serverHost = "127.0.0.1"; [SerializeField] private int serverPort = 8080; [SerializeField] private string uploadAsPlayer = "player1"; // Upload as which player [Header("Upload Configuration")] [SerializeField] private bool autoUpload = true; [SerializeField] private float uploadInterval = 0.1f; // How often to upload data (in seconds) [SerializeField] private string localDataFile = "avatar_sync_data.json"; // Local file to upload [Header("Debug")] [SerializeField] private bool enableDebugMode = false; [SerializeField] private bool showConnectionStatus = true; private string syncFilesPath; private Coroutine uploadCoroutine; private bool isConnected = false; private float lastSuccessfulUpload = 0f; private int totalUploads = 0; private int successfulUploads = 0; // Connection status public bool IsConnected => isConnected; public string ServerUrl => $"http://{serverHost}:{serverPort}"; public float LastUploadTime => lastSuccessfulUpload; public float SuccessRate => totalUploads > 0 ? (float)successfulUploads / totalUploads : 0f; void Start() { // Set up file paths syncFilesPath = Path.Combine(Application.dataPath, "Sync-Files"); if (!Directory.Exists(syncFilesPath)) { Directory.CreateDirectory(syncFilesPath); } Debug.Log($"Avatar Data Uploader initialized"); Debug.Log($"Server: {ServerUrl}"); Debug.Log($"Upload As Player: {uploadAsPlayer}"); Debug.Log($"Local Data File: {localDataFile}"); // Start uploading if auto-upload is enabled if (autoUpload) { StartUpload(); } // Test connection StartCoroutine(TestConnection()); } void OnValidate() { // Ensure valid values if (uploadInterval < 0.01f) uploadInterval = 0.01f; if (serverPort < 1 || serverPort > 65535) serverPort = 8080; } public void StartUpload() { if (uploadCoroutine == null) { uploadCoroutine = StartCoroutine(UploadLoop()); Debug.Log("Avatar upload started"); } } public void StopUpload() { if (uploadCoroutine != null) { StopCoroutine(uploadCoroutine); uploadCoroutine = null; Debug.Log("Avatar upload stopped"); } } IEnumerator TestConnection() { string url = $"{ServerUrl}/status"; using (UnityWebRequest request = UnityWebRequest.Get(url)) { request.timeout = 5; // 5 second timeout for connection test yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { isConnected = true; if (showConnectionStatus) { Debug.Log($"Successfully connected to avatar sync server at {ServerUrl}"); } if (enableDebugMode) { Debug.Log($"Server status: {request.downloadHandler.text}"); } } else { isConnected = false; if (showConnectionStatus) { Debug.LogWarning($"Failed to connect to avatar sync server at {ServerUrl}: {request.error}"); } } } } IEnumerator UploadLoop() { while (true) { yield return StartCoroutine(UploadLocalData()); yield return new WaitForSeconds(uploadInterval); } } IEnumerator UploadLocalData() { string localFilePath = Path.Combine(syncFilesPath, localDataFile); if (!File.Exists(localFilePath)) { if (enableDebugMode) { Debug.LogWarning($"Local data file not found: {localFilePath}"); } yield break; } string jsonData = null; // Read file outside of try block with yield try { jsonData = File.ReadAllText(localFilePath); } catch (Exception e) { Debug.LogError($"Error reading local data file: {e.Message}"); yield break; } if (string.IsNullOrEmpty(jsonData)) { if (enableDebugMode) { Debug.LogWarning("Local avatar data is empty, skipping upload"); } yield break; } // Upload to server string url = $"{ServerUrl}/{uploadAsPlayer}"; totalUploads++; using (UnityWebRequest request = new UnityWebRequest(url, "POST")) { byte[] jsonBytes = System.Text.Encoding.UTF8.GetBytes(jsonData); request.uploadHandler = new UploadHandlerRaw(jsonBytes); request.downloadHandler = new DownloadHandlerBuffer(); request.SetRequestHeader("Content-Type", "application/json"); request.timeout = 10; yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { successfulUploads++; lastSuccessfulUpload = Time.time; isConnected = true; if (enableDebugMode) { Debug.Log($"Successfully uploaded data as {uploadAsPlayer}"); } } else { isConnected = false; if (enableDebugMode) { Debug.LogWarning($"Failed to upload data as {uploadAsPlayer}: {request.error}"); } } } } // Public methods for runtime control public void SetServerAddress(string host, int port) { serverHost = host; serverPort = port; // Test new connection StartCoroutine(TestConnection()); } public void SetUploadPlayer(string player) { uploadAsPlayer = player; } public void ManualUpload() { if (gameObject.activeInHierarchy) { StartCoroutine(UploadLocalData()); } } // Get current stats for UI display public string GetUploadStats() { return $"Connected: {isConnected}\n" + $"Success Rate: {(SuccessRate * 100):F1}%\n" + $"Total Uploads: {totalUploads}\n" + $"Last Upload: {(Time.time - lastSuccessfulUpload):F1}s ago"; } void OnDisable() { StopUpload(); } void OnDestroy() { StopUpload(); } // GUI for runtime debugging void OnGUI() { if (!enableDebugMode) return; GUILayout.BeginArea(new Rect(10, 10, 300, 180)); GUILayout.BeginVertical("box"); GUILayout.Label($"Avatar Uploader - {uploadAsPlayer}"); GUILayout.Label($"Server: {ServerUrl}"); GUILayout.Label($"Status: {(isConnected ? "Connected" : "Disconnected")}"); GUILayout.Label($"Success Rate: {(SuccessRate * 100):F1}%"); GUILayout.Label($"Last Upload: {(Time.time - lastSuccessfulUpload):F1}s ago"); GUILayout.BeginHorizontal(); if (GUILayout.Button("Manual Upload")) { ManualUpload(); } if (GUILayout.Button("Test Connection")) { StartCoroutine(TestConnection()); } GUILayout.EndHorizontal(); if (uploadCoroutine == null) { if (GUILayout.Button("Start Auto Upload")) { StartUpload(); } } else { if (GUILayout.Button("Stop Auto Upload")) { StopUpload(); } } GUILayout.EndVertical(); GUILayout.EndArea(); } }