Search in sources :

Example 26 with Route

use of net.dv8tion.jda.internal.requests.Route in project JDA by DV8FromTheWorld.

the class Guild method addRoleToMember.

/**
 * Atomically assigns the provided {@link net.dv8tion.jda.api.entities.Role Role} to the specified member by their user id.
 * <br><b>This can be used together with other role modification methods as it does not require an updated cache!</b>
 *
 * <p>If multiple roles should be added/removed (efficiently) in one request
 * you may use {@link #modifyMemberRoles(Member, Collection, Collection) modifyMemberRoles(Member, Collection, Collection)} or similar methods.
 *
 * <p>If the specified role is already present in the member's set of roles this does nothing.
 *
 * <p>Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
 * the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
 * <ul>
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS}
 *     <br>The Members Roles could not be modified due to a permission discrepancy</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MEMBER UNKNOWN_MEMBER}
 *     <br>The target Member was removed from the Guild before finishing the task</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_ROLE UNKNOWN_ROLE}
 *     <br>If the specified Role does not exist</li>
 * </ul>
 *
 * @param  userId
 *         The id of the target member who will receive the new role
 * @param  role
 *         The role which should be assigned atomically
 *
 * @throws java.lang.IllegalArgumentException
 *         <ul>
 *             <li>If the specified role is not from the current Guild</li>
 *             <li>If the role is {@code null}</li>
 *         </ul>
 * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
 *         If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES Permission.MANAGE_ROLES}
 * @throws net.dv8tion.jda.api.exceptions.HierarchyException
 *         If the provided roles are higher in the Guild's hierarchy
 *         and thus cannot be modified by the currently logged in account
 *
 * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction}
 */
@Nonnull
@CheckReturnValue
default AuditableRestAction<Void> addRoleToMember(long userId, @Nonnull Role role) {
    Checks.notNull(role, "Role");
    Checks.check(role.getGuild().equals(this), "Role must be from the same guild! Trying to use role from %s in %s", role.getGuild().toString(), toString());
    Member member = getMemberById(userId);
    if (member != null)
        return addRoleToMember(member, role);
    if (!getSelfMember().hasPermission(Permission.MANAGE_ROLES))
        throw new InsufficientPermissionException(this, Permission.MANAGE_ROLES);
    if (!getSelfMember().canInteract(role))
        throw new HierarchyException("Can't modify a role with higher or equal highest role than yourself! Role: " + role.toString());
    Route.CompiledRoute route = Route.Guilds.ADD_MEMBER_ROLE.compile(getId(), Long.toUnsignedString(userId), role.getId());
    return new AuditableRestActionImpl<>(getJDA(), route);
}
Also used : HierarchyException(net.dv8tion.jda.api.exceptions.HierarchyException) AuditableRestActionImpl(net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl) InsufficientPermissionException(net.dv8tion.jda.api.exceptions.InsufficientPermissionException) Route(net.dv8tion.jda.internal.requests.Route) CheckReturnValue(javax.annotation.CheckReturnValue) Nonnull(javax.annotation.Nonnull)

Example 27 with Route

use of net.dv8tion.jda.internal.requests.Route in project JDA by DV8FromTheWorld.

the class Guild method removeRoleFromMember.

