Skip to content

Commit

Permalink
feat: quote reply for image forwarding
Browse files Browse the repository at this point in the history
  • Loading branch information
xslingcn committed May 9, 2022
1 parent 3757adb commit e4cbaed
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 56 deletions.
2 changes: 1 addition & 1 deletion bungee/src/main/resources/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion bungee/src/main/resources/messages_en.properties
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion bungee/src/main/resources/messages_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ readConfigFail=读取配置文件失败。{0}
createLogFileFail=日志文件创建失败。{0}
createAvatarFail=创建头像文件失败: {0}
getAvatarFail=获取头像失败:{0}
getImageFail=获取图片失败:{0}
getImageFail=获取图片失败
imageMessage=[图片]
configLoaded=加载配置成功
debugEnabled=已开启DEBUG输出
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<MessageReceipt<Group>> 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);
Expand All @@ -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<MessageReceipt<Group>> forwardSingleImage(String url, String userName, String uuid, String subServer) {
ArrayList<MessageReceipt<Group>> referenceReceipts;
AtomicReference<ArrayList<MessageReceipt<Group>>> 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<Boolean> 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<BufferedImage> 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<MessageReceipt<Group>> 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<MessageReceipt<Group>> 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<>();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.
*
Expand Down Expand Up @@ -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));
}
}
52 changes: 38 additions & 14 deletions common/src/main/java/live/turna/phenyl/common/utils/MiraiUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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();
}

/**
Expand Down Expand Up @@ -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<Group> sendGroup(Group group, String message) {
return group.sendMessage(message);
}

/**
Expand All @@ -108,32 +110,46 @@ 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<Group> sendGroup(Group group, MessageChain message) {
return group.sendMessage(message);
}

/**
* Send all group the message.
*
* @param message The message in plain string type.
*/
public void sendGroup(String message) throws NoSuchElementException {
sendGroup(new MessageChainBuilder().append(message).build());
public ArrayList<MessageReceipt<Group>> sendAllGroup(String message) throws NoSuchElementException {
return sendAllGroup(new MessageChainBuilder().append(message).build());
}

public ArrayList<MessageReceipt<Group>> sendAllGroup(String message, ArrayList<MessageReceipt<Group>> referenceReceipts) throws NoSuchElementException {
return sendAllGroup(new MessageChainBuilder().append(message).build(), referenceReceipts);
}

/**
* Send all group the message.
*
* @param message The message in {@link MessageChain} type.
*/
public void sendGroup(MessageChain message) throws NoSuchElementException {
public ArrayList<MessageReceipt<Group>> sendAllGroup(MessageChain message) throws NoSuchElementException {
return sendAllGroup(message, null);
}

public ArrayList<MessageReceipt<Group>> sendAllGroup(MessageChain message, ArrayList<MessageReceipt<Group>> referenceReceipts) throws NoSuchElementException {
ArrayList<MessageReceipt<Group>> 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;
}

/**
Expand All @@ -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<MessageReceipt<Group>> sendImage(BufferedImage image, ArrayList<MessageReceipt<Group>> referenceReceipts) throws NoSuchElementException {
ArrayList<MessageReceipt<Group>> receipts = new ArrayList<>();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
ImageIO.write(image, "png", stream);
Expand All @@ -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));
}
Expand All @@ -165,5 +184,10 @@ public void sendImage(BufferedImage image) throws NoSuchElementException {
} catch (IOException e) {
if (Config.debug) e.printStackTrace();
}
return receipts;
}

public ArrayList<MessageReceipt<Group>> sendImage(BufferedImage image) throws NoSuchElementException {
return sendImage(image, null);
}
}

0 comments on commit e4cbaed

Please # to comment.