예제 #1
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            parseContext.Reset();

            var events = new List <object> {
                new GameEvents.GameStarted()
            };
            var linesConsumed = new List <string>();

            while (!lines.HasCompleted)
            {
                string currentLine = lines.Current;

                // Check if the current line is outside the scope of this parser
                if (!parserContext.NestedOffsetPattern.IsMatch(currentLine))
                {
                    parsedEvents = events;

                    return(linesConsumed);
                }

                linesConsumed.Add(currentLine);
                lines.MoveNext();
            }

            return(linesConsumed);
        }
예제 #2
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            IDictionary <string, string> attributes = parserContext.StartLine.ParseKeyValuePairs();

            attributes.TryGetValue("tag", out string tag);
            attributes.TryGetValue("value", out string value);

            attributes.TryGetValue("Entity", out string entity);
            IDictionary <string, string> entityAttributes = entity.Rem("[", "]").ParseKeyValuePairs();

            entityAttributes.TryGetValue("zone", out string zone);
            entityAttributes.TryGetValue("cardId", out string cardID);
            entityAttributes.TryGetValue("player", out string player);

            int.TryParse(player, out int playerID);

            var events = new List <object>();

            if (tag.Eq("ZONE") && value.Eq("DECK") && zone.Eq("HAND"))
            {
                events.Add(new GameEvents.CardReturnedToDeckFromHand(playerID, cardID));
            }

            parsedEvents = events;

            return(Enumerable.Empty <string>());
        }
예제 #3
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            string playerID   = parserContext.StartGroupValues["PlayerID"];
            string playerName = parserContext.StartGroupValues["PlayerName"];

            parseContext.PlayerNames[playerID] = playerName;

            parsedEvents = Enumerable.Empty <object>();

            return(Enumerable.Empty <string>());
        }
예제 #4
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            IDictionary <string, string> attributes = parserContext.StartLine.ParseKeyValuePairs();

            attributes.TryGetValue("tag", out string tag);
            attributes.TryGetValue("value", out string value);

            attributes.TryGetValue("Entity", out string entity);
            IDictionary <string, string> entityAttributes = entity.Rem("[", "]").ParseKeyValuePairs();

            entityAttributes.TryGetValue("id", out string entityID);
            entityAttributes.TryGetValue("zone", out string entityZone);

            entityAttributes.TryGetValue("player", out string entityPlayer);
            int.TryParse(entityPlayer, out int playerID);

            var events = new List <object>();

            if (tag.Eq("STEP"))
            {
                parseContext.CurrentGameStep = value;
            }
            else if (tag.Eq("PLAYSTATE"))
            {
                if (value.Eq("WON"))
                {
                    parseContext.GameWinners.Add(entity);
                }
                else if (value.Eq("LOST"))
                {
                    parseContext.GameLosers.Add(entity);
                }
            }
            else if (tag.Eq("ZONE") && entityZone.Eq("DECK") && value.Eq("PLAY") && parseContext.EntityMappings.TryGetValue(entityID, out string cardID))
            {
                events.Add(new GameEvents.CardEnteredPlayFromDeck(playerID, cardID));
            }
            else if (tag.Eq("ZONE") && entityZone.Eq("PLAY") && value.Eq("DECK") && entityAttributes.TryGetValue("cardId", out string entityCardID))
            {
                if (entityID != null && parseContext.EntityControllers.TryGetValue(entityID, out string controller) && int.TryParse(controller, out int controllerID))
                {
                    playerID = controllerID;
                }

                events.Add(new GameEvents.CardAddedToDeck(playerID, entityCardID));
            }
            else if (tag.Eq("ZONE") && value.Eq("GRAVEYARD") && parseContext.CoinEntityID != null && parseContext.CoinEntityID.Eq(entityID))
            {
                events.Add(new GameEvents.OpponentCoinLost());
            }
            else if (tag.Eq("CONTROLLER") && entityID != null)
            {
                parseContext.EntityControllers[entityID] = value;
            }
            else if (tag.Eq("STATE") && value.Eq("COMPLETE"))
            {
                if (parseContext.PlayerID != null && parseContext.PlayerNames.TryGetValue(parseContext.PlayerID, out string playerName))
                {
                    bool gameWon = parseContext.GameWinners.Contains(playerName);

                    string opponentHeroCardID =
                        parseContext.PlayerHeroCards
                        .Where(heroCardIDByPlayerName => heroCardIDByPlayerName.Key != playerName)
                        .Select(heroCardIDByPlayerName => heroCardIDByPlayerName.Value)
                        .FirstOrDefault();

                    events.Add(new GameEvents.GameEnded(gameWon, opponentHeroCardID));
                }
            }

            parsedEvents = events;

            return(Enumerable.Empty <string>());
        }