/**
 * Atomically removes the provided {@link net.dv8tion.jda.api.entities.Role Role} from the specified member by their user id.
 * <br><b>This can be used together with other role modification methods as it does not require an updated cache!</b>
 *
 * <p>If multiple roles should be added/removed (efficiently) in one request
 * you may use {@link #modifyMemberRoles(Member, Collection, Collection) modifyMemberRoles(Member, Collection, Collection)} or similar methods.
 *
 * <p>If the specified role is not present in the member's set of roles this does nothing.
 *
 * <p>Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
 * the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
 * <ul>
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS}
 *     <br>The Members Roles could not be modified due to a permission discrepancy</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MEMBER UNKNOWN_MEMBER}
 *     <br>The target Member was removed from the Guild before finishing the task</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_ROLE UNKNOWN_ROLE}
 *     <br>If the specified Role does not exist</li>
 * </ul>
 *
 * @param  userId
 *         The id of the target member who will lose the specified role
 * @param  role
 *         The role which should be removed atomically
 *
 * @throws java.lang.IllegalArgumentException
 *         <ul>
 *             <li>If the specified role is not from the current Guild</li>
 *             <li>The role is {@code null}</li>
 *         </ul>
 * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
 *         If the currently logged in account does not have {@link net.dv8tion.jda.api.Permission#MANAGE_ROLES Permission.MANAGE_ROLES}
 * @throws net.dv8tion.jda.api.exceptions.HierarchyException
 *         If the provided roles are higher in the Guild's hierarchy
 *         and thus cannot be modified by the currently logged in account
 *
 * @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction}
 */
@Nonnull
@CheckReturnValue
default AuditableRestAction<Void> removeRoleFromMember(long userId, @Nonnull Role role) {
    Checks.notNull(role, "Role");
    Checks.check(role.getGuild().equals(this), "Role must be from the same guild! Trying to use role from %s in %s", role.getGuild().toString(), toString());
    Member member = getMemberById(userId);
    if (member != null)
        return removeRoleFromMember(member, role);
    if (!getSelfMember().hasPermission(Permission.MANAGE_ROLES))
        throw new InsufficientPermissionException(this, Permission.MANAGE_ROLES);
    if (!getSelfMember().canInteract(role))
        throw new HierarchyException("Can't modify a role with higher or equal highest role than yourself! Role: " + role.toString());
    Route.CompiledRoute route = Route.Guilds.REMOVE_MEMBER_ROLE.compile(getId(), Long.toUnsignedString(userId), role.getId());
    return new AuditableRestActionImpl<>(getJDA(), route);
}
Also used : HierarchyException(net.dv8tion.jda.api.exceptions.HierarchyException) AuditableRestActionImpl(net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl) InsufficientPermissionException(net.dv8tion.jda.api.exceptions.InsufficientPermissionException) Route(net.dv8tion.jda.internal.requests.Route) CheckReturnValue(javax.annotation.CheckReturnValue) Nonnull(javax.annotation.Nonnull)

Example 28 with Route

use of net.dv8tion.jda.internal.requests.Route in project JDA by DV8FromTheWorld.

the class MessageReference method resolve.

/**
 * Retrieves the referenced message for this message.
 * <br>If the message already exists, it will be returned immediately.
 *
 * <p>The following {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} are possible:
 * <ul>
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_ACCESS MISSING_ACCESS}
 *     <br>The request was attempted after the account lost access to the {@link net.dv8tion.jda.api.entities.Guild Guild}
 *         typically due to being kicked or removed, or after {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}
 *         was revoked in the {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#MISSING_PERMISSIONS MISSING_PERMISSIONS}
 *     <br>The request was attempted after the account lost {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}
 *         in the {@link net.dv8tion.jda.api.entities.TextChannel TextChannel}.</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_MESSAGE UNKNOWN_MESSAGE}
 *     <br>The message has already been deleted.</li>
 *
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_CHANNEL UNKNOWN_CHANNEL}
 *     <br>The request was attempted after the channel was deleted.</li>
 * </ul>
 *
 * @param  update
 *         Whether to update the already stored message
 *
 * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
 *         If this reference refers to a {@link net.dv8tion.jda.api.entities.TextChannel TextChannel} and the logged in account does not have
 *         <ul>
 *             <li>{@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL Permission.VIEW_CHANNEL}</li>
 *             <li>{@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY Permission.MESSAGE_HISTORY}</li>
 *         </ul>
 *
 * @throws java.lang.IllegalStateException
 *         If this message reference does not have a channel
 *
 * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: {@link net.dv8tion.jda.api.entities.Message}
 */
