From 1dfa50bf0aade8d604a5642b4e017171f45507ec Mon Sep 17 00:00:00 2001 From: Benedict Etzel Date: Wed, 29 Nov 2023 19:39:21 +0100 Subject: [PATCH] feat(Choices): start parsing SendChoices --- Hearthstone Deck Tracker/GameEventHandler.cs | 1 + .../Hearthstone/Choice.cs | 26 +++++++++++++ Hearthstone Deck Tracker/IGameHandler.cs | 2 + .../LogReader/Handlers/ChoicesHandler.cs | 37 +++++++++++++++++++ .../LogReader/Handlers/SendChoicesHandler.cs | 37 +++++++++++++++++++ .../LogReader/LogConstants.cs | 6 +++ .../LogReader/LogWatcherManager.cs | 5 +++ 7 files changed, 114 insertions(+) create mode 100644 Hearthstone Deck Tracker/Hearthstone/Choice.cs create mode 100644 Hearthstone Deck Tracker/LogReader/Handlers/ChoicesHandler.cs create mode 100644 Hearthstone Deck Tracker/LogReader/Handlers/SendChoicesHandler.cs diff --git a/Hearthstone Deck Tracker/GameEventHandler.cs b/Hearthstone Deck Tracker/GameEventHandler.cs index 56b634673..d433817b9 100644 --- a/Hearthstone Deck Tracker/GameEventHandler.cs +++ b/Hearthstone Deck Tracker/GameEventHandler.cs @@ -1732,6 +1732,7 @@ public void HandleQuestRewardDatabaseId(int id, int value) void IGameHandler.SetOpponentHero(string? cardId) => SetOpponentHero(cardId); void IGameHandler.SetPlayerHero(string? cardId) => SetPlayerHero(cardId); void IGameHandler.HandleOpponentHeroPower(string cardId, int turn) => HandleOpponentHeroPower(cardId, turn); + void IGameHandler.HandlePlayerSendChoices(Choice choice) {} void IGameHandler.TurnStart(ActivePlayer player, int turnNumber) => TurnStart(player, turnNumber); void IGameHandler.HandleGameStart(DateTime timestamp) => HandleGameStart(timestamp); void IGameHandler.HandleGameEnd(bool stateComplete) => HandleGameEnd(stateComplete); diff --git a/Hearthstone Deck Tracker/Hearthstone/Choice.cs b/Hearthstone Deck Tracker/Hearthstone/Choice.cs new file mode 100644 index 000000000..52ac27012 --- /dev/null +++ b/Hearthstone Deck Tracker/Hearthstone/Choice.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using Hearthstone_Deck_Tracker.Hearthstone.Entities; +using HearthDb.Enums; +using System; + +namespace Hearthstone_Deck_Tracker.Hearthstone +{ + [Serializable] + public class Choice + { + public readonly int Id; + public readonly ChoiceType ChoiceType; + public readonly List ChosenEntities = new List(); + + public Choice(int id, ChoiceType choiceType) + { + Id = id; + ChoiceType = choiceType; + } + + public void AttachChosenEntity(int index, Entity entity) + { + ChosenEntities.Add(entity); + } + } +} diff --git a/Hearthstone Deck Tracker/IGameHandler.cs b/Hearthstone Deck Tracker/IGameHandler.cs index 0d6e905e3..79c90f358 100644 --- a/Hearthstone Deck Tracker/IGameHandler.cs +++ b/Hearthstone Deck Tracker/IGameHandler.cs @@ -3,6 +3,7 @@ using System; using HearthDb.Enums; using Hearthstone_Deck_Tracker.Enums; +using Hearthstone_Deck_Tracker.Hearthstone; using Hearthstone_Deck_Tracker.Hearthstone.Entities; #endregion @@ -21,6 +22,7 @@ public interface IGameHandler void HandlePlayerDeckDiscard(Entity entity, string cardId, int turn); void HandlePlayerPlayToDeck(Entity entity, string cardId, int turn); void HandlePlayerHeroPower(string cardId, int turn); + void HandlePlayerSendChoices(Choice choice); void SetPlayerHero(string? cardId); void HandlePlayerGetToDeck(Entity entity, string cardId, int turn); void TurnStart(ActivePlayer player, int turnNumber); diff --git a/Hearthstone Deck Tracker/LogReader/Handlers/ChoicesHandler.cs b/Hearthstone Deck Tracker/LogReader/Handlers/ChoicesHandler.cs new file mode 100644 index 000000000..abfb2b7c7 --- /dev/null +++ b/Hearthstone Deck Tracker/LogReader/Handlers/ChoicesHandler.cs @@ -0,0 +1,37 @@ +using Hearthstone_Deck_Tracker.Hearthstone; +using Hearthstone_Deck_Tracker.LogReader.Interfaces; +using System; +using HearthDb.Enums; +using static Hearthstone_Deck_Tracker.LogReader.LogConstants.Choices; + +namespace Hearthstone_Deck_Tracker.LogReader.Handlers +{ + internal class ChoicesHandler + { + SendChoicesHandler _sendChoicesHandler = new SendChoicesHandler(); + + public void Handle(string logLine, IHsGameState gameState, IGame game) + { + if(SendChoicesHeaderRegex.IsMatch(logLine)) + { + var match = SendChoicesHeaderRegex.Match(logLine); + var choiceId = int.Parse(match.Groups["id"].Value); + if(!Enum.TryParse(match.Groups["choiceType"].Value, out ChoiceType choiceType)) + choiceType = ChoiceType.INVALID; + _sendChoicesHandler.SendChoices(choiceId, choiceType, gameState, game); + } + else if(SendChoicesBodyRegex.IsMatch(logLine)) + { + var match = SendChoicesBodyRegex.Match(logLine); + var index = int.Parse(match.Groups["index"].Value); + var entityId = int.Parse(match.Groups["id"].Value); + _sendChoicesHandler.SendChoice(index, entityId, gameState, game); + } + else + { + // Terminate the current Choice. + _sendChoicesHandler.Flush(gameState, game); + } + } + } +} diff --git a/Hearthstone Deck Tracker/LogReader/Handlers/SendChoicesHandler.cs b/Hearthstone Deck Tracker/LogReader/Handlers/SendChoicesHandler.cs new file mode 100644 index 000000000..bb5ade4e9 --- /dev/null +++ b/Hearthstone Deck Tracker/LogReader/Handlers/SendChoicesHandler.cs @@ -0,0 +1,37 @@ +using Hearthstone_Deck_Tracker.Hearthstone; +using Hearthstone_Deck_Tracker.LogReader.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using HearthDb.Enums; + +namespace Hearthstone_Deck_Tracker.LogReader.Handlers +{ + internal class SendChoicesHandler + { + private Choice? Choice; + + public void SendChoices(int id, ChoiceType choiceType, IHsGameState gameState, IGame game) + { + Choice = new Choice(id, choiceType); + } + + public void SendChoice(int index, int entityId, IHsGameState gameState, IGame game) + { + if(Choice is null) return; + + if(game.Entities.TryGetValue(entityId, out var entity)) + Choice.AttachChosenEntity(index, entity); + } + + public void Flush(IHsGameState gameState, IGame game) + { + if(Choice is null) return; + + gameState.GameHandler?.HandlePlayerSendChoices(Choice); + Choice = null; + } + } +} diff --git a/Hearthstone Deck Tracker/LogReader/LogConstants.cs b/Hearthstone Deck Tracker/LogReader/LogConstants.cs index b9f52697a..223289d73 100644 --- a/Hearthstone Deck Tracker/LogReader/LogConstants.cs +++ b/Hearthstone Deck Tracker/LogReader/LogConstants.cs @@ -49,5 +49,11 @@ public static class PowerTaskList public static readonly Regex ShuffleRegex = new Regex(@"SHUFFLE_DECK\ PlayerID=(?(\d+))"); } + + public static class Choices + { + public static readonly Regex SendChoicesHeaderRegex = new Regex(@"id=(?(\d+)) ChoiceType=(?(\w+))"); + public static readonly Regex SendChoicesBodyRegex = new Regex(@"m_chosenEntities\[(?(\d+))]=.* id=(?(\d+))"); + } } } diff --git a/Hearthstone Deck Tracker/LogReader/LogWatcherManager.cs b/Hearthstone Deck Tracker/LogReader/LogWatcherManager.cs index e0f83b959..4f2754290 100644 --- a/Hearthstone Deck Tracker/LogReader/LogWatcherManager.cs +++ b/Hearthstone Deck Tracker/LogReader/LogWatcherManager.cs @@ -22,6 +22,7 @@ namespace Hearthstone_Deck_Tracker.LogReader public class LogWatcherManager { private readonly PowerHandler _powerLineHandler = new PowerHandler(); + private readonly ChoicesHandler _choicesHandler = new ChoicesHandler(); private readonly ArenaHandler _arenaHandler = new ArenaHandler(); private readonly LoadingScreenHandler _loadingScreenHandler = new LoadingScreenHandler(); private HsGameState? _gameState; @@ -128,7 +129,11 @@ private void OnNewLines(List lines) break; case "Power": if(line.LineContent.StartsWith("GameState.")) + { _game.PowerLog.Add(line.Line); + if(line.LineContent.StartsWith("GameState.SendChoices") || line.LineContent.StartsWith("GameState.DebugPrintEntitiesChosen")) + _choicesHandler.Handle(line.Line, _gameState, _game); + } else { _powerLineHandler.Handle(line.Line, _gameState, _game);