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);
}
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);
}
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;
});
}
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()));
}
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;
}
});
}
Aggregations