Explorar o código

Add GroupInfo

Him188 %!s(int64=6) %!d(string=hai) anos
pai
achega
d171073dc5

+ 1 - 1
gradle.properties

@@ -1,7 +1,7 @@
 # style guide
 kotlin.code.style=official
 # config
-mirai_version=0.1.7
+mirai_version=0.2.0
 kotlin.incremental.multiplatform=true
 kotlin.parallel.tasks.in.project=true
 # kotlin

+ 6 - 2
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Contact.kt

@@ -59,9 +59,13 @@ inline fun <R> Contact.withSession(block: BotSession.() -> R): R {
 /**
  * 只读联系人列表
  */
-class ContactList<C : Contact> internal constructor(private val delegate: MutableContactList<C>) : Map<UInt, C> by delegate
+class ContactList<C : Contact> internal constructor(private val delegate: MutableContactList<C>) : Map<UInt, C> by delegate {
+    override fun toString(): String = delegate.toString()
+}
 
 /**
  * 可修改联系人列表. 只会在内部使用.
  */
-internal class MutableContactList<C : Contact> : MutableMap<UInt, C> by mutableMapOf()
+internal class MutableContactList<C : Contact> : MutableMap<UInt, C> by mutableMapOf() {
+    override fun toString(): String = asIterable().joinToString(separator = ", ", prefix = "ContactList(", postfix = ")") { it.value.toString() }
+}

+ 8 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Group.kt

@@ -2,6 +2,7 @@
 
 package net.mamoe.mirai.contact
 
+import net.mamoe.mirai.network.protocol.tim.packet.action.GroupInfo
 import net.mamoe.mirai.utils.internal.PositiveNumbers
 import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
 
@@ -20,6 +21,11 @@ interface Group : Contact {
     val member: ContactList<Member>
 
     suspend fun getMember(id: UInt): Member
+
+    /**
+     * 查询群资料
+     */
+    suspend fun queryGroupInfo(): GroupInfo
 }
 
 /**
@@ -36,7 +42,8 @@ inline class GroupId(inline val value: UInt)
 /**
  * 将 [this] 转为 [GroupId].
  */
-fun UInt.groupId(): GroupId = GroupId(this)
+@Suppress("NOTHING_TO_INLINE")
+inline fun UInt.groupId(): GroupId = GroupId(this)
 
 /**
  * 将无符号整数格式的 [Long] 转为 [GroupId].

+ 5 - 0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/Member.kt

@@ -10,6 +10,11 @@ interface Member : QQ, Contact {
      * 所在的群
      */
     val group: Group
+
+    /**
+     * 权限
+     */
+    val permission: MemberPermission
 }
 
 /**

+ 13 - 6
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/contact/internal/ContactImpl.kt

@@ -5,8 +5,7 @@ package net.mamoe.mirai.contact.internal
 import kotlinx.coroutines.CompletableDeferred
 import kotlinx.coroutines.Deferred
 import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.sync.withLock
-import net.mamoe.mirai.*
+import net.mamoe.mirai.Bot
 import net.mamoe.mirai.contact.*
 import net.mamoe.mirai.contact.data.Profile
 import net.mamoe.mirai.message.Message
@@ -14,8 +13,12 @@ import net.mamoe.mirai.message.MessageChain
 import net.mamoe.mirai.message.chain
 import net.mamoe.mirai.message.singleChain
 import net.mamoe.mirai.network.protocol.tim.packet.action.*
+import net.mamoe.mirai.network.qqAccount
 import net.mamoe.mirai.network.sessionKey
+import net.mamoe.mirai.qqAccount
+import net.mamoe.mirai.sendPacket
 import net.mamoe.mirai.utils.SuspendLazy
+import net.mamoe.mirai.withSession
 
 internal sealed class ContactImpl : Contact {
     abstract override suspend fun sendMessage(message: MessageChain)
@@ -37,14 +40,18 @@ internal data class GroupImpl internal constructor(override val bot: Bot, val gr
 
     override suspend fun getMember(id: UInt): Member =
         if (_members.containsKey(id)) _members[id]!!
-        else membersLock.withLock {
+        else throw NoSuchElementException("No such member whose id is $id in group $id") /*membersLock.withLock {
             _members.getOrPut(id) { MemberImpl(bot.getQQ(id), this) }
-        }
+        }*/
 
     override suspend fun sendMessage(message: MessageChain) {
         bot.sendPacket(GroupPacket.Message(bot.qqAccount, internalId, bot.sessionKey, message))
     }
 
