docs: public void fromBytes(byte[] data) {
          int index = 0;
          // 1. read protocol_version
          protocolVersion = data[index];
          index++;
          // 2. read server_version
          byte[] serverVersionBytes = ByteHelper.readNullTerminatedBytes(data, index);
          serverVersion = new String(serverVersionBytes);
          index += (serverVersionBytes.length + 1);
          // 3. read thread_id
          threadId = ByteHelper.readUnsignedIntLittleEndian(data, index);
          index += 4;
          // 4. read scramble_buff
          seed = ByteHelper.readFixedLengthBytes(data, index, 8);
          index += 8;
          index += 1; // 1 byte (filler) always 0x00
          // 5. read server_capabilities
          this.serverCapabilities = ByteHelper.readUnsignedShortLittleEndian(data, index);
          index += 2;
          if (data.length > index) {
              // 6. read server_language
              this.serverCharsetNumber = data[index];
              index++;
              // 7. read server_status
              this.serverStatus = ByteHelper.readUnsignedShortLittleEndian(data, index);
              index += 2;
              // 8. bypass filtered bytes
              int capabilityFlags2 = ByteHelper.readUnsignedShortLittleEndian(data, index);
              index += 2;
              int capabilities = (capabilityFlags2 << 16) | this.serverCapabilities;
              // int authPluginDataLen = -1;
              // if ((capabilities & Capability.CLIENT_PLUGIN_AUTH) != 0) {
              // authPluginDataLen = data[index];
              // }
              index += 1;
              index += 10;
              // 9. read rest of scramble_buff
              if ((capabilities & Capability.CLIENT_SECURE_CONNECTION) != 0) {
                  // int len = Math.max(13, authPluginDataLen - 8);
                  // this.authPluginDataPart2 =
                  // buffer.readFixedLengthString(len);// scramble2
  
                  // Packet规定最后13个byte是剩下的scrumble,
                  // 但实际上最后一个字节是0, 不应该包含在scrumble中.
                  this.restOfScrambleBuff = ByteHelper.readFixedLengthBytes(data, index, 12);
              }
  
              index += 12 + 1;
              if ((capabilities & Capability.CLIENT_PLUGIN_AUTH) != 0) {
                  this.authPluginName = ByteHelper.readNullTerminatedBytes(data, index);
              }
              // end read
          }
      }