kick(@Nullable String reason)
/**
* Puts this Member in time out in this {@link net.dv8tion.jda.api.entities.Guild Guild} for a specific amount of time.
- *
While a Member is in time out, all permissions except {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL VIEW_CHANNEL} and
- * {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
+ *
While a Member is in time out, all permissions except {@link Permission#VIEW_CHANNEL VIEW_CHANNEL} and
+ * {@link Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
*
* Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
* the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
@@ -589,7 +615,7 @@ default AuditableRestAction kick(@Nullable String reason)
* The {@link TimeUnit Unit} type of {@code amount}
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS} permission.
+ * If the logged in account does not have the {@link Permission#MODERATE_MEMBERS} permission.
* @throws IllegalArgumentException
* If any of the following checks are true
*
@@ -609,8 +635,8 @@ default AuditableRestAction timeoutFor(long amount, @Nonnull TimeUnit unit
/**
* Puts this Member in time out in this {@link net.dv8tion.jda.api.entities.Guild Guild} for a specific amount of time.
- *
While a Member is in time out, all permissions except {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL VIEW_CHANNEL} and
- * {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
+ *
While a Member is in time out, all permissions except {@link Permission#VIEW_CHANNEL VIEW_CHANNEL} and
+ * {@link Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
*
* Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
* the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
@@ -626,7 +652,7 @@ default AuditableRestAction timeoutFor(long amount, @Nonnull TimeUnit unit
* The duration to put this Member in time out for
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS} permission.
+ * If the logged in account does not have the {@link Permission#MODERATE_MEMBERS} permission.
* @throws IllegalArgumentException
* If any of the following checks are true
*
@@ -646,8 +672,8 @@ default AuditableRestAction timeoutFor(@Nonnull Duration duration)
/**
* Puts this Member in time out in this {@link net.dv8tion.jda.api.entities.Guild Guild} until the specified date.
- *
While a Member is in time out, all permissions except {@link net.dv8tion.jda.api.Permission#VIEW_CHANNEL VIEW_CHANNEL} and
- * {@link net.dv8tion.jda.api.Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
+ *
While a Member is in time out, all permissions except {@link Permission#VIEW_CHANNEL VIEW_CHANNEL} and
+ * {@link Permission#MESSAGE_HISTORY MESSAGE_HISTORY} are removed from them.
*
* Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
* the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
@@ -663,7 +689,7 @@ default AuditableRestAction timeoutFor(@Nonnull Duration duration)
* The time this Member will be released from time out
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS} permission.
+ * If the logged in account does not have the {@link Permission#MODERATE_MEMBERS} permission.
* @throws IllegalArgumentException
* If any of the following checks are true
*
@@ -695,7 +721,7 @@ default AuditableRestAction timeoutUntil(@Nonnull TemporalAccessor tempora
*
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#MODERATE_MEMBERS} permission.
+ * If the logged in account does not have the {@link Permission#MODERATE_MEMBERS} permission.
*
* @return {@link net.dv8tion.jda.api.requests.restaction.AuditableRestAction AuditableRestAction}
*/
@@ -730,7 +756,7 @@ default AuditableRestAction removeTimeout()
* Whether this {@link net.dv8tion.jda.api.entities.Member Member} should be muted or unmuted.
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#VOICE_DEAF_OTHERS} permission.
+ * If the logged in account does not have the {@link Permission#VOICE_DEAF_OTHERS} permission.
* @throws java.lang.IllegalStateException
* If the member is not currently connected to a voice channel.
*
@@ -768,7 +794,7 @@ default AuditableRestAction mute(boolean mute)
* Whether this {@link net.dv8tion.jda.api.entities.Member Member} should be deafened or undeafened.
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
- * If the logged in account does not have the {@link net.dv8tion.jda.api.Permission#VOICE_DEAF_OTHERS} permission.
+ * If the logged in account does not have the {@link Permission#VOICE_DEAF_OTHERS} permission.
* @throws java.lang.IllegalStateException
* If the member is not currently connected to a voice channel.
*
@@ -788,9 +814,9 @@ default AuditableRestAction deafen(boolean deafen)
* The nickname is visible to all members of this guild.
*
* To change the nickname for the currently logged in account
- * only the Permission {@link net.dv8tion.jda.api.Permission#NICKNAME_CHANGE NICKNAME_CHANGE} is required.
+ * only the Permission {@link Permission#NICKNAME_CHANGE NICKNAME_CHANGE} is required.
*
To change the nickname of any {@link net.dv8tion.jda.api.entities.Member Member} for this {@link net.dv8tion.jda.api.entities.Guild Guild}
- * the Permission {@link net.dv8tion.jda.api.Permission#NICKNAME_MANAGE NICKNAME_MANAGE} is required.
+ * the Permission {@link Permission#NICKNAME_MANAGE NICKNAME_MANAGE} is required.
*
*
Possible {@link net.dv8tion.jda.api.requests.ErrorResponse ErrorResponses} caused by
* the returned {@link net.dv8tion.jda.api.requests.RestAction RestAction} include the following:
@@ -808,9 +834,9 @@ default AuditableRestAction deafen(boolean deafen)
*
* @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
*
- * - If attempting to set nickname for self and the logged in account has neither {@link net.dv8tion.jda.api.Permission#NICKNAME_CHANGE}
- * or {@link net.dv8tion.jda.api.Permission#NICKNAME_MANAGE}
- * - If attempting to set nickname for another member and the logged in account does not have {@link net.dv8tion.jda.api.Permission#NICKNAME_MANAGE}
+ * - If attempting to set nickname for self and the logged in account has neither {@link Permission#NICKNAME_CHANGE}
+ * or {@link Permission#NICKNAME_MANAGE}
+ * - If attempting to set nickname for another member and the logged in account does not have {@link Permission#NICKNAME_MANAGE}
*
* @throws net.dv8tion.jda.api.exceptions.HierarchyException
* If attempting to set nickname for another member and the logged in account cannot manipulate the other user due to permission hierarchy position.
@@ -826,4 +852,138 @@ default AuditableRestAction modifyNickname(@Nullable String nickname)
{
return getGuild().modifyNickname(this, nickname);
}
+
+ /**
+ * Updates the flags to the new flag set.
+ *
If any of the flags is not {@link MemberFlag#isModifiable() modifiable}, it is not updated.
+ *
+ * Any flags not provided by the set will be disabled, all contained flags will be enabled.
+ *
+ * @param newFlags
+ * The new flags for the member.
+ *
+ * @throws net.dv8tion.jda.api.exceptions.InsufficientPermissionException
+ * If the bot does not have {@link Permission#MODERATE_MEMBERS} in the guild
+ * @throws IllegalArgumentException
+ * If {@code null} is provided
+ *
+ * @return {@link AuditableRestAction}
+ */
+ @Nonnull
+ @CheckReturnValue
+ default AuditableRestAction modifyFlags(@Nonnull Collection newFlags)
+ {
+ Checks.noneNull(newFlags, "Flags");
+ if (!getGuild().getSelfMember().hasPermission(Permission.MODERATE_MEMBERS))
+ throw new InsufficientPermissionException(getGuild(), Permission.MODERATE_MEMBERS);
+ int flags = getFlagsRaw();
+ EnumSet updated = Helpers.copyEnumSet(MemberFlag.class, newFlags);
+ for (MemberFlag flag : MemberFlag.values())
+ {
+ if (flag.modifiable)
+ {
+ if (updated.contains(flag))
+ flags |= flag.raw;
+ else
+ flags &= ~flag.raw;
+ }
+ }
+
+ DataObject body = DataObject.empty().put("flags", flags);
+ Route.CompiledRoute route = Route.Guilds.MODIFY_MEMBER.compile(getGuild().getId(), getId());
+ return new AuditableRestActionImpl<>(getJDA(), route, body);
+ }
+
+ /**
+ * Member flags indicating information about the membership state.
+ */
+ enum MemberFlag
+ {
+ /**
+ * The Member has left and rejoined the guild
+ */
+ DID_REJOIN(1, false),
+ /**
+ * The Member has completed the onboarding process
+ */
+ COMPLETED_ONBOARDING(1 << 1, false),
+ /**
+ * The Member bypasses guild verification requirements
+ */
+ BYPASSES_VERIFICATION(1 << 2, true),
+ /**
+ * The Member has started the onboarding process
+ */
+ STARTED_ONBOARDING(1 << 3, false),
+ ;
+
+ private final int raw;
+ private final boolean modifiable;
+
+
+ MemberFlag(int raw, boolean modifiable)
+ {
+ this.raw = raw;
+ this.modifiable = modifiable;
+ }
+
+ /**
+ * The raw value used by Discord for this flag
+ *
+ * @return The raw value
+ */
+ public int getRaw()
+ {
+ return raw;
+ }
+
+ /**
+ * Whether this flag can be modified by the client
+ *
+ * @return True, if this flag can be modified
+ */
+ public boolean isModifiable()
+ {
+ return modifiable;
+ }
+
+ /**
+ * The {@link MemberFlag Flags} represented by the provided raw value.
+ *
If the provided raw value is {@code 0} this will return an empty {@link java.util.EnumSet EnumSet}.
+ *
+ * @param raw
+ * The raw value
+ *
+ * @return EnumSet containing the flags represented by the provided raw value
+ */
+ @Nonnull
+ public static EnumSet fromRaw(int raw)
+ {
+ EnumSet flags = EnumSet.noneOf(MemberFlag.class);
+ for (MemberFlag flag : values())
+ {
+ if ((raw & flag.raw) == flag.raw)
+ flags.add(flag);
+ }
+ return flags;
+ }
+
+ /**
+ * The raw value of the provided {@link MemberFlag Flags}.
+ *
If the provided set is empty this will return {@code 0}.
+ *
+ * @param flags
+ * The flags
+ *
+ * @return The raw value of the provided flags
+ */
+ public static int toRaw(@Nonnull Collection flags)
+ {
+ Checks.noneNull(flags, "Flags");
+ int raw = 0;
+ for (MemberFlag flag : flags)
+ raw |= flag.raw;
+ return raw;
+ }
+ }
}
diff --git a/src/main/java/net/dv8tion/jda/api/events/guild/member/update/GuildMemberUpdateFlagsEvent.java b/src/main/java/net/dv8tion/jda/api/events/guild/member/update/GuildMemberUpdateFlagsEvent.java
new file mode 100644
index 0000000000..3c4555efd6
--- /dev/null
+++ b/src/main/java/net/dv8tion/jda/api/events/guild/member/update/GuildMemberUpdateFlagsEvent.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2015 Austin Keener, Michael Ritter, Florian Spieß, and the JDA contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dv8tion.jda.api.events.guild.member.update;
+
+import net.dv8tion.jda.api.JDA;
+import net.dv8tion.jda.api.entities.Member;
+
+import javax.annotation.Nonnull;
+import java.util.EnumSet;
+
+/**
+ * Indicates that the {@link Member#getFlags()} flags for a {@link Member} were updated.
+ *
+ * Identifier: {@code flags}
+ *
+ *
Requirements
+ *
+ *
This event requires the {@link net.dv8tion.jda.api.requests.GatewayIntent#GUILD_MEMBERS GUILD_MEMBERS} intent to be enabled.
+ *
{@link net.dv8tion.jda.api.JDABuilder#createDefault(String) createDefault(String)} and
+ * {@link net.dv8tion.jda.api.JDABuilder#createLight(String) createLight(String)} disable this by default!
+ *
+ *
Additionally, this event also requires the {@link net.dv8tion.jda.api.utils.MemberCachePolicy MemberCachePolicy}
+ * to cache the updated members. Discord does not specifically tell us about the updates, but merely tells us the
+ * member was updated and gives us the updated member object. In order to fire a specific event like this we
+ * need to have the old member cached to compare against.
+ */
+public class GuildMemberUpdateFlagsEvent extends GenericGuildMemberUpdateEvent>
+{
+ public static final String IDENTIFIER = "flags";
+
+ public GuildMemberUpdateFlagsEvent(@Nonnull JDA api, long responseNumber, @Nonnull Member member, @Nonnull EnumSet previous)
+ {
+ super(api, responseNumber, member, previous, member.getFlags(), IDENTIFIER);
+ }
+}
diff --git a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java
index 0a9e5a3186..a0ea417616 100644
--- a/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java
+++ b/src/main/java/net/dv8tion/jda/api/hooks/ListenerAdapter.java
@@ -299,6 +299,7 @@ public void onGuildMemberUpdateNickname(@Nonnull GuildMemberUpdateNicknameEvent
public void onGuildMemberUpdateAvatar(@Nonnull GuildMemberUpdateAvatarEvent event) {}
public void onGuildMemberUpdateBoostTime(@Nonnull GuildMemberUpdateBoostTimeEvent event) {}
public void onGuildMemberUpdatePending(@Nonnull GuildMemberUpdatePendingEvent event) {}
+ public void onGuildMemberUpdateFlags(@Nonnull GuildMemberUpdateFlagsEvent event) {}
public void onGuildMemberUpdateTimeOut(@Nonnull GuildMemberUpdateTimeOutEvent event) {}
//Guild Voice Events
diff --git a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java
index dee8de93e5..a9609ed92f 100644
--- a/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java
+++ b/src/main/java/net/dv8tion/jda/internal/entities/EntityBuilder.java
@@ -600,6 +600,8 @@ public MemberImpl createMember(GuildImpl guild, DataObject memberJson, DataObjec
member = new MemberImpl(guild, user);
member.setNickname(memberJson.getString("nick", null));
member.setAvatarId(memberJson.getString("avatar", null));
+ if (!memberJson.isNull("flags"))
+ member.setFlags(memberJson.getInt("flags"));
long boostTimestamp = memberJson.isNull("premium_since")
? 0
@@ -768,6 +770,20 @@ public void updateMember(GuildImpl guild, MemberImpl member, DataObject content,
}
}
+ if (!content.isNull("flags"))
+ {
+ int flags = content.getInt("flags");
+ int oldFlags = member.getFlagsRaw();
+ if (flags != oldFlags)
+ {
+ member.setFlags(flags);
+ getJDA().handleEvent(
+ new GuildMemberUpdateFlagsEvent(
+ getJDA(), responseNumber,
+ member, Member.MemberFlag.fromRaw(oldFlags)));
+ }
+ }
+
updateUser((UserImpl) member.getUser(), content.getObject("user"));
}
diff --git a/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java b/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java
index 6f689c3256..192aebfea3 100644
--- a/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java
+++ b/src/main/java/net/dv8tion/jda/internal/entities/MemberImpl.java
@@ -55,6 +55,7 @@ public class MemberImpl implements Member
private String avatarId;
private long joinDate, boostDate, timeOutEnd;
private boolean pending = false;
+ private int flags;
public MemberImpl(GuildImpl guild, User user)
{
@@ -225,6 +226,12 @@ public int getColorRaw()
return Role.DEFAULT_COLOR_RAW;
}
+ @Override
+ public int getFlagsRaw()
+ {
+ return flags;
+ }
+
@Nonnull
@Override
public EnumSet getPermissions()
@@ -406,6 +413,12 @@ public MemberImpl setPending(boolean pending)
return this;
}
+ public MemberImpl setFlags(int flags)
+ {
+ this.flags = flags;
+ return this;
+ }
+
public Set getRoleSet()
{
return roles;