Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor StatSvc ip recording, fix #2349 #2351

Draft
wants to merge 16 commits into
base: dev
Choose a base branch
from
Draft
10 changes: 1 addition & 9 deletions mirai-core/src/commonMain/kotlin/QQAndroidBot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ import net.mamoe.mirai.internal.network.component.ComponentStorageDelegate
import net.mamoe.mirai.internal.network.component.ConcurrentComponentStorage
import net.mamoe.mirai.internal.network.component.withFallback
import net.mamoe.mirai.internal.network.components.*
import net.mamoe.mirai.internal.network.handler.NetworkHandler
import net.mamoe.mirai.internal.network.handler.*
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContextImpl
import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory
import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport
import net.mamoe.mirai.internal.network.handler.NetworkHandlerSupport.BaseStateImpl
import net.mamoe.mirai.internal.network.handler.selector.KeepAliveNetworkHandlerSelector
import net.mamoe.mirai.internal.network.handler.selector.NetworkException
Expand Down Expand Up @@ -123,11 +120,6 @@ 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,12 @@ internal interface ServerList {
/**
* Last disconnected ip
*/
var lastDisconnectedIP: String
var lastDisconnectedIP: Long

/**
* Last connected ip
*/
var lastConnectedIP: String
var lastConnectedIP: Long

/**
* Get last poll ip
Expand Down Expand Up @@ -139,8 +139,8 @@ internal class ServerListImpl(
}
}

override var lastDisconnectedIP: String = ""
override var lastConnectedIP: String = ""
override var lastDisconnectedIP: Long = 0L
override var lastConnectedIP: Long = 0L

override fun getLastPolledIP(): String = lastPolledAddress?.host ?: ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ internal abstract class CommonNetworkHandler<Conn>(
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "KotlinRedundantDiagnosticSuppress") // can happen on some platforms
protected abstract fun Conn.close()

/**
* Get the connected ip in network order
*/
protected abstract fun Conn.getConnectedIP(): Long

/**
* *Single-thread* event-loop packet decoder.
*
Expand Down Expand Up @@ -244,6 +249,7 @@ internal abstract class CommonNetworkHandler<Conn>(
connection.join()
try {
context[SsoProcessor].login(this@CommonNetworkHandler)
context[ServerList].lastConnectedIP = connection.await().getConnectedIP()
} catch (e: LoginFailedException) {
throw LoginFailedExceptionAsNetworkException(e)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,16 @@ internal class StatSvc {
if (client.bot.configuration.protocol == BotConfiguration.MiraiProtocol.ANDROID_PHONE) {
client.bot.components[ServerList].run {
kotlin.runCatching {
uOldSSOIp = lastDisconnectedIP.toIpV4Long()
uNewSSOIp = lastConnectedIP.toIpV4Long()
uOldSSOIp = if (lastDisconnectedIP in 1..2) {
-lastDisconnectedIP
} else {
lastDisconnectedIP
}
uNewSSOIp = if (lastConnectedIP in 1..2) {
-lastDisconnectedIP
} else {
lastConnectedIP
}
Comment on lines +172 to +181
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这部分应该在提供这个 ip 的地方处理

}.onFailure { err ->
client.bot.network.logger.warning({
"Exception when converting ipaddress to long: ld=${lastDisconnectedIP}, lc=${lastConnectedIP}"
Expand All @@ -194,7 +202,7 @@ internal class StatSvc {
fun offline(
client: QQAndroidClient,
regPushReason: RegPushReason = RegPushReason.appRegister
) = impl("offline", client, 1L or 2 or 4, OnlineStatus.OFFLINE, regPushReason)
) = impl("offline", client, 0, OnlineStatus.OFFLINE, regPushReason)

private fun impl(
name: String,
Expand Down Expand Up @@ -425,9 +433,3 @@ internal class StatSvc {
}
}

internal fun String.toIpV4Long(): Long {
if (isEmpty()) return 0
val split = split('.')
if (split.size != 4) return 0
return split.mapToByteArray { it.toUByte().toByte() }.toInt().toLongUnsigned()
}
1 change: 1 addition & 0 deletions mirai-core/src/commonMain/kotlin/utils/PlatformSocket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import kotlin.jvm.JvmName
*/
internal expect class PlatformSocket : Closeable, HighwayProtocolChannel {
val isOpen: Boolean
val connectedIp: Long
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

给特殊意义值留下注释


override fun close()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ internal abstract class TestCommonNetworkHandler(
address: SocketAddress,
) : CommonNetworkHandler<PlatformConn>(context, address), ITestNetworkHandler<PlatformConn> {
override suspend fun createConnection(): PlatformConn {
return PlatformConn()
return PlatformConn(address)
}

override fun PlatformConn.getConnectedIP(): Long {
return getConnectedIPPlatform()
}

override fun PlatformConn.writeAndFlushOrCloseAsync(packet: OutgoingPacket) {
Expand Down Expand Up @@ -104,4 +108,8 @@ internal expect abstract class AbstractCommonNHTest() :
protected fun removeOutgoingPacketEncoder()
}

internal expect class PlatformConn()
internal expect class PlatformConn(address: SocketAddress) {
val address: SocketAddress
internal fun getConnectedIPPlatform(): Long

}
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,15 @@ internal abstract class AbstractCommonNHTestWithSelector :
overrideComponents[BotOfflineEventMonitor] = BotOfflineEventMonitorImpl()
}

val conn = PlatformConn()
val conn get() = PlatformConn(createAddress())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by lazy?


val selector = TestSelector<TestCommonNetworkHandler> {
object : TestCommonNetworkHandler(bot, createContext(), createAddress()) {
// override suspend fun createConnection(decodePipeline: PacketDecodePipeline): PlatformConn = channel
override suspend fun createConnection(): PlatformConn {
return conn
}

}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2019-2022 Mamoe Technologies and contributors.
*
* 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
* Use of this source code is governed by the GNU AGPLv3 license that can be found through the following link.
*
* https://github.com/mamoe/mirai/blob/dev/LICENSE
*/

package net.mamoe.mirai.internal.network.framework.test

import net.mamoe.mirai.internal.network.framework.PlatformConn
import net.mamoe.mirai.internal.network.handler.createSocketAddress
import net.mamoe.mirai.internal.test.runBlockingUnit
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue

class IpConversionTest {
private fun String.toIpV4Long(): Long {
PlatformConn(address = createSocketAddress(host = this, port = 80)).getConnectedIPPlatform().run {
return if (this in 1..2) {
-this
} else {
this
}
}
}

@Test
fun `test bad ipAddress`() = runBlockingUnit {
assertEquals(-2, "some^ting%bad".toIpV4Long())
assertEquals(-2, "another_bad".toIpV4Long())
assertEquals(-2, " ".toIpV4Long())
assertEquals(-2, "w.a.c.d".toIpV4Long())
assertEquals(-2, "the..anotherbad......".toIpV4Long())
assertEquals(-2, "错误的IP地址".toIpV4Long())
}

@Test
fun `test good ipAddress`() = runBlockingUnit {
assertTrue("www.baidu.com".toIpV4Long() > 0)
assertTrue("www.qq.com".toIpV4Long() > 0)
assertTrue("www.sohu.com".toIpV4Long() > 0)
assertTrue("www.weibo.com".toIpV4Long() > 0)
}

@Test
fun `test plain ipAddress`() = runBlockingUnit {
assertEquals(16885952L, "192.168.1.1".toIpV4Long())
assertEquals(4294967295L, "255.255.255.255".toIpV4Long())
assertEquals(0L, "0.0.0.0".toIpV4Long())
assertEquals(1869573999L, "111.111.111.111".toIpV4Long())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

package net.mamoe.mirai.internal.network.handler

import kotlinx.atomicfu.atomic
import net.mamoe.mirai.internal.network.components.FirstLoginResult
import net.mamoe.mirai.internal.network.components.SsoProcessor
import net.mamoe.mirai.internal.network.framework.AbstractCommonNHTest
Expand Down Expand Up @@ -41,7 +40,7 @@ internal class StandaloneSelectorTests : AbstractCommonNHTest() {
NetworkHandlerFactory<TestCommonNetworkHandler> { context, address ->
object : TestCommonNetworkHandler(bot, context, address) {
override suspend fun createConnection(): PlatformConn {
return throwExceptionOnConnecting?.invoke() ?: PlatformConn()
return throwExceptionOnConnecting?.invoke() ?: PlatformConn(address)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ internal class CommonNHAddressChangedTest : AbstractCommonNHTest() {
networkLogger.debug("before login, Assuming both ip is empty")
val lastConnectedIpOld = bot.components[ServerList].lastConnectedIP
val lastDisconnectedIpOld = bot.components[ServerList].lastDisconnectedIP
assertTrue(lastConnectedIpOld.isEmpty(), "Assuming lastConnectedIp is empty")
assertTrue(lastDisconnectedIpOld.isEmpty(), "Assuming lastDisconnectedIp is empty")
assertTrue(lastConnectedIpOld == 0L, "Assuming lastConnectedIp is empty")
assertTrue(lastDisconnectedIpOld == 0L, "Assuming lastDisconnectedIp is empty")

networkLogger.debug("Do login, Assuming lastConnectedIp is NOT empty")
bot.login()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import net.mamoe.mirai.internal.network.handler.CommonNetworkHandler
import net.mamoe.mirai.internal.network.handler.NetworkHandler.State
import net.mamoe.mirai.internal.network.handler.NetworkHandlerContext
import net.mamoe.mirai.internal.network.protocol.packet.OutgoingPacket
import net.mamoe.mirai.utils.cast
import net.mamoe.mirai.utils.debug
import net.mamoe.mirai.utils.*
import java.net.InetSocketAddress
import java.net.SocketAddress
import io.netty.channel.Channel as NettyChannel

Expand Down Expand Up @@ -131,6 +131,16 @@ internal open class NettyNetworkHandler(
return contextResult.await()
}

override fun io.netty.channel.Channel.getConnectedIP(): Long = this.remoteAddress().let { address ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为什么要有这个lambda?

{
if (this.isActive && address is InetSocketAddress) {
address.address?.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L
} else {
0L
}
}
}.invoke()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

创建lambda立即invoke只会增加复杂度


@Suppress("EXTENSION_SHADOWED_BY_MEMBER")
override fun io.netty.channel.Channel.close() {
this.close()
Expand Down
8 changes: 8 additions & 0 deletions mirai-core/src/jvmBaseMain/kotlin/utils/PlatformSocket.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runInterruptible
import kotlinx.coroutines.suspendCancellableCoroutine
import net.mamoe.mirai.internal.network.highway.HighwayProtocolChannel
import net.mamoe.mirai.utils.toInt
import net.mamoe.mirai.utils.toLongUnsigned
import java.io.BufferedInputStream
import java.io.BufferedOutputStream
import java.io.IOException
Expand All @@ -31,6 +33,12 @@ internal actual class PlatformSocket : Closeable, HighwayProtocolChannel {
if (::socket.isInitialized)
socket.isConnected
else false
actual val connectedIp: Long
get() = if (isOpen) {
socket.inetAddress.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L
} else {
0L
}

actual override fun close() {
if (::socket.isInitialized) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ package net.mamoe.mirai.internal.network.framework

import kotlinx.coroutines.ExecutorCoroutineDispatcher
import net.mamoe.mirai.internal.network.handler.NetworkHandlerFactory
import net.mamoe.mirai.internal.network.handler.SocketAddress
import net.mamoe.mirai.internal.network.handler.getHost
import net.mamoe.mirai.utils.toInt
import net.mamoe.mirai.utils.toLongUnsigned
import java.net.InetAddress
import java.net.UnknownHostException
import kotlin.test.AfterTest

/**
Expand Down Expand Up @@ -51,7 +57,16 @@ internal actual abstract class AbstractCommonNHTest actual constructor() :
}
}

actual val conn: PlatformConn = NettyNHTestChannel()
actual val conn: PlatformConn get() = PlatformConn(address = createAddress())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by lazy?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JVM那边的测试也是get() 而且这里是创建连接才会去get这个 get()这里应该没问题

}

internal actual class PlatformConn actual constructor(actual val address: SocketAddress) : NettyNHTestChannel() {
actual fun getConnectedIPPlatform(): Long {
return (address.address ?: try {
InetAddress.getByName(address.getHost())
} catch (e: UnknownHostException) {
null
})?.address?.copyOf()?.also { it.reverse() }?.toInt()?.toLongUnsigned() ?: 2L
}
}

internal actual typealias PlatformConn = NettyNHTestChannel
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.cast
import net.mamoe.mirai.utils.error

internal class NettyNHTestChannel(
internal sealed class NettyNHTestChannel(
var fakeServer: (NettyNHTestChannel.(msg: Any?) -> Unit)?,
) : EmbeddedChannel() {
constructor() : this(null)
Expand Down
Loading