WebPanelBridge 0.1.0: live server status for simpleadmin-web over RCON
This commit is contained in:
commit
d02c8454df
5 changed files with 257 additions and 0 deletions
79
WebPanelBridge.cs
Normal file
79
WebPanelBridge.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using CounterStrikeSharp.API;
|
||||
using CounterStrikeSharp.API.Core;
|
||||
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
||||
using CounterStrikeSharp.API.Modules.Commands;
|
||||
using CounterStrikeSharp.API.Modules.Cvars;
|
||||
using CounterStrikeSharp.API.Modules.Utils;
|
||||
|
||||
namespace WebPanelBridge;
|
||||
|
||||
// Reports live match state to simpleadmin-web over RCON. The server console command prints one
|
||||
// JSON object per line, each prefixed with "wpb ", so the web panel can pick them out of whatever
|
||||
// else lands in the RCON response. Nothing here changes game state.
|
||||
public class WebPanelBridge : BasePlugin
|
||||
{
|
||||
public override string ModuleName => "WebPanelBridge";
|
||||
public override string ModuleVersion => "0.1.0";
|
||||
public override string ModuleAuthor => "astra";
|
||||
public override string ModuleDescription => "Live server status for simpleadmin-web, over RCON";
|
||||
|
||||
private const string Prefix = "wpb ";
|
||||
|
||||
private static readonly JsonSerializerOptions JsonOptions = new()
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
|
||||
};
|
||||
|
||||
private record ServerLine(int V, string Hostname, string Map, int MaxPlayers, int ScoreT, int ScoreCt, bool Warmup);
|
||||
|
||||
private record PlayerLine(int Userid, string Name, string Steamid, int Team, int Kills, int Deaths, uint Ping, bool Bot);
|
||||
|
||||
[ConsoleCommand("css_webpanel_status", "Prints live server status as JSON lines for simpleadmin-web")]
|
||||
[CommandHelper(whoCanExecute: CommandUsage.SERVER_ONLY)]
|
||||
public void OnStatus(CCSPlayerController? caller, CommandInfo command)
|
||||
{
|
||||
int scoreT = 0, scoreCt = 0;
|
||||
foreach (var team in Utilities.FindAllEntitiesByDesignerName<CCSTeam>("cs_team_manager"))
|
||||
{
|
||||
if (team.TeamNum == (byte)CsTeam.Terrorist)
|
||||
scoreT = team.Score;
|
||||
else if (team.TeamNum == (byte)CsTeam.CounterTerrorist)
|
||||
scoreCt = team.Score;
|
||||
}
|
||||
|
||||
var warmup = Utilities.FindAllEntitiesByDesignerName<CCSGameRulesProxy>("cs_gamerules")
|
||||
.FirstOrDefault()?.GameRules?.WarmupPeriod ?? false;
|
||||
|
||||
var maxPlayers = Server.MaxPlayers;
|
||||
var visible = ConVar.Find("sv_visiblemaxplayers")?.GetPrimitiveValue<int>() ?? -1;
|
||||
if (visible > 0)
|
||||
maxPlayers = visible;
|
||||
|
||||
var server = new ServerLine(1, ConVar.Find("hostname")?.StringValue ?? "", Server.MapName, maxPlayers,
|
||||
scoreT, scoreCt, warmup);
|
||||
command.ReplyToCommand(Prefix + JsonSerializer.Serialize(server, JsonOptions));
|
||||
|
||||
foreach (var player in Utilities.GetPlayers())
|
||||
{
|
||||
if (player is not { IsValid: true, IsHLTV: false } || player.Connected != PlayerConnectedState.Connected)
|
||||
continue;
|
||||
|
||||
var stats = player.ActionTrackingServices?.MatchStats;
|
||||
var line = new PlayerLine(
|
||||
player.UserId ?? -1,
|
||||
player.PlayerName,
|
||||
player.IsBot ? "0" : player.SteamID.ToString(),
|
||||
player.TeamNum,
|
||||
stats?.Kills ?? 0,
|
||||
stats?.Deaths ?? 0,
|
||||
player.Ping,
|
||||
player.IsBot);
|
||||
command.ReplyToCommand(Prefix + JsonSerializer.Serialize(line, JsonOptions));
|
||||
}
|
||||
|
||||
command.ReplyToCommand(Prefix + "end");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue