Beispiel #1
0
        public async Task <IPacketHeader> ReadHeaderAsync(CancellationToken token)
        {
            //If the token is canceled just return null;
            if (token.IsCancellationRequested)
            {
                return(null);
            }

            //If we had access to the stream we could wrap it in a reader and use it
            //without knowing the size. Since we don't have access we must manually read
            int count = await DecoratedClient.ReadAsync(PacketHeaderBuffer, 0, PacketHeaderBuffer.Length, token)
                        .ConfigureAwait(false);        //TODO: How long should the timeout be if any?

            //This means the socket is disconnected
            if (count == 0)
            {
                return(null);
            }

            //If the token is canceled just return null;
            if (token.IsCancellationRequested)
            {
                return(null);
            }

            //This will deserialize
            return(Serializer.Deserialize <TPacketHeaderType>(PacketHeaderBuffer));
        }
        private async Task <bool> ReadAndDecrypt(byte[] buffer, int start, CancellationToken token, int extendedCount)
        {
            //We don't need to know the amount read, I think.
            int count = await DecoratedClient.ReadAsync(buffer, start, extendedCount, token)
                        .ConfigureAwait(false);

            //IF we read nothing then that means the socket disconnected
            if (count == 0)
            {
                return(false);
            }

            //Check cancel again, we want to fail quick
            if (token.IsCancellationRequested)
            {
                return(false);
            }

            //We throw above if we have an invalid size that can't be decrypted once read.
            //That means callers will need to be careful in what they request to read.
            DecryptionServiceProvider.Crypt(buffer, start, extendedCount);

            //Check cancel again, we want to fail quick
            if (token.IsCancellationRequested)
            {
                return(false);
            }

            return(true);
        }
 /// <inheritdoc />
 public override async Task ClearReadBuffers()
 {
     using (await ReadBuffer.BufferLock.LockAsync().ConfigureAwait(false))
     {
         //Reset the crypto buffer
         CryptoBlockOverflowReadIndex = CryptoBlockOverflow.Length;
         await DecoratedClient.ClearReadBuffers()
         .ConfigureAwait(false);
     }
 }
Beispiel #4
0
        /// <inheritdoc />
        public async Task <int> WriteHeaderAsync(IPacketHeader header)
        {
            //We only need to serialize and then write
            byte[] bytes = Serializer.Serialize(header);

            await DecoratedClient.WriteAsync(bytes)
            .ConfigureAwait(false);

            return(bytes.Length);
        }
Beispiel #5
0
        /// <inheritdoc />
        public async Task WriteAsync(TWritePayloadBaseType payload)
        {
            //Serializer the payload first so we can build the header
            byte[] payloadData = Serializer.Serialize(payload);

            using (await writeSynObj.LockAsync().ConfigureAwait(false))
            {
                //Write the outgoing message
                await DecoratedClient.WriteAsync(payloadData)
                .ConfigureAwait(false);
            }
        }
        public override Task WriteAsync(byte[] bytes, int offset, int count)
        {
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            return(DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count));
        }
        /// <summary>
        /// The Execute.
        /// </summary>
        /// <param name="request">The request<see cref="IRestRequest"/>.</param>
        /// <returns>The <see cref="IRestResponse"/>.</returns>
        public override IRestResponse Execute(IRestRequest request)
        {
            InjectAccessToken(request);
            IRestResponse response = DecoratedClient.Execute(request);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                RefreshAccessToken();
                InjectAccessToken(request);
                response = DecoratedClient.Execute(request);
            }

            return(response);
        }
        /// <summary>
        /// The ExecuteTaskAsync.
        /// </summary>
        /// <typeparam name="T">.</typeparam>
        /// <param name="request">The request<see cref="IRestRequest"/>.</param>
        /// <param name="token">The token<see cref="CancellationToken"/>.</param>
        /// <returns>The <see cref="Task{IRestResponse{T}}"/>.</returns>
        public override async Task <IRestResponse <T> > ExecuteTaskAsync <T>(IRestRequest request, CancellationToken token)
        {
            InjectAccessToken(request);
            IRestResponse <T> response = await DecoratedClient.ExecuteTaskAsync <T>(request, token);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                RefreshAccessToken();
                InjectAccessToken(request);
                response = await DecoratedClient.ExecuteTaskAsync <T>(request, token);
            }

            return(response);
        }
        /// <summary>
        /// The ExecuteTaskAsync.
        /// </summary>
        /// <param name="request">The request<see cref="IRestRequest"/>.</param>
        /// <returns>The <see cref="Task{IRestResponse}"/>.</returns>
        public override async Task <IRestResponse> ExecuteTaskAsync(IRestRequest request)
        {
            InjectAccessToken(request);
            IRestResponse response = await DecoratedClient.ExecuteTaskAsync(request);

            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                RefreshAccessToken();
                InjectAccessToken(request);
                response = await DecoratedClient.ExecuteTaskAsync(request);
            }

            return(response);
        }
        /// <inheritdoc />
        public async Task <NetworkIncomingMessage <TReadPayloadBaseType> > ReadAsync(CancellationToken token)
        {
            using (await ReadLock.LockAsync(token).ConfigureAwait(false))
            {
                //We want to clear the read buffers after reaiding a full message.
                NetworkIncomingMessage <TReadPayloadBaseType> message = await DecoratedClient.ReadAsync(token)
                                                                        .ConfigureAwait(false);

                //Do not call the object's ClearBuffer or we will deadlock; isn't re-enterant
                await DecoratedClient.ClearReadBuffers()
                .ConfigureAwait(false);

                //Could be null if the socket disconnected
                return(message);
            }
        }
