Files
AIGame/AIClient/Assets/Editor/UI/LocalServerAutoStart.cs

75 lines
3.2 KiB
C#

#if UNITY_EDITOR
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using AOT.Boot;
using UnityEditor;
using UnityEngine;
namespace AIGame.EditorTools
{
/// <summary>仅在 Boot 配置为本机 AIServer 时,进入 Play Mode 前启动已有服务。</summary>
[InitializeOnLoad]
public static class LocalServerAutoStart
{
[Serializable] class Health { public bool ok; public string service; }
static LocalServerAutoStart()
{
EditorApplication.playModeStateChanged += state =>
{
if (state != PlayModeStateChange.ExitingEditMode) return;
var boot = UnityEngine.Object.FindObjectOfType<BootDriver>();
if (boot == null) return;
var settings = new SerializedObject(boot).FindProperty("settings");
if (settings.FindPropertyRelative("HttpBase").stringValue.TrimEnd('/') != "http://127.0.0.1:8080") return;
try { UnityEngine.Debug.Log("[LocalAIServer] " + StartLocal()); }
catch (Exception e) { UnityEngine.Debug.LogWarning("[LocalAIServer] " + e.Message); }
};
}
static bool IsHealthy()
{
try
{
var request = (HttpWebRequest)WebRequest.Create("http://127.0.0.1:8080/health");
request.Timeout = 250; request.ReadWriteTimeout = 250; request.Proxy = null;
using (var response = request.GetResponse())
using (var reader = new StreamReader(response.GetResponseStream()))
{
var health = JsonUtility.FromJson<Health>(reader.ReadToEnd());
return health != null && health.ok && health.service == "aiserver";
}
}
catch { return false; }
}
[MenuItem("AIGame/Boot/Server/Start Local AIServer")]
public static string StartLocal()
{
if (IsHealthy()) return "already healthy at 127.0.0.1:8080";
string repo = Directory.GetParent(Application.dataPath).Parent.FullName;
string exe = Path.Combine(repo, "AIServer/build/Release/aiserver.exe");
if (!File.Exists(exe)) throw new FileNotFoundException("Build AIServer first: cmake --build AIServer/build --config Release", exe);
var info = new ProcessStartInfo(exe)
{
Arguments = "--host 127.0.0.1 --port 8080 --daemon --db \"" + Path.Combine(repo, "AIServer/data/aiserver.db") + "\"",
WorkingDirectory = Path.Combine(repo, "AIServer"),
UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden
};
using (var process = Process.Start(info))
{
for (int i = 0; i < 15; i++)
{
System.Threading.Thread.Sleep(100);
if (IsHealthy()) return "started at 127.0.0.1:8080";
if (process.HasExited) throw new Exception("Local AIServer exited; check port 8080 and the database path.");
}
}
throw new Exception("Local AIServer did not become healthy; theme preview remains available without login.");
}
}
}
#endif