Переглянути джерело

Updated message&contact adding

Him188moe 6 роки тому
батько
коміт
fa6a9b66b2

+ 75 - 5
mirai-core/src/main/java/net/mamoe/mirai/network/RobotNetworkHandler.kt

@@ -17,9 +17,7 @@ import net.mamoe.mirai.message.Message
 import net.mamoe.mirai.message.defaults.MessageChain
 import net.mamoe.mirai.network.RobotNetworkHandler.*
 import net.mamoe.mirai.network.packet.*
-import net.mamoe.mirai.network.packet.action.ClientSendFriendMessagePacket
-import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
-import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
+import net.mamoe.mirai.network.packet.action.*
 import net.mamoe.mirai.network.packet.login.*
 import net.mamoe.mirai.task.MiraiThreadPool
 import net.mamoe.mirai.utils.*
@@ -31,6 +29,7 @@ import java.util.*
 import java.util.concurrent.CompletableFuture
 import java.util.concurrent.ScheduledFuture
 import java.util.concurrent.TimeUnit
+import java.util.function.Supplier
 import javax.imageio.ImageIO
 import kotlin.reflect.KClass
 
@@ -545,16 +544,87 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
             }
         internal var gtk: Int = 0
 
-        override fun onPacketReceived(packet: ServerPacket) {
+        private val addFriendSessions = Collections.synchronizedCollection(mutableListOf<AddFriendSession>())
 
+        override fun onPacketReceived(packet: ServerPacket) {
+            when (packet) {
+                is ServerCanAddFriendResponsePacket -> {
+                    this.addFriendSessions.forEach {
+                        it.onPacketReceived(packet)
+                    }
+                }
+                else -> {
+                }
+            }
         }
 
-        fun addFriend(qqNumber: Long): Unit {
+        fun addFriend(qqNumber: Long, message: Supplier<String>) {
+            addFriend(qqNumber, lazy { message.get() })
+        }
 
+        @JvmSynthetic
+        fun addFriend(qqNumber: Long, message: Lazy<String> = lazyOf("")): CompletableFuture<AddFriendResult> {
+            val future = CompletableFuture<AddFriendResult>()
+            val session = AddFriendSession(qqNumber, future, message)
+            addFriendSessions.add(session)
+            session.sendAddRequest();
+            return future
         }
 
         override fun close() {
 
         }
+
+        private inner class AddFriendSession(
+                private val qq: Long,
+                private val future: CompletableFuture<AddFriendResult>,
+                private val message: Lazy<String>
+        ) : Closeable {
+            lateinit var id: ByteArray
+
+            fun onPacketReceived(packet: ServerPacket) {
+                if (!::id.isInitialized) {
+                    return
+                }
+
+                when (packet) {
+                    is ServerCanAddFriendResponsePacket -> {
+                        if (!(packet.idByteArray[2] == id[0] && packet.idByteArray[3] == id[1])) {
+                            return
+                        }
+
+                        when (packet.state) {
+                            ServerCanAddFriendResponsePacket.State.FAILED -> {
+                                future.complete(AddFriendResult.FAILED)
+                                close()
+                            }
+
+                            ServerCanAddFriendResponsePacket.State.ALREADY_ADDED -> {
+                                future.complete(AddFriendResult.ALREADY_ADDED)
+                                close()
+                            }
+
+                            ServerCanAddFriendResponsePacket.State.REQUIRE_VERIFICATION -> {
+                                sendPacket(ClientAddFriendPacket(robot.account.qqNumber, qq, sessionKey))
+                            }
+
+                            ServerCanAddFriendResponsePacket.State.NOT_REQUIRE_VERIFICATION -> {
+
+                            }
+                        }
+                    }
+
+
+                }
+            }
+
+            fun sendAddRequest() {
+                sendPacket(ClientCanAddFriendPacket(robot.account.qqNumber, qq, sessionKey).also { this.id = it.packetIdLast })
+            }
+
+            override fun close() {
+                addFriendSessions.remove(this)
+            }
+        }
     }
 }

+ 0 - 1
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ClientPacket.kt

@@ -30,7 +30,6 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
         } catch (e: IOException) {
             throw RuntimeException(e)
         }
-
     }
 
     @Throws(IOException::class)

