-
-
Notifications
You must be signed in to change notification settings - Fork 101
whois command #352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
whois command #352
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
252 changes: 252 additions & 0 deletions
252
application/src/main/java/org/togetherjava/tjbot/commands/moderation/WhoIsCommand.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
package org.togetherjava.tjbot.commands.moderation; | ||
|
||
import net.dv8tion.jda.api.EmbedBuilder; | ||
import net.dv8tion.jda.api.entities.*; | ||
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; | ||
import net.dv8tion.jda.api.interactions.Interaction; | ||
import net.dv8tion.jda.api.interactions.callbacks.IReplyCallback; | ||
import net.dv8tion.jda.api.interactions.commands.OptionMapping; | ||
import net.dv8tion.jda.api.interactions.commands.OptionType; | ||
import net.dv8tion.jda.api.requests.restaction.interactions.ReplyCallbackAction; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.togetherjava.tjbot.commands.SlashCommandAdapter; | ||
import org.togetherjava.tjbot.commands.SlashCommandVisibility; | ||
import org.togetherjava.tjbot.commands.utils.DiscordClientAction; | ||
|
||
import javax.annotation.CheckReturnValue; | ||
import java.awt.Color; | ||
import java.time.Instant; | ||
import java.time.OffsetDateTime; | ||
import java.time.format.DateTimeFormatter; | ||
import java.util.Collection; | ||
import java.util.Objects; | ||
import java.util.stream.Collectors; | ||
|
||
/** | ||
* This command allows you to look up user (or member) info. | ||
*/ | ||
@SuppressWarnings("ClassWithoutLogger") | ||
public final class WhoIsCommand extends SlashCommandAdapter { | ||
private static final String USER_OPTION = "user"; | ||
private static final String SHOW_SERVER_INFO_OPTION = "show_server_specific_info"; | ||
|
||
private static final String USER_PROFILE_PICTURE_SIZE = "4096"; | ||
|
||
// Sun, December 11, 2016, 13:36:30 | ||
private static final DateTimeFormatter DATE_TIME_FORMAT = | ||
DateTimeFormatter.ofPattern("E, MMMM d, u, HH:mm:ss"); | ||
|
||
/** | ||
* Creates an instance. | ||
*/ | ||
public WhoIsCommand() { | ||
super("whois", "Provides info about the given user", SlashCommandVisibility.GUILD); | ||
|
||
getData().addOption(OptionType.USER, USER_OPTION, "the user to look up", true) | ||
.addOption(OptionType.BOOLEAN, SHOW_SERVER_INFO_OPTION, | ||
"Whenever to show info that is specific to this server, such as their roles. This is true by default.", | ||
false); | ||
} | ||
|
||
@Override | ||
public void onSlashCommand(@NotNull final SlashCommandInteractionEvent event) { | ||
OptionMapping userOption = Objects.requireNonNull(event.getOption(USER_OPTION), | ||
"The given user option cannot be null"); | ||
OptionMapping showServerSpecificInfoOption = event.getOption(SHOW_SERVER_INFO_OPTION); | ||
|
||
User user = userOption.getAsUser(); | ||
Member member = userOption.getAsMember(); | ||
|
||
boolean showServerSpecificInfo = null != member && (null == showServerSpecificInfoOption | ||
|| showServerSpecificInfoOption.getAsBoolean()); | ||
Zabuzard marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
user.retrieveProfile().flatMap((User.Profile profile) -> { | ||
if (showServerSpecificInfo) { | ||
return handleWhoIsMember(event, member, profile); | ||
} else { | ||
return handleWhoIsUser(event, user, profile); | ||
} | ||
}).queue(); | ||
} | ||
|
||
@CheckReturnValue | ||
private static @NotNull ReplyCallbackAction handleWhoIsUser(final @NotNull IReplyCallback event, | ||
final @NotNull User user, final @NotNull User.Profile profile) { | ||
String description = userIdentificationToStringItem(user) + "\n**Is bot:** " + user.isBot() | ||
+ userFlagsToStringItem(user.getFlags()) + "\n**Registration date:** " | ||
+ DATE_TIME_FORMAT.format(user.getTimeCreated()); | ||
|
||
EmbedBuilder embedBuilder = | ||
generateEmbedBuilder(event, user, profile, profile.getAccentColor()).setAuthor( | ||
user.getName(), user.getEffectiveAvatarUrl(), user.getEffectiveAvatarUrl()) | ||
.setDescription(description); | ||
|
||
return sendEmbedWithProfileAction(event, embedBuilder.build(), user.getId()); | ||
} | ||
|
||
@CheckReturnValue | ||
private static @NotNull ReplyCallbackAction handleWhoIsMember( | ||
final @NotNull IReplyCallback event, final @NotNull Member member, | ||
final @NotNull User.Profile profile) { | ||
User user = member.getUser(); | ||
|
||
Color memberColor = member.getColor(); | ||
Color effectiveColor = (null == memberColor) ? profile.getAccentColor() : memberColor; | ||
|
||
String description = userIdentificationToStringItem(user) + voiceStateToStringItem(member) | ||
+ "\n**Is bot:** " + user.isBot() + possibleBoosterToStringItem(member) | ||
+ userFlagsToStringItem(user.getFlags()) + "\n**Join date:** " | ||
+ DATE_TIME_FORMAT.format(member.getTimeJoined()) + "\n**Registration date:** " | ||
+ DATE_TIME_FORMAT.format(user.getTimeCreated()) + "\n**Roles:** " | ||
+ formatRoles(member); | ||
|
||
EmbedBuilder embedBuilder = generateEmbedBuilder(event, user, profile, effectiveColor) | ||
.setAuthor(member.getEffectiveName(), member.getEffectiveAvatarUrl(), | ||
member.getEffectiveAvatarUrl()) | ||
.setDescription(description); | ||
|
||
return sendEmbedWithProfileAction(event, embedBuilder.build(), user.getId()); | ||
} | ||
|
||
private static @NotNull ReplyCallbackAction sendEmbedWithProfileAction( | ||
final @NotNull IReplyCallback event, @NotNull MessageEmbed embed, | ||
@NotNull String userId) { | ||
return event.replyEmbeds(embed) | ||
.addActionRow( | ||
DiscordClientAction.General.USER.asLinkButton("Click to see profile!", userId)); | ||
} | ||
|
||
private static @NotNull String voiceStateToStringItem(@NotNull final Member member) { | ||
GuildVoiceState voiceState = Objects.requireNonNull(member.getVoiceState(), | ||
"The given voiceState cannot be null"); | ||
|
||
if (!voiceState.inAudioChannel()) { | ||
return ""; | ||
} | ||
|
||
return "\n**In voicechannel:** " + (voiceState.getChannel().getAsMention()); | ||
} | ||
|
||
|
||
/** | ||
* Generates whois embed based on the given parameters. | ||
* | ||
* @param event the {@link SlashCommandInteractionEvent} | ||
* @param user the {@link User} getting whois'd | ||
* @param profile the {@link net.dv8tion.jda.api.entities.User.Profile} of the whois'd user | ||
* @param effectiveColor the {@link Color} that the embed will become | ||
* @return the generated {@link EmbedBuilder} | ||
*/ | ||
private static @NotNull EmbedBuilder generateEmbedBuilder(@NotNull final Interaction event, | ||
@NotNull final User user, final @NotNull User.Profile profile, | ||
final Color effectiveColor) { | ||
|
||
EmbedBuilder embedBuilder = new EmbedBuilder().setThumbnail(user.getEffectiveAvatarUrl()) | ||
.setColor(effectiveColor) | ||
.setFooter("Requested by " + event.getUser().getAsTag(), | ||
event.getMember().getEffectiveAvatarUrl()) | ||
.setTimestamp(Instant.now()); | ||
|
||
if (null != profile.getBannerId()) { | ||
embedBuilder.setImage(profile.getBannerUrl() + "?size=" + USER_PROFILE_PICTURE_SIZE); | ||
} | ||
|
||
return embedBuilder; | ||
} | ||
|
||
/** | ||
* Handles boosting properties of a {@link Member} | ||
* | ||
* @param member the {@link Member} to take the booster properties from | ||
* @return user readable {@link String} | ||
*/ | ||
private static @NotNull String possibleBoosterToStringItem(final @NotNull Member member) { | ||
OffsetDateTime timeBoosted = member.getTimeBoosted(); | ||
|
||
if (null == timeBoosted) { | ||
return "\n**Is booster:** false"; | ||
} | ||
|
||
return "\n**Is booster:** true \n**Boosting since:** " | ||
+ DATE_TIME_FORMAT.format(timeBoosted); | ||
} | ||
|
||
/** | ||
* Handles the user's identifying properties (such as ID, tag) | ||
* | ||
* @param user the {@link User} to take the identifiers from | ||
* @return user readable {@link String} | ||
*/ | ||
private static @NotNull String userIdentificationToStringItem(final @NotNull User user) { | ||
return "**Mention:** " + user.getAsMention() + "\n**Tag:** " + user.getAsTag() | ||
+ "\n**ID:** " + user.getId(); | ||
} | ||
|
||
/** | ||
* Formats the roles into a user readable {@link String} | ||
* | ||
* @param member member to take the Roles from | ||
* @return user readable {@link String} of the roles | ||
*/ | ||
private static String formatRoles(final @NotNull Member member) { | ||
return member.getRoles().stream().map(Role::getAsMention).collect(Collectors.joining(", ")); | ||
} | ||
|
||
/** | ||
* Formats Hypesquad and the flags | ||
* | ||
* @param flags the {@link Collection} of {@link net.dv8tion.jda.api.entities.User.UserFlag} | ||
* (recommend {@link java.util.EnumSet} | ||
* @return user readable {@link StringBuilder} | ||
*/ | ||
private static @NotNull StringBuilder userFlagsToStringItem( | ||
final @NotNull Collection<User.UserFlag> flags) { | ||
String formattedFlags = formatUserFlags(flags); | ||
StringBuilder result = hypeSquadToStringItem(flags); | ||
|
||
if (!formattedFlags.isBlank()) { | ||
result.append("\n**Flags:** ").append(formattedFlags); | ||
} | ||
|
||
return result; | ||
} | ||
|
||
/** | ||
* Formats user readable Hypesquad item | ||
* | ||
* @param flags the {@link Collection} of {@link net.dv8tion.jda.api.entities.User.UserFlag} | ||
* (recommend {@link java.util.EnumSet} | ||
* @return user readable {@link StringBuilder} | ||
*/ | ||
private static @NotNull StringBuilder hypeSquadToStringItem( | ||
final @NotNull Collection<User.UserFlag> flags) { | ||
StringBuilder stringBuilder = new StringBuilder("**\nHypesquad:** "); | ||
|
||
if (flags.contains(User.UserFlag.HYPESQUAD_BALANCE)) { | ||
stringBuilder.append(User.UserFlag.HYPESQUAD_BALANCE.getName()); | ||
} else if (flags.contains(User.UserFlag.HYPESQUAD_BRAVERY)) { | ||
stringBuilder.append(User.UserFlag.HYPESQUAD_BRAVERY.getName()); | ||
} else if (flags.contains(User.UserFlag.HYPESQUAD_BRILLIANCE)) { | ||
stringBuilder.append(User.UserFlag.HYPESQUAD_BRILLIANCE.getName()); | ||
} else { | ||
stringBuilder.append("joined none"); | ||
} | ||
|
||
return stringBuilder; | ||
} | ||
|
||
/** | ||
* Formats the flags into a user readable {@link String}, filters Hypesquad relating flags | ||
* | ||
* @param flags the {@link Collection} of {@link net.dv8tion.jda.api.entities.User.UserFlag} | ||
* (recommend {@link java.util.EnumSet} | ||
* @return the user readable string | ||
*/ | ||
@NotNull | ||
private static String formatUserFlags(final @NotNull Collection<User.UserFlag> flags) { | ||
return flags.stream() | ||
.map(User.UserFlag::getName) | ||
.filter(name -> (name.contains("Hypesquad"))) | ||
.collect(Collectors.joining(", ")); | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.