Beispiel #1
0
        private SendBuffer SpawnBuffer(WebSocketMessageType type, byte[] bytes, Action callback)
        {
            SendBuffer sendBuffer = null;

            if (pooledSendBuffers.Count <= 0)
            {
                sendBuffer = new SendBuffer
                {
                    type     = WebSocketMessageType.Text,
                    buffer   = new ArraySegment <byte>(bytes),
                    callback = callback
                };
                return(sendBuffer);
            }

            lock (pooledSendBuffers)
            {
                sendBuffer = pooledSendBuffers.Dequeue();
            }

            sendBuffer.type     = type;
            sendBuffer.buffer   = new ArraySegment <byte>(bytes);
            sendBuffer.callback = callback;

            return(sendBuffer);
        }
Beispiel #2
0
 private void SendCallback(IAsyncResult ar)
 {
     try
     {
         var socket = ar.AsyncState as System.Net.Sockets.Socket;
         int length = 0;
         length = socket.EndSend(ar);
         if (length > 0)
         {
             byte[] data = SendBuffer.ReadFromHead(length);
             SendBytesEvent(data);
             int remain = SendBuffer.Index;
             if (remain > 0)
             {
                 SendBytes(SendBuffer.Buffer, 0, SendBuffer.Index);
             }
         }
         else
         {
             DisconnectedEvent();
         }
     }
     catch (Exception e)
     {
         ExceptionEvent(e);
     }
 }
Beispiel #3
0
 public void Clear()
 {
     lock (clearLock)
     {
         isSend = false;
         if (sendDataQueue.Count > 0)
         {
             SendData cmd;
             if (!sendDataQueue.TryDequeue(out cmd))
             {
                 SpinWait spinWait = new SpinWait();
                 while (sendDataQueue.TryDequeue(out cmd))
                 {
                     spinWait.SpinOnce();
                 }
             }
         }
         if (InterimPacketBuffer != null)
         {
             Session.Pool.FixedBufferPool.Push(InterimPacketBuffer);
             InterimPacketBuffer = null;
         }
         while (ReceiveBuffers.Count > 0)
         {
             var packetBuffer = ReceiveBuffers.Dequeue();
             Session.Pool.FixedBufferPool.Push(packetBuffer);
         }
     }
     SendBuffer.Clear();
     NoComplateCmd = null;
     alreadyReceivePacketLength = 0;
     needReceivePacketLenght    = 0;
 }
 public void Clear()
 {
     SendBuffer.Clear();
     lock (clearLock)
     {
         isSend = false;
         if (sendDataQueue.Count > 0)
         {
             SendData cmd;
             while (sendDataQueue.TryDequeue(out cmd))
             {
             }
         }
         if (InterimPacketBuffer != null)
         {
             BufferPool.Push(InterimPacketBuffer);
             InterimPacketBuffer = null;
         }
         while (ReceiveBuffers.Count > 0)
         {
             var packetBuffer = ReceiveBuffers.Dequeue();
             BufferPool.Push(packetBuffer);
         }
     }
     NoComplateCmd = null;
     alreadyReceivePacketLength = 0;
     needReceivePacketLenght    = 0;
 }
Beispiel #5
0
 public void Send(byte[] datas)
 {
     lock (m_sendBufferList)
     {
         SendBuffer sb = new SendBuffer()
         {
             position = 0,
             buffer   = datas
         };
         m_sendBufferList.Add(sb);
         if (m_sendBufferList.Count == 1)
         {
             try
             {
                 IAsyncResult ar = m_clientSocket.BeginSend(sb.buffer, sb.position, sb.Size,
                                                            SocketFlags.None, new AsyncCallback(OnSendCallback), null);
                 //开启线程检查发送数据是否正确, 是否超时, 瞬间发送10000条数据,那这里岂不是瞬间要开启10000个线程,这里有问题哈!
                 ThreadPool.QueueUserWorkItem(CheckSendTimeout, ar);
             }
             catch (Exception exception)
             {
                 Debug.LogError("客户端发送Packet失败, Reason: " + exception.Message);
                 Close();
             }
         }
     }
 }
