mirror of
https://github.com/mamoe/mirai.git
synced 2025-04-25 04:50:26 +08:00
Platform specified Contact
This commit is contained in:
parent
ad43a92be4
commit
93607e4999
README.md
mirai-core/src
commonMain/kotlin/net.mamoe.mirai
Bot.kt
contact
event/events
message/internal
network
jvmMain/kotlin/net/mamoe/mirai/contact
mirai-demos/mirai-demo-1/src/main/java/demo1
41
README.md
41
README.md
@ -1,12 +1,11 @@
|
||||
# Mirai
|
||||
[](http://hits.dwyl.io/him188/mamoe/mirai)
|
||||
|
||||
一个以 **TIM QQ协议(非web)** 驱动的QQ机器人服务端核心
|
||||
采用服务端-插件模式运行,同时提供独立的核心库
|
||||
一个以 **TIM PC协议(非web)** 驱动的跨平台QQ机器人服务端核心, 虽然目前仅支持 JVM
|
||||
采用服务端-插件模式运行,同时提供独立的跨平台核心库.
|
||||
Mirai 的所有模块均开源
|
||||
|
||||
项目处于开发阶段,学生无法每日大量更新。
|
||||
项目还有很多未完善的地方, 欢迎任何的代码贡献, 或是 issue.
|
||||
项目处于开发阶段, 还有很多未完善的地方. 欢迎任何的代码贡献, 或是 issue.
|
||||
部分协议来自网络上开源项目
|
||||
**一切开发旨在学习,请勿用于非法用途**
|
||||
|
||||
@ -22,7 +21,8 @@ Mirai 的所有模块均开源
|
||||
3. Run demo main [Demo 1 Main](mirai-demos/mirai-demo-1/src/main/java/demo1/Main.kt#L22)
|
||||
|
||||
### 事件
|
||||
#### Kotlin
|
||||
|
||||
#### 使用 Kotlin
|
||||
这里只演示进行不终止地监听。
|
||||
##### Top-level reified
|
||||
多数情况下这是最好的方式。
|
||||
@ -35,7 +35,7 @@ subscribeAlways<FriendMessageEvent>{
|
||||
```
|
||||
|
||||
##### DSL
|
||||
查看更多: [ListenerBuilder](mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/event/Subscribers.kt#L69)
|
||||
查看更多: [ListenerBuilder](mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt#L87)
|
||||
```kotlin
|
||||
inline fun <reified E: Event> subscribeAll(builder: ListenerBuilder.() -> Unit)
|
||||
|
||||
@ -66,38 +66,25 @@ FriendMessageEvent::class.subscribeAlways{
|
||||

|
||||
|
||||
### 图片测试
|
||||
**现在可以接收图片消息**(并解析为消息链):
|
||||
现在可以接收图片消息(并解析为消息链):
|
||||

|
||||

|
||||
|
||||
发送图片已经完成,但我们还在开发上传图片至服务器。
|
||||
现在你可以通过发送一张图片给机器人账号,再让机器人账号发送这张图片。你可以查看 [Image.kt](mirai-core/src/jvmMain/kotlin/net/mamoe/mirai/message/Message.kt#L81)
|
||||
机器人可以转发图片消息.详情查看 [Image.kt](mirai-core/src/commonMain/kotlin/net.mamoe.mirai/message/Message.kt#L81)
|
||||
|
||||
# TODO
|
||||
- [x] 事件(Event)模块
|
||||
- [ ] 插件(Plugin)模块
|
||||
- [x] Network - Touch
|
||||
- [X] Network - Login
|
||||
- [X] Network - Session
|
||||
- [X] Network - Verification Code
|
||||
- [X] Network - Message Receiving
|
||||
- [X] Network - Message Sending
|
||||
- [ ] Network - Events
|
||||
- [ ] Bot - Friend/group list
|
||||
- [ ] Bot - Actions(joining group, adding friend, etc.)
|
||||
- [x] Message Section
|
||||
- [ ] Image uploading
|
||||
- [ ] Contact
|
||||
- [ ] UI
|
||||
- [ ] Console
|
||||
# 现已支持
|
||||
- 发送好友/群消息(2019/10/14)
|
||||
- 接收好友/群消息, 消息链解析(2019/10/14)
|
||||
- 好友在线状态改变(2019/10/14)
|
||||
|
||||
<br>
|
||||
|
||||
# 使用方法
|
||||
## 要求
|
||||
- Kotlin 1.3+
|
||||
### JVM
|
||||
- Java 11
|
||||
### 用于 JVM 平台
|
||||
- Java 8
|
||||
## 插件开发
|
||||
``` text
|
||||
to be continued
|
||||
|
@ -5,6 +5,7 @@ import kotlinx.coroutines.sync.Mutex
|
||||
import net.mamoe.mirai.Bot.ContactSystem
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.QQ
|
||||
import net.mamoe.mirai.contact.groupIdToNumber
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.TIMBotNetworkHandler
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.LoginResult
|
||||
|
@ -7,15 +7,11 @@ import net.mamoe.mirai.message.PlainText
|
||||
import net.mamoe.mirai.message.toChain
|
||||
|
||||
/**
|
||||
* 联系人.
|
||||
* 联系人平台基础. 包含所有平台通用的函数等.
|
||||
*
|
||||
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
|
||||
*
|
||||
* @param bot the Owner [Bot]
|
||||
* @param number the id number of this contact
|
||||
* @author Him188moe
|
||||
*/
|
||||
abstract class Contact internal constructor(val bot: Bot, val number: Long) {
|
||||
abstract class PlatformContactBase internal constructor(val bot: Bot, val number: Long) {
|
||||
|
||||
abstract suspend fun sendMessage(message: MessageChain)
|
||||
|
||||
@ -26,13 +22,15 @@ abstract class Contact internal constructor(val bot: Bot, val number: Long) {
|
||||
return sendMessage(message.toChain())
|
||||
}
|
||||
|
||||
suspend fun sendMessage(plain: String) {
|
||||
this.sendMessage(PlainText(plain))
|
||||
}
|
||||
suspend fun sendMessage(plain: String) = this.sendMessage(PlainText(plain))
|
||||
|
||||
suspend fun sendMessage(message: List<Message>) {
|
||||
this.sendMessage(MessageChain(message))
|
||||
}
|
||||
|
||||
abstract suspend fun sendXMLMessage(message: String)
|
||||
}
|
||||
|
||||
/**
|
||||
* 所有的 [QQ], [Group] 都继承自这个类.
|
||||
* 在不同平台可能有不同的实现.
|
||||
* 如在 JVM, suspend 调用不便, [Contact] 中有简化调用的 `blocking`() 和 `async`
|
||||
*/
|
||||
expect sealed class Contact(bot: Bot, number: Long) : PlatformContactBase
|
@ -1,11 +1,8 @@
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.Group.Companion.groupNumberToId
|
||||
import net.mamoe.mirai.message.MessageChain
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
|
||||
import net.mamoe.mirai.utils.ContactList
|
||||
import kotlin.jvm.JvmStatic
|
||||
|
||||
/**
|
||||
* 群.
|
||||
@ -14,125 +11,110 @@ import kotlin.jvm.JvmStatic
|
||||
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
|
||||
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
|
||||
*
|
||||
* Java 获取 groupNumber: `group.getNumber()`
|
||||
* Java 获取所属 bot: `group.getBot()`
|
||||
* Java 获取群成员列表: `group.getMembers()`
|
||||
* Java 获取 groupId: `group.getGroupId()`
|
||||
*
|
||||
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
|
||||
* @author Him188moe
|
||||
*/
|
||||
class Group(bot: Bot, number: Long) : Contact(bot, number) {
|
||||
val groupId = groupNumberToId(number)
|
||||
expect class Group(bot: Bot, number: Long) : Contact {
|
||||
val groupId: Long
|
||||
val members: ContactList<QQ>
|
||||
//todo members
|
||||
get() = throw UnsupportedOperationException("Not yet supported")
|
||||
|
||||
override suspend fun sendMessage(message: MessageChain) {
|
||||
bot.network[EventPacketHandler].sendGroupMessage(this, message)
|
||||
override suspend fun sendMessage(message: MessageChain)
|
||||
override suspend fun sendXMLMessage(message: String)
|
||||
|
||||
companion object
|
||||
}
|
||||
|
||||
fun Group.Companion.groupNumberToId(number: Long): Long {//求你别出错
|
||||
val left: Long = number.toString().let {
|
||||
if (it.length < 6) {
|
||||
return@groupNumberToId number
|
||||
}
|
||||
it.substring(0, it.length - 6).toLong()
|
||||
}
|
||||
val right: Long = number.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
|
||||
override suspend fun sendXMLMessage(message: String) {
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun groupNumberToId(number: Long): Long {//求你别出错
|
||||
val left: Long = number.toString().let {
|
||||
if (it.length < 6) {
|
||||
return@groupNumberToId number
|
||||
}
|
||||
it.substring(0, it.length - 6).toLong()
|
||||
}
|
||||
val right: Long = number.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
|
||||
return when (left) {
|
||||
in 1..10 -> {
|
||||
((left + 202).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 11..19 -> {
|
||||
((left + 469).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 20..66 -> {
|
||||
((left + 208).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 67..156 -> {
|
||||
((left + 1943).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 157..209 -> {
|
||||
((left + 199).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 210..309 -> {
|
||||
((left + 389).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 310..499 -> {
|
||||
((left + 349).toString() + right.toString()).toLong()
|
||||
}
|
||||
else -> number
|
||||
}
|
||||
return when (left) {
|
||||
in 1..10 -> {
|
||||
((left + 202).toString() + right.toString()).toLong()
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun groupIdToNumber(id: Long): Long {//求你别出错
|
||||
var left: Long = id.toString().let {
|
||||
if (it.length < 6) {
|
||||
return@groupIdToNumber id
|
||||
}
|
||||
it.substring(0 until it.length - 6).toLong()
|
||||
}
|
||||
|
||||
return when (left) {
|
||||
in 203..212 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 202).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 480..488 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 469).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2100..2146 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 208).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2010..2099 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 1943).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2147..2199 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 199).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 4100..4199 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 389).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 3800..3989 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 349).toString() + right.toString()).toLong()
|
||||
}
|
||||
else -> id
|
||||
}
|
||||
in 11..19 -> {
|
||||
((left + 469).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 20..66 -> {
|
||||
((left + 208).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 67..156 -> {
|
||||
((left + 1943).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 157..209 -> {
|
||||
((left + 199).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 210..309 -> {
|
||||
((left + 389).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 310..499 -> {
|
||||
((left + 349).toString() + right.toString()).toLong()
|
||||
}
|
||||
else -> number
|
||||
}
|
||||
}
|
||||
|
||||
fun Group.Companion.groupIdToNumber(id: Long): Long {//求你别出错
|
||||
var left: Long = id.toString().let {
|
||||
if (it.length < 6) {
|
||||
return@groupIdToNumber id
|
||||
}
|
||||
it.substring(0 until it.length - 6).toLong()
|
||||
}
|
||||
|
||||
return when (left) {
|
||||
in 203..212 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 202).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 480..488 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 469).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2100..2146 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 208).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2010..2099 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 6).toLong()
|
||||
}
|
||||
((left - 1943).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 2147..2199 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 199).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 4100..4199 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 389).toString() + right.toString()).toLong()
|
||||
}
|
||||
in 3800..3989 -> {
|
||||
val right: Long = id.toString().let {
|
||||
it.substring(it.length - 7).toLong()
|
||||
}
|
||||
left = left.toString().substring(0 until 3).toLong()
|
||||
((left - 349).toString() + right.toString()).toLong()
|
||||
}
|
||||
else -> id
|
||||
}
|
||||
}
|
@ -4,28 +4,20 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.message.At
|
||||
import net.mamoe.mirai.message.Message
|
||||
import net.mamoe.mirai.message.MessageChain
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
|
||||
|
||||
/**
|
||||
* QQ 账号.
|
||||
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
|
||||
*
|
||||
* Java 获取 qq 号: `qq.getNumber()`
|
||||
* Java 获取所属 bot: `qq.getBot()`
|
||||
*
|
||||
* A QQ instance helps you to receive event from or sendPacket event to.
|
||||
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
class QQ(bot: Bot, number: Long) : Contact(bot, number) {
|
||||
override suspend fun sendMessage(message: MessageChain) {
|
||||
bot.network[EventPacketHandler].sendFriendMessage(this, message)
|
||||
}
|
||||
expect class QQ(bot: Bot, number: Long) : Contact {
|
||||
override suspend fun sendMessage(message: MessageChain)
|
||||
|
||||
override suspend fun sendXMLMessage(message: String) {
|
||||
|
||||
}
|
||||
override suspend fun sendXMLMessage(message: String)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -18,7 +18,5 @@ class FriendMessageEvent(bot: Bot, sender: QQ, val message: MessageChain) : Frie
|
||||
|
||||
suspend inline fun reply(message: String) = sender.sendMessage(message)
|
||||
|
||||
suspend inline fun reply(message: List<Message>) = sender.sendMessage(message)
|
||||
|
||||
suspend inline fun reply(message: MessageChain) = sender.sendMessage(message)//shortcut
|
||||
}
|
@ -15,7 +15,5 @@ class GroupMessageEvent(bot: Bot, group: Group, val sender: QQ, val message: Mes
|
||||
|
||||
suspend inline fun reply(message: String) = group.sendMessage(message)
|
||||
|
||||
suspend inline fun reply(message: List<Message>) = group.sendMessage(message)
|
||||
|
||||
suspend inline fun reply(message: MessageChain) = group.sendMessage(message)
|
||||
}
|
@ -70,7 +70,10 @@ internal fun ByteReadPacket.readMessage(): Message? {
|
||||
|
||||
0x19 -> {//未知, 可能是长文本?
|
||||
//bot手机自己跟自己发消息会出这个
|
||||
//似乎手机发消息就会有这个?
|
||||
//sectionData: 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00
|
||||
// 01 00 1C AA 02 19 08 00 88 01 00 9A 01 11 78 00 C8 01 00 F0 01 00 F8 01 00 90 02 00 C8 02 00
|
||||
return null
|
||||
sectionData.readBytes().debugPrint("sectionData")
|
||||
return PlainText("[UNKNOWN(${this.readBytes().toUHexString()})]")
|
||||
println()
|
||||
|
@ -71,4 +71,9 @@ interface BotNetworkHandler<Socket : DataPacketSocket> : Closeable {
|
||||
override fun close() {
|
||||
NetworkScope.cancel("handler closed", HandlerClosedException())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [BotNetworkHandler] closed
|
||||
*/
|
||||
class HandlerClosedException : Exception()
|
@ -1,3 +1 @@
|
||||
package net.mamoe.mirai.network
|
||||
|
||||
class HandlerClosedException : Exception()
|
@ -70,6 +70,9 @@ class EventPacketHandler(session: LoginSession) : PacketHandler(session) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
is IgnoredServerEventPacket -> {
|
||||
|
||||
}
|
||||
else -> {
|
||||
//ignored
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import net.mamoe.mirai.utils.*
|
||||
|
||||
@PacketId("00 58")
|
||||
class ClientHeartbeatPacket(
|
||||
private val qq: Long,
|
||||
private val bot: Long,
|
||||
private val sessionKey: ByteArray
|
||||
) : ClientPacket() {
|
||||
override val idHex: String by lazy {
|
||||
@ -16,7 +16,7 @@ class ClientHeartbeatPacket(
|
||||
}
|
||||
|
||||
override fun encode(builder: BytePacketBuilder) = with(builder) {
|
||||
this.writeQQ(qq)
|
||||
this.writeQQ(bot)
|
||||
this.writeHex(TIMProtocol.fixVer)
|
||||
this.encryptAndWrite(sessionKey) {
|
||||
writeHex("00 01 00 01")
|
||||
|
@ -9,6 +9,9 @@ import net.mamoe.mirai.network.protocol.tim.TIMProtocol
|
||||
import net.mamoe.mirai.utils.*
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
/**
|
||||
* 事件的识别 ID. 在 [事件确认包][ServerEventPacket.ResponsePacket] 中被使用.
|
||||
*/
|
||||
data class EventPacketIdentity(
|
||||
val from: UInt,//对于好友消息, 这个是发送人
|
||||
val to: UInt,//对于好友消息, 这个是bot
|
||||
@ -37,8 +40,9 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
|
||||
to = readUInt(),
|
||||
uniqueId = readIoBuffer(8)
|
||||
)
|
||||
readBytes(2).takeIf { it[0].toUInt() != 0x1Fu && it[1].toUInt() != 0x40u }?.debugPrint("type前面2个byte")
|
||||
discardExact(2)
|
||||
val type = readBytes(2)
|
||||
//DebugLogger.logPurple("unknown2Byte+byte = ${unknown2Byte.toUHexString()} ${type.toUHexString()}")
|
||||
return when (type.toUHexString()) {
|
||||
"00 C4" -> {
|
||||
discardExact(13)
|
||||
@ -56,11 +60,17 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
|
||||
|
||||
|
||||
//00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 16 00 00 00 37 08 02 1A 12 08 95 02 10 90 04 40 98 E1 8C ED 05 48 AF 96 C3 A4 03 08 A2 FF 8C F0 03 10 DD F1 92 B7 07 1A 29 08 00 10 05 18 98 E1 8C ED 05 20 01 28 FF FF FF FF 0F 32 15 E5 AF B9 E6 96 B9 E6 AD A3 E5 9C A8 E8 BE 93 E5 85 A5 2E 2E 2E
|
||||
//00 00 00 08 00 0A 00 04 01 00 00 00 00 00 00 07 00 00 00
|
||||
"02 10" -> {
|
||||
discardExact(19)
|
||||
println(readUByte().toUInt())
|
||||
|
||||
//todo 错了. 可能是 00 79 才是.
|
||||
return@with ServerFriendTypingCanceledPacket(input, eventIdentity)
|
||||
if (readUByte().toUInt() == 0x37u) ServerFriendTypingStartedPacket(input, eventIdentity)
|
||||
else /*0x22*/ ServerFriendTypingCanceledPacket(input, eventIdentity)
|
||||
}
|
||||
"00 79" -> IgnoredServerEventPacket(type, input, eventIdentity)
|
||||
|
||||
//"02 10", "00 12" -> ServerUnknownEventPacket(input, eventIdentity)
|
||||
|
||||
@ -95,6 +105,12 @@ abstract class ServerEventPacket(input: ByteReadPacket, val eventIdentity: Event
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略的事件.
|
||||
* 如 00 79: 总是与 01 12 一起发生, 但 00 79 却没多大意义
|
||||
*/
|
||||
class IgnoredServerEventPacket(val eventId: ByteArray/*2*/, input: ByteReadPacket, eventIdentity: EventPacketIdentity) : ServerEventPacket(input, eventIdentity)
|
||||
|
||||
/**
|
||||
* Unknown event
|
||||
*/
|
||||
@ -121,7 +137,6 @@ class ServerFriendTypingStartedPacket(input: ByteReadPacket, eventIdentity: Even
|
||||
class ServerFriendTypingCanceledPacket(input: ByteReadPacket, eventIdentity: EventPacketIdentity) : ServerFriendTypingPacket(input, eventIdentity)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Android 客户端上线
|
||||
*/
|
||||
|
@ -0,0 +1,118 @@
|
||||
package net.mamoe.mirai.contact
|
||||
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.message.Message
|
||||
import net.mamoe.mirai.message.MessageChain
|
||||
import net.mamoe.mirai.network.protocol.tim.handler.EventPacketHandler
|
||||
import net.mamoe.mirai.utils.ContactList
|
||||
|
||||
/**
|
||||
* 联系人.
|
||||
*
|
||||
* A contact is a [QQ] or a [Group] for one particular [Bot] instance only.
|
||||
*
|
||||
* @param bot the Owner [Bot]
|
||||
* @param number the id number of this contact
|
||||
* @author Him188moe
|
||||
*/
|
||||
@Suppress("unused")
|
||||
actual sealed class Contact actual constructor(bot: Bot, number: Long) : PlatformContactBase(bot, number) {
|
||||
|
||||
abstract override suspend fun sendMessage(message: MessageChain)
|
||||
|
||||
abstract override suspend fun sendXMLMessage(message: String)
|
||||
|
||||
|
||||
/**
|
||||
* 阻塞发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun blockingSendMessage(chain: MessageChain) = runBlocking { sendMessage(chain) }
|
||||
|
||||
/**
|
||||
* 阻塞发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun blockingSendMessage(message: Message) = runBlocking { sendMessage(message) }
|
||||
|
||||
|
||||
/**
|
||||
* 阻塞发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun blockingSendMessage(plain: String) = runBlocking { sendMessage(plain) }
|
||||
|
||||
/**
|
||||
* 异步发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun asyncSendMessage(chain: MessageChain) {
|
||||
bot.network.NetworkScope.launch { sendMessage(chain) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun asyncSendMessage(message: Message) {
|
||||
bot.network.NetworkScope.launch { sendMessage(message) }
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步发送一个消息. 仅应在 Java 使用
|
||||
*/
|
||||
fun asyncSendMessage(plain: String) {
|
||||
bot.network.NetworkScope.launch { sendMessage(plain) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 群.
|
||||
*
|
||||
* Group ID 与 Group Number 并不是同一个值.
|
||||
* - Group Number([Group.number]) 是通常使用的群号码.(在 QQ 客户端中可见)
|
||||
* - Group ID([Group.groupId]) 是与服务器通讯时使用的 id.(在 QQ 客户端中不可见)
|
||||
*
|
||||
* Java 获取 groupNumber: `group.getNumber()`
|
||||
* Java 获取所属 bot: `group.getBot()`
|
||||
* Java 获取群成员列表: `group.getMembers()`
|
||||
* Java 获取 groupId: `group.getGroupId()`
|
||||
*
|
||||
* Java 调用 [groupNumberToId] : `Group.groupNumberToId(number)`
|
||||
* @author Him188moe
|
||||
*/
|
||||
actual class Group actual constructor(bot: Bot, number: Long) : Contact(bot, number) {
|
||||
actual val groupId = groupNumberToId(number)
|
||||
actual val members: ContactList<QQ>
|
||||
//todo members
|
||||
get() = throw UnsupportedOperationException("Not yet supported")
|
||||
|
||||
actual override suspend fun sendMessage(message: MessageChain) {
|
||||
bot.network[EventPacketHandler].sendGroupMessage(this, message)
|
||||
}
|
||||
|
||||
actual override suspend fun sendXMLMessage(message: String) {
|
||||
|
||||
}
|
||||
|
||||
actual companion object
|
||||
}
|
||||
|
||||
/**
|
||||
* QQ 账号.
|
||||
* 注意: 一个 [QQ] 实例并不是独立的, 它属于一个 [Bot].
|
||||
*
|
||||
* Java 获取 qq 号: `qq.getNumber()`
|
||||
* Java 获取所属 bot: `qq.getBot()`
|
||||
*
|
||||
* A QQ instance helps you to receive event from or sendPacket event to.
|
||||
* Notice that, one QQ instance belong to one [Bot], that is, QQ instances from different [Bot] are NOT the same.
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
actual class QQ actual constructor(bot: Bot, number: Long) : Contact(bot, number) {
|
||||
actual override suspend fun sendMessage(message: MessageChain) {
|
||||
bot.network[EventPacketHandler].sendFriendMessage(this, message)
|
||||
}
|
||||
|
||||
actual override suspend fun sendXMLMessage(message: String) {
|
||||
TODO()
|
||||
}
|
||||
}
|
@ -49,10 +49,7 @@ suspend fun main() {
|
||||
"复读" in it.message -> it.sender.sendMessage(it.message)
|
||||
|
||||
"发群" in it.message -> {
|
||||
it.message.list.toMutableList().let { messages ->
|
||||
messages.removeAt(0)
|
||||
Group(bot, 580266363).sendMessage(messages)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*it.event eq "发图片群" -> sendGroupMessage(Group(session.bot, 580266363), PlainText("test") + UnsolvedImage(File("C:\\Users\\Him18\\Desktop\\faceImage_1559564477775.jpg")).also { image ->
|
||||
|
Loading…
Reference in New Issue
Block a user