ThreatSourceLibaray/tools/Program.cs

378 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}
}
}