Ejemplo n.º 1
0
        /// <inheritdoc />
        public override async Task <PackedGuid> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            //See: https://github.com/jackpoz/BotFarm/blob/592dbc9dbb58c06175bffecfced56eba42107c9a/Client/World/Network/InPacket.cs#L24
            var mask = await source.ReadByteAsync();

            if (mask == 0)
            {
                return(PackedGuid.Empty);
            }

            ulong res = 0;

            var i = 0;

            while (i < 8)
            {
                if ((mask & 1 << i) != 0)
                {
                    res += (ulong)(await source.ReadByteAsync()) << (i * 8);
                }

                i++;
            }

            return(new PackedGuid(res));
        }
        /// <inheritdoc />
        public override async Task <TBaseType> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //TODO: Handle 0 flags
            //Ask the key strategy for what flags are present
            int flags = await keyStrategy.ReadAsync(source)
                        .ConfigureAwait(false);         //defer to key reader (could be int, byte or something else)

            //TODO: Test perf
            foreach (ChildKeyPair childKey in serializers)
            {
                if ((childKey.Flags & flags) != 0)
                {
                    return((TBaseType)await childKey.Serializer.ReadAsync(source)
                           .ConfigureAwait(false));
                }
                ;
            }

            //If we didn't find a flags for it then try the default
            if (DefaultSerializer != null)
            {
                return((TBaseType)await DefaultSerializer.ReadAsync(source)
                       .ConfigureAwait(false));
            }
            else
            {
                throw new InvalidOperationException($"{this.GetType()} attempted to deserialize to a child type with Flags: {flags} but no valid type matches and there is no default type.");
            }
        }
        /// <inheritdoc />
        public override async Task <UpdateFieldValueCollection> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            //Update fields are sent with an inital byte size
            byte size = await source.ReadByteAsync();

            if (size == 0)
            {
                return(new UpdateFieldValueCollection(new WireReadyBitArray(0), Array.Empty <byte>()));
            }

            //TODO: Reduce allocation somehow.
            byte[] bytes = await source.ReadBytesAsync(size *sizeof(int));

            WireReadyBitArray mask = new WireReadyBitArray(bytes);

            //We know how many bytes the bitarray is suppose to be
            //but to know how many values are read we need to compute the bit size
            int updateValueSize = GetCardinality(mask.InternalArray);

            AssertSizeIsCorrect(mask, updateValueSize);

            //Once we have the mask AND the bytes we can construct the update values
            byte[] updateValueBytes = await source.ReadBytesAsync(updateValueSize *sizeof(int));

            return(new UpdateFieldValueCollection(mask, updateValueBytes));
        }
Ejemplo n.º 4
0
        public static async Task Test_Buffered_Peeking_Can_Peek_Counted_Bytes_Async()
        {
            //arrange
            DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[] { 5, 6, 7, 5 });

            //act
            IWireStreamReaderStrategyAsync peekedBufferReader = reader.PeekWithBufferingAsync();

            byte[] peekedBytes = await peekedBufferReader.PeekBytesAsync(4);

            byte[] peekedBytesAgain = await peekedBufferReader.PeekBytesAsync(2);

            byte[] readBytes = await peekedBufferReader.ReadBytesAsync(4);


            //assert
            Assert.AreEqual(4, readBytes.Length);
            for (int i = 0; i < peekedBytes.Length; i++)
            {
                Assert.AreEqual(peekedBytes[i], readBytes[i]);
            }

            for (int i = 0; i < peekedBytesAgain.Length; i++)
            {
                Assert.AreEqual(peekedBytes[i], peekedBytesAgain[i]);
            }

            Assert.Throws <InvalidOperationException>(() => peekedBufferReader.ReadByte());
        }
Ejemplo n.º 5
0
        public static async Task Test_Buffered_Peeking_Can_Peek_Bytes_Async()
        {
            //arrange
            DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[] { 5, 6, 7, 5 });

            //act
            IWireStreamReaderStrategyAsync peekedBufferReader = reader.PeekWithBufferingAsync();

            //assert
            for (int i = 0; i < 5; i++)
            {
                Assert.AreEqual(5, await peekedBufferReader.PeekByteAsync());
            }

            Assert.AreEqual(5, await peekedBufferReader.ReadByteAsync());
            Assert.AreEqual(6, await peekedBufferReader.ReadByteAsync());

            byte[] readBytes = await peekedBufferReader.ReadAllBytesAsync();

            Assert.AreEqual(7, readBytes[0]);
            Assert.AreEqual(5, readBytes[1]);

            Assert.Throws <AggregateException>(() =>
            {
                byte b = peekedBufferReader.ReadByteAsync().Result;
            });
        }
        /// <inheritdoc />
        public override Task SetMemberAsync(TContainingType obj, IWireStreamReaderStrategyAsync source)
        {
            //We need to reconvert the size back to bytes to reinsert into the stream
            //so that the collection can recieve it and then be able to deserialize the elements.
            byte[] bytes = ((TSizeType)SizeMemberGetter.Getter(obj)).Reinterpret();

            //We don't need to modify how we set the size member
            return(DecoratedMediator.SetMemberAsync(obj, source.PreprendWithBytesAsync(bytes)));
        }
        /// <inheritdoc />
        public override async Task <TType> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(DeserializeFromBuffer(await source.ReadBytesAsync(ByteRepresentationSize).ConfigureAwait(false)));
        }
        /// <inheritdoc />
        public async Task <int> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            //Read the key from the stream.
            TKeyType key = await KeyTypeSerializerStrategy
                           .ReadAsync(typeHandlingFlags.HasFlag(InformationHandlingFlags.DontConsumeRead)?source.WithOnlyPeekingAsync() : source)
                           .ConfigureAwait(false);

            return(GenericMath.Convert <TKeyType, int>(key));
        }