+    override suspend fun queryGroupInfo(): GroupInfo = bot.withSession {
+        GroupPacket.QueryGroupInfo(qqAccount, internalId, sessionKey).sendAndExpect()
+    }
+
     override fun toString(): String = "Group(${this.id})"
 }
 
@@ -74,6 +81,6 @@ internal data class QQImpl internal constructor(override val bot: Bot, override
 /**
  * 群成员
  */
-internal data class MemberImpl(private val delegate: QQ, override val group: Group) : QQ by delegate, Member {
-    override fun toString(): String = "Member(${this.id})"
+internal data class MemberImpl(private val delegate: QQ, override val group: Group, override val permission: MemberPermission) : QQ by delegate, Member {
+    override fun toString(): String = "Member(id=${this.id}, permission=$permission)"
 }

+ 2 - 0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/PacketId.kt

@@ -81,6 +81,8 @@ enum class KnownPacketId(override inline val value: UShort, override inline val
     inline REQUEST_PROFILE_DETAILS(0x003Cu, RequestProfileDetailsPacket),
 
     inline QUERY_PREVIOUS_NAME(0x01BCu, QueryPreviousNamePacket),
+
+    inline QUERY_FRIEND_REMARK(0x003Eu, QueryFriendRemarkPacket)
     // 031F  查询 "新朋友" 记录
 
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 5 - 10
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/action/GroupPacket.kt


+ 6 - 0
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/network/protocol/tim/packet/event/Unknown.kt

@@ -18,6 +18,12 @@ data class UnknownEventPacket(
     override fun toString(): String = "UnknownEventPacket(id=${id.toUHexString()}, identity=$identity)\n = ${body.readBytes().toUHexString()}"
 }
 
+/*
+被好友拉入群 (已经进入)
+Mirai 21:54:15 : Packet received: UnknownEventPacket(id=00 57, identity=(920503456->1994701021))
+ = 00 00 00 08 00 0A 00 04 01 00 00 00 36 DD C4 A0 01 04 00 00 00 00 3E 03 3F A2 00 00 20 E5 96 01 BC 23 AE 03 C7 B8 9F BE B3 E5 E4 77 A9 0E FD 2B 7C 64 8B C0 5F 29 8B D7 DC 85 7E 44 7B 00 30 33 65 62 61 62 31 31 66 63 63 61 34 63 38 39 31 36 31 33 37 37 65 65 62 36 63 32 39 37 31 33 34 32 35 62 64 30 34 66 62 31 61 31 65 37 31 63 33
+ */
+
 //TODO This class should be declared with `inline`, but a CompilationException will be thrown
 class UnknownEventParserAndHandler(override val id: UShort) : EventParserAndHandler<UnknownEventPacket> {
 

+ 19 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/InputUtils.kt

@@ -7,6 +7,19 @@ import kotlinx.io.pool.useInstance
 import kotlin.jvm.JvmName
 import kotlin.jvm.JvmSynthetic
 
+@Suppress("NOTHING_TO_INLINE")
+inline fun Input.discardExact(n: Short) = this.discardExact(n.toInt())
+
+@Suppress("NOTHING_TO_INLINE")
+@JvmSynthetic
+inline fun Input.discardExact(n: UShort) = this.discardExact(n.toInt())
+
+@Suppress("NOTHING_TO_INLINE")
+@JvmSynthetic
+inline fun Input.discardExact(n: UByte) = this.discardExact(n.toInt())
+
+@Suppress("NOTHING_TO_INLINE")
+inline fun Input.discardExact(n: Byte) = this.discardExact(n.toInt())
 
 fun ByteReadPacket.readRemainingBytes(
     n: Int = remaining.toInt()//not that safe but adequate
@@ -30,13 +43,17 @@ fun Input.readPacket(length: Int): ByteReadPacket = this.readBytes(length).toRea
 
 fun Input.readUVarIntLVString(): String = String(this.readUVarIntByteArray())
 
+fun Input.readUByteLVString(): String = String(this.readUByteLVByteArray())
+
 fun Input.readUShortLVString(): String = String(this.readUShortLVByteArray())
 
 fun Input.readUVarIntByteArray(): ByteArray = this.readBytes(this.readUVarInt().toInt())
 
+fun Input.readUByteLVByteArray(): ByteArray = this.readBytes(this.readUByte().toInt())
+
 fun Input.readUShortLVByteArray(): ByteArray = this.readBytes(this.readUShort().toInt())
 
-private inline fun <R> inline(block: () -> R): R = block()
+internal inline fun <R> inline(block: () -> R): R = block()
 
 @Suppress("DuplicatedCode")
 fun Input.readTLVMap(expectingEOF: Boolean = false, tagSize: Int = 1): MutableMap<UInt, ByteArray> {
@@ -138,6 +155,7 @@ fun Input.readString(length: Long): String = String(this.readBytes(length.toInt(
 fun Input.readString(length: Short): String = String(this.readBytes(length.toInt()))
 @JvmSynthetic
 fun Input.readString(length: UShort): String = String(this.readBytes(length.toInt()))
+
 fun Input.readString(length: Byte): String = String(this.readBytes(length.toInt()))
 
 @JvmSynthetic

+ 5 - 1
mirai-core/src/commonMain/kotlin/net.mamoe.mirai/utils/io/OutputUtils.kt

@@ -16,7 +16,11 @@ import net.mamoe.mirai.utils.internal.coerceAtMostOrFail
 import kotlin.random.Random
 import kotlin.random.nextInt
 
-fun BytePacketBuilder.writeZero(count: Int) = repeat(count) { this.writeByte(0) }
+fun BytePacketBuilder.writeZero(count: Int) {
+    require(count != 0) { "Trying to write zero with count 0, you made a mistake?" }
+    require(count > 0) { "writeZero: count must > 0" }
+    repeat(count) { this.writeByte(0) }
+}
 
 fun BytePacketBuilder.writeRandom(length: Int) = repeat(length) { this.writeByte(Random.Default.nextInt(255).toByte()) }
 

+ 21 - 0
mirai-debug/src/main/kotlin/HexDebuggerGui.kt

@@ -7,7 +7,9 @@ import javafx.scene.layout.Region
 import javafx.scene.paint.Color
 import javafx.scene.text.FontWeight
 import kotlinx.coroutines.*
+import kotlinx.io.core.readUByte
 import kotlinx.io.core.readUInt
+import kotlinx.io.core.readUShort
 import net.mamoe.mirai.utils.io.encodeToString
 import net.mamoe.mirai.utils.io.hexToBytes
 import net.mamoe.mirai.utils.io.read
@@ -77,6 +79,7 @@ class HexDebuggerGui : View("s") {
     private lateinit var outShort: TextField
     private lateinit var outUInt: TextField
     private lateinit var outString: TextArea
+    private lateinit var outBits: TextField
 
 
     private val clip = Toolkit.getDefaultToolkit().systemClipboard
@@ -151,6 +154,18 @@ class HexDebuggerGui : View("s") {
             value.hexToBytes().size.toString()
         }
 
+        outBits.text = runOrNull {
+            value.hexToBytes().read {
+                when (remaining.toInt()) {
+                    0 -> null
+                    1 -> readUByte().toString(2)
+                    2 -> readUShort().toString(2)
+                    4 -> readUInt().toString(2)
+                    else -> ""
+                }
+            }
+        }
+
         outString.text = runOrNull {
             value.hexToBytes().encodeToString()
         }
@@ -201,6 +216,7 @@ class HexDebuggerGui : View("s") {
             label("UVarInt")
             label("short")
             label("uint")
+            label("bits")
             label("string")
             children.filterIsInstance<Region>().forEach {
                 it.fitToParentWidth()
@@ -230,6 +246,11 @@ class HexDebuggerGui : View("s") {
                 isEditable = false
             }
 
+            outBits = textfield {
+                promptText = "Bits"
+                isEditable = false
+            }
+
             outString = textarea {
                 promptText = "String"
                 isEditable = false

+ 1 - 1
mirai-debug/src/main/kotlin/PacketDebuger.kt

@@ -116,7 +116,7 @@ object PacketDebugger {
      * 7. 运行完 `mov eax,dword ptr ss:[ebp+10]`
      * 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey`
      */
-    val sessionKey: SessionKey = SessionKey("43 EA BD 3C FF 6A 07 8E E4 13 E9 42 7F AD 03 F1".hexToBytes())
+    val sessionKey: SessionKey = SessionKey("10 52 CD 27 0B A5 9C 74 1B A2 15 7E 41 19 0C 7B".hexToBytes())
     const val qq: UInt = 761025446u
 
     val IgnoredPacketIdList: List<PacketId> = listOf(

+ 17 - 0
mirai-debug/src/main/kotlin/test/PacketTest.kt

@@ -0,0 +1,17 @@
+@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS")
+
+package test
+
+import DebugNetworkHandler
+import net.mamoe.mirai.network.protocol.tim.packet.UnknownPacketId
+import net.mamoe.mirai.network.protocol.tim.packet.action.GroupPacket.decode
+import net.mamoe.mirai.utils.io.hexToBytes
+import net.mamoe.mirai.utils.io.read
+
+suspend fun main() {
+
+    "00 00 00 03 01 41 00 04 01 00 23 04 40 1A F7 2F 11 02 00 00 00 00 00 00 00 00 00 21 00 C8 01 00 00 00 01 00 00 00 9E 1E 32 30 E7 A7 83 E9 A1 B6 32 38 E7 81 AB E8 91 AC 33 30 E9 87 8D E7 94 9F E5 BC 82 E4 B8 96 00 00 00 00 00 38 0D 3F 83 73 6A 9C F1 71 7C 10 DC CE F0 03 EA D9 FC 03 D5 87 E1 CD F5 F4 FA 63 37 26 07 17 9F 98 68 06 1A B6 4E 49 0A 14 DE B1 6B E1 32 99 30 29 AB 11 06 28 D9 0E 8A 3C 00 0A 00 00 00 00 06 00 03 00 02 00 01 00 04 00 04 00 00 00 01 00 05 00 04 5D BF EB 82 00 06 00 04 04 08 00 00 00 07 00 04 00 00 85 84 00 09 00 01 01 9F D6 4B F1 00 1A F7 2F 11 00 00 3E 03 3F A2 00 00 53 12 02 7F 00 00 76 E4 B8 DD 00 00 87 73 86 9D 00 00 87 CF 53 7B 00 00 8A 92 D8 1D 00 00 8C D9 1B 93 00 00 8E E0 1A 8A 00 01 9F D6 4B F1 00 00".hexToBytes()
+        .read {
+            decode(UnknownPacketId(0u), 0u, DebugNetworkHandler)
+        }
+}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 12
mirai-debug/src/main/kotlin/test/ProtoTest.kt


+ 7 - 0
mirai-demos/mirai-demo-gentleman/src/main/kotlin/demo/gentleman/Main.kt

@@ -64,6 +64,13 @@ suspend fun main() {
 
         "你好" reply "你好!"
 
+        "群资料" reply {
+            if (this is GroupMessage) {
+                group.queryGroupInfo().toString().reply()
+            }
+            ""
+        }
+
         startsWith("profile", removePrefix = true) {
             val account = it.trim()
             if (account.isNotEmpty()) {

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio