Search in sources :

Example 16 with RestRequest

use of org.javacord.core.util.rest.RestRequest in project Javacord by BtoBastian.

the class RatelimitManager method handleResponse.

/**
 * Updates the ratelimit information and sets the result if the request was successful.
 *
 * @param request The request.
 * @param result The result of the request.
 * @param bucket The bucket the request belongs to.
 * @param responseTimestamp The timestamp directly after the response finished.
 */
private void handleResponse(RestRequest<?> request, RestRequestResult result, RatelimitBucket bucket, long responseTimestamp) {
    if (result == null || result.getResponse() == null) {
        return;
    }
    Response response = result.getResponse();
    boolean global = response.header("X-RateLimit-Global", "false").equalsIgnoreCase("true");
    int remaining = Integer.parseInt(response.header("X-RateLimit-Remaining", "1"));
    long reset = request.getEndpoint().getHardcodedRatelimit().map(ratelimit -> responseTimestamp + api.getTimeOffset() + ratelimit).orElseGet(() -> (long) (Double.parseDouble(response.header("X-RateLimit-Reset", "0")) * 1000));
    // Check if we received a 429 response
    if (result.getResponse().code() == 429) {
        if (response.header("Via") == null) {
            logger.warn("Hit a CloudFlare API ban! This means you were sending a very large " + "amount of invalid requests.");
            long retryAfter = Long.parseLong(response.header("Retry-after")) * 1000;
            RatelimitBucket.setGlobalRatelimitResetTimestamp(api, responseTimestamp + retryAfter);
            return;
        }
        long retryAfter = result.getJsonBody().isNull() ? 0 : (long) (result.getJsonBody().get("retry_after").asDouble() * 1000);
        if (global) {
            // We hit a global ratelimit. Time to panic!
            logger.warn("Hit a global ratelimit! This means you were sending a very large " + "amount within a very short time frame.");
            RatelimitBucket.setGlobalRatelimitResetTimestamp(api, responseTimestamp + retryAfter);
        } else {
            logger.debug("Received a 429 response from Discord! Recalculating time offset...");
            // Setting the offset to null causes a recalculate for the next request
            api.setTimeOffset(null);
            // Update the bucket information
            bucket.setRatelimitRemaining(0);
            bucket.setRatelimitResetTimestamp(responseTimestamp + retryAfter);
        }
    } else {
        // Check if we didn't already complete it exceptionally.
        CompletableFuture<RestRequestResult> requestResult = request.getResult();
        if (!requestResult.isDone()) {
            requestResult.complete(result);
        }
        // Update bucket information
        bucket.setRatelimitRemaining(remaining);
        bucket.setRatelimitResetTimestamp(reset);
    }
}
Also used : Response(okhttp3.Response) DiscordException(org.javacord.api.exception.DiscordException) Set(java.util.Set) CompletableFuture(java.util.concurrent.CompletableFuture) DiscordApiImpl(org.javacord.core.DiscordApiImpl) Function(java.util.function.Function) RestRequestResponseInformationImpl(org.javacord.core.util.rest.RestRequestResponseInformationImpl) HashSet(java.util.HashSet) LoggerUtil(org.javacord.core.util.logging.LoggerUtil) Logger(org.apache.logging.log4j.Logger) OffsetDateTime(java.time.OffsetDateTime) RestRequestResult(org.javacord.core.util.rest.RestRequestResult) DateTimeFormatter(java.time.format.DateTimeFormatter) RestRequest(org.javacord.core.util.rest.RestRequest) Response(okhttp3.Response) RestRequestResult(org.javacord.core.util.rest.RestRequestResult)

Example 17 with RestRequest

use of org.javacord.core.util.rest.RestRequest in project Javacord by BtoBastian.

the class ServerImpl method getAuditLogBefore.

