mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-21 07:56:56 +08:00
StatSvc.Register: Provide SSO Ip and correct logic (#1240)
* StatSvc.Register: Provide SSO Ip and correct logic * Remove unnessacy launch Co-authored-by: Him188 <Him188@mamoe.net> * Test for last polled ip * Normal login test for last ip * Fix test failed and remove debug code * Fix unit test and build * Optimize pollCurrent and pollAny method * Use uOldSSOIp and uNewSSOIp only when protocol is PHONE * Fix bug in toIpV4Long * Fix new line in NettyBotNormalLoginTest.kt * Using Inet4Address and toInt method for toIpV4Long * Return Unsigned Long for toIpV4Long * Remove unnessacy synchronized annotation Co-authored-by: Him188 <Him188@mamoe.net> * Using createAddress method instead of address * Moving lastDisconnectedIp and lastConnectedIp to Server List * Fix build * Fix build and remove empty line * Keeping naming consistent * Use bot.components instead of overrideComponents Co-authored-by: Him188 <Him188@mamoe.net> * Revert overrideComponents changes and add comment for overrideComponents Co-authored-by: Him188 <Him188@mamoe.net>
This commit is contained in:
parent
2713127466
commit
b7869888f0
@ -102,6 +102,16 @@ internal open class QQAndroidBot constructor(
|
||||
|
||||
override fun toString(): String = "StateChangedObserver(BotOnlineEventBroadcaster)"
|
||||
},
|
||||
StateChangedObserver("LastConnectedAddressUpdater", State.OK) {
|
||||
components[ServerList].run {
|
||||
lastConnectedIP = getLastPolledIP()
|
||||
}
|
||||
},
|
||||
StateChangedObserver("LastDisconnectedAddressUpdater", State.CLOSED) {
|
||||
components[ServerList].run {
|
||||
lastDisconnectedIP = lastConnectedIP
|
||||
}
|
||||
},
|
||||
StateChangedObserver("BotOfflineEventBroadcaster", State.OK, State.CLOSED) { new ->
|
||||
// logging performed by BotOfflineEventMonitor
|
||||
val cause = new.getCause()
|
||||
|
@ -58,6 +58,22 @@ internal interface ServerList {
|
||||
*/
|
||||
fun refresh()
|
||||
|
||||
|
||||
/**
|
||||
* Last disconnected ip
|
||||
*/
|
||||
var lastDisconnectedIP: String
|
||||
|
||||
/**
|
||||
* Last connected ip
|
||||
*/
|
||||
var lastConnectedIP: String
|
||||
|
||||
/**
|
||||
* Get last poll ip
|
||||
*/
|
||||
fun getLastPolledIP(): String
|
||||
|
||||
/**
|
||||
* [Poll][Queue.poll] from current address list. Returns `null` if current address list is empty.
|
||||
*/
|
||||
@ -100,6 +116,9 @@ internal class ServerListImpl(
|
||||
@Volatile
|
||||
private var current: Queue<ServerAddress> = ArrayDeque(initial)
|
||||
|
||||
@Volatile
|
||||
private var lastPolledAddress: ServerAddress? = null
|
||||
|
||||
@Synchronized
|
||||
override fun setPreferred(list: Collection<ServerAddress>) {
|
||||
logger.info { "Server list: ${list.joinToString()}." }
|
||||
@ -121,12 +140,19 @@ internal class ServerListImpl(
|
||||
}
|
||||
}
|
||||
|
||||
override var lastDisconnectedIP: String = ""
|
||||
override var lastConnectedIP: String = ""
|
||||
|
||||
override fun getLastPolledIP(): String = lastPolledAddress?.host ?: ""
|
||||
|
||||
/**
|
||||
* [Poll][Queue.poll] from current address list. Returns `null` if current address list is empty.
|
||||
*/
|
||||
@Synchronized
|
||||
override fun pollCurrent(): ServerAddress? {
|
||||
return current.poll()
|
||||
return current.poll()?.also { address ->
|
||||
lastPolledAddress = address
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,10 +161,12 @@ internal class ServerListImpl(
|
||||
@Synchronized
|
||||
override fun pollAny(): ServerAddress {
|
||||
if (current.isEmpty()) refresh()
|
||||
return current.remove()
|
||||
return current.remove().also { address ->
|
||||
lastPolledAddress = address
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "ServerListImpl(current.size=${current.size})"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import net.mamoe.mirai.internal.message.contextualBugReportException
|
||||
import net.mamoe.mirai.internal.network.*
|
||||
import net.mamoe.mirai.internal.network.components.ContactCacheService
|
||||
import net.mamoe.mirai.internal.network.components.ContactUpdater
|
||||
import net.mamoe.mirai.internal.network.components.ServerList
|
||||
import net.mamoe.mirai.internal.network.impl.netty.HeartbeatFailedException
|
||||
import net.mamoe.mirai.internal.network.protocol.data.jce.*
|
||||
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x769
|
||||
@ -39,6 +40,8 @@ import net.mamoe.mirai.internal.network.protocol.packet.*
|
||||
import net.mamoe.mirai.internal.utils.NetworkType
|
||||
import net.mamoe.mirai.internal.utils._miraiContentToString
|
||||
import net.mamoe.mirai.internal.utils.io.serialization.*
|
||||
import net.mamoe.mirai.internal.utils.toIpV4Long
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.currentTimeMillis
|
||||
import net.mamoe.mirai.utils.encodeToString
|
||||
import net.mamoe.mirai.utils.toReadPacket
|
||||
@ -158,16 +161,27 @@ internal class StatSvc {
|
||||
client: QQAndroidClient,
|
||||
regPushReason: RegPushReason = RegPushReason.appRegister
|
||||
) = impl("online", client, 1L or 2 or 4, client.onlineStatus, regPushReason) {
|
||||
client.bot.components[ContactCacheService].friendListCache?.let { friendListCache: FriendListCache ->
|
||||
iLargeSeq = friendListCache.friendListSeq
|
||||
// timeStamp = friendListCache.timeStamp
|
||||
if (client.bot.configuration.protocol == BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
|
||||
client.bot.components[ServerList].run {
|
||||
uOldSSOIp = lastDisconnectedIP.toIpV4Long()
|
||||
uNewSSOIp = lastConnectedIP.toIpV4Long()
|
||||
}
|
||||
} else {
|
||||
uOldSSOIp = 0
|
||||
uNewSSOIp = 0
|
||||
}
|
||||
client.bot.components[ContactCacheService].friendListCache?.let { friendListCache ->
|
||||
iLargeSeq = friendListCache.friendListSeq
|
||||
}
|
||||
// timeStamp = friendListCache.timeStamp
|
||||
strVendorName = "MIUI"
|
||||
strVendorOSName = "?ONEPLUS A5000_23_17"
|
||||
}
|
||||
|
||||
fun offline(
|
||||
client: QQAndroidClient,
|
||||
regPushReason: RegPushReason = RegPushReason.appRegister
|
||||
) = impl("offline", client, 0, OnlineStatus.OFFLINE, regPushReason)
|
||||
) = impl("offline", client, 1L or 2 or 4, OnlineStatus.OFFLINE, regPushReason)
|
||||
|
||||
private fun impl(
|
||||
name: String,
|
||||
@ -221,10 +235,6 @@ internal class StatSvc {
|
||||
strDevName = client.device.model.encodeToString(),
|
||||
strDevType = client.device.model.encodeToString(),
|
||||
strOSVer = client.device.version.release.encodeToString(),
|
||||
uOldSSOIp = 0,
|
||||
uNewSSOIp = 0,
|
||||
strVendorName = "MIUI",
|
||||
strVendorOSName = "?ONEPLUS A5000_23_17",
|
||||
// register 时还需要
|
||||
/*
|
||||
var44.uNewSSOIp = field_127445;
|
||||
|
@ -11,6 +11,9 @@ package net.mamoe.mirai.internal.utils
|
||||
|
||||
import net.mamoe.mirai.contact.ContactOrBot
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.toInt
|
||||
import net.mamoe.mirai.utils.toLongUnsigned
|
||||
import java.net.Inet4Address
|
||||
|
||||
|
||||
internal fun Int.toIpV4AddressString(): String {
|
||||
@ -27,6 +30,18 @@ internal fun Int.toIpV4AddressString(): String {
|
||||
}
|
||||
}
|
||||
|
||||
internal fun String.toIpV4Long(): Long {
|
||||
return if (isEmpty()) {
|
||||
0
|
||||
} else {
|
||||
try {
|
||||
Inet4Address.getByName(this).address.toInt().toLongUnsigned()
|
||||
} catch (e: UnknownHostException) {
|
||||
-2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun String.chineseLength(upTo: Int): Int {
|
||||
return this.sumUpTo(upTo) {
|
||||
when (it) {
|
||||
|
@ -27,6 +27,18 @@ internal class ServerListTest : AbstractTest() {
|
||||
assertNotNull(ServerListImpl().pollCurrent())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `last poll ip is updated when polled`() {
|
||||
val instance = ServerListImpl()
|
||||
val old = instance.getLastPolledIP()
|
||||
assertNotNull(old)
|
||||
assert(old.isEmpty())
|
||||
assertNotNull(instance.pollCurrent())
|
||||
val new = instance.getLastPolledIP()
|
||||
assertNotNull(new)
|
||||
assertNotEquals(old, new)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `not empty for initial`() {
|
||||
assertNotNull(ServerListImpl().pollAny())
|
||||
|
@ -34,7 +34,7 @@ internal abstract class AbstractNettyNHTestWithSelector : AbstractRealNetworkHan
|
||||
val channel = AbstractNettyNHTest.NettyNHTestChannel()
|
||||
|
||||
val selector = TestSelector<TestNettyNH> {
|
||||
object : TestNettyNH(bot, createContext(), address) {
|
||||
object : TestNettyNH(bot, createContext(), createAddress()) {
|
||||
override suspend fun createConnection(decodePipeline: PacketDecodePipeline): Channel = channel
|
||||
}
|
||||
}
|
||||
|
@ -132,11 +132,13 @@ internal sealed class AbstractRealNetworkHandlerTest<H : NetworkHandler> : Abstr
|
||||
return instance
|
||||
}
|
||||
|
||||
open fun createHandler(): NetworkHandler = factory.create(createContext(), address)
|
||||
open fun createHandler(): NetworkHandler = factory.create(createContext(), createAddress())
|
||||
open fun createContext(): NetworkHandlerContextImpl =
|
||||
NetworkHandlerContextImpl(bot, networkLogger, bot.createNetworkLevelComponents())
|
||||
|
||||
val address: InetSocketAddress = InetSocketAddress.createUnresolved("localhost", 123)
|
||||
//Use overrideComponents to avoid StackOverflowError when applying components
|
||||
open fun createAddress(): InetSocketAddress =
|
||||
overrideComponents[ServerList].pollAny().let { InetSocketAddress.createUnresolved(it.host, it.port) }
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Assertions
|
||||
|
@ -0,0 +1,39 @@
|
||||
package net.mamoe.mirai.internal.network.impl.netty
|
||||
|
||||
import net.mamoe.mirai.internal.network.components.ServerList
|
||||
import net.mamoe.mirai.internal.network.framework.AbstractNettyNHTest
|
||||
import net.mamoe.mirai.internal.network.framework.TestNettyNH
|
||||
import net.mamoe.mirai.internal.network.handler.NetworkHandler
|
||||
import net.mamoe.mirai.internal.test.runBlockingUnit
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
|
||||
internal class NettyAddressChangedTest : AbstractNettyNHTest() {
|
||||
@Test
|
||||
fun `test login ip changes`() = runBlockingUnit {
|
||||
networkLogger.debug("before login, Assuming both ip is empty")
|
||||
val lastConnectedIpOld = bot.components[ServerList].lastConnectedIP
|
||||
val lastDisconnectedIpOld = bot.components[ServerList].lastDisconnectedIP
|
||||
assert(lastConnectedIpOld.isEmpty()) { "Assuming lastConnectedIp is empty" }
|
||||
assert(lastDisconnectedIpOld.isEmpty()) { "Assuming lastDisconnectedIp is empty" }
|
||||
|
||||
networkLogger.debug("Do login, Assuming lastConnectedIp is NOT empty")
|
||||
bot.login()
|
||||
assertState(NetworkHandler.State.OK)
|
||||
assertNotEquals(
|
||||
lastConnectedIpOld,
|
||||
bot.components[ServerList].lastConnectedIP,
|
||||
"Assuming lastConnectedIp is NOT empty"
|
||||
)
|
||||
|
||||
networkLogger.debug("Offline the bot, Assuming lastConnectedIp is equals lastDisconnectedIp")
|
||||
(bot.network as TestNettyNH).setStateClosed()
|
||||
assertState(NetworkHandler.State.CLOSED)
|
||||
assertEquals(
|
||||
bot.components[ServerList].lastConnectedIP,
|
||||
bot.components[ServerList].lastDisconnectedIP,
|
||||
"Assuming lastConnectedIp is equals lastDisconnectedIp"
|
||||
)
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ import kotlin.test.assertFalse
|
||||
|
||||
internal class NettyBotNormalLoginTest : AbstractNettyNHTest() {
|
||||
val selector = KeepAliveNetworkHandlerSelector(selectorLogger) {
|
||||
super.factory.create(createContext(), address)
|
||||
super.factory.create(createContext(), createAddress())
|
||||
}
|
||||
|
||||
override fun createHandler(): NetworkHandler {
|
||||
|
Loading…
Reference in New Issue
Block a user