From b18dad9612aedf36d38759257b70f33dcf40e29a Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 6 Dec 2019 20:50:01 +0800 Subject: [PATCH 1/2] Add blocking wrappers --- .../protocol/tim/packet/event/MemberJoin.kt | 5 +- mirai-japt/README.md | 9 +++ mirai-japt/build.gradle.kts | 44 ++++++++++++++ mirai-japt/mirai-japt.postfixTemplates | 4 ++ .../net/mamoe/mirai/japt/BlockingContact.java | 26 +++++++++ .../mamoe/mirai/japt/BlockingContacts.java | 22 +++++++ .../net/mamoe/mirai/japt/BlockingGroup.java | 57 +++++++++++++++++++ .../net/mamoe/mirai/japt/BlockingMember.java | 29 ++++++++++ .../java/net/mamoe/mirai/japt/BlockingQQ.java | 31 ++++++++++ .../net/mamoe/mirai/japt/BlockingContacts.kt | 11 ++++ .../mamoe/mirai/japt/BlockingContactsImpl.kt | 46 +++++++++++++++ mirai-japt/src/test/kotlin/BlockingTest.java | 14 +++++ mirai-japt/src/test/kotlin/TestBlocking.kt | 31 ++++++++++ settings.gradle | 1 + 14 files changed, 328 insertions(+), 2 deletions(-) create mode 100644 mirai-japt/README.md create mode 100644 mirai-japt/build.gradle.kts create mode 100644 mirai-japt/mirai-japt.postfixTemplates create mode 100644 mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContact.java create mode 100644 mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContacts.java create mode 100644 mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingGroup.java create mode 100644 mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingMember.java create mode 100644 mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingQQ.java create mode 100644 mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContacts.kt create mode 100644 mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContactsImpl.kt create mode 100644 mirai-japt/src/test/kotlin/BlockingTest.java create mode 100644 mirai-japt/src/test/kotlin/TestBlocking.kt diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt index 53d551898..5a39203e4 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt @@ -8,7 +8,7 @@ import net.mamoe.mirai.Bot import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.MemberPermission -import net.mamoe.mirai.contact.internal.MemberImpl +import net.mamoe.mirai.contact.internal.Member import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.getGroup @@ -16,6 +16,7 @@ import net.mamoe.mirai.getQQ import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.io.discardExact +import kotlin.coroutines.coroutineContext /** * 成员加入前的事件. 群的成员列表中还没有这个人 @@ -74,7 +75,7 @@ internal object MemberJoinPacketHandler : KnownEventParserAndHandler() { + options.encoding = "UTF-8" +} \ No newline at end of file diff --git a/mirai-japt/mirai-japt.postfixTemplates b/mirai-japt/mirai-japt.postfixTemplates new file mode 100644 index 000000000..9df0de9fd --- /dev/null +++ b/mirai-japt/mirai-japt.postfixTemplates @@ -0,0 +1,4 @@ +# Contact + +.blocking : 阻塞式包装 + net.mamoe.mirai.contact.QQ [net.mamoe.mirai.japt.BlockingContacts] -> BlockingQQ. BlockingContacts.createBlocking($var$) diff --git a/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContact.java b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContact.java new file mode 100644 index 000000000..dcc1585cb --- /dev/null +++ b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContact.java @@ -0,0 +1,26 @@ +package net.mamoe.mirai.japt; + +import net.mamoe.mirai.Bot; +import net.mamoe.mirai.message.MessageChain; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public interface BlockingContact { + /** + * 这个联系人所属 [Bot] + */ + @NotNull + Bot getBot(); + + /** + * 可以是 QQ 号码或者群号码 [GroupId]. + */ + long getId(); + + /** + * 向这个对象发送消息. + *

+ * 速度太快会被服务器屏蔽(无响应). 在测试中不延迟地发送 6 条消息就会被屏蔽之后的数据包 1 秒左右. + */ + void sendMessage(@NotNull MessageChain messages); +} diff --git a/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContacts.java b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContacts.java new file mode 100644 index 000000000..de7a3b9cf --- /dev/null +++ b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingContacts.java @@ -0,0 +1,22 @@ +package net.mamoe.mirai.japt; + +import net.mamoe.mirai.contact.Group; +import net.mamoe.mirai.contact.Member; +import net.mamoe.mirai.contact.QQ; + +/** + * 构造阻塞式的联系人. + */ +public final class BlockingContacts { + public static BlockingQQ createBlocking(QQ qq) { + return new BlockingQQImpl(qq); + } + + public static BlockingGroup createBlocking(Group group) { + return new BlockingGroupImpl(group); + } + + public static BlockingMember createBlocking(Member member) { + return new BlockingMemberImpl(member); + } +} diff --git a/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingGroup.java b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingGroup.java new file mode 100644 index 000000000..37fdc62b1 --- /dev/null +++ b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingGroup.java @@ -0,0 +1,57 @@ +package net.mamoe.mirai.japt; + +import net.mamoe.mirai.network.protocol.tim.packet.action.GroupInfo; + +import java.util.Map; + +@SuppressWarnings("unused") +public interface BlockingGroup extends BlockingContact { + /** + * 内部 ID. 内部 ID 为 [GroupId] 的映射 + */ + Long getInternalId(); + + /** + * 群主 (同步事件更新) + * 进行 [updateGroupInfo] 时将会更新这个值. + */ + BlockingMember getOwner(); + + /** + * 群名称 (同步事件更新) + * 进行 [updateGroupInfo] 时将会更新这个值. + */ + String getName(); + + /** + * 入群公告, 没有时为空字符串. (同步事件更新) + * 进行 [updateGroupInfo] 时将会更新这个值. + */ + String getAnnouncement(); + + /** + * 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新 + *

+ * **注意**: 获得的列表仅为这一时刻的成员列表的镜像. 它将不会被更新 + */ + Map getMembers(); + + /** + * 获取群成员. 若此 ID 的成员不存在, 则会抛出 [kotlin.NoSuchElementException] + */ + BlockingMember getMember(long id); + + /** + * 更新群资料. 群资料会与服务器事件同步事件更新, 一般情况下不需要手动更新. + * + * @return 这一时刻的群资料 + */ + GroupInfo updateGroupInfo(); + + /** + * 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败 + */ + boolean quit(); + + String toFullString(); +} \ No newline at end of file diff --git a/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingMember.java b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingMember.java new file mode 100644 index 000000000..bea594a00 --- /dev/null +++ b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingMember.java @@ -0,0 +1,29 @@ +package net.mamoe.mirai.japt; + +import net.mamoe.mirai.contact.MemberPermission; + +@SuppressWarnings("unused") +public interface BlockingMember { + /** + * 所在的群 + */ + BlockingGroup getGroup(); + + /** + * 权限 + */ + MemberPermission getPermission(); + + /** + * 禁言 + * + * @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常. + * @return 若机器人无权限禁言这个群成员, 返回 `false` + */ + Boolean mute(int durationSeconds); + + /** + * 解除禁言 + */ + void unmute(); +} diff --git a/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingQQ.java b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingQQ.java new file mode 100644 index 000000000..e01aa246c --- /dev/null +++ b/mirai-japt/src/main/java/net/mamoe/mirai/japt/BlockingQQ.java @@ -0,0 +1,31 @@ +package net.mamoe.mirai.japt; + +import net.mamoe.mirai.contact.data.Profile; +import net.mamoe.mirai.network.protocol.tim.packet.action.FriendNameRemark; +import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList; +import org.jetbrains.annotations.NotNull; + +@SuppressWarnings("unused") +public interface BlockingQQ extends BlockingContact { + /** + * 查询用户资料 + */ + @NotNull + Profile queryProfile(); + + /** + * 查询曾用名. + *

+ * 曾用名可能是: + * - 昵称 + * - 共同群内的群名片 + */ + @NotNull + PreviousNameList queryPreviousNameList(); + + /** + * 查询机器人账号给这个人设置的备注 + */ + @NotNull + FriendNameRemark queryRemark(); +} diff --git a/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContacts.kt b/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContacts.kt new file mode 100644 index 000000000..e583d33b5 --- /dev/null +++ b/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContacts.kt @@ -0,0 +1,11 @@ +@file:Suppress("NOTHING_TO_INLINE", "unused") + +package net.mamoe.mirai.japt + +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.contact.QQ + +inline fun Group.blocking(): BlockingGroup = BlockingContacts.createBlocking(this) +inline fun QQ.blocking(): BlockingQQ = BlockingContacts.createBlocking(this) +inline fun Member.blocking(): BlockingMember = BlockingContacts.createBlocking(this) \ No newline at end of file diff --git a/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContactsImpl.kt b/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContactsImpl.kt new file mode 100644 index 000000000..550d5a807 --- /dev/null +++ b/mirai-japt/src/main/kotlin/net/mamoe/mirai/japt/BlockingContactsImpl.kt @@ -0,0 +1,46 @@ +@file:Suppress("EXPERIMENTAL_API_USAGE") + +package net.mamoe.mirai.japt + +import kotlinx.coroutines.runBlocking +import net.mamoe.mirai.Bot +import net.mamoe.mirai.contact.Group +import net.mamoe.mirai.contact.Member +import net.mamoe.mirai.contact.MemberPermission +import net.mamoe.mirai.contact.QQ +import net.mamoe.mirai.contact.data.Profile +import net.mamoe.mirai.message.MessageChain +import net.mamoe.mirai.network.protocol.tim.packet.action.FriendNameRemark +import net.mamoe.mirai.network.protocol.tim.packet.action.GroupInfo +import net.mamoe.mirai.network.protocol.tim.packet.action.PreviousNameList + +internal class BlockingQQImpl(private val delegate: QQ) : BlockingQQ { + override fun getBot(): Bot = delegate.bot + override fun getId(): Long = delegate.id.toLong() + override fun sendMessage(messages: MessageChain) = runBlocking { delegate.sendMessage(messages) } + override fun queryProfile(): Profile = runBlocking { delegate.queryProfile() } + override fun queryPreviousNameList(): PreviousNameList = runBlocking { delegate.queryPreviousNameList() } + override fun queryRemark(): FriendNameRemark = runBlocking { delegate.queryRemark() } +} + +internal class BlockingGroupImpl(private val delegate: Group) : BlockingGroup { + override fun sendMessage(messages: MessageChain) = runBlocking { delegate.sendMessage(messages) } + override fun getOwner(): BlockingMember = delegate.owner.blocking() + override fun getName(): String = delegate.name + override fun getId(): Long = delegate.id.toLong() + override fun updateGroupInfo(): GroupInfo = runBlocking { delegate.updateGroupInfo() } + override fun toFullString(): String = delegate.toFullString() + override fun getMember(id: Long): BlockingMember = delegate.getMember(id.toUInt()).blocking() + override fun getBot(): Bot = delegate.bot + override fun getAnnouncement(): String = delegate.announcement + override fun getMembers(): MutableMap = delegate.members.mapKeys { it.key.toLong() }.mapValues { it.value.blocking() }.toMutableMap() + override fun getInternalId(): Long = delegate.internalId.value.toLong() + override fun quit(): Boolean = runBlocking { delegate.quit().isSuccess } +} + +internal class BlockingMemberImpl(private val delegate: Member) : BlockingMember { + override fun getGroup(): BlockingGroup = delegate.group.blocking() + override fun getPermission(): MemberPermission = delegate.permission + override fun mute(durationSeconds: Int): Boolean = runBlocking { delegate.mute(durationSeconds) } + override fun unmute() = runBlocking { delegate.unmute() } +} \ No newline at end of file diff --git a/mirai-japt/src/test/kotlin/BlockingTest.java b/mirai-japt/src/test/kotlin/BlockingTest.java new file mode 100644 index 000000000..385ab7c23 --- /dev/null +++ b/mirai-japt/src/test/kotlin/BlockingTest.java @@ -0,0 +1,14 @@ +public class BlockingTest { + + + public static void main(String[] args) { + //Bot bot = new Bot(new BotAccount(123456, ""), EmptyCoroutineContext.INSTANCE); + //if (bot.getNetwork().login() != LoginResult.) { + // throw IllegalStateException("Login failed") + //} + //bot.getContacts().getGroups(); + + //var qq = BlockingContacts.createBlocking(bot.getContacts().getQQ(123L)) + //println(createBlocking.queryRemark()) + } +} diff --git a/mirai-japt/src/test/kotlin/TestBlocking.kt b/mirai-japt/src/test/kotlin/TestBlocking.kt new file mode 100644 index 000000000..01393988a --- /dev/null +++ b/mirai-japt/src/test/kotlin/TestBlocking.kt @@ -0,0 +1,31 @@ +import net.mamoe.mirai.Bot +import net.mamoe.mirai.BotAccount +import net.mamoe.mirai.japt.BlockingContacts +import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult +import java.io.File + +@ExperimentalUnsignedTypes +private fun readTestAccount(): BotAccount? { + val file = File("testAccount.txt") + if (!file.exists() || !file.canRead()) { + return null + } + + val lines = file.readLines() + return try { + BotAccount(lines[0].toUInt(), lines[1]) + } catch (e: Exception) { + null + } +} + +@ExperimentalUnsignedTypes +suspend fun main() { + val bot = Bot(readTestAccount()!!) + if (bot.network.login() != LoginResult.SUCCESS) { + throw IllegalStateException("Login failed") + } + + val createBlocking = BlockingContacts.createBlocking(bot.contacts.getQQ(123L)) + println(createBlocking.queryRemark()) +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index c73bf1627..8b6a36bf7 100644 --- a/settings.gradle +++ b/settings.gradle @@ -22,6 +22,7 @@ rootProject.name = 'mirai' include(':mirai-core') +include(':mirai-japt') include(':mirai-console') //include(':mirai-api') include(':mirai-api-http') From cff2fc585cdf6f3b4607bfe6d4cba450bb84512c Mon Sep 17 00:00:00 2001 From: Him188 Date: Fri, 6 Dec 2019 20:52:51 +0800 Subject: [PATCH 2/2] Use coroutineContext from qq --- .../network/protocol/tim/packet/event/MemberJoin.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt index 5a39203e4..c5d736023 100644 --- a/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt +++ b/mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/MemberJoin.kt @@ -16,7 +16,6 @@ import net.mamoe.mirai.getQQ import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.io.discardExact -import kotlin.coroutines.coroutineContext /** * 成员加入前的事件. 群的成员列表中还没有这个人 @@ -75,7 +74,8 @@ internal object MemberJoinPacketHandler : KnownEventParserAndHandler