Ejemplo n.º 9
0
        /// <inheritdoc />
        public override async Task <bool> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(ConvertFromByte(await source.ReadByteAsync().ConfigureAwait(false)));
        }
        /// <inheritdoc />
        public override async Task SetMemberAsync(object obj, IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            await SetMemberAsync((TContainingType)obj, source)
            .ConfigureAwait(false);
        }
Ejemplo n.º 11
0
        /// <inheritdoc />
        public Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            //It's always a fixed size. Just reutnr the size.
            return(Task.FromResult(FixedSize));
        }
        /// <inheritdoc />
        public override Task <string> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //This is akward. If to terminator was sent we cannot really fall back to the default string reader.
            //Someone must decorate this and override the read. Otherwise this will almost assuredly fail.
            return(decoratedSerializer.ReadAsync(source));
        }
        /// <inheritdoc />
        public override async Task <TEnumType> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //TODO: Should be handle exceptions?
            return(GenericMath.Convert <TBaseType, TEnumType>(await serializerStrategy.ReadAsync(source)
                                                              .ConfigureAwait(false)));
        }
Ejemplo n.º 14
0
        /// <inheritdoc />
        public async Task SetMemberAsync(object obj, IWireStreamReaderStrategyAsync source)
        {
            //Check if we should read
            if (!(bool)isReadWriteEnabledGetter.Getter((TContainingType)obj))
            {
                return;
            }

            await DecoratedMediator.SetMemberAsync(obj, source)
            .ConfigureAwait(false);
        }
Ejemplo n.º 15
0
        /*private byte[] ConvertToByteArray(TType[] array)
         * {
         *      Span<TType> span = new Span<TType>(array);
         *
         *      return span.AsBytes();
         * }*/

        /// <inheritdoc />
        public override async Task <TType[]> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            int size = await SizeStrategyService.SizeAsync(source)
                       .ConfigureAwait(false);

            int byteCount = SizeOfType * size;

            byte[] bytes = await source.ReadBytesAsync(byteCount)
                           .ConfigureAwait(false);

            return(bytes.ReinterpretToArray <TType>());
        }
Ejemplo n.º 16
0
        /// <inheritdoc />
        public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            string value = await decoratedSerializer.ReadAsync(source)
                           .ConfigureAwait(false);

            return(new string(value.Reverse().ToArray()));
        }
Ejemplo n.º 17
0
        //Async implementation

        /// <inheritdoc />
        public virtual Task <TType> ReadIntoObjectAsync(TType obj, IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //We can't really write or read into an object on a simple type.

            //Default implementation is to just read the object from the source.
            return(ReadAsync(source));
        }
        /// <inheritdoc />
        public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            //See sync method for doc

            //TODO: Find an average size for WoW strings
            List <byte> stringBytes = new List <byte>();

            //This is used to track larger than 1 char null terminators
            int zeroByteCountFound = 0;

            //How many characters have been counted
            int currentCharCount = 0;

            do
            {
                byte currentByte = await source.ReadByteAsync()
                                   .ConfigureAwait(false);

                currentCharCount++;

                stringBytes.Add(currentByte);

                //If we find a 0 byte we need to track it
                //char could be 1 byte or even 4 so we need to reset
                //if we encounter an actual character before we find all
                //null terminator bytes
                if (currentByte == 0)
                {
                    zeroByteCountFound++;
                }
                else
                {
                    zeroByteCountFound = 0;
                }

                //if we found 4 0 bytes in arow but we didn't find a full char set of CharacterSize
                //then we should reset. This can happen if you have {5 0 0 0} {0 0 0 0} it will stop after the first 4
                //But with this is will read the whole {0 0 0 0}.
                if (currentCharCount % CharacterSize == 0 && zeroByteCountFound < CharacterSize)
                {
                    zeroByteCountFound = 0;
                }
            } while(zeroByteCountFound < CharacterSize);

            //TODO: Invesitgate expected WoW/TC behavior for strings of length 0. Currently violates contract for return type.
            //I have decided to support empty strings instead of null
            return(stringBytes.Count - CharacterSize <= 0 ? "" : EncodingStrategy.GetString(stringBytes.ToArray(), 0, Math.Max(0, stringBytes.Count - CharacterSize)));
        }
        /// <inheritdoc />
        public async Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            TSizeType size = await sizeSerializer.ReadAsync(reader)
                             .ConfigureAwait(false);

            //Using JonSkeets MiscUtils we can convert objects efficently
            return(GenericMath <TSizeType, int> .Convert(size) + AddedSize);
        }
        /// <inheritdoc />
        public override async Task SetMemberAsync(TContainingType obj, IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

#if NET35
            throw new NotImplementedException();
#else
            MemberSetter.Setter(obj, (TMemberType)await TypeSerializer.ReadAsync(source).ConfigureAwait(false));
#endif
        }
