libtorrent4j

repository·master·Indexed 42 days ago

https://github.com/aldenml/libtorrent4j

A SWIG-generated Java interface for the libtorrent C++ library. It enables Java developers to implement BitTorrent features including WebTorrent support, sequential downloading, DHT, and BitTorrent Protocol v2. The library provides platform-specific artifacts for Android, macOS, Linux, and Windows, and includes the Entry class for handling bencoded data.

Tokens
1.6K
Snippets
8
Records
9
Agent score
5%

What's inside libtorrent4j

  1. Install libtorrent4j via Maven or Gradle

    master

    You can add libtorrent4j to your project using Maven or Gradle. Note that you must select the specific artifact corresponding to your target platform and architecture (e.g., libtorrent4j-android-arm64-v8a, libtorrent4j-macos, libtorrent4j-linux, or libtorrent4j-windows).

    <!-- Maven -->
    <dependency>
      <groupId>org.libtorrent4j</groupId>
      <artifactId>libtorrent4j</artifactId>
      <version>2.x.x</version>
    </dependency>
    
    <!-- Gradle -->
    compile 'org.libtorrent4j:libtorrent4j:2.x.x'
  2. Build Android binaries locally using Docker

    master

    To build Android binaries locally, you must have Docker installed. All operations should be performed within the swig/android-build directory.

    1. Build the Docker image (this is a one-time, long-running step): docker build -t lt4j:latest .

    2. Run the build script for your desired architecture (e.g., for ARM): ./build-arm.sh

    3. Collect the results: The generated JAR files will be located in build/libs at the root of the project.

    # 1. Build image
    docker build -t lt4j:latest .
    
    # 2. Build architecture (example for ARM)
    ./build-arm.sh
  3. Configure ProGuard for libtorrent4j

    master

    If you use ProGuard for obfuscation or minification, you must add the following rule to prevent the JNI bindings from being stripped or renamed, which would break the library's functionality.

    -keep class org.libtorrent4j.swig.libtorrent_jni {*;}
  4. How the Entry class works as a variant type

    master

    The Entry class represents a single node in a bencoded hierarchy. It acts as a variant type, meaning a single Entry instance can represent one of the following four types:

    1. String: Accessed via .string().
    2. Integer: Accessed via .integer().
    3. List: Accessed via .list(), which returns a List<Entry>.
    4. Dictionary: Accessed via .dictionary(), which returns a Map<String, Entry>.

    You can create an Entry from a raw string, a long integer, or by decoding bencoded data.

    // Creating entries from primitives
    Entry stringEntry = new Entry("hello");
    Entry intEntry = new Entry(42L);
    
    // Decoding from bytes
    byte[] data = ...;
    Entry decoded = Entry.bdecode(data);
    
    // Accessing data based on type
    if (decoded.string() != null) {
        String s = decoded.string();
    } else if (decoded.integer() != 0) {
        long n = decoded.integer();
    }
  5. Access Entry list and dictionary contents

    master

    Once you have an Entry representing a collection, you can interact with it using standard Java collection patterns:

    • Lists: Use .list() to get a List<Entry>. You can use .get(int index), .add(Entry entry), .size(), and .clear().
    • Dictionaries: Use .dictionary() to get a Map<String, Entry>. You can use .get(Object key), .put(String key, Entry value), .containsKey(Object key), and .size().

    Note: The EntryMap implementation does not support entrySet() and will throw an UnsupportedOperationException if called.

    // Iterating over a dictionary Entry
    Entry dictEntry = ...;
    Map<String, Entry> map = dictEntry.dictionary();
    for (Map.Entry<String, Entry> item : map.keySet().stream()
            .map(k -> Map.entry(k, map.get(k)))
            .toList()) {
        System.out.println(item.getKey() + ": " + item.getValue().toString());
    }
    
    // Accessing a list Entry
    Entry listEntry = ...;
    List<Entry> list = listEntry.list();
    Entry firstItem = list.get(0);
  6. Convert Java collections to an Entry

    master

    You can wrap standard Java collections into a bencoded Entry using the following static factory methods:

    • Entry.fromList(List<?> list): Converts a Java List into a bencoded list Entry.
    • Entry.fromMap(Map<String, ?> map): Converts a Java Map into a bencoded dictionary Entry.

    Supported types within these collections include String, Integer, Entry, List, and Map. Other types will be converted using their .toString() representation.

    // Create a dictionary Entry from a Map
    Map<String, Object> myMap = new HashMap<>();
    myMap.put("key", "value");
    myMap.put("count", 10);
    
    Entry dictEntry = Entry.fromMap(myMap);
  7. Decode bencoded data into an Entry

    master

    Use the static bdecode methods to convert bencoded bytes or files into an Entry object.

    • Entry.bdecode(byte[] data): Decodes a byte array.
    • Entry.bdecode(File file): Decodes a file from the filesystem (throws IOException).
    // From a byte array
    Entry entry = Entry.bdecode(new byte[]{...});
    
    // From a file
    File torrentFile = new File("example.torrent");
    Entry entryFromFile = Entry.bdecode(torrentFile);