mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-31 20:02:27 +08:00
Updated message&contact adding
This commit is contained in:
parent
b33e8757e5
commit
fa6a9b66b2
@ -17,9 +17,7 @@ import net.mamoe.mirai.message.Message
|
|||||||
import net.mamoe.mirai.message.defaults.MessageChain
|
import net.mamoe.mirai.message.defaults.MessageChain
|
||||||
import net.mamoe.mirai.network.RobotNetworkHandler.*
|
import net.mamoe.mirai.network.RobotNetworkHandler.*
|
||||||
import net.mamoe.mirai.network.packet.*
|
import net.mamoe.mirai.network.packet.*
|
||||||
import net.mamoe.mirai.network.packet.action.ClientSendFriendMessagePacket
|
import net.mamoe.mirai.network.packet.action.*
|
||||||
import net.mamoe.mirai.network.packet.action.ServerSendFriendMessageResponsePacket
|
|
||||||
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
|
||||||
import net.mamoe.mirai.network.packet.login.*
|
import net.mamoe.mirai.network.packet.login.*
|
||||||
import net.mamoe.mirai.task.MiraiThreadPool
|
import net.mamoe.mirai.task.MiraiThreadPool
|
||||||
import net.mamoe.mirai.utils.*
|
import net.mamoe.mirai.utils.*
|
||||||
@ -31,6 +29,7 @@ import java.util.*
|
|||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.ScheduledFuture
|
import java.util.concurrent.ScheduledFuture
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import java.util.function.Supplier
|
||||||
import javax.imageio.ImageIO
|
import javax.imageio.ImageIO
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@ -545,16 +544,87 @@ class RobotNetworkHandler(private val robot: Robot) : Closeable {
|
|||||||
}
|
}
|
||||||
internal var gtk: Int = 0
|
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() {
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -30,7 +30,6 @@ abstract class ClientPacket : ByteArrayDataOutputStream(), Packet {
|
|||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
throw RuntimeException(e)
|
throw RuntimeException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
|
@ -26,10 +26,6 @@ class ClientAccountInfoRequestPacket(
|
|||||||
it.writeByte(0x00)
|
it.writeByte(0x00)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFixedId(): String {
|
|
||||||
return this.idHex + " ?? ??"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@PacketId("00 5C")
|
@PacketId("00 5C")
|
||||||
|
@ -22,10 +22,6 @@ class ClientHeartbeatPacket(
|
|||||||
it.writeHex("00 01 00 01")
|
it.writeHex("00 01 00 01")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFixedId(): String {
|
|
||||||
return this.idHex + " ?? ??"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ServerHeartbeatResponsePacket(input: DataInputStream) : ServerPacket(input)
|
class ServerHeartbeatResponsePacket(input: DataInputStream) : ServerPacket(input)
|
@ -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")
|
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 + " ?? ??"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package net.mamoe.mirai.network.packet
|
package net.mamoe.mirai.network.packet
|
||||||
|
|
||||||
import lombok.Getter
|
|
||||||
import net.mamoe.mirai.network.packet.PacketNameFormatter.adjustName
|
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.ServerSendFriendMessageResponsePacket
|
||||||
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
import net.mamoe.mirai.network.packet.action.ServerSendGroupMessageResponsePacket
|
||||||
import net.mamoe.mirai.network.packet.login.*
|
import net.mamoe.mirai.network.packet.login.*
|
||||||
@ -12,9 +12,11 @@ import java.io.DataInputStream
|
|||||||
* @author Him188moe
|
* @author Him188moe
|
||||||
*/
|
*/
|
||||||
abstract class ServerPacket(val input: DataInputStream) : Packet {
|
abstract class ServerPacket(val input: DataInputStream) : Packet {
|
||||||
@Getter
|
|
||||||
var idHex: String
|
var idHex: String
|
||||||
|
|
||||||
|
var idByteArray: ByteArray//fixed 4 size
|
||||||
|
|
||||||
|
|
||||||
var encoded: Boolean = false
|
var encoded: Boolean = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -24,6 +26,12 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
|
|||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
idByteArray = if (idHex.isEmpty()) {
|
||||||
|
byteArrayOf(0, 0, 0, 0)
|
||||||
|
} else {
|
||||||
|
idHex.hexToBytes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <P : ServerPacket> P.setId(idHex: String): P {
|
fun <P : ServerPacket> P.setId(idHex: String): P {
|
||||||
@ -101,6 +109,8 @@ abstract class ServerPacket(val input: DataInputStream) : Packet {
|
|||||||
"00 CD" -> ServerSendFriendMessageResponsePacket(stream)
|
"00 CD" -> ServerSendFriendMessageResponsePacket(stream)
|
||||||
"00 02" -> ServerSendGroupMessageResponsePacket(stream)
|
"00 02" -> ServerSendGroupMessageResponsePacket(stream)
|
||||||
|
|
||||||
|
"00 A7" -> ServerCanAddFriendResponsePacket(stream)
|
||||||
|
|
||||||
else -> throw IllegalArgumentException(idHex)
|
else -> throw IllegalArgumentException(idHex)
|
||||||
}
|
}
|
||||||
}.apply { this.idHex = idHex }
|
}.apply { this.idHex = idHex }
|
||||||
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package net.mamoe.mirai.network.packet.action
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加好友结果
|
||||||
|
*/
|
||||||
|
enum class AddFriendResult {
|
||||||
|
/**
|
||||||
|
* 等待对方处理
|
||||||
|
*/
|
||||||
|
WAITING_FOR_AGREEMENT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 和对方已经是好友了
|
||||||
|
*/
|
||||||
|
ALREADY_ADDED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对方设置为不添加好友等
|
||||||
|
*/
|
||||||
|
FAILED,
|
||||||
|
}
|
@ -17,9 +17,6 @@ class ClientChangeOnlineStatusPacket(
|
|||||||
private val loginStatus: ClientLoginStatus
|
private val loginStatus: ClientLoginStatus
|
||||||
|
|
||||||
) : ClientPacket() {
|
) : ClientPacket() {
|
||||||
override fun getFixedId(): String {
|
|
||||||
return this.idHex + " ?? ??";
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun encode() {
|
override fun encode() {
|
||||||
this.writeRandom(2)//part of packet id
|
this.writeRandom(2)//part of packet id
|
||||||
|
Loading…
Reference in New Issue
Block a user