Example #1
0
        private async Task ReceiveMessageLoop()
        {
            try
            {
                var stableBuffer = new byte[16];
                var buffer       = new byte[4096];
                while (this.Connected)
                {
                    await NetStream.ReadBAsync(stableBuffer, 0, 16);

                    var protocol = DanmakuProtocol.FromBuffer(stableBuffer);
                    if (protocol.PacketLength < 16)
                    {
                        throw new NotSupportedException("协议失败: (L:" + protocol.PacketLength + ")");
                    }
                    var payloadlength = protocol.PacketLength - 16;
                    if (payloadlength == 0)
                    {
                        continue;
                    }
                    buffer = new byte[payloadlength];
                    await NetStream.ReadBAsync(buffer, 0, payloadlength);

                    if (protocol.Version == 2 && protocol.Action == 5)
                    {
                        using (var ms = new MemoryStream(buffer, 2, payloadlength - 2))
                            using (var deflate = new DeflateStream(ms, CompressionMode.Decompress))
                            {
                                var headerbuffer = new byte[16];
                                try
                                {
                                    while (true)
                                    {
                                        await deflate.ReadBAsync(headerbuffer, 0, 16);

                                        var protocol_in = DanmakuProtocol.FromBuffer(headerbuffer);
                                        payloadlength = protocol_in.PacketLength - 16;
                                        var danmakubuffer = new byte[payloadlength];
                                        await deflate.ReadBAsync(danmakubuffer, 0, payloadlength);

                                        ProcessDanmaku(protocol.Action, danmakubuffer);
                                    }
                                }
                                catch { }
                            }
                    }
                    else
                    {
                        ProcessDanmaku(protocol.Action, buffer);
                    }
                }
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("ReceiveMessageLoop", ex);
                Disconnect();
            }
        }
Example #2
0
        private static unsafe void Parse2Protocol(byte[] buffer, out DanmakuProtocol protocol)
        {
            fixed(byte *ptr = buffer)
            {
                protocol = *(DanmakuProtocol *)ptr;
            }

            protocol.ChangeEndian();
        }
Example #3
0
        /// <summary>
        /// 消息拆包
        /// </summary>
        private void DepackDanmakuData(byte[] messages)
        {
            byte[] headerBuffer = new byte[16];
            //for (int i = 0; i < 16; i++)
            //{
            //    headerBuffer[i] = messages[i];
            //}
            Array.Copy(messages, 0, headerBuffer, 0, 16);
            DanmakuProtocol protocol = new DanmakuProtocol(headerBuffer);

            //Debug.LogError(protocol.Version + "\\" + protocol.Operation);
            //
            if (protocol.PacketLength < 16)
            {
                if (TroomId == 21446992)
                {
                    ;
                }
                InfoLog.InfoPrintf($@"协议失败: (L:{protocol.PacketLength})", InfoLog.InfoClass.Debug);
                InfoLog.InfoPrintf($@"{TroomId}房间收到协议PacketLength长度小于16,作为观测包更新心跳时间处理", InfoLog.InfoClass.Debug);
                ProcessDanmakuData(99, null, 0);
                //throw new NotSupportedException($@"协议失败: (L:{protocol.PacketLength})");
                return;
            }
            int bodyLength = protocol.PacketLength - 16;

            if (bodyLength == 0)
            {
                //continue;
                return;
            }
            byte[] buffer = new byte[bodyLength];
            //for (int i = 0; i < bodyLength; i++)
            //{
            //    buffer[i] = messages[i + 16];
            //}
            Array.Copy(messages, 16, buffer, 0, bodyLength);

            switch (protocol.Version)
            {
            case 1:
                ProcessDanmakuData(protocol.Operation, buffer, bodyLength);
                break;

            case 2:
            {
                var ms      = new MemoryStream(buffer, 2, bodyLength - 2);
                var deflate = new DeflateStream(ms, CompressionMode.Decompress);
                while (deflate.Read(headerBuffer, 0, 16) > 0)
                {
                    protocol   = new DanmakuProtocol(headerBuffer);
                    bodyLength = protocol.PacketLength - 16;
                    if (bodyLength == 0)
                    {
                        continue;                   // 没有内容了
                    }
                    if (buffer.Length < bodyLength) // 不够长再申请
                    {
                        buffer = new byte[bodyLength];
                    }
                    deflate.Read(buffer, 0, bodyLength);
                    ProcessDanmakuData(protocol.Operation, buffer, bodyLength);
                }
                ms.Dispose();
                deflate.Dispose();
                break;
            }

            case 3:
                ;
                break;

            case 5:
                ;
                break;

            case 7:
                ;
                break;

            case 8:
                ;
                break;

            default:
                ;
                break;
            }
        }
