319 lines
9.7 KiB
C#
319 lines
9.7 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using Newtonsoft.Json;
|
|
|
|
public class AvatarDataDownloader : MonoBehaviour
|
|
{
|
|
[Header("Server Configuration")]
|
|
[SerializeField] private string serverHost = "127.0.0.1";
|
|
[SerializeField] private int serverPort = 8080;
|
|
[SerializeField] private bool useGlobalNetworkConfig = true;
|
|
[SerializeField] private NetworkConfig networkConfigAsset;
|
|
[SerializeField] private string targetPlayer = "player1"; // Which player data to fetch
|
|
|
|
[Header("Download Configuration")]
|
|
[SerializeField] private bool autoDownload = true;
|
|
[SerializeField] private float downloadInterval = 0.1f; // How often to fetch data (in seconds)
|
|
[SerializeField] private string localFileName = ""; // Leave empty to use targetPlayer name
|
|
|
|
[Header("Debug")]
|
|
[SerializeField] private bool enableDebugMode = false;
|
|
[SerializeField] private bool showConnectionStatus = true;
|
|
|
|
private string syncFilesPath;
|
|
private string outputFilePath;
|
|
private Coroutine downloadCoroutine;
|
|
private bool isConnected = false;
|
|
private float lastSuccessfulDownload = 0f;
|
|
private int totalDownloads = 0;
|
|
private int successfulDownloads = 0;
|
|
|
|
// Connection status
|
|
public bool IsConnected => isConnected;
|
|
public string ServerUrl => $"http://{serverHost}:{serverPort}";
|
|
public float LastDownloadTime => lastSuccessfulDownload;
|
|
public float SuccessRate => totalDownloads > 0 ? (float)successfulDownloads / totalDownloads : 0f;
|
|
|
|
void Start()
|
|
{
|
|
// Apply global config if enabled
|
|
if (useGlobalNetworkConfig)
|
|
{
|
|
var cfg = networkConfigAsset != null ? networkConfigAsset : NetworkConfig.Instance;
|
|
if (cfg != null)
|
|
{
|
|
serverHost = cfg.ipAddress;
|
|
serverPort = cfg.port;
|
|
}
|
|
}
|
|
// Set up file paths
|
|
syncFilesPath = Path.Combine(Application.dataPath, "Sync-Files");
|
|
if (!Directory.Exists(syncFilesPath))
|
|
{
|
|
Directory.CreateDirectory(syncFilesPath);
|
|
}
|
|
|
|
// Determine output file name
|
|
string fileName = string.IsNullOrEmpty(localFileName) ? $"{targetPlayer}.json" : localFileName;
|
|
outputFilePath = Path.Combine(syncFilesPath, fileName);
|
|
|
|
Debug.Log($"Avatar Data Downloader initialized");
|
|
Debug.Log($"Server: {ServerUrl}");
|
|
Debug.Log($"Target Player: {targetPlayer}");
|
|
Debug.Log($"Output File: {outputFilePath}");
|
|
|
|
// Start downloading if auto-download is enabled
|
|
if (autoDownload)
|
|
{
|
|
StartDownload();
|
|
}
|
|
|
|
// Test connection
|
|
StartCoroutine(TestConnection());
|
|
}
|
|
|
|
void OnValidate()
|
|
{
|
|
// Ensure valid values
|
|
if (downloadInterval < 0.01f)
|
|
downloadInterval = 0.01f;
|
|
|
|
if (serverPort < 1 || serverPort > 65535)
|
|
serverPort = 8080;
|
|
}
|
|
|
|
public void StartDownload()
|
|
{
|
|
if (downloadCoroutine == null)
|
|
{
|
|
downloadCoroutine = StartCoroutine(DownloadLoop());
|
|
Debug.Log("Avatar download started");
|
|
}
|
|
}
|
|
|
|
public void StopDownload()
|
|
{
|
|
if (downloadCoroutine != null)
|
|
{
|
|
StopCoroutine(downloadCoroutine);
|
|
downloadCoroutine = null;
|
|
Debug.Log("Avatar download 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 DownloadLoop()
|
|
{
|
|
while (true)
|
|
{
|
|
yield return StartCoroutine(FetchPlayerData());
|
|
yield return new WaitForSeconds(downloadInterval);
|
|
}
|
|
}
|
|
|
|
IEnumerator FetchPlayerData()
|
|
{
|
|
string url = $"{ServerUrl}/{targetPlayer}";
|
|
totalDownloads++;
|
|
|
|
using (UnityWebRequest request = UnityWebRequest.Get(url))
|
|
{
|
|
request.timeout = 10; // 10 second timeout
|
|
|
|
yield return request.SendWebRequest();
|
|
|
|
if (request.result == UnityWebRequest.Result.Success)
|
|
{
|
|
// Try to validate JSON structure
|
|
bool isValidData = false;
|
|
float dataTimestamp = 0f;
|
|
|
|
try
|
|
{
|
|
var avatarData = JsonConvert.DeserializeObject<AvatarSyncData>(request.downloadHandler.text);
|
|
isValidData = avatarData != null;
|
|
dataTimestamp = avatarData?.timestamp ?? 0f;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"Error parsing avatar data for {targetPlayer}: {e.Message}");
|
|
isValidData = false;
|
|
}
|
|
|
|
if (isValidData)
|
|
{
|
|
// Write to local file
|
|
File.WriteAllText(outputFilePath, request.downloadHandler.text);
|
|
|
|
successfulDownloads++;
|
|
lastSuccessfulDownload = Time.time;
|
|
isConnected = true;
|
|
|
|
if (enableDebugMode)
|
|
{
|
|
Debug.Log($"Successfully fetched and saved data for {targetPlayer}. Timestamp: {dataTimestamp}");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (enableDebugMode)
|
|
{
|
|
Debug.LogWarning($"Received invalid avatar data for {targetPlayer}");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
isConnected = false;
|
|
if (enableDebugMode)
|
|
{
|
|
Debug.LogWarning($"Failed to fetch data for {targetPlayer}: {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 SetTargetPlayer(string player)
|
|
{
|
|
targetPlayer = player;
|
|
|
|
// Update output file path
|
|
string fileName = string.IsNullOrEmpty(localFileName) ? $"{targetPlayer}.json" : localFileName;
|
|
outputFilePath = Path.Combine(syncFilesPath, fileName);
|
|
}
|
|
|
|
public void ManualDownload()
|
|
{
|
|
if (gameObject.activeInHierarchy)
|
|
{
|
|
StartCoroutine(FetchPlayerData());
|
|
}
|
|
}
|
|
|
|
// Get current stats for UI display
|
|
public string GetDownloadStats()
|
|
{
|
|
return $"Connected: {isConnected}\n" +
|
|
$"Success Rate: {(SuccessRate * 100):F1}%\n" +
|
|
$"Total Downloads: {totalDownloads}\n" +
|
|
$"Last Download: {(Time.time - lastSuccessfulDownload):F1}s ago";
|
|
}
|
|
|
|
// Check if the output file exists and has recent data
|
|
public bool HasRecentData(float maxAgeSeconds = 5f)
|
|
{
|
|
if (!File.Exists(outputFilePath))
|
|
return false;
|
|
|
|
try
|
|
{
|
|
FileInfo fileInfo = new FileInfo(outputFilePath);
|
|
return (DateTime.Now - fileInfo.LastWriteTime).TotalSeconds < maxAgeSeconds;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void OnDisable()
|
|
{
|
|
StopDownload();
|
|
}
|
|
|
|
void OnDestroy()
|
|
{
|
|
StopDownload();
|
|
}
|
|
|
|
// GUI for runtime debugging
|
|
void OnGUI()
|
|
{
|
|
if (!enableDebugMode)
|
|
return;
|
|
|
|
GUILayout.BeginArea(new Rect(320, 10, 300, 180));
|
|
GUILayout.BeginVertical("box");
|
|
|
|
GUILayout.Label($"Avatar Downloader - {targetPlayer}");
|
|
GUILayout.Label($"Server: {ServerUrl}");
|
|
GUILayout.Label($"Status: {(isConnected ? "Connected" : "Disconnected")}");
|
|
GUILayout.Label($"Success Rate: {(SuccessRate * 100):F1}%");
|
|
GUILayout.Label($"Last Download: {(Time.time - lastSuccessfulDownload):F1}s ago");
|
|
|
|
GUILayout.BeginHorizontal();
|
|
if (GUILayout.Button("Manual Download"))
|
|
{
|
|
ManualDownload();
|
|
}
|
|
if (GUILayout.Button("Test Connection"))
|
|
{
|
|
StartCoroutine(TestConnection());
|
|
}
|
|
GUILayout.EndHorizontal();
|
|
|
|
if (downloadCoroutine == null)
|
|
{
|
|
if (GUILayout.Button("Start Auto Download"))
|
|
{
|
|
StartDownload();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GUILayout.Button("Stop Auto Download"))
|
|
{
|
|
StopDownload();
|
|
}
|
|
}
|
|
|
|
GUILayout.EndVertical();
|
|
GUILayout.EndArea();
|
|
}
|
|
} |