Ejemplo n.º 21
0
        /// <inheritdoc />
        public async Task <int> SizeAsync(IWireStreamReaderStrategyAsync reader)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }

            //Read the byte size from the stream.
            TSizeType result = await SizeTypeSerializerStrategy.ReadAsync(reader)
                               .ConfigureAwait(false);

            //Readd the addedsize so that we know how many items are really there.
            return(GenericMath.Convert <TSizeType, int>(result) + AddedSize);
        }
Ejemplo n.º 22
0
        /// <inheritdoc />
        public override async Task <TEnumType> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Read the string serialized version of the enum value
            string readString = await decoratedSerializer.ReadAsync(source)
                                .ConfigureAwait(false);

            //TODO: What should we do if it's empty or null?
            return((TEnumType)Enum.Parse(typeof(TEnumType), readString));
        }
Ejemplo n.º 23
0
        public static async Task Test_That_Prepended_Reader_Contains_Bytes_Async(byte[] bytes)
        {
            //arrange
            DefaultStreamReaderStrategyAsync reader = new DefaultStreamReaderStrategyAsync(new byte[0]);

            //act
            IWireStreamReaderStrategyAsync bufferedReader = reader.PreprendWithBytesAsync(bytes);

            //assert
            for (int i = 0; i < bytes.Length; i++)
            {
                Assert.AreEqual(await bufferedReader.ReadByteAsync(), bytes[i]);
            }
        }
        protected async Task SetMembersFromReaderDataAsync(TType obj, [NotNull] IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            // Tested, does not yield better perf
            // ReSharper disable once ForCanBeConvertedToForeach
            for (int i = 0; i < orderedMemberInfos.Length; i++)
            {
                await orderedMemberInfos[i].SetMemberAsync(obj, source)
                .ConfigureAwait(false);
            }
        }
        /// <inheritdoc />
        public override async Task <TComplexType> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            TComplexType obj = await ReadAsync(prototypeGeneratorService.Create(), source)
                               .ConfigureAwait(false);

            //invoke after deserialization if it's available
            (obj as ISerializationEventListener)?.OnAfterDeserialization();

            return(obj);
        }
        /// <inheritdoc />
        public override async Task <string> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //The size must come from the strategy provided
            int size = CharacterSize * await sizeProvider.SizeAsync(source)
                       .ConfigureAwait(false);

            byte[] bytes = await source.ReadBytesAsync(size)
                           .ConfigureAwait(false);

            return(EncodingStrategy.GetString(bytes).TrimEnd(NullTermincatorCharacterArray));
        }
        /// <inheritdoc />
        public override async Task <byte[]> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Must read size first before reverseing
            int size = await SizeStrategy.SizeAsync(source)
                       .ConfigureAwait(false);

            return(await source.WithOneTimeReadingAsync()
                   .WithByteReversalAsync()
                   .ReadBytesAsync(size)
                   .ConfigureAwait(false));
        }
Ejemplo n.º 28
0
        /// <inheritdoc />
        public override async Task <TObjectType[]> ReadAsync(IWireStreamReaderStrategyAsync source)
        {
            int size = await sizeStrategyService.SizeAsync(source).ConfigureAwait(false);

            TObjectType[] objectArray = new TObjectType[size];

            //TODO: Error handling
            //read as many objects as in the message (this is safe for clients. Not so safe if the client sent a message of this type)
            for (int i = 0; i < objectArray.Length; i++)
            {
                objectArray[i] = await decoratedSerializer.ReadAsync(source)
                                 .ConfigureAwait(false);
            }

            return(objectArray);
        }
        /// <inheritdoc />
        public override async Task <TType> ReadIntoObjectAsync(TType obj, IWireStreamReaderStrategyAsync source)
        {
            if (obj == null)
            {
                throw new ArgumentNullException(nameof(obj));
            }
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //Basically if someone calls this method they want us to set the members from the reader
            await SetMembersFromReaderDataAsync(obj, source)
            .ConfigureAwait(false);

            return(obj);
        }
        /// <inheritdoc />
        public override async Task <BitArray> ReadAsync([NotNull] IWireStreamReaderStrategyAsync source)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            //TODO: We should handle multiple types of sizes
            //WoW sends a byte for the block count and an int array. We use a surrogate to deserialize it
            byte size = await source.ReadByteAsync()
                        .ConfigureAwait(false);

            //Load the data for the bitmask
            //WoW sends the size as an int array but we can more efficiently read a byte array so we pretend
            //It is the same
            return(new BitArray(await source.ReadBytesAsync(size * sizeof(int)).ConfigureAwait(false)));
        }