use of net.dv8tion.jda.api.events.ExceptionEvent in project JDA by DV8FromTheWorld.
the class Request method onSuccess.
public void onSuccess(T successObj) {
if (done)
return;
done = true;
api.getCallbackPool().execute(() -> {
try (ThreadLocalReason.Closable __ = ThreadLocalReason.closable(localReason);
CallbackContext ___ = CallbackContext.getInstance()) {
onSuccess.accept(successObj);
} catch (Throwable t) {
RestActionImpl.LOG.error("Encountered error while processing success consumer", t);
if (t instanceof Error) {
api.handleEvent(new ExceptionEvent(api, t, true));
throw (Error) t;
}
}
});
}
use of net.dv8tion.jda.api.events.ExceptionEvent in project JDA by DV8FromTheWorld.
the class AudioWebSocket method handleCallbackError.
@Override
public void handleCallbackError(WebSocket websocket, Throwable cause) {
LOG.error("There was some audio websocket error", cause);
JDAImpl api = getJDA();
api.handleEvent(new ExceptionEvent(api, cause, true));
}
use of net.dv8tion.jda.api.events.ExceptionEvent in project JDA by DV8FromTheWorld.
the class AudioConnection method setupReceiveThread.
private synchronized void setupReceiveThread() {
if (receiveThread == null) {
receiveThread = new Thread(() -> {
getJDA().setContext();
try {
udpSocket.setSoTimeout(1000);
} catch (SocketException e) {
LOG.error("Couldn't set SO_TIMEOUT for UDP socket", e);
}
while (!udpSocket.isClosed() && !Thread.currentThread().isInterrupted()) {
DatagramPacket receivedPacket = new DatagramPacket(new byte[1920], 1920);
try {
udpSocket.receive(receivedPacket);
boolean shouldDecode = receiveHandler != null && (receiveHandler.canReceiveUser() || receiveHandler.canReceiveCombined());
boolean canReceive = receiveHandler != null && (receiveHandler.canReceiveUser() || receiveHandler.canReceiveCombined() || receiveHandler.canReceiveEncoded());
if (canReceive && webSocket.getSecretKey() != null) {
if (!couldReceive) {
couldReceive = true;
sendSilentPackets();
}
AudioPacket decryptedPacket = AudioPacket.decryptAudioPacket(webSocket.encryption, receivedPacket, webSocket.getSecretKey());
if (decryptedPacket == null)
continue;
int ssrc = decryptedPacket.getSSRC();
final long userId = ssrcMap.get(ssrc);
Decoder decoder = opusDecoders.get(ssrc);
if (userId == ssrcMap.getNoEntryValue()) {
ByteBuffer audio = decryptedPacket.getEncodedAudio();
// and as such, we haven't yet received information to pair the SSRC with the UserId.
if (!audio.equals(silenceBytes))
LOG.debug("Received audio data with an unknown SSRC id. Ignoring");
continue;
}
if (decoder == null) {
if (AudioNatives.ensureOpus()) {
opusDecoders.put(ssrc, decoder = new Decoder(ssrc));
} else if (!receiveHandler.canReceiveEncoded()) {
LOG.error("Unable to decode audio due to missing opus binaries!");
break;
}
}
OpusPacket opusPacket = new OpusPacket(decryptedPacket, userId, decoder);
if (receiveHandler.canReceiveEncoded())
receiveHandler.handleEncodedAudio(opusPacket);
if (!shouldDecode || !opusPacket.canDecode())
continue;
User user = getJDA().getUserById(userId);
if (user == null) {
LOG.warn("Received audio data with a known SSRC, but the userId associate with the SSRC is unknown to JDA!");
continue;
}
short[] decodedAudio = opusPacket.decode();
// If decodedAudio is null, then the Opus decode failed, so throw away the packet.
if (decodedAudio == null) {
// decoder error logged in method
continue;
}
if (receiveHandler.canReceiveUser()) {
receiveHandler.handleUserAudio(new UserAudio(user, decodedAudio));
}
if (receiveHandler.canReceiveCombined() && receiveHandler.includeUserInCombinedAudio(user)) {
Queue<AudioData> queue = combinedQueue.get(user);
if (queue == null) {
queue = new ConcurrentLinkedQueue<>();
combinedQueue.put(user, queue);
}
queue.add(new AudioData(decodedAudio));
}
} else if (couldReceive) {
couldReceive = false;
sendSilentPackets();
}
} catch (SocketTimeoutException e) {
// Ignore. We set a low timeout so that we wont block forever so we can properly shutdown the loop.
} catch (SocketException e) {
// The socket was closed while we were listening for the next packet.
// This is expected. Ignore the exception. The thread will exit during the next while
// iteration because the udpSocket.isClosed() will return true.
} catch (Exception e) {
LOG.error("There was some random exception while waiting for udp packets", e);
}
}
});
receiveThread.setUncaughtExceptionHandler((thread, throwable) -> {
LOG.error("There was some uncaught exception in the audio receive thread", throwable);
JDAImpl api = getJDA();
api.handleEvent(new ExceptionEvent(api, throwable, true));
});
receiveThread.setDaemon(true);
receiveThread.setName(threadIdentifier + " Receiving Thread");
receiveThread.start();
}
if (receiveHandler.canReceiveCombined()) {
setupCombinedExecutor();
}
}
use of net.dv8tion.jda.api.events.ExceptionEvent in project JDA by DV8FromTheWorld.
the class AudioConnection method prepareReady.
/* Used by AudioWebSocket */
protected void prepareReady() {
Thread readyThread = new Thread(() -> {
getJDA().setContext();
final long timeout = getGuild().getAudioManager().getConnectTimeout();
final long started = System.currentTimeMillis();
while (!webSocket.isReady()) {
if (timeout > 0 && System.currentTimeMillis() - started > timeout)
break;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
LOG.error("AudioConnection ready thread got interrupted while sleeping", e);
Thread.currentThread().interrupt();
}
}
if (webSocket.isReady()) {
setupSendSystem();
setupReceiveSystem();
} else {
webSocket.close(ConnectionStatus.ERROR_CONNECTION_TIMEOUT);
}
});
readyThread.setUncaughtExceptionHandler((thread, throwable) -> {
LOG.error("Uncaught exception in Audio ready-thread", throwable);
JDAImpl api = getJDA();
api.handleEvent(new ExceptionEvent(api, throwable, true));
});
readyThread.setDaemon(true);
readyThread.setName(threadIdentifier + " Ready Thread");
readyThread.start();
}
use of net.dv8tion.jda.api.events.ExceptionEvent in project JDA by DV8FromTheWorld.
the class AudioConnection method setupCombinedExecutor.
private synchronized void setupCombinedExecutor() {
if (combinedAudioExecutor == null) {
combinedAudioExecutor = Executors.newSingleThreadScheduledExecutor((task) -> {
final Thread t = new Thread(task, threadIdentifier + " Combined Thread");
t.setDaemon(true);
t.setUncaughtExceptionHandler((thread, throwable) -> {
LOG.error("I have no idea how, but there was an uncaught exception in the combinedAudioExecutor", throwable);
JDAImpl api = getJDA();
api.handleEvent(new ExceptionEvent(api, throwable, true));
});
return t;
});
combinedAudioExecutor.scheduleAtFixedRate(() -> {
getJDA().setContext();
try {
List<User> users = new LinkedList<>();
List<short[]> audioParts = new LinkedList<>();
if (receiveHandler != null && receiveHandler.canReceiveCombined()) {
long currentTime = System.currentTimeMillis();
for (Map.Entry<User, Queue<AudioData>> entry : combinedQueue.entrySet()) {
User user = entry.getKey();
Queue<AudioData> queue = entry.getValue();
if (queue.isEmpty())
continue;
AudioData audioData = queue.poll();
// Make sure the audio packet is younger than 100ms
while (audioData != null && currentTime - audioData.time > queueTimeout) {
audioData = queue.poll();
}
// If none of the audio packets were younger than 100ms, then there is nothing to add.
if (audioData == null) {
continue;
}
users.add(user);
audioParts.add(audioData.data);
}
if (!audioParts.isEmpty()) {
int audioLength = audioParts.stream().mapToInt(it -> it.length).max().getAsInt();
// 960 PCM samples for each channel
short[] mix = new short[1920];
int sample;
for (int i = 0; i < audioLength; i++) {
sample = 0;
for (Iterator<short[]> iterator = audioParts.iterator(); iterator.hasNext(); ) {
short[] audio = iterator.next();
if (i < audio.length)
sample += audio[i];
else
iterator.remove();
}
if (sample > Short.MAX_VALUE)
mix[i] = Short.MAX_VALUE;
else if (sample < Short.MIN_VALUE)
mix[i] = Short.MIN_VALUE;
else
mix[i] = (short) sample;
}
receiveHandler.handleCombinedAudio(new CombinedAudio(users, mix));
} else {
// No audio to mix, provide 20 MS of silence. (960 PCM samples for each channel)
receiveHandler.handleCombinedAudio(new CombinedAudio(Collections.emptyList(), new short[1920]));
}
}
} catch (Exception e) {
LOG.error("There was some unexpected exception in the combinedAudioExecutor!", e);
}
}, 0, 20, TimeUnit.MILLISECONDS);
}
}
Aggregations