Add Events

This commit is contained in:
glax 2024-01-15 22:37:00 +01:00
parent 9489c45e9f
commit 01b5a4945f
3 changed files with 304 additions and 0 deletions

6
CS2EventArgs.cs Normal file
View File

@ -0,0 +1,6 @@
namespace CS2GSI;
public class CS2EventArgs : EventArgs
{
}

107
CS2EventGenerator.cs Normal file
View File

@ -0,0 +1,107 @@
using CS2GSI.GameState;
using CS2Event = CS2GSI.CS2GSI.CS2Event;
namespace CS2GSI;
internal static class CS2EventGenerator
{
internal static List<ValueTuple<CS2Event, CS2EventArgs>> GenerateEvents(CS2GameState previousPlayerState, CS2GameState newGameState, CS2GameState lastGameState)
{
List<ValueTuple<CS2Event, CS2EventArgs>> events = new();
events.AddRange(GeneratePlayerEvents(previousPlayerState, newGameState));
events.AddRange(GenerateMapEvents(previousPlayerState, newGameState, lastGameState));
if(lastGameState.Player?.SteamId != newGameState.Player?.SteamId)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnPlayerChange, new CS2EventArgs()));
if(events.Count > 0)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.AnyEvent, new CS2EventArgs()));
return events;
}
private static List<ValueTuple<CS2Event, CS2EventArgs>> GenerateMapEvents(CS2GameState previousPlayerState, CS2GameState newGameState, CS2GameState lastGameState)
{
List<ValueTuple<CS2Event, CS2EventArgs>> events = new();
if (newGameState.Player?.Team == previousPlayerState.Player?.Team && lastGameState.Player?.Team == previousPlayerState.Player?.Team)
{
if(newGameState.Round?.Phase == Round.RoundPhase.Live && lastGameState.Round?.Phase != Round.RoundPhase.Live)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnRoundStart, new CS2EventArgs()));
if(newGameState.Round?.Phase == Round.RoundPhase.Over && lastGameState.Round?.Phase == Round.RoundPhase.Live)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnRoundOver, new CS2EventArgs()));
}
if(newGameState.Map?.Phase == Map.MapPhase.Live && lastGameState.Map?.Phase != Map.MapPhase.Live)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnMatchStart, new CS2EventArgs()));
if(newGameState.Map?.Phase == Map.MapPhase.GameOver && lastGameState.Map?.Phase != Map.MapPhase.GameOver)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnMatchOver, new CS2EventArgs()));
if(newGameState.Map?.Phase == Map.MapPhase.Intermission && lastGameState.Map?.Phase != Map.MapPhase.Intermission)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnHalfTime, new CS2EventArgs()));
if(newGameState.Round?.Phase == Round.RoundPhase.Freezetime && lastGameState.Round?.Phase != Round.RoundPhase.Freezetime)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnFreezeTime, new CS2EventArgs()));
if(newGameState.Round?.Bomb == Round.BombStatus.Planted && lastGameState.Round?.Bomb != Round.BombStatus.Planted)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnBombPlanted, new CS2EventArgs()));
if(newGameState.Round?.Bomb == Round.BombStatus.Defused && lastGameState.Round?.Bomb != Round.BombStatus.Defused)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnBombDefused, new CS2EventArgs()));
if(newGameState.Round?.Bomb == Round.BombStatus.Exploded && lastGameState.Round?.Bomb != Round.BombStatus.Exploded)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnBombExploded, new CS2EventArgs()));
return events;
}
private static List<ValueTuple<CS2Event, CS2EventArgs>> GeneratePlayerEvents(CS2GameState previousPlayerState, CS2GameState newGameState)
{
List<ValueTuple<CS2Event, CS2EventArgs>> events = new();
if (newGameState.Player?.SteamId != newGameState.ProviderSteamId || previousPlayerState.Player?.SteamId != newGameState.Player?.SteamId)
return events;
if(newGameState.Player?.MatchStats?.Kills > previousPlayerState.Player?.MatchStats?.Kills && newGameState.Player is { MatchStats: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnKill, new CS2EventArgs()));
if(newGameState.Player?.State?.RoundHs > previousPlayerState.Player?.State?.RoundHs && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnHeadshot, new CS2EventArgs()));
if(newGameState.Player?.MatchStats?.Deaths > previousPlayerState.Player?.MatchStats?.Deaths && newGameState.Player is { MatchStats: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnDeath, new CS2EventArgs()));
if(newGameState.Player?.State?.Flashed > 0 && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnFlashed, new CS2EventArgs()));
if(newGameState.Player?.State?.Burning > 0 && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnBurning, new CS2EventArgs()));
if(newGameState.Player?.State?.Smoked > 0 && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnSmoked, new CS2EventArgs()));
if(newGameState.Player?.State?.Health < previousPlayerState.Player?.State?.Health && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnDamageTaken, new CS2EventArgs()));
if(newGameState.Player?.State?.Health != previousPlayerState.Player?.State?.Health && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnHealthChange, new CS2EventArgs()));
if(newGameState.Player?.State?.Money != previousPlayerState.Player?.State?.Money && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnMoneyChange, new CS2EventArgs()));
if(newGameState.Player?.State?.Armor != previousPlayerState.Player?.State?.Armor && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnArmorChange, new CS2EventArgs()));
if(newGameState.Player?.State?.Helmet != previousPlayerState.Player?.State?.Helmet && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnHelmetChange, new CS2EventArgs()));
if(newGameState.Player?.State?.EquipmentValue != previousPlayerState.Player?.State?.EquipmentValue && newGameState.Player is { State: not null})
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnEquipmentValueChange, new CS2EventArgs()));
if(newGameState.Player?.Team != previousPlayerState.Player?.Team && newGameState.Player is not null)
events.Add(new ValueTuple<CS2Event, CS2EventArgs>(CS2Event.OnTeamChange, new CS2EventArgs()));
return events;
}
}

