289 lines
8.3 KiB
C#
289 lines
8.3 KiB
C#
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();
|
|
}
|
|
} |