// XERON Engine Plugin for Unity Editor // Version: 1.0.0 // Window > XERON Engine — connect to xeron-labs.com to receive AI-generated C# code using System; using System.IO; using System.Text; using System.Threading.Tasks; using System.Collections.Generic; using UnityEditor; using UnityEngine; using UnityEngine.Networking; namespace XeronEngine { public class XeronEditorWindow : EditorWindow { private const string BASE_URL = "https://www.xeron-labs.com/api/plugin"; private const string PREF_TOKEN = "XERON_Token"; private const string PREF_EMAIL = "XERON_Email"; private const string PREF_PLAN = "XERON_Plan"; private const string PREF_CREDITS = "XERON_Credits"; private const double POLL_INTERVAL = 3.0; private string sessionToken = ""; private string userEmail = ""; private string userPlan = "free"; private int userCredits = 0; private bool isConnected = false; private bool isConnecting = false; private string codeInput = ""; private string statusMessage = "Waiting for code from website..."; private string errorMessage = ""; private double lastPollTime = 0; private Vector2 logScroll; [MenuItem("Window/XERON Engine")] public static void ShowWindow() { var win = GetWindow("XERON Engine"); win.minSize = new Vector2(280, 420); } private void OnEnable() { sessionToken = EditorPrefs.GetString(PREF_TOKEN, ""); userEmail = EditorPrefs.GetString(PREF_EMAIL, ""); userPlan = EditorPrefs.GetString(PREF_PLAN, "free"); userCredits = EditorPrefs.GetInt(PREF_CREDITS, 0); isConnected = !string.IsNullOrEmpty(sessionToken); EditorApplication.update += OnUpdate; } private void OnDisable() { EditorApplication.update -= OnUpdate; } private void OnUpdate() { if (!isConnected || string.IsNullOrEmpty(sessionToken)) return; if (EditorApplication.timeSinceStartup - lastPollTime < POLL_INTERVAL) return; lastPollTime = EditorApplication.timeSinceStartup; _ = PollAsync(); } private void OnGUI() { GUILayout.Space(8); // Header var headerStyle = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = FontStyle.Bold, normal = { textColor = Color.white }, }; GUILayout.Label("XERON Engine", headerStyle); GUILayout.Space(6); if (!isConnected) DrawConnectScreen(); else DrawHomeScreen(); } // ── CONNECT SCREEN ──────────────────────────────────────────────────── private void DrawConnectScreen() { var subStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, normal = { textColor = new Color(0.63f, 0.72f, 0.8f) }, wordWrap = true, }; GUILayout.Label("Enter your 6-digit connection code:", subStyle); GUILayout.Space(8); var inputStyle = new GUIStyle(GUI.skin.textField) { fontSize = 18, alignment = TextAnchor.MiddleCenter, normal = { textColor = new Color(0.93f, 0.67f, 0.09f) }, }; codeInput = EditorGUILayout.TextField(codeInput.ToUpper(), inputStyle, GUILayout.Height(38)); if (codeInput.Length > 6) codeInput = codeInput.Substring(0, 6); GUILayout.Space(8); GUI.enabled = !isConnecting && codeInput.Length == 6; var btnStyle = new GUIStyle(GUI.skin.button) { fontSize = 13, fontStyle = FontStyle.Bold }; if (GUILayout.Button(isConnecting ? "Connecting..." : "Connect to XERON", btnStyle, GUILayout.Height(38))) _ = ConnectAsync(); GUI.enabled = true; if (!string.IsNullOrEmpty(errorMessage)) { GUILayout.Space(6); EditorGUILayout.HelpBox(errorMessage, MessageType.Error); } GUILayout.Space(14); var linkStyle = new GUIStyle(GUI.skin.label) { fontSize = 10, normal = { textColor = new Color(0.4f, 0.6f, 1f) } }; GUILayout.Label("Get this plugin at: xeron-labs.com/download", linkStyle); } // ── HOME SCREEN ─────────────────────────────────────────────────────── private void DrawHomeScreen() { var connStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, fontStyle = FontStyle.Bold, normal = { textColor = new Color(0f, 0.8f, 0.47f) }, }; GUILayout.Label("● Connected to XERON", connStyle); GUILayout.Space(4); var infoStyle = new GUIStyle(GUI.skin.label) { fontSize = 11, normal = { textColor = new Color(0.63f, 0.72f, 0.8f) } }; GUILayout.Label(userEmail, infoStyle); GUILayout.Label("Plan: " + userPlan, infoStyle); GUILayout.Label("Credits: " + userCredits, infoStyle); GUILayout.Space(10); EditorGUILayout.HelpBox(statusMessage, MessageType.None); GUILayout.Space(10); var discStyle = new GUIStyle(GUI.skin.button) { fontSize = 11, normal = { textColor = new Color(1f, 0.4f, 0.4f) } }; if (GUILayout.Button("Disconnect", discStyle)) Disconnect(); } // ── LOGIC ───────────────────────────────────────────────────────────── private async Task ConnectAsync() { isConnecting = true; errorMessage = ""; isConnecting = true; Repaint(); try { var body = $"{{\"code\":\"{codeInput.ToUpper()}\",\"platform\":\"unity\"}}"; var req = new UnityWebRequest(BASE_URL + "/connect", "POST"); req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body)); req.downloadHandler = new DownloadHandlerBuffer(); req.SetRequestHeader("Content-Type", "application/json"); req.SendWebRequest(); while (!req.isDone) await Task.Yield(); if (req.result == UnityWebRequest.Result.Success) { var data = JsonUtility.FromJson(req.downloadHandler.text); if (data != null && !string.IsNullOrEmpty(data.token)) { sessionToken = data.token; userEmail = data.user?.email ?? ""; userPlan = data.user?.plan ?? "free"; userCredits = data.user?.credits ?? 0; EditorPrefs.SetString(PREF_TOKEN, sessionToken); EditorPrefs.SetString(PREF_EMAIL, userEmail); EditorPrefs.SetString(PREF_PLAN, userPlan); EditorPrefs.SetInt (PREF_CREDITS, userCredits); isConnected = true; statusMessage = "Waiting for code from website..."; errorMessage = ""; } else { errorMessage = "Invalid code. Please try again."; } } else { errorMessage = "Connection failed: " + req.error; } } catch (Exception ex) { errorMessage = "Error: " + ex.Message; } isConnecting = false; Repaint(); } private async Task PollAsync() { try { var req = UnityWebRequest.Get(BASE_URL + "/pending"); req.SetRequestHeader("X-Session-Token", sessionToken); req.SendWebRequest(); while (!req.isDone) await Task.Yield(); if (req.result != UnityWebRequest.Result.Success) return; var data = JsonUtility.FromJson(req.downloadHandler.text); if (data?.pending == null || data.pending.Count == 0) return; foreach (var item in data.pending) { InsertCode(item.code, item.file_name, item.id); } } catch { /* silent — poll failures are non-fatal */ } } private void InsertCode(string code, string fileName, string insertionId) { try { string dir = Path.Combine(Application.dataPath, "XeronGenerated"); Directory.CreateDirectory(dir); string clean = string.IsNullOrEmpty(fileName) ? "XeronGenerated" : fileName.Replace(".cs", ""); string path = Path.Combine(dir, clean + ".cs"); File.WriteAllText(path, code, Encoding.UTF8); AssetDatabase.Refresh(); statusMessage = "✓ Inserted: " + clean + ".cs"; ShowNotification(new GUIContent("XERON: Code inserted → " + clean + ".cs")); Repaint(); _ = ConfirmAsync(insertionId); } catch (Exception ex) { statusMessage = "✗ Insert failed: " + ex.Message; Repaint(); } } private async Task ConfirmAsync(string insertionId) { try { var body = $"{{\"insertion_id\":\"{insertionId}\"}}"; var req = new UnityWebRequest(BASE_URL + "/confirm", "POST"); req.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(body)); req.downloadHandler = new DownloadHandlerBuffer(); req.SetRequestHeader("Content-Type", "application/json"); req.SendWebRequest(); while (!req.isDone) await Task.Yield(); } catch { /* silent */ } } private void Disconnect() { sessionToken = ""; userEmail = ""; userPlan = "free"; userCredits = 0; isConnected = false; codeInput = ""; EditorPrefs.DeleteKey(PREF_TOKEN); EditorPrefs.DeleteKey(PREF_EMAIL); EditorPrefs.DeleteKey(PREF_PLAN); EditorPrefs.DeleteKey(PREF_CREDITS); statusMessage = "Waiting for code from website..."; Repaint(); } // ── JSON models ─────────────────────────────────────────────────────── [Serializable] private class ConnectResponse { public string token; public UserInfo user; } [Serializable] private class UserInfo { public string email; public string plan; public int credits; } [Serializable] private class PendingResponse { public List pending; } [Serializable] private class PendingItem { public string id; public string code; public string file_name; public string language; } } }