Skip to content

CrashSystemZ/jDRPC

Repository files navigation

jDRPC

JitPack Java 17+ License: MIT

Java Discord Rich Presence is a modern Java 17 library for Discord IPC / Rich Presence. It is lightweight, cross-platform and pure Java: Unix domain sockets on macOS/Linux (JDK 17+), named pipes on Windows (RandomAccessFile, no native code).

preview

Features

  • Java 17+ support
  • Pure Java: Unix domain sockets on macOS/Linux, RandomAccessFile named pipes on Windows
  • Rich Presence activity updates (set / clear activity)
  • Activity buttons, party info with privacy, timestamps, assets, secrets
  • Event listener support (ready, disconnect, error, activity join/spectate/join request)
  • Optional auto-reconnect with exponential backoff
  • Async API wrappers (connectAsync, setActivityAsync, ...)

Requirements

  • Java 17+
  • A running Discord desktop client
  • A Discord application CLIENT_ID from the Developer Portal

Installation

The library is hosted on JitPack. You must add the JitPack repository to your project first.

Gradle (Groovy DSL)

repositories {
    mavenCentral()
    maven { url 'https://jitpack.io' }
}

dependencies {
    implementation 'com.github.CrashSystemZ:jDRPC:v1.0.0'
}

Gradle (Kotlin DSL)

repositories {
    mavenCentral()
    maven("https://jitpack.io")
}

dependencies {
    implementation("com.github.CrashSystemZ:jDRPC:v1.0.0")
}

Maven

Add the JitPack repository to your pom.xml:

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

Then add the dependency:

<dependency>
    <groupId>com.github.CrashSystemZ</groupId>
    <artifactId>jDRPC</artifactId>
    <version>v1.0.0</version>
</dependency>

Quick start

import fun.crashsystem.jdrpc.DiscordIPC;
import fun.crashsystem.jdrpc.activity.Activity;
import fun.crashsystem.jdrpc.activity.ActivityType;

public class Example {
    public static void main(String[] args) {
        long clientId = 123456789012345678L;

        try (DiscordIPC discord = DiscordIPC.create(clientId)) {
            discord.connect();

            Activity activity = new Activity.Builder()
                    .setType(ActivityType.PLAYING)
                    .setState("Main Menu")
                    .setDetails("Building Discord rich presence")
                    .setLargeImage("game-logo", "jDRPC")
                    .setStartTimestamp(System.currentTimeMillis() / 1000L)
                    .addButton("GitHub", "https://github.com/")
                    .build();

            discord.setActivity(activity);

            System.out.println("Connected: " + discord.isConnected());
            System.out.println("State: " + discord.status());
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

Async usage

DiscordIPC client = DiscordIPC.create(clientId);
client.connectAsync().thenRun(() -> System.out.println("Connected asynchronously"));

client.setActivityAsync(activity)
      .thenAccept(resp -> System.out.println("Activity sent"))
      .exceptionally(err -> {
          err.printStackTrace();
          return null;
      });

Event handling + subscriptions

import fun.crashsystem.jdrpc.event.DiscordEventListener;
import fun.crashsystem.jdrpc.event.EventType;
import fun.crashsystem.jdrpc.entity.User;

DiscordIPC client = DiscordIPC.create(123456789012345678L);

client.addListener(new DiscordEventListener() {
    @Override
    public void onReady(User user) {
        System.out.println("Connected as: " + user.username());
    }

    @Override
    public void onActivityJoinRequest(User user) {
        System.out.println("Join request from: " + user.username());
    }

    @Override
    public void onError(int errorCode, String message) {
        System.err.println("Error: " + message + " (code " + errorCode + ")");
    }

    @Override
    public void onDisconnect(int errorCode, String message) {
        System.err.println("Disconnected: " + message + " (code " + errorCode + ")");
    }

    @Override
    public void onClose() {
        System.out.println("Connection closed");
    }
});

client.connect();
client.subscribe(EventType.ACTIVITY_JOIN_REQUEST);

You can subscribe only to event types with subscribable = true in EventType.

Configuration (optional)

import fun.crashsystem.jdrpc.DiscordIPCConfig;
import fun.crashsystem.jdrpc.entity.DiscordBuild;

DiscordIPC client = DiscordIPC.create(
    DiscordIPCConfig.builder()
        .clientId(123456789012345678L)
        .preferredBuilds(java.util.List.of(DiscordBuild.STABLE))
        .reconnect(true)
        .maxReconnectAttempts(5)
        .build()
);

Shutdown

  • disconnect() -- graceful IPC close
  • close() -- stop background threads and close connection
  • If created with try-with-resources, close() is called automatically.

Build this project

./gradlew build       # compile and package
./gradlew javadoc     # generate Javadoc

Notes

  • Timestamps are in Unix epoch seconds, not milliseconds.
  • JSON serialization uses com.google.gson (bundled).
  • Logging uses org.apache.logging.log4j:log4j-api as a compileOnly dependency — the consumer provides a Log4j2 implementation at runtime.
  • On Windows the connection uses RandomAccessFile with a polling read strategy: a synchronous pipe handle would deadlock if a blocking ReadFile ran concurrently with a WriteFile, so the read side polls RandomAccessFile.length() (which on Windows pipes reports buffered byte count) and only invokes read(...) once data is available. No native code or JNA is required.

About

jDRPC is a modern Java 17 library for Discord IPC / Rich Presence. It is lightweight, cross-platform and has no native dependencies.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages