4 Commits

Author SHA1 Message Date
Lorenzo Dellacà
db943f7e05 Fix messages with newlines not being handled for commands
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-19 00:05:36 +01:00
Lorenzo Dellacà
cb49bda84a Make say support both slash and message commands 2022-12-19 00:05:13 +01:00
Lorenzo Dellacà
b318b9f22b Bump version to 0.5.1
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 23:49:00 +01:00
Lorenzo Dellacà
1447f8c177 Make avatar support both slash and message commands
All checks were successful
continuous-integration/drone/push Build is passing
2022-12-18 23:47:54 +01:00
9 changed files with 220 additions and 57 deletions

View File

@@ -6,7 +6,7 @@
<groupId>wtf.beatrice.hidekobot</groupId>
<artifactId>HidekoBot</artifactId>
<version>0.5.0</version>
<version>0.5.1</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>

View File

@@ -129,10 +129,11 @@ public class HidekoBot
// register message commands
MessageCommandListener messageCommandListener = new MessageCommandListener();
messageCommandListener.registerCommand(new HelloCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.InviteCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.AvatarCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.BotInfoCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.CoinFlipCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.ClearCommand());
messageCommandListener.registerCommand(new wtf.beatrice.hidekobot.commands.message.SayCommand());
Cache.setMessageCommandListener(messageCommandListener);
// register listeners

View File

@@ -0,0 +1,62 @@
package wtf.beatrice.hidekobot.commands.base;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import wtf.beatrice.hidekobot.Cache;
public class Avatar
{
public static int parseResolution(int resolution)
{
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
// method to find closest value to accepted values
int distance = Math.abs(acceptedSizes[0] - resolution);
int idx = 0;
for(int c = 1; c < acceptedSizes.length; c++){
int cdistance = Math.abs(acceptedSizes[c] - resolution);
if(cdistance < distance){
idx = c;
distance = cdistance;
}
}
return acceptedSizes[idx];
}
public static MessageEmbed buildEmbed(int resolution, User user)
{
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setColor(Cache.getBotColor());
embedBuilder.setTitle("Profile picture");
embedBuilder.addField("User", "<@" + user.getId() + ">", false);
embedBuilder.addField("Current resolution", resolution + " × " + resolution, false);
// string builder to create a string that links to all available resolutions
StringBuilder links = new StringBuilder();
for(int pos = 0; pos < acceptedSizes.length; pos++)
{
int currSize = acceptedSizes[pos];
String currLink = user.getEffectiveAvatar().getUrl(currSize);
links.append("[").append(currSize).append("px](").append(currLink).append(")");
if(pos + 1 != acceptedSizes.length) // don't add a separator on the last iteration
{
links.append(" | ");
}
}
embedBuilder.addField("Available resolutions", links.toString(), false);
embedBuilder.setImage(user.getEffectiveAvatar().getUrl(resolution));
return embedBuilder.build();
}
}

View File

@@ -0,0 +1,11 @@
package wtf.beatrice.hidekobot.commands.base;
import net.dv8tion.jda.api.Permission;
public class Say
{
public static Permission getPermission() {
return Permission.MESSAGE_MANAGE;
}
}

View File

@@ -0,0 +1,81 @@
package wtf.beatrice.hidekobot.commands.message;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.IMentionable;
import net.dv8tion.jda.api.entities.Mentions;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.jetbrains.annotations.Nullable;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.HidekoBot;
import wtf.beatrice.hidekobot.commands.base.Avatar;
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class AvatarCommand implements MessageCommand
{
@Override
public LinkedList<String> getCommandLabels() {
return new LinkedList<>(Collections.singletonList("avatar"));
}
@Nullable
@Override
public List<Permission> getPermissions() {
return null; // anyone can use it
}
@Override
public boolean passRawArgs() {
return false;
}
@Override
public void runCommand(MessageReceivedEvent event, String label, String[] args)
{
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
User user = null;
int resolution = -1;
// we have no specific order for user and resolution, so let's try parsing any arg as resolution
// (mentions are handled differently by a specific method)
boolean resFound = false;
for (String arg : args) {
try {
int givenRes = Integer.parseInt(arg);
resolution = Avatar.parseResolution(givenRes);
resFound = true;
break;
} catch (NumberFormatException ignored) {
}
}
// fallback in case we didn't find any specified resolution
if(!resFound) resolution = Avatar.parseResolution(512);
// check if someone is mentioned
Mentions mentions = event.getMessage().getMentions();
if(mentions.getMentions().isEmpty())
{
user = event.getAuthor();
} else
{
String mentionedId = mentions.getMentions().get(0).getId();
user = HidekoBot.getAPI().retrieveUserById(mentionedId).complete();
}
// in case of issues, fallback to the sender
if(user == null) user = event.getAuthor();
// send a response
MessageEmbed embed = Avatar.buildEmbed(resolution, user);
event.getMessage().replyEmbeds(embed).queue();
}
}

View File

