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(); } }
private static unsafe void Parse2Protocol(byte[] buffer, out DanmakuProtocol protocol) { fixed(byte *ptr = buffer) { protocol = *(DanmakuProtocol *)ptr; } protocol.ChangeEndian(); }
/// <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; } }
/// <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(); } }