mirror of
https://github.com/mamoe/mirai.git
synced 2025-02-01 20:10:18 +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)"
|
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 ->
|
StateChangedObserver("BotOfflineEventBroadcaster", State.OK, State.CLOSED) { new ->
|
||||||
// logging performed by BotOfflineEventMonitor
|
// logging performed by BotOfflineEventMonitor
|
||||||
val cause = new.getCause()
|
val cause = new.getCause()
|
||||||
|
@ -58,6 +58,22 @@ internal interface ServerList {
|
|||||||
*/
|
*/
|
||||||
fun refresh()
|
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.
|
* [Poll][Queue.poll] from current address list. Returns `null` if current address list is empty.
|
||||||
*/
|
*/
|
||||||
@ -100,6 +116,9 @@ internal class ServerListImpl(
|
|||||||
@Volatile
|
@Volatile
|
||||||
private var current: Queue<ServerAddress> = ArrayDeque(initial)
|
private var current: Queue<ServerAddress> = ArrayDeque(initial)
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var lastPolledAddress: ServerAddress? = null
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun setPreferred(list: Collection<ServerAddress>) {
|
override fun setPreferred(list: Collection<ServerAddress>) {
|
||||||
logger.info { "Server list: ${list.joinToString()}." }
|
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.
|
* [Poll][Queue.poll] from current address list. Returns `null` if current address list is empty.
|
||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun pollCurrent(): ServerAddress? {
|
override fun pollCurrent(): ServerAddress? {
|
||||||
return current.poll()
|
return current.poll()?.also { address ->
|
||||||
|
lastPolledAddress = address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,7 +161,9 @@ internal class ServerListImpl(
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
override fun pollAny(): ServerAddress {
|
override fun pollAny(): ServerAddress {
|
||||||
if (current.isEmpty()) refresh()
|
if (current.isEmpty()) refresh()
|
||||||
return current.remove()
|
return current.remove().also { address ->
|
||||||
|
lastPolledAddress = address
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
|
@ -30,6 +30,7 @@ import net.mamoe.mirai.internal.message.contextualBugReportException
|
|||||||
import net.mamoe.mirai.internal.network.*
|
import net.mamoe.mirai.internal.network.*
|
||||||
import net.mamoe.mirai.internal.network.components.ContactCacheService
|
import net.mamoe.mirai.internal.network.components.ContactCacheService
|
||||||
import net.mamoe.mirai.internal.network.components.ContactUpdater
|
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.impl.netty.HeartbeatFailedException
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.jce.*
|
import net.mamoe.mirai.internal.network.protocol.data.jce.*
|
||||||
import net.mamoe.mirai.internal.network.protocol.data.proto.Oidb0x769
|
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.NetworkType
|
||||||
import net.mamoe.mirai.internal.utils._miraiContentToString
|
import net.mamoe.mirai.internal.utils._miraiContentToString
|
||||||
import net.mamoe.mirai.internal.utils.io.serialization.*
|
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.currentTimeMillis
|
||||||
import net.mamoe.mirai.utils.encodeToString
|
import net.mamoe.mirai.utils.encodeToString
|
||||||
import net.mamoe.mirai.utils.toReadPacket
|
import net.mamoe.mirai.utils.toReadPacket
|
||||||
@ -158,16 +161,27 @@ internal class StatSvc {
|
|||||||
client: QQAndroidClient,
|
client: QQAndroidClient,
|
||||||
regPushReason: RegPushReason = RegPushReason.appRegister
|
regPushReason: RegPushReason = RegPushReason.appRegister
|
||||||
) = impl("online", client, 1L or 2 or 4, client.onlineStatus, regPushReason) {
|
) = impl("online", client, 1L or 2 or 4, client.onlineStatus, regPushReason) {
|
||||||
client.bot.components[ContactCacheService].friendListCache?.let { friendListCache: FriendListCache ->
|
if (client.bot.configuration.protocol == BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
|
||||||
iLargeSeq = friendListCache.friendListSeq
|
client.bot.components[ServerList].run {
|
||||||
// timeStamp = friendListCache.timeStamp
|
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(
|
fun offline(
|
||||||
client: QQAndroidClient,
|
client: QQAndroidClient,
|
||||||
regPushReason: RegPushReason = RegPushReason.appRegister
|
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(
|
private fun impl(
|
||||||
name: String,
|
name: String,
|
||||||
@ -221,10 +235,6 @@ internal class StatSvc {
|
|||||||
strDevName = client.device.model.encodeToString(),
|
strDevName = client.device.model.encodeToString(),
|
||||||
strDevType = client.device.model.encodeToString(),
|
strDevType = client.device.model.encodeToString(),
|
||||||
strOSVer = client.device.version.release.encodeToString(),
|
strOSVer = client.device.version.release.encodeToString(),
|
||||||
uOldSSOIp = 0,
|
|
||||||
uNewSSOIp = 0,
|
|
||||||
strVendorName = "MIUI",
|
|
||||||
strVendorOSName = "?ONEPLUS A5000_23_17",
|
|
||||||
// register 时还需要
|
// register 时还需要
|
||||||
/*
|
/*
|
||||||
var44.uNewSSOIp = field_127445;
|
var44.uNewSSOIp = field_127445;
|
||||||
|
@ -11,6 +11,9 @@ package net.mamoe.mirai.internal.utils
|
|||||||
|
|
||||||
import net.mamoe.mirai.contact.ContactOrBot
|
import net.mamoe.mirai.contact.ContactOrBot
|
||||||
import net.mamoe.mirai.message.data.*
|
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 {
|
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 {
|
internal fun String.chineseLength(upTo: Int): Int {
|
||||||
return this.sumUpTo(upTo) {
|
return this.sumUpTo(upTo) {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
@ -27,6 +27,18 @@ internal class ServerListTest : AbstractTest() {
|
|||||||
assertNotNull(ServerListImpl().pollCurrent())
|
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
|
@Test
|
||||||
fun `not empty for initial`() {
|
fun `not empty for initial`() {
|
||||||
assertNotNull(ServerListImpl().pollAny())
|
assertNotNull(ServerListImpl().pollAny())
|
||||||
|
@ -34,7 +34,7 @@ internal abstract class AbstractNettyNHTestWithSelector : AbstractRealNetworkHan
|
|||||||
val channel = AbstractNettyNHTest.NettyNHTestChannel()
|
val channel = AbstractNettyNHTest.NettyNHTestChannel()
|
||||||
|
|
||||||
val selector = TestSelector<TestNettyNH> {
|
val selector = TestSelector<TestNettyNH> {
|
||||||
object : TestNettyNH(bot, createContext(), address) {
|
object : TestNettyNH(bot, createContext(), createAddress()) {
|
||||||
override suspend fun createConnection(decodePipeline: PacketDecodePipeline): Channel = channel
|
override suspend fun createConnection(decodePipeline: PacketDecodePipeline): Channel = channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,11 +132,13 @@ internal sealed class AbstractRealNetworkHandlerTest<H : NetworkHandler> : Abstr
|
|||||||
return instance
|
return instance
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun createHandler(): NetworkHandler = factory.create(createContext(), address)
|
open fun createHandler(): NetworkHandler = factory.create(createContext(), createAddress())
|
||||||
open fun createContext(): NetworkHandlerContextImpl =
|
open fun createContext(): NetworkHandlerContextImpl =
|
||||||
NetworkHandlerContextImpl(bot, networkLogger, bot.createNetworkLevelComponents())
|
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
|
// 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() {
|
internal class NettyBotNormalLoginTest : AbstractNettyNHTest() {
|
||||||
val selector = KeepAliveNetworkHandlerSelector(selectorLogger) {
|
val selector = KeepAliveNetworkHandlerSelector(selectorLogger) {
|
||||||
super.factory.create(createContext(), address)
|
super.factory.create(createContext(), createAddress())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createHandler(): NetworkHandler {
|
override fun createHandler(): NetworkHandler {
|
||||||
|
Loading…
Reference in New Issue
Block a user