@Override
public CompletableFuture<AuditLog> getAuditLogBefore(int limit, AuditLogEntry before, AuditLogActionType type) {
    CompletableFuture<AuditLog> future = new CompletableFuture<>();
    api.getThreadPool().getExecutorService().submit(() -> {
        try {
            AuditLogImpl auditLog = new AuditLogImpl(this);
            boolean requestMore = true;
            while (requestMore) {
                int requestAmount = limit - auditLog.getEntries().size();
                requestAmount = Math.min(requestAmount, 100);
                RestRequest<JsonNode> request = new RestRequest<JsonNode>(getApi(), RestMethod.GET, RestEndpoint.AUDIT_LOG).setUrlParameters(getIdAsString()).addQueryParameter("limit", String.valueOf(requestAmount));
                List<AuditLogEntry> lastAuditLogEntries = auditLog.getEntries();
                if (!lastAuditLogEntries.isEmpty()) {
                    // It's not the first request, so append a "before"
                    request.addQueryParameter("before", lastAuditLogEntries.get(lastAuditLogEntries.size() - 1).getIdAsString());
                } else if (before != null) {
                    // It's the first request, and we have a non-null "before" parameter
                    request.addQueryParameter("before", before.getIdAsString());
                }
                if (type != null) {
                    request.addQueryParameter("action_type", String.valueOf(type.getValue()));
                }
                JsonNode data = request.execute(RestRequestResult::getJsonBody).join();
                // Add the new entries
                auditLog.addEntries(data);
                // Check if we have to make another request
                requestMore = auditLog.getEntries().size() < limit && data.get("audit_log_entries").size() >= requestAmount;
            }
            future.complete(auditLog);
        } catch (Throwable t) {
            future.completeExceptionally(t);
        }
    });
    return future;
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) RestRequest(org.javacord.core.util.rest.RestRequest) AuditLogEntry(org.javacord.api.entity.auditlog.AuditLogEntry) AuditLogImpl(org.javacord.core.entity.auditlog.AuditLogImpl) JsonNode(com.fasterxml.jackson.databind.JsonNode) AuditLog(org.javacord.api.entity.auditlog.AuditLog) RestEndpoint(org.javacord.core.util.rest.RestEndpoint)

Example 18 with RestRequest

use of org.javacord.core.util.rest.RestRequest in project Javacord by BtoBastian.

the class InteractionMessageBuilderDelegateImpl method checkForAttachmentsAndExecuteRequest.

private CompletableFuture<Message> checkForAttachmentsAndExecuteRequest(RestRequest<Message> request, ObjectNode body) {
    if (!attachments.isEmpty() || embeds.stream().anyMatch(EmbedBuilder::requiresAttachments)) {
        CompletableFuture<Message> future = new CompletableFuture<>();
        // We access files etc. so this should be async
        request.getApi().getThreadPool().getExecutorService().submit(() -> {
            try {
                List<FileContainer> tempAttachments = new ArrayList<>(attachments);
                // Add the attachments required for the embed
                for (EmbedBuilder embed : embeds) {
                    tempAttachments.addAll(((EmbedBuilderDelegateImpl) embed.getDelegate()).getRequiredAttachments());
                }
                addMultipartBodyToRequest(request, body, tempAttachments, request.getApi());
                request.execute(result -> request.getApi().getOrCreateMessage(request.getApi().getTextChannelById(result.getJsonBody().get("channel_id").asLong()).orElseThrow(() -> new NoSuchElementException("TextChannel is not cached")), result.getJsonBody())).whenComplete((message, throwable) -> {
                    if (throwable != null) {
                        future.completeExceptionally(throwable);
                    } else {
                        future.complete(message);
                    }
                });
            } catch (Throwable t) {
                future.completeExceptionally(t);
            }
        });
        return future;
    } else {
        request.setBody(body);
        return request.execute(result -> request.getApi().getOrCreateMessage(request.getApi().getTextChannelById(result.getJsonBody().get("channel_id").asLong()).orElseThrow(() -> new NoSuchElementException("TextChannel is not cached")), result.getJsonBody()));
    }
}
Also used : InteractionCallbackDataFlag(org.javacord.api.interaction.callback.InteractionCallbackDataFlag) EmbedBuilder(org.javacord.api.entity.message.embed.EmbedBuilder) InteractionBase(org.javacord.api.interaction.InteractionBase) CompletableFuture(java.util.concurrent.CompletableFuture) RestMethod(org.javacord.core.util.rest.RestMethod) Message(org.javacord.api.entity.message.Message) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode) FileContainer(org.javacord.core.util.FileContainer) ArrayList(java.util.ArrayList) RestEndpoint(org.javacord.core.util.rest.RestEndpoint) List(java.util.List) JsonNodeFactory(com.fasterxml.jackson.databind.node.JsonNodeFactory) MessageComponentInteraction(org.javacord.api.interaction.MessageComponentInteraction) RestRequest(org.javacord.core.util.rest.RestRequest) EmbedBuilderDelegateImpl(org.javacord.core.entity.message.embed.EmbedBuilderDelegateImpl) InteractionImpl(org.javacord.core.interaction.InteractionImpl) NoSuchElementException(java.util.NoSuchElementException) EnumSet(java.util.EnumSet) InteractionMessageBuilderDelegate(org.javacord.api.entity.message.internal.InteractionMessageBuilderDelegate) CompletableFuture(java.util.concurrent.CompletableFuture) EmbedBuilder(org.javacord.api.entity.message.embed.EmbedBuilder) Message(org.javacord.api.entity.message.Message) ArrayList(java.util.ArrayList) FileContainer(org.javacord.core.util.FileContainer) NoSuchElementException(java.util.NoSuchElementException)

