mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-24 20:43:33 +08:00
Japt
This commit is contained in:
parent
a5ef34b53a
commit
25b3b2b2be
gradle.properties
mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/utils
mirai-demos/mirai-demo-java
mirai-japt
settings.gradle@ -2,6 +2,7 @@
|
||||
kotlin.code.style=official
|
||||
# config
|
||||
mirai_version=0.15.0
|
||||
mirai_japt_version=1.0.0
|
||||
kotlin.incremental.multiplatform=true
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
# kotlin
|
||||
|
@ -62,7 +62,7 @@ internal class DefaultLoginSolver : LoginSolver() {
|
||||
}
|
||||
}
|
||||
bot.logger.info("请输入 4 位字母验证码. 若要更换验证码, 请直接回车")
|
||||
return readLine()?.takeUnless { it.isEmpty() || it.length != 4 }.also {
|
||||
return readLine()!!.takeUnless { it.isEmpty() || it.length != 4 }.also {
|
||||
bot.logger.info("正在提交[$it]中...")
|
||||
}
|
||||
}
|
||||
|
18
mirai-demos/mirai-demo-java/build.gradle
Normal file
18
mirai-demos/mirai-demo-java/build.gradle
Normal file
@ -0,0 +1,18 @@
|
||||
apply plugin: "java"
|
||||
apply plugin: "kotlin"
|
||||
|
||||
dependencies {
|
||||
implementation files("../../mirai-core/build/classes/kotlin/jvm/main") // IDE bug
|
||||
|
||||
implementation files("../../mirai-core-qqandroid/build/classes/kotlin/jvm/main") // IDE bug
|
||||
implementation project(":mirai-core-qqandroid")
|
||||
implementation project(":mirai-japt")
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
compileJava.options.encoding = 'UTF-8'
|
||||
|
||||
compileTestJava.options.encoding = 'UTF-8'
|
@ -0,0 +1,28 @@
|
||||
package demo;
|
||||
|
||||
import net.mamoe.mirai.japt.BlockingBot;
|
||||
import net.mamoe.mirai.japt.BlockingContacts;
|
||||
import net.mamoe.mirai.japt.BlockingQQ;
|
||||
import net.mamoe.mirai.japt.Events;
|
||||
import net.mamoe.mirai.message.GroupMessage;
|
||||
|
||||
class BlockingTest {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException {
|
||||
BlockingBot bot = BlockingBot.newInstance(123456, "");
|
||||
|
||||
bot.login();
|
||||
|
||||
bot.getFriendList().forEach(friend -> {
|
||||
System.out.println(friend.getNick());
|
||||
});
|
||||
|
||||
Events.subscribeAlways(GroupMessage.class, (GroupMessage message) -> {
|
||||
final BlockingQQ sender = BlockingContacts.createBlocking(message.getSender());
|
||||
|
||||
sender.sendMessage("Hello");
|
||||
});
|
||||
|
||||
Thread.sleep(999999999);
|
||||
}
|
||||
}
|
@ -13,6 +13,12 @@ val serializationVersion: String by rootProject.ext
|
||||
val klockVersion: String by rootProject.ext
|
||||
val ktorVersion: String by rootProject.ext
|
||||
|
||||
description = "Java helper for Mirai"
|
||||
|
||||
@Suppress("PropertyName")
|
||||
val mirai_japt_version: String by rootProject.ext
|
||||
version = mirai_japt_version
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
all {
|
||||
@ -38,6 +44,8 @@ dependencies {
|
||||
api(kotlinx("io", kotlinXIoVersion))
|
||||
api(kotlinx("coroutines-io", coroutinesIoVersion))
|
||||
api(kotlinx("coroutines-core", coroutinesVersion))
|
||||
api(kotlin("stdlib-jdk7", kotlinVersion))
|
||||
api(kotlin("stdlib-jdk8", kotlinVersion))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile>() {
|
||||
|
@ -1,34 +1,87 @@
|
||||
package net.mamoe.mirai.japt;
|
||||
|
||||
import net.mamoe.mirai.Bot;
|
||||
import net.mamoe.mirai.contact.Contact;
|
||||
import net.mamoe.mirai.contact.Member;
|
||||
import net.mamoe.mirai.contact.QQ;
|
||||
import net.mamoe.mirai.event.events.BeforeImageUploadEvent;
|
||||
import net.mamoe.mirai.event.events.EventCancelledException;
|
||||
import net.mamoe.mirai.event.events.ImageUploadEvent;
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.FriendMessageSendEvent;
|
||||
import net.mamoe.mirai.event.events.MessageSendEvent.GroupMessageSendEvent;
|
||||
import net.mamoe.mirai.message.data.Image;
|
||||
import net.mamoe.mirai.message.data.Message;
|
||||
import net.mamoe.mirai.message.data.MessageChain;
|
||||
import net.mamoe.mirai.utils.ExternalImage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* 对 {@link Contact} 的阻塞式包装.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface BlockingContact {
|
||||
/**
|
||||
* 这个联系人所属 [Bot]
|
||||
* 这个联系人所属 {@link Bot}
|
||||
*/
|
||||
@NotNull
|
||||
BlockingBot getBot();
|
||||
|
||||
/**
|
||||
* 可以是 QQ 号码或者群号码 [GroupId].
|
||||
* 可以是 QQ 号码或者群号码.
|
||||
* <p>
|
||||
* 对于 QQ, {@code uin} 与 {@code id} 是相同的意思.
|
||||
* 对于 Group, {@code groupCode} 与 {@code id} 是相同的意思.
|
||||
*/
|
||||
long getId();
|
||||
|
||||
/**
|
||||
* 向这个对象发送消息.
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
*/
|
||||
void sendMessage(@NotNull MessageChain messages);
|
||||
// kotlin bug
|
||||
void sendMessage(@NotNull MessageChain messages) throws EventCancelledException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* 向这个对象发送消息.
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
*/
|
||||
void sendMessage(@NotNull String message);
|
||||
void sendMessage(@NotNull String message) throws EventCancelledException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* 向这个对象发送消息.
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @throws IllegalStateException 发送群消息时若 [Bot] 被禁言抛出
|
||||
* @see FriendMessageSendEvent 发送好友信息事件, cancellable
|
||||
* @see GroupMessageSendEvent 发送群消息事件. cancellable
|
||||
*/
|
||||
void sendMessage(@NotNull Message message);
|
||||
void sendMessage(@NotNull Message message) throws EventCancelledException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* 上传一个图片以备发送.
|
||||
* 群图片与好友图片在服务器上是通用的, 在 mirai 目前不通用.
|
||||
*
|
||||
* @throws EventCancelledException 当发送消息事件被取消
|
||||
* @see BeforeImageUploadEvent 图片发送前事件, cancellable
|
||||
* @see ImageUploadEvent 图片发送完成事件
|
||||
*/
|
||||
Image uploadImage(@NotNull ExternalImage image) throws EventCancelledException;
|
||||
|
||||
/**
|
||||
* 判断 {@code this} 和 {@code other} 是否是相同的类型, 并且 {@link Contact#getId()} 相同.
|
||||
* <p>
|
||||
* 注:
|
||||
* {@link Contact#getId()} 相同的 {@link Member} 和 {@link QQ}, 他们并不 equals.
|
||||
* 因为, {@link Member} 含义为群员, 必属于一个群.
|
||||
* 而 {@link QQ} 含义为一个独立的人, 可以是好友, 也可以是陌生人.
|
||||
*/
|
||||
boolean equals(Object other);
|
||||
}
|
||||
|
@ -8,24 +8,31 @@ import net.mamoe.mirai.japt.internal.BlockingBotImpl;
|
||||
import net.mamoe.mirai.japt.internal.BlockingGroupImpl;
|
||||
import net.mamoe.mirai.japt.internal.BlockingMemberImpl;
|
||||
import net.mamoe.mirai.japt.internal.BlockingQQImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 构造阻塞式的联系人.
|
||||
*/
|
||||
public final class BlockingContacts {
|
||||
public static BlockingQQ createBlocking(QQ qq) {
|
||||
return new BlockingQQImpl(qq);
|
||||
@NotNull
|
||||
public static BlockingQQ createBlocking(@NotNull QQ qq) {
|
||||
return new BlockingQQImpl(Objects.requireNonNull(qq));
|
||||
}
|
||||
|
||||
public static BlockingGroup createBlocking(Group group) {
|
||||
return new BlockingGroupImpl(group);
|
||||
@NotNull
|
||||
public static BlockingGroup createBlocking(@NotNull Group group) {
|
||||
return new BlockingGroupImpl(Objects.requireNonNull(group));
|
||||
}
|
||||
|
||||
public static BlockingMember createBlocking(Member member) {
|
||||
return new BlockingMemberImpl(member);
|
||||
@NotNull
|
||||
public static BlockingMember createBlocking(@NotNull Member member) {
|
||||
return new BlockingMemberImpl(Objects.requireNonNull(member));
|
||||
}
|
||||
|
||||
public static BlockingBot createBlocking(Bot bot) {
|
||||
return new BlockingBotImpl(bot);
|
||||
@NotNull
|
||||
public static BlockingBot createBlocking(@NotNull Bot bot) {
|
||||
return new BlockingBotImpl(Objects.requireNonNull(bot));
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,30 @@ package net.mamoe.mirai.japt;
|
||||
import net.mamoe.mirai.data.FriendNameRemark;
|
||||
import net.mamoe.mirai.data.PreviousNameList;
|
||||
import net.mamoe.mirai.data.Profile;
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface BlockingQQ extends BlockingContact {
|
||||
/**
|
||||
* 获取 QQ 号码
|
||||
*
|
||||
* @return QQ 号码
|
||||
*/
|
||||
@Override
|
||||
long getId();
|
||||
|
||||
/**
|
||||
* 获取昵称
|
||||
*
|
||||
* @return 昵称
|
||||
*/
|
||||
String getNick();
|
||||
|
||||
/**
|
||||
* 查询用户资料
|
||||
*/
|
||||
@MiraiExperimentalAPI(message = "还未支持")
|
||||
@NotNull
|
||||
Profile queryProfile();
|
||||
|
||||
@ -20,12 +37,14 @@ public interface BlockingQQ extends BlockingContact {
|
||||
* - 昵称
|
||||
* - 共同群内的群名片
|
||||
*/
|
||||
@MiraiExperimentalAPI(message = "还未支持")
|
||||
@NotNull
|
||||
PreviousNameList queryPreviousNameList();
|
||||
|
||||
/**
|
||||
* 查询机器人账号给这个人设置的备注
|
||||
*/
|
||||
@MiraiExperimentalAPI(message = "还未支持")
|
||||
@NotNull
|
||||
FriendNameRemark queryRemark();
|
||||
}
|
||||
|
@ -20,18 +20,46 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* 事件处理
|
||||
*/
|
||||
public final class Events {
|
||||
|
||||
/**
|
||||
* 监听一个事件, 当 {@code onEvent} 返回 {@link ListeningStatus#STOPPED} 时停止监听.
|
||||
* 机器人离线后不会停止监听.
|
||||
*
|
||||
* @param eventClass 事件类
|
||||
* @param onEvent 事件处理. 返回 {@link ListeningStatus#LISTENING} 时继续监听.
|
||||
* @param <E> 事件类型
|
||||
* @return 事件监听器. 可调用 {@link Listener#complete()} 或 {@link Listener#completeExceptionally(Throwable)} 让监听正常停止或异常停止.
|
||||
*/
|
||||
@NotNull
|
||||
public static <E extends Event> Listener<E> subscribe(@NotNull Class<E> eventClass, @NotNull Function<E, ListeningStatus> onEvent) {
|
||||
return EventInternalJvmKt._subscribeEventForJaptOnly(eventClass, GlobalScope.INSTANCE, onEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听一个事件, 直到手动停止.
|
||||
* 机器人离线后不会停止监听.
|
||||
*
|
||||
* @param eventClass 事件类
|
||||
* @param onEvent 事件处理. 返回 {@link ListeningStatus#LISTENING} 时继续监听.
|
||||
* @param <E> 事件类型
|
||||
* @return 事件监听器. 可调用 {@link Listener#complete()} 或 {@link Listener#completeExceptionally(Throwable)} 让监听正常停止或异常停止.
|
||||
*/
|
||||
@NotNull
|
||||
public static <E extends Event> Listener<E> subscribeAlways(@NotNull Class<E> eventClass, @NotNull Consumer<E> onEvent) {
|
||||
return EventInternalJvmKt._subscribeEventForJaptOnly(eventClass, GlobalScope.INSTANCE, onEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 阻塞地广播一个事件.
|
||||
*
|
||||
* @param event 事件
|
||||
* @param <E> 事件类型
|
||||
* @return {@code event} 本身
|
||||
*/
|
||||
@NotNull
|
||||
public static <E extends Event> E broadcast(@NotNull E event) {
|
||||
return EventsImplKt.broadcast(event);
|
||||
|
@ -14,34 +14,55 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.readBytes
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.BotAccount
|
||||
import net.mamoe.mirai.contact.QQ
|
||||
import net.mamoe.mirai.data.AddFriendResult
|
||||
import net.mamoe.mirai.data.GroupInfo
|
||||
import net.mamoe.mirai.data.MemberInfo
|
||||
import net.mamoe.mirai.japt.BlockingBot
|
||||
import net.mamoe.mirai.japt.BlockingGroup
|
||||
import net.mamoe.mirai.japt.BlockingQQ
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.utils.MiraiExperimentalAPI
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import net.mamoe.mirai.utils.toList
|
||||
import java.io.OutputStream
|
||||
import java.util.stream.Stream
|
||||
import kotlin.streams.asStream
|
||||
|
||||
internal class BlockingBotImpl(private val bot: Bot) : BlockingBot {
|
||||
@MiraiInternalAPI
|
||||
override fun getAccount(): BotAccount = bot.account
|
||||
|
||||
override fun getUin(): Long = bot.uin
|
||||
override fun getLogger(): MiraiLogger = bot.logger
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
override fun getQQs(): List<BlockingQQ> = bot.qqs.delegate.toList().map { it.blocking() }
|
||||
@MiraiExperimentalAPI
|
||||
override fun getNick(): String = bot.nick
|
||||
|
||||
override fun getLogger(): MiraiLogger = bot.logger
|
||||
override fun getSelfQQ(): QQ = bot.selfQQ
|
||||
|
||||
override fun queryGroupMemberList(groupUin: Long, groupCode: Long, ownerId: Long): Stream<MemberInfo> =
|
||||
runBlocking { bot.queryGroupMemberList(groupUin, groupCode, ownerId) }.asStream()
|
||||
|
||||
override fun getQQ(id: Long): BlockingQQ = bot.getFriend(id).blocking()
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
override fun getGroups(): List<BlockingGroup> = bot.groups.delegate.toList().map { it.blocking() }
|
||||
override fun getFriendList(): List<BlockingQQ> = bot.qqs.delegate.toList().map { it.blocking() }
|
||||
|
||||
override fun getFriend(id: Long): BlockingQQ = bot.getFriend(id).blocking()
|
||||
override fun queryGroupList(): Stream<Long> = runBlocking { bot.queryGroupList() }.asStream()
|
||||
|
||||
@UseExperimental(MiraiInternalAPI::class)
|
||||
override fun getGroupList(): List<BlockingGroup> = bot.groups.delegate.toList().map { it.blocking() }
|
||||
|
||||
override fun queryGroupInfo(code: Long): GroupInfo = runBlocking { bot.queryGroupInfo(code) }
|
||||
|
||||
override fun getGroup(id: Long): BlockingGroup = runBlocking { bot.getGroup(id).blocking() }
|
||||
override fun getNetwork(): BotNetworkHandler = bot.network
|
||||
override fun login() = runBlocking { bot.login() }
|
||||
override fun downloadAsByteArray(image: Image): ByteArray = bot.run { runBlocking { image.download().readBytes() } }
|
||||
override fun download(image: Image): ByteReadPacket = bot.run { runBlocking { image.download() } }
|
||||
override fun download(image: Image, outputStream: OutputStream) = bot.run { runBlocking { image.downloadTo(outputStream) } }
|
||||
|
||||
override fun addFriend(id: Long, message: String?, remark: String?): AddFriendResult = runBlocking { bot.addFriend(id, message, remark) }
|
||||
override fun approveFriendAddRequest(id: Long, remark: String?) = runBlocking { bot.approveFriendAddRequest(id, remark) }
|
||||
override fun dispose(throwable: Throwable?) = bot.close(throwable)
|
||||
|
@ -1,14 +0,0 @@
|
||||
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())
|
||||
}
|
||||
}
|
@ -21,6 +21,8 @@ pluginManagement {
|
||||
|
||||
rootProject.name = 'mirai'
|
||||
|
||||
include(':mirai-demos')
|
||||
|
||||
try {
|
||||
def keyProps = new Properties()
|
||||
def keyFile = file("local.properties")
|
||||
@ -46,7 +48,7 @@ include(':mirai-console')
|
||||
include(':mirai-api-http')
|
||||
include(':mirai-demos:mirai-demo-1')
|
||||
include(':mirai-demos:mirai-demo-gentleman')
|
||||
include(':mirai-demos')
|
||||
include(':mirai-demos:mirai-demo-java')
|
||||
include(':mirai-plugins')
|
||||
include(':mirai-plugins:image-sender')
|
||||
|
||||
@ -67,6 +69,7 @@ if (versionPos==-1){
|
||||
|
||||
project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1')
|
||||
project(':mirai-demos:mirai-demo-gentleman').projectDir = file('mirai-demos/mirai-demo-gentleman')
|
||||
project(':mirai-demos:mirai-demo-java').projectDir = file('mirai-demos/mirai-demo-java')
|
||||
project(':mirai-plugins:image-sender').projectDir = file('mirai-plugins/image-sender')
|
||||
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
Loading…
Reference in New Issue
Block a user