/// <summary> /// The write. /// </summary> /// <param name="mxMessage"> /// The mx message. /// </param> /// <param name="protoWriter"> /// The proto writer. /// </param> private static void Write(MxMessage mxMessage, ProtoWriter protoWriter) { if (mxMessage.GetType() != typeof(MxMessage)) { ThrowUnexpectedSubtype(typeof(MxMessage), mxMessage.GetType()); } uint expr_2D = mxMessage.ProtocolID; if (expr_2D != 0u) { ProtoWriter.WriteFieldHeader(1, WireType.Variant, protoWriter); ProtoWriter.WriteUInt32(expr_2D, protoWriter); } uint expr_4A = mxMessage.Sequence; if (expr_4A != 0u) { ProtoWriter.WriteFieldHeader(2, WireType.Variant, protoWriter); ProtoWriter.WriteUInt32(expr_4A, protoWriter); } uint expr_67 = mxMessage.Ack; if (expr_67 != 0u) { ProtoWriter.WriteFieldHeader(3, WireType.Variant, protoWriter); ProtoWriter.WriteUInt32(expr_67, protoWriter); } uint expr_84 = mxMessage.AckBitfield; if (expr_84 != 0u) { ProtoWriter.WriteFieldHeader(4, WireType.Variant, protoWriter); ProtoWriter.WriteUInt32(expr_84, protoWriter); } MxPayload[] expr_A1 = mxMessage.Payloads; if (expr_A1 != null) { MxPayload[] array = expr_A1; for (int i = 0; i < array.Length; i++) { MxPayload expr_B5 = array[i]; if (expr_B5 != null) { ProtoWriter.WriteFieldHeader(6, WireType.String, protoWriter); SubItemToken token = ProtoWriter.StartSubItem(expr_B5, protoWriter); Write(expr_B5, protoWriter); ProtoWriter.EndSubItem(token, protoWriter); } } } }
/// <summary> /// Handles sending packets to the target endpoint. /// </summary> private void PerformSend() { this.m_SendAccumulator += this.m_DeltaTime; while (this.m_SendAccumulator >= this.GetSendTime()) { var queues = new[] { new KeyValuePair <uint, Queue <byte[]> >(MxMessage.RealtimeProtocol, this.m_PendingRealtimeSendPackets), new KeyValuePair <uint, Queue <byte[]> >(MxMessage.ReliableProtocol, this.m_PendingReliableSendPackets) }; foreach (var item in queues) { var protocol = item.Key; var queue = item.Value; byte[][] packets; if (protocol == MxMessage.ReliableProtocol) { // In reliable mode, we know the sender is MxReliability and that it's optimized it's // send calls for ~512 bytes. Thus we just take one packet and use that. packets = queue.Count > 0 ? new[] { queue.Peek() } : new byte[0][]; } else { // In real time mode, we use all of the currently queued packets and hope that the resulting // size is not larger than 512 bytes (or is otherwise fragmented and dropped along the way). packets = queue.ToArray(); } using (var memory = new MemoryStream()) { var message = new MxMessage { ProtocolID = protocol, Payloads = packets.Select(x => new MxPayload { Data = x }).ToArray(), Sequence = this.m_LocalSequenceNumber, Ack = this.m_RemoteSequenceNumber }; message.SetAckBitfield(this.m_ReceiveQueue.ToArray()); var serializer = new MxMessageSerializer(); serializer.Serialize(memory, message); var len = (int)memory.Position; memory.Seek(0, SeekOrigin.Begin); var bytes = new byte[len]; memory.Read(bytes, 0, len); if (len > 512 && protocol != MxMessage.ReliableProtocol) { // TODO: Probably fire an event here to warn that the queued messages exceeds the safe packet size. } try { try { this.m_SharedUdpClient.Send(bytes, bytes.Length, this.m_TargetEndPoint); this.m_SendQueue.Add(this.m_LocalSequenceNumber, this.GetUnixTimestamp()); this.m_SendMessageQueue.Add(this.m_LocalSequenceNumber, new KeyValuePair <uint, byte[][]>(protocol, packets)); this.m_LocalSequenceNumber++; if (protocol == MxMessage.ReliableProtocol) { // Only dequeue the pending send packet once we know that it's at least // left this machine successfully (otherwise there'd be no message lost // event if they got consumed by a SocketException). if (queue.Count > 0) { queue.Dequeue(); } } else { // Only clear the pending send packets once we know that they've at least // left this machine successfully (otherwise there'd be no message lost // event if they got consumed by a SocketException). queue.Clear(); } // Raise the OnMessageSent event. foreach (var packet in packets) { this.OnMessageSent(new MxMessageEventArgs { Client = this, Payload = packet }); } } catch (SocketException) { // We don't care. } } catch (ObjectDisposedException) { // We don't care. } } } this.m_SendAccumulator -= this.m_DeltaTime; } }
/// <summary> /// The read. /// </summary> /// <param name="mxMessage"> /// The mx message. /// </param> /// <param name="protoReader"> /// The proto reader. /// </param> /// <returns> /// The <see cref="MxMessage"/>. /// </returns> private static MxMessage Read(MxMessage mxMessage, ProtoReader protoReader) { int num; while ((num = protoReader.ReadFieldHeader()) > 0) { if (num != 1) { if (num != 2) { if (num != 3) { if (num != 4) { if (num != 6) { if (mxMessage == null) { var expr_170 = new MxMessage(); ProtoReader.NoteObject(expr_170, protoReader); mxMessage = expr_170; } protoReader.SkipField(); } else { if (mxMessage == null) { var expr_D9 = new MxMessage(); ProtoReader.NoteObject(expr_D9, protoReader); mxMessage = expr_D9; } MxPayload[] payloads = mxMessage.Payloads; var list = new List <MxPayload>(); int num2 = protoReader.FieldNumber; do { List <MxPayload> arg_111_0 = list; MxPayload arg_104_0 = null; SubItemToken token = ProtoReader.StartSubItem(protoReader); MxPayload arg_111_1 = Read(arg_104_0, protoReader); ProtoReader.EndSubItem(token, protoReader); arg_111_0.Add(arg_111_1); }while (protoReader.TryReadFieldHeader(num2)); MxPayload[] expr_124 = payloads; var array = new MxPayload[(num2 = (expr_124 != null) ? expr_124.Length : 0) + list.Count]; if (num2 != 0) { payloads.CopyTo(array, 0); } list.CopyTo(array, num2); array = array; if (array != null) { mxMessage.Payloads = array; } } } else { if (mxMessage == null) { var expr_A9 = new MxMessage(); ProtoReader.NoteObject(expr_A9, protoReader); mxMessage = expr_A9; } uint num3 = protoReader.ReadUInt32(); mxMessage.AckBitfield = num3; } } else { if (mxMessage == null) { var expr_79 = new MxMessage(); ProtoReader.NoteObject(expr_79, protoReader); mxMessage = expr_79; } uint num3 = protoReader.ReadUInt32(); mxMessage.Ack = num3; } } else { if (mxMessage == null) { var expr_49 = new MxMessage(); ProtoReader.NoteObject(expr_49, protoReader); mxMessage = expr_49; } uint num3 = protoReader.ReadUInt32(); mxMessage.Sequence = num3; } } else { if (mxMessage == null) { var expr_19 = new MxMessage(); ProtoReader.NoteObject(expr_19, protoReader); mxMessage = expr_19; } uint num3 = protoReader.ReadUInt32(); mxMessage.ProtocolID = num3; } } if (mxMessage == null) { var expr_198 = new MxMessage(); ProtoReader.NoteObject(expr_198, protoReader); mxMessage = expr_198; } return(mxMessage); }
/// <summary> /// The read. /// </summary> /// <param name="mxMessage"> /// The mx message. /// </param> /// <param name="protoReader"> /// The proto reader. /// </param> /// <returns> /// The <see cref="MxMessage"/>. /// </returns> private static MxMessage Read(MxMessage mxMessage, ProtoReader protoReader) { int num; while ((num = protoReader.ReadFieldHeader()) > 0) { if (num != 1) { if (num != 2) { if (num != 3) { if (num != 4) { if (num != 6) { if (mxMessage == null) { var expr_170 = new MxMessage(); ProtoReader.NoteObject(expr_170, protoReader); mxMessage = expr_170; } protoReader.SkipField(); } else { if (mxMessage == null) { var expr_D9 = new MxMessage(); ProtoReader.NoteObject(expr_D9, protoReader); mxMessage = expr_D9; } MxPayload[] payloads = mxMessage.Payloads; var list = new List<MxPayload>(); int num2 = protoReader.FieldNumber; do { List<MxPayload> arg_111_0 = list; MxPayload arg_104_0 = null; SubItemToken token = ProtoReader.StartSubItem(protoReader); MxPayload arg_111_1 = Read(arg_104_0, protoReader); ProtoReader.EndSubItem(token, protoReader); arg_111_0.Add(arg_111_1); } while (protoReader.TryReadFieldHeader(num2)); MxPayload[] expr_124 = payloads; var array = new MxPayload[(num2 = (expr_124 != null) ? expr_124.Length : 0) + list.Count]; if (num2 != 0) { payloads.CopyTo(array, 0); } list.CopyTo(array, num2); array = array; if (array != null) { mxMessage.Payloads = array; } } } else { if (mxMessage == null) { var expr_A9 = new MxMessage(); ProtoReader.NoteObject(expr_A9, protoReader); mxMessage = expr_A9; } uint num3 = protoReader.ReadUInt32(); mxMessage.AckBitfield = num3; } } else { if (mxMessage == null) { var expr_79 = new MxMessage(); ProtoReader.NoteObject(expr_79, protoReader); mxMessage = expr_79; } uint num3 = protoReader.ReadUInt32(); mxMessage.Ack = num3; } } else { if (mxMessage == null) { var expr_49 = new MxMessage(); ProtoReader.NoteObject(expr_49, protoReader); mxMessage = expr_49; } uint num3 = protoReader.ReadUInt32(); mxMessage.Sequence = num3; } } else { if (mxMessage == null) { var expr_19 = new MxMessage(); ProtoReader.NoteObject(expr_19, protoReader); mxMessage = expr_19; } uint num3 = protoReader.ReadUInt32(); mxMessage.ProtocolID = num3; } } if (mxMessage == null) { var expr_198 = new MxMessage(); ProtoReader.NoteObject(expr_198, protoReader); mxMessage = expr_198; } return mxMessage; }