From e4cbaed8e6abbe5e3cd2d4f7109f1998ba64d9da Mon Sep 17 00:00:00 2001 From: xsling Date: Tue, 10 May 2022 01:26:42 +0800 Subject: [PATCH] feat: quote reply for image forwarding --- bungee/src/main/resources/messages.properties | 2 +- .../src/main/resources/messages_en.properties | 2 +- .../main/resources/messages_zh_CN.properties | 2 +- .../phenyl/common/dependency/Dependency.java | 2 +- .../common/message/AbstractForwarder.java | 66 +++++++++++-------- .../phenyl/common/message/ImageMessage.java | 18 ++--- .../turna/phenyl/common/utils/MiraiUtils.java | 52 +++++++++++---- 7 files changed, 88 insertions(+), 56 deletions(-) diff --git a/bungee/src/main/resources/messages.properties b/bungee/src/main/resources/messages.properties index 53e9010..dc1fc53 100644 --- a/bungee/src/main/resources/messages.properties +++ b/bungee/src/main/resources/messages.properties @@ -18,7 +18,7 @@ readConfigFail=Failed to read configurations. {0} createLogFileFail=Failed to create the log file. {0} createAvatarFail=Failed to create avatar file: {0} getAvatarFail=Failed to get the avatar: {0} -getImageFail=Filed to get the image: {0} +getImageFail=Failed to get the image imageMessage=[Image] configLoaded=Loaded configurations debugEnabled=DEBUG enabled. diff --git a/bungee/src/main/resources/messages_en.properties b/bungee/src/main/resources/messages_en.properties index 53e9010..dc1fc53 100644 --- a/bungee/src/main/resources/messages_en.properties +++ b/bungee/src/main/resources/messages_en.properties @@ -18,7 +18,7 @@ readConfigFail=Failed to read configurations. {0} createLogFileFail=Failed to create the log file. {0} createAvatarFail=Failed to create avatar file: {0} getAvatarFail=Failed to get the avatar: {0} -getImageFail=Filed to get the image: {0} +getImageFail=Failed to get the image imageMessage=[Image] configLoaded=Loaded configurations debugEnabled=DEBUG enabled. diff --git a/bungee/src/main/resources/messages_zh_CN.properties b/bungee/src/main/resources/messages_zh_CN.properties index c59626b..edcd236 100644 --- a/bungee/src/main/resources/messages_zh_CN.properties +++ b/bungee/src/main/resources/messages_zh_CN.properties @@ -18,7 +18,7 @@ readConfigFail=读取配置文件失败。{0} createLogFileFail=日志文件创建失败。{0} createAvatarFail=创建头像文件失败: {0} getAvatarFail=获取头像失败:{0} -getImageFail=获取图片失败:{0} +getImageFail=获取图片失败 imageMessage=[图片] configLoaded=加载配置成功 debugEnabled=已开启DEBUG输出 diff --git a/common/src/main/java/live/turna/phenyl/common/dependency/Dependency.java b/common/src/main/java/live/turna/phenyl/common/dependency/Dependency.java index 8e59135..e1757ff 100644 --- a/common/src/main/java/live/turna/phenyl/common/dependency/Dependency.java +++ b/common/src/main/java/live/turna/phenyl/common/dependency/Dependency.java @@ -9,7 +9,7 @@ public enum Dependency { LOG4JCORE("org.apache.logging.log4j", "log4j-core", "2.17.1"), LOG4JAPI("org.apache.logging.log4j", "log4j-api", "2.17.1"), - MIRAI("net.mamoe", "mirai-core-all", "2.10.3", "all"), + MIRAI("net.mamoe", "mirai-core-all", "2.10.0", "all"), GENEREX("com.github.mifmif", "generex", "1.0.2"), JACKSON("com.fasterxml.jackson.dataformat", "jackson-dataformat-xml", "2.13.1"), AUTOMATON("dk.brics.automaton", "automaton", "1.11-8"), diff --git a/common/src/main/java/live/turna/phenyl/common/message/AbstractForwarder.java b/common/src/main/java/live/turna/phenyl/common/message/AbstractForwarder.java index e1a32cf..28702fa 100644 --- a/common/src/main/java/live/turna/phenyl/common/message/AbstractForwarder.java +++ b/common/src/main/java/live/turna/phenyl/common/message/AbstractForwarder.java @@ -6,18 +6,21 @@ import live.turna.phenyl.common.utils.MiraiUtils; import net.kyori.adventure.text.Component; import net.mamoe.mirai.contact.Group; +import net.mamoe.mirai.message.MessageReceipt; import net.mamoe.mirai.message.data.MessageChain; import net.mamoe.mirai.message.data.MessageChainBuilder; import net.mamoe.mirai.message.data.SingleMessage; import org.apache.logging.log4j.Logger; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -81,9 +84,9 @@ public Component matchMessageType(MessageChain message, String[] format, String * @param uuid The sender's Minecraft UUID. * @param subServer In which sub server the message is sent. */ - public boolean forwardToQQ(String message, String userName, String uuid, String subServer) { + public ArrayList> forwardToQQ(String message, String userName, String uuid, String subServer) { for (Player it : phenyl.getMutedPlayer()) { - if (uuid.equals(it.uuid())) return false; + if (uuid.equals(it.uuid())) return null; } if (Config.save_message) { phenyl.getStorage().addMessage(message.replaceAll("'", "''"), uuid); @@ -100,50 +103,59 @@ public boolean forwardToQQ(String message, String userName, String uuid, String else return forwardPlainMessage(message, userName, subServer); } - private boolean forwardSingleImage(String url, String userName, String uuid, String subServer) { + private ArrayList> forwardSingleImage(String url, String userName, String uuid, String subServer) { + ArrayList> referenceReceipts; + AtomicReference>> receipts = new AtomicReference<>(); if (Config.server_to_qq_format.equals("image")) - forwardImageMessage(i18n("imageMessage"), userName, uuid); - else forwardPlainMessage(i18n("imageMessage"), userName, subServer); + referenceReceipts = forwardImageMessage(i18n("imageMessage"), userName, uuid); + else referenceReceipts = forwardPlainMessage(i18n("imageMessage"), userName, subServer); // retrieve and send image - CompletableFuture futureGet = CompletableFuture.supplyAsync(() -> new ImageMessage(phenyl).getImageFromURL(url)) - .orTimeout(Config.get_image_timeout, TimeUnit.SECONDS).thenApplyAsync((@NotNull BufferedImage image) -> { - try { - new MiraiUtils(phenyl).sendImage(image); - return true; - } catch (NoSuchElementException e) { - LOGGER.error(i18n("noSuchGroup", e.getLocalizedMessage())); - if (Config.debug) e.printStackTrace(); - return false; - } - }).orTimeout(3, TimeUnit.SECONDS); - return !futureGet.isCompletedExceptionally(); + CompletableFuture futureGet = CompletableFuture.supplyAsync(() -> { + try { + return new ImageMessage(phenyl).getImageFromURL(url); + } catch (IOException e) { + return null; + } + }).completeOnTimeout(null, Config.get_image_timeout, TimeUnit.SECONDS); + futureGet.thenApplyAsync((BufferedImage image) -> { + if (image == null) { + receipts.set(new MiraiUtils(phenyl).sendAllGroup(i18n("getImageFail"), referenceReceipts)); + return false; + } + try { + receipts.set(new MiraiUtils(phenyl).sendImage(image, referenceReceipts)); + return true; + } catch (NoSuchElementException e) { + LOGGER.error(i18n("noSuchGroup", e.getLocalizedMessage())); + if (Config.debug) e.printStackTrace(); + return false; + } + }).orTimeout(3, TimeUnit.SECONDS); + return receipts.get(); } - private boolean forwardPlainMessage(String message, String userName, String subServer) { + private ArrayList> forwardPlainMessage(String message, String userName, String subServer) { String format = Config.server_to_qq_format .replace("%sub_server%", subServer) .replace("%username%", userName) .replace("%message%", message); - MessageChain messageChain = new MessageChainBuilder().append(format).build(); try { - new MiraiUtils(phenyl).sendGroup(messageChain); - return true; + return new MiraiUtils(phenyl).sendAllGroup(format); } catch (NoSuchElementException e) { LOGGER.error(i18n("noSuchGroup", e.getLocalizedMessage())); if (Config.debug) e.printStackTrace(); - return false; + return new ArrayList<>(); } } - private boolean forwardImageMessage(String message, String userName, String uuid) { + private ArrayList> forwardImageMessage(String message, String userName, String uuid) { try { - new MiraiUtils(phenyl).sendImage(new ImageMessage(phenyl).drawImageMessage(message, userName, uuid)); - return true; + return new MiraiUtils(phenyl).sendImage(new ImageMessage(phenyl).drawImageMessage(message, userName, uuid)); } catch (NoSuchElementException e) { LOGGER.error(i18n("noSuchGroup", e.getLocalizedMessage())); if (Config.debug) e.printStackTrace(); - return false; + return new ArrayList<>(); } } } \ No newline at end of file diff --git a/common/src/main/java/live/turna/phenyl/common/message/ImageMessage.java b/common/src/main/java/live/turna/phenyl/common/message/ImageMessage.java index d5e65bc..0240050 100644 --- a/common/src/main/java/live/turna/phenyl/common/message/ImageMessage.java +++ b/common/src/main/java/live/turna/phenyl/common/message/ImageMessage.java @@ -10,6 +10,7 @@ import java.awt.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; +import java.io.IOException; import java.net.URL; import static live.turna.phenyl.common.message.I18n.i18n; @@ -24,10 +25,11 @@ public class ImageMessage { private final transient AbstractPhenyl phenyl; private final transient Logger LOGGER; - public ImageMessage(AbstractPhenyl plugin){ - phenyl=plugin; - LOGGER=phenyl.getLogger(); + public ImageMessage(AbstractPhenyl plugin) { + phenyl = plugin; + LOGGER = phenyl.getLogger(); } + /** * Draw an image message. * @@ -157,13 +159,7 @@ public String insertPeriodically(String message, int maxChars) { * @param url The remote URL. * @return The buffered image. */ - public BufferedImage getImageFromURL(String url) { - try { - return ImageIO.read(new URL(url)); - } catch (Exception e) { - LOGGER.error(i18n("getImageFail", e.getLocalizedMessage())); - if (Config.debug) e.printStackTrace(); - } - return null; + public BufferedImage getImageFromURL(String url) throws IOException { + return ImageIO.read(new URL(url)); } } \ No newline at end of file diff --git a/common/src/main/java/live/turna/phenyl/common/utils/MiraiUtils.java b/common/src/main/java/live/turna/phenyl/common/utils/MiraiUtils.java index 5aeae9a..12a6085 100644 --- a/common/src/main/java/live/turna/phenyl/common/utils/MiraiUtils.java +++ b/common/src/main/java/live/turna/phenyl/common/utils/MiraiUtils.java @@ -3,6 +3,7 @@ import live.turna.phenyl.common.config.Config; import live.turna.phenyl.common.plugin.AbstractPhenyl; import net.mamoe.mirai.contact.Group; +import net.mamoe.mirai.message.MessageReceipt; import net.mamoe.mirai.message.data.Image; import net.mamoe.mirai.message.data.MessageChain; import net.mamoe.mirai.message.data.MessageChainBuilder; @@ -18,6 +19,7 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.ArrayList; import java.util.NoSuchElementException; import static live.turna.phenyl.common.message.I18n.i18n; @@ -32,9 +34,9 @@ public class MiraiUtils { private final transient AbstractPhenyl phenyl; private final transient Logger LOGGER; - public MiraiUtils(AbstractPhenyl plugin){ - phenyl=plugin; - LOGGER=phenyl.getLogger(); + public MiraiUtils(AbstractPhenyl plugin) { + phenyl = plugin; + LOGGER = phenyl.getLogger(); } /** @@ -98,8 +100,8 @@ public BotConfiguration.MiraiProtocol matchProtocol(String proString) throws Ill * @param group The group to send to. * @param message The message in plain string type. */ - public void sendGroup(Group group, String message) { - group.sendMessage(message); + public MessageReceipt sendGroup(Group group, String message) { + return group.sendMessage(message); } /** @@ -108,8 +110,8 @@ public void sendGroup(Group group, String message) { * @param group The group to send to. * @param message The message in {@link MessageChain} type. */ - public void sendGroup(Group group, MessageChain message) { - group.sendMessage(message); + public MessageReceipt sendGroup(Group group, MessageChain message) { + return group.sendMessage(message); } /** @@ -117,8 +119,12 @@ public void sendGroup(Group group, MessageChain message) { * * @param message The message in plain string type. */ - public void sendGroup(String message) throws NoSuchElementException { - sendGroup(new MessageChainBuilder().append(message).build()); + public ArrayList> sendAllGroup(String message) throws NoSuchElementException { + return sendAllGroup(new MessageChainBuilder().append(message).build()); + } + + public ArrayList> sendAllGroup(String message, ArrayList> referenceReceipts) throws NoSuchElementException { + return sendAllGroup(new MessageChainBuilder().append(message).build(), referenceReceipts); } /** @@ -126,14 +132,24 @@ public void sendGroup(String message) throws NoSuchElementException { * * @param message The message in {@link MessageChain} type. */ - public void sendGroup(MessageChain message) throws NoSuchElementException { + public ArrayList> sendAllGroup(MessageChain message) throws NoSuchElementException { + return sendAllGroup(message, null); + } + + public ArrayList> sendAllGroup(MessageChain message, ArrayList> referenceReceipts) throws NoSuchElementException { + ArrayList> receipts = new ArrayList<>(); for (Long id : Config.enabled_groups) { try { - phenyl.getMirai().getBot().getGroupOrFail(id).sendMessage(message); + Group group = phenyl.getMirai().getBot().getGroupOrFail(id); + MessageChainBuilder msg = new MessageChainBuilder().append(message); + if (referenceReceipts != null) + referenceReceipts.stream().filter(r -> r.getTarget().equals(group)).forEach(r -> msg.append(r.quote())); + receipts.add(group.sendMessage(msg.build())); } catch (NoSuchElementException e) { throw new NoSuchElementException(String.valueOf(id)); } } + return receipts; } /** @@ -142,7 +158,8 @@ public void sendGroup(MessageChain message) throws NoSuchElementException { * @param image The image to be sent. * @throws NoSuchElementException Target group not found. */ - public void sendImage(BufferedImage image) throws NoSuchElementException { + public ArrayList> sendImage(BufferedImage image, ArrayList> referenceReceipts) throws NoSuchElementException { + ArrayList> receipts = new ArrayList<>(); ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { ImageIO.write(image, "png", stream); @@ -154,8 +171,10 @@ public void sendImage(BufferedImage image) throws NoSuchElementException { try { Group group = phenyl.getMirai().getBot().getGroupOrFail(id); Image img = ExternalResource.uploadAsImage(resource, group); - MessageChain message = new MessageChainBuilder().append(img).build(); - group.sendMessage(message); + MessageChainBuilder message = new MessageChainBuilder().append(img); + if (referenceReceipts != null) + referenceReceipts.stream().filter(r -> r.getTarget().equals(group)).forEach(r -> message.append(r.quote())); + receipts.add(group.sendMessage(message.build())); } catch (NoSuchElementException e) { throw new NoSuchElementException(String.valueOf(id)); } @@ -165,5 +184,10 @@ public void sendImage(BufferedImage image) throws NoSuchElementException { } catch (IOException e) { if (Config.debug) e.printStackTrace(); } + return receipts; + } + + public ArrayList> sendImage(BufferedImage image) throws NoSuchElementException { + return sendImage(image, null); } } \ No newline at end of file