Example 19 with RestRequest

use of org.javacord.core.util.rest.RestRequest in project Javacord by BtoBastian.

the class ServerTextChannelBuilderDelegateImpl method create.

@Override
public CompletableFuture<ServerTextChannel> create() {
    ObjectNode body = JsonNodeFactory.instance.objectNode();
    body.put("type", 0);
    super.prepareBody(body);
    if (topic != null) {
        body.put("topic", topic);
    }
    if (category != null) {
        body.put("parent_id", category.getIdAsString());
    }
    if (delayModified) {
        body.put("rate_limit_per_user", delay);
    }
    return new RestRequest<ServerTextChannel>(server.getApi(), RestMethod.POST, RestEndpoint.SERVER_CHANNEL).setUrlParameters(server.getIdAsString()).setBody(body).setAuditLogReason(reason).execute(result -> server.getOrCreateServerTextChannel(result.getJsonBody()));
}
Also used : RestRequest(org.javacord.core.util.rest.RestRequest) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode)

Example 20 with RestRequest

use of org.javacord.core.util.rest.RestRequest in project Javacord by BtoBastian.

the class ServerVoiceChannelBuilderDelegateImpl method create.

@Override
public CompletableFuture<ServerVoiceChannel> create() {
    ObjectNode body = JsonNodeFactory.instance.objectNode();
    body.put("type", 2);
    super.prepareBody(body);
    if (bitrate != null) {
        body.put("bitrate", (int) bitrate);
    }
    if (userlimit != null) {
        body.put("user_limit", (int) userlimit);
    }
    if (category != null) {
        body.put("parent_id", category.getIdAsString());
    }
    return new RestRequest<ServerVoiceChannel>(server.getApi(), RestMethod.POST, RestEndpoint.SERVER_CHANNEL).setUrlParameters(server.getIdAsString()).setBody(body).setAuditLogReason(reason).execute(result -> server.getOrCreateServerVoiceChannel(result.getJsonBody()));
}
Also used : RestRequest(org.javacord.core.util.rest.RestRequest) ObjectNode(com.fasterxml.jackson.databind.node.ObjectNode)

Aggregations

RestRequest (org.javacord.core.util.rest.RestRequest)22 ObjectNode (com.fasterxml.jackson.databind.node.ObjectNode)16 CompletableFuture (java.util.concurrent.CompletableFuture)13 RestEndpoint (org.javacord.core.util.rest.RestEndpoint)11 JsonNodeFactory (com.fasterxml.jackson.databind.node.JsonNodeFactory)9 FileContainer (org.javacord.core.util.FileContainer)9 RestMethod (org.javacord.core.util.rest.RestMethod)9 ArrayNode (com.fasterxml.jackson.databind.node.ArrayNode)7 ArrayList (java.util.ArrayList)7 DiscordApiImpl (org.javacord.core.DiscordApiImpl)7 BufferedImage (java.awt.image.BufferedImage)6 File (java.io.File)6 InputStream (java.io.InputStream)6 URL (java.net.URL)6 Icon (org.javacord.api.entity.Icon)6 JsonNode (com.fasterxml.jackson.databind.JsonNode)5 Base64 (java.util.Base64)5 HashSet (java.util.HashSet)5 List (java.util.List)5 Message (org.javacord.api.entity.message.Message)5