@Nonnull
public RestAction<Message> resolve(boolean update) {
    checkPermission(Permission.VIEW_CHANNEL);
    checkPermission(Permission.MESSAGE_HISTORY);
    if (channel == null)
        throw new IllegalStateException("Cannot resolve a message without a channel present.");
    JDAImpl jda = (JDAImpl) getJDA();
    Message referenced = getMessage();
    if (referenced != null && !update)
        return new CompletedRestAction<>(jda, referenced);
    Route.CompiledRoute route = Route.Messages.GET_MESSAGE.compile(getChannelId(), getMessageId());
    return new RestActionImpl<>(jda, route, (response, request) -> {
        // channel can be null for MessageReferences, but we've already checked for that above, so it is nonnull here
        Message created = jda.getEntityBuilder().createMessageWithChannel(response.getObject(), channel, false);
        this.referencedMessage = created;
        return created;
    });
}
Also used : RestActionImpl(net.dv8tion.jda.internal.requests.RestActionImpl) JDAImpl(net.dv8tion.jda.internal.JDAImpl) Route(net.dv8tion.jda.internal.requests.Route) Nonnull(javax.annotation.Nonnull)

Example 29 with Route

use of net.dv8tion.jda.internal.requests.Route in project JDA by DV8FromTheWorld.

the class Template method resolve.

/**
 * Retrieves a new {@link net.dv8tion.jda.api.entities.templates.Template Template} instance for the given template code.
 *
 * <p>Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} include:
 * <ul>
 *     <li>{@link net.dv8tion.jda.api.requests.ErrorResponse#UNKNOWN_GUILD_TEMPLATE Unknown Guild Template}
 *     <br>The template doesn't exist.</li>
 * </ul>
 *
 * @param  api
 *         The JDA instance
 * @param  code
 *         A valid template code
 *
 * @throws java.lang.IllegalArgumentException
 *         <ul>
 *             <li>If the provided code is null or empty</li>
 *             <li>If the provided code contains a whitespace</li>
 *             <li>If the provided JDA object is null</li>
 *         </ul>
 *
 * @return {@link net.dv8tion.jda.api.requests.RestAction RestAction} - Type: {@link net.dv8tion.jda.api.entities.templates.Template Template}
 *         <br>The Template object
 */
@Nonnull
public static RestAction<Template> resolve(final JDA api, final String code) {
    Checks.notEmpty(code, "code");
    Checks.noWhitespace(code, "code");
    Checks.notNull(api, "api");
    Route.CompiledRoute route = Route.Templates.GET_TEMPLATE.compile(code);
    JDAImpl jda = (JDAImpl) api;
    return new RestActionImpl<>(api, route, (response, request) -> jda.getEntityBuilder().createTemplate(response.getObject()));
}
Also used : RestActionImpl(net.dv8tion.jda.internal.requests.RestActionImpl) JDAImpl(net.dv8tion.jda.internal.JDAImpl) Route(net.dv8tion.jda.internal.requests.Route) Nonnull(javax.annotation.Nonnull)

Example 30 with Route

use of net.dv8tion.jda.internal.requests.Route in project JDA by DV8FromTheWorld.

the class BotRateLimiter method updateBucket.