Beispiel #11
0
        private async Task CryptAndSend(byte[] payloadData, int offset, int payloadBytesCount)
        {
            //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween
            using (await writeSynObj.LockAsync().ConfigureAwait(!GladMMOAsyncSettings.ConfigureAwaitFalseSupported))
            {
                //TODO: Optimize the header size writing.
                //We skip the first 2 bytes of the payload because it contains the opcode
                //Which is suppose to be in the header. Therefore we don't wnat to write it twice
                await DecoratedClient.WriteAsync(((short)payloadBytesCount).Reinterpret(), 0, 2)
                .ConfigureAwaitFalseVoid();

                //We skip the first 2 bytes of the payload because it contains the opcode
                //Which is suppose to be in the header. Therefore we don't wnat to write it twice
                await DecoratedClient.WriteAsync(payloadData, offset, payloadBytesCount)
                .ConfigureAwaitFalseVoid();
            }
        }
Beispiel #12
0
        private async Task CryptAndSend(byte[] payloadData, int offset, int payloadBytesCount)
        {
            //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween
            using (await writeSynObj.LockAsync().ConfigureAwait(false))
            {
                //Custom 317 Protocol:
                //2 byte short payload length.
                //1 byte opcode (in the payload data).

                //TODO: Optimize the header size writing.
                await DecoratedClient.WriteAsync(((short)payloadBytesCount).Reinterpret(), 0, 2)
                .ConfigureAwait(false);

                //1 byte opcode is basically type information in the payload data.
                await DecoratedClient.WriteAsync(payloadData, offset, payloadBytesCount)
                .ConfigureAwait(false);
            }
        }
        /// <inheritdoc />
        public async Task WriteAsync(TWritePayloadBaseType payload)
        {
            //Serializer the payload first so we can build the header
            byte[] payloadData = Serializer.Serialize(payload);

            IPacketHeader header = PacketHeaderFactory.Create(payload, payloadData);

            //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween
            using (await writeSynObj.LockAsync().ConfigureAwait(false))
            {
                //It's important to always write the header first
                await HeaderReaderWriter.WriteHeaderAsync(header)
                .ConfigureAwait(false);

                //Write the outgoing message, it will internally create the header and it will be serialized
                await DecoratedClient.WriteAsync(payloadData)
                .ConfigureAwait(false);
            }
        }
        public override async Task WriteAsync(byte[] bytes, int offset, int count)
        {
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(offset));
            }
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            int blocksizeAdjustedCount = ConvertToBlocksizeCount(count);

            if (count == blocksizeAdjustedCount)
            {
                await DecoratedClient.WriteAsync(EncryptionServiceProvider.Crypt(bytes, offset, count), offset, count)
                .ConfigureAwait(false);
            }
            else
            {
                //Lock because we use the crypto buffer for this
                using (await WriteBuffer.BufferLock.LockAsync().ConfigureAwait(false))
                {
                    try
                    {
                        //We copy to the thread local buffer so we can use it as an extended buffer by "neededBytes" many more bytes.
                        //So the buffer is very large but we'll tell it to write bytes.length + neededBytes.
                        BufferUtil.QuickUnsafeCopy(bytes, offset, WriteBuffer.Buffer, 0, count);                         //dont copy full array, might only need less with count
                    }
                    catch (Exception e)
                    {
                        throw new InvalidOperationException($"Failed to copy bytes to crypto buffer. Bytes Length: {bytes.Length} Offset: {offset} Count: {count} BlocksizeAdjustedCount: {blocksizeAdjustedCount}", e);
                    }

                    EncryptionServiceProvider.Crypt(WriteBuffer.Buffer, 0, blocksizeAdjustedCount);

                    //recurr to write the bytes with the now properly sized buffer.
                    await DecoratedClient.WriteAsync(WriteBuffer.Buffer, 0, blocksizeAdjustedCount)
                    .ConfigureAwait(false);
                }
            }
        }
Beispiel #15
0
        private async Task CryptAndSend(byte[] payloadData, byte[] clientPacketHeader, int payloadBytesOffset, int payloadBytesCount)
        {
            //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween
            using (await writeSynObj.LockAsync().ConfigureAwait(false))
            {
                //We should check crypto first. If it's init then we need to encrypt the serverPacketHeader
                if (CryptoService.isInitialized)                //TODO: This is a hack, can we fix this?
                {
                    CryptoService.EncryptionService.ProcessBytes(clientPacketHeader, 0, clientPacketHeader.Length, clientPacketHeader, 0);
                }

                //It's important to always write the header first
                await DecoratedClient.WriteAsync(clientPacketHeader)
                .ConfigureAwait(false);

                //We skip the first 2 bytes of the payload because it contains the opcode
                //Which is suppose to be in the header. Therefore we don't wnat to write it twice
                await DecoratedClient.WriteAsync(payloadData, 2 + payloadBytesOffset, payloadBytesCount - 2)
                .ConfigureAwait(false);
            }
        }
