diff --git a/.idea/fileTemplates/includes/Version.txt b/.idea/fileTemplates/includes/Version.txt
index e59eb1a..37e50c3 100644
--- a/.idea/fileTemplates/includes/Version.txt
+++ b/.idea/fileTemplates/includes/Version.txt
@@ -1 +1 @@
-0.0.2-dev
\ No newline at end of file
+0.0.3-dev
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f6589e3..474b38c 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,10 +1,19 @@
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index 4c896d4..d993c9f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
val projectName = rootProject.name
val groupName by extra("cn.wzpmc")
val projectArtifactId by extra("my-bot")
-val projectVersion by extra("0.0.2-dev")
+val projectVersion by extra("0.0.3-dev")
plugins {
id("java")
diff --git a/src/main/java/cn/wzpmc/Main.java b/src/main/java/cn/wzpmc/Main.java
index 28d8bff..2146953 100644
--- a/src/main/java/cn/wzpmc/Main.java
+++ b/src/main/java/cn/wzpmc/Main.java
@@ -6,6 +6,7 @@ import cn.wzpmc.console.MyBotConsole;
import cn.wzpmc.entities.user.bot.MyBot;
import cn.wzpmc.network.WebSocketConnectionHandler;
import cn.wzpmc.plugins.CommandManager;
+import cn.wzpmc.utils.JsonUtils;
import cn.wzpmc.utils.TemplateFileUtils;
import cn.wzpmc.utils.YamlUtils;
import io.netty.channel.ChannelFuture;
@@ -23,6 +24,8 @@ public class Main {
public static void main(String[] args) {
System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager");
System.setProperty("terminal.jline", "true");
+ JsonUtils.initReader();
+ JsonUtils.initWriter();
log.info("启动MyBot...");
File configurationFile = new File("config.yaml");
if (TemplateFileUtils.saveDefaultConfig(Main.class.getClassLoader(), DEFAULT_CONFIGURATION_FILE_PATH, configurationFile)) {
diff --git a/src/main/java/cn/wzpmc/api/events/EventPostType.java b/src/main/java/cn/wzpmc/api/events/EventPostType.java
index 3a49072..b6e3b77 100644
--- a/src/main/java/cn/wzpmc/api/events/EventPostType.java
+++ b/src/main/java/cn/wzpmc/api/events/EventPostType.java
@@ -1,5 +1,10 @@
package cn.wzpmc.api.events;
+import cn.wzpmc.api.events.message.MessageEvent;
+import cn.wzpmc.api.events.meta.MetaEvent;
+import cn.wzpmc.api.events.notice.NoticeEvent;
+import cn.wzpmc.api.events.request.RequestEvent;
+
/**
* 事件类型
* @author wzp
@@ -11,20 +16,24 @@ public enum EventPostType {
* 消息事件
* @since 2024/8/1 下午5:48 v0.0.2-dev
*/
- MESSAGE,
+ MESSAGE(MessageEvent.class),
/**
* 通知事件
* @since 2024/8/1 下午5:47 v0.0.2-dev
*/
- NOTICE,
+ NOTICE(NoticeEvent.class),
/**
* 请求事件
* @since 2024/8/1 下午5:47 v0.0.2-dev
*/
- REQUEST,
+ REQUEST(RequestEvent.class),
/**
* 元事件
* @since 2024/8/1 下午5:47 v0.0.2-dev
*/
- META_EVENT,
+ META_EVENT(MetaEvent.class);
+ public final Class extends Event> clazz;
+ EventPostType(Class extends Event> clazz){
+ this.clazz = clazz;
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/events/message/MessageEvent.java b/src/main/java/cn/wzpmc/api/events/message/MessageEvent.java
index 14b8231..e80b8f1 100644
--- a/src/main/java/cn/wzpmc/api/events/message/MessageEvent.java
+++ b/src/main/java/cn/wzpmc/api/events/message/MessageEvent.java
@@ -1,7 +1,8 @@
package cn.wzpmc.api.events.message;
import cn.wzpmc.api.events.Event;
-import cn.wzpmc.api.message.MessageComponent;
+import cn.wzpmc.api.message.StringMessage;
+import cn.wzpmc.api.message.json.JsonMessage;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.AllArgsConstructor;
import lombok.Data;
@@ -47,13 +48,13 @@ public class MessageEvent extends Event {
* 消息详细内容
* @since 2024/8/1 下午11:11 v0.0.2-dev
*/
- private MessageComponent message;
+ private JsonMessage message;
/**
* 文本格式消息
* @since 2024/8/1 下午11:11 v0.0.2-dev
*/
@JSONField(name = "raw_message")
- private String rawMessage;
+ private StringMessage rawMessage;
/**
* 消息使用字体
* @since 2024/8/1 下午11:11 v0.0.2-dev
diff --git a/src/main/java/cn/wzpmc/api/message/StringMessage.java b/src/main/java/cn/wzpmc/api/message/StringMessage.java
index 9955642..2ec5d5c 100644
--- a/src/main/java/cn/wzpmc/api/message/StringMessage.java
+++ b/src/main/java/cn/wzpmc/api/message/StringMessage.java
@@ -1,6 +1,12 @@
package cn.wzpmc.api.message;
-import lombok.RequiredArgsConstructor;
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
/**
* 纯文本消息
@@ -8,9 +14,12 @@ import lombok.RequiredArgsConstructor;
* @version 0.0.1-dev
* @since 2024/7/31 上午2:34
*/
-@RequiredArgsConstructor
-public class StringMessage implements MessageComponent{
- private final String message;
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class StringMessage implements MessageComponent, JsonMessagePart {
+ @JSONField(name = "text")
+ private String message;
@Override
public String toMessageString() {
return this.message;
@@ -26,4 +35,24 @@ public class StringMessage implements MessageComponent{
public static StringMessage text(String message){
return new StringMessage(message);
}
+
+ @Override
+ public PartType getPartType() {
+ return PartType.TEXT;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("text", this.message);
+ }
+
+ @Override
+ public String getTextDisplay() {
+ return this.message;
+ }
+
+ @Override
+ public String getCQCode() {
+ return this.message;
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java b/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
index baeb333..5a6b0be 100644
--- a/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
+++ b/src/main/java/cn/wzpmc/api/message/json/JsonMessage.java
@@ -2,6 +2,7 @@ package cn.wzpmc.api.message.json;
import cn.wzpmc.api.message.MessageComponent;
import com.alibaba.fastjson2.JSON;
+import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@@ -13,6 +14,7 @@ import java.util.stream.Collectors;
* @version 0.0.1-dev
* @since 2024/7/31 上午2:34
*/
+@Data
public class JsonMessage implements MessageComponent {
private final List messageParts = new ArrayList<>();
@Override
@@ -22,4 +24,16 @@ public class JsonMessage implements MessageComponent {
public String toTextDisplay() {
return this.messageParts.stream().map(JsonMessagePart::getTextDisplay).collect(Collectors.joining(""));
}
+
+ /**
+ * 将JSON消息转换为CQ文本消息
+ * @author wzp
+ * @since 2024/8/2 下午9:36 v0.0.3-dev
+ * @return 文本消息
+ */
+ public String toCqString(){
+ StringBuilder stringBuilder = new StringBuilder();
+ this.messageParts.stream().map(JsonMessagePart::getCQCode).forEach(stringBuilder::append);
+ return stringBuilder.toString();
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/message/json/JsonMessagePart.java b/src/main/java/cn/wzpmc/api/message/json/JsonMessagePart.java
index 27bbdef..ff54325 100644
--- a/src/main/java/cn/wzpmc/api/message/json/JsonMessagePart.java
+++ b/src/main/java/cn/wzpmc/api/message/json/JsonMessagePart.java
@@ -1,6 +1,9 @@
package cn.wzpmc.api.message.json;
-import java.util.Map;
+import cn.wzpmc.api.message.json.parts.PartType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.alibaba.fastjson2.annotation.JSONType;
/**
* JSON消息段
@@ -8,14 +11,19 @@ import java.util.Map;
* @version 0.0.1-dev
* @since 2024/7/31 上午2:36
*/
+@JSONType(includes = {"type", "data"})
public interface JsonMessagePart {
/**
* 获取消息的类型
* @author wzp
* @since 2024/7/31 上午2:40 v0.0.1-dev
- * @return 消息类型字符串
+ * @return 消息类型
*/
- String getType();
+ PartType getPartType();
+ @JSONField(name = "type")
+ default String getStringPartType(){
+ return this.getPartType().toString().toLowerCase();
+ }
/**
* 获取消息附带的数据
@@ -23,7 +31,7 @@ public interface JsonMessagePart {
* @since 2024/7/31 上午2:40 v0.0.1-dev
* @return 数据
*/
- Map getData();
+ JSONObject getData();
/**
* 获取当纯文本界面的代替文本
@@ -33,14 +41,31 @@ public interface JsonMessagePart {
*/
default String getTextDisplay(){
StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append(this.getType())
+ stringBuilder.append(this.getPartType())
.append('(')
.append('\n');
- Map data = this.getData();
+ JSONObject data = this.getData();
data.forEach((key, value) -> stringBuilder.append('\t').append(key).append('=').append(value).append(',').append('\n'));
int length = stringBuilder.length();
stringBuilder.delete(length - 2, length - 1);
stringBuilder.append(')');
return stringBuilder.toString();
}
+
+ /**
+ * 获取消息段的CQ码
+ * @author wzp
+ * @since 2024/8/2 下午9:32 v0.0.3-dev
+ * @return CQ码
+ */
+ default String getCQCode(){
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("[CQ:").append(this.getPartType().toString().toLowerCase()).append(',');
+ JSONObject data = getData();
+ data.forEach((key, value) -> stringBuilder.append(key).append('=').append(value).append(','));
+ int lastSplit = stringBuilder.length() - 1;
+ stringBuilder.deleteCharAt(lastSplit);
+ stringBuilder.append(']');
+ return stringBuilder.toString();
+ }
}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Anonymous.java b/src/main/java/cn/wzpmc/api/message/json/parts/Anonymous.java
new file mode 100644
index 0000000..3f5cf40
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Anonymous.java
@@ -0,0 +1,31 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 匿名发消息
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:19
+ */
+@Data
+@NoArgsConstructor
+public class Anonymous implements JsonMessagePart {
+ /**
+ * 可选,表示无法匿名时是否继续发送
+ * @since 2024/8/3 下午5:55 v0.0.3-dev
+ */
+ private boolean ignore = false;
+ @Override
+ public PartType getPartType() {
+ return PartType.ANONYMOUS;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("ignore", this.ignore);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/CustomJSONMessage.java b/src/main/java/cn/wzpmc/api/message/json/parts/CustomJSONMessage.java
new file mode 100644
index 0000000..164406e
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/CustomJSONMessage.java
@@ -0,0 +1,31 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * JSON 消息
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:43
+ */
+@Data
+@NoArgsConstructor
+public class CustomJSONMessage implements JsonMessagePart {
+ /**
+ * JSON 内容
+ * @since 2024/8/3 下午6:11 v0.0.3-dev
+ */
+ private JSONObject data;
+ @Override
+ public PartType getPartType() {
+ return PartType.JSON;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("data", this.data);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Face.java b/src/main/java/cn/wzpmc/api/message/json/parts/Face.java
new file mode 100644
index 0000000..1d85264
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Face.java
@@ -0,0 +1,32 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * QQ表情
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:00
+ */
+@Data
+@NoArgsConstructor
+public class Face implements JsonMessagePart {
+ /**
+ * qq表情ID
+ * @since 2024/8/2 下午11:46 v0.0.3-dev
+ */
+ private Short id;
+ @Override
+ public PartType getPartType() {
+ return PartType.FACE;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("face", id);
+ }
+
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Forward.java b/src/main/java/cn/wzpmc/api/message/json/parts/Forward.java
new file mode 100644
index 0000000..e9327fd
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Forward.java
@@ -0,0 +1,31 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合并转发
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:38
+ */
+@Data
+@NoArgsConstructor
+public class Forward implements JsonMessagePart {
+ /**
+ * 合并转发 ID,需通过 get_forward_msg API 获取具体内容
+ * @since 2024/8/3 下午6:10 v0.0.3-dev
+ */
+ private Long id;
+ @Override
+ public PartType getPartType() {
+ return PartType.FORWARD;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("id", this.id);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Location.java b/src/main/java/cn/wzpmc/api/message/json/parts/Location.java
new file mode 100644
index 0000000..549008d
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Location.java
@@ -0,0 +1,50 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 位置
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:22
+ */
+@Data
+@NoArgsConstructor
+public class Location implements JsonMessagePart {
+ /**
+ * 纬度
+ * @since 2024/8/3 下午6:06 v0.0.3-dev
+ */
+ private Double lat;
+ /**
+ * 经度
+ * @since 2024/8/3 下午6:07 v0.0.3-dev
+ */
+ private Double lon;
+ /**
+ * 发送时可选,标题
+ * @since 2024/8/3 下午6:07 v0.0.3-dev
+ */
+ private String title = "";
+ /**
+ * 发送时可选,内容描述
+ * @since 2024/8/3 下午6:07 v0.0.3-dev
+ */
+ private String content = "";
+ @Override
+ public PartType getPartType() {
+ return PartType.LOCATION;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return new JSONObject()
+ .fluentPut("lat", this.lat)
+ .fluentPut("lon", this.lon)
+ .fluentPut("title", this.title)
+ .fluentPut("content", this.content);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java b/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java
new file mode 100644
index 0000000..d84259e
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/PartType.java
@@ -0,0 +1,40 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.StringMessage;
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.contact.Contact;
+import cn.wzpmc.api.message.json.parts.music.Music;
+import cn.wzpmc.api.message.json.parts.node.Node;
+import cn.wzpmc.api.message.json.parts.poke.Poke;
+
+/**
+ * 消息段类型
+ * @author wzp
+ * @since 2024/8/3 下午6:18
+ * @version 0.0.3-dev */
+public enum PartType {
+ TEXT(StringMessage.class),
+ FACE(Face.class),
+ IMAGE(Image.class),
+ RECORD(Record.class),
+ VIDEO(Video.class),
+ AT(At.class),
+ RPS(cn.wzpmc.api.message.json.parts.RPS.class),
+ DICE(Dice.class),
+ SHAKE(Shake.class),
+ POKE(Poke.class),
+ ANONYMOUS(Anonymous.class),
+ SHARE(Share.class),
+ CONTACT(Contact.class),
+ LOCATION(Location.class),
+ MUSIC(Music.class),
+ REPLY(Reply.class),
+ FORWARD(Forward.class),
+ NODE(Node.class),
+ XML(XMLMessage.class),
+ JSON(CustomJSONMessage.class);
+ public final Class extends JsonMessagePart> clazz;
+ PartType(Class extends JsonMessagePart> clazz){
+ this.clazz = clazz;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/RPS.java b/src/main/java/cn/wzpmc/api/message/json/parts/RPS.java
new file mode 100644
index 0000000..2377c80
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/RPS.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 拳魔法表情
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:17
+ */
+@Data
+@NoArgsConstructor
+public class RPS implements JsonMessagePart {
+ @Override
+ public PartType getPartType() {
+ return PartType.RPS;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of();
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Reply.java b/src/main/java/cn/wzpmc/api/message/json/parts/Reply.java
new file mode 100644
index 0000000..b8d65bc
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Reply.java
@@ -0,0 +1,31 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 回复
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:33
+ */
+@Data
+@NoArgsConstructor
+public class Reply implements JsonMessagePart {
+ /**
+ * 回复时引用的消息 ID
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private Long id;
+ @Override
+ public PartType getPartType() {
+ return PartType.REPLY;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("id", id);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Shake.java b/src/main/java/cn/wzpmc/api/message/json/parts/Shake.java
new file mode 100644
index 0000000..9c354a1
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Shake.java
@@ -0,0 +1,27 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 窗口抖动(戳一戳)
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:18
+ */
+@Data
+@NoArgsConstructor
+public class Shake implements JsonMessagePart {
+
+ @Override
+ public PartType getPartType() {
+ return PartType.SHAKE;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of();
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/Video.java b/src/main/java/cn/wzpmc/api/message/json/parts/Video.java
new file mode 100644
index 0000000..8294452
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/Video.java
@@ -0,0 +1,53 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.net.URL;
+
+/**
+ * 短视频
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:16
+ */
+@Data
+@NoArgsConstructor
+public class Video implements JsonMessagePart {
+ /**
+ * 视频文件名
+ * @since 2024/8/2 下午11:49 v0.0.3-dev
+ */
+ private String file;
+ /**
+ * 视频 URL
+ * @since 2024/8/2 下午11:49 v0.0.3-dev
+ */
+ private URL url;
+ /**
+ * 只在通过网络 URL 发送时有效,表示是否使用已缓存的文件,默认 true
+ * @since 2024/8/2 下午11:49 v0.0.3-dev
+ */
+ private Boolean cache = true;
+ /**
+ * 只在通过网络 URL 发送时有效,表示是否通过代理下载文件(需通过环境变量或配置文件配置代理),默认 true
+ * @since 2024/8/2 下午11:49 v0.0.3-dev
+ */
+ private Boolean proxy = true;
+ /**
+ * 只在通过网络 URL 发送时有效,单位秒,表示下载网络文件的超时时间 ,默认不超时
+ * @since 2024/8/2 下午11:49 v0.0.3-dev
+ */
+ private Float timeout = null;
+ @Override
+ public PartType getPartType() {
+ return PartType.VIDEO;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return null;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/XMLMessage.java b/src/main/java/cn/wzpmc/api/message/json/parts/XMLMessage.java
new file mode 100644
index 0000000..69e81eb
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/XMLMessage.java
@@ -0,0 +1,32 @@
+package cn.wzpmc.api.message.json.parts;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * XML消息
+ * @author MoYiJiangNan
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:40
+ */
+@Data
+@NoArgsConstructor
+public class XMLMessage implements JsonMessagePart {
+ /**
+ * XML 内容
+ * @since 2024/8/3 下午6:11 v0.0.3-dev
+ */
+ private String data;
+
+ @Override
+ public PartType getPartType() {
+ return PartType.XML;
+ }
+
+ public JSONObject getData() {
+ return new JSONObject()
+ .fluentPut("data", data);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/contact/Contact.java b/src/main/java/cn/wzpmc/api/message/json/parts/contact/Contact.java
new file mode 100644
index 0000000..aeb5f6f
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/contact/Contact.java
@@ -0,0 +1,37 @@
+package cn.wzpmc.api.message.json.parts.contact;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 推荐好友/群
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:21
+ */
+@Data
+@NoArgsConstructor
+public class Contact implements JsonMessagePart {
+ /**
+ * 推荐类型
+ * @since 2024/8/3 下午5:57 v0.0.3-dev
+ */
+ private ContactType type;
+ /**
+ * 被推荐人的 QQ 号
+ * @since 2024/8/3 下午5:57 v0.0.3-dev
+ */
+ private Long id;
+ @Override
+ public PartType getPartType() {
+ return PartType.CONTACT;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("type", this.type.name().toLowerCase(), "id", this.id);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java b/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java
new file mode 100644
index 0000000..8557ad9
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/contact/ContactType.java
@@ -0,0 +1,20 @@
+package cn.wzpmc.api.message.json.parts.contact;
+
+/**
+ * 推荐类型
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:34
+ */
+public enum ContactType {
+ /**
+ * 推荐qq
+ * @since 2024/8/2 下午11:36 v0.0.3-dev
+ */
+ QQ,
+ /**
+ * 推荐群
+ * @since 2024/8/2 下午11:36 v0.0.3-dev
+ */
+ GROUP;
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/music/Music.java b/src/main/java/cn/wzpmc/api/message/json/parts/music/Music.java
new file mode 100644
index 0000000..fc7c344
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/music/Music.java
@@ -0,0 +1,32 @@
+package cn.wzpmc.api.message.json.parts.music;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 音乐分享
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:24
+ */
+@Data
+@NoArgsConstructor
+public abstract class Music implements JsonMessagePart {
+ /**
+ * 音乐类型
+ * @since 2024/8/3 下午6:07 v0.0.3-dev
+ */
+ protected MusicType musicType;
+ @Override
+ public PartType getPartType() {
+ return PartType.MUSIC;
+ }
+
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("type", this.musicType.name);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicAppShare.java b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicAppShare.java
new file mode 100644
index 0000000..83bbbb7
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicAppShare.java
@@ -0,0 +1,27 @@
+package cn.wzpmc.api.message.json.parts.music;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 音乐App分享
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:28
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+public class MusicAppShare extends Music {
+ /**
+ * 歌曲 ID
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private Long id;
+ @Override
+ public JSONObject getData() {
+ return super.getData().fluentPut("id", this.id);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicCustomShare.java b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicCustomShare.java
new file mode 100644
index 0000000..da24c5c
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicCustomShare.java
@@ -0,0 +1,52 @@
+package cn.wzpmc.api.message.json.parts.music;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 音乐自定义分享
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:30
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+public class MusicCustomShare extends Music {
+ /**
+ * 点击后跳转目标 URL
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private String url;
+ /**
+ * 音乐 URL
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private String audio;
+ /**
+ * 标题
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private String title;
+ /**
+ * 发送时可选,内容描述
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private String content = "";
+ /**
+ * 发送时可选,图片 URL
+ * @since 2024/8/3 下午6:08 v0.0.3-dev
+ */
+ private String image = "";
+ @Override
+ public JSONObject getData() {
+ return super.getData()
+ .fluentPut("url", this.url)
+ .fluentPut("audio", this.audio)
+ .fluentPut("title", this.title)
+ .fluentPut("content", this.content)
+ .fluentPut("image", this.image);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicType.java b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicType.java
new file mode 100644
index 0000000..f4ef080
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/music/MusicType.java
@@ -0,0 +1,36 @@
+package cn.wzpmc.api.message.json.parts.music;
+
+/**
+ * 音乐类型
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:25
+ */
+public enum MusicType {
+ /**
+ * qq音乐
+ * @since 2024/8/2 下午11:25 v0.0.3-dev
+ */
+ QQ("qq", MusicAppShare.class),
+ /**
+ * 网易云音乐
+ * @since 2024/8/2 下午11:26 v0.0.3-dev
+ */
+ NETEASE("163", MusicAppShare.class),
+ /**
+ * 虾米音乐
+ * @since 2024/8/2 下午11:27 v0.0.3-dev
+ */
+ XM("xm", MusicAppShare.class),
+ /**
+ * 自定义
+ * @since 2024/8/2 下午11:30 v0.0.3-dev
+ */
+ CUSTOM("custom", MusicCustomShare.class);
+ public final String name;
+ public final Class extends Music> clazz;
+ MusicType(String name, Class extends Music> clazz){
+ this.name = name;
+ this.clazz = clazz;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/node/CustomNode.java b/src/main/java/cn/wzpmc/api/message/json/parts/node/CustomNode.java
new file mode 100644
index 0000000..b7f1478
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/node/CustomNode.java
@@ -0,0 +1,40 @@
+package cn.wzpmc.api.message.json.parts.node;
+
+import cn.wzpmc.api.message.MessageComponent;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.annotation.JSONField;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合并转发自定义节点
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:42
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+public class CustomNode extends Node {
+ /**
+ * 发送者 QQ 号
+ * @since 2024/8/3 下午6:10 v0.0.3-dev
+ */
+ @JSONField(name = "user_id")
+ private Long userId;
+ /**
+ * 发送者昵称
+ * @since 2024/8/3 下午6:11 v0.0.3-dev
+ */
+ private String nickname;
+ /**
+ * 消息内容
+ * @since 2024/8/3 下午6:11 v0.0.3-dev
+ */
+ private MessageComponent content;
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("user_id", userId, "nickname", nickname, "content", content);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/node/Node.java b/src/main/java/cn/wzpmc/api/message/json/parts/node/Node.java
new file mode 100644
index 0000000..4ebe010
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/node/Node.java
@@ -0,0 +1,19 @@
+package cn.wzpmc.api.message.json.parts.node;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合并转发节点
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:39
+ */
+@NoArgsConstructor
+public abstract class Node implements JsonMessagePart {
+ @Override
+ public PartType getPartType() {
+ return PartType.NODE;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/node/SingleNode.java b/src/main/java/cn/wzpmc/api/message/json/parts/node/SingleNode.java
new file mode 100644
index 0000000..0fcd90b
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/node/SingleNode.java
@@ -0,0 +1,27 @@
+package cn.wzpmc.api.message.json.parts.node;
+
+import com.alibaba.fastjson2.JSONObject;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合并转发节点
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:41
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@NoArgsConstructor
+public class SingleNode extends Node{
+ /**
+ * 转发的消息 ID
+ * @since 2024/8/3 下午6:10 v0.0.3-dev
+ */
+ private Long id;
+ @Override
+ public JSONObject getData() {
+ return JSONObject.of("id", this.id);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/poke/Poke.java b/src/main/java/cn/wzpmc/api/message/json/parts/poke/Poke.java
new file mode 100644
index 0000000..687893b
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/poke/Poke.java
@@ -0,0 +1,33 @@
+package cn.wzpmc.api.message.json.parts.poke;
+
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import com.alibaba.fastjson2.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 戳一戳
+ * @author MoYiJiangNan
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:28
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Poke implements JsonMessagePart {
+ private PokeType pokeType;
+
+ @Override
+ public PartType getPartType() {
+ return PartType.POKE;
+ }
+
+ public JSONObject getData() {
+ return new JSONObject()
+ .fluentPut("type", this.pokeType.type)
+ .fluentPut("id", this.pokeType.id)
+ .fluentPut("name", this.pokeType.name);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/api/message/json/parts/poke/PokeType.java b/src/main/java/cn/wzpmc/api/message/json/parts/poke/PokeType.java
new file mode 100644
index 0000000..1c291f0
--- /dev/null
+++ b/src/main/java/cn/wzpmc/api/message/json/parts/poke/PokeType.java
@@ -0,0 +1,46 @@
+package cn.wzpmc.api.message.json.parts.poke;
+
+/**
+ * 戳一戳类型
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午11:51
+ */
+public enum PokeType {
+ CHUO_YI_CHUO("戳一戳", 1, -1),
+ SHOW_LOVE("比心", 2, -1),
+ LIKE("点赞", 2, -1),
+ HEART_BROKEN("心碎", 4, -1),
+ SIX_SIX_SIX("666", 5, -1),
+ FANG_DA_ZHAO("放大招", 6, -1),
+ BAO_BEI_QOI("宝贝球", 126, 2011),
+ MEI_GUI_HUA("玫瑰花", 126, 2007),
+ ZHAO_HUAN_SHU("召唤术", 126, 2006),
+ RANG_NI_PI("让你皮", 126, 2009),
+ JIE_YIN("结印", 126, 2005),
+ SHOU_LEI("手雷", 126, 2004),
+ GOU_YIN("勾引", 126, 2003),
+ ZHUA_YI_XIA("抓一下", 126, 2001),
+ SUI_PIN("碎屏", 126, 2002),
+ QIAO_MEN("敲门", 126, 2002);
+ /**
+ * 戳一戳名称
+ * @since 2024/8/3 下午6:18 v0.0.3-dev
+ */
+ public final String name;
+ /**
+ * 戳一戳类型
+ * @since 2024/8/3 下午6:18 v0.0.3-dev
+ */
+ public final Integer type;
+ /**
+ * 戳一戳ID
+ * @since 2024/8/3 下午6:18 v0.0.3-dev
+ */
+ public final Integer id;
+ PokeType(String name, Integer type, Integer id){
+ this.name = name;
+ this.type = type;
+ this.id = id;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/network/PacketHandler.java b/src/main/java/cn/wzpmc/network/PacketHandler.java
index ed5869a..cd4b525 100644
--- a/src/main/java/cn/wzpmc/network/PacketHandler.java
+++ b/src/main/java/cn/wzpmc/network/PacketHandler.java
@@ -1,13 +1,6 @@
package cn.wzpmc.network;
import cn.wzpmc.api.events.Event;
-import cn.wzpmc.api.events.message.MessageEvent;
-import cn.wzpmc.api.events.meta.MetaEvent;
-import cn.wzpmc.api.events.notice.NoticeEvent;
-import cn.wzpmc.api.events.notice.NoticeType;
-import cn.wzpmc.api.events.notice.notify.NotifyEvent;
-import cn.wzpmc.api.events.request.RequestEvent;
-import cn.wzpmc.api.events.request.RequestEventType;
import com.alibaba.fastjson2.JSON;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
@@ -32,31 +25,6 @@ public class PacketHandler extends SimpleChannelInboundHandler eventClass = switch (event.getPostType()) {
- case NOTICE -> {
- NoticeEvent noticeEvent = JSON.parseObject(text, NoticeEvent.class);
- NoticeType noticeType = noticeEvent.getNoticeType();
- if (NoticeType.NOTIFY.equals(noticeType)) {
- NotifyEvent notifyEvent = JSON.parseObject(text, NotifyEvent.class);
- yield notifyEvent.getSubType().clazz;
- }
- yield noticeType.clazz;
- }
- case MESSAGE -> {
- MessageEvent, ?> messageEvent = JSON.parseObject(text, MessageEvent.class);
- yield messageEvent.getMessageType().clazz;
- }
- case REQUEST -> {
- RequestEvent requestEvent = JSON.parseObject(text, RequestEvent.class);
- RequestEventType requestType = requestEvent.getRequestType();
- yield requestType.clazz;
- }
- case META_EVENT -> {
- MetaEvent metaEvent = JSON.parseObject(text, MetaEvent.class);
- yield metaEvent.getMetaEventType().clazz;
- }
- };
- Event event1 = JSON.parseObject(text, eventClass);
- System.out.println(event1);
+ System.out.println(event);
}
}
diff --git a/src/main/java/cn/wzpmc/plugins/CommandManager.java b/src/main/java/cn/wzpmc/plugins/CommandManager.java
index ced14cc..4d6f45c 100644
--- a/src/main/java/cn/wzpmc/plugins/CommandManager.java
+++ b/src/main/java/cn/wzpmc/plugins/CommandManager.java
@@ -27,6 +27,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
/**
* 指令管理器实现类
@@ -116,7 +117,7 @@ public class CommandManager implements ICommandManager, Completer, Highlighter {
}
}
Suggestions suggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(rawCommandLine, sender), cursor).get();
- result.addAll(suggestions.getList().stream().map(Suggestion::getText).toList());
+ result.addAll(suggestions.getList().stream().map(Suggestion::getText).collect(Collectors.toList()));
return result;
}
@@ -124,7 +125,7 @@ public class CommandManager implements ICommandManager, Completer, Highlighter {
public void complete(LineReader lineReader, ParsedLine parsedLine, List list) {
String line = parsedLine.line();
int cursor = parsedLine.cursor();
- list.addAll(this.tabComplete(this.bot, line, cursor).stream().map(Candidate::new).toList());
+ list.addAll(this.tabComplete(this.bot, line, cursor).stream().map(Candidate::new).collect(Collectors.toList()));
}
@Override
diff --git a/src/main/java/cn/wzpmc/utils/JsonUtils.java b/src/main/java/cn/wzpmc/utils/JsonUtils.java
new file mode 100644
index 0000000..c3d3e79
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/JsonUtils.java
@@ -0,0 +1,38 @@
+package cn.wzpmc.utils;
+
+import cn.wzpmc.api.events.Event;
+import cn.wzpmc.api.events.message.MessageEvent;
+import cn.wzpmc.api.events.meta.MetaEvent;
+import cn.wzpmc.api.events.notice.NoticeEvent;
+import cn.wzpmc.api.events.notice.notify.NotifyEvent;
+import cn.wzpmc.api.events.request.RequestEvent;
+import cn.wzpmc.api.message.StringMessage;
+import cn.wzpmc.api.message.json.JsonMessage;
+import cn.wzpmc.utils.json.event.*;
+import cn.wzpmc.utils.json.message.JsonMessageReader;
+import cn.wzpmc.utils.json.message.JsonMessageWriter;
+import cn.wzpmc.utils.json.message.StringMessageReader;
+import com.alibaba.fastjson2.JSON;
+
+/**
+ * JSON相关工具类
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午2:04
+ */
+public class JsonUtils {
+ public static void initWriter() {
+ JSON.register(JsonMessage.class, new JsonMessageWriter());
+ }
+ public static void initReader() {
+ JSON.register(MessageEvent.class, new MessageEventReader());
+ JSON.register(MetaEvent.class, new MetaEventReader());
+ JSON.register(NotifyEvent.class, new NotifyNoticeEventReader());
+ JSON.register(NoticeEvent.class, new NoticeEventReader());
+ JSON.register(RequestEvent.class, new RequestEventReader());
+ JSON.register(Event.class, new EventReader());
+ JSON.register(JsonMessage.class, new JsonMessageReader());
+ JSON.register(StringMessage.class, new StringMessageReader());
+ }
+
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/EventReader.java b/src/main/java/cn/wzpmc/utils/json/event/EventReader.java
new file mode 100644
index 0000000..7958705
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/EventReader.java
@@ -0,0 +1,28 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.Event;
+import cn.wzpmc.api.events.EventPostType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * event类型JSON反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午2:07
+ */
+public class EventReader implements ObjectReader {
+ @Override
+ public Event readObject(JSONReader jsonReader, Type type, Object o, long l) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ EventPostType postType = EventPostType.valueOf(jsonObject.getString("post_type").toUpperCase());
+ jsonReader.reset(mark);
+ Event event = jsonReader.read(postType.clazz);
+ jsonReader.close();
+ return event;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/MessageEventReader.java b/src/main/java/cn/wzpmc/utils/json/event/MessageEventReader.java
new file mode 100644
index 0000000..a130af3
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/MessageEventReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.message.MessageEvent;
+import cn.wzpmc.api.events.message.MessageType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * 消息事件反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午8:56
+ */
+public class MessageEventReader implements ObjectReader> {
+ @Override
+ public MessageEvent, ?> readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ MessageType messageType = MessageType.valueOf(jsonObject.getString("message_type").toUpperCase());
+ jsonReader.reset(mark);
+ return jsonReader.read(messageType.clazz);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/MetaEventReader.java b/src/main/java/cn/wzpmc/utils/json/event/MetaEventReader.java
new file mode 100644
index 0000000..bc893fd
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/MetaEventReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.meta.MetaEvent;
+import cn.wzpmc.api.events.meta.MetaEventType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * 元事件反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午8:56
+ */
+public class MetaEventReader implements ObjectReader {
+ @Override
+ public MetaEvent readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ MetaEventType metaEventType = MetaEventType.valueOf(jsonObject.getString("meta_event_type").toUpperCase());
+ jsonReader.reset(mark);
+ return jsonReader.read(metaEventType.clazz);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/NoticeEventReader.java b/src/main/java/cn/wzpmc/utils/json/event/NoticeEventReader.java
new file mode 100644
index 0000000..c7eacae
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/NoticeEventReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.notice.NoticeEvent;
+import cn.wzpmc.api.events.notice.NoticeType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * 提醒类型事件反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午8:48
+ */
+public class NoticeEventReader implements ObjectReader {
+ @Override
+ public NoticeEvent readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ NoticeType noticeType = NoticeType.valueOf(jsonObject.getString("notice_type").toUpperCase());
+ jsonReader.reset(mark);
+ return jsonReader.read(noticeType.clazz);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/NotifyNoticeEventReader.java b/src/main/java/cn/wzpmc/utils/json/event/NotifyNoticeEventReader.java
new file mode 100644
index 0000000..7983ea4
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/NotifyNoticeEventReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.notice.notify.NotifyEvent;
+import cn.wzpmc.api.events.notice.notify.NotifySubType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * 群提醒事件反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午8:53
+ */
+public class NotifyNoticeEventReader implements ObjectReader {
+ @Override
+ public NotifyEvent readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ NotifySubType subType = NotifySubType.valueOf(jsonObject.getString("sub_type").toUpperCase());
+ jsonReader.reset(mark);
+ return jsonReader.read(subType.clazz);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/event/RequestEventReader.java b/src/main/java/cn/wzpmc/utils/json/event/RequestEventReader.java
new file mode 100644
index 0000000..91aec05
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/event/RequestEventReader.java
@@ -0,0 +1,26 @@
+package cn.wzpmc.utils.json.event;
+
+import cn.wzpmc.api.events.request.RequestEvent;
+import cn.wzpmc.api.events.request.RequestEventType;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * 请求事件反序列化
+ * @author wzp
+ * @version 0.0.3-dev
+ * @since 2024/8/2 下午8:56
+ */
+public class RequestEventReader implements ObjectReader {
+ @Override
+ public RequestEvent readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONReader.SavePoint mark = jsonReader.mark();
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ RequestEventType requestType = RequestEventType.valueOf(jsonObject.getString("request_type").toUpperCase());
+ jsonReader.reset(mark);
+ return jsonReader.read(requestType.clazz);
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/message/JsonMessageReader.java b/src/main/java/cn/wzpmc/utils/json/message/JsonMessageReader.java
new file mode 100644
index 0000000..a29d46d
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/message/JsonMessageReader.java
@@ -0,0 +1,85 @@
+package cn.wzpmc.utils.json.message;
+
+import cn.wzpmc.api.message.json.JsonMessage;
+import cn.wzpmc.api.message.json.JsonMessagePart;
+import cn.wzpmc.api.message.json.parts.PartType;
+import cn.wzpmc.api.message.json.parts.music.MusicType;
+import cn.wzpmc.api.message.json.parts.node.CustomNode;
+import cn.wzpmc.api.message.json.parts.node.SingleNode;
+import cn.wzpmc.api.message.json.parts.poke.Poke;
+import cn.wzpmc.api.message.json.parts.poke.PokeType;
+import com.alibaba.fastjson2.JSONArray;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.annotation.JSONField;
+import com.alibaba.fastjson2.reader.ObjectReader;
+import lombok.SneakyThrows;
+import lombok.extern.log4j.Log4j2;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * json消息解析器
+ * @author wzp
+ * @since 2024/8/3 下午6:25
+ * @version 0.0.3-dev
+ */
+@Log4j2
+public class JsonMessageReader implements ObjectReader {
+ @SneakyThrows
+ @Override
+ public JsonMessage readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ JSONArray objects = jsonReader.readJSONArray();
+ JsonMessage message = new JsonMessage();
+ List messageParts = message.getMessageParts();
+ messageFor: for (int i = 0; i < objects.size(); i++) {
+ JSONObject jsonObject = objects.getJSONObject(i);
+ PartType type = jsonObject.getObject("type", PartType.class);
+ Class extends JsonMessagePart> clazz = type.clazz;
+ JSONObject dataObject = jsonObject.getJSONObject("data");
+ if (type.equals(PartType.POKE)){
+ Integer pokeType = dataObject.getInteger("type");
+ Integer pokeId = dataObject.getInteger("id");
+ for (PokeType value : PokeType.values()) {
+ if (value.type.equals(pokeType) && value.id.equals(pokeId)){
+ messageParts.add(new Poke(value));
+ continue messageFor;
+ }
+ }
+ log.warn("无法识别的戳一戳类型:type: {}, id: {}", pokeType, pokeId);
+ messageParts.add(new Poke());
+ }
+ if (type.equals(PartType.NODE)){
+ if (jsonObject.containsKey("content")){
+ clazz = CustomNode.class;
+ }else{
+ clazz = SingleNode.class;
+ }
+ }
+ if (type.equals(PartType.MUSIC)){
+ MusicType musicType = dataObject.getObject("type", MusicType.class);
+ dataObject.put("musicType", musicType);
+ clazz = musicType.clazz;
+ }
+ Constructor extends JsonMessagePart> declaredConstructor = clazz.getDeclaredConstructor();
+ JsonMessagePart resultPart = declaredConstructor.newInstance();
+ for (Field declaredField : clazz.getDeclaredFields()) {
+ JSONField annotation = declaredField.getAnnotation(JSONField.class);
+ String name = Objects.isNull(annotation) ? declaredField.getName() : annotation.name();
+ if (!dataObject.containsKey(name)) {
+ continue;
+ }
+ declaredField.setAccessible(true);
+ Class> thisFieldClass = declaredField.getType();
+ Object value = dataObject.getObject(name, thisFieldClass);
+ declaredField.set(resultPart, value);
+ }
+ messageParts.add(resultPart);
+ }
+ return message;
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/message/JsonMessageWriter.java b/src/main/java/cn/wzpmc/utils/json/message/JsonMessageWriter.java
new file mode 100644
index 0000000..741d775
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/message/JsonMessageWriter.java
@@ -0,0 +1,21 @@
+package cn.wzpmc.utils.json.message;
+
+import cn.wzpmc.api.message.json.JsonMessage;
+import com.alibaba.fastjson2.JSONWriter;
+import com.alibaba.fastjson2.writer.ObjectWriter;
+
+import java.lang.reflect.Type;
+
+/**
+ * JSON格式消息反序列化
+ * @author wzp
+ * @since 2024/8/3 下午6:28
+ * @version 0.0.3-dev */
+public class JsonMessageWriter implements ObjectWriter {
+ @Override
+ public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
+ if (object instanceof JsonMessage) {
+ jsonWriter.write(((JsonMessage) object).getMessageParts());
+ }
+ }
+}
diff --git a/src/main/java/cn/wzpmc/utils/json/message/StringMessageReader.java b/src/main/java/cn/wzpmc/utils/json/message/StringMessageReader.java
new file mode 100644
index 0000000..60eaa63
--- /dev/null
+++ b/src/main/java/cn/wzpmc/utils/json/message/StringMessageReader.java
@@ -0,0 +1,25 @@
+package cn.wzpmc.utils.json.message;
+
+import cn.wzpmc.api.message.StringMessage;
+import com.alibaba.fastjson2.JSONObject;
+import com.alibaba.fastjson2.JSONReader;
+import com.alibaba.fastjson2.reader.ObjectReader;
+
+import java.lang.reflect.Type;
+
+/**
+ * @author wzp
+ * @since 2024/8/3 下午8:38
+ * @version 0.0.3-dev
+ */
+public class StringMessageReader implements ObjectReader {
+ @Override
+ public StringMessage readObject(JSONReader jsonReader, Type fieldType, Object fieldName, long features) {
+ if (jsonReader.isObject()){
+ JSONObject jsonObject = jsonReader.readJSONObject();
+ return new StringMessage(jsonObject.getJSONObject("data").getString("text"));
+ }
+ String s = jsonReader.readString();
+ return new StringMessage(s);
+ }
+}