private Bucket updateBucket(Route.CompiledRoute route, okhttp3.Response response) {
    return MiscUtil.locked(bucketLock, () -> {
        try {
            Bucket bucket = getBucket(route, true);
            Headers headers = response.headers();
            boolean global = headers.get(GLOBAL_HEADER) != null;
            boolean cloudflare = headers.get("via") == null;
            String hash = headers.get(HASH_HEADER);
            long now = getNow();
            // Create a new bucket for the hash if needed
            Route baseRoute = route.getBaseRoute();
            if (hash != null) {
                if (!this.hashes.containsKey(baseRoute)) {
                    this.hashes.put(baseRoute, hash);
                    log.debug("Caching bucket hash {} -> {}", baseRoute, hash);
                }
                bucket = getBucket(route, true);
            }
            if (response.code() == 429) {
                String retryAfterHeader = headers.get(RETRY_AFTER_HEADER);
                // seconds precision
                long retryAfter = parseLong(retryAfterHeader) * 1000;
                // Handle global rate limit if necessary
                if (global) {
                    requester.getJDA().getSessionController().setGlobalRatelimit(now + retryAfter);
                    log.error("Encountered global rate limit! Retry-After: {} ms", retryAfter);
                } else // Handle cloudflare rate limits, this applies to all routes and uses seconds for retry-after
                if (cloudflare) {
                    requester.getJDA().getSessionController().setGlobalRatelimit(now + retryAfter);
                    log.error("Encountered cloudflare rate limit! Retry-After: {} s", retryAfter / 1000);
                } else // Handle hard rate limit, pretty much just log that it happened
                {
                    boolean firstHit = hitRatelimit.add(baseRoute) && retryAfter < 60000;
                    // Update the bucket to the new information
                    bucket.remaining = 0;
                    bucket.reset = getNow() + retryAfter;
                    // unless its a long retry-after delay (more than a minute)
                    if (firstHit)
                        log.debug("Encountered 429 on route {} with bucket {} Retry-After: {} ms", baseRoute, bucket.bucketId, retryAfter);
                    else
                        log.warn("Encountered 429 on route {} with bucket {} Retry-After: {} ms", baseRoute, bucket.bucketId, retryAfter);
                }
                return bucket;
            }
            // If hash is null this means we didn't get enough information to update a bucket
            if (hash == null)
                return bucket;
            // Update the bucket parameters with new information
            String limitHeader = headers.get(LIMIT_HEADER);
            String remainingHeader = headers.get(REMAINING_HEADER);
            String resetAfterHeader = headers.get(RESET_AFTER_HEADER);
            String resetHeader = headers.get(RESET_HEADER);
            bucket.limit = (int) Math.max(1L, parseLong(limitHeader));
            bucket.remaining = (int) parseLong(remainingHeader);
            if (requester.getJDA().isRelativeRateLimit())
                bucket.reset = now + parseDouble(resetAfterHeader);
            else
                bucket.reset = parseDouble(resetHeader);
            log.trace("Updated bucket {} to ({}/{}, {})", bucket.bucketId, bucket.remaining, bucket.limit, bucket.reset - now);
            return bucket;
        } catch (Exception e) {
            Bucket bucket = getBucket(route, true);
            log.error("Encountered Exception while updating a bucket. Route: {} Bucket: {} Code: {} Headers:\n{}", route.getBaseRoute(), bucket, response.code(), response.headers(), e);
            return bucket;
        }
    });
}
Also used : Headers(okhttp3.Headers) Route(net.dv8tion.jda.internal.requests.Route)

Aggregations

Route (net.dv8tion.jda.internal.requests.Route)31 Nonnull (javax.annotation.Nonnull)24 RestActionImpl (net.dv8tion.jda.internal.requests.RestActionImpl)24 DataObject (net.dv8tion.jda.api.utils.data.DataObject)12 JDAImpl (net.dv8tion.jda.internal.JDAImpl)12 InsufficientPermissionException (net.dv8tion.jda.api.exceptions.InsufficientPermissionException)10 AuditableRestActionImpl (net.dv8tion.jda.internal.requests.restaction.AuditableRestActionImpl)10 CheckReturnValue (javax.annotation.CheckReturnValue)9 DataArray (net.dv8tion.jda.api.utils.data.DataArray)8 EntityBuilder (net.dv8tion.jda.internal.entities.EntityBuilder)5 JDA (net.dv8tion.jda.api.JDA)3 HierarchyException (net.dv8tion.jda.api.exceptions.HierarchyException)3 MissingAccessException (net.dv8tion.jda.api.exceptions.MissingAccessException)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 List (java.util.List)2 DeferredRestAction (net.dv8tion.jda.internal.requests.DeferredRestAction)2 WebhookEmbed (club.minnced.discord.webhook.send.WebhookEmbed)1 WebhookEmbedBuilder (club.minnced.discord.webhook.send.WebhookEmbedBuilder)1 WebhookMessage (club.minnced.discord.webhook.send.WebhookMessage)1