Beispiel #16
0
        //TODO: Validate sizes
        private async Task CryptAndSend(byte[] payloadData, byte[] serverPacketHeader, int payloadDataOffset, int payloadDataCount)
        {
            //VERY critical we lock here otherwise we could write a header and then another unrelated body could be written inbetween
            using (await writeSynObj.LockAsync().ConfigureAwait(false))
            {
                //We should check crypto first. If it's init then we need to encrypt the serverPacketHeader
                if (CryptoService.isInitialized)
                {
                    CryptoService.EncryptionService.ProcessBytes(serverPacketHeader, 0, serverPacketHeader.Length, serverPacketHeader, 0);

                    //Encrypt the opcode on the payload data too
                    CryptoService.EncryptionService.ProcessBytes(payloadData, payloadDataOffset, 2, payloadData, payloadDataOffset);
                }

                //It's important to always write the header first
                await DecoratedClient.WriteAsync(serverPacketHeader)
                .ConfigureAwait(false);

                await DecoratedClient.WriteAsync(payloadData, payloadDataOffset, payloadDataCount)
                .ConfigureAwait(false);
            }
        }
Beispiel #17
0
        /// <inheritdoc />
        public override async Task WriteAsync(byte[] bytes, int offset, int count)
        {
            if (count < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(count));
            }

            //If we have more bytes than we require buffering till
            //we should just write
            //We have to lock to prevent anything from touching the combined or buffer inbetween
            using (await BufferedData.BufferLock.LockAsync().ConfigureAwait(false))
                using (await CombinedBuffer.BufferLock.LockAsync().ConfigureAwait(false))
                {
                    if (count > BufferedData.Buffer.Length && CurrentIndex == -1)
                    {
                        await DecoratedClient.WriteAsync(bytes, offset, count)
                        .ConfigureAwait(false);
                    }
                    else if (count + CurrentIndex + 1 > BufferedData.Buffer.Length && CurrentIndex != -1)
                    {
                        //TODO: Do this somehow without copying
                        BufferUtil.QuickUnsafeCopy(BufferedData.Buffer, 0, CombinedBuffer.Buffer, 0, CurrentIndex + 1);
                        BufferUtil.QuickUnsafeCopy(bytes, offset, CombinedBuffer.Buffer, CurrentIndex + 1, count);

                        await DecoratedClient.WriteAsync(CombinedBuffer.Buffer, 0, count + CurrentIndex + 1)
                        .ConfigureAwait(false);

                        CurrentIndex = -1;
                    }
                    else
                    {
                        //At this point we know that the buffer isn't large enough to write so we need to buffer it
                        BufferUtil.QuickUnsafeCopy(bytes, offset, BufferedData.Buffer, CurrentIndex + 1, count);
                        CurrentIndex += count;
                    }
                }
        }
 /// <inheritdoc />
 public override Task DisconnectAsync(int delay)
 {
     return(DecoratedClient.DisconnectAsync(delay));
 }
 /// <inheritdoc />
 public override async Task <int> ReadAsync(byte[] buffer, int start, int count, CancellationToken token)
 {
     using (await ReadLock.LockAsync(token).ConfigureAwait(false))
         return(await DecoratedClient.ReadAsync(buffer, start, count, token)
                .ConfigureAwait(false));
 }
 public override Task <bool> ConnectAsync(string ip, int port)
 {
     return(DecoratedClient.ConnectAsync(ip, port));
 }
Beispiel #21
0
 /// <inheritdoc />
 public override async Task ClearReadBuffers()
 {
     using (await readSynObj.LockAsync().ConfigureAwait(false))
         await DecoratedClient.ClearReadBuffers()
         .ConfigureAwait(false);
 }
Beispiel #22
0
 /// <inheritdoc />
 public override Task ClearReadBuffers()
 {
     return(DecoratedClient.ClearReadBuffers());
 }
Beispiel #23
0
 /// <inheritdoc />
 public override async Task ClearReadBuffers()
 {
     using (await readSynObj.LockAsync().ConfigureAwait(!GladMMOAsyncSettings.ConfigureAwaitFalseSupported))
         await DecoratedClient.ClearReadBuffers()
         .ConfigureAwaitFalseVoid();
 }
 /// <inheritdoc />
 public override Task WriteAsync(byte[] bytes, int offset, int count)
 {
     return(DecoratedClient.WriteAsync(bytes, offset, count));
 }
Beispiel #25
0
 /// <inheritdoc />
 public override Task <int> ReadAsync(byte[] buffer, int start, int count, CancellationToken token)
 {
     return(DecoratedClient.ReadAsync(buffer, start, count, token));
 }
 /// <inheritdoc />
 public Task WriteAsync(TWritePayloadBaseType payload)
 {
     return(DecoratedClient.WriteAsync(payload));
 }