1
0
mirror of https://github.com/RaidMax/IW4M-Admin.git synced 2025-06-09 23:00:57 -05:00
Files
IW4M-Admin/Plugins/ZombieStats/Events/ZombieEventParser.cs
2024-07-02 16:27:28 -05:00

252 lines
7.7 KiB
C#

using System.ComponentModel;
using Data.Models;
using Microsoft.Extensions.Logging;
using SharedLibraryCore;
using SharedLibraryCore.Database.Models;
using SharedLibraryCore.Events.Game;
using SharedLibraryCore.Events.Game.GameScript;
using SharedLibraryCore.Events.Game.GameScript.Zombie;
namespace IW4MAdmin.Plugins.ZombieStats.Events;
public class ZombieEventParser(ILogger<ZombieEventParser> logger)
{
private const char DataSeparator = ';';
private readonly Dictionary<string, Func<GameScriptEvent, string[], GameEventV2>> _eventParsers = new()
{
{"K", ParsePlayerKilledEvent},
{"D", ParsePlayerDamageEvent},
{"PD", ParsePlayerDownedEvent},
{"PR", ParsePlayerRevivedEvent},
{"PC", ParsePlayerConsumedPerkEvent},
{"PG", ParsePlayerGrabbedPowerupEvent},
{"AD", ParseZombieDamageEvent},
{"AK", ParseZombieKilledEvent},
{"RD", ParsePlayerRoundDataEvent},
{"RC", ParseRoundCompleteEvent},
{"SU", ParsePlayerStatUpdatedEvent},
};
public GameEventV2? ParseScriptEvent(GameScriptEvent scriptEvent)
{
var eventArgs = scriptEvent.ScriptData.Split(DataSeparator);
if (eventArgs.Length < 2)
{
logger.LogDebug("Ignoring {EventType} because there is not enough data {Data}", nameof(GameScriptEvent),
scriptEvent.ScriptData);
return null;
}
if (!_eventParsers.TryGetValue(eventArgs[1], out var parser))
{
logger.LogWarning("No parser registered for GSE type \"{Type}\"", eventArgs[1]);
return null;
}
var parsedEvent = parser(scriptEvent, eventArgs[2..]);
logger.LogDebug("Parsed GSE type {Type}", parsedEvent.GetType().Name);
return parsedEvent;
}
private static GameEventV2 ParsePlayerKilledEvent(GameScriptEvent scriptEvent, string[] data)
{
var (victim, attacker) = ParseClientInfo(scriptEvent, data);
var killEvent = new PlayerKilledGameEvent
{
Target = victim,
Origin = attacker,
WeaponName = data[8],
Damage = Convert.ToInt32(data[9]),
MeansOfDeath = data[10],
HitLocation = data[11]
};
return killEvent;
}
private static GameEventV2 ParsePlayerDamageEvent(GameScriptEvent scriptEvent, string[] data)
{
var (victim, attacker) = ParseClientInfo(scriptEvent, data);
var killEvent = new PlayerDamageGameEvent
{
Target = victim,
Origin = attacker,
WeaponName = data[8],
Damage = Convert.ToInt32(data[9]),
MeansOfDeath = data[10],
HitLocation = data[11]
};
return killEvent;
}
private static GameEventV2 ParsePlayerRevivedEvent(GameScriptEvent scriptEvent, string[] data)
{
var (revived, reviver) = ParseClientInfo(scriptEvent, data);
return new PlayerRevivedGameEvent
{
Origin = reviver,
Target = revived
};
}
private static GameEventV2 ParsePlayerConsumedPerkEvent(GameScriptEvent scriptEvent, string[] data)
{
var consumer = ParseVictimClient(scriptEvent, data);
return new PlayerConsumedPerkGameEvent
{
Origin = consumer,
PerkName = data.Last()
};
}
private static GameEventV2 ParsePlayerGrabbedPowerupEvent(GameScriptEvent scriptEvent, string[] data)
{
var consumer = ParseVictimClient(scriptEvent, data);
return new PlayerGrabbedPowerupGameEvent
{
Origin = consumer,
PowerupName = data.Last()
};
}
private static GameEventV2 ParseZombieDamageEvent(GameScriptEvent scriptEvent, string[] data)
{
var (victim, attacker) = ParseClientInfo(scriptEvent, data);
var killEvent = new ZombieDamageGameEvent
{
Target = victim,
Origin = attacker,
WeaponName = data[8],
Damage = Convert.ToInt32(data[9]),
MeansOfDeath = data[10],
HitLocation = data[11]
};
return killEvent;
}
private static GameEventV2 ParseZombieKilledEvent(GameScriptEvent scriptEvent, string[] data)
{
var (victim, attacker) = ParseClientInfo(scriptEvent, data);
var killEvent = new ZombieKilledGameEvent
{
Target = victim,
Origin = attacker,
WeaponName = data[8],
Damage = Convert.ToInt32(data[9]),
MeansOfDeath = data[10],
HitLocation = data[11]
};
return killEvent;
}
private static GameEventV2 ParsePlayerDownedEvent(GameScriptEvent scriptEvent, string[] data)
{
var client = ParseVictimClient(scriptEvent, data);
return new PlayerDownedGameEvent
{
Origin = client
};
}
private static GameEventV2 ParsePlayerRoundDataEvent(GameScriptEvent scriptEvent, string[] data)
{
var client = ParseVictimClient(scriptEvent, data);
return new PlayerRoundDataGameEvent
{
Origin = client,
TotalScore = Convert.ToInt32(data[4]),
CurrentScore = Convert.ToInt32(data[5]),
CurrentRound = Convert.ToInt32(data[6]),
IsGameOver = data[7] == "1"
};
}
private static GameEventV2 ParseRoundCompleteEvent(GameScriptEvent scriptEvent, string[] data)
{
return new RoundEndEvent
{
RoundNumber = Convert.ToInt32(data[0])
};
}
private static GameEventV2 ParsePlayerStatUpdatedEvent(GameScriptEvent scriptEvent, string[] data)
{
var client = ParseVictimClient(scriptEvent, data);
var rawStatValue = data[^1];
var updateType = rawStatValue[0] switch
{
'+' => PlayerStatUpdatedGameEvent.StatUpdateType.Increment,
'-' => PlayerStatUpdatedGameEvent.StatUpdateType.Decrement,
'=' => PlayerStatUpdatedGameEvent.StatUpdateType.Absolute,
_ => throw new InvalidEnumArgumentException($"{rawStatValue[0]} is not a valid state update type")
};
return new PlayerStatUpdatedGameEvent
{
Origin = client,
UpdateType = updateType,
StatTag = data[^2],
StatValue = int.Parse(rawStatValue[1..])
};
}
private static (EFClient victim, EFClient attacker) ParseClientInfo(GameScriptEvent scriptEvent, string[] data)
{
var victim = ParseVictimClient(scriptEvent, data);
var attackerGuid = data[4].ConvertGuidToLong(scriptEvent.Owner.EventParser.Configuration.GuidNumberStyle);
var attackerClientNum = Convert.ToInt32(data[5]);
var attackerTeam = data[6];
var attackerName = data[7];
var attacker = new EFClient
{
NetworkId = attackerGuid,
ClientNumber = attackerClientNum,
TeamName = attackerTeam,
CurrentAlias = new EFAlias
{
Name = attackerName
}
};
return (victim, attacker);
}
private static EFClient ParseVictimClient(GameScriptEvent scriptEvent, string[] data)
{
var victimGuid = data[0].ConvertGuidToLong(scriptEvent.Owner.EventParser.Configuration.GuidNumberStyle);
var victimClientNum = Convert.ToInt32(data[1]);
var victimTeam = data[2];
var victimName = data[3];
var victim = new EFClient
{
NetworkId = victimGuid,
ClientNumber = victimClientNum,
TeamName = victimTeam,
CurrentAlias = new EFAlias
{
Name = victimName
}
};
return victim;
}
}