protected internal void CheckIn(BufferSegment segment) { if (m_mgr != null) { m_mgr.CheckIn(segment); } }
/// <summary> /// Constructs a RealmPacketIn object given the buffer to read, the offset to read from, and the number of bytes to read. /// Do not use this, unless you have a BufferManager that ensures the BufferWrapper's content to be pinned. /// For self-managed RealmPackets, use <c>DisposableRealmPacketIn</c>. /// </summary> /// <param name="segment">buffer container to read from</param> /// <param name="offset">offset to read from relative to the segment offset</param> /// <param name="length">number of bytes to read</param> /// <param name="opcode">the opcode of this packet</param> public RealmPacketIn(BufferSegment segment, int offset, int length, RealmServerOpCode opcode, int headerSize) : base(segment, offset, length) { _packetID = opcode; Position = headerSize; _headerSize = headerSize; _oversizedPacket = (_headerSize == LARGE_PACKET_HEADER_SIZE); }
public static DisposableRealmPacketIn CreateFromOutPacket(BufferSegment oldSegment, BufferSegment newSegment, int offset, int totalLength) { var index = oldSegment.Offset + offset; var opcode = (RealmServerOpCode)(oldSegment.Buffer.Array[index + 2] | (oldSegment.Buffer.Array[index + 3] << 8)); return Create(opcode, oldSegment.Buffer.Array, oldSegment.Offset + offset + RealmPacketOut.HEADER_SIZE, totalLength - RealmPacketOut.HEADER_SIZE, newSegment); }
/// <summary> /// Tries to parse data that has been received. /// </summary> /// <param name="numBytes">the number of bytes waiting to be read</param> protected override bool OnReceive(BufferSegment segment) { var packet = new AuthPacketIn(segment, 0, _remainingLength); segment.IncrementUsage(); Console.WriteLine("S <- C: " + packet.PacketId); AuthPacketManager.Instance.HandlePacket(this, packet); _remainingLength = 0; return true; }
public static DisposableRealmPacketIn Create(PacketId opCode, byte[] outPacketContent, int contentOffset, int contentLength, BufferSegment segment) { #if DEBUG if (!Enum.IsDefined(typeof(RealmServerOpCode), opCode.RawId)) { throw new Exception("Packet had undefined Opcode: " + opCode); } #endif int headerSize = (contentLength > WCellDef.HEADER_CHANGE_THRESHOLD ? LARGE_PACKET_HEADER_SIZE : HEADER_SIZE); var totalLength = contentLength + headerSize; var packetSize = totalLength - (headerSize - 4); if (headerSize == LARGE_PACKET_HEADER_SIZE) { segment.Buffer.Array[segment.Offset] = (byte)((packetSize >> 16) | 0x80); segment.Buffer.Array[segment.Offset + 1] = (byte)(packetSize >> 8); segment.Buffer.Array[segment.Offset + 2] = (byte)packetSize; segment.Buffer.Array[segment.Offset + 3] = (byte)((int)opCode.RawId); segment.Buffer.Array[segment.Offset + 4] = (byte)(((int)opCode.RawId) >> 8); } else { segment.Buffer.Array[segment.Offset] = (byte)(packetSize >> 8); segment.Buffer.Array[segment.Offset + 1] = (byte)packetSize; segment.Buffer.Array[segment.Offset + 2] = (byte)((int)opCode.RawId); segment.Buffer.Array[segment.Offset + 3] = (byte)(((int)opCode.RawId) >> 8); } Array.Copy(outPacketContent, contentOffset, segment.Buffer.Array, segment.Offset + headerSize, contentLength); return new DisposableRealmPacketIn(segment, 0, totalLength, contentLength, (RealmServerOpCode)opCode.RawId); }
public void Send(BufferSegment segment, int length) { this.Send(segment.Buffer.Array, segment.Offset, length); }
/// <summary> /// </summary> /// <param name="segment"> /// </param> /// <returns> /// </returns> protected uint GetMessageNumber(BufferSegment segment) { var messageNumberArray = new byte[4]; messageNumberArray[3] = segment.SegmentData[16]; messageNumberArray[2] = segment.SegmentData[17]; messageNumberArray[1] = segment.SegmentData[18]; messageNumberArray[0] = segment.SegmentData[19]; uint reply = BitConverter.ToUInt32(messageNumberArray, 0); return reply; }
/// <summary> /// Called when a packet has been received and needs to be processed. /// </summary> /// <param name="numBytes">The size of the packet in bytes.</param> protected abstract bool OnReceive(BufferSegment buffer);
/// <summary> /// Copys the data in this segment to another <see cref="T:Cell.Core.BufferSegment" />. /// </summary> /// <param name="segment">the <see cref="T:Cell.Core.BufferSegment" /> instance to copy to</param> /// <param name="length">the amount of bytes to copy from this segment</param> /// <exception cref="T:System.ArgumentException">an ArgumentException will be thrown if length is greater than /// the length of the segment</exception> public void CopyTo(BufferSegment segment, int length) { System.Buffer.BlockCopy(Buffer.Array, Offset, segment.Buffer.Array, segment.Offset, length); }
/// <summary> /// </summary> /// <param name="buffer"> /// </param> /// <returns> /// </returns> private int CheckData(BufferSegment buffer) { if (BitConverter.ToInt32(buffer.SegmentData, this._offset) != 0x00FF55AA) { Console.WriteLine("Invalid packet header"); return -1; } return BitConverter.ToInt32(buffer.SegmentData, this._offset + 4); }
/// <summary> /// </summary> /// <param name="buffer"> /// </param> /// <returns> /// </returns> /// <exception cref="NotImplementedException"> /// </exception> protected override bool OnReceive(BufferSegment buffer) { Message message = null; var packet = new byte[this._remainingLength]; Array.Copy(buffer.SegmentData, packet, this._remainingLength); LogUtil.Debug(DebugInfoDetail.Network, "\r\nReceived: \r\n" + HexOutput.Output(packet)); this._remainingLength = 0; try { message = this.messageSerializer.Deserialize(packet); } catch (Exception) { uint messageNumber = this.GetMessageNumber(packet); this.Server.Warning( this, "Client sent malformed message {0}", messageNumber.ToString(CultureInfo.InvariantCulture)); LogUtil.Debug(DebugInfoDetail.Error, HexOutput.Output(packet)); return false; } buffer.IncrementUsage(); if (message == null) { uint messageNumber = this.GetMessageNumber(packet); this.Server.Warning( this, "Client sent unknown message {0}", messageNumber.ToString(CultureInfo.InvariantCulture)); return false; } // FUUUUUGLY Type wrapperType = typeof(MessageWrapper<>); Type genericWrapperType = wrapperType.MakeGenericType(message.Body.GetType()); object wrapped = Activator.CreateInstance(genericWrapperType); wrapped.GetType().GetProperty("Client").SetValue(wrapped, (IZoneClient)this, null); wrapped.GetType().GetProperty("Message").SetValue(wrapped, message, null); wrapped.GetType().GetProperty("MessageBody").SetValue(wrapped, message.Body, null); this.bus.Publish(wrapped); return true; }
public static DisposableRealmPacketIn CreateFromOutPacket(BufferSegment segment, RealmPacketOut packet) { var bytes = packet.GetFinalizedPacket(); return Create(packet.PacketId, bytes, packet.HeaderSize, bytes.Length - packet.HeaderSize, segment); }
/// <summary> /// Copys the data in this segment to another <see cref="T:Cell.Core.BufferSegment" />. /// </summary> /// <param name="segment">the <see cref="T:Cell.Core.BufferSegment" /> instance to copy to</param> /// <param name="length">the amount of bytes to copy from this segment</param> /// <exception cref="T:System.ArgumentException">an ArgumentException will be thrown if length is greater than /// the length of the segment</exception> public void CopyTo(BufferSegment segment, int length) { System.Buffer.BlockCopy((Array)this.Buffer.Array, this.Offset, (Array)segment.Buffer.Array, segment.Offset, length); }
/// <summary> /// Default constructor. /// </summary> /// <param name="length">the length of bytes to read</param> public AuthPacketIn(BufferSegment segment, int length) : base(segment, 0, length) { }
/// <summary> /// </summary> /// <param name="buffer"> /// </param> /// <returns> /// </returns> protected override bool OnReceive(BufferSegment buffer) { if (this._remainingLength > 4) { byte[] packet = new byte[this._remainingLength]; Array.Copy(buffer.SegmentData, 0, packet, 0, this._remainingLength); LogUtil.Debug(DebugInfoDetail.Network, "\r\nReceived:\r\n" + HexOutput.Output(packet)); ushort messageNumber = this.GetMessageNumber(packet); Parser parser = new Parser(); return parser.Parse(this, packet, messageNumber); } // TODO: check what needs to be done if no suitable packet was found return true; }
/// <summary>Creates a new BufferSegment for the given buffer.</summary> /// <param name="bytes">the buffer to wrap</param> /// <returns>a new BufferSegment wrapping the given buffer</returns> /// <remarks>This will also create an underlying ArrayBuffer to pin the buffer /// for the BufferSegment. The ArrayBuffer will be disposed when the segment /// is released.</remarks> public static BufferSegment CreateSegment(byte[] bytes) { return(BufferSegment.CreateSegment(bytes, 0, bytes.Length)); }
public SegmentStream(BufferSegment segment) { _segment = segment; m_Position = _segment.Offset; }
/// <summary> /// </summary> public ISComV2ClientBase() { this._bufferSegment = Buffers.CheckOut(); }
/// <summary> /// </summary> /// <param name="args"> /// </param> private void ProcessRecieve(SocketAsyncEventArgs args) { try { int bytesReceived = args.BytesTransferred; if (bytesReceived == 0) { // if (args.SocketError != SocketError.Success) this.ServerDisconnected(); } else { // increment our counters unchecked { this._bytesReceived += (uint)bytesReceived; } Interlocked.Add(ref _totalBytesReceived, bytesReceived); this._remainingLength += bytesReceived; if (this.OnReceive(this._bufferSegment)) { // packet processed entirely this._offset = 0; this._remainingLength = 0; this._bufferSegment.DecrementUsage(); this._bufferSegment = Buffers.CheckOut(); } else { this.EnsureBuffer(); } this.ResumeReceive(); } } catch (ObjectDisposedException) { this.ServerDisconnected(); } catch (Exception e) { LogUtil.ErrorException(e); // Error occurred, need proper handler } finally { args.Completed -= this.ReceiveAsyncComplete; SocketHelpers.ReleaseSocketArg(args); } }
private void EnsureCapacity(int size) { // return the old segment and get a new, bigger one var newSegment = BufferManager.GetSegment(size); _segment.CopyTo(newSegment, _length); m_Position = m_Position - _segment.Offset + newSegment.Offset; _segment.DecrementUsage(); _segment = newSegment; }
private static void SendPacket(IRealmClient client, BufferSegment outputBuffer, int totalLength, int actualLength) { var offset = (uint)outputBuffer.Offset; outputBuffer.Buffer.Array.SetUShortBE(offset, (ushort)(totalLength - 2)); outputBuffer.Buffer.Array.SetBytes(offset + 2, BitConverter.GetBytes((ushort)RealmServerOpCode.SMSG_COMPRESSED_UPDATE_OBJECT)); // original length outputBuffer.Buffer.Array.SetBytes(offset + HEADER_SIZE, BitConverter.GetBytes((uint)actualLength)); client.Send(outputBuffer, totalLength); }
private void ProcessRecieve(SocketAsyncEventArgs args) { try { var bytesReceived = args.BytesTransferred; if (bytesReceived == 0) //if (args.SocketError != SocketError.Success) { // no bytes means the client disconnected, so clean up! _server.DisconnectClient(this, true); } else { // increment our counters unchecked { _bytesReceived += (uint)bytesReceived; } Interlocked.Add(ref _totalBytesReceived, bytesReceived); _remainingLength += bytesReceived; if (OnReceive(_bufferSegment)) { // packet processed entirely _offset = 0; _bufferSegment.DecrementUsage(); _bufferSegment = Buffers.CheckOut(); } else { EnsureBuffer(); } ResumeReceive(); } } catch (ObjectDisposedException) { _server.DisconnectClient(this, true); } catch (Exception e) { _server.Warning(this, e); _server.DisconnectClient(this, true); } finally { args.Completed -= ReceiveAsyncComplete; SocketHelpers.ReleaseSocketArg(args); } }
public DisposableRealmPacketIn(BufferSegment segment, int offset, int length, int contentLength, RealmServerOpCode packetId) : base(segment, offset, length, packetId, (length - contentLength)) { }
public static DisposableRealmPacketIn CreateFromOutPacket(BufferSegment oldSegment, BufferSegment newSegment, int totalLength) { return CreateFromOutPacket(oldSegment, newSegment, 0, totalLength); }
/// <summary> /// Constructs a PacketIn object given the buffer to read, the offset to read from, and the number of bytes to read. /// </summary> /// <param name="segment">The buffer container wrapping our data</param> /// <param name="offset">The offset to read from the data array</param> /// <param name="length">The number of bytes to read</param> protected PacketIn(BufferSegment segment, int offset, int length) : base(new MemoryStream(segment.Buffer.Array, segment.Offset + offset, length), DefaultEncoding) { _segment = segment; _offset = offset; }
/// <summary> /// Default constructor. /// </summary> /// <param name="offset">the zero-based index to read from</param> /// <param name="length">the length of bytes to read</param> public AuthPacketIn(BufferSegment segment, int offset, int length) : base(segment, offset, length) { _packetID = (AuthServerOpCode)ReadByte(); }
/// <summary>Default constructor</summary> /// <param name="server">The server this client is connected to.</param> protected ClientBase(ServerBase server) { this._server = server; this._bufferSegment = ClientBase.Buffers.CheckOut(); }
/// <summary> /// Default constructor /// </summary> /// <param name="server">The server this client is connected to.</param> protected ClientBase(ServerBase server) { _server = server; _bufferSegment = Buffers.CheckOut(); }
/// <summary> /// Requeues a segment into the buffer pool. /// </summary> /// <param name="segment">the segment to requeue</param> public void CheckIn(BufferSegment segment) { if (segment.m_uses > 1) { log.Error("Checked in segment (Size: {0}, Number: {1}) that is already in use! Queue contains: {2}, Buffer amount: {3}", segment.Length, segment.Number, _availableSegments.Count, _buffers.Count); } _availableSegments.Enqueue(segment); }
/// <summary> /// Makes sure the underlying buffer is big enough (but will never exceed BufferSize) /// </summary> /// <param name="size"></param> protected void EnsureBuffer() //(int size) { //if (size > BufferSize - _offset) { // not enough space left in buffer: Copy to new buffer var newSegment = Buffers.CheckOut(); Array.Copy(_bufferSegment.Buffer.Array, _bufferSegment.Offset + _offset, newSegment.Buffer.Array, newSegment.Offset, _remainingLength); _bufferSegment.DecrementUsage(); _bufferSegment = newSegment; _offset = 0; } }
/// <summary> /// Copys the data in this segment to another <see cref="BufferSegment" />. /// </summary> /// <param name="segment">the <see cref="BufferSegment" /> instance to copy to</param> /// <param name="length">the amount of bytes to copy from this segment</param> /// <exception cref="ArgumentException">an ArgumentException will be thrown if length is greater than /// the length of the segment</exception> public void CopyTo(BufferSegment segment, int length) { System.Buffer.BlockCopy(Buffer.Array, Offset, segment.Buffer.Array, segment.Offset, length); }
public void Send(BufferSegment segment, int length) { Send(segment.Buffer.Array, segment.Offset, length); }
/// <summary>Requeues a segment into the buffer pool.</summary> /// <param name="segment">the segment to requeue</param> public void CheckIn(BufferSegment segment) { this._availableSegments.Enqueue(segment); }
/// <summary> /// </summary> /// <param name="segment"> /// </param> /// <param name="length"> /// </param> /// <exception cref="NotImplementedException"> /// </exception> public void Send(BufferSegment segment, int length) { throw new NotImplementedException(); }
/// <summary> /// Pass recieved data into the packet buffer and try to parse. /// </summary> /// <param name="_remainingLength">number of bytes waiting to be read</param> /// <returns>false, if there is a part of a packet still remaining</returns> protected override bool OnReceive(BufferSegment segment) { var recvBuffer = segment.Buffer.Array; var i = 1; do { if (_remainingLength < RealmPacketIn.HEADER_SIZE) { return false; } RealmServerOpCode opcode; //var headerSize = GetContentInfo(recvBuffer, segment.Offset + _offset, out packetLength, out opcode); var offset = segment.Offset + _offset; int headerSize; bool isLargePacket; var packetLength = 0; if (IsEncrypted) { //headerSize = Decrypt(recvBuffer, offset, out packetLength, out opcode); var firstByte = GetDecryptedByte(recvBuffer, offset, 0); isLargePacket = (firstByte & 0x80) != 0; // check for the big packet marker if (isLargePacket) { // packetLength has 23 bits if (_remainingLength < RealmPacketIn.LARGE_PACKET_HEADER_SIZE) { decryptUntil = 0; log.Warn("DecryptUntil: " + decryptUntil); return false; } packetLength = (firstByte & 0x7F) << 16; packetLength |= GetDecryptedByte(recvBuffer, offset, 1) << 8; packetLength |= GetDecryptedByte(recvBuffer, offset, 2); opcode = (RealmServerOpCode)GetDecryptedOpcode(recvBuffer, offset, 3); headerSize = RealmPacketIn.LARGE_PACKET_HEADER_SIZE; } else { // packetLength has 15 bits packetLength |= firstByte << 8; packetLength |= GetDecryptedByte(recvBuffer, offset, 1); opcode = (RealmServerOpCode)GetDecryptedOpcode(recvBuffer, offset, 2); headerSize = RealmPacketIn.HEADER_SIZE; } } else { packetLength = recvBuffer[offset] << 8 | recvBuffer[offset + 1]; isLargePacket = false; // the opcode is actually 4 bytes, but can never go over 2, so we skip the last 2 opcode = (RealmServerOpCode)(recvBuffer[offset + 2] | recvBuffer[offset + 3] << 8); headerSize = RealmPacketIn.HEADER_SIZE; } packetLength += (headerSize - 4); if (packetLength > BufferSize) { // packet is just too big var bytes = new byte[headerSize]; Array.Copy(recvBuffer, offset, bytes, 0, headerSize); LogUtil.ErrorException("Client {0} sent corrupted packet (ID: {1}) with size {2} bytes, which exceeds maximum: " + "{3} (packet #{4}, segment #{5}, LargePacket: {6}, Remaining: {7}, Header: {8} ({9}))", this, opcode, packetLength, BufferSize, i, segment.Number, isLargePacket, _remainingLength, bytes.ToString(" ", b => string.Format("{0:X2}", b)), Encoding.ASCII.GetString(bytes)); Disconnect(); return false; } if (_remainingLength < packetLength) { // packet incomplete if (IsEncrypted) { decryptUntil = headerSize; log.Warn("DecryptUntil: {0}, HeaderSize: {1}, Packet: {2}", decryptUntil, headerSize, opcode); } return false; } var pkt = new RealmPacketIn(segment, _offset, packetLength, opcode, headerSize); segment.IncrementUsage(); //.UpdatePacketCounters(pkt.PacketId, fullPacketSize); PerformanceCounters.PacketsReceivedPerSecond.Increment(); PerformanceCounters.TotalBytesReceived.IncrementBy(packetLength); RealmPacketMgr.Instance.HandlePacket(this, pkt); _remainingLength -= packetLength; _offset += packetLength; decryptUntil = -1; i++; } while (_remainingLength > 0); return true; }
/// <summary> /// </summary> /// <param name="buffer"> /// </param> /// <returns> /// </returns> protected override bool OnReceive(BufferSegment buffer) { Message message = null; var packet = new byte[this._remainingLength]; Array.Copy(buffer.SegmentData, packet, this._remainingLength); LogUtil.Debug( DebugInfoDetail.Network, "Offset: " + buffer.Offset.ToString() + " -- RemainingLength: " + this._remainingLength); LogUtil.Debug(DebugInfoDetail.Network, HexOutput.Output(packet)); this._remainingLength = 0; try { message = this.messageSerializer.Deserialize(packet); } catch (Exception) { uint messageNumber = this.GetMessageNumber(packet); this.Server.Warning( this, "Client sent malformed message {0}", messageNumber.ToString(CultureInfo.InvariantCulture)); LogUtil.Debug(DebugInfoDetail.Error, HexOutput.Output(packet)); return false; } buffer.IncrementUsage(); if (message == null) { uint messageNumber = this.GetMessageNumber(packet); this.Server.Warning( this, "Client sent unknown message {0}", messageNumber.ToString(CultureInfo.InvariantCulture)); return false; } this.bus.Publish(new MessageReceivedEvent(this, message)); return true; }