Пример #1
0
        private static byte[] EncodeToBytes(DecodedDeck deck)
        {
            if (deck == null || deck.Heroes == null || deck.Cards == null)
            {
                return(null);
            }

            //Combine hero and normal cards and sort by id
            List <CardId> heroesSorted = deck.Heroes.Select(x => (CardId)x).OrderBy(x => x, new SortByComparer()).ToList();
            List <CardId> cardsSorted  = deck.Cards.Select(x => (CardId)x).OrderBy(x => x, new SortByComparer()).ToList();

            int           countHeroes = deck.Heroes.Count;
            List <CardId> allCards    = heroesSorted.Concat(cardsSorted).ToList();

            byte[] bytes = new byte[0];
            //our version and hero count
            int  intVersion = CurrentVersion << 4 | ExtractNBitsWithCarry(countHeroes, 3);
            byte version    = (byte)intVersion;

            if (!AddByte(ref bytes, version))
            {
                return(null);
            }

            //the checksum which will be updated at the end
            byte nDummyChecksum = 0;
            int  nChecksumByte  = bytes.Length;

            bool addByteResult = AddByte(ref bytes, nDummyChecksum);

            if (!addByteResult)
            {
                return(null);
            }

            // write the name size
            int    nameLen = 0;
            string name    = "";

            if (!string.IsNullOrEmpty(deck.Name))
            {
                // replace strip_tags() with your own HTML santizer or escaper.
                name = Helper.StripTags(deck.Name);
                int trimLen = name.Length;

                while (trimLen > 63)
                {
                    int amountToTrim = (int)Math.Floor((trimLen - 63.0) / 4.0);
                    amountToTrim = (amountToTrim > 1) ? amountToTrim : 1;
                    name         = name.Substring(0, name.Length - amountToTrim);
                    trimLen      = name.Length;
                }

                nameLen = name.Length;
            }

            addByteResult = AddByte(ref bytes, (byte)nameLen);
            if (!addByteResult)
            {
                return(null);
            }

            int  keepCount    = countHeroes;
            bool bufferResult = AddRemainingNumberToBuffer(ref countHeroes, 3, ref bytes);

            if (!bufferResult)
            {
                return(null);
            }

            int unChecksum = 0;
            int prevCardId = 0;

            for (int unCurrHero = 0; unCurrHero < keepCount; unCurrHero++)
            {
                CardId      card   = allCards[unCurrHero];
                DecodedHero casted = null;
                if (card is DecodedHero)
                {
                    casted = (DecodedHero)card;
                }
                else
                {
                    continue;
                }

                if (casted.Turn == 0)
                {
                    continue;
                }

                bufferResult = AddCardToBuffer(casted.Turn, card.Id - prevCardId, ref bytes, unChecksum);
                if (!bufferResult)
                {
                    continue;
                }

                prevCardId = casted.Id;
            }

            //reset our card offset
            prevCardId = 0;

            //now all of the cards
            for (int nCurrCard = countHeroes; nCurrCard < allCards.Count; nCurrCard++)
            {
                //see how many cards we can group together
                CardId card = allCards[nCurrCard];
                if (card.Id <= 0)
                {
                    continue;
                }

                DecodedCard castedCard = null;
                if (card is DecodedCard)
                {
                    castedCard = (DecodedCard)card;
                }
                else
                {
                    continue;
                }

                if (castedCard.Count == 0)
                {
                    continue;
                }

                //record this set of cards, and advance
                bufferResult = AddCardToBuffer(castedCard.Count, castedCard.Id - prevCardId, ref bytes, unChecksum);
                if (!bufferResult)
                {
                    continue;
                }

                prevCardId = castedCard.Id;
            }

            // save off the pre string bytes for the checksum
            int preStringByteCount = bytes.Length;

            //write the string
            if (!string.IsNullOrEmpty(name))
            {
                byte[] nameBytes = System.Text.Encoding.UTF8.GetBytes(name);
                foreach (byte nameByte in nameBytes)
                {
                    addByteResult = AddByte(ref bytes, nameByte);
                    if (!addByteResult)
                    {
                        return(null);
                    }
                }
            }

            int unFullChecksum  = ComputeChecksum(ref bytes, preStringByteCount - HeaderSize);
            int unSmallChecksum = (unFullChecksum & 0x0FF);

            bytes[nChecksumByte] = (byte)unSmallChecksum;

            return(bytes);
        }
Пример #2
0
        private static DecodedDeck ParseDeck(string deckCode, byte[] deckBytes)
        {
            int nCurrentByteIndex = 0;
            int nTotalBytes       = deckBytes.Length;

            byte nVersionAndHeroes = deckBytes[nCurrentByteIndex++];
            int  version           = nVersionAndHeroes >> 4;

            if (CURRENT_VERSION != version && version != 1)
            {
                return(null);
            }

            byte checksum = deckBytes[nCurrentByteIndex++];

            int nStringLength = 0;

            if (version > 1)
            {
                nStringLength = deckBytes[nCurrentByteIndex++];
            }
            int nTotalCardBytes = nTotalBytes - nStringLength;

            int computedChecksum = 0;

            for (int i = nCurrentByteIndex; i < nTotalCardBytes; i++)
            {
                computedChecksum += deckBytes[i];
            }

            var masked = (computedChecksum & 0xFF);

            if (checksum != masked)
            {
                return(null);
            }

            //read in our hero count (part of the bits are in the version, but we can overflow bits here
            var nNumHeroes = 0;

            if (!ReadVarEncodedUint32((int)nVersionAndHeroes, 3, deckBytes, ref nCurrentByteIndex, nTotalCardBytes, ref nNumHeroes))
            {
                return(null);
            }

            //now read in the heroes
            int nPrevCardBase         = 0;
            List <DecodedHero> heroes = new List <DecodedHero>();

            for (int nCurrHero = 0; nCurrHero < nNumHeroes; nCurrHero++)
            {
                int nHeroTurn   = 0;
                int nHeroCardID = 0;
                if (!ReadSerializedCard(deckBytes, ref nCurrentByteIndex, nTotalCardBytes, ref nPrevCardBase, ref nHeroTurn, ref nHeroCardID))
                {
                    return(null);
                }

                DecodedHero currentHero = new DecodedHero()
                {
                    Id   = nHeroCardID,
                    Turn = nHeroTurn,
                };

                heroes.Add(currentHero);
            }

            List <DecodedCard> cards = new List <DecodedCard>();

            nPrevCardBase = 0;
            while (nCurrentByteIndex < nTotalCardBytes)
            {
                int nCardCount = 0;
                int nCardID    = 0;
                if (!ReadSerializedCard(deckBytes, ref nCurrentByteIndex, nTotalBytes, ref nPrevCardBase, ref nCardCount, ref nCardID))
                {
                    return(null);
                }

                cards.Add(new DecodedCard()
                {
                    Id    = nCardID,
                    Count = nCardCount,
                });
            }

            string name = "";

            if (nCurrentByteIndex <= nTotalBytes)
            {
                byte[] bytes = deckBytes.Skip(deckBytes.Length - nStringLength).ToArray();
                name = System.Text.Encoding.UTF8.GetString(bytes);

                // replace strip_tags with an HTML sanitizer or escaper as needed.
                name = Helper.StripTags(name);
            }

            return(new DecodedDeck()
            {
                Heroes = heroes,
                Cards = cards,
                Name = name,
            });
        }