// File: MainForm.cs using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Text.Json.Nodes; using System.Windows.Forms; namespace AI_C2_Server { public partial class MainForm : Form { [DllImport("user32.dll", SetLastError = true)] public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab); public MainForm() { InitializeComponent(); Logger.LogReceived += Logger_LogReceived; } private void MainForm_Load(object sender, EventArgs e) { notifyIcon.Visible = false; // Load initial OpenAI settings chkEnableOpenAI.Checked = OperationCenter.Instance.UseOpenAIMode; txtOpenAIUrl.Text = OperationCenter.Instance.OpenAIApiUrl; txtOpenAIKey.Text = OperationCenter.Instance.OpenAIApiKey; WebServer.Instance.Start(); timerUpdateInstances.Start(); this.Deactivate += MainForm_Deactivate; } private void MainForm_Deactivate(object? sender, EventArgs e) { if (!this.Disposing && !this.IsDisposed) { notifyIcon?.Visible = true; this.Hide(); } } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { timerUpdateInstances.Stop(); WebServer.Instance.Stop(); } private void Logger_LogReceived(string message) { if (rtbConsole.InvokeRequired) { rtbConsole.Invoke(new Action(() => Logger_LogReceived(message))); return; } rtbConsole.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}" + Environment.NewLine); if (rtbConsole.Lines.Length > 1000) { int excessLines = rtbConsole.Lines.Length - 1000; int indexToCut = rtbConsole.GetFirstCharIndexFromLine(excessLines); rtbConsole.Select(0, indexToCut); rtbConsole.SelectedText = ""; } rtbConsole.ScrollToCaret(); } private void RestartServer() { Logger.Log("[SYSTEM] Restarting server and clearing state..."); WebServer.Instance.Stop(); OperationCenter.Instance.ClearAll(); listViewInstances.Items.Clear(); // Reset UI state for OpenAI chkEnableOpenAI.Checked = false; WebServer.Instance.Start(); } private void btnRestart_Click(object sender, EventArgs e) { RestartServer(); } private void MainForm_Resize(object sender, EventArgs e) { if (this.WindowState == FormWindowState.Minimized) { notifyIcon.Visible = true; this.Hide(); } } private void notifyIcon_MouseDoubleClick(object sender, MouseEventArgs e) { RestoreForm(); } private void notifyIcon_Click(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { RestoreForm(); } } private void showServerToolStripMenuItem_Click(object sender, EventArgs e) { RestoreForm(); } private void RestoreForm() { this.Show(); //this.WindowState = FormWindowState.Normal; this.BringToFront(); notifyIcon.Visible = false; SwitchToThisWindow(this.Handle, true); } private void restartServerToolStripMenuItem_Click(object sender, EventArgs e) { RestartServer(); } private void exitShutdownToolStripMenuItem_Click(object sender, EventArgs e) { WebServer.Instance.Stop(); OperationCenter.Instance.ClearAll(); Close(); } private void timerUpdateInstances_Tick(object sender, EventArgs e) { var instances = OperationCenter.Instance.GetActiveInstances(); listViewInstances.BeginUpdate(); // Remove stale items var keysToRemove = new List(); foreach (ListViewItem item in listViewInstances.Items) { if (!instances.ContainsKey(item.Name)) keysToRemove.Add(item); } foreach (var item in keysToRemove) listViewInstances.Items.Remove(item); // Add or update items foreach (var kvp in instances) { string id = kvp.Key; var data = kvp.Value as JsonObject; string platform = data?["platform"]?.ToString() ?? "Unknown"; string status = (data?["is_busy"]?.GetValue() ?? false) ? "Busy" : "Idle"; DateTime lastSeenTime; string lastSeenStr = data?["last_seen"]?.ToString() ?? ""; if (DateTime.TryParse(lastSeenStr, out lastSeenTime)) { lastSeenStr = lastSeenTime.ToString("HH:mm:ss"); } if (listViewInstances.Items.ContainsKey(id)) { var item = listViewInstances.Items[id]; item.SubItems[0].Text = platform; item.SubItems[1].Text = id; item.SubItems[2].Text = status; item.SubItems[3].Text = lastSeenStr; } else { var item = new ListViewItem(new[] { platform, id, status, lastSeenStr }) { Name = id }; listViewInstances.Items.Add(item); } } listViewInstances.EndUpdate(); // Keep the checkbox in sync if the OpenAI instance was shut down via the list view if (chkEnableOpenAI.Checked && !OperationCenter.Instance.UseOpenAIMode) { chkEnableOpenAI.Checked = false; } } private void ResetSelectedInstanceChat() { if (listViewInstances.SelectedItems.Count > 0) { string instanceId = listViewInstances.SelectedItems[0].Name; if (OperationCenter.Instance.IsOpenAIInstance(instanceId)) { OperationCenter.Instance.ClearChatHistory(instanceId); Logger.Log($"[ADMIN] Reset chat history for OpenAI instance {instanceId}"); } else { OperationCenter.Instance.QueueCommand(new JsonObject { ["type"] = "NEW_CHAT" }, instanceId); Logger.Log($"[ADMIN] Sent NEW_CHAT command to {instanceId}"); } } } private void ShutdownSelectedInstance() { if (listViewInstances.SelectedItems.Count > 0) { string instanceId = listViewInstances.SelectedItems[0].Name; OperationCenter.Instance.ShutdownInstance(instanceId); Logger.Log($"[ADMIN] Sent SHUTDOWN command to {instanceId} and removed from active list."); listViewInstances.Items.RemoveByKey(instanceId); } } private void btnResetChat_Click(object sender, EventArgs e) { ResetSelectedInstanceChat(); } private void btnShutdown_Click(object sender, EventArgs e) { ShutdownSelectedInstance(); } private void resetChatToolStripMenuItem_Click(object sender, EventArgs e) { ResetSelectedInstanceChat(); } private void shutdownHarnessToolStripMenuItem_Click(object sender, EventArgs e) { ShutdownSelectedInstance(); } private void chkEnableOpenAI_CheckedChanged(object sender, EventArgs e) { if (chkEnableOpenAI.Checked) { OperationCenter.Instance.EnableOpenAIMode(txtOpenAIUrl.Text, txtOpenAIKey.Text); Logger.Log($"[SYSTEM] OpenAI API Mode: Enabled"); } else { OperationCenter.Instance.DisableOpenAIMode(); Logger.Log($"[SYSTEM] OpenAI API Mode: Disabled"); } } private void txtOpenAIUrl_TextChanged(object sender, EventArgs e) { if (OperationCenter.Instance.UseOpenAIMode) { OperationCenter.Instance.OpenAIApiUrl = txtOpenAIUrl.Text; OperationCenter.Instance.UpdateOpenAIUrl(txtOpenAIUrl.Text); } } private void txtOpenAIKey_TextChanged(object sender, EventArgs e) { if (OperationCenter.Instance.UseOpenAIMode) { OperationCenter.Instance.OpenAIApiKey = txtOpenAIKey.Text; } } private void restartApplicationToolStripMenuItem_Click(object sender, EventArgs e) { // Start a new instance of the current executable Process.Start(new ProcessStartInfo { FileName = Environment.ProcessPath, UseShellExecute = true }); WebServer.Instance.Stop(); OperationCenter.Instance.ClearAll(); Close(); } } }