Files
java-discord-sdk-wrapper/example/Bridge.java
2026-04-07 02:38:08 +02:00

88 lines
3.1 KiB
Java

package com.leohabrom.discordrpc;
import com.leohabrom.discord.DiscordActivity;
import com.leohabrom.discord.DiscordBridge;
import com.leohabrom.discord.DiscordBridgeAdapter;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
public class Bridge implements DiscordBridgeAdapter {
private final DiscordBridge bridge;
private final BlockingQueue<Boolean> feedbackQueue = new ArrayBlockingQueue<>(1);
// Scheduling tools
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
private final AtomicLong lastSendTime = new AtomicLong(0);
private final AtomicReference<DiscordActivity> pendingActivity = new AtomicReference<>();
private final AtomicReference<ScheduledFuture<?>> scheduledTask = new AtomicReference<>();
private DiscordActivity lastSentActivity = null;
public Bridge(long appId) {
this.bridge = new DiscordBridge();
this.bridge.init(appId);
this.bridge.setAdapter(this);
this.bridge.start();
}
/**
* Updates the activity. If called too fast, it buffers the latest
* request and sends it as soon as the rate limit allows.
*/
public void update(DiscordActivity activity) {
pendingActivity.set(activity);
long now = System.currentTimeMillis();
long timeSinceLastSend = now - lastSendTime.get();
long delayNeeded = 1000 - timeSinceLastSend;
if (delayNeeded <= 0) {
sendNow();
} else {
// If a task is already scheduled, don't create another one.
// The scheduled task will naturally pick up the "latest" pendingActivity.
if (scheduledTask.get() == null || scheduledTask.get().isDone()) {
ScheduledFuture<?> task = scheduler.schedule(this::sendNow, delayNeeded, TimeUnit.MILLISECONDS);
scheduledTask.set(task);
}
}
}
private void sendNow() {
DiscordActivity activity = pendingActivity.getAndSet(null);
if (activity != null) {
if (activity.equals(lastSentActivity)) {
return;
}
lastSentActivity = activity;
lastSendTime.set(System.currentTimeMillis());
bridge.update(activity);
}
}
public boolean updateWithFeedback(DiscordActivity activity) {
feedbackQueue.clear();
update(activity);
try {
// We wait a bit longer because the update might be delayed by the scheduler
Boolean result = feedbackQueue.poll(3, TimeUnit.SECONDS);
return result != null && result;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
@Override
public void onMessage(String message) {
if (message == null) return;
String msg = message.toLowerCase();
if (msg.contains("sent") || msg.contains("success")) {
feedbackQueue.offer(true);
} else if (msg.contains("fail") || msg.contains("error")) {
feedbackQueue.offer(false);
}
}
}