Beispiel #6
0
        private async Task SendThread()
        {
            try
            {
                isSendThreadRunning = true;
                while (!IsCtsCancel)
                {
                    SendBuffer buffer = null;
                    if (sendCaches.Count <= 0)
                    {
                        await Task.Delay(1);

                        continue;
                    }
                    lock (sendCaches)
                    {
                        buffer = sendCaches.Dequeue();
                    }
                    if (!IsCtsCancel)
                    {
                        await socket.SendAsync(buffer.buffer, buffer.type, true, cts.Token);

                        buffer.callback?.Invoke();
                    }
                }
            }
            catch (Exception e)
            {
                HandleError(e);
            }
            finally
            {
                isSendThreadRunning = false;
            }
        }
Beispiel #7
0
 /// <summary>
 /// Внутренняя реализация отправки сообщений
 /// </summary>
 /// <param name="Frames"></param>
 protected override void SendImplementation(IList <CanFrame> Frames)
 {
     foreach (var f in Frames)
     {
         SendBuffer.Enqueue(f);
     }
 }
Beispiel #8
0
        public void Test1()
        {
            var l1   = new List <string>();
            var l2   = new List <int>();
            var buff = new SendBuffer <string>(async x => { l1.Add(x); l2.Add(Thread.CurrentThread.ManagedThreadId); await Task.Delay(100); }, x => { });

            buff.Enqueue("1");
            Thread.Sleep(10);

            buff.Enqueue("2");
            buff.Enqueue("3");
            buff.Enqueue("4");
            buff.Enqueue("5");
            buff.Enqueue("6");
            buff.Enqueue("7");
            buff.Enqueue("8");
            buff.Enqueue("9");
            buff.Enqueue("10");

            Thread.Sleep(5000);

            buff.Enqueue("11");
            buff.Enqueue("12");
            buff.Enqueue("13");
            Thread.Sleep(1000);

            Assert.Equal(new[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13" }, l1);
        }
Beispiel #9
0
        protected override void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }

            if (disposing)
            {
                lock (SendBuffer)
                {
                    while (SendBuffer.GetAvailibleBytesAtBegin() > 0 && DateTime.Now - LastRecieved < disconnectTimeout)
                    {
                        Monitor.Wait(SendBuffer, resendTimeout);
                    }
                }

                stopping = true;
                udpclient.Close();

                Task.WaitAll(sendTask, recieveTask);
            }

            disposed = true;
        }
Beispiel #10
0
    //new player for me
    public static void sendCreateSelf()
    {
        // ====== 走pb 发送 ====== or 直接发送 =====
#if PROTOBUFF
        Rqst_CreateSelf data = new Rqst_CreateSelf();
        data.Account  = "" + 1000 + UnityEngine.Random.Range(1, 100);
        data.Password = "" + 123456;
        DebugTool.LogYellow("[TCP] sendCreateSelf 请求创建我方角色" + data.Account);
        connect_TCP.Send <Rqst_CreateSelf> ((short)NetCode.CreateSelf, data);
        GameProxy.mine        = new PlayerData();
        GameProxy.mine.userid = data.Account;
#else
        DebugTool.LogError("已经不许使用自写编码,请检察 UnityEngine里是否添加宏: PROTOBUFF");
        //===== 直接发送  自写的编码,无法对付可变长byte[]======
        SendBuffer.ResetIndex();
        SendBuffer.writeUshort(10000);         //cmd,  payload as below
        var r = UnityEngine.Random.Range(1, 100);
        SendBuffer.writeInt(9999 + r);         //accountid
//		SendBuffer.writeString ("gaohebing" + UnityEngine.Random.Range (0, 100));//nickname
//		SendBuffer.writeInt (1);//level
        SendBuffer.writeInt(123);         //password

        var    arr      = SendBuffer.GetBytes_HasData();
        byte[] sendbuff = new byte[arr.Length];
        Array.Copy(arr, sendbuff, sendbuff.Length);

        connect_TCP.SendBytes(sendbuff);
#endif
    }
Beispiel #11
0
        public void ReleaseTest()
        {
            SendBuffer target = new SendBuffer(); // TODO: 初始化为适当的值

            target.Release();
            Assert.Inconclusive("无法验证不返回值的方法。");
        }
