Rework seq system (#1230)

* Rework seq system, should help #1209

* Use non-blocking (CAS) implement

* Making next seq code more clear for reading

* Fix mistake
This commit is contained in:
sandtechnology 2021-05-02 13:50:24 +08:00 committed by GitHub
parent 0dbb448cad
commit db4c41f84a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 37 deletions

View File

@ -14,6 +14,7 @@
package net.mamoe.mirai.utils
import kotlin.math.absoluteValue
import kotlin.random.Random
import kotlin.random.nextInt
@ -23,6 +24,11 @@ import kotlin.random.nextInt
*/
public fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
/**
* 随机生成一个正整数
*/
public fun getRandomUnsignedInt(): Int = Random.nextInt().absoluteValue
/**
* 随机生成长度为 [length] [String].
*/

View File

@ -86,48 +86,50 @@ internal open class QQAndroidClient(
internal val miscBitMap: Int get() = protocol.miscBitMap // 184024956 // 也可能是 150470524 ?
internal val mainSigMap: Int get() = protocol.mainSigMap
private val _ssoSequenceId: AtomicInt = atomic(85600)
@Volatile
private var _ssoSequenceId: Int = Random.nextInt(100000)
var fileStoragePushFSSvcList: FileStoragePushFSSvcList? = null
@Synchronized
@MiraiInternalApi("Do not use directly. Get from the lambda param of buildSsoPacket")
internal fun nextSsoSequenceId() = _ssoSequenceId.addAndGet(2)
internal fun nextSsoSequenceId(): Int {
_ssoSequenceId += 2
val new = _ssoSequenceId
if (new > 100000) {
_ssoSequenceId = Random.nextInt(100000) + 60000
}
return new
}
val apkVersionName: ByteArray get() = protocol.ver.toByteArray() //"8.4.18".toByteArray()
val buildVer: String get() = "8.4.18.4810" // 8.2.0.1296 // 8.4.8.4810 // 8.2.7.4410
private val messageSequenceId: AtomicInt = atomic(22911)
internal fun atomicNextMessageSequenceId(): Int = messageSequenceId.getAndAdd(2)
private val sequenceId: AtomicInt = atomic(getRandomUnsignedInt())
internal fun atomicNextMessageSequenceId(): Int = sequenceId.incrementAndGet()
internal fun nextRequestPacketRequestId(): Int = sequenceId.incrementAndGet()
@Volatile
private var highwayDataTransSequenceId: Int = Random.nextInt(100000)
private val friendSeq: AtomicInt = atomic(22911)
internal fun getFriendSeq(): Int {
return friendSeq.value
@Synchronized
internal fun nextHighwayDataTransSequenceId(): Int {
highwayDataTransSequenceId += 1
val new = highwayDataTransSequenceId
if (new > 1000000) {
highwayDataTransSequenceId = Random.nextInt(1060000)
}
return new
}
internal fun nextFriendSeq(): Int {
return friendSeq.incrementAndGet()
}
private val friendSeq: AtomicInt = atomic(getRandomUnsignedInt())
internal fun getFriendSeq(): Int = friendSeq.value
internal fun setFriendSeq(compare: Int, id: Int): Boolean {
return friendSeq.compareAndSet(compare, id % 65535)
}
private val requestPacketRequestId: AtomicInt = atomic(1921334513)
internal fun nextRequestPacketRequestId(): Int = requestPacketRequestId.getAndAdd(2)
private val highwayDataTransSequenceIdForGroup: AtomicInt = atomic(87017)
internal fun nextHighwayDataTransSequenceIdForGroup(): Int = highwayDataTransSequenceIdForGroup.getAndAdd(2)
private val highwayDataTransSequenceIdForFriend: AtomicInt = atomic(43973)
internal fun nextHighwayDataTransSequenceIdForFriend(): Int = highwayDataTransSequenceIdForFriend.getAndAdd(2)
private val highwayDataTransSequenceIdForApplyUp: AtomicInt = atomic(77918)
internal fun nextHighwayDataTransSequenceIdForApplyUp(): Int = highwayDataTransSequenceIdForApplyUp.getAndAdd(2)
internal fun nextFriendSeq(): Int = friendSeq.incrementAndGet()
internal fun setFriendSeq(compare: Int, id: Int): Boolean = friendSeq.compareAndSet(compare, id % 65535)
val appClientVersion: Int = 0

View File

@ -388,13 +388,7 @@ internal fun highwayPacketSession(
version = 1,
uin = client.uin.toString(),
command = command,
seq = when (commandId) {
2 -> client.nextHighwayDataTransSequenceIdForGroup()
1 -> client.nextHighwayDataTransSequenceIdForFriend()
27 -> client.nextHighwayDataTransSequenceIdForApplyUp()
29 -> client.nextHighwayDataTransSequenceIdForGroup()
else -> client.nextHighwayDataTransSequenceIdForGroup()
},
seq = client.nextHighwayDataTransSequenceId(),
retryTimes = 0,
appid = appId,
dataflag = dataFlag,

View File

@ -35,6 +35,7 @@ import net.mamoe.mirai.internal.utils.io.serialization.readProtoBuf
import net.mamoe.mirai.internal.utils.io.serialization.writeProtoBuf
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.currentTimeSeconds
import net.mamoe.mirai.utils.getRandomUnsignedInt
import java.util.concurrent.atomic.AtomicReference
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@ -116,11 +117,11 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
else listOf(message)
val response = mutableListOf<OutgoingPacket>()
val div = if (fragmented.size == 1) 0 else Random.nextInt().absoluteValue
val div = if (fragmented.size == 1) 0 else getRandomUnsignedInt()
val pkgNum = fragmented.size
val seqIds = sequenceIdsInitializer(pkgNum)
val randIds0 = IntArray(pkgNum) { Random.nextInt().absoluteValue }
val randIds0 = IntArray(pkgNum) { getRandomUnsignedInt() }
sequenceIds.set(seqIds)
randIds.set(randIds0)
postInit()
@ -182,7 +183,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
sequenceIds = sequenceIds,
randIds = randIds,
sequenceIdsInitializer = { size ->
IntArray(size) { client.nextFriendSeq() }
IntArray(size) { client.atomicNextMessageSequenceId() }
},
postInit = {
source(
@ -379,7 +380,7 @@ internal object MessageSvcPbSendMsg : OutgoingPacketFactory<MessageSvcPbSendMsg.
sequenceIds = sequenceIds,
randIds = randIds,
sequenceIdsInitializer = { size ->
IntArray(size) { client.nextFriendSeq() }
IntArray(size) { client.atomicNextMessageSequenceId() }
},
postInit = {
randIds.get().forEach { id ->