예제 #5
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            IDictionary <string, string> attributes = parserContext.StartGroupValues["Attributes"].ParseKeyValuePairs();

            attributes.TryGetValue("CardID", out string cardID);
            attributes.TryGetValue("ID", out string id);

            var events        = new List <object>();
            var linesConsumed = new List <string>();
            var tags          = new Dictionary <string, string>();

            while (!lines.HasCompleted)
            {
                string currentLine = lines.Current;

                // Check if the current line is outside the scope of this parser
                if (!parserContext.NestedOffsetPattern.IsMatch(currentLine))
                {
                    tags.TryGetValue("CARDTYPE", out string cardTypeTag);
                    tags.TryGetValue("CONTROLLER", out string controllerTag);
                    tags.TryGetValue("ZONE", out string zoneTag);

                    int.TryParse(controllerTag, out int playerID);

                    if (parseContext.ParentBlock != null)
                    {
                        parseContext.ParentBlock.Attributes.TryGetValue("BlockType", out string parentBlockType);

                        parseContext.ParentBlock.Attributes.TryGetValue("Entity", out string parentBlockEntity);
                        IDictionary <string, string> parentBlockEntityAttributes = parentBlockEntity.ParseKeyValuePairs();
                        parentBlockEntityAttributes.TryGetValue("cardId", out string parentBlockEntityCardID);

                        if (parentBlockType.Eq("POWER") && zoneTag.Eq("DECK"))
                        {
                            // Fal'dorei Strider
                            if (parentBlockEntityCardID.Eq("LOOT_026"))
                            {
                                events.Add(new GameEvents.CardAddedToDeck(playerID, "LOOT_026e"));
                            }
                            // Jade Idol
                            else if (parentBlockEntityCardID.Eq("CFM_602"))
                            {
                                events.Add(new GameEvents.CardAddedToDeck(playerID, "CFM_602"));
                            }
                            // Un'Goro Pack
                            else if (parentBlockEntityCardID.Eq("UNG_851"))
                            {
                                events.Add(new GameEvents.CardAddedToDeck(playerID, "UNG_851t1"));
                            }
                        }
                        else if (parentBlockType.Eq("TRIGGER") && zoneTag.Eq("DECK"))
                        {
                            // Augmented Elekk
                            if (parentBlockEntityCardID.Eq("BOT_559"))
                            {
                                // TODO:
                                // The log file itself doesn't indicate what card was added to the deck
                                // Keep track of most recent card(s) added to deck and replay the events?
                                // Track cards added during the current main block and clear on new main block start
                            }
                            // Direhorn Hatchling
                            else if (parentBlockEntityCardID.Eq("UNG_957"))
                            {
                                events.Add(new GameEvents.CardAddedToDeck(playerID, "UNG_957t1"));
                            }
                            // Kingsbane
                            else if (parentBlockEntityCardID.Eq("LOOT_542"))
                            {
                                events.Add(new GameEvents.CardAddedToDeck(playerID, "LOOT_542"));
                            }
                        }
                    }

                    if (cardTypeTag.Eq("HERO") && !parseContext.PlayerHeroCards.ContainsKey(controllerTag))
                    {
                        parseContext.PlayerHeroCards[controllerTag] = cardID;
                    }

                    if (parseContext.CurrentGameStep == null)
                    {
                        if (cardID.Eq("GAME_005"))
                        {
                            events.Add(new GameEvents.PlayerReceivedCoin());
                        }
                        else if (cardID == string.Empty && zoneTag.Eq("HAND"))
                        {
                            parseContext.CoinEntityID = id;

                            events.Add(new GameEvents.OpponentReceivedCoin());
                        }
                    }

                    parsedEvents = events;

                    return(linesConsumed);
                }

                Match tagMatch;
                if ((tagMatch = s_tagPattern.Match(currentLine)).Success)
                {
                    tags.Add(tagMatch.Groups["tag"].Value, tagMatch.Groups["value"].Value);
                }

                linesConsumed.Add(currentLine);
                lines.MoveNext();
            }

            return(linesConsumed);
        }
