mirror of
https://gitee.com/xiarenalofs/squad-rain-ops-mini.git
synced 2026-08-07 05:45:46 +08:00
178 lines
7.4 KiB
C#
178 lines
7.4 KiB
C#
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}" });
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|