+ 0 - 4
mirai-core/src/main/java/net/mamoe/mirai/network/packet/GradeInfo.kt

@@ -26,10 +26,6 @@ class ClientAccountInfoRequestPacket(
             it.writeByte(0x00)
         }
     }
-
-    override fun getFixedId(): String {
-        return this.idHex + " ?? ??"
-    }
 }
 
 @PacketId("00 5C")

+ 0 - 4
mirai-core/src/main/java/net/mamoe/mirai/network/packet/Heartbeat.kt

@@ -22,10 +22,6 @@ class ClientHeartbeatPacket(
             it.writeHex("00 01 00 01")
         }
     }
-
-    override fun getFixedId(): String {
-        return this.idHex + " ?? ??"
-    }
 }
 
 class ServerHeartbeatResponsePacket(input: DataInputStream) : ServerPacket(input)

+ 0 - 4
mirai-core/src/main/java/net/mamoe/mirai/network/packet/SKey.kt

@@ -23,10 +23,6 @@ class ClientSKeyRequestPacket(
             it.writeHex("33 00 05 00 08 74 2E 71 71 2E 63 6F 6D 00 0A 71 75 6E 2E 71 71 2E 63 6F 6D 00 0C 71 7A 6F 6E 65 2E 71 71 2E 63 6F 6D 00 0C 6A 75 62 61 6F 2E 71 71 2E 63 6F 6D 00 09 6B 65 2E 71 71 2E 63 6F 6D")
         }
     }
-
-    override fun getFixedId(): String {
-        return this.idHex + " ?? ??"
-    }
 }
 
 /**

+ 12 - 2
mirai-core/src/main/java/net/mamoe/mirai/network/packet/ServerPacket.kt

@@ -1,7 +1,7 @@
 package net.mamoe.mirai.network.packet
 
-import lombok.Getter
 import net.mamoe.mirai.network.packet.PacketNameFormatter.adjustName
+import net.mamoe.mirai.network.packet.action.ServerCanAddFriendResponsePacket
 import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
 import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
 import net.mamoe.mirai.network.packet.login.*
@@ -12,9 +12,11 @@ import java.io.DataInputStream
  * @author Him188moe
  */
 abstract class ServerPacket(val input: DataInputStream) : Packet {
-    @Getter
     var idHex: String
 
+    var idByteArray: ByteArray//fixed 4 size
+
+
     var encoded: Boolean = false
 
     init {
@@ -24,6 +26,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
         } catch (e: NullPointerException) {
             ""
         }
+
+        idByteArray = if (idHex.isEmpty()) {
+            byteArrayOf(0, 0, 0, 0)
+        } else {
+            idHex.hexToBytes()
+        }
     }
 
     fun <P : ServerPacket> P.setId(idHex: String): P {
@@ -101,6 +109,8 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
                     "00 CD" -> ServerSendFriendMessageResponsePacket(stream)
                     "00 02" -> ServerSendGroupMessageResponsePacket(stream)
 
+                    "00 A7" -> ServerCanAddFriendResponsePacket(stream)
+
                     else -> throw IllegalArgumentException(idHex)
                 }
             }.apply { this.idHex = idHex }

+ 133 - 0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddContact.kt

