/// <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); }
/// <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)); }
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(); } }
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); } } }
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); } }
//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); } }
/// <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 WriteAsync(byte[] bytes, int offset, int count) { return(DecoratedClient.WriteAsync(bytes, offset, count)); }
/// <inheritdoc /> public Task WriteAsync(TWritePayloadBaseType payload) { return(DecoratedClient.WriteAsync(payload)); }