Updated message&contact adding

This commit is contained in:
Him188moe 2019-09-08 16:16:36 +08:00
parent b33e8757e5
commit fa6a9b66b2
9 changed files with 241 additions and 23 deletions

View File

@ -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)
}
}
}
}

View File

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

View File

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

View File

@ -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)

View File

@ -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 + " ?? ??"
}
}
/**

View File

@ -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 }

View File

@ -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))
}
}
}

View File

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

View File

@ -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