@@ -0,0 +1,133 @@
+package net.mamoe.mirai.network.packet.action
+
+import net.mamoe.mirai.network.Protocol
+import net.mamoe.mirai.network.packet.*
+import net.mamoe.mirai.utils.getRandomByteArray
+import net.mamoe.mirai.utils.toUHexString
+import java.io.DataInputStream
+import java.util.*
+
+/**
+ * 向服务器检查是否可添加某人为好友
+ *
+ * @author Him188moe
+ */
+@PacketId("00 A7")
+@ExperimentalUnsignedTypes
+class ClientCanAddFriendPacket(
+        val robot: Long,
+        val qq: Long,
+        val sessionKey: ByteArray
+) : ClientPacket() {
+    val packetIdLast = getRandomByteArray(2)
+
+    override fun getFixedId(): String {
+        return idHex + " " + packetIdLast.toUHexString()
+    }
+
+    override fun encode() {
+        this.write(packetIdLast)//id, 2bytes
+
+        this.writeQQ(robot)
+        this.writeHex(Protocol.fixVer2)
+        this.encryptAndWrite(sessionKey) {
+            it.writeQQ(qq)
+        }
+    }
+}
+
+@PacketId("00 A7")
+class ServerCanAddFriendResponsePacket(input: DataInputStream) : ServerPacket(input) {
+    lateinit var state: State
+
+    enum class State {
+        ALREADY_ADDED,
+        REQUIRE_VERIFICATION,
+        NOT_REQUIRE_VERIFICATION,
+        FAILED,
+    }
+
+    @ExperimentalUnsignedTypes
+    override fun decode() {
+        val data = input.goto(0).readAllBytes()
+        if (data.size == 99) {
+            state = State.ALREADY_ADDED
+            return
+        }
+        state = when (data[data.size - 1].toUInt()) {
+            0u -> State.NOT_REQUIRE_VERIFICATION
+            1u -> State.REQUIRE_VERIFICATION
+            99u -> State.ALREADY_ADDED
+            3u, 4u -> State.FAILED
+            else -> throw IllegalArgumentException(Arrays.toString(data))
+        }
+    }
+
+
+    @PacketId("00 A7")
+    class Encrypted(inputStream: DataInputStream) : ServerPacket(inputStream) {
+        fun decrypt(sessionKey: ByteArray): ServerCanAddFriendResponsePacket {
+            return ServerCanAddFriendResponsePacket(this.decryptBy(sessionKey)).setId(this.idHex)
+        }
+    }
+}
+
+
+/**
+ * 请求添加好友
+ */
+@PacketId("00 AE")
+@ExperimentalUnsignedTypes
+class ClientAddFriendPacket(
+        val robot: Long,
+        val qq: Long,
+        val sessionKey: ByteArray
+) : ClientPacket() {
+    val packetIdLast = getRandomByteArray(2)
+
+    override fun getFixedId(): String {
+        return idHex + " " + packetIdLast.toUHexString()
+    }
+
+    override fun encode() {
+        this.write(packetIdLast)//id, 2bytes
+
+        this.writeQQ(robot)
+        this.writeHex(Protocol.fixVer2)
+        this.encryptAndWrite(sessionKey) {
+            it.writeHex("01 00 01")
+            it.writeQQ(qq)
+        }
+    }
+
+}
+
+
+class ServerAddFriendResponsePacket(input: DataInputStream) : ServerAddContactResponsePacket(input)
+
+class ServerAddGroupResponsePacket(input: DataInputStream) : ServerAddContactResponsePacket(input)
+
+/**
+ * 添加好友/群的回复
+ */
+open class ServerAddContactResponsePacket(input: DataInputStream) : ServerPacket(input) {
+
+
+    class Raw(input: DataInputStream) : ServerPacket(input) {
+
+        override fun decode() {
+
+        }
+
+        fun distribute(): ServerAddContactResponsePacket {
+
+            TODO()
+        }
+
+        class Encrypted(input: DataInputStream) : ServerPacket(input) {
+            fun decrypt(sessionKey: ByteArray): Raw = Raw(this.decryptBy(sessionKey))
+        }
+    }
+
+
+}

+ 21 - 0
mirai-core/src/main/java/net/mamoe/mirai/network/packet/action/AddFriendResult.kt

@@ -0,0 +1,21 @@
+package net.mamoe.mirai.network.packet.action
+
+/**
+ * 添加好友结果
+ */
+enum class AddFriendResult {
+    /**
+     * 等待对方处理
+     */
+    WAITING_FOR_AGREEMENT,
+
+    /**
+     * 和对方已经是好友了
+     */
+    ALREADY_ADDED,
+
+    /**
+     * 对方设置为不添加好友等
+     */
+    FAILED,
+}

+ 0 - 3
mirai-core/src/main/java/net/mamoe/mirai/network/packet/login/ClientChangeOnlineStatusPacket.kt

@@ -17,9 +17,6 @@ class ClientChangeOnlineStatusPacket(
         private val loginStatus: ClientLoginStatus
 
 ) : ClientPacket() {
-    override fun getFixedId(): String {
-        return this.idHex + " ?? ??";
-    }
 
     override fun encode() {
         this.writeRandom(2)//part of packet id