mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-25 15:40:28 +08:00
Add blocking wrappers
This commit is contained in:
parent
fae8486395
commit
b18dad9612
@ -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<MemberJoinE
|
||||
val group = bot.getGroup(readUInt())
|
||||
|
||||
discardExact(1) // 01
|
||||
val member = MemberImpl(bot.getQQ(readUInt()), group, MemberPermission.MEMBER)
|
||||
val member = Member(bot.getQQ(readUInt()), group, MemberPermission.MEMBER, coroutineContext)
|
||||
|
||||
return if (readByte().toInt() == 0x03) {
|
||||
MemberJoinEventPacket(member, null)
|
||||
|
9
mirai-japt/README.md
Normal file
9
mirai-japt/README.md
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
# mirai-japt
|
||||
|
||||
Mirai Java Apt
|
||||
|
||||
提供一些阻塞/异步/RxJava API 来让 Java 调用 Mirai 的挂起函数 API 更容易
|
||||
提供 Utils 类来让 Java 调用 Mirai 的内联方法更容易
|
||||
|
||||
该模块暂未完成.
|
44
mirai-japt/build.gradle.kts
Normal file
44
mirai-japt/build.gradle.kts
Normal file
@ -0,0 +1,44 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
java
|
||||
}
|
||||
|
||||
val kotlinVersion: String by rootProject.ext
|
||||
val atomicFuVersion: String by rootProject.ext
|
||||
val coroutinesVersion: String by rootProject.ext
|
||||
val kotlinXIoVersion: String by rootProject.ext
|
||||
val coroutinesIoVersion: String by rootProject.ext
|
||||
val serializationVersion: String by rootProject.ext
|
||||
|
||||
val klockVersion: String by rootProject.ext
|
||||
val ktorVersion: String by rootProject.ext
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun kotlinx(id: String, version: String) = "org.jetbrains.kotlinx:kotlinx-$id:$version"
|
||||
|
||||
fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
|
||||
|
||||
dependencies {
|
||||
api(project(":mirai-core"))
|
||||
runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) // classpath is not added correctly by IDE
|
||||
|
||||
api(group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-javafx", version = "1.3.2")
|
||||
|
||||
api(kotlin("stdlib", kotlinVersion))
|
||||
api(kotlinx("io-jvm", kotlinXIoVersion))
|
||||
api(kotlinx("io", kotlinXIoVersion))
|
||||
api(kotlinx("coroutines-io", coroutinesIoVersion))
|
||||
api(kotlinx("coroutines-core", coroutinesVersion))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>() {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
4
mirai-japt/mirai-japt.postfixTemplates
Normal file
4
mirai-japt/mirai-japt.postfixTemplates
Normal file
@ -0,0 +1,4 @@
|
||||
# Contact
|
||||
|
||||
.blocking : 阻塞式包装
|
||||
net.mamoe.mirai.contact.QQ [net.mamoe.mirai.japt.BlockingContacts] -> BlockingQQ. BlockingContacts.createBlocking($var$)
|
@ -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();
|
||||
|
||||
/**
|
||||
* 向这个对象发送消息.
|
||||
* <p>
|
||||
* 速度太快会被服务器屏蔽(无响应). 在测试中不延迟地发送 6 条消息就会被屏蔽之后的数据包 1 秒左右.
|
||||
*/
|
||||
void sendMessage(@NotNull MessageChain messages);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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] 实例创建的时候查询一次. 并与事件同步事件更新
|
||||
* <p>
|
||||
* **注意**: 获得的列表仅为这一时刻的成员列表的镜像. 它将不会被更新
|
||||
*/
|
||||
Map<Long, BlockingMember> getMembers();
|
||||
|
||||
/**
|
||||
* 获取群成员. 若此 ID 的成员不存在, 则会抛出 [kotlin.NoSuchElementException]
|
||||
*/
|
||||
BlockingMember getMember(long id);
|
||||
|
||||
/**
|
||||
* 更新群资料. 群资料会与服务器事件同步事件更新, 一般情况下不需要手动更新.
|
||||
*
|
||||
* @return 这一时刻的群资料
|
||||
*/
|
||||
GroupInfo updateGroupInfo();
|
||||
|
||||
/**
|
||||
* 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败
|
||||
*/
|
||||
boolean quit();
|
||||
|
||||
String toFullString();
|
||||
}
|
@ -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();
|
||||
}
|
@ -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();
|
||||
|
||||
/**
|
||||
* 查询曾用名.
|
||||
* <p>
|
||||
* 曾用名可能是:
|
||||
* - 昵称
|
||||
* - 共同群内的群名片
|
||||
*/
|
||||
@NotNull
|
||||
PreviousNameList queryPreviousNameList();
|
||||
|
||||
/**
|
||||
* 查询机器人账号给这个人设置的备注
|
||||
*/
|
||||
@NotNull
|
||||
FriendNameRemark queryRemark();
|
||||
}
|
@ -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)
|
@ -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<Long, BlockingMember> = 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() }
|
||||
}
|
14
mirai-japt/src/test/kotlin/BlockingTest.java
Normal file
14
mirai-japt/src/test/kotlin/BlockingTest.java
Normal file
@ -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())
|
||||
}
|
||||
}
|
31
mirai-japt/src/test/kotlin/TestBlocking.kt
Normal file
31
mirai-japt/src/test/kotlin/TestBlocking.kt
Normal file
@ -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())
|
||||
}
|
@ -22,6 +22,7 @@ rootProject.name = 'mirai'
|
||||
|
||||
include(':mirai-core')
|
||||
|
||||
include(':mirai-japt')
|
||||
include(':mirai-console')
|
||||
//include(':mirai-api')
|
||||
include(':mirai-api-http')
|
||||
|
Loading…
Reference in New Issue
Block a user