mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-29 09:10:11 +08:00
Merge branch 'dev' of https://github.com/mamoe/mirai into dev
This commit is contained in:
commit
410f371c74
@ -36,6 +36,10 @@ object Versions {
|
|||||||
const val bintray = "1.8.5"
|
const val bintray = "1.8.5"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Logging {
|
||||||
|
const val slf4j = "1.7.30"
|
||||||
|
const val log4j = "2.13.3"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
|
@ -8,33 +8,33 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.javatest;
|
package net.mamoe.mirai.javatest;
|
||||||
|
|
||||||
import kotlin.coroutines.CoroutineContext;
|
|
||||||
import kotlin.coroutines.EmptyCoroutineContext;
|
import kotlin.coroutines.EmptyCoroutineContext;
|
||||||
import kotlinx.coroutines.CoroutineScope;
|
import kotlinx.coroutines.CoroutineScope;
|
||||||
import kotlinx.coroutines.CoroutineScopeKt;
|
import kotlinx.coroutines.CoroutineScopeKt;
|
||||||
import net.mamoe.mirai.event.*;
|
import net.mamoe.mirai.event.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class SimpleListenerHostTest {
|
public class SimpleListenerHostTest {
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void testJavaSimpleListenerHostWork() {
|
||||||
|
AtomicBoolean called = new AtomicBoolean();
|
||||||
final SimpleListenerHost host = new SimpleListenerHost() {
|
final SimpleListenerHost host = new SimpleListenerHost() {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void testListen(
|
public void testListen(
|
||||||
AbstractEvent event
|
AbstractEvent event
|
||||||
) {
|
) {
|
||||||
System.out.println(event);
|
System.out.println(event);
|
||||||
}
|
called.set(true);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
|
|
||||||
exception.printStackTrace();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
CoroutineScope scope = CoroutineScopeKt.CoroutineScope(EmptyCoroutineContext.INSTANCE);
|
CoroutineScope scope = CoroutineScopeKt.CoroutineScope(EmptyCoroutineContext.INSTANCE);
|
||||||
Events.registerEvents(scope, host);
|
Events.registerEvents(scope, host);
|
||||||
EventKt.broadcast(new AbstractEvent() {
|
EventKt.broadcast(new AbstractEvent() {
|
||||||
});
|
});
|
||||||
|
if (!called.get()) {
|
||||||
|
throw new AssertionError("JavaTest: SimpleListenerHost Failed.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
|
|
||||||
package net.mamoe.mirai.qqandroid.contact
|
package net.mamoe.mirai.qqandroid.contact
|
||||||
|
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.io.core.Closeable
|
import kotlinx.io.core.Closeable
|
||||||
import net.mamoe.mirai.LowLevelAPI
|
import net.mamoe.mirai.LowLevelAPI
|
||||||
import net.mamoe.mirai.contact.*
|
import net.mamoe.mirai.contact.*
|
||||||
@ -33,9 +31,13 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
|
|||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.image.ImgStore
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.MessageSvcPbSendMsg
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToGroup
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.receive.createToGroup
|
||||||
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.voice.PttStore
|
||||||
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
|
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.ProfileService
|
||||||
|
import net.mamoe.mirai.qqandroid.utils.MiraiPlatformUtils
|
||||||
import net.mamoe.mirai.qqandroid.utils.estimateLength
|
import net.mamoe.mirai.qqandroid.utils.estimateLength
|
||||||
|
import net.mamoe.mirai.qqandroid.utils.toUHexString
|
||||||
import net.mamoe.mirai.utils.*
|
import net.mamoe.mirai.utils.*
|
||||||
|
import java.io.InputStream
|
||||||
import kotlin.contracts.contract
|
import kotlin.contracts.contract
|
||||||
import kotlin.coroutines.CoroutineContext
|
import kotlin.coroutines.CoroutineContext
|
||||||
import kotlin.jvm.JvmSynthetic
|
import kotlin.jvm.JvmSynthetic
|
||||||
@ -130,18 +132,18 @@ internal class GroupImpl(
|
|||||||
set(newValue) {
|
set(newValue) {
|
||||||
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
||||||
//if (_announcement != newValue) {
|
//if (_announcement != newValue) {
|
||||||
val oldValue = _announcement
|
val oldValue = _announcement
|
||||||
_announcement = newValue
|
_announcement = newValue
|
||||||
launch {
|
launch {
|
||||||
bot.network.run {
|
bot.network.run {
|
||||||
TroopManagement.GroupOperation.memo(
|
TroopManagement.GroupOperation.memo(
|
||||||
client = bot.client,
|
client = bot.client,
|
||||||
groupCode = id,
|
groupCode = id,
|
||||||
newMemo = newValue
|
newMemo = newValue
|
||||||
).sendWithoutExpect()
|
).sendWithoutExpect()
|
||||||
}
|
|
||||||
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
|
||||||
}
|
}
|
||||||
|
GroupEntranceAnnouncementChangeEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,18 +153,18 @@ internal class GroupImpl(
|
|||||||
set(newValue) {
|
set(newValue) {
|
||||||
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
||||||
//if (_allowMemberInvite != newValue) {
|
//if (_allowMemberInvite != newValue) {
|
||||||
val oldValue = _allowMemberInvite
|
val oldValue = _allowMemberInvite
|
||||||
_allowMemberInvite = newValue
|
_allowMemberInvite = newValue
|
||||||
launch {
|
launch {
|
||||||
bot.network.run {
|
bot.network.run {
|
||||||
TroopManagement.GroupOperation.allowMemberInvite(
|
TroopManagement.GroupOperation.allowMemberInvite(
|
||||||
client = bot.client,
|
client = bot.client,
|
||||||
groupCode = id,
|
groupCode = id,
|
||||||
switch = newValue
|
switch = newValue
|
||||||
).sendWithoutExpect()
|
).sendWithoutExpect()
|
||||||
}
|
|
||||||
GroupAllowMemberInviteEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
|
||||||
}
|
}
|
||||||
|
GroupAllowMemberInviteEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,18 +210,18 @@ internal class GroupImpl(
|
|||||||
set(newValue) {
|
set(newValue) {
|
||||||
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
checkBotPermission(MemberPermission.ADMINISTRATOR)
|
||||||
//if (_muteAll != newValue) {
|
//if (_muteAll != newValue) {
|
||||||
val oldValue = _muteAll
|
val oldValue = _muteAll
|
||||||
_muteAll = newValue
|
_muteAll = newValue
|
||||||
launch {
|
launch {
|
||||||
bot.network.run {
|
bot.network.run {
|
||||||
TroopManagement.GroupOperation.muteAll(
|
TroopManagement.GroupOperation.muteAll(
|
||||||
client = bot.client,
|
client = bot.client,
|
||||||
groupCode = id,
|
groupCode = id,
|
||||||
switch = newValue
|
switch = newValue
|
||||||
).sendWithoutExpect()
|
).sendWithoutExpect()
|
||||||
}
|
|
||||||
GroupMuteAllEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
|
||||||
}
|
}
|
||||||
|
GroupMuteAllEvent(oldValue, newValue, this@GroupImpl, null).broadcast()
|
||||||
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,5 +445,37 @@ internal class GroupImpl(
|
|||||||
(image.input as? Closeable)?.close()
|
(image.input as? Closeable)?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传一个语音消息以备发送.
|
||||||
|
* 请注意,这是一个实验性api且随时会被删除
|
||||||
|
* @throws EventCancelledException 当发送消息事件被取消
|
||||||
|
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||||
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
override suspend fun uploadGroupVoice(input: InputStream): Voice {
|
||||||
|
val content = ByteArray(input.available())
|
||||||
|
input.read(content)
|
||||||
|
if (content.size > 1048576) {
|
||||||
|
throw OverFileSizeMaxException()
|
||||||
|
}
|
||||||
|
val md5 = MiraiPlatformUtils.md5(content)
|
||||||
|
return bot.network.run {
|
||||||
|
val response: PttStore.GroupPttUp.Response.RequireUpload =
|
||||||
|
PttStore.GroupPttUp(bot.client, bot.id, 0L, md5, content.size.toLong()).sendAndExpect()
|
||||||
|
HighwayHelper.uploadPttToServers(
|
||||||
|
bot,
|
||||||
|
response.uploadIpList.zip(response.uploadPortList),
|
||||||
|
content,
|
||||||
|
md5,
|
||||||
|
response.uKey,
|
||||||
|
response.fileKey
|
||||||
|
)
|
||||||
|
Voice("${md5.toUHexString("")}.amr", md5, content.size.toLong(), "")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun toString(): String = "Group($id)"
|
override fun toString(): String = "Group($id)"
|
||||||
}
|
}
|
||||||
|
@ -413,9 +413,8 @@ internal class QQAndroidBotNetworkHandler(coroutineContext: CoroutineContext, bo
|
|||||||
logger.info { "Syncing friend message history..." }
|
logger.info { "Syncing friend message history..." }
|
||||||
withTimeoutOrNull(30000) {
|
withTimeoutOrNull(30000) {
|
||||||
launch(CoroutineName("Syncing friend message history")) { syncFromEvent<MessageSvcPbGetMsg.GetMsgSuccess, Unit> { Unit } }
|
launch(CoroutineName("Syncing friend message history")) { syncFromEvent<MessageSvcPbGetMsg.GetMsgSuccess, Unit> { Unit } }
|
||||||
// 别问我为什么要发两个 我也不知道 反正它能用
|
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null).sendAndExpect<Packet>()
|
||||||
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null, firstSync = true).sendAndExpect<Packet>()
|
|
||||||
MessageSvcPbGetMsg(bot.client, MsgSvc.SyncFlag.START, null, firstSync = true).sendAndExpect<Packet>()
|
|
||||||
} ?: error("timeout syncing friend message history")
|
} ?: error("timeout syncing friend message history")
|
||||||
logger.info { "Syncing friend message history: Success" }
|
logger.info { "Syncing friend message history: Success" }
|
||||||
}
|
}
|
||||||
|
@ -128,8 +128,6 @@ internal open class QQAndroidClient(
|
|||||||
|
|
||||||
lateinit var fileStoragePushFSSvcList: FileStoragePushFSSvcListFuckKotlin
|
lateinit var fileStoragePushFSSvcList: FileStoragePushFSSvcListFuckKotlin
|
||||||
|
|
||||||
internal val firstSyncPackets: AtomicInt = atomic(0) // 启动时候仅将所有好友信息设为已读的包
|
|
||||||
|
|
||||||
internal suspend inline fun useNextServers(crossinline block: suspend (host: String, port: Int) -> Unit) {
|
internal suspend inline fun useNextServers(crossinline block: suspend (host: String, port: Int) -> Unit) {
|
||||||
if (bot.client.serverList.isEmpty()) {
|
if (bot.client.serverList.isEmpty()) {
|
||||||
throw NoServerAvailableException(null)
|
throw NoServerAvailableException(null)
|
||||||
|
@ -61,14 +61,10 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
|||||||
client: QQAndroidClient,
|
client: QQAndroidClient,
|
||||||
syncFlag: MsgSvc.SyncFlag = MsgSvc.SyncFlag.START,
|
syncFlag: MsgSvc.SyncFlag = MsgSvc.SyncFlag.START,
|
||||||
syncCookie: ByteArray?, //PbPushMsg.msg.msgHead.msgTime
|
syncCookie: ByteArray?, //PbPushMsg.msg.msgHead.msgTime
|
||||||
firstSync: Boolean = false
|
|
||||||
): OutgoingPacket = buildOutgoingUniPacket(
|
): OutgoingPacket = buildOutgoingUniPacket(
|
||||||
client
|
client
|
||||||
) {
|
) {
|
||||||
//println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
|
//println("syncCookie=${client.c2cMessageSync.syncCookie?.toUHexString()}")
|
||||||
if (firstSync) {
|
|
||||||
client.firstSyncPackets.getAndAdd(1)
|
|
||||||
}
|
|
||||||
writeProtoBuf(
|
writeProtoBuf(
|
||||||
MsgSvc.PbGetMsgReq.serializer(),
|
MsgSvc.PbGetMsgReq.serializer(),
|
||||||
MsgSvc.PbGetMsgReq(
|
MsgSvc.PbGetMsgReq(
|
||||||
@ -150,10 +146,13 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
|||||||
|
|
||||||
val messages = resp.uinPairMsgs.asFlow()
|
val messages = resp.uinPairMsgs.asFlow()
|
||||||
.filterNot { it.msg == null }
|
.filterNot { it.msg == null }
|
||||||
.flatMapConcat { it.msg!!.asFlow() }
|
.flatMapConcat {
|
||||||
.also {
|
it.msg!!.asFlow()
|
||||||
MessageSvcPbDeleteMsg.delete(bot, it)
|
.filter { msg: MsgComm.Msg -> msg.msgHead.msgTime > it.lastReadTime.toLong() and 4294967295L }
|
||||||
} // 删除消息
|
}.also {
|
||||||
|
MessageSvcPbDeleteMsg.delete(bot, it) // 删除消息
|
||||||
|
// todo 实现一个锁来防止重复收到消息
|
||||||
|
}
|
||||||
.mapNotNull<MsgComm.Msg, Packet> { msg ->
|
.mapNotNull<MsgComm.Msg, Packet> { msg ->
|
||||||
|
|
||||||
suspend fun createGroupForBot(groupUin: Long): Group? {
|
suspend fun createGroupForBot(groupUin: Long): Group? {
|
||||||
@ -277,9 +276,6 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
166 -> {
|
166 -> {
|
||||||
if (bot.client.firstSyncPackets.value != 0) {
|
|
||||||
return@mapNotNull null
|
|
||||||
}
|
|
||||||
if (msg.msgHead.fromUin == bot.id) {
|
if (msg.msgHead.fromUin == bot.id) {
|
||||||
loop@ while (true) {
|
loop@ while (true) {
|
||||||
val instance = bot.client.getFriendSeq()
|
val instance = bot.client.getFriendSeq()
|
||||||
@ -383,9 +379,7 @@ internal object MessageSvcPbGetMsg : OutgoingPacketFactory<MessageSvcPbGetMsg.Re
|
|||||||
override suspend fun QQAndroidBot.handle(packet: Response) {
|
override suspend fun QQAndroidBot.handle(packet: Response) {
|
||||||
when (packet.syncFlagFromServer) {
|
when (packet.syncFlagFromServer) {
|
||||||
MsgSvc.SyncFlag.STOP -> {
|
MsgSvc.SyncFlag.STOP -> {
|
||||||
if (client.firstSyncPackets.value != 0) {
|
|
||||||
client.firstSyncPackets.getAndDecrement()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MsgSvc.SyncFlag.START -> {
|
MsgSvc.SyncFlag.START -> {
|
||||||
|
@ -37,9 +37,8 @@ internal class PttStore {
|
|||||||
uin: Long,
|
uin: Long,
|
||||||
groupCode: Long,
|
groupCode: Long,
|
||||||
md5: ByteArray,
|
md5: ByteArray,
|
||||||
size: Long = 0,
|
size: Long,
|
||||||
voiceLength: Int = 0,
|
codec: Int = 0
|
||||||
fileId: Long = 0
|
|
||||||
): OutgoingPacket {
|
): OutgoingPacket {
|
||||||
val pack = Cmd0x388.ReqBody(
|
val pack = Cmd0x388.ReqBody(
|
||||||
netType = 3, // wifi
|
netType = 3, // wifi
|
||||||
@ -48,7 +47,7 @@ internal class PttStore {
|
|||||||
Cmd0x388.TryUpPttReq(
|
Cmd0x388.TryUpPttReq(
|
||||||
srcUin = uin,
|
srcUin = uin,
|
||||||
groupCode = groupCode,
|
groupCode = groupCode,
|
||||||
fileId = fileId,
|
fileId = 0,
|
||||||
fileSize = size,
|
fileSize = size,
|
||||||
fileMd5 = md5,
|
fileMd5 = md5,
|
||||||
fileName = md5,
|
fileName = md5,
|
||||||
@ -57,8 +56,8 @@ internal class PttStore {
|
|||||||
buType = 4,
|
buType = 4,
|
||||||
innerIp = 0,
|
innerIp = 0,
|
||||||
buildVer = "6.5.5.663".encodeToByteArray(),
|
buildVer = "6.5.5.663".encodeToByteArray(),
|
||||||
voiceLength = voiceLength,
|
voiceLength = 1,
|
||||||
codec = 0,
|
codec = codec,
|
||||||
voiceType = 1,
|
voiceType = 1,
|
||||||
boolNewUpChan = true
|
boolNewUpChan = true
|
||||||
)
|
)
|
||||||
|
@ -108,6 +108,8 @@ kotlin {
|
|||||||
//api(kotlin("stdlib-jdk8"))
|
//api(kotlin("stdlib-jdk8"))
|
||||||
//api(kotlin("stdlib-jdk7"))
|
//api(kotlin("stdlib-jdk7"))
|
||||||
api(kotlin("reflect"))
|
api(kotlin("reflect"))
|
||||||
|
compileOnly("org.apache.logging.log4j:log4j-api:" + Versions.Logging.log4j)
|
||||||
|
compileOnly("org.slf4j:slf4j-api:" + Versions.Logging.slf4j)
|
||||||
|
|
||||||
api(ktor("client-core-jvm", Versions.Kotlin.ktor))
|
api(ktor("client-core-jvm", Versions.Kotlin.ktor))
|
||||||
implementation(kotlinx("io-jvm", Versions.Kotlin.io))
|
implementation(kotlinx("io-jvm", Versions.Kotlin.io))
|
||||||
|
@ -18,13 +18,11 @@ import net.mamoe.mirai.LowLevelAPI
|
|||||||
import net.mamoe.mirai.data.MemberInfo
|
import net.mamoe.mirai.data.MemberInfo
|
||||||
import net.mamoe.mirai.event.events.*
|
import net.mamoe.mirai.event.events.*
|
||||||
import net.mamoe.mirai.message.MessageReceipt
|
import net.mamoe.mirai.message.MessageReceipt
|
||||||
import net.mamoe.mirai.message.data.Image
|
import net.mamoe.mirai.message.data.*
|
||||||
import net.mamoe.mirai.message.data.Message
|
|
||||||
import net.mamoe.mirai.message.data.isContentEmpty
|
|
||||||
import net.mamoe.mirai.message.data.toMessage
|
|
||||||
import net.mamoe.mirai.message.recall
|
import net.mamoe.mirai.message.recall
|
||||||
import net.mamoe.mirai.utils.*
|
import net.mamoe.mirai.utils.*
|
||||||
import net.mamoe.mirai.utils.internal.runBlocking
|
import net.mamoe.mirai.utils.internal.runBlocking
|
||||||
|
import java.io.InputStream
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.jvm.JvmStatic
|
import kotlin.jvm.JvmStatic
|
||||||
import kotlin.jvm.JvmSynthetic
|
import kotlin.jvm.JvmSynthetic
|
||||||
@ -174,6 +172,19 @@ public abstract class Group : Contact(), CoroutineScope {
|
|||||||
@JvmSynthetic
|
@JvmSynthetic
|
||||||
public abstract override suspend fun uploadImage(image: ExternalImage): Image
|
public abstract override suspend fun uploadImage(image: ExternalImage): Image
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传一个语音消息以备发送.
|
||||||
|
* 请手动关闭输入流
|
||||||
|
* 请使用mar格式
|
||||||
|
* 请注意,这是一个实验性api且随时会被删除
|
||||||
|
* @throws EventCancelledException 当发送消息事件被取消
|
||||||
|
* @throws OverFileSizeMaxException 当图片文件过大而被服务器拒绝上传时. (最大大小约为 1 MB)
|
||||||
|
*/
|
||||||
|
@JvmSynthetic
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
public abstract suspend fun uploadGroupVoice(input: InputStream): Voice
|
||||||
|
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* 使用 groupCode 计算 groupUin. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.
|
* 使用 groupCode 计算 groupUin. 这两个值仅在 mirai 内部协议区分, 一般人使用时无需在意.
|
||||||
|
@ -159,8 +159,11 @@ public open class BotConfigurationBase internal constructor() {
|
|||||||
@MiraiExperimentalAPI
|
@MiraiExperimentalAPI
|
||||||
public var json: Json = kotlin.runCatching {
|
public var json: Json = kotlin.runCatching {
|
||||||
@OptIn(UnstableDefault::class)
|
@OptIn(UnstableDefault::class)
|
||||||
Json(JsonConfiguration(isLenient = true, ignoreUnknownKeys = true))
|
Json {
|
||||||
}.getOrElse { Json(JsonConfiguration.Stable) }
|
isLenient = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
}
|
||||||
|
}.getOrElse { Json {} }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 不显示网络日志. 不推荐.
|
* 不显示网络日志. 不推荐.
|
||||||
|
@ -161,11 +161,11 @@ internal fun Method.registerEvent(
|
|||||||
if (annotation.ignoreCancelled) {
|
if (annotation.ignoreCancelled) {
|
||||||
if ((this as? CancellableEvent)?.isCancelled != true) {
|
if ((this as? CancellableEvent)?.isCancelled != true) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
this@registerEvent.invoke(owner, this)
|
this@registerEvent.invoke(owner, this@subscribeAlways)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else withContext(Dispatchers.IO) {
|
} else withContext(Dispatchers.IO) {
|
||||||
this@registerEvent.invoke(owner, this)
|
this@registerEvent.invoke(owner, this@subscribeAlways)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -179,11 +179,11 @@ internal fun Method.registerEvent(
|
|||||||
if (annotation.ignoreCancelled) {
|
if (annotation.ignoreCancelled) {
|
||||||
if ((this as? CancellableEvent)?.isCancelled != true) {
|
if ((this as? CancellableEvent)?.isCancelled != true) {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
this@registerEvent.invoke(owner, this) as ListeningStatus
|
this@registerEvent.invoke(owner, this@subscribe) as ListeningStatus
|
||||||
}
|
}
|
||||||
} else ListeningStatus.LISTENING
|
} else ListeningStatus.LISTENING
|
||||||
} else withContext(Dispatchers.IO) {
|
} else withContext(Dispatchers.IO) {
|
||||||
this@registerEvent.invoke(owner, this) as ListeningStatus
|
this@registerEvent.invoke(owner, this@subscribe) as ListeningStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,12 @@
|
|||||||
package net.mamoe.mirai.message
|
package net.mamoe.mirai.message
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import kotlinx.io.core.Input
|
import kotlinx.io.core.Input
|
||||||
import net.mamoe.mirai.contact.Contact
|
import net.mamoe.mirai.contact.Contact
|
||||||
|
import net.mamoe.mirai.contact.Group
|
||||||
import net.mamoe.mirai.message.data.Image
|
import net.mamoe.mirai.message.data.Image
|
||||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
import net.mamoe.mirai.message.data.Voice
|
||||||
import net.mamoe.mirai.utils.sendTo
|
import net.mamoe.mirai.utils.*
|
||||||
import net.mamoe.mirai.utils.toExternalImage
|
|
||||||
import net.mamoe.mirai.utils.upload
|
|
||||||
import java.awt.image.BufferedImage
|
import java.awt.image.BufferedImage
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
@ -120,6 +118,19 @@ public suspend fun File.uploadAsImage(contact: Contact): Image {
|
|||||||
return toExternalImage().upload(contact)
|
return toExternalImage().upload(contact)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在 [Dispatchers.IO] 中将文件作为语音上传后构造 [Image]
|
||||||
|
* 请手动关闭输入流
|
||||||
|
* 请使用mar格式
|
||||||
|
* 注意,这只是个实验性功能且随时可能会删除
|
||||||
|
* @throws OverFileSizeMaxException
|
||||||
|
*/
|
||||||
|
@Throws(OverFileSizeMaxException::class)
|
||||||
|
@MiraiExperimentalAPI
|
||||||
|
public suspend fun InputStream.uploadAsGroupVoice(group: Group): Voice {
|
||||||
|
return group.uploadGroupVoice(this)
|
||||||
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Contact.sendImage(IMAGE)
|
// region Contact.sendImage(IMAGE)
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.utils
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.internal.logging.JdkLogger
|
||||||
|
import net.mamoe.mirai.utils.internal.logging.Log4jLogger
|
||||||
|
import net.mamoe.mirai.utils.internal.logging.Slf4jLogger
|
||||||
|
|
||||||
|
@SinceMirai("1.2.0")
|
||||||
|
public object LoggerAdapters {
|
||||||
|
@JvmStatic
|
||||||
|
public fun java.util.logging.Logger.asMiraiLogger(): MiraiLogger {
|
||||||
|
return JdkLogger(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
public fun org.apache.logging.log4j.Logger.asMiraiLogger(): MiraiLogger {
|
||||||
|
return Log4jLogger(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
public fun org.slf4j.Logger.asMiraiLogger(): MiraiLogger {
|
||||||
|
return Slf4jLogger(this)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.utils.internal.logging
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
|
||||||
|
import java.util.logging.Level
|
||||||
|
import java.util.logging.Logger
|
||||||
|
|
||||||
|
internal class JdkLogger(private val logger: Logger) : MiraiLoggerPlatformBase() {
|
||||||
|
override fun verbose0(message: String?, e: Throwable?) {
|
||||||
|
logger.log(Level.FINER, message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun debug0(message: String?, e: Throwable?) {
|
||||||
|
logger.log(Level.FINEST, message, e)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun info0(message: String?, e: Throwable?) {
|
||||||
|
logger.log(Level.INFO, message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun warning0(message: String?, e: Throwable?) {
|
||||||
|
logger.log(Level.WARNING, message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun error0(message: String?, e: Throwable?) {
|
||||||
|
logger.log(Level.SEVERE, message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val identity: String?
|
||||||
|
get() = logger.name
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.utils.internal.logging
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
|
||||||
|
import org.apache.logging.log4j.Logger
|
||||||
|
|
||||||
|
internal class Log4jLogger(private val logger: Logger) : MiraiLoggerPlatformBase() {
|
||||||
|
|
||||||
|
override fun verbose0(message: String?, e: Throwable?) {
|
||||||
|
logger.trace(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun debug0(message: String?, e: Throwable?) {
|
||||||
|
logger.debug(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun info0(message: String?, e: Throwable?) {
|
||||||
|
logger.info(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun warning0(message: String?, e: Throwable?) {
|
||||||
|
logger.warn(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun error0(message: String?, e: Throwable?) {
|
||||||
|
logger.error(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val identity: String?
|
||||||
|
get() = logger.name
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Mamoe Technologies and contributors.
|
||||||
|
*
|
||||||
|
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions 许可证的约束, 可以在以下链接找到该许可证.
|
||||||
|
* Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 with Mamoe Exceptions license that can be found via the following link.
|
||||||
|
*
|
||||||
|
* https://github.com/mamoe/mirai/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.mamoe.mirai.utils.internal.logging
|
||||||
|
|
||||||
|
import net.mamoe.mirai.utils.MiraiLoggerPlatformBase
|
||||||
|
import org.slf4j.Logger
|
||||||
|
|
||||||
|
internal class Slf4jLogger(private val logger: Logger) : MiraiLoggerPlatformBase() {
|
||||||
|
override fun verbose0(message: String?, e: Throwable?) {
|
||||||
|
logger.trace(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun debug0(message: String?, e: Throwable?) {
|
||||||
|
logger.debug(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun info0(message: String?, e: Throwable?) {
|
||||||
|
logger.info(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun warning0(message: String?, e: Throwable?) {
|
||||||
|
logger.warn(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun error0(message: String?, e: Throwable?) {
|
||||||
|
logger.error(message, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val identity: String?
|
||||||
|
get() = logger.name
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user