Commit 28e8c5d0 authored by jiahua.liu's avatar jiahua.liu

Merge remote-tracking branch 'origin/master'

parents 9e0251e6 3204f204
...@@ -101,13 +101,7 @@ class PluginDescription( ...@@ -101,13 +101,7 @@ class PluginDescription(
} }
} }
internal class PluginClassLoader(file: File, parent: ClassLoader) : URLClassLoader(arrayOf(file.toURI().toURL()), parent)
internal class PluginClassLoader(file: File, parent: ClassLoader) : URLClassLoader(arrayOf(file.toURI().toURL()), parent) {
override fun findClass(moduleName: String?, name: String?): Class<*> {
return super.findClass(name)
}
}
object PluginManager { object PluginManager {
internal val pluginsPath = System.getProperty("user.dir") + "/plugins/".replace("//", "/").also { internal val pluginsPath = System.getProperty("user.dir") + "/plugins/".replace("//", "/").also {
...@@ -136,7 +130,9 @@ object PluginManager { ...@@ -136,7 +130,9 @@ object PluginManager {
logger.info("plugin.yml not found in jar " + jar.name + ", it will not be consider as a Plugin") logger.info("plugin.yml not found in jar " + jar.name + ", it will not be consider as a Plugin")
} else { } else {
val description = val description =
PluginDescription.readFromContent(URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.readAllBytes().encodeToString()) PluginDescription.readFromContent(URL("jar:file:" + file.absoluteFile + "!/" + pluginYml.name).openConnection().inputStream.use {
it.readBytes().encodeToString()
})
println(description) println(description)
pluginsFound[description.name] = description pluginsFound[description.name] = description
pluginsLocation[description.name] = file pluginsLocation[description.name] = file
......
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
package net.mamoe.mirai package net.mamoe.mirai
import kotlinx.coroutines.* import kotlinx.coroutines.*
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotOfflineEvent
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.logStacktrace import net.mamoe.mirai.utils.io.logStacktrace
...@@ -41,6 +43,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -41,6 +43,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
fun instanceWhose(qq: Long): Bot { fun instanceWhose(qq: Long): Bot {
instances.forEach { instances.forEach {
@Suppress("PropertyName")
if (it.uin == qq) { if (it.uin == qq) {
return it return it
} }
...@@ -55,6 +58,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -55,6 +58,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
final override val network: N get() = _network final override val network: N get() = _network
@Suppress("PropertyName")
internal lateinit var _network: N internal lateinit var _network: N
final override suspend fun login() = reinitializeNetworkHandler(null) final override suspend fun login() = reinitializeNetworkHandler(null)
...@@ -86,6 +90,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor( ...@@ -86,6 +90,7 @@ abstract class BotImpl<N : BotNetworkHandler> constructor(
logger.info("Initializing BotNetworkHandler") logger.info("Initializing BotNetworkHandler")
try { try {
if (::_network.isInitialized) { if (::_network.isInitialized) {
BotOfflineEvent(this).broadcast()
_network.dispose(cause) _network.dispose(cause)
} }
} catch (e: Exception) { } catch (e: Exception) {
......
...@@ -15,4 +15,6 @@ abstract class BotEvent : Event { ...@@ -15,4 +15,6 @@ abstract class BotEvent : Event {
constructor() : super() constructor() : super()
} }
class BotLoginSucceedEvent(bot: Bot) : BotEvent(bot) class BotLoginSucceedEvent(bot: Bot) : BotEvent(bot)
\ No newline at end of file
class BotOfflineEvent(bot: Bot) : BotEvent(bot)
\ No newline at end of file
...@@ -86,19 +86,6 @@ interface Message { ...@@ -86,19 +86,6 @@ interface Message {
operator fun plus(another: String): MessageChain = this.followedBy(another.toString().toMessage()) operator fun plus(another: String): MessageChain = this.followedBy(another.toString().toMessage())
// `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)` // `+ ""` will be resolved to `plus(String)` instead of `plus(CharSeq)`
operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage()) operator fun plus(another: CharSequence): MessageChain = this.followedBy(another.toString().toMessage())
// do remove these primitive types, they can reduce boxing
operator fun plus(another: Int): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Double): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Long): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Short): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Byte): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Float): MessageChain = this.followedBy(another.toString().toMessage())
operator fun plus(another: Number): MessageChain = this.followedBy(another.toString().toMessage())
} }
/** /**
......
...@@ -5,4 +5,4 @@ import net.mamoe.mirai.data.LoginResult ...@@ -5,4 +5,4 @@ import net.mamoe.mirai.data.LoginResult
class LoginFailedException( class LoginFailedException(
val result: LoginResult, val result: LoginResult,
message: String = "Login failed with reason $result" message: String = "Login failed with reason $result"
) : Exception(message) ) : RuntimeException(message)
\ No newline at end of file \ No newline at end of file
...@@ -63,7 +63,7 @@ suspend fun main() { ...@@ -63,7 +63,7 @@ suspend fun main() {
* *
* @see MessageSubscribersBuilder * @see MessageSubscribersBuilder
*/ */
suspend fun Bot.messageDSL() { fun Bot.messageDSL() {
// 监听这个 bot 的来自所有群和好友的消息 // 监听这个 bot 的来自所有群和好友的消息
this.subscribeMessages { this.subscribeMessages {
// 当接收到消息 == "你好" 时就回复 "你好!" // 当接收到消息 == "你好" 时就回复 "你好!"
......
package net.mamoe.mirai.japt; package net.mamoe.mirai.japt;
import kotlinx.io.core.ByteReadPacket;
import net.mamoe.mirai.BotAccount;
import net.mamoe.mirai.data.AddFriendResult;
import net.mamoe.mirai.data.ImageLink;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.network.BotNetworkHandler;
import net.mamoe.mirai.utils.GroupNotFoundException;
import net.mamoe.mirai.utils.MiraiInternalAPI;
import net.mamoe.mirai.utils.MiraiLogger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@SuppressWarnings("unused")
public interface BlockingBot { public interface BlockingBot {
/**
* 账号信息
*/
@MiraiInternalAPI
@NotNull
BotAccount getAccount();
/**
* QQ 号码. 实际类型为 uint
*/
long getUin();
/**
* 日志记录器
*/
@NotNull
MiraiLogger getLogger();
// region contacts
/**
* 与这个机器人相关的 QQ 列表. 机器人与 QQ 不一定是好友
*/
@NotNull
List<BlockingQQ> getQQs();
/**
* 获取缓存的 QQ 对象. 若没有对应的缓存, 则会线程安全地创建一个.
*/
@NotNull
BlockingQQ getQQ(long id);
/**
* 与这个机器人相关的群列表. 机器人不一定是群成员.
*/
@NotNull
List<BlockingGroup> getGroups();
/**
* 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
* 若 {@code id} 无效, 将会抛出 {@link GroupNotFoundException}
*/
@NotNull
BlockingGroup getGroup(long id);
/**
* 获取缓存的群对象. 若没有对应的缓存, 则会线程安全地创建一个.
* 若 {@code internalId} 无效, 将会抛出 {@link GroupNotFoundException}
*/
@NotNull
BlockingGroup getGroupByInternalId(long internalId);
// endregion
// region network
/**
* 网络模块
*/
@NotNull
BotNetworkHandler getNetwork();
/**
* 登录.
* <p>
* 最终调用 [net.mamoe.mirai.network.BotNetworkHandler.login]
*
* @throws net.mamoe.mirai.utils.LoginFailedException
*/
@SuppressWarnings("JavaDoc")
void login();
// endregion
// region actions
@NotNull
ImageLink getLink(@NotNull Image image);
byte[] downloadAsByteArray(@NotNull Image image);
@NotNull
ByteReadPacket download(@NotNull Image image);
/**
* 添加一个好友
*
* @param message 若需要验证请求时的验证消息.
* @param remark 好友备注
*/
@NotNull
AddFriendResult addFriend(long id, @Nullable String message, @Nullable String remark);
/**
* 同意来自陌生人的加好友请求
*/
void approveFriendAddRequest(long id, @Nullable String remark);
// endregion
/**
* 关闭这个 [Bot], 停止一切相关活动. 不可重新登录.
*/
void dispose(@Nullable Throwable throwable);
} }
package net.mamoe.mirai.japt; package net.mamoe.mirai.japt;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.message.data.Message; import net.mamoe.mirai.message.data.Message;
import net.mamoe.mirai.message.data.MessageChain; import net.mamoe.mirai.message.data.MessageChain;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
...@@ -11,7 +10,7 @@ public interface BlockingContact { ...@@ -11,7 +10,7 @@ public interface BlockingContact {
* 这个联系人所属 [Bot] * 这个联系人所属 [Bot]
*/ */
@NotNull @NotNull
Bot getBot(); BlockingBot getBot();
/** /**
* 可以是 QQ 号码或者群号码 [GroupId]. * 可以是 QQ 号码或者群号码 [GroupId].
......
package net.mamoe.mirai.japt; package net.mamoe.mirai.japt;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.contact.Group; import net.mamoe.mirai.contact.Group;
import net.mamoe.mirai.contact.Member; import net.mamoe.mirai.contact.Member;
import net.mamoe.mirai.contact.QQ; import net.mamoe.mirai.contact.QQ;
...@@ -19,4 +20,8 @@ public final class BlockingContacts { ...@@ -19,4 +20,8 @@ public final class BlockingContacts {
public static BlockingMember createBlocking(Member member) { public static BlockingMember createBlocking(Member member) {
return new BlockingMemberImpl(member); return new BlockingMemberImpl(member);
} }
public static BlockingBot createBlocking(Bot bot) {
return new BlockingBotImpl(bot);
}
} }
package net.mamoe.mirai.japt; package net.mamoe.mirai.japt;
import net.mamoe.mirai.contact.Group;
import net.mamoe.mirai.data.GroupInfo; import net.mamoe.mirai.data.GroupInfo;
import org.jetbrains.annotations.NotNull;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface BlockingGroup extends BlockingContact { public interface BlockingGroup extends BlockingContact {
/** /**
* 内部 ID. 内部 ID 为 [GroupId] 的映射 * 内部 ID
*/ */
long getInternalId(); long getInternalId();
/** /**
* 群主 (同步事件更新) * 群主 (同步事件更新)
* 进行 [updateGroupInfo] 时将会更新这个值. * 进行 {@link #updateGroupInfo} 时将会更新这个值.
*/ */
@NotNull
BlockingMember getOwner(); BlockingMember getOwner();
/** /**
* 群名称 (同步事件更新) * 群名称 (同步事件更新)
* 进行 [updateGroupInfo] 时将会更新这个值. * 进行 {@link #updateGroupInfo} 时将会更新这个值.
*/ */
@NotNull
String getName(); String getName();
/** /**
* 入群公告, 没有时为空字符串. (同步事件更新) * 入群公告, 没有时为空字符串. (同步事件更新)
* 进行 [updateGroupInfo] 时将会更新这个值. * 进行 {@link #updateGroupInfo} 时将会更新这个值.
*/ */
@NotNull
String getAnnouncement(); String getAnnouncement();
/** /**
* 在 [Group] 实例创建的时候查询一次. 并与事件同步事件更新 * 在 {@link Group} 实例创建的时候查询一次. 并与事件同步事件更新
* <p> * <p>
* **注意**: 获得的列表仅为这一时刻的成员列表的镜像. 它将不会被更新 * **注意**: 获得的列表仅为这一时刻的成员列表的镜像. 它将不会被更新
*/ */
@NotNull
Map<Long, BlockingMember> getMembers(); Map<Long, BlockingMember> getMembers();
/** /**
* 获取群成员. 若此 ID 的成员不存在, 则会抛出 [kotlin.NoSuchElementException] * 获取群成员. 若此 ID 的成员不存在, 则会抛出 {@link NoSuchElementException}
*/ */
@NotNull
BlockingMember getMember(long id); BlockingMember getMember(long id);
/** /**
...@@ -46,6 +54,7 @@ public interface BlockingGroup extends BlockingContact { ...@@ -46,6 +54,7 @@ public interface BlockingGroup extends BlockingContact {
* *
* @return 这一时刻的群资料 * @return 这一时刻的群资料
*/ */
@NotNull
GroupInfo updateGroupInfo(); GroupInfo updateGroupInfo();
/** /**
...@@ -53,5 +62,6 @@ public interface BlockingGroup extends BlockingContact { ...@@ -53,5 +62,6 @@ public interface BlockingGroup extends BlockingContact {
*/ */
boolean quit(); boolean quit();
@NotNull
String toFullString(); String toFullString();
} }
\ No newline at end of file
package net.mamoe.mirai.japt; package net.mamoe.mirai.japt;
import net.mamoe.mirai.contact.MemberPermission; import net.mamoe.mirai.contact.MemberPermission;
import org.jetbrains.annotations.NotNull;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public interface BlockingMember { public interface BlockingMember {
/** /**
* 所在的群 * 所在的群
*/ */
@NotNull
BlockingGroup getGroup(); BlockingGroup getGroup();
/** /**
* 权限 * 权限
*/ */
@NotNull
MemberPermission getPermission(); MemberPermission getPermission();
/** /**
...@@ -20,7 +23,7 @@ public interface BlockingMember { ...@@ -20,7 +23,7 @@ public interface BlockingMember {
* @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常. * @param durationSeconds 持续时间. 精确到秒. 范围区间表示为 `(0s, 30days]`. 超过范围则会抛出异常.
* @return 若机器人无权限禁言这个群成员, 返回 `false` * @return 若机器人无权限禁言这个群成员, 返回 `false`
*/ */
Boolean mute(int durationSeconds); boolean mute(int durationSeconds);
/** /**
* 解除禁言 * 解除禁言
......
package net.mamoe.mirai.japt
import kotlinx.coroutines.runBlocking
import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.Bot
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.data.AddFriendResult
import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.toList
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() }
override fun getQQ(id: Long): BlockingQQ = bot.getQQ(id).blocking()
@UseExperimental(MiraiInternalAPI::class)
override fun getGroups(): List<BlockingGroup> = bot.groups.delegate.toList().map { it.blocking() }
override fun getGroup(id: Long): BlockingGroup = runBlocking { bot.getGroup(id).blocking() }
override fun getGroupByInternalId(internalId: Long): BlockingGroup = runBlocking { bot.getGroup(GroupInternalId(internalId)).blocking() }
override fun getNetwork(): BotNetworkHandler = bot.network
override fun login() = runBlocking { bot.login() }
override fun getLink(image: Image): ImageLink = bot.run { runBlocking { image.getLink() } }
override fun downloadAsByteArray(image: Image): ByteArray = bot.run { runBlocking { image.downloadAsByteArray() } }
override fun download(image: Image): ByteReadPacket = bot.run { runBlocking { image.download() } }
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.dispose(throwable)
}
\ No newline at end of file
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
package net.mamoe.mirai.japt package net.mamoe.mirai.japt
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.contact.QQ
inline fun Group.blocking(): BlockingGroup = BlockingContacts.createBlocking(this) inline fun Group.blocking(): BlockingGroup = BlockingContacts.createBlocking(this)
inline fun QQ.blocking(): BlockingQQ = BlockingContacts.createBlocking(this) inline fun QQ.blocking(): BlockingQQ = BlockingContacts.createBlocking(this)
inline fun Member.blocking(): BlockingMember = BlockingContacts.createBlocking(this) inline fun Member.blocking(): BlockingMember = BlockingContacts.createBlocking(this)
\ No newline at end of file inline fun Bot.blocking(): BlockingBot = BlockingContacts.createBlocking(this)
\ No newline at end of file
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
package net.mamoe.mirai.japt package net.mamoe.mirai.japt
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission import net.mamoe.mirai.contact.MemberPermission
...@@ -20,7 +19,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI ...@@ -20,7 +19,7 @@ import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.toList import net.mamoe.mirai.utils.toList
internal class BlockingQQImpl(private val delegate: QQ) : BlockingQQ { internal class BlockingQQImpl(private val delegate: QQ) : BlockingQQ {
override fun getBot(): Bot = delegate.bot override fun getBot(): BlockingBot = delegate.bot.blocking()
override fun getId(): Long = delegate.id override fun getId(): Long = delegate.id
override fun sendMessage(messages: MessageChain) = runBlocking { delegate.sendMessage(messages) } override fun sendMessage(messages: MessageChain) = runBlocking { delegate.sendMessage(messages) }
override fun sendMessage(message: String) = runBlocking { delegate.sendMessage(message.toMessage().toChain()) } override fun sendMessage(message: String) = runBlocking { delegate.sendMessage(message.toMessage().toChain()) }
...@@ -41,7 +40,7 @@ internal class BlockingGroupImpl(private val delegate: Group) : BlockingGroup { ...@@ -41,7 +40,7 @@ internal class BlockingGroupImpl(private val delegate: Group) : BlockingGroup {
override fun updateGroupInfo(): GroupInfo = runBlocking { delegate.updateGroupInfo() } override fun updateGroupInfo(): GroupInfo = runBlocking { delegate.updateGroupInfo() }
override fun toFullString(): String = delegate.toFullString() override fun toFullString(): String = delegate.toFullString()
override fun getMember(id: Long): BlockingMember = delegate.getMember(id).blocking() override fun getMember(id: Long): BlockingMember = delegate.getMember(id).blocking()
override fun getBot(): Bot = delegate.bot override fun getBot(): BlockingBot = delegate.bot.blocking()
override fun getAnnouncement(): String = delegate.announcement override fun getAnnouncement(): String = delegate.announcement
@UseExperimental(MiraiInternalAPI::class) @UseExperimental(MiraiInternalAPI::class)
override fun getMembers(): Map<Long, BlockingMember> = override fun getMembers(): Map<Long, BlockingMember> =
......
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