diff --git a/CS2GSI.csproj b/CS2GSI.csproj index c0c3371..49fa879 100644 --- a/CS2GSI.csproj +++ b/CS2GSI.csproj @@ -21,4 +21,8 @@ + + + + diff --git a/CS2GSIJsonParser.cs b/CS2GSIJsonParser.cs new file mode 100644 index 0000000..9ad24c4 --- /dev/null +++ b/CS2GSIJsonParser.cs @@ -0,0 +1,87 @@ +using CS2GSI.GameState; +using Newtonsoft.Json.Linq; + +namespace CS2GSI; + +internal static class CS2GSIJsonParser +{ + internal static CS2GameState ParseGameStateFromJson(string jsonString) + { + JObject jsonObject = JObject.Parse(jsonString); + return new CS2GameState() + { + Timestamp = jsonObject.SelectToken("provider.timestamp")!.Value(), + Map = ParseMapFromJObject(jsonObject), + Player = ParsePlayerFromJObject(jsonObject) + }; + } + + private static Map? ParseMapFromJObject(JObject jsonObject) + { + return jsonObject.SelectToken("map") is { } mapToken + ? new Map() + { + Mode = jsonObject.SelectToken("map.mode")!.Value()!, + Name = jsonObject.SelectToken("map.name")!.Value()!, + Phase = jsonObject.SelectToken("map.phase")!.Value()!, + Round = jsonObject.SelectToken("map.round")!.Value(), + NumMatchesToWinSeries = jsonObject.SelectToken("map.num_matches_to_win_series")!.Value(), + TeamCT = ParseTeamFromJObject(jsonObject, "ct"), + TeamT = ParseTeamFromJObject(jsonObject, "t") + } + : null; + } + + private static Team ParseTeamFromJObject(JObject jsonObject, string team) + { + return new Team() + { + Score = jsonObject.SelectToken($"map.team_{team}.score")!.Value(), + ConsecutiveRoundLosses = jsonObject.SelectToken($"map.team_{team}.consecutive_round_losses")!.Value(), + TimeoutsRemaining = jsonObject.SelectToken($"map.team_{team}.timeouts_remaining")!.Value(), + MatchesWonThisSeries = jsonObject.SelectToken($"map.team_{team}.matches_won_this_series")!.Value(), + }; + } + + private static Player? ParsePlayerFromJObject(JObject jsonObject) + { + return new Player() + { + SteamId = jsonObject.SelectToken("player.steamid")!.Value()!, + Name = jsonObject.SelectToken("player.name")!.Value()!, + Team = jsonObject.SelectToken("player.team")!.Value()!, + Activity = jsonObject.SelectToken("player.activity")!.Value()!, + State = ParsePlayerStateFromJObject(jsonObject), + MatchStats = ParsePlayerMatchStatsFromJObject(jsonObject) + }; + } + + private static PlayerState ParsePlayerStateFromJObject(JObject jsonObject) + { + return new PlayerState() + { + Health = jsonObject.SelectToken($"player.state.health")!.Value(), + Armor = jsonObject.SelectToken($"player.state.armor")!.Value(), + Helmet = jsonObject.SelectToken($"player.state.helmet")!.Value(), + Flashed = jsonObject.SelectToken($"player.state.flashed")!.Value(), + Smoked = jsonObject.SelectToken($"player.state.smoked")!.Value(), + Burning = jsonObject.SelectToken($"player.state.burning")!.Value(), + Money = jsonObject.SelectToken($"player.state.money")!.Value(), + RoundKills = jsonObject.SelectToken($"player.state.round_kills")!.Value(), + RoundHs = jsonObject.SelectToken($"player.state.round_killhs")!.Value(), + EquipmentValue = jsonObject.SelectToken($"player.state.equip_value")!.Value(), + }; + } + + private static PlayerMatchStats ParsePlayerMatchStatsFromJObject(JObject jsonObject) + { + return new PlayerMatchStats() + { + Kills = jsonObject.SelectToken($"player.match_stats.kills")!.Value(), + Assists = jsonObject.SelectToken($"player.match_stats.assists")!.Value(), + Deaths = jsonObject.SelectToken($"player.match_stats.deaths")!.Value(), + MVPs = jsonObject.SelectToken($"player.match_stats.mvps")!.Value(), + Score = jsonObject.SelectToken($"player.match_stats.score")!.Value(), + }; + } +} \ No newline at end of file diff --git a/GameState/CS2GameState.cs b/GameState/CS2GameState.cs new file mode 100644 index 0000000..48f2b1a --- /dev/null +++ b/GameState/CS2GameState.cs @@ -0,0 +1,8 @@ +namespace CS2GSI.GameState; + +public struct CS2GameState +{ + public int Timestamp; + public Map? Map; + public Player? Player; +} \ No newline at end of file diff --git a/GameState/Map.cs b/GameState/Map.cs new file mode 100644 index 0000000..6e16e52 --- /dev/null +++ b/GameState/Map.cs @@ -0,0 +1,8 @@ +namespace CS2GSI.GameState; + +public struct Map +{ + public string Mode, Name, Phase; + public int Round, NumMatchesToWinSeries; + public Team TeamCT, TeamT; +} \ No newline at end of file diff --git a/GameState/Player.cs b/GameState/Player.cs new file mode 100644 index 0000000..9e0de63 --- /dev/null +++ b/GameState/Player.cs @@ -0,0 +1,10 @@ +namespace CS2GSI.GameState; + +public struct Player +{ + public string SteamId, Name, Activity; + public string? Team; + public int? ObserverSlot; + public PlayerState? State; + public PlayerMatchStats? MatchStats; +} \ No newline at end of file diff --git a/GameState/PlayerMatchStats.cs b/GameState/PlayerMatchStats.cs new file mode 100644 index 0000000..3b8ccd5 --- /dev/null +++ b/GameState/PlayerMatchStats.cs @@ -0,0 +1,6 @@ +namespace CS2GSI.GameState; + +public struct PlayerMatchStats +{ + public int Kills, Assists, Deaths, MVPs, Score; +} \ No newline at end of file diff --git a/GameState/PlayerState.cs b/GameState/PlayerState.cs new file mode 100644 index 0000000..e8ada4c --- /dev/null +++ b/GameState/PlayerState.cs @@ -0,0 +1,7 @@ +namespace CS2GSI.GameState; + +public struct PlayerState +{ + public int Health, Armor, Flashed, Smoked, Burning, Money, RoundKills, RoundHs, EquipmentValue; + public bool Helmet; +} \ No newline at end of file diff --git a/GameState/Team.cs b/GameState/Team.cs new file mode 100644 index 0000000..c08eec7 --- /dev/null +++ b/GameState/Team.cs @@ -0,0 +1,6 @@ +namespace CS2GSI.GameState; + +public struct Team +{ + public int Score, ConsecutiveRoundLosses, TimeoutsRemaining, MatchesWonThisSeries; +} \ No newline at end of file