Commit 25b3b2b2 authored by Him188's avatar Him188

Japt

parent a5ef34b5
......@@ -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]中...")
}
}
......
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'
\ No newline at end of file
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>() {
......
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
@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()
@UseExperimental(MiraiInternalAPI::class)
override fun getQQs(): List<BlockingQQ> = bot.qqs.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()
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 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)
......
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')
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment