using System;
using UnityEngine;
using UnityEditor;
namespace LocalMcp.UnityServer
{
/// <summary>
/// Monitors connection health and provides retry functionality
/// </summary>
public static class ConnectionHealthMonitor
{
private static DateTime lastHeartbeat = DateTime.Now;
private static int totalRequests = 0;
private static int successfulRequests = 0;
private static int failedRequests = 0;
private static bool isHealthy = true;
/// <summary>
/// Records a successful request
/// </summary>
public static void RecordSuccess()
{
totalRequests++;
successfulRequests++;
lastHeartbeat = DateTime.Now;
isHealthy = true;
}
/// <summary>
/// Records a failed request
/// </summary>
public static void RecordFailure()
{
totalRequests++;
failedRequests++;
lastHeartbeat = DateTime.Now;
// Mark as unhealthy if failure rate is high
if (totalRequests > 10 && failedRequests > totalRequests / 2)
{
isHealthy = false;
}
}
/// <summary>
/// Gets the current connection status
/// </summary>
public static string GetStatus(object id)
{
try
{
var result = new ConnectionStatusResult
{
isConnected = true, // Server is running
isHealthy = isHealthy,
lastHeartbeat = lastHeartbeat.ToString("yyyy-MM-dd HH:mm:ss"),
totalRequests = totalRequests,
successfulRequests = successfulRequests,
failedRequests = failedRequests,
uptime = GetUptime(),
serverPid = System.Diagnostics.Process.GetCurrentProcess().Id,
unityVersion = Application.unityVersion
};
var response = JsonRpcResponse.Success(result, id);
return response.ToJson();
}
catch (Exception e)
{
Debug.LogError($"[MCP] GetConnectionStatus error: {e.Message}\n{e.StackTrace}");
return JsonRpcResponseHelper.ErrorMessage($"Failed to get connection status: {e.Message}", id);
}
}
/// <summary>
/// Resets connection statistics
/// </summary>
public static string Reset(object id)
{
try
{
totalRequests = 0;
successfulRequests = 0;
failedRequests = 0;
isHealthy = true;
lastHeartbeat = DateTime.Now;
var result = new ConnectionResetResult
{
success = true,
message = "Connection statistics reset successfully"
};
var response = JsonRpcResponse.Success(result, id);
return response.ToJson();
}
catch (Exception e)
{
Debug.LogError($"[MCP] ResetConnection error: {e.Message}\n{e.StackTrace}");
return JsonRpcResponseHelper.ErrorMessage($"Failed to reset connection: {e.Message}", id);
}
}
/// <summary>
/// Performs a health check ping
/// </summary>
public static string Ping(object id)
{
try
{
lastHeartbeat = DateTime.Now;
var result = new ConnectionPingResult
{
success = true,
timestamp = lastHeartbeat.ToString("yyyy-MM-dd HH:mm:ss.fff"),
message = "Pong from Unity Editor"
};
var response = JsonRpcResponse.Success(result, id);
return response.ToJson();
}
catch (Exception e)
{
Debug.LogError($"[MCP] Ping error: {e.Message}\n{e.StackTrace}");
return JsonRpcResponseHelper.ErrorMessage($"Failed to ping: {e.Message}", id);
}
}
private static string GetUptime()
{
// EditorApplication.timeSinceStartup is in seconds (double)
double uptimeSeconds = EditorApplication.timeSinceStartup;
TimeSpan uptime = TimeSpan.FromSeconds(uptimeSeconds);
return $"{(int)uptime.TotalHours}h {uptime.Minutes}m {uptime.Seconds}s";
}
}
#region Data Structures
[Serializable]
public class ConnectionStatusResult
{
public bool isConnected;
public bool isHealthy;
public string lastHeartbeat;
public int totalRequests;
public int successfulRequests;
public int failedRequests;
public string uptime;
public int serverPid;
public string unityVersion;
}
[Serializable]
public class ConnectionResetResult
{
public bool success;
public string message;
}
[Serializable]
public class ConnectionPingResult
{
public bool success;
public string timestamp;
public string message;
}
#endregion
}