@@ -0,0 +1,51 @@
package wtf.beatrice.hidekobot.commands.message;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import org.jetbrains.annotations.Nullable;
import wtf.beatrice.hidekobot.commands.base.ClearChat;
import wtf.beatrice.hidekobot.commands.base.Say;
import wtf.beatrice.hidekobot.objects.commands.MessageCommand;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class SayCommand implements MessageCommand
{
@Override
public LinkedList<String> getCommandLabels() {
return new LinkedList<>(Collections.singletonList("say"));
}
@Nullable
@Override
public List<Permission> getPermissions() { return Collections.singletonList(Say.getPermission()); }
@Override
public boolean passRawArgs() {
return true;
}
@Override
public void runCommand(MessageReceivedEvent event, String label, String[] args)
{
String messageContent = "";
if(args.length != 0)
{
messageContent = args[0];
} else {
event.getMessage().reply("\uD83D\uDE20 Hey, you have to tell me what to say!")
.queue();
return;
}
event.getChannel().sendMessage(messageContent).queue();
event.getMessage().delete().queue();
}
}

View File

@@ -1,6 +1,7 @@
package wtf.beatrice.hidekobot.commands.slash;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.MessageEmbed;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@@ -9,6 +10,7 @@ import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.Cache;
import wtf.beatrice.hidekobot.commands.base.Avatar;
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
public class AvatarCommand extends SlashCommandImpl
@@ -31,9 +33,6 @@ public class AvatarCommand extends SlashCommandImpl
User user;
int resolution;
int[] acceptedSizes = Cache.getSupportedAvatarResolutions();
OptionMapping userArg = event.getOption("user");
if(userArg != null)
{
@@ -45,57 +44,12 @@ public class AvatarCommand extends SlashCommandImpl
OptionMapping sizeArg = event.getOption("size");
if(sizeArg != null)
{
resolution = sizeArg.getAsInt();
// method to find closest value to accepted values
int distance = Math.abs(acceptedSizes[0] - resolution);
int idx = 0;
for(int c = 1; c < acceptedSizes.length; c++){
int cdistance = Math.abs(acceptedSizes[c] - resolution);
if(cdistance < distance){
idx = c;
distance = cdistance;
}
}
resolution = acceptedSizes[idx];
resolution = Avatar.parseResolution(sizeArg.getAsInt());
} else {
resolution = 512;
resolution = Avatar.parseResolution(512);
}
EmbedBuilder embedBuilder = new EmbedBuilder();
// embed processing
{
embedBuilder.setColor(Cache.getBotColor());
embedBuilder.setTitle("Profile picture");
embedBuilder.addField("User", "<@" + user.getId() + ">", false);
embedBuilder.addField("Current resolution", resolution + " × " + resolution, false);
// string builder to create a string that links to all available resolutions
StringBuilder links = new StringBuilder();
for(int pos = 0; pos < acceptedSizes.length; pos++)
{
int currSize = acceptedSizes[pos];
String currLink = user.getEffectiveAvatar().getUrl(currSize);
links.append("[").append(currSize).append("px](").append(currLink).append(")");
if(pos + 1 != acceptedSizes.length) // don't add a separator on the last iteration
{
links.append(" | ");
}
}
embedBuilder.addField("Available resolutions", links.toString(), false);
embedBuilder.setImage(user.getEffectiveAvatar().getUrl(resolution));
}
event.getHook().editOriginalEmbeds(embedBuilder.build()).queue();
MessageEmbed embed = Avatar.buildEmbed(resolution, user);
event.getHook().editOriginalEmbeds(embed).queue();
}
}

View File

@@ -9,6 +9,7 @@ import net.dv8tion.jda.api.interactions.commands.OptionType;
import net.dv8tion.jda.api.interactions.commands.build.CommandData;
import net.dv8tion.jda.api.interactions.commands.build.Commands;
import org.jetbrains.annotations.NotNull;
import wtf.beatrice.hidekobot.commands.base.Say;
import wtf.beatrice.hidekobot.objects.commands.SlashCommandImpl;
public class SayCommand extends SlashCommandImpl
@@ -22,7 +23,7 @@ public class SayCommand extends SlashCommandImpl
"The message to send.",
true,
false)
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Permission.MESSAGE_MANAGE));
.setDefaultPermissions(DefaultMemberPermissions.enabledFor(Say.getPermission()));
}
@Override

View File

@@ -57,10 +57,11 @@ public class MessageCommandListener extends ListenerAdapter
@Override
public void onMessageReceived(@NotNull MessageReceivedEvent event)
{
String eventMessage = event.getMessage().getContentDisplay();
// warning: we are getting the RAW value of the message content, not the DISPLAY value!
String eventMessage = event.getMessage().getContentRaw();
// check if the sent message matches the bot activation regex (prefix, name, ...)
if(!eventMessage.toLowerCase().matches(commandRegex + ".*"))
if(!eventMessage.toLowerCase().matches(commandRegex + "((.|\\n)*)"))
return;
// generate args from the string
@@ -120,6 +121,7 @@ public class MessageCommandListener extends ListenerAdapter
String[] commandArgs;
if(commandObject.passRawArgs())
{
// remove first argument, which is the command label
argsString = argsString.replaceAll("^[\\S]+\\s+", "");
// pass all other arguments as a single argument as the first array element