예제 #6
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            IDictionary <string, string> attributes = parserContext.StartGroupValues["Attributes"].ParseKeyValuePairs();

            attributes.TryGetValue("CardID", out string cardID);

            attributes.TryGetValue("Entity", out string entity);
            IDictionary <string, string> entityAttributes = entity.Rem("[", "]").ParseKeyValuePairs();

            entityAttributes.TryGetValue("id", out string id);
            entityAttributes.TryGetValue("player", out string player);
            entityAttributes.TryGetValue("zone", out string zone);

            var events        = new List <object>();
            var linesConsumed = new List <string>();
            var tags          = new Dictionary <string, string>();

            while (!lines.HasCompleted)
            {
                string currentLine = lines.Current;

                // Check if the current line is outside the scope of this parser
                if (!parserContext.NestedOffsetPattern.IsMatch(currentLine))
                {
                    tags.TryGetValue("CONTROLLER", out string controller);
                    tags.TryGetValue("ZONE", out string zoneTag);

                    if (int.TryParse(entity, out int entityID))
                    {
                        parseContext.EntityMappings[entityID.ToString()] = cardID;

                        if (zoneTag.Eq("HAND"))
                        {
                            events.Add(new GameEvents.MulliganOptionPresented(cardID));

                            if (int.TryParse(controller, out int playerID) && parseContext.PlayerID == null)
                            {
                                parseContext.PlayerID = controller;

                                events.Add(new GameEvents.PlayerDetermined(playerID));
                            }
                        }
                    }
                    else if (int.TryParse(player, out int playerID))
                    {
                        parseContext.EntityMappings[id] = cardID;

                        if (zone.Eq("DECK"))
                        {
                            if (zoneTag.Eq("HAND"))
                            {
                                events.Add(new GameEvents.CardDrawnFromDeck(playerID, cardID));
                            }
                            else if (zoneTag.Eq("PLAY"))
                            {
                                events.Add(new GameEvents.CardEnteredPlayFromDeck(playerID, cardID));
                            }
                            else if (zoneTag.Eq("GRAVEYARD"))
                            {
                                events.Add(new GameEvents.CardOverdrawnFromDeck(playerID, cardID));
                            }
                            else if (zoneTag.Eq("SETASIDE"))
                            {
                                events.Add(new GameEvents.CardRemovedFromDeck(playerID, cardID));
                            }
                        }
                        else if (zone.Eq("HAND"))
                        {
                            if (zoneTag.Eq("HAND"))
                            {
                                events.Add(new GameEvents.CardDrawnFromDeck(playerID, cardID));
                            }
                        }
                    }

                    if (parseContext.ParentBlock != null)
                    {
                        IDictionary <string, string> parentBlockAttributes = parseContext.ParentBlock.Attributes;
                        parentBlockAttributes.TryGetValue("BlockType", out string parentBlockType);
                        parentBlockAttributes.TryGetValue("Entity", out string parentBlockEntity);

                        IDictionary <string, string> parentBlockEntityAttributes = parentBlockEntity.ParseKeyValuePairs();
                        parentBlockEntityAttributes.TryGetValue("id", out string parentBlockEntityID);

                        if (parentBlockType.Eq("POWER") && parentBlockEntityID != null && parseContext.EntityMappings.TryGetValue(parentBlockEntityID, out string parentBlockEntityCardID) && int.TryParse(player, out int playerID))
                        {
                            // Skulking Geist
                            if (parentBlockEntityCardID.Eq("ICC_701"))
                            {
                                events.Add(new GameEvents.CardRemovedFromDeck(playerID, cardID));
                            }
                        }
                    }

                    parsedEvents = events;

                    return(linesConsumed);
                }

                Match tagMatch;
                if ((tagMatch = s_tagPattern.Match(currentLine)).Success)
                {
                    tags.Add(tagMatch.Groups["tag"].Value, tagMatch.Groups["value"].Value);
                }

                linesConsumed.Add(currentLine);
                lines.MoveNext();
            }

            return(linesConsumed);
        }