Beispiel #12
0
        public bool SendAsync(byte[] bytes)
        {
            SendBuffer.StartPacket();
            // 写入包头
            SendBuffer.Buffer.WriteInt16(Packet.HEAD);
            // 写入包长
            SendBuffer.Buffer.WriteInt32(bytes.Length);
            // 写入数据
            SendBuffer.Buffer.WriteBytes(bytes, 0, bytes.Length);
            SendBuffer.EndPacket();
            bool result = true;

            if (!mSendAsync)
            {
                int count  = 0;
                int offset = 0;
                if (SendBuffer.GetFirstPacket(ref offset, ref count))
                {
                    mSendAsync = true;
                    SendEventArgs.SetBuffer(SendBuffer.Buffer.Bytes, offset, count);
                    result = AsyncNet.SendAsync(this);
                }
            }
            return(result);
        }
Beispiel #13
0
    byte[] PackingData(string _id, string _pw, string name)
    {
        int        size = _id.Length + _pw.Length + name.Length + (sizeof(int) * 3);
        SendBuffer data = new SendBuffer();

        data.buffer = new byte[size];
        data.size   = 0;
        data.offset = 0;

        Buffer.BlockCopy(BitConverter.GetBytes(_id.Length), 0, data.buffer, data.offset, sizeof(int));
        data.size   += sizeof(int);
        data.offset += sizeof(int);

        Buffer.BlockCopy(Encoding.Default.GetBytes(_id.ToCharArray()), 0, data.buffer, data.offset, _id.Length);
        data.size   += _id.Length;
        data.offset += _id.Length;

        Buffer.BlockCopy(BitConverter.GetBytes(_pw.Length), 0, data.buffer, data.offset, sizeof(int));
        data.size   += sizeof(int);
        data.offset += sizeof(int);

        Buffer.BlockCopy(Encoding.Default.GetBytes(_pw.ToCharArray()), 0, data.buffer, data.offset, _pw.Length);
        data.size   += _pw.Length;
        data.offset += _pw.Length;

        Buffer.BlockCopy(BitConverter.GetBytes(name.Length), 0, data.buffer, data.offset, sizeof(int));
        data.size   += sizeof(int);
        data.offset += sizeof(int);

        Buffer.BlockCopy(Encoding.Default.GetBytes(name.ToCharArray()), 0, data.buffer, data.offset, name.Length);
        data.size += name.Length;

        return(data.buffer);
    }
Beispiel #14
0
 //Agent发送数据包
 public void SendPacket(byte[] datas)
 {
     if (Valid() == false)
     {
         return;
     }
     lock (m_sendBufferList)
     {
         SendBuffer sb = new SendBuffer()
         {
             position = 0,
             buffer   = datas,
         };
         m_sendBufferList.Add(sb); //需要发送的数据包先放入到发送缓存列表中
         if (m_sendBufferList.Count == 1)
         {
             try
             {
                 m_socket.BeginSend(sb.buffer, sb.position, sb.Size, SocketFlags.None, OnSendCallback, m_socket);
             }
             catch (Exception exception)
             {
                 Debug.LogError("服务器BeginSend时失败, Reason: " + exception.Message);
                 Close();
             }
         }
     }
 }
Beispiel #15
0
 private void PushBuffer(SendBuffer sendBuffer)
 {
     lock (sendBuffers)
     {
         sendBuffers.Enqueue(sendBuffer);
     }
 }
        public void SendProcess()
        {
            SendBuffer.Clear(); //清除已发送的包
            int surplus = SendBuffer.Buffer.Length;

            FlushBuffer(ref surplus);
            if (surplus < SendBuffer.Buffer.Length)
            {
                if (Session.ConnectSocket != null)
                {
                    Session.SendEventArgs.SetBuffer(SendBuffer.Buffer, 0, SendBuffer.DataSize);
                    bool willRaiseEvent = Session.ConnectSocket.SendAsync(Session.SendEventArgs);
                    if (!willRaiseEvent)
                    {
                        Session.SendComplate();
                    }
                }
                else
                {
                    isSend = false;
                }
            }
            else
            {
                isSend = false;
            }
        }
