This commit is contained in:
Linrador 2025-09-20 21:28:52 +02:00
parent 20e18fca62
commit af8793c53d
8 changed files with 106 additions and 13 deletions

View File

@ -21,6 +21,7 @@ using CounterStrikeSharp.API.Core;
using CounterStrikeSharp.API.Core.Attributes;
using CounterStrikeSharp.API.Core.Attributes.Registration;
using CounterStrikeSharp.API.Modules.Commands;
using CounterStrikeSharp.API.Modules.Cvars;
using Microsoft.Extensions.Logging;
namespace WsTelemetry;
@ -46,6 +47,10 @@ public class MetaWebSocketPlugin : BasePlugin
private X509Certificate2? _serverCert;
private volatile string _mapName = "";
private volatile string _serverName = "";
private int _scoreCT = 0;
private int _scoreT = 0;
private TcpListener? _listener;
private CancellationTokenSource? _serverCts;
@ -88,7 +93,7 @@ public class MetaWebSocketPlugin : BasePlugin
return JsonSerializer.Serialize(new {
type = "map",
name = _mapName,
phase = _phase,
serverName = _serverName,
t = NowMs()
});
}
@ -98,14 +103,29 @@ public class MetaWebSocketPlugin : BasePlugin
{
try
{
var mn = Server.MapName; // jetzt sicher, weil NextFrame/MapStart
if (!string.IsNullOrEmpty(mn))
RefreshServerName();
// Map-Name aus dem Server holen (erst im NextFrame sicher verfügbar)
var mn = Server.MapName;
if (!string.IsNullOrWhiteSpace(mn))
{
_mapName = mn!;
Broadcast(BuildMapPayload()); // 👈 statt anonymes Json
// Map + (aktuelle) Phase in EINEM Payload
Broadcast(BuildMapPayload());
}
SendFullPlayerList(); // nur hier oder aus Events heraus aufrufen
Broadcast(JsonSerializer.Serialize(new { type = "phase", phase = _phase, t = NowMs() }));
// Vollständige Spielerliste
SendFullPlayerList();
// Phase separat noch einmal senden (falls ein Client erst danach connected)
Broadcast(JsonSerializer.Serialize(new {
type = "phase",
phase = _phase,
t = NowMs()
}));
// Optional: aktuellen Score mitschicken (falls du BroadcastScore() implementiert hast)
BroadcastScore();
}
catch (Exception ex)
{
@ -113,6 +133,26 @@ public class MetaWebSocketPlugin : BasePlugin
}
}
private void RefreshServerName()
{
try
{
// Standard in Source/CS2
var s = ConVar.Find("hostname")?.StringValue;
if (!string.IsNullOrWhiteSpace(s))
{
_serverName = s!;
return;
}
// Fallback (vereinzelt genutzt)
s = ConVar.Find("host_name")?.StringValue;
if (!string.IsNullOrWhiteSpace(s))
_serverName = s!;
}
catch { /* ignore */ }
}
private void LoadAndApplyConfig(bool generateIfMissing = true)
{
try
@ -251,10 +291,16 @@ public class MetaWebSocketPlugin : BasePlugin
{
_mapName = newMap ?? Server.MapName ?? "";
SetPhase("warmup"); // 👈 zuerst Phase setzen (sendet auch ein separates phase-Event)
Broadcast(BuildMapPayload()); // 👈 Map + Phase zusammen
SendFullPlayerList();
// Score neu starten
_scoreCT = 0;
_scoreT = 0;
RefreshServerName();
SetPhase("warmup");
Broadcast(BuildMapPayload());
SendFullPlayerList();
BroadcastScore(); // gleich initial 0:0 senden
Logger.LogInformation($"[WS] Map gewechselt: '{(_mapName ?? "")}' Meta gesendet.");
}
@ -314,6 +360,7 @@ public class MetaWebSocketPlugin : BasePlugin
{
// Start der Runde == Freezezeit
SetPhase("freezetime");
BroadcastScore();
return HookResult.Continue;
}
@ -321,18 +368,43 @@ public class MetaWebSocketPlugin : BasePlugin
{
// Ende Freeze -> Live
SetPhase("live");
BroadcastScore();
return HookResult.Continue;
}
private HookResult OnRoundEnd(EventRoundEnd ev, GameEventInfo info)
{
try
{
// Viele Builds haben ev.Winner (2 = T, 3 = CT).
// Falls in deinem Build anders, kannst du unten noch "WinnerTeam" per Reflection abfragen.
int? winner = null;
// direkt zugreifen, wenn Property existiert
try { winner = ev.Winner; } catch { /* Property evtl. nicht vorhanden */ }
// Fallback per Reflection (WinnerTeam / Team / …)
if (!winner.HasValue)
{
winner = TryGetIntProp(ev, "Winner")
?? TryGetIntProp(ev, "WinnerTeam")
?? TryGetIntProp(ev, "Team");
}
if (winner == 3) _scoreCT++;
else if (winner == 2) _scoreT++;
}
catch { /* ignore */ }
SetPhase("over");
BroadcastScore();
return HookResult.Continue;
}
private HookResult OnBombPlanted(EventBombPlanted ev, GameEventInfo info)
{
SetPhase("bomb");
BroadcastScore();
return HookResult.Continue;
}
@ -631,11 +703,11 @@ public class MetaWebSocketPlugin : BasePlugin
try
{
if (!_clients.ContainsKey(id) || state.Cts.IsCancellationRequested) return;
SendTextFrame(state, BuildMapPayload()); // 👈
SendTextFrame(state, BuildMapPayload()); // ✅ Map ohne Phase
var buf = BuildPlayersPayload();
SendTextFrame(state, buf);
// optional zusätzlich:
// SendTextFrame(state, JsonSerializer.Serialize(new { type = "phase", phase = _phase, t = NowMs() }));
// ✅ Phase EINMAL separat für den neu verbundenen Client
SendTextFrame(state, JsonSerializer.Serialize(new { type = "phase", phase = _phase, t = NowMs() }));
}
catch { /* ignore */ }
});
@ -680,6 +752,27 @@ public class MetaWebSocketPlugin : BasePlugin
return JsonSerializer.Serialize(new { type = "players", t = NowMs(), players = list });
}
// kleiner Helper für obige Reflection-Zugriffe
private static int? TryGetIntProp(object obj, string prop)
{
try
{
var pi = obj.GetType().GetProperty(prop, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (pi != null)
{
var v = pi.GetValue(obj);
if (v is int i) return i;
}
}
catch { }
return null;
}
private void BroadcastScore()
{
Broadcast(JsonSerializer.Serialize(new { type = "score", ct = _scoreCT, t = _scoreT, tms = NowMs() }));
}
private void Broadcast(string text)
{
foreach (var kv in _clients)

View File

@ -13,7 +13,7 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("CS2WebSocketTelemetryPlugin")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+5cd0409eda59707069d32b70b5c63a1fd2d8956a")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+20e18fca62bdfacbfc20e6e98cbe220dc389b3cb")]
[assembly: System.Reflection.AssemblyProductAttribute("CS2WebSocketTelemetryPlugin")]
[assembly: System.Reflection.AssemblyTitleAttribute("CS2WebSocketTelemetryPlugin")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]