Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.pcsx2</groupId>
<artifactId>HifumiBot</artifactId>
<version>4.10.0</version>
<version>4.10.1</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
Expand Down
70 changes: 63 additions & 7 deletions src/main/java/net/pcsx2/hifumi/async/AntiBotRunnable.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
package net.pcsx2.hifumi.async;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.URI;
import java.net.URL;
import java.time.OffsetDateTime;
import java.util.ArrayList;

import javax.imageio.ImageIO;

import org.apache.commons.lang3.StringUtils;

import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
import net.dv8tion.jda.api.components.buttons.Button;
Expand All @@ -12,6 +23,7 @@
import net.dv8tion.jda.api.entities.Message.Attachment;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
import net.dv8tion.jda.api.utils.FileUpload;
import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder;
import net.pcsx2.hifumi.HifumiBot;
import net.pcsx2.hifumi.database.Database;
Expand Down Expand Up @@ -57,8 +69,40 @@ private boolean isImageScam() {
User user = this.message.getAuthor();

if (timeoutRes) {
// Since our timeout succeeded, now sweep up any other messages the bot might have
// blasted out while this runnable was going.
// Since our timeout succeeded, grab some thumbnails of the images so we have something to present for review before deleting stuff.
// If we delete the message first then attachments go too.
ArrayList<FileUpload> files = new ArrayList<FileUpload>();

for (Attachment attachment : this.message.getAttachments()) {
// For now, just do one image... If we have problems later and need them all, yank out this if.
if (!files.isEmpty()) {
break;
}

try {
URL url = URL.of(URI.create(attachment.getProxyUrl()), null);
BufferedImage img = ImageIO.read(url);
int width = img.getWidth() / 2, height = img.getHeight() / 2;
Image scaled = img.getScaledInstance(width, height, Image.SCALE_FAST);
BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graph = bufImg.createGraphics();
graph.drawImage(scaled, 0, 0, null);
graph.dispose();

try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
ImageIO.write(bufImg, "png", os);

try (ByteArrayInputStream imgStream = new ByteArrayInputStream(os.toByteArray())) {
FileUpload file = FileUpload.fromData(imgStream, attachment.getFileName()).asSpoiler();
files.add(file);
}
}
} catch (Exception e) {
// Squelch
}
}

// Sweep up any other messages the bot might have blasted out while this runnable was going.
OffsetDateTime timeToRemoveMessagesSince = OffsetDateTime.now().minusMinutes(AGE_MINUTES_TO_REMOVE_MESSAGES);
ArrayList<MessageObject> otherMessages = Database.getAllMessagesSinceTime(this.message.getAuthor().getIdLong(), timeToRemoveMessagesSince.toEpochSecond());

Expand All @@ -75,24 +119,36 @@ private boolean isImageScam() {
eb.addField("Username", user.getName(), true);
eb.addField("Display Name (as mention)", user.getAsMention(), true);
eb.setColor(Color.YELLOW);
eb.appendDescription("Links in body:\n");

// Body content preview
eb.addField("Body Content (raw, first 100 chars)", StringUtils.abbreviate(this.message.getContentRaw(), 100), false);

// Links
StringBuilder sb = new StringBuilder();

for (String link : links) {
eb.appendDescription(link + "\n");
sb.append(link + "\n");
}

eb.appendDescription("Attachments:\n");

eb.addField("Links in Body", sb.toString(), false);

// Attachments
sb = new StringBuilder();

for (Attachment attachment : this.message.getAttachments()) {
eb.appendDescription(attachment.getProxyUrl() + "\n");
sb.append(attachment.getProxyUrl() + "\n");
}

eb.addField("Attachments", sb.toString(), false);

MessageCreateBuilder mb = new MessageCreateBuilder();
mb.addEmbeds(eb.build());
mb.addFiles(files);
mb.addComponents(ActionRow.of(
Button.of(ButtonStyle.DANGER, "imagescam:dospamkick:" + authorIdLong, "Looks like a bot scam, kick user"),
Button.of(ButtonStyle.SUCCESS, "imagescam:clear:" + authorIdLong, "Looks innocent, remove timeout")
));

Messaging.sendMessage(HifumiBot.getSelf().getConfig().channels.systemOutputChannelId, mb.build());
return true;
} else {
Expand Down
31 changes: 18 additions & 13 deletions src/main/java/net/pcsx2/hifumi/event/ButtonEventListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,10 @@
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import net.pcsx2.hifumi.HifumiBot;
import net.pcsx2.hifumi.command.AbstractSlashCommand;
import net.pcsx2.hifumi.command.slash.CommandEmulog;
import net.pcsx2.hifumi.command.slash.CommandServerMetadata;
import net.pcsx2.hifumi.command.slash.CommandWhois;
import net.pcsx2.hifumi.moderation.ModActions;
import net.pcsx2.hifumi.util.MemberUtils;
import net.pcsx2.hifumi.util.Messaging;
import net.pcsx2.hifumi.util.UserUtils;

import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.components.MessageTopLevelComponent;
import net.dv8tion.jda.api.components.actionrow.ActionRow;
Expand All @@ -25,6 +16,15 @@
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.pcsx2.hifumi.HifumiBot;
import net.pcsx2.hifumi.command.AbstractSlashCommand;
import net.pcsx2.hifumi.command.slash.CommandEmulog;
import net.pcsx2.hifumi.command.slash.CommandServerMetadata;
import net.pcsx2.hifumi.command.slash.CommandWhois;
import net.pcsx2.hifumi.moderation.ModActions;
import net.pcsx2.hifumi.util.MemberUtils;
import net.pcsx2.hifumi.util.Messaging;
import net.pcsx2.hifumi.util.UserUtils;

public class ButtonEventListener extends ListenerAdapter {

Expand Down Expand Up @@ -132,6 +132,7 @@ public void onButtonInteraction(ButtonInteractionEvent event) {
Button button = Button.of(ButtonStyle.PRIMARY, "imagescam:resolved:" + userIdLong, "Resolved by " + event.getUser().getEffectiveName() + " (kicked user)");
ActionRow actionRow = ActionRow.of(button);
event.getHook().editMessageComponentsById(event.getMessageId(), actionRow).queue();
event.getMessage().editMessageAttachments(List.of()).queue();
}
case "clear" -> {
Optional<Member> memberOpt = MemberUtils.getOrRetrieveMember(event.getGuild(), userIdLong);
Expand All @@ -140,10 +141,14 @@ public void onButtonInteraction(ButtonInteractionEvent event) {
Member member = memberOpt.get();
member.removeTimeout().queue();
event.reply("Timeout removed from user").setEphemeral(true).queue();
Button button = Button.of(ButtonStyle.PRIMARY, "imagescam:resolved:" + userIdLong, "Resolved by " + event.getUser().getEffectiveName() + " (removed timeout)");
ActionRow actionRow = ActionRow.of(button);
event.getHook().editMessageComponentsById(event.getMessageId(), actionRow).queue();
} else {
event.reply("User could not be retrieved, did they already leave?").setEphemeral(true).queue();
}

Button button = Button.of(ButtonStyle.PRIMARY, "imagescam:resolved:" + userIdLong, "Resolved by " + event.getUser().getEffectiveName() + " (removed timeout)");
ActionRow actionRow = ActionRow.of(button);
event.getHook().editMessageComponentsById(event.getMessageId(), actionRow).queue();
event.getMessage().editMessageAttachments(List.of()).queue();
}
case "resolved" -> {
event.reply("This event has already been resolved.").setEphemeral(true).queue();
Expand Down