using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using System.Text.Json; using RainOpsMini.Services; using RainOpsMini.Plugins; using RainOpsMini.Models; using RainOpsMini; namespace RainOpsMini.Apis { public static class SystemApi { public static void MapSystemApis(this IEndpointRouteBuilder app) { // API: 获取在线管理端/OB 状态 // 用于管理面板查看当前有哪些管理员或 OB 在线 app.MapGet("/api/online-status", (OnlineUserService service, HttpContext ctx) => { // 需要认证后才能查看 if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized(); return Results.Ok(new { panelUsers = service.GetOnlinePanelUsers(), cameramen = service.GetOnlineCameramen() }); }); // API: 获取插件列表 // 返回所有已加载的插件及其状态 app.MapGet("/api/plugins", (PluginManager pm, HttpContext ctx) => { if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized(); return Results.Ok(pm.GetPlugins()); }); // API: 更新插件配置 // 动态修改插件的运行参数 app.MapPost("/api/plugins/{name}/config", (string name, JsonElement config, PluginManager pm, HttpContext ctx) => { if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized(); // 建议增加更严格的权限检查,例如 IsSuperAdmin pm.UpdateConfig(name, config); return Results.Ok(); }); // API: 重置插件配置 // 将插件配置恢复为默认值 app.MapPost("/api/plugins/{name}/reset", (string name, PluginManager pm, HttpContext ctx) => { if (ctx.User.Identity?.IsAuthenticated != true) return Results.Unauthorized(); pm.ResetConfig(name); return Results.Ok(); }); // API: 自动检测服务器配置 // 尝试从 Squad 服务器配置文件中读取 RCON 信息 app.MapGet("/api/setup/detect-config", async () => { if (Program.isConfigured) return Results.BadRequest(new { error = "系统已初始化,禁止重复配置" }); string cfgPath = Path.Combine(Directory.GetCurrentDirectory(), "SquadGame", "ServerConfig", "Rcon.cfg"); if (!File.Exists(cfgPath)) { // 尝试全大写文件名(虽然 Windows 不区分大小写,但为了兼容性) cfgPath = Path.Combine(Directory.GetCurrentDirectory(), "SquadGame", "ServerConfig", "RCON.cfg"); if (!File.Exists(cfgPath)) return Results.NotFound(new { error = "Config file not found" }); } try { string[] lines = await File.ReadAllLinesAsync(cfgPath); string? ip = null; int? port = null; string? password = null; bool modified = false; for (int i = 0; i < lines.Length; i++) { string line = lines[i].Trim(); if (string.IsNullOrWhiteSpace(line) || line.StartsWith("//") || line.StartsWith("#")) continue; // 简单的键值对解析 int eqIndex = line.IndexOf('='); if (eqIndex == -1) continue; string key = line.Substring(0, eqIndex).Trim(); string value = line.Substring(eqIndex + 1).Trim(); if (key.Equals("IP", StringComparison.OrdinalIgnoreCase)) ip = value; else if (key.Equals("Port", StringComparison.OrdinalIgnoreCase)) { if (int.TryParse(value, out int p)) port = p; } else if (key.Equals("Password", StringComparison.OrdinalIgnoreCase)) password = value; else if (key.Equals("MaxConnections", StringComparison.OrdinalIgnoreCase)) { if (int.TryParse(value, out int maxCon) && maxCon < 100) { // 强制更新最大连接数为 100 lines[i] = "MaxConnections=100"; modified = true; } } } if (modified) { await File.WriteAllLinesAsync(cfgPath, lines); } if (string.IsNullOrEmpty(ip) || port == null || string.IsNullOrEmpty(password)) { return Results.NotFound(new { error = "Incomplete config" }); } return Results.Ok(new { ip, port, password }); } catch (Exception ex) { return Results.BadRequest(new { error = ex.Message }); } }); // API: 系统初始化配置 // 首次运行时设置 RCON 连接信息和管理员账号 app.MapPost("/api/setup", async (SetupRequest req, HttpContext ctx) => { if (Program.isConfigured) return Results.BadRequest(new { error = "系统已初始化,禁止重复配置" }); if (string.IsNullOrWhiteSpace(req.Ip) || req.Port <= 0 || req.Port > 65535 || string.IsNullOrWhiteSpace(req.Password)) { return Results.BadRequest(new { error = "RCON 配置无效" }); } if (string.IsNullOrWhiteSpace(req.WebUser)) { return Results.BadRequest(new { error = "Web 用户名不能为空" }); } string generatedPwd = ""; if (string.IsNullOrWhiteSpace(req.WebPassword)) { generatedPwd = Program.GenerateRandomPassword(); req.WebPassword = generatedPwd; } else if (!Program.ValidatePassword(req.WebPassword)) { return Results.BadRequest(new { error = "密码强度不足" }); } // 保存配置 Program.Config.Ip = req.Ip; Program.Config.Port = req.Port; Program.Config.Password = req.Password; Program.Config.WebUser = req.WebUser; Program.Config.WebPassword = req.WebPassword; try { Program.SaveConfigToFile(); Program.isConfigured = true; // 初始化 RCON await Program.InitializeRcon(); return Results.Ok(new { success = true, generatedPassword = generatedPwd }); } catch (Exception ex) { return Results.BadRequest(new { error = $"保存配置失败: {ex.Message}" }); } }); } } }