예제 #1
0
  /* Change playlist. The response comes as plain XML. */
  public void sendChangePlaylist(
      ChannelListener listener, Playlist playlist, String xml, String packetDescription)
      throws DespotifyException {
    /* Create channel and buffer. */
    Channel channel = new Channel("Change-Playlist-Channel", Channel.Type.TYPE_PLAYLIST, listener);
    byte[] xmlBytes = xml.getBytes();
    ByteBuffer buffer = ByteBuffer.allocate(2 + 17 + 4 + 4 + 4 + 1 + 1 + xmlBytes.length);

    /* Append channel id, playlist id and some bytes... */
    buffer.putShort((short) channel.getId());
    buffer.put(playlist.getByteUUID()); /* 16 bytes */
    buffer.put((byte) 0x00); // 0x00 for adding tracks, 0x02 for the rest?
    buffer.putInt(playlist.getRevision().intValue());
    buffer.putInt(playlist.getTracks().size());
    buffer.putInt(playlist.getChecksum().intValue()); /* -1: Create playlist. */
    buffer.put((byte) (playlist.isCollaborative() ? 0x01 : 0x00));
    buffer.put((byte) 0x03); /* Unknown */
    buffer.put(xmlBytes);
    buffer.flip();

    /* Register channel. */
    Channel.register(channel);

    /* Send packet. */
    this.sendPacket(PacketType.changePlaylist, buffer, packetDescription);
  }
예제 #2
0
  /* Request image using a 20 byte id. The response is a JPG. */
  public void sendImageRequest(ChannelListener listener, String id) throws DespotifyException {
    /* Create channel and buffer. */
    Channel channel = new Channel("Image-Channel", Channel.Type.TYPE_IMAGE, listener);
    ByteBuffer buffer = ByteBuffer.allocate(2 + 20);

    /* Append channel id and image hash. */
    buffer.putShort((short) channel.getId());
    buffer.put(Hex.toBytes(id));
    buffer.flip();

    /* Register channel. */
    Channel.register(channel);

    /* Send packet. */
    this.sendPacket(PacketType.image, buffer);
  }
예제 #3
0
  /* Request ads. The response is GZIP compressed XML. */
  public void sendAdRequest(ChannelListener listener, int type) throws DespotifyException {
    /* Create channel and buffer. */
    Channel channel = new Channel("Ad-Channel", Channel.Type.TYPE_AD, listener);
    ByteBuffer buffer = ByteBuffer.allocate(2 + 1);

    /* Append channel id and ad type. */
    buffer.putShort((short) channel.getId());
    buffer.put((byte) type);
    buffer.flip();

    /* Register channel. */
    Channel.register(channel);

    /* Send packet. */
    this.sendPacket(PacketType.requestAd, buffer);
  }
예제 #4
0
  /* Request AES key for a track. */
  public void sendAesKeyRequest(ChannelListener listener, Track track) throws DespotifyException {
    /* Create channel and buffer. */
    Channel channel = new Channel("AES-Key-Channel", Channel.Type.TYPE_AESKEY, listener);
    ByteBuffer buffer = ByteBuffer.allocate(20 + 16 + 2 + 2);

    /* Request the AES key for this file by sending the file id and track id. */
    buffer.put(Hex.toBytes(track.getFiles().get(0))); /* 20 bytes */
    buffer.put(track.getByteUUID()); /* 16 bytes */
    buffer.putShort((short) 0x0000);
    buffer.putShort((short) channel.getId());
    buffer.flip();

    /* Register channel. */
    Channel.register(channel);

    /* Send packet. */
    this.sendPacket(PacketType.requestKey, buffer);
  }
예제 #5
0
  /*
   * Request a part of the encrypted file from the server.
   *
   * The data should be decrypted using AES key in CTR mode
   * with AES key provided and a static IV, incremented for
   * each 16 byte data processed.
   */
  public void sendSubstreamRequest(ChannelListener listener, Track track, int offset, int length)
      throws DespotifyException {
    /* Create channel and buffer. */
    Channel channel = new Channel("Substream-Channel", Channel.Type.TYPE_SUBSTREAM, listener);
    ByteBuffer buffer = ByteBuffer.allocate(2 + 2 + 2 + 2 + 2 + 2 + 4 + 20 + 4 + 4);

    /* Append channel id. */
    buffer.putShort((short) channel.getId());

    /* Unknown 10 bytes. */
    buffer.putShort((short) 0x0800);
    buffer.putShort((short) 0x0000);
    buffer.putShort((short) 0x0000);
    buffer.putShort((short) 0x0000);
    buffer.putShort((short) 0x4e20);

    /* Unknown (static value) */
    buffer.putInt(200 * 1000);

    /* 20 bytes file id. */
    buffer.put(Hex.toBytes(track.getFiles().get(0)));

    if (offset % 4096 != 0 || length % 4096 != 0) {
      throw new IllegalArgumentException("Offset and length need to be a multiple of 4096.");
    }

    offset >>= 2;
    length >>= 2;

    /* Append offset and length. */
    buffer.putInt(offset);
    buffer.putInt(offset + length);
    buffer.flip();

    /* Register channel. */
    Channel.register(channel);

    /* Send packet. */
    this.sendPacket(PacketType.getSubStream, buffer);
  }