191
CS2GSI.cs Normal file
View File

@ -0,0 +1,191 @@
using CS2GSI.GameState;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
namespace CS2GSI;
public class CS2GSI
{
private GSIServer _gsiServer;
private List<CS2GameState> _allGameStates = new();
private CS2GameState? _lastLocalGameState = null;
private ILogger? logger;
public CS2GSI(ILogger? logger = null)
{
this.logger = logger;
this.logger?.Log(LogLevel.Information, "Installing GSI-Configfile...");
try
{
GsiConfigInstaller.InstallGsi();
}
catch (Exception e)
{
this.logger?.Log(LogLevel.Error, e.StackTrace);
this.logger?.Log(LogLevel.Critical, "Could not install GSI-Configfile. Exiting.");
return;
}
this._gsiServer = new GSIServer(3000);
this._gsiServer.OnMessage += messageJson =>
{
JObject jsonObject = JObject.Parse(messageJson);
CS2GameState newState = CS2GameState.ParseFromJObject(jsonObject);
this.logger?.Log(LogLevel.Debug, $"Received State:\n{newState.ToString()}");
this._lastLocalGameState = newState.UpdateGameStateForLocal(_lastLocalGameState);
this.logger?.Log(LogLevel.Debug, $"Updated Local State:\n{_lastLocalGameState.ToString()}");
if (_lastLocalGameState is not null)
{
List<ValueTuple<CS2Event, CS2EventArgs>> generatedEvents = CS2EventGenerator.GenerateEvents(_lastLocalGameState.Value, newState, _allGameStates.Last());
this.logger?.Log(LogLevel.Information, $"Generated {generatedEvents.Count} events.");
if(generatedEvents.Count > 0)
this.logger?.Log(LogLevel.Debug, $"Events:\n\t{string.Join("\n\t", generatedEvents)}");
InvokeEvents(generatedEvents);
}
_allGameStates.Add(newState);
};
}
private void InvokeEvents(List<ValueTuple<CS2Event, CS2EventArgs>> cs2Events)
{
foreach(ValueTuple<CS2Event, CS2EventArgs> cs2Event in cs2Events)
InvokeEvent(cs2Event);
}
private void InvokeEvent(ValueTuple<CS2Event, CS2EventArgs> cs2Event)
{
switch (cs2Event.Item1)
{
case CS2Event.OnKill:
OnKill?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnHeadshot:
OnHeadshot?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnDeath:
OnDeath?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnFlashed:
OnFlashed?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnBurning:
OnBurning?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnSmoked:
OnSmoked?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnRoundStart:
OnRoundStart?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnRoundOver:
OnRoundOver?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnDamageTaken:
OnDamageTaken?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnMatchStart:
OnMatchStart?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnMatchOver:
OnMatchOver?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnMoneyChange:
OnMoneyChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnHealthChange:
OnHealthChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnArmorChange:
OnArmorChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnHelmetChange:
OnHelmetChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnEquipmentValueChange:
OnEquipmentValueChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnTeamChange:
OnTeamChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnPlayerChange:
OnPlayerChange?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnFreezeTime:
OnFreezeTime?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnHalfTime:
OnHalfTime?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnBombDefused:
OnBombDefused?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnBombExploded:
OnBombExploded?.Invoke(cs2Event.Item2);
break;
case CS2Event.OnBombPlanted:
OnBombPlanted?.Invoke(cs2Event.Item2);
break;
case CS2Event.AnyEvent:
AnyEvent?.Invoke(cs2Event.Item2);
break;
default:
this.logger?.Log(LogLevel.Error, $"Unknown Event {cs2Event}");
return;
}
}
internal enum CS2Event {
OnKill,
OnHeadshot,
OnDeath,
OnFlashed,
OnBurning,
OnSmoked,
OnRoundStart,
OnRoundOver,
OnDamageTaken,
OnMatchStart,
OnMatchOver,
OnMoneyChange,
OnHealthChange,
OnArmorChange,
OnHelmetChange,
OnEquipmentValueChange,
OnTeamChange,
OnPlayerChange,
OnHalfTime,
OnFreezeTime,
OnBombPlanted,
OnBombDefused,
OnBombExploded,
AnyEvent
}
public delegate void CS2EventHandler(CS2EventArgs eventArgs);
public event CS2EventHandler? OnKill,
OnHeadshot,
OnDeath,
OnFlashed,
OnBurning,
OnSmoked,
OnRoundStart,
OnRoundOver,
OnDamageTaken,
OnMatchStart,
OnMatchOver,
OnMoneyChange,
OnHealthChange,
OnArmorChange,
OnHelmetChange,
OnEquipmentValueChange,
OnTeamChange,
OnPlayerChange,
OnHalfTime,
OnFreezeTime,
OnBombPlanted,
OnBombDefused,
OnBombExploded,
AnyEvent;
}