예제 #7
0
        protected override IEnumerable <string> ParseEvents(
            TrackingEnumerator <string> lines,
            ParseContext parseContext,
            ParserContext parserContext,
            ref IEnumerable <object> parsedEvents)
        {
            IDictionary <string, string> attributes = parserContext.StartGroupValues["Attributes"].ParseKeyValuePairs();

            attributes.TryGetValue("TriggerKeyword", out string triggerKeyword);

            attributes.TryGetValue("Entity", out string entity);
            IDictionary <string, string> entityAttributes = entity.Rem("[", "]").ParseKeyValuePairs();

            entityAttributes.TryGetValue("id", out string entityID);
            entityAttributes.TryGetValue("player", out string entityPlayer);

            int?playerID = null;

            if (int.TryParse(entityPlayer, out int parsedPlayerID))
            {
                playerID = parsedPlayerID;
            }

            parseContext.ParentBlock = new BlockContext(attributes, parseContext.ParentBlock);

            var events        = new List <object>();
            var linesConsumed = new List <string>();

            while (!lines.HasCompleted)
            {
                string currentLine = lines.Current;

                // Check if the current line ends this parser
                if (s_blockEndPattern.IsMatch(currentLine))
                {
                    linesConsumed.Add(currentLine);
                    lines.MoveNext();

                    parseContext.ParentBlock = parseContext.ParentBlock.ParentBlock;

                    parsedEvents = __CreateBlockEvents().Concat(events);

                    return(linesConsumed);
                }

                // Check if the current line is outside the scope of this parser
                if (!parserContext.NestedOffsetPattern.IsMatch(currentLine))
                {
                    parseContext.ParentBlock = parseContext.ParentBlock.ParentBlock;

                    parsedEvents = __CreateBlockEvents().Concat(events);

                    return(linesConsumed);
                }

                IEnumerable <string> innerLinesConsumed = null;

                foreach (IGameStateDebugEventParser parser in parseContext.Parsers)
                {
                    innerLinesConsumed = parser.TryParseEvents(lines, parseContext, out IEnumerable <object> innerEvents);
                    if (innerLinesConsumed == null)
                    {
                        continue;
                    }

                    linesConsumed.AddRange(innerLinesConsumed);

                    if (innerEvents == null)
                    {
                        return(linesConsumed);
                    }

                    events.AddRange(innerEvents);

                    break;
                }

                if (innerLinesConsumed == null)
                {
                    linesConsumed.Add(currentLine);
                    lines.MoveNext();
                }
            }

            return(linesConsumed);

            IEnumerable <object> __CreateBlockEvents()
            {
                var blockEvents = new List <object>();

                if (triggerKeyword.Eq("TOPDECK"))
                {
                    if (playerID.HasValue && parseContext.EntityMappings.TryGetValue(entityID, out string cardID))
                    {
                        blockEvents.Add(new GameEvents.CardRemovedFromDeck(playerID.Value, cardID));
                    }
                }

                return(blockEvents);
            }
        }