Beispiel #17
0
        public void Send(String type, String data)
        {
            Status = ConnectionStatus.sending;

            var structure = new DataTemplate
            {
                Type = type,
                Data = data
            };

            try
            {
                string jsonString = JsonSerializer.Serialize(structure);

                Debug.WriteLine(" Send data: " + jsonString);
                SendBuffer buffer = new SendBuffer
                {
                    buff = Encoding.ASCII.GetBytes(jsonString + "\n")
                };


                _socket.BeginSend(buffer.buff, 0, buffer.buff.Length, 0, new AsyncCallback(SendCallback), buffer);
            }
            catch (Exception exc)
            {
                Error = -1;
                Debug.WriteLine(" Error while sending data: " + exc.Message.ToString());
            }
        }
        public void WriteMSGSize()
        {
//			msgSize = SendBuffer.sendbufIndex;
//			SendBuffer.sendbufIndex = 0;
//			SendBuffer.writeUint (msgSize);
            SendBuffer.last();
        }
Beispiel #19
0
        public void SpareSpaceTest()
        {
            SendBuffer target = new SendBuffer(); // TODO: 初始化为适当的值
            long       actual;

            actual = target.SpareSpace;
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #20
0
 public void Dispose()
 {
     Disconnect();
     SendBuffer.Dispose();
     SendBuffer = null;
     ReceiveBuffer.Dispose();
     ReceiveBuffer = null;
 }
        /// <summary>
        /// 获取数据比特流
        /// </summary>
        /// <returns></returns>
        public virtual void WriteMSG()
        {
//			SendBuf buf = BufferManager.getSendBuffer(opcode, true).writeUshort(cmd).writeBytes(bytes_strm).last();
            SendBuffer.writeShort(opcode);            //"WO"
            SendBuffer.writeInt(msgSize);             //uint
            SendBuffer.writeShort(cmd);
//			SendBuffer.sendbufIndex = 6;
        }
Beispiel #22
0
        public void IsFullTest()
        {
            SendBuffer target = new SendBuffer(); // TODO: 初始化为适当的值
            bool       actual;

            actual = target.IsFull;
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #23
0
        public void LengthTest()
        {
            SendBuffer target = new SendBuffer(); // TODO: 初始化为适当的值
            long       actual;

            actual = target.Length;
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #24
0
        public void BufferTest()
        {
            SendBuffer target = new SendBuffer(); // TODO: 初始化为适当的值

            byte[] actual;
            actual = target.Buffer;
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #25
0
 private void ReleaseBuffer(SendBuffer sendBuffer)
 {
     sendBuffer.buffer = default;
     lock (pooledSendBuffers)
     {
         pooledSendBuffers.Enqueue(sendBuffer);
     }
 }
Beispiel #26
0
        public void InstanceTest()
        {
            SendBuffer expected = new SendBuffer(); // TODO: 初始化为适当的值
            SendBuffer actual;

            actual = SendBuffer.Instance();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #27
0
 public void SendMessage(string msg)
 {
     lock (SendBuffer)
     {
         SendBuffer.Clear();
         SendBuffer.Write(msg);
         tcpClient.Client.Send(SendBuffer.Buffer, 0, SendBuffer.DataCount, SocketFlags.None);
     }
 }
Beispiel #28
0
 public void SendMessage(DataBase db)
 {
     lock (SendBuffer)
     {
         SendBuffer.Clear();
         SendBuffer.Write(db);
         tcpClient.Client.Send(SendBuffer.Buffer, 0, SendBuffer.DataCount, SocketFlags.None);
     }
 }
Beispiel #29
0
    /// <summary>
    /// 如果数据满了,且缓冲区内的数据是空的则返回需要发送的数据
    /// 调用Enqueue(...)后调用Dequeue(...),不能直接调用Dequeue(...)
    /// </summary>
    /// <param name="byteBuffer"></param>
    /// <param name="iOffset"></param>
    /// <param name="iLength"></param>
    /// <returns></returns>
    public void Enqueue(byte[] byteBuffer, long iOffset, long iLength)
    {
        if (byteBuffer == null)
        {
            throw new Exception("SendQueue.Enqueue(...) - byteBuffer == null error!");
        }

        if (iOffset < 0 || iOffset >= byteBuffer.Length)
        {
            throw new Exception("SendQueue.Enqueue(...) - iOffset < 0 || iOffset >= byteBuffer.Length error!");
        }

        if (iLength < 0 || iLength > byteBuffer.Length) // 如果iLength == 0就返回空,如果iLength == 0就跳过
        {
            throw new Exception("SendQueue.Enqueue(...) - iLength < 0 || iLength > byteBuffer.Length error!");
        }

        if ((byteBuffer.Length - iOffset) < iLength)
        {
            throw new Exception("SendQueue.Enqueue(...) - ( byteBuffer.Length - iOffset ) < iLength error!");
        }

        m_LockFlushAndPending.Enter();
        {
            do
            {
                if (m_FlushBuffer.IsNull == true)
                {
                    // nothing yet buffered
                    m_FlushBuffer = SendBuffer.Instance();

                    if (m_FlushBuffer.IsNull == true)
                    {
                        throw new Exception("SendQueue.Enqueue(...) - m_FlushBuffer.IsNull == true error!");
                    }
                }

                // 当前已经写入的字节
                long iBytesWritten = m_FlushBuffer.Write(byteBuffer, iOffset, iLength);

                iOffset += iBytesWritten;
                iLength -= iBytesWritten;

                // 写入需要发送的数据的大小
                m_WaitSendSize += iBytesWritten;

                // 如果数据没有满,且数据写入完毕则退出,返回空,不添加到集合内
                if (m_FlushBuffer.IsFull == true)
                {
                    // 如果满了添加到集合内的尾处
                    m_PendingBuffer.Enqueue(m_FlushBuffer);
                    m_FlushBuffer = SendBuffer.NullBuffer; // 置空再次请求缓存
                }
            } while (iLength > 0);
        }
        m_LockFlushAndPending.Exit();
    }
        public void DequeueTest()
        {
            SendQueue  target   = new SendQueue();  // TODO: 初始化为适当的值
            SendBuffer expected = new SendBuffer(); // TODO: 初始化为适当的值
            SendBuffer actual;

            actual = target.Dequeue();
            Assert.AreEqual(expected, actual);
            Assert.Inconclusive("验证此测试方法的正确性。");
        }
Beispiel #31
0
    /// <summary>  
    /// 清除数据  
    /// </summary>  
    public void Clear()
    {
        m_LockFlushAndPending.Enter();
        {
            while (m_PendingBuffer.Count > 0)
                m_PendingBuffer.Dequeue().Release();

            if (m_FlushBuffer.IsNull == false)
            {
                m_FlushBuffer.Release();
                m_FlushBuffer = SendBuffer.NullBuffer;
            }

            // 清空
            m_WaitSendSize = 0;
        }
        m_LockFlushAndPending.Exit();
    }
 private void Send(SendBuffer message)
 {
     _stream.Write(message.Buffer, message.Offset, message.Count);
 }
Beispiel #33
0
    /// <summary>  
    /// 获取当前的数据  
    /// </summary>  
    /// <returns></returns>  
    public SendBuffer Dequeue()
    {
        SendBuffer sendGram = SendBuffer.NullBuffer;

        m_LockFlushAndPending.Enter();
        {
            if (m_PendingBuffer.Count > 0)
            {
                sendGram = m_PendingBuffer.Dequeue();   // 再给出数据
            }
            else if (m_FlushBuffer.IsNull == false)
            {
                sendGram = m_FlushBuffer;               // 再给出数据
                m_FlushBuffer = SendBuffer.NullBuffer;
            }

            // 移去已发送的数据的大小
            m_WaitSendSize -= sendGram.Length;
        }
        m_LockFlushAndPending.Exit();

        return sendGram;
    }
Beispiel #34
0
    /// <summary>  
    /// 如果数据满了,且缓冲区内的数据是空的则返回需要发送的数据  
    /// 调用Enqueue(...)后调用Dequeue(...),不能直接调用Dequeue(...)  
    /// </summary>  
    /// <param name="byteBuffer"></param>  
    /// <param name="iOffset"></param>  
    /// <param name="iLength"></param>  
    /// <returns></returns>  
    public void Enqueue(byte[] byteBuffer, long iOffset, long iLength)
    {
        if (byteBuffer == null)
            throw new Exception("SendQueue.Enqueue(...) - byteBuffer == null error!");

        if (iOffset < 0 || iOffset >= byteBuffer.Length)
            throw new Exception("SendQueue.Enqueue(...) - iOffset < 0 || iOffset >= byteBuffer.Length error!");

        if (iLength < 0 || iLength > byteBuffer.Length) // 如果iLength == 0就返回空,如果iLength == 0就跳过
            throw new Exception("SendQueue.Enqueue(...) - iLength < 0 || iLength > byteBuffer.Length error!");

        if ((byteBuffer.Length - iOffset) < iLength)
            throw new Exception("SendQueue.Enqueue(...) - ( byteBuffer.Length - iOffset ) < iLength error!");

        m_LockFlushAndPending.Enter();
        {
            do
            {
                if (m_FlushBuffer.IsNull == true)
                {
                    // nothing yet buffered
                    m_FlushBuffer = SendBuffer.Instance();

                    if (m_FlushBuffer.IsNull == true)
                        throw new Exception("SendQueue.Enqueue(...) - m_FlushBuffer.IsNull == true error!");
                }

                // 当前已经写入的字节
                long iBytesWritten = m_FlushBuffer.Write(byteBuffer, iOffset, iLength);

                iOffset += iBytesWritten;
                iLength -= iBytesWritten;

                // 写入需要发送的数据的大小
                m_WaitSendSize += iBytesWritten;

                // 如果数据没有满,且数据写入完毕则退出,返回空,不添加到集合内
                if (m_FlushBuffer.IsFull == true)
                {
                    // 如果满了添加到集合内的尾处
                    m_PendingBuffer.Enqueue(m_FlushBuffer);
                    m_FlushBuffer = SendBuffer.NullBuffer; // 置空再次请求缓存
                }
            } while (iLength > 0);
        }
        m_LockFlushAndPending.Exit();
    }
        private void UpdateRecording()
        {
            uint size = 0;
            var result = (m_VoIP.GetAvailableVoice(out size));
            if (result == VoiceResult.OK)
            {
                result = m_VoIP.GetVoice(m_compressedVoiceBuffer, out size);
                Debug.Assert(result == VoiceResult.OK, "Get voice failed: " + result.ToString());

                if (MyFakes.ENABLE_VOICE_CHAT_DEBUGGING)
                {
                    ProcessBuffer(m_compressedVoiceBuffer, (int)size, Sync.MyId);
                }

                foreach (var player in Sync.Players.GetOnlinePlayers())
                {
                    if (player.Id.SerialId == 0 
                        && player.Id.SteamId != MySession.Static.LocalHumanPlayer.Id.SteamId 
                        && IsCharacterValid(player.Character) 
                        && m_voiceChatLogic.ShouldSendVoice(player)
                        && !MySandboxGame.Config.DontSendVoicePlayers.Contains(player.Id.SteamId))// check if that user wants messages from this user
                    {
                        SendBuffer buffer = new SendBuffer { CompressedVoiceBuffer = m_compressedVoiceBuffer,
                                                             NumElements = (int)(size / sizeof(byte)),
                                                             SenderUserId = (long)MySession.Static.LocalHumanPlayer.Id.SteamId};

                        if (Sync.IsServer)
                        {
                            MyMultiplayer.RaiseStaticEvent(x => SendVoicePlayer, player.Id.SteamId, (BitReaderWriter)buffer, new EndpointId(player.Id.SteamId));
                        }
                        else
                        {
                            MyMultiplayer.RaiseStaticEvent(x => SendVoice, player.Id.SteamId, (BitReaderWriter)buffer);
                        }

                        if (MyFakes.ENABLE_VOICE_CHAT_DEBUGGING)
                            m_debugSentVoice[player.Id.SteamId] = true;
                    }
                    else
                    {
                        if (MyFakes.ENABLE_VOICE_CHAT_DEBUGGING)
                            m_debugSentVoice[player.Id.SteamId] = false;
                    }
                }
            }
            else if (result == VoiceResult.NotRecording)
            {
                m_recording = false;

                if (MyFakes.ENABLE_VOICE_CHAT_DEBUGGING)
                {
                    var localUser = Sync.MyId;
                    if (!m_voices.ContainsKey(localUser))
                    {
                        var player = Sync.Players.GetPlayerById(new MyPlayer.PlayerId(localUser));
                        m_voices[localUser] = new MyEntity3DSoundEmitter(player.Character);
                    }

                    var emitter = m_voices[localUser];
                    if (m_receivedVoiceData.ContainsKey(localUser))
                    {
                        var data = m_receivedVoiceData[localUser];
                        emitter.PlaySound(data.UncompressedBuffer.ToArray(), (int)data.UncompressedBuffer.Count, m_VoIP.SampleRate);
                        data.ClearData();
                        data.ClearSpeakerTimestamp();
                        m_receivedVoiceData[localUser] = data;
                    }
                }
            }
        }