Example #4
0
        /// <summary>
        /// 消息拆包
        /// </summary>
        private void DepackDanmakuData(byte[] messages)
        {
            byte[] headerBuffer = new byte[16];
            //for (int i = 0; i < 16; i++)
            //{
            //    headerBuffer[i] = messages[i];
            //}
            Array.Copy(messages, 0, headerBuffer, 0, 16);
            DanmakuProtocol protocol = new DanmakuProtocol(headerBuffer);

            //Debug.LogError(protocol.Version + "\\" + protocol.Operation);
            //
            if (protocol.PacketLength < 16)
            {
                InfoLog.InfoPrintf($@"协议失败: (L:{protocol.PacketLength})", InfoLog.InfoClass.杂项提示);
                throw new NotSupportedException($@"协议失败: (L:{protocol.PacketLength})");
            }
            int bodyLength = protocol.PacketLength - 16;

            if (bodyLength == 0)
            {
                //continue;
                return;
            }
            byte[] buffer = new byte[bodyLength];
            //for (int i = 0; i < bodyLength; i++)
            //{
            //    buffer[i] = messages[i + 16];
            //}
            Array.Copy(messages, 16, buffer, 0, bodyLength);

            switch (protocol.Version)
            {
            case 1:    //弹幕数据
                ProcessDanmakuData(protocol.Operation, buffer, bodyLength);
                break;

            case 2:    //心跳数据
            {
                var ms      = new MemoryStream(buffer, 2, bodyLength - 2);
                var deflate = new DeflateStream(ms, CompressionMode.Decompress);
                while (deflate.Read(headerBuffer, 0, 16) > 0)
                {
                    protocol   = new DanmakuProtocol(headerBuffer);
                    bodyLength = protocol.PacketLength - 16;
                    if (bodyLength == 0)
                    {
                        continue;                   // 没有内容了
                    }
                    if (buffer.Length < bodyLength) // 不够长再申请
                    {
                        buffer = new byte[bodyLength];
                    }
                    deflate.Read(buffer, 0, bodyLength);
                    ProcessDanmakuData(protocol.Operation, buffer, bodyLength);
                }
                ms.Dispose();
                deflate.Dispose();
                break;
            }

            case 3:    //人气值
                ;
                break;

            case 5:    //命令
                ;
                break;

            case 7:    //认证信息
                ;
                break;

            case 8:    //服务器心跳包
                ;
                break;

            default:
                ;
                break;
            }
        }
    private void ReceiveMessageLoop()
    {
        Debug.Log("ReceiveMessageLoop Started!");
        try
        {
            var stableBuffer = new byte[16];
            var buffer       = new byte[4096];
            while (this.Connected)
            {
                NetStream.ReadB(stableBuffer, 0, 16);
                DanmakuProtocol protocol = Parse2Protocol(stableBuffer);

                if (protocol.PacketLength < 16)
                {
                    throw new NotSupportedException("协议失败: (L:" + protocol.PacketLength + ")");
                }
                var payloadlength = protocol.PacketLength - 16;
                if (payloadlength == 0)
                {
                    continue;                      //没有内容了
                }
                if (buffer.Length < payloadlength) // 不够长再申请
                {
                    buffer = new byte[payloadlength];
                }

                NetStream.ReadB(buffer, 0, payloadlength);

                if (protocol.Version == 2 && protocol.Action == 5) // 处理deflate消息
                {
                    // Skip 0x78 0xDA
                    using (DeflateStream deflate = new DeflateStream(new MemoryStream(buffer, 2, payloadlength - 2), CompressionMode.Decompress))
                    {
                        while (deflate.Read(stableBuffer, 0, 16) > 0)
                        {
                            protocol      = Parse2Protocol(stableBuffer);
                            payloadlength = protocol.PacketLength - 16;
                            if (payloadlength == 0)
                            {
                                continue;                      // 没有内容了
                            }
                            if (buffer.Length < payloadlength) // 不够长再申请
                            {
                                buffer = new byte[payloadlength];
                            }
                            deflate.Read(buffer, 0, payloadlength);
                            ProcessDanmaku(protocol.Action, buffer, payloadlength);
                        }
                    }
                }
                else
                {
                    ProcessDanmaku(protocol.Action, buffer, payloadlength);
                }
            }
        }
        catch (Exception ex)
        {
            this.Error = ex;
            _disconnect();
        }
    }