mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-19 19:44:41 +08:00
Enhanced Message
This commit is contained in:
parent
95b0d3b907
commit
6da2bd2f31
@ -9,10 +9,6 @@
|
|||||||
|
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<properties>
|
|
||||||
<kotlin.version>1.3.41</kotlin.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>net.mamoe</groupId>
|
<groupId>net.mamoe</groupId>
|
||||||
<artifactId>mirai</artifactId>
|
<artifactId>mirai</artifactId>
|
||||||
@ -21,7 +17,6 @@
|
|||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-coroutines-core -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlinx</groupId>
|
<groupId>org.jetbrains.kotlinx</groupId>
|
||||||
<artifactId>kotlinx-coroutines-core</artifactId>
|
<artifactId>kotlinx-coroutines-core</artifactId>
|
||||||
@ -31,42 +26,36 @@
|
|||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>net.java.dev.jna</groupId>
|
<groupId>net.java.dev.jna</groupId>
|
||||||
<artifactId>jna</artifactId>
|
<artifactId>jna</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-stdlib</artifactId>
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.logging.log4j</groupId>
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
<artifactId>log4j-core</artifactId>
|
<artifactId>log4j-core</artifactId>
|
||||||
<version>2.12.1</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.yaml</groupId>
|
<groupId>org.yaml</groupId>
|
||||||
<artifactId>snakeyaml</artifactId>
|
<artifactId>snakeyaml</artifactId>
|
||||||
<version>1.18</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.yaml</groupId>
|
|
||||||
<artifactId>snakeyaml</artifactId>
|
|
||||||
<version>1.18</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-reflect</artifactId>
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
<version>1.3.41</version>
|
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>/src/main/resources</directory>
|
<directory>/src/main/resources</directory>
|
||||||
@ -94,63 +83,16 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4.3</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<shadedArtifactAttached>true</shadedArtifactAttached>
|
|
||||||
<shadedClassifierName>shaded</shadedClassifierName>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
<artifactId>kotlin-maven-plugin</artifactId>
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compile</id>
|
|
||||||
<phase>process-sources</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-compile</id>
|
|
||||||
<phase>test-compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test-compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<configuration>
|
|
||||||
<jvmTarget>1.8</jvmTarget>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compile</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>testCompile</id>
|
|
||||||
<phase>test-compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>testCompile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
@ -2,6 +2,7 @@ package net.mamoe.mirai.contact
|
|||||||
|
|
||||||
import net.mamoe.mirai.Robot
|
import net.mamoe.mirai.Robot
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
import net.mamoe.mirai.message.defaults.PlainText
|
import net.mamoe.mirai.message.defaults.PlainText
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +16,14 @@ abstract class Contact(val robot: Robot, val number: Long) {
|
|||||||
/**
|
/**
|
||||||
* Async
|
* Async
|
||||||
*/
|
*/
|
||||||
abstract fun sendMessage(message: Message)
|
abstract fun sendMessage(message: MessageChain)
|
||||||
|
|
||||||
|
fun sendMessage(message: Message) {
|
||||||
|
if (message is MessageChain) {
|
||||||
|
return sendMessage(message)
|
||||||
|
}
|
||||||
|
return sendMessage(message.toChain())
|
||||||
|
}
|
||||||
|
|
||||||
fun sendMessage(message: String) {
|
fun sendMessage(message: String) {
|
||||||
this.sendMessage(PlainText(message))
|
this.sendMessage(PlainText(message))
|
||||||
|
@ -1,15 +1,26 @@
|
|||||||
package net.mamoe.mirai.contact
|
package net.mamoe.mirai.contact
|
||||||
|
|
||||||
import net.mamoe.mirai.Robot
|
import net.mamoe.mirai.Robot
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.contact.Group.Companion.groupNumberToId
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
import net.mamoe.mirai.utils.ContactList
|
import net.mamoe.mirai.utils.ContactList
|
||||||
import java.io.Closeable
|
import java.io.Closeable
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群
|
||||||
|
*
|
||||||
|
* Java 获取 groupNumber: `group.getNumber()`
|
||||||
|
* Java 获取所属 robot: `group.getRobot()`
|
||||||
|
* Java 获取群成员列表: `group.getMembers()`
|
||||||
|
* Java 获取 groupId: `group.getGroupId()`
|
||||||
|
*
|
||||||
|
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
|
||||||
|
*/
|
||||||
class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
|
class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
|
||||||
val groupId = groupNumberToId(number)
|
val groupId = groupNumberToId(number)
|
||||||
val members = ContactList<QQ>()
|
val members = ContactList<QQ>()
|
||||||
|
|
||||||
override fun sendMessage(message: Message) {
|
override fun sendMessage(message: MessageChain) {
|
||||||
robot.network.messageHandler.sendGroupMessage(this, message)
|
robot.network.messageHandler.sendGroupMessage(this, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +34,7 @@ class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun groupNumberToId(number: Long): Long {
|
fun groupNumberToId(number: Long): Long {//求你别出错
|
||||||
val left: Long = number.toString().let {
|
val left: Long = number.toString().let {
|
||||||
if (it.length < 6) {
|
if (it.length < 6) {
|
||||||
return@groupNumberToId number
|
return@groupNumberToId number
|
||||||
@ -61,7 +72,7 @@ class Group(robot: Robot, number: Long) : Contact(robot, number), Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun groupIdToNumber(id: Long): Long {
|
fun groupIdToNumber(id: Long): Long {//求你别出错
|
||||||
var left: Long = id.toString().let {
|
var left: Long = id.toString().let {
|
||||||
if (it.length < 6) {
|
if (it.length < 6) {
|
||||||
return@groupIdToNumber id
|
return@groupIdToNumber id
|
||||||
|
@ -3,18 +3,22 @@ package net.mamoe.mirai.contact
|
|||||||
import net.mamoe.mirai.Robot
|
import net.mamoe.mirai.Robot
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.message.Message
|
||||||
import net.mamoe.mirai.message.defaults.At
|
import net.mamoe.mirai.message.defaults.At
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* QQ 账号.
|
* QQ 账号.
|
||||||
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Robot].
|
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Robot].
|
||||||
*
|
*
|
||||||
|
* Java 获取 qq 号: `qq.getNumber()`
|
||||||
|
* Java 获取所属 robot: `qq.getRobot()`
|
||||||
|
*
|
||||||
* A QQ instance helps you to receive message from or send message to.
|
* A QQ instance helps you to receive message from or send message to.
|
||||||
* Notice that, one QQ instance belong to one [Robot], that is, QQ instances from different [Robot] are NOT the same.
|
* Notice that, one QQ instance belong to one [Robot], that is, QQ instances from different [Robot] are NOT the same.
|
||||||
*
|
*
|
||||||
* @author Him188moe
|
* @author Him188moe
|
||||||
*/
|
*/
|
||||||
class QQ(robot: Robot, number: Long) : Contact(robot, number) {
|
class QQ(robot: Robot, number: Long) : Contact(robot, number) {
|
||||||
override fun sendMessage(message: Message) {
|
override fun sendMessage(message: MessageChain) {
|
||||||
robot.network.messageHandler.sendFriendMessage(this, message)
|
robot.network.messageHandler.sendFriendMessage(this, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,19 +12,14 @@ import java.util.Objects;
|
|||||||
*/
|
*/
|
||||||
public final class FriendMessageEvent extends FriendEvent {
|
public final class FriendMessageEvent extends FriendEvent {
|
||||||
private final MessageChain messageChain;
|
private final MessageChain messageChain;
|
||||||
private final String messageString;
|
|
||||||
|
|
||||||
public FriendMessageEvent(@NotNull Robot robot, @NotNull QQ sender, @NotNull MessageChain messageChain) {
|
public FriendMessageEvent(@NotNull Robot robot, @NotNull QQ sender, @NotNull MessageChain messageChain) {
|
||||||
super(robot, sender);
|
super(robot, sender);
|
||||||
this.messageChain = Objects.requireNonNull(messageChain);
|
this.messageChain = Objects.requireNonNull(messageChain);
|
||||||
this.messageString = messageChain.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessageString() {
|
@NotNull
|
||||||
return messageString;
|
public MessageChain message() {
|
||||||
}
|
|
||||||
|
|
||||||
public MessageChain getMessageChain() {
|
|
||||||
return messageChain;
|
return messageChain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
package net.mamoe.mirai.message;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.contact.Contact;
|
|
||||||
import net.mamoe.mirai.contact.QQ;
|
|
||||||
import net.mamoe.mirai.message.defaults.At;
|
|
||||||
import net.mamoe.mirai.message.defaults.Image;
|
|
||||||
import net.mamoe.mirai.message.defaults.MessageChain;
|
|
||||||
import net.mamoe.mirai.message.defaults.PlainText;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 可发送的或从服务器接收的消息.
|
|
||||||
* 采用这样的消息模式是因为 QQ 的消息多元化, 一条消息中可包含 {@linkplain PlainText 纯文本}, {@linkplain Image 图片} 等.
|
|
||||||
*
|
|
||||||
* @author Him188moe
|
|
||||||
* @see Contact#sendMessage(Message) 发送这个消息
|
|
||||||
* @see MessageKt 若你使用 kotlin, 请查看针对 kotlin 的优化实现
|
|
||||||
*/
|
|
||||||
public abstract class Message {
|
|
||||||
@Override
|
|
||||||
public abstract String toString();
|
|
||||||
|
|
||||||
public String toDebugString() {
|
|
||||||
return this.getClass().getSimpleName() + String.format("(%s)", this.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 把这个消息连接到另一个消息的头部. 相当于字符串相加
|
|
||||||
* <p>
|
|
||||||
* Connects this Message to the head of another Message.
|
|
||||||
* That is, another message becomes the tail of this message.
|
|
||||||
* This method does similar to {@link String#concat(String)}
|
|
||||||
* <p>
|
|
||||||
* E.g.:
|
|
||||||
* PlainText a = new PlainText("Hello ");
|
|
||||||
* PlainText b = new PlainText("world");
|
|
||||||
* PlainText c = a.concat(b);
|
|
||||||
* <p>
|
|
||||||
* the text of c is "Hello world"
|
|
||||||
*
|
|
||||||
* @param tail tail
|
|
||||||
* @return message connected
|
|
||||||
*/
|
|
||||||
public Message concat(@NotNull Message tail) {
|
|
||||||
return new MessageChain(this, Objects.requireNonNull(tail));
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Message concat(String tail) {
|
|
||||||
return concat(new PlainText(tail));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Message withImage(String imageId) {
|
|
||||||
|
|
||||||
// TODO: 2019/9/1
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message withImage(BufferedImage image) {
|
|
||||||
// TODO: 2019/9/1
|
|
||||||
return this;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message withImage(File image) {
|
|
||||||
// TODO: 2019/9/1
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message withAt(@NotNull QQ target) {
|
|
||||||
this.concat(target.at());
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message withAt(int target) {
|
|
||||||
this.concat(new At(target));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
174
mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
Normal file
174
mirai-core/src/main/java/net/mamoe/mirai/message/Message.kt
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package net.mamoe.mirai.message
|
||||||
|
|
||||||
|
import net.mamoe.mirai.contact.Contact
|
||||||
|
import net.mamoe.mirai.contact.QQ
|
||||||
|
import net.mamoe.mirai.message.defaults.At
|
||||||
|
import net.mamoe.mirai.message.defaults.Image
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
|
import net.mamoe.mirai.message.defaults.PlainText
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 可发送的或从服务器接收的消息.
|
||||||
|
* 采用这样的消息模式是因为 QQ 的消息多元化, 一条消息中可包含 [纯文本][PlainText], [图片][Image] 等.
|
||||||
|
*
|
||||||
|
* 在 Kotlin, 使用 [Message] 与使用 [String] 几乎没有什么用法上的区别.
|
||||||
|
*
|
||||||
|
* @author Him188moe
|
||||||
|
* @see Contact.sendMessage
|
||||||
|
*/
|
||||||
|
abstract class Message {
|
||||||
|
internal abstract val type: Int
|
||||||
|
|
||||||
|
private var toStringCache: String? = null
|
||||||
|
private val cacheLock = object : Any() {}
|
||||||
|
|
||||||
|
internal abstract fun toStringImpl(): String
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到用户层的文本消息. 如:
|
||||||
|
* - [PlainText] 得到 消息内容
|
||||||
|
* - [Image] 得到 "{ID}.png"
|
||||||
|
* - [At] 得到 "[@qq]"
|
||||||
|
*/
|
||||||
|
final override fun toString(): String {
|
||||||
|
synchronized(cacheLock) {
|
||||||
|
if (toStringCache != null) {
|
||||||
|
return toStringCache!!
|
||||||
|
}
|
||||||
|
|
||||||
|
this.toStringCache = toStringImpl()
|
||||||
|
return toStringCache!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun clearToStringCache() {
|
||||||
|
synchronized(cacheLock) {
|
||||||
|
toStringCache = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到类似 "PlainText(内容)", "Image(ID)"
|
||||||
|
*/
|
||||||
|
open fun toObjectString(): String {
|
||||||
|
return this.javaClass.simpleName + String.format("(%s)", this.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为数据包使用的 byte array
|
||||||
|
*/
|
||||||
|
abstract fun toByteArray(): ByteArray
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较两个 Message 的内容是否相等. 如:
|
||||||
|
* - [PlainText] 比较 [PlainText.text]
|
||||||
|
* - [Image] 比较 [Image.imageID]
|
||||||
|
*/
|
||||||
|
abstract infix fun valueEquals(another: Message): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将这个消息的 [toString] 与 [another] 比较
|
||||||
|
*/
|
||||||
|
infix fun valueEquals(another: String): Boolean = this.toString() == another
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把这个消息连接到另一个消息的头部. 相当于字符串相加
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Connects this Message to the head of another Message.
|
||||||
|
* That is, another message becomes the tail of this message.
|
||||||
|
* This method does similar to [String.concat]
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* E.g.:
|
||||||
|
* PlainText a = new PlainText("Hello ");
|
||||||
|
* PlainText b = new PlainText("world");
|
||||||
|
* PlainText c = a.concat(b);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* the text of c is "Hello world"
|
||||||
|
*
|
||||||
|
* @param tail tail
|
||||||
|
* @return message connected
|
||||||
|
*/
|
||||||
|
open fun concat(tail: Message): Message {
|
||||||
|
return MessageChain(this, Objects.requireNonNull(tail))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun concat(tail: String): Message {
|
||||||
|
return concat(PlainText(tail))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun withImage(imageId: String): Message {
|
||||||
|
|
||||||
|
// TODO: 2019/9/1
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withImage(image: BufferedImage): Message {
|
||||||
|
// TODO: 2019/9/1
|
||||||
|
return this
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withImage(image: File): Message {
|
||||||
|
// TODO: 2019/9/1
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withAt(target: QQ): Message {
|
||||||
|
this.concat(target.at())
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withAt(target: Int): Message {
|
||||||
|
this.concat(At(target.toLong()))
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun toChain(): MessageChain {
|
||||||
|
return MessageChain(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For Kotlin */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现使用 '+' 操作符连接 [Message] 与 [Message]
|
||||||
|
*/
|
||||||
|
infix operator fun plus(another: Message): Message = this.concat(another)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现使用 '+' 操作符连接 [Message] 与 [String]
|
||||||
|
*/
|
||||||
|
infix operator fun plus(another: String): Message = this.concat(another)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实现使用 '+' 操作符连接 [Message] 与 [Number]
|
||||||
|
*/
|
||||||
|
infix operator fun plus(another: Number): Message = this.concat(another.toString())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接 [String] 与 [Message]
|
||||||
|
*/
|
||||||
|
fun String.concat(another: Message): Message = PlainText(this).concat(another)
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
return javaClass.hashCode()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is Message) return false
|
||||||
|
|
||||||
|
if (type != other.type) return false
|
||||||
|
|
||||||
|
return this.toString() == other.toString()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package net.mamoe.mirai.message
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Message] 在数据包中的 id([UByte])
|
||||||
|
*
|
||||||
|
* Java 调用方式:
|
||||||
|
* MessageId.at
|
||||||
|
*
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
object MessageId {
|
||||||
|
|
||||||
|
const val AT: Int = 0x00//todo 不知道是多少
|
||||||
|
|
||||||
|
const val FACE: Int = 0x00//todo 不知道是多少
|
||||||
|
|
||||||
|
const val TEXT: Int = 0x01
|
||||||
|
|
||||||
|
const val IMAGE: Int = 0x06
|
||||||
|
|
||||||
|
const val CHAIN: Int = 0xff//仅用于 equals. Packet 中不存在 Chain 概念
|
||||||
|
}
|
@ -1,20 +0,0 @@
|
|||||||
@file:JvmName("MessageKt")
|
|
||||||
|
|
||||||
package net.mamoe.mirai.message
|
|
||||||
|
|
||||||
import net.mamoe.mirai.message.defaults.PlainText
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现使用 '+' 操作符连接 [Message] 与 [Message]
|
|
||||||
*/
|
|
||||||
infix operator fun Message.plus(another: Message): Message = this.concat(another)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 实现使用 '+' 操作符连接 [Message] 与 [String]
|
|
||||||
*/
|
|
||||||
infix operator fun Message.plus(another: String): Message = this.concat(another)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 连接 [String] 与 [Message]
|
|
||||||
*/
|
|
||||||
infix fun String.concat(another: Message): Message = PlainText(this).concat(another)
|
|
@ -1,34 +0,0 @@
|
|||||||
package net.mamoe.mirai.message.defaults;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.contact.QQ;
|
|
||||||
import net.mamoe.mirai.message.Message;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* At 一个人的消息.
|
|
||||||
*
|
|
||||||
* @author Him188moe
|
|
||||||
*/
|
|
||||||
public final class At extends Message {
|
|
||||||
private final long target;
|
|
||||||
|
|
||||||
public At(@NotNull QQ target) {
|
|
||||||
this(Objects.requireNonNull(target).getNumber());
|
|
||||||
}
|
|
||||||
|
|
||||||
public At(long target) {
|
|
||||||
this.target = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getTarget() {
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
// TODO: 2019/9/4 At.toString
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package net.mamoe.mirai.message.defaults
|
||||||
|
|
||||||
|
import net.mamoe.mirai.contact.QQ
|
||||||
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.MessageId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* At 一个人
|
||||||
|
*
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
class At(val target: Long) : Message() {
|
||||||
|
override val type: Int = MessageId.AT
|
||||||
|
|
||||||
|
constructor(target: QQ) : this(target.number)
|
||||||
|
|
||||||
|
override fun toStringImpl(): String = "[@$target]"
|
||||||
|
|
||||||
|
override fun toByteArray(): ByteArray {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun valueEquals(another: Message): Boolean {
|
||||||
|
if (another !is At) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return another.target == this.target
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +0,0 @@
|
|||||||
package net.mamoe.mirai.message.defaults;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.message.FaceID;
|
|
||||||
import net.mamoe.mirai.message.Message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QQ 自带表情
|
|
||||||
*
|
|
||||||
* @author Him188moe
|
|
||||||
*/
|
|
||||||
public final class Face extends Message {
|
|
||||||
private final FaceID id;
|
|
||||||
|
|
||||||
public Face(FaceID id) {
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public FaceID getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
if (id == null) {
|
|
||||||
return "[face?]";
|
|
||||||
|
|
||||||
}
|
|
||||||
return String.format("[face%d]", id.getId());
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,33 @@
|
|||||||
|
package net.mamoe.mirai.message.defaults
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.FaceID
|
||||||
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.MessageId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QQ 自带表情
|
||||||
|
*
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
class Face(val id: FaceID?) : Message() {
|
||||||
|
override val type: Int = MessageId.FACE
|
||||||
|
|
||||||
|
override fun toStringImpl(): String {
|
||||||
|
return if (id == null) {
|
||||||
|
"[face?]"
|
||||||
|
|
||||||
|
} else String.format("[face%d]", id.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toByteArray(): ByteArray {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun valueEquals(another: Message): Boolean {
|
||||||
|
if (another !is Face) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.id == another.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,45 +0,0 @@
|
|||||||
package net.mamoe.mirai.message.defaults;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.message.Message;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.URL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Him188moe
|
|
||||||
*/
|
|
||||||
public final class Image extends Message {
|
|
||||||
private String imageID;
|
|
||||||
|
|
||||||
public Image(InputStream inputStream) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Image(BufferedImage image) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Image(File imageFile) throws FileNotFoundException {
|
|
||||||
this(new FileInputStream(imageFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Image(URL url) throws IOException {
|
|
||||||
this(ImageIO.read(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {xxxxx}.jpg
|
|
||||||
*
|
|
||||||
* @param imageID
|
|
||||||
*/
|
|
||||||
public Image(String imageID) {
|
|
||||||
this.imageID = imageID;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return imageID;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,57 @@
|
|||||||
|
package net.mamoe.mirai.message.defaults
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.MessageId
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io.*
|
||||||
|
import java.net.URL
|
||||||
|
import javax.imageio.ImageIO
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
class Image : Message {
|
||||||
|
override val type: Int = MessageId.IMAGE
|
||||||
|
|
||||||
|
private var imageID: String? = null
|
||||||
|
|
||||||
|
constructor(inputStream: InputStream) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(image: BufferedImage) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(FileNotFoundException::class)
|
||||||
|
constructor(imageFile: File) : this(FileInputStream(imageFile)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
constructor(url: URL) : this(ImageIO.read(url)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {xxxxx}.jpg
|
||||||
|
*
|
||||||
|
* @param imageID
|
||||||
|
*/
|
||||||
|
constructor(imageID: String) {
|
||||||
|
this.imageID = imageID
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toStringImpl(): String {
|
||||||
|
return imageID!!
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toByteArray(): ByteArray {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun valueEquals(another: Message): Boolean {
|
||||||
|
if (another !is Image) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.imageID == another.imageID
|
||||||
|
}
|
||||||
|
}
|
@ -1,61 +0,0 @@
|
|||||||
package net.mamoe.mirai.message.defaults;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.message.Message;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Him188moe
|
|
||||||
*/
|
|
||||||
public final class MessageChain extends Message {
|
|
||||||
private LinkedList<Message> list = new LinkedList<>();
|
|
||||||
|
|
||||||
public MessageChain(@NotNull Message head, @NotNull Message tail) {
|
|
||||||
Objects.requireNonNull(head);
|
|
||||||
Objects.requireNonNull(tail);
|
|
||||||
|
|
||||||
list.add(head);
|
|
||||||
list.add(tail);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageChain(@NotNull Message message) {
|
|
||||||
Objects.requireNonNull(message);
|
|
||||||
list.add(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MessageChain() {
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return An unmodifiable list
|
|
||||||
*/
|
|
||||||
public List<Message> toList() {
|
|
||||||
return List.copyOf(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stream<Message> stream() {
|
|
||||||
return new ArrayList<>(list).stream();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized String toString() {
|
|
||||||
return this.list.stream().map(Message::toString).collect(Collectors.joining(""));
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized String toDebugString() {
|
|
||||||
return String.format("MessageChain(%s)", this.list.stream().map(Message::toDebugString).collect(Collectors.joining(", ")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public synchronized Message concat(@NotNull Message tail) {
|
|
||||||
this.list.add(tail);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,71 @@
|
|||||||
|
package net.mamoe.mirai.message.defaults
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.MessageId
|
||||||
|
import net.mamoe.mirai.utils.lazyEncode
|
||||||
|
import java.util.*
|
||||||
|
import java.util.stream.Collectors
|
||||||
|
import java.util.stream.Stream
|
||||||
|
|
||||||
|
class MessageChain : Message {
|
||||||
|
override val type: Int = MessageId.CHAIN
|
||||||
|
|
||||||
|
internal val list = LinkedList<Message>()
|
||||||
|
|
||||||
|
constructor(head: Message, tail: Message) {
|
||||||
|
Objects.requireNonNull(head)
|
||||||
|
Objects.requireNonNull(tail)
|
||||||
|
|
||||||
|
list.add(head)
|
||||||
|
list.add(tail)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(message: Message) {
|
||||||
|
Objects.requireNonNull(message)
|
||||||
|
list.add(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
|
||||||
|
fun toList(): List<Message> {
|
||||||
|
return list.toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun stream(): Stream<Message> {
|
||||||
|
return ArrayList(list).stream()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun toStringImpl(): String {
|
||||||
|
return this.list.stream().map { it.toString() }.collect(Collectors.joining(""))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun toObjectString(): String {
|
||||||
|
return String.format("MessageChain(%s)", this.list.stream().map { it.toObjectString() }.collect(Collectors.joining(", ")))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
|
override fun concat(tail: Message): Message {
|
||||||
|
this.list.add(tail)
|
||||||
|
clearToStringCache()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toChain(): MessageChain {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toByteArray(): ByteArray = lazyEncode {
|
||||||
|
stream().forEach { message ->
|
||||||
|
it.write(message.toByteArray())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun valueEquals(another: Message): Boolean {
|
||||||
|
if (another !is MessageChain) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.list == another.list
|
||||||
|
}
|
||||||
|
}
|
@ -1,19 +0,0 @@
|
|||||||
package net.mamoe.mirai.message.defaults;
|
|
||||||
|
|
||||||
import net.mamoe.mirai.message.Message;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Him188moe
|
|
||||||
*/
|
|
||||||
public final class PlainText extends Message {
|
|
||||||
private final String text;
|
|
||||||
|
|
||||||
public PlainText(String text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,34 @@
|
|||||||
|
package net.mamoe.mirai.message.defaults
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.MessageId
|
||||||
|
import net.mamoe.mirai.network.packet.writeVarByteArray
|
||||||
|
import net.mamoe.mirai.network.packet.writeVarString
|
||||||
|
import net.mamoe.mirai.utils.lazyEncode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Him188moe
|
||||||
|
*/
|
||||||
|
class PlainText(private val text: String) : Message() {
|
||||||
|
override val type: Int = MessageId.TEXT
|
||||||
|
|
||||||
|
override fun toStringImpl(): String {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toByteArray(): ByteArray = lazyEncode { section ->
|
||||||
|
section.writeByte(this.type)
|
||||||
|
|
||||||
|
section.writeVarByteArray(lazyEncode { child ->
|
||||||
|
child.writeByte(0x01)
|
||||||
|
child.writeVarString(this.text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun valueEquals(another: Message): Boolean {
|
||||||
|
if (another !is PlainText) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return this.text == another.text
|
||||||
|
}
|
||||||
|
}
|
@ -14,8 +14,10 @@ import net.mamoe.mirai.event.events.qq.FriendMessageEvent
|
|||||||
import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
|
import net.mamoe.mirai.event.events.robot.RobotLoginSucceedEvent
|
||||||
import net.mamoe.mirai.event.hookWhile
|
import net.mamoe.mirai.event.hookWhile
|
||||||
import net.mamoe.mirai.message.Message
|
import net.mamoe.mirai.message.Message
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
import net.mamoe.mirai.network.RobotNetworkHandler.*
|
import net.mamoe.mirai.network.RobotNetworkHandler.*
|
||||||
import net.mamoe.mirai.network.packet.*
|
import net.mamoe.mirai.network.packet.*
|
||||||
|
import net.mamoe.mirai.network.packet.action.ClientSendFriendMessagePacket
|
||||||
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
|
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
|
||||||
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
||||||
import net.mamoe.mirai.network.packet.login.*
|
import net.mamoe.mirai.network.packet.login.*
|
||||||
@ -85,16 +87,14 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
|
|
||||||
//private | internal
|
//private | internal
|
||||||
|
|
||||||
internal fun tryLogin(): CompletableFuture<LoginState> = this.tryLogin(200)//登录回复非常快, 没必要等太久.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 仅当 [LoginState] 非 [LoginState.UNKNOWN] 且非 [LoginState.TIMEOUT] 才会调用 [loginHook].
|
* 仅当 [LoginState] 非 [LoginState.UNKNOWN] 且非 [LoginState.TIMEOUT] 才会调用 [loginHook].
|
||||||
* 如果要输入验证码, 那么会以参数 [LoginState.VERIFICATION_CODE] 调用 [loginHandler], 登录完成后再以 [LoginState.SUCCESS] 调用 [loginHandler]
|
* 如果要输入验证码, 那么会以参数 [LoginState.VERIFICATION_CODE] 调用 [loginHandler], 登录完成后再以 [LoginState.SUCCESS] 调用 [loginHandler]
|
||||||
*
|
*
|
||||||
* @param touchingTimeoutMillis 连接每个服务器的 timeout
|
* @param touchingTimeoutMillis 连接每个服务器的 timeout
|
||||||
*/
|
*/
|
||||||
internal fun tryLogin(touchingTimeoutMillis: Long): CompletableFuture<LoginState> {
|
@JvmOverloads
|
||||||
|
internal fun tryLogin(touchingTimeoutMillis: Long = 200): CompletableFuture<LoginState> {
|
||||||
val ipQueue: LinkedList<String> = LinkedList(Protocol.SERVER_IP)
|
val ipQueue: LinkedList<String> = LinkedList(Protocol.SERVER_IP)
|
||||||
val future = CompletableFuture<LoginState>()
|
val future = CompletableFuture<LoginState>()
|
||||||
|
|
||||||
@ -199,10 +199,10 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
return this.loginFuture!!
|
return this.loginFuture!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
/**
|
/**
|
||||||
* Not async
|
* Not async
|
||||||
*/
|
*/
|
||||||
|
@Synchronized
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
internal fun sendPacket(packet: ClientPacket) {
|
internal fun sendPacket(packet: ClientPacket) {
|
||||||
checkNotNull(socket) { "network closed" }
|
checkNotNull(socket) { "network closed" }
|
||||||
@ -329,7 +329,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
this.loginIP = packet.loginIP
|
this.loginIP = packet.loginIP
|
||||||
this.loginTime = packet.loginTime
|
this.loginTime = packet.loginTime
|
||||||
this.token0825 = packet.token0825
|
this.token0825 = packet.token0825
|
||||||
sendPacket(ClientPasswordSubmissionPacket(robot.account.qqNumber, robot.account.password, packet.loginTime, packet.loginIP, this.tgtgtKey!!, packet.token0825))
|
sendPacket(ClientPasswordSubmissionPacket(robot.account.qqNumber, robot.account.password, packet.loginTime, packet.loginIP, this.tgtgtKey, packet.token0825))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
is ServerVerificationCodeCorrectPacket -> {
|
is ServerVerificationCodeCorrectPacket -> {
|
||||||
this.tgtgtKey = getRandomByteArray(16)
|
this.tgtgtKey = getRandomByteArray(16)
|
||||||
this.token00BA = packet.token00BA
|
this.token00BA = packet.token00BA
|
||||||
sendPacket(ClientLoginResendPacket3105(robot.account.qqNumber, robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey!!, this.token0825, this.token00BA))
|
sendPacket(ClientLoginResendPacket3105(robot.account.qqNumber, robot.account.password, this.loginTime, this.loginIP, this.tgtgtKey, this.token0825, this.token00BA))
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServerLoginResponseVerificationCodeInitPacket -> {
|
is ServerLoginResponseVerificationCodeInitPacket -> {
|
||||||
@ -419,7 +419,7 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
|
|
||||||
//登录成功后会收到大量上次的消息, 忽略掉
|
//登录成功后会收到大量上次的消息, 忽略掉
|
||||||
MiraiThreadPool.getInstance().schedule({
|
MiraiThreadPool.getInstance().schedule({
|
||||||
(packetHandlers[MessageHandler::class] as MessageHandler).ignoreMessage = false
|
messageHandler.ignoreMessage = false
|
||||||
}, 2, TimeUnit.SECONDS)
|
}, 2, TimeUnit.SECONDS)
|
||||||
|
|
||||||
this.tlv0105 = packet.tlv0105
|
this.tlv0105 = packet.tlv0105
|
||||||
@ -432,7 +432,6 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
is ServerSKeyResponsePacket -> {
|
is ServerSKeyResponsePacket -> {
|
||||||
val actionHandler = packetHandlers[ActionHandler::class] as ActionHandler
|
|
||||||
actionHandler.sKey = packet.sKey
|
actionHandler.sKey = packet.sKey
|
||||||
actionHandler.cookies = "uin=o" + robot.account.qqNumber + ";skey=" + actionHandler.sKey + ";"
|
actionHandler.cookies = "uin=o" + robot.account.qqNumber + ";skey=" + actionHandler.sKey + ";"
|
||||||
|
|
||||||
@ -496,7 +495,12 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
FriendMessageEvent(robot, robot.contacts.getQQ(packet.qq), packet.message)
|
val friendMessageEvent = FriendMessageEvent(robot, robot.contacts.getQQ(packet.qq), packet.message)
|
||||||
|
friendMessageEvent.broadcast()
|
||||||
|
|
||||||
|
if (friendMessageEvent.message() valueEquals "你好") {
|
||||||
|
friendMessageEvent.qq.sendMessage("你好")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is ServerGroupMessageEventPacket -> {
|
is ServerGroupMessageEventPacket -> {
|
||||||
@ -515,9 +519,8 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendFriendMessage(qq: QQ, message: Message) {
|
fun sendFriendMessage(qq: QQ, message: MessageChain) {
|
||||||
TODO()
|
sendPacket(ClientSendFriendMessagePacket(robot.account.qqNumber, qq.number, sessionKey, message))
|
||||||
//sendPacket(ClientSendFriendMessagePacket(robot.account.qqNumber, qq.number, sessionKey, message))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendGroupMessage(group: Group, message: Message): Unit {
|
fun sendGroupMessage(group: Group, message: Message): Unit {
|
||||||
@ -532,7 +535,11 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
*/
|
*/
|
||||||
inner class ActionHandler : PacketHandler() {
|
inner class ActionHandler : PacketHandler() {
|
||||||
internal lateinit var cookies: String
|
internal lateinit var cookies: String
|
||||||
internal lateinit var sKey: String
|
internal var sKey: String = ""
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
gtk = getGTK(value)
|
||||||
|
}
|
||||||
internal var gtk: Int = 0
|
internal var gtk: Int = 0
|
||||||
|
|
||||||
override fun onPacketReceived(packet: ServerPacket) {
|
override fun onPacketReceived(packet: ServerPacket) {
|
||||||
|
@ -230,7 +230,7 @@ fun DataOutputStream.writeZero(count: Int) {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun DataOutputStream.writeRandom(length: Int) {
|
fun DataOutputStream.writeRandom(length: Int) {
|
||||||
repeat(length) {
|
repeat(length) {
|
||||||
this.writeByte((Math.random() * 255).toInt().toByte().toInt())
|
this.writeByte((Math.random() * 255).toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,4 +244,13 @@ fun DataOutputStream.writeQQ(qq: Long) {
|
|||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun DataOutputStream.writeGroup(groupIdOrGroupNumber: Long) {
|
fun DataOutputStream.writeGroup(groupIdOrGroupNumber: Long) {
|
||||||
this.write(groupIdOrGroupNumber.toUInt().toByteArray())
|
this.write(groupIdOrGroupNumber.toUInt().toByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DataOutputStream.writeVarByteArray(byteArray: ByteArray) {
|
||||||
|
this.writeShort(byteArray.size)
|
||||||
|
this.write(byteArray)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DataOutputStream.writeVarString(str: String) {
|
||||||
|
this.writeVarByteArray(str.toByteArray())
|
||||||
}
|
}
|
@ -199,11 +199,10 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
|||||||
|
|
||||||
val l1 = input.readShortAt(22)
|
val l1 = input.readShortAt(22)
|
||||||
input.goto(93 + l1)
|
input.goto(93 + l1)
|
||||||
val l2 = input.readShort()
|
input.readVarByteArray()//font
|
||||||
input.readNBytes(l2)//font
|
|
||||||
input.skip(2)//2个0x00
|
input.skip(2)//2个0x00
|
||||||
message = input.readSections()
|
message = input.readSections()
|
||||||
println(message.toDebugString())
|
println(message.toObjectString())
|
||||||
|
|
||||||
/*
|
/*
|
||||||
val offset = unknownLength0 + fontLength//57
|
val offset = unknownLength0 + fontLength//57
|
||||||
@ -218,14 +217,14 @@ class ServerFriendMessageEventPacket(input: DataInputStream, packetId: ByteArray
|
|||||||
val sectionLength = this.readShort().toLong()//sectionLength: short
|
val sectionLength = this.readShort().toLong()//sectionLength: short
|
||||||
this.skip(1)//message和face是 0x01, image是0x06
|
this.skip(1)//message和face是 0x01, image是0x06
|
||||||
return when (messageType) {
|
return when (messageType) {
|
||||||
0x01 -> PlainText(readShortVarString())
|
0x01 -> PlainText(readVarString())
|
||||||
0x02 -> {
|
0x02 -> {
|
||||||
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
|
//00 01 AF 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 F0
|
||||||
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
|
//00 01 0C 0B 00 08 00 01 00 04 52 CC F5 D0 FF 00 02 14 4D
|
||||||
|
|
||||||
val id1 = FaceID.ofId(readShortVarNumber().toInt())//可能这个是id, 也可能下面那个
|
val id1 = FaceID.ofId(readVarNumber().toInt())//可能这个是id, 也可能下面那个
|
||||||
this.skip(this.readByte().toLong())
|
this.skip(this.readByte().toLong())
|
||||||
this.readShortVarNumber()//某id?
|
this.readVarNumber()//某id?
|
||||||
return Face(id1)
|
return Face(id1)
|
||||||
}
|
}
|
||||||
0x06 -> {
|
0x06 -> {
|
||||||
|
@ -176,8 +176,12 @@ fun DataInputStream.readIP(): String {
|
|||||||
return buff
|
return buff
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DataInputStream.readShortVarString(): String {
|
fun DataInputStream.readVarString(): String {
|
||||||
return String(this.readNBytes(this.readShort().toInt()))
|
return String(this.readVarByteArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DataInputStream.readVarByteArray(): ByteArray {
|
||||||
|
return this.readNBytes(this.readShort().toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun DataInputStream.readString(length: Int): String {
|
fun DataInputStream.readString(length: Int): String {
|
||||||
@ -206,7 +210,7 @@ fun <N : Number> DataInputStream.readNBytes(length: N): ByteArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun DataInputStream.readShortVarNumber(): Number {
|
fun DataInputStream.readVarNumber(): Number {
|
||||||
return when (this.readShort().toInt()) {
|
return when (this.readShort().toInt()) {
|
||||||
1 -> this.readByte()
|
1 -> this.readByte()
|
||||||
2 -> this.readShort()
|
2 -> this.readShort()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.mamoe.mirai.network.packet.action
|
package net.mamoe.mirai.network.packet.action
|
||||||
|
|
||||||
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
import net.mamoe.mirai.network.Protocol
|
import net.mamoe.mirai.network.Protocol
|
||||||
import net.mamoe.mirai.network.packet.*
|
import net.mamoe.mirai.network.packet.*
|
||||||
import net.mamoe.mirai.utils.lazyEncode
|
import net.mamoe.mirai.utils.lazyEncode
|
||||||
@ -14,7 +15,7 @@ class ClientSendFriendMessagePacket(
|
|||||||
private val robotQQ: Long,
|
private val robotQQ: Long,
|
||||||
private val targetQQ: Long,
|
private val targetQQ: Long,
|
||||||
private val sessionKey: ByteArray,
|
private val sessionKey: ByteArray,
|
||||||
private val message: String
|
private val message: MessageChain
|
||||||
) : ClientPacket() {
|
) : ClientPacket() {
|
||||||
override fun encode() {
|
override fun encode() {
|
||||||
this.writeRandom(2)//part of packet id
|
this.writeRandom(2)//part of packet id
|
||||||
@ -36,24 +37,20 @@ class ClientSendFriendMessagePacket(
|
|||||||
it.writeTime()
|
it.writeTime()
|
||||||
it.writeRandom(4)
|
it.writeRandom(4)
|
||||||
it.writeHex("00 00 00 00 09 00 86")
|
it.writeHex("00 00 00 00 09 00 86")
|
||||||
it.writeHex(Protocol.friendMessageConst1)
|
it.writeHex(Protocol.friendMessageConst1)//... 85 E9 BB 91
|
||||||
it.writeZero(2)
|
it.writeZero(2)
|
||||||
|
|
||||||
if ("[face" in message
|
|
||||||
|| ".gif]" in message
|
it.write(message.toByteArray())
|
||||||
|| ".jpg]" in message
|
|
||||||
|| ".png]" in message
|
/*
|
||||||
) {
|
|
||||||
TODO("复合消息构建")
|
|
||||||
} else {
|
|
||||||
//Plain text
|
//Plain text
|
||||||
val bytes = message.toByteArray()
|
val bytes = message.toByteArray()
|
||||||
it.writeByte(0x01)
|
it.writeByte(0x01)
|
||||||
it.writeShort(bytes.size + 3)
|
it.writeShort(bytes.size + 3)
|
||||||
it.writeByte(0x01)
|
it.writeByte(0x01)
|
||||||
it.writeShort(bytes.size)
|
it.writeShort(bytes.size)
|
||||||
it.write(bytes)
|
it.write(bytes)*/
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ object MiraiLogger {
|
|||||||
this.print(e.cause.toString())*/
|
this.print(e.cause.toString())*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
||||||
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
||||||
kotlin.io.println("$color[Mirai] $s : $value")
|
kotlin.io.println("$color[Mirai] $s : $value")
|
||||||
@ -52,12 +53,14 @@ infix fun Robot.success(o: Any?) = print(this, o.toString(), LoggerTextFormat.GR
|
|||||||
infix fun Robot.debug(o: Any?) = print(this, o.toString(), LoggerTextFormat.YELLOW)
|
infix fun Robot.debug(o: Any?) = print(this, o.toString(), LoggerTextFormat.YELLOW)
|
||||||
|
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
private fun print(robot: Robot, value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
private fun print(robot: Robot, value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
||||||
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
||||||
kotlin.io.println("$color[Mirai] $s #R${robot.id}: $value")
|
kotlin.io.println("$color[Mirai] $s #R${robot.id}: $value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Synchronized
|
||||||
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
private fun print(value: String?, color: LoggerTextFormat = LoggerTextFormat.WHITE) {
|
||||||
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
val s = SimpleDateFormat("MM-dd HH:mm:ss").format(Date())
|
||||||
kotlin.io.println("$color[Mirai] $s : $value")
|
kotlin.io.println("$color[Mirai] $s : $value")
|
||||||
|
39
mirai-ui/pom.xml
Normal file
39
mirai-ui/pom.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>mirai-ui</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>net.mamoe</groupId>
|
||||||
|
<artifactId>mirai</artifactId>
|
||||||
|
<version>1.0</version>
|
||||||
|
<relativePath>../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>/src/main/resources</directory>
|
||||||
|
|
||||||
|
<includes>
|
||||||
|
<include>**/*.*</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
139
pom.xml
139
pom.xml
@ -12,6 +12,7 @@
|
|||||||
<modules>
|
<modules>
|
||||||
<module>mirai-core</module>
|
<module>mirai-core</module>
|
||||||
<module>mirai-native</module>
|
<module>mirai-native</module>
|
||||||
|
<module>mirai-ui</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -27,41 +28,14 @@
|
|||||||
|
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<kotlin.version>1.3.41</kotlin.version>
|
||||||
<maven.compiler.source>11</maven.compiler.source>
|
<maven.compiler.source>11</maven.compiler.source>
|
||||||
<maven.compiler.target>11</maven.compiler.target>
|
<maven.compiler.target>11</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
|
||||||
<defaultGoal>package</defaultGoal>
|
|
||||||
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<version>3.8.1</version>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ow2.asm</groupId>
|
|
||||||
<artifactId>asm</artifactId>
|
|
||||||
<version>7.1</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
<configuration>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok-maven-plugin</artifactId>
|
|
||||||
<version>1.18.6.0</version>
|
|
||||||
</plugin>
|
|
||||||
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -121,7 +95,114 @@
|
|||||||
<version>0.5.2</version>
|
<version>0.5.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-stdlib</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-core</artifactId>
|
||||||
|
<version>2.12.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.yaml</groupId>
|
||||||
|
<artifactId>snakeyaml</artifactId>
|
||||||
|
<version>1.18</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-reflect</artifactId>
|
||||||
|
<version>1.3.41</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<defaultGoal>package</defaultGoal>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.ow2.asm</groupId>
|
||||||
|
<artifactId>asm</artifactId>
|
||||||
|
<version>7.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
<configuration>
|
||||||
|
<encoding>UTF-8</encoding>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<version>1.18.6.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>2.4.3</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<shadedArtifactAttached>true</shadedArtifactAttached>
|
||||||
|
<shadedClassifierName>shaded</shadedClassifierName>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<version>1.18.6.0</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.jetbrains.kotlin</groupId>
|
||||||
|
<artifactId>kotlin-maven-plugin</artifactId>
|
||||||
|
<version>${kotlin.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>compile</id>
|
||||||
|
<phase>process-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
<execution>
|
||||||
|
<id>test-compile</id>
|
||||||
|
<phase>test-compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>test-compile</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
<configuration>
|
||||||
|
<jvmTarget>1.8</jvmTarget>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
|
||||||
</project>
|
</project>
|
Loading…
Reference in New Issue
Block a user