using System.Diagnostics; namespace ThreatSource.Tools.MissileSimulation { class Program { static void Main(string[] args) { Console.WriteLine("综合导弹模拟程序启动..."); var simulator = new ComprehensiveMissileSimulator(); // 如果需要,可以在启动时设置默认日志级别,或依赖Simulator的默认值 simulator.SetLogLevel(SourceLevels.Verbose); ApplicationHostLoop(simulator); Console.WriteLine("\n程序已退出。"); } static void ApplicationHostLoop(ComprehensiveMissileSimulator simulator) { bool exitProgram = false; while (!exitProgram) { Console.WriteLine("\n=== 导弹仿真系统主菜单 ==="); string missileStatus = string.IsNullOrEmpty(simulator.SelectedMissileId) ? "未选择" : $"已选: {simulator.SelectedMissileDisplayName}"; string sensorStatusString = ""; if (!string.IsNullOrEmpty(simulator.SelectedMissileId)) { var indicators = simulator.GetActiveIndicators(); var firstActiveIndicator = indicators.FirstOrDefault(ind => ind.IsActive); if (firstActiveIndicator.Name != null) { sensorStatusString = $"(已激活: {firstActiveIndicator.Name})"; } else { sensorStatusString = "(无默认激活指示器)"; } } else { sensorStatusString = "(需先选导弹)"; } Console.WriteLine($"1. 选择导弹 ({missileStatus})"); Console.WriteLine($"2. 配置传感器 {sensorStatusString}"); Console.WriteLine($"3. 配置干扰 {simulator.GetActiveJammingDescription()} {(string.IsNullOrEmpty(simulator.SelectedMissileId) ? "(需先选导弹)" : "")}"); Console.WriteLine($"4. 设置日志级别 (当前级别: {simulator.CurrentLogLevel})"); Console.WriteLine($"5. 开始仿真 {(string.IsNullOrEmpty(simulator.SelectedMissileId) ? "(需先选导弹)" : "")}"); Console.WriteLine($"6. 设置仿真步长 (当前: {simulator.TimeStep}s)"); Console.WriteLine("0. 退出程序"); Console.Write("\n请选择: "); string choice = Console.ReadLine()?.ToLower() ?? string.Empty; switch (choice) { case "1": SelectMissile(simulator); break; case "2": if (!string.IsNullOrEmpty(simulator.SelectedMissileId)) ConfigureSensors(simulator); else Console.WriteLine("请先选择导弹。"); break; case "3": if (!string.IsNullOrEmpty(simulator.SelectedMissileId)) ConfigureJamming(simulator); else Console.WriteLine("请先选择导弹。"); break; case "4": ShowLogLevelMenu(simulator); break; case "5": if (!string.IsNullOrEmpty(simulator.SelectedMissileId)) { RunSimulationInstance(simulator); } else { Console.WriteLine("请先选择导弹并完成基本配置 (选择导弹是启动仿真的最低要求)。"); } break; case "6": ConfigureTimeStep(simulator); break; case "0": exitProgram = true; break; default: Console.WriteLine("无效选择,请重试。"); break; } } } static void ShowLogLevelMenu(ComprehensiveMissileSimulator simulator) { bool backToMainMenu = false; while (!backToMainMenu) { Console.WriteLine("\n--- 设置日志级别 ---"); Console.WriteLine("1. Off (关闭所有Trace/Debug输出)"); Console.WriteLine("2. Error (仅错误信息)"); Console.WriteLine("3. Warning (警告及错误)"); Console.WriteLine("4. Information (普通信息、警告、错误)"); Console.WriteLine("5. Verbose (所有信息,包括Debug.WriteLine)"); Console.WriteLine("0. 返回主菜单"); Console.Write("请选择日志级别: "); string input = Console.ReadLine()?.ToLower() ?? string.Empty; SourceLevels currentLevel = simulator.CurrentLogLevel; SourceLevels selectedLevel = currentLevel; // 默认使用当前级别 bool levelSet = false; switch (input) { case "1": selectedLevel = SourceLevels.Off; levelSet = true; break; case "2": selectedLevel = SourceLevels.Error; levelSet = true; break; case "3": selectedLevel = SourceLevels.Warning; levelSet = true; break; case "4": selectedLevel = SourceLevels.Information; levelSet = true; break; case "5": selectedLevel = SourceLevels.Verbose; levelSet = true; break; case "0": backToMainMenu = true; break; default: Console.WriteLine("无效选择,请重试。"); break; } if (levelSet) { simulator.SetLogLevel(selectedLevel); // 设置日志级别后,会由simulator打印确认 return; // 设置后返回主菜单 } } } static void RunSimulationInstance(ComprehensiveMissileSimulator simulator) { Console.WriteLine("\n--- 开始仿真 --- "); var simulationEndedEvent = new ManualResetEvent(false); simulator.SimulationEnded += (sender, e) => { simulationEndedEvent.Set(); // 防止多次调用RunSimulationInstance时出现的问题 if (sender is ComprehensiveMissileSimulator sim) { sim.SimulationEnded -= (s, args) => simulationEndedEvent.Set(); // 尝试取消订阅,精确的lambda匹配比较困难 } }; var simulationThread = new Thread(simulator.Start); simulationThread.Start(); Console.WriteLine("仿真已开始运行。在主菜单输入 '0' 可在下次返回主菜单时退出程序。"); Console.WriteLine("仿真过程中,您可以随时按 Enter 键尝试提前中止当前仿真实例并返回主菜单。"); bool simulationForceStopped = false; while (!simulationEndedEvent.WaitOne(100)) // 每100ms检查一次仿真是否结束 { if (Console.KeyAvailable) { var keyInfo = Console.ReadKey(intercept: true); if (keyInfo.Key == ConsoleKey.Enter) { Console.WriteLine("\n用户请求中止当前仿真实例..."); simulator.Stop(); simulationForceStopped = true; break; } } } // 等待仿真线程实际完成,特别是如果被强制停止。 simulationThread.Join(); if (simulationForceStopped) { Console.WriteLine("当前仿真实例已被用户中止。"); } else { Console.WriteLine("当前导弹仿真自然结束。"); } Console.WriteLine("按任意键返回主菜单..."); Console.ReadKey(); // 等待用户确认后返回主菜单 } static void SelectMissile(ComprehensiveMissileSimulator simulator) { var missiles = new[] { ("LSGM_1", "激光半主动制导导弹"), ("LBRM_1", "激光驾束制导导弹"), ("TSM_1", "末敏弹"), ("ICGM_1", "红外指令制导导弹"), ("ITGM_1", "红外成像末制导导弹"), ("MMWG_1", "毫米波末制导导弹"), ("CGGM_1", "复合制导导弹") }; while (true) { Console.WriteLine("\n--- 选择导弹类型 ---"); for (int i = 0; i < missiles.Length; i++) { Console.WriteLine($" {i + 1}. {missiles[i].Item2}"); } Console.WriteLine(" 0. 返回主菜单"); Console.Write("请选择: "); string input = Console.ReadLine()?.ToLower() ?? string.Empty; if (input == "0") return; if (int.TryParse(input, out int choice) && choice >= 1 && choice <= missiles.Length) { simulator.SelectMissile(missiles[choice - 1].Item1); Console.WriteLine($"已选择: {simulator.SelectedMissileDisplayName}"); return; } Console.WriteLine("无效选择,请重试。"); } } static void ConfigureSensors(ComprehensiveMissileSimulator simulator) { while (true) { Console.WriteLine("\n--- 配置传感器和指示器 ---"); Console.WriteLine("当前传感器状态:"); var indicators = simulator.GetActiveIndicators(); if (indicators.Length == 0) { Console.WriteLine("当前导弹类型没有可配置的独立传感器/指示器,或未实现获取接口。"); } else { for (int i = 0; i < indicators.Length; i++) { Console.WriteLine($" {i + 1}. {indicators[i].Name} [{(indicators[i].IsActive ? "激活" : "未激活")}]"); } } Console.WriteLine(" 0. 返回主菜单"); Console.Write("请选择切换状态的传感器,或返回: "); string input = Console.ReadLine()?.ToLower() ?? string.Empty; if (input == "0") return; if (int.TryParse(input, out int choice)) { if (choice >= 1 && choice <= indicators.Length) { simulator.ToggleIndicator(indicators[choice - 1].Id); return; } else { Console.WriteLine("无效选择,请重试。"); } } else { Console.WriteLine("无效输入,请输入数字。"); } } } static void ConfigureJamming(ComprehensiveMissileSimulator simulator) { var availableJammingOptions = simulator.GetAvailableJammingOptions(); var currentlyActiveJammingsFromSimulator = simulator.GetCurrentlyActiveJammings(); var jammingStatus = new bool[availableJammingOptions.Length]; for (int i = 0; i < availableJammingOptions.Length; i++) { var currentOptionForLoop = availableJammingOptions[i]; // Renamed to avoid conflict if (currentlyActiveJammingsFromSimulator.Any(activeJam => activeJam.JammerId == currentOptionForLoop.JammerId && activeJam.Type == currentOptionForLoop.Type)) { jammingStatus[i] = true; } else { jammingStatus[i] = false; } } while (true) { Console.WriteLine("\n--- 配置干扰方式 ---"); Console.WriteLine($"当前导弹: {simulator.SelectedMissileDisplayName}"); if (availableJammingOptions.Length == 0) { Console.WriteLine("当前导弹类型没有可配置的干扰选项。"); } else { Console.WriteLine("可用干扰方式:"); for (int i = 0; i < availableJammingOptions.Length; i++) { var option = availableJammingOptions[i]; Console.WriteLine($" {i + 1}. {option.DisplayName} [{(jammingStatus[i] ? "激活" : "未激活")}] " + $"(干扰模式: {option.Mode}, 作用对象: {option.Target})"); } } Console.WriteLine(" 0. 返回主菜单"); Console.Write("请选择切换状态的干扰项,或返回: "); string input = Console.ReadLine()?.ToLower() ?? string.Empty; if (input == "0") return; if (int.TryParse(input, out int choice)) { if (choice >= 1 && choice <= availableJammingOptions.Length) { var option = availableJammingOptions[choice - 1]; jammingStatus[choice - 1] = !jammingStatus[choice - 1]; // Toggle local status for display if (jammingStatus[choice - 1]) simulator.ApplyJamming(option.Type, option.DisplayName, option.JammerId, option.Mode, option.Target); else simulator.ClearJamming(option.Type, option.DisplayName, option.JammerId); return; } else { Console.WriteLine("无效选择,请重试。"); } } else { Console.WriteLine("无效输入,请输入数字。"); } } } static void ConfigureTimeStep(ComprehensiveMissileSimulator simulator) { bool backToMainMenu = false; while (!backToMainMenu) { Console.WriteLine("\n--- 设置仿真步长 ---"); Console.WriteLine($"当前步长: {simulator.TimeStep}s"); Console.WriteLine("1. 低精度 (0.02s)"); Console.WriteLine("2. 中精度 (0.01s)"); Console.WriteLine("3. 高精度 (0.005s)"); Console.WriteLine("0. 返回主菜单"); Console.Write("请选择步长: "); string input = Console.ReadLine()?.ToLower() ?? string.Empty; switch (input) { case "1": simulator.TimeStep = 0.02; Console.WriteLine($"仿真步长已设置为: {simulator.TimeStep}s (低精度)"); return; // 设置后返回主菜单 case "2": simulator.TimeStep = 0.01; Console.WriteLine($"仿真步长已设置为: {simulator.TimeStep}s (中精度)"); return; // 设置后返回主菜单 case "3": simulator.TimeStep = 0.005; Console.WriteLine($"仿真步长已设置为: {simulator.TimeStep}s (高精度)"); return; // 设置后返回主菜单 case "0": backToMainMenu = true; break; default: Console.WriteLine("无效选择,请重试。"); break; } } } } }