From 1d5df8a095ff509edf5a31b1b187c1a0fe9cf4b3 Mon Sep 17 00:00:00 2001 From: glax Date: Mon, 15 Jan 2024 23:32:57 +0100 Subject: [PATCH] Fix null-references --- CS2GSI/CS2GSI.cs | 2 +- CS2GSI/GameState/CS2GameState.cs | 10 +++--- CS2GSI/GameState/GameStateTeam.cs | 10 +++--- CS2GSI/GameState/Map.cs | 16 +++++---- CS2GSI/GameState/Player.cs | 22 ++++++------ CS2GSI/GameState/PlayerMatchStats.cs | 32 ++++++++--------- CS2GSI/GameState/PlayerState.cs | 54 ++++++++++++++-------------- CS2GSI/GameState/Round.cs | 29 ++++++++------- 8 files changed, 91 insertions(+), 84 deletions(-) diff --git a/CS2GSI/CS2GSI.cs b/CS2GSI/CS2GSI.cs index b0f2222..d5a8f49 100644 --- a/CS2GSI/CS2GSI.cs +++ b/CS2GSI/CS2GSI.cs @@ -40,7 +40,7 @@ public class CS2GSI this._lastLocalGameState = newState.UpdateGameStateForLocal(_lastLocalGameState); this.logger?.Log(LogLevel.Debug, $"Updated Local State:\n{_lastLocalGameState.ToString()}"); - if (_lastLocalGameState is not null) + if (_lastLocalGameState is not null && _allGameStates.Count > 0) { List> generatedEvents = CS2EventGenerator.GenerateEvents(_lastLocalGameState.Value, newState, _allGameStates.Last()); this.logger?.Log(LogLevel.Information, $"Generated {generatedEvents.Count} events."); diff --git a/CS2GSI/GameState/CS2GameState.cs b/CS2GSI/GameState/CS2GameState.cs index 6797d1d..2ff4b19 100644 --- a/CS2GSI/GameState/CS2GameState.cs +++ b/CS2GSI/GameState/CS2GameState.cs @@ -12,11 +12,11 @@ public struct CS2GameState public override string ToString() { - return $"{GetType()}\n" + - $"\tTime: {Timestamp}\tSteamId: {ProviderSteamId}\n" + - $"\t{Map}\n" + - $"\t{Round}\n" + - $"\t{Player}\n"; + return $"{GetType().Name}\n" + + $"..Time: {Timestamp}\tProviderSteamId: {ProviderSteamId}\n" + + $"..{Map.ToString()?.Replace("\n", "\n...")}\n" + + $"..{Round.ToString()?.Replace("\n", "\n...")}\n" + + $"..{Player.ToString()?.Replace("\n", "\n...")}\n"; } internal static CS2GameState ParseFromJObject(JObject jsonObject) diff --git a/CS2GSI/GameState/GameStateTeam.cs b/CS2GSI/GameState/GameStateTeam.cs index 86df151..01b810c 100644 --- a/CS2GSI/GameState/GameStateTeam.cs +++ b/CS2GSI/GameState/GameStateTeam.cs @@ -9,11 +9,11 @@ public struct GameStateTeam public override string ToString() { - return $"{GetType()}\n" + - $"\tScore: {Score}\n" + - $"\tConsecutiveRoundLosses: {ConsecutiveRoundLosses}\n" + - $"\tTimeoutsRemaining: {TimeoutsRemaining}\n" + - $"\tMatchesWonThisSeries: {MatchesWonThisSeries}\n"; + return $"{GetType().Name}\n" + + $"..Team {Team}\tScore: {Score}\n" + + $"..ConsecutiveRoundLosses: {ConsecutiveRoundLosses}\n" + + $"..TimeoutsRemaining: {TimeoutsRemaining}\n" + + $"..MatchesWonThisSeries: {MatchesWonThisSeries}\n"; } internal static GameStateTeam ParseFromJObject(JObject jsonObject, CS2Team team) diff --git a/CS2GSI/GameState/Map.cs b/CS2GSI/GameState/Map.cs index 51ddcd2..132a962 100644 --- a/CS2GSI/GameState/Map.cs +++ b/CS2GSI/GameState/Map.cs @@ -4,18 +4,20 @@ namespace CS2GSI.GameState; public struct Map { - public string Mode, Name; + public string Mode, MapName; public MapPhase Phase; public int Round, NumMatchesToWinSeries; public GameStateTeam GameStateTeamCT, GameStateTeamT; public override string ToString() { - return $"{GetType()}\n" + - $"\t{Mode} {Name} {Round} Matches to Win Series: {NumMatchesToWinSeries}\n" + - $"\t{Phase}\n" + - $"\t{GameStateTeamCT}\n" + - $"\t{GameStateTeamT}\n"; + return $"{GetType().Name}\n" + + $"..Mode: {Mode} Map: {MapName}\n" + + $"..Round: {Round}\n" + + $"..Matches to Win Series: {NumMatchesToWinSeries}\n" + + $"..Phase: {Phase}\n" + + $"..{GameStateTeamCT.ToString().Replace("\n", "\n...")}\n" + + $"..{GameStateTeamT.ToString().Replace("\n", "\n...")}\n"; } internal static Map? ParseFromJObject(JObject jsonObject) @@ -24,7 +26,7 @@ public struct Map ? new Map() { Mode = jsonObject.SelectToken("map.mode")!.Value()!, - Name = jsonObject.SelectToken("map.name")!.Value()!, + MapName = jsonObject.SelectToken("map.name")!.Value()!, Phase = MapPhaseFromString(jsonObject.SelectToken("map.phase")!.Value()!), Round = jsonObject.SelectToken("map.round")!.Value(), NumMatchesToWinSeries = jsonObject.SelectToken("map.num_matches_to_win_series")!.Value(), diff --git a/CS2GSI/GameState/Player.cs b/CS2GSI/GameState/Player.cs index 9da3d41..470ba3c 100644 --- a/CS2GSI/GameState/Player.cs +++ b/CS2GSI/GameState/Player.cs @@ -13,34 +13,36 @@ public struct Player public override string ToString() { - return $"{GetType()}\n" + - $"\t{Name} {SteamId} {Activity} {Team}\n" + - $"\t{State}\n" + - $"\t{MatchStats}\n"; + return $"{GetType().Name}\n" + + $"..Name: {Name} SteamId: {SteamId}\n" + + $"..Activity: {Activity}\n" + + $"..Team: {Team}\n" + + $"..{State.ToString()?.Replace("\n", "\n...")}\n" + + $"..{MatchStats.ToString()?.Replace("\n", "\n...")}\n"; } internal static Player? ParseFromJObject(JObject jsonObject) { - return new Player() + return jsonObject.SelectToken("player") is not null ? new Player() { SteamId = jsonObject.SelectToken("player.steamid")!.Value()!, Name = jsonObject.SelectToken("player.name")!.Value()!, - Team = CS2TeamFromString(jsonObject.SelectToken("player.team")!.Value()!), + Team = CS2TeamFromString(jsonObject.SelectToken("player.team")?.Value()), Activity = PlayerActivityFromString(jsonObject.SelectToken("player.activity")!.Value()!), State = PlayerState.ParseFromJObject(jsonObject), MatchStats = PlayerMatchStats.ParseFromJObject(jsonObject) - }; + } : null; } public enum PlayerActivity {Playing, Menu, TextInput} - private static CS2Team CS2TeamFromString(string str) + private static CS2Team? CS2TeamFromString(string? str) { - return str.ToLower() switch + return str?.ToLower() switch { "t" => CS2Team.T, "ct" => CS2Team.CT, - _ => throw new ArgumentOutOfRangeException() + _ => null }; } diff --git a/CS2GSI/GameState/PlayerMatchStats.cs b/CS2GSI/GameState/PlayerMatchStats.cs index a370457..d8f5349 100644 --- a/CS2GSI/GameState/PlayerMatchStats.cs +++ b/CS2GSI/GameState/PlayerMatchStats.cs @@ -6,23 +6,23 @@ public struct PlayerMatchStats { public int Kills, Assists, Deaths, MVPs, Score; - internal static PlayerMatchStats ParseFromJObject(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(), - }; - } - public override string ToString() { - return $"{GetType()}\n" + - $"\tKAD: {Kills} {Assists} {Deaths}\n" + - $"\tMVPs: {MVPs}\n" + - $"\tScore: {Score}\n"; + return $"{GetType().Name}\n" + + $"..KAD: {Kills} {Assists} {Deaths}\n" + + $"..MVPs: {MVPs}\n" + + $"..Score: {Score}\n"; + } + + internal static PlayerMatchStats? ParseFromJObject(JObject jsonObject) + { + return jsonObject.SelectToken("player.match_stats") is not null ? 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(), + } : null; } } \ No newline at end of file diff --git a/CS2GSI/GameState/PlayerState.cs b/CS2GSI/GameState/PlayerState.cs index a37d65f..e1da95b 100644 --- a/CS2GSI/GameState/PlayerState.cs +++ b/CS2GSI/GameState/PlayerState.cs @@ -7,34 +7,34 @@ public struct PlayerState public int Health, Armor, Flashed, Smoked, Burning, Money, RoundKills, RoundHs, EquipmentValue; public bool Helmet; - internal static PlayerState ParseFromJObject(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(), - }; - } - public override string ToString() { - return $"{GetType()}\n" + - $"\tHealth: {Health}\n" + - $"\tArmor: {Armor}\n" + - $"\tFlashed: {Flashed}\n" + - $"\tSmoked: {Smoked}\n" + - $"\tBurning: {Burning}\n" + - $"\tMoney: {Money}\n" + - $"\tRoundKills: {RoundKills}\n" + - $"\tRoundHs: {RoundHs}\n" + - $"\tEquipmentValue: {EquipmentValue}\n"; + return $"{GetType().Name}\n" + + $"..Health: {Health}\n" + + $"..Armor: {Armor}\n" + + $"..Flashed: {Flashed}\n" + + $"..Smoked: {Smoked}\n" + + $"..Burning: {Burning}\n" + + $"..Money: {Money}\n" + + $"..RoundKills: {RoundKills}\n" + + $"..RoundHs: {RoundHs}\n" + + $"..EquipmentValue: {EquipmentValue}\n"; + } + + internal static PlayerState? ParseFromJObject(JObject jsonObject) + { + return jsonObject.SelectToken("player.state") is not null ? 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(), + } : null; } } \ No newline at end of file diff --git a/CS2GSI/GameState/Round.cs b/CS2GSI/GameState/Round.cs index 0ab4868..bc525a4 100644 --- a/CS2GSI/GameState/Round.cs +++ b/CS2GSI/GameState/Round.cs @@ -5,29 +5,32 @@ namespace CS2GSI.GameState; public struct Round { public RoundPhase Phase; - public BombStatus Bomb; - public CS2Team WinnerTeam; + public BombStatus? Bomb; + public CS2Team? WinnerTeam; public override string ToString() { - return $"{GetType()}\n" + - $"\t{Phase} {WinnerTeam} {Bomb}\n"; + return $"{GetType().Name}\n" + + $"..Phase: {Phase}\n" + + $"..Winner: {WinnerTeam}\n" + + $"..Bomb: {Bomb}\n"; } internal static Round? ParseFromJObject(JObject jsonObject) { - return new Round() + return jsonObject.SelectToken("round") is not null ? new Round() { Phase = RoundPhaseFromString(jsonObject.SelectToken("round.phase")!.Value()!), - WinnerTeam = CS2TeamFromString(jsonObject.SelectToken("round.win_team")!.Value()!), - Bomb = BombStatusFromString(jsonObject.SelectToken("round.bomb")!.Value()!) - }; + WinnerTeam = CS2TeamFromString(jsonObject.SelectToken("round.win_team")?.Value()), + Bomb = BombStatusFromString(jsonObject.SelectToken("round.bomb")?.Value()) + } : null; } public enum RoundPhase { Over, Freezetime, Live } + private static RoundPhase RoundPhaseFromString(string str) { return str switch @@ -44,24 +47,24 @@ public struct Round Planted, Exploded, Defused } - private static BombStatus BombStatusFromString(string str) + private static BombStatus? BombStatusFromString(string? str) { return str switch { "planted" => BombStatus.Planted, "exploded" => BombStatus.Exploded, "defused" => BombStatus.Defused, - _ => throw new ArgumentOutOfRangeException() + _ => null }; } - private static CS2Team CS2TeamFromString(string str) + private static CS2Team? CS2TeamFromString(string? str) { - return str.ToLower() switch + return str?.ToLower() switch { "t" => CS2Team.T, "ct" => CS2Team.CT, - _ => throw new ArgumentOutOfRangeException() + _ => null }; } } \ No newline at end of file