Explorar el Código

Simplify DeviceInfo (#655)

* Simplify DeviceInfo

* Place random string helper properly

* Make DeviceInfo::random java-friendly
AdoptOSS hace 5 años
padre
commit
bb3d039bf8

+ 2 - 2
mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.common.kt

@@ -53,7 +53,7 @@ public expect open class BotConfiguration() : BotConfigurationBase {
     public fun randomDeviceInfo()
 
     /**
-     * 使用特定由 [DeviceInfoData] 序列化产生的 JSON 的设备信息
+     * 使用特定由 [DeviceInfo] 序列化产生的 JSON 的设备信息
      *
      * @see deviceInfo
      */
@@ -251,5 +251,5 @@ internal val deviceInfoStub: (Context) -> DeviceInfo = {
     MiraiLogger.warning("未指定设备信息, 已使用随机设备信息. 请查看 BotConfiguration.deviceInfo 以获取更多信息.")
     @Suppress("DEPRECATION")
     MiraiLogger.warning("Device info isn't specified. Please refer to BotConfiguration.deviceInfo for more information")
-    SystemDeviceInfo()
+    DeviceInfo.random()
 }

+ 88 - 106
mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt

@@ -9,124 +9,106 @@
 
 package net.mamoe.mirai.utils
 
+import kotlinx.io.core.toByteArray
 import kotlinx.serialization.Serializable
-import kotlinx.serialization.Transient
 import kotlinx.serialization.protobuf.ProtoBuf
 import kotlinx.serialization.protobuf.ProtoNumber
+import net.mamoe.mirai.utils.internal.getRandomByteArray
+import net.mamoe.mirai.utils.internal.getRandomIntString
+import net.mamoe.mirai.utils.internal.getRandomString
+import net.mamoe.mirai.utils.internal.md5
+import kotlin.jvm.JvmStatic
 
-/**
- * 设备信息. 可通过继承 [SystemDeviceInfo] 来在默认的基础上修改
- */
-public abstract class DeviceInfo {
-    @Transient
-    public abstract val context: Context
-
-    public abstract val display: ByteArray
-    public abstract val product: ByteArray
-    public abstract val device: ByteArray
-    public abstract val board: ByteArray
-
-    public abstract val brand: ByteArray
-    public abstract val model: ByteArray
-    public abstract val bootloader: ByteArray
-    public abstract val fingerprint: ByteArray
-    public abstract val bootId: ByteArray
-
-    public abstract val procVersion: ByteArray
-    public abstract val baseBand: ByteArray
-
-    public abstract val version: Version
-
-    public abstract val simInfo: ByteArray
-
-    public abstract val osType: ByteArray
-
-    public abstract val macAddress: ByteArray
-
-    public abstract val wifiBSSID: ByteArray?
-    public abstract val wifiSSID: ByteArray?
-
-    public abstract val imsiMd5: ByteArray
-    public abstract val imei: String
-
+@Serializable
+public class DeviceInfo(
+    public val display: ByteArray,
+    public val product: ByteArray,
+    public val device: ByteArray,
+    public val board: ByteArray,
+    public val brand: ByteArray,
+    public val model: ByteArray,
+    public val bootloader: ByteArray,
+    public val fingerprint: ByteArray,
+    public val bootId: ByteArray,
+    public val procVersion: ByteArray,
+    public val baseBand: ByteArray,
+    public val version: Version,
+    public val simInfo: ByteArray,
+    public val osType: ByteArray,
+    public val macAddress: ByteArray,
+    public val wifiBSSID: ByteArray?,
+    public val wifiSSID: ByteArray?,
+    public val imsiMd5: ByteArray,
+    public val imei: String,
+    public val apn: ByteArray
+) {
+    public val androidId: ByteArray get() = display
     public val ipAddress: ByteArray get() = byteArrayOf(192.toByte(), 168.toByte(), 1, 123)
 
-    public abstract val androidId: ByteArray
-
-    public abstract val apn: ByteArray
-
-    public fun generateDeviceInfoData(): ByteArray {
-        @Serializable
-        class DevInfo(
-            @ProtoNumber(1) val bootloader: ByteArray,
-            @ProtoNumber(2) val procVersion: ByteArray,
-            @ProtoNumber(3) val codename: ByteArray,
-            @ProtoNumber(4) val incremental: ByteArray,
-            @ProtoNumber(5) val fingerprint: ByteArray,
-            @ProtoNumber(6) val bootId: ByteArray,
-            @ProtoNumber(7) val androidId: ByteArray,
-            @ProtoNumber(8) val baseBand: ByteArray,
-            @ProtoNumber(9) val innerVersion: ByteArray
-        )
+    @Serializable
+    public class Version(
+        public val incremental: ByteArray = "5891938".toByteArray(),
+        public val release: ByteArray = "10".toByteArray(),
+        public val codename: ByteArray = "REL".toByteArray(),
+        public val sdk: Int = 29
+    )
 
-        return ProtoBuf.encodeToByteArray(
-            DevInfo.serializer(), DevInfo(
-                bootloader,
-                procVersion,
-                version.codename,
-                version.incremental,
-                fingerprint,
-                bootId,
-                androidId,
-                baseBand,
-                version.incremental
+    public companion object {
+        @JvmStatic
+        public fun random(): DeviceInfo {
+            return DeviceInfo(
+                display = "MIRAI.${getRandomString(6, '0'..'9')}.001".toByteArray(),
+                product = "mirai".toByteArray(),
+                device = "mirai".toByteArray(),
+                board = "mirai".toByteArray(),
+                brand = "mamoe".toByteArray(),
+                model = "mirai".toByteArray(),
+                bootloader = "unknown".toByteArray(),
+                fingerprint = "mamoe/mirai/mirai:10/MIRAI.200122.001/${getRandomIntString(7)}:user/release-keys".toByteArray(),
+                bootId = ExternalImage.generateUUID(getRandomByteArray(16).md5()).toByteArray(),
+                procVersion = "Linux version 3.0.31-${getRandomString(8)} ([email protected])".toByteArray(),
+                baseBand = byteArrayOf(),
+                version = Version(),
+                simInfo = "T-Mobile".toByteArray(),
+                osType = "android".toByteArray(),
+                macAddress = "02:00:00:00:00:00".toByteArray(),
+                wifiBSSID = "02:00:00:00:00:00".toByteArray(),
+                wifiSSID = "<unknown ssid>".toByteArray(),
+                imsiMd5 = getRandomByteArray(16).md5(),
+                imei = getRandomIntString(15),
+                apn = "wifi".toByteArray()
             )
-        )
-    }
-
-    public interface Version {
-        public val incremental: ByteArray
-        public val release: ByteArray
-        public val codename: ByteArray
-        public val sdk: Int
+        }
     }
 }
 
-@Serializable
-public class DeviceInfoData(
-    public override val display: ByteArray,
-    public override val product: ByteArray,
-    public override val device: ByteArray,
-    public override val board: ByteArray,
-    public override val brand: ByteArray,
-    public override val model: ByteArray,
-    public override val bootloader: ByteArray,
-    public override val fingerprint: ByteArray,
-    public override val bootId: ByteArray,
-    public override val procVersion: ByteArray,
-    public override val baseBand: ByteArray,
-    public override val version: VersionData,
-    public override val simInfo: ByteArray,
-    public override val osType: ByteArray,
-    public override val macAddress: ByteArray,
-    public override val wifiBSSID: ByteArray?,
-    public override val wifiSSID: ByteArray?,
-    public override val imsiMd5: ByteArray,
-    public override val imei: String,
-    public override val apn: ByteArray
-) : DeviceInfo() {
-    @Transient
-    public override lateinit var context: Context
-
-    public override val androidId: ByteArray get() = display
-
+public fun DeviceInfo.generateDeviceInfoData(): ByteArray {
     @Serializable
-    public class VersionData(
-        public override val incremental: ByteArray = SystemDeviceInfo.Version.incremental,
-        public override val release: ByteArray = SystemDeviceInfo.Version.release,
-        public override val codename: ByteArray = SystemDeviceInfo.Version.codename,
-        public override val sdk: Int = SystemDeviceInfo.Version.sdk
-    ) : Version
+    class DevInfo(
+        @ProtoNumber(1) val bootloader: ByteArray,
+        @ProtoNumber(2) val procVersion: ByteArray,
+        @ProtoNumber(3) val codename: ByteArray,
+        @ProtoNumber(4) val incremental: ByteArray,
+        @ProtoNumber(5) val fingerprint: ByteArray,
+        @ProtoNumber(6) val bootId: ByteArray,
+        @ProtoNumber(7) val androidId: ByteArray,
+        @ProtoNumber(8) val baseBand: ByteArray,
+        @ProtoNumber(9) val innerVersion: ByteArray
+    )
+
+    return ProtoBuf.encodeToByteArray(
+        DevInfo.serializer(), DevInfo(
+            bootloader,
+            procVersion,
+            version.codename,
+            version.incremental,
+            fingerprint,
+            bootId,
+            androidId,
+            baseBand,
+            version.incremental
+        )
+    )
 }
 
 /*

+ 0 - 23
mirai-core-api/src/commonMain/kotlin/utils/SystemDeviceInfo.kt

@@ -1,23 +0,0 @@
-/*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
- *
- * https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-/**
- * 通过本机信息来获取设备信息.
- *
- * Android: 获取手机信息, 与 QQ 官方相同.
- * JVM: 部分为常量, 部分为随机
- */
-public expect open class SystemDeviceInfo : DeviceInfo {
-    public constructor()
-    public constructor(context: Context)
-
-    public object Version : DeviceInfo.Version
-}

+ 49 - 0
mirai-core-api/src/commonMain/kotlin/utils/internal/RandomUtils.kt

@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019-2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+package net.mamoe.mirai.utils.internal
+
+import kotlin.jvm.JvmSynthetic
+import kotlin.random.Random
+import kotlin.random.nextInt
+
+
+/**
+ * 生成长度为 [length], 元素为随机 `0..255` 的 [ByteArray]
+ */
+@JvmSynthetic
+internal fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
+
+/**
+ * 随机生成长度为 [length] 的 [String].
+ */
+@JvmSynthetic
+internal fun getRandomString(length: Int): String =
+    getRandomString(length, *defaultRanges)
+
+private val defaultRanges: Array<CharRange> = arrayOf('a'..'z', 'A'..'Z', '0'..'9')
+private val intCharRanges: Array<CharRange> = arrayOf('0'..'9')
+/**
+ * 根据所给 [charRange] 随机生成长度为 [length] 的 [String].
+ */
+@JvmSynthetic
+internal fun getRandomString(length: Int, charRange: CharRange): String =
+    CharArray(length) { charRange.random() }.concatToString()
+
+/**
+ * 根据所给 [charRanges] 随机生成长度为 [length] 的 [String].
+ */
+@JvmSynthetic
+internal fun getRandomString(length: Int, vararg charRanges: CharRange): String =
+    CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() }.concatToString()
+
+
+@JvmSynthetic
+internal fun getRandomIntString(length: Int): String =
+    getRandomString(length, *intCharRanges)

+ 2 - 2
mirai-core-api/src/jvmMain/kotlin/utils/BotConfiguration.kt

@@ -57,14 +57,14 @@ public actual open class BotConfiguration : BotConfigurationBase() { // open for
     }
 
     /**
-     * 使用特定由 [DeviceInfoData] 序列化产生的 JSON 的设备信息
+     * 使用特定由 [DeviceInfo] 序列化产生的 JSON 的设备信息
      *
      * @see deviceInfo
      */
     @SinceMirai("1.2.0")
     public actual fun loadDeviceInfoJson(json: String) {
         deviceInfo = { context ->
-            this.json.decodeFromString(DeviceInfoData.serializer(), json).also { it.context = context }
+            this.json.decodeFromString(DeviceInfo.serializer(), json)
         }
     }
 

+ 25 - 0
mirai-core-api/src/jvmMain/kotlin/utils/DeviceInfoUtils.kt

@@ -0,0 +1,25 @@
+/*
+ * Copyright 2019-2020 Mamoe Technologies and contributors.
+ *
+ * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
+ * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
+ *
+ * https://github.com/mamoe/mirai/blob/master/LICENSE
+ */
+
+package net.mamoe.mirai.utils
+
+import kotlinx.serialization.json.Json
+import java.io.File
+
+/**
+ * 加载一个设备信息. 若文件不存在或为空则随机并创建一个设备信息保存.
+ */
+public fun File.loadAsDeviceInfo(json: Json): DeviceInfo {
+    if (!this.exists() || this.length() == 0L) {
+        return DeviceInfo.random().also {
+            this.writeText(json.encodeToString(DeviceInfo.serializer(), it))
+        }
+    }
+    return json.decodeFromString(DeviceInfo.serializer(), this.readText())
+}

+ 1 - 1
mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt

@@ -154,7 +154,7 @@ public actual abstract class LoginSolver {
 
 internal fun BotConfiguration.getFileBasedDeviceInfoSupplier(filename: String): ((Context) -> DeviceInfo)? {
     return {
-        File(filename).loadAsDeviceInfo(json, it)
+        File(filename).loadAsDeviceInfo(json)
     }
 }
 

+ 0 - 104
mirai-core-api/src/jvmMain/kotlin/utils/SystemDeviceInfo.kt

@@ -1,104 +0,0 @@
-/*
- * Copyright 2019-2020 Mamoe Technologies and contributors.
- *
- * 此源代码的使用受 GNU AFFERO GENERAL PUBLIC LICENSE version 3 许可证的约束, 可以在以下链接找到该许可证.
- * Use of this source code is governed by the GNU AFFERO GENERAL PUBLIC LICENSE version 3 license that can be found via the following link.
- *
- * https://github.com/mamoe/mirai/blob/master/LICENSE
- */
-
-package net.mamoe.mirai.utils
-
-import kotlinx.io.core.toByteArray
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.Transient
-import kotlinx.serialization.json.Json
-import net.mamoe.mirai.utils.internal.md5
-import java.io.File
-import kotlin.random.Random
-import kotlin.random.nextInt
-
-/**
- * 加载一个设备信息. 若文件不存在或为空则随机并创建一个设备信息保存.
- */
-public fun File.loadAsDeviceInfo(json: Json, context: Context = ContextImpl()): DeviceInfo {
-    if (!this.exists() || this.length() == 0L) {
-        return SystemDeviceInfo(context).also {
-            this.writeText(json.encodeToString(SystemDeviceInfo.serializer(), it))
-        }
-    }
-    return json.decodeFromString(DeviceInfoData.serializer(), this.readText()).also {
-        it.context = context
-    }
-}
-
-@Serializable
-public actual open class SystemDeviceInfo actual constructor() : DeviceInfo() {
-    public actual constructor(context: Context) : this() {
-        this.context = context
-    }
-
-    @Transient
-    public final override lateinit var context: Context
-
-    public override val display: ByteArray = "MIRAI.${getRandomString(6, '0'..'9')}.001".toByteArray()
-    public override val product: ByteArray = "mirai".toByteArray()
-    public override val device: ByteArray = "mirai".toByteArray()
-    public override val board: ByteArray = "mirai".toByteArray()
-    public override val brand: ByteArray = "mamoe".toByteArray()
-    public override val model: ByteArray = "mirai".toByteArray()
-    public override val bootloader: ByteArray = "unknown".toByteArray()
-    public override val fingerprint: ByteArray =
-        "mamoe/mirai/mirai:10/MIRAI.200122.001/${getRandomString(7, '0'..'9')}:user/release-keys".toByteArray()
-    public override val bootId: ByteArray = ExternalImage.generateUUID(getRandomByteArray(16).md5()).toByteArray()
-    public override val procVersion: ByteArray =
-        "Linux version 3.0.31-${getRandomString(8)} ([email protected])".toByteArray()
-    public override val baseBand: ByteArray = byteArrayOf()
-    public override val version: Version = Version
-    public override val simInfo: ByteArray = "T-Mobile".toByteArray()
-    public override val osType: ByteArray = "android".toByteArray()
-    public override val macAddress: ByteArray = "02:00:00:00:00:00".toByteArray()
-    public override val wifiBSSID: ByteArray? = "02:00:00:00:00:00".toByteArray()
-    public override val wifiSSID: ByteArray? = "<unknown ssid>".toByteArray()
-    public override val imsiMd5: ByteArray = getRandomByteArray(16).md5()
-    public override val imei: String = getRandomString(15, '0'..'9')
-    public override val androidId: ByteArray get() = display
-    public override val apn: ByteArray = "wifi".toByteArray()
-
-    @Serializable
-    public actual object Version : DeviceInfo.Version {
-        public override val incremental: ByteArray = "5891938".toByteArray()
-        public override val release: ByteArray = "10".toByteArray()
-        public override val codename: ByteArray = "REL".toByteArray()
-        public override val sdk: Int = 29
-    }
-}
-
-/**
- * 生成长度为 [length], 元素为随机 `0..255` 的 [ByteArray]
- */
-@JvmSynthetic
-internal fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
-
-/**
- * 随机生成长度为 [length] 的 [String].
- */
-@JvmSynthetic
-internal fun getRandomString(length: Int): String =
-    getRandomString(length, *defaultRanges)
-
-private val defaultRanges: Array<CharRange> = arrayOf('a'..'z', 'A'..'Z', '0'..'9')
-
-/**
- * 根据所给 [charRange] 随机生成长度为 [length] 的 [String].
- */
-@JvmSynthetic
-internal fun getRandomString(length: Int, charRange: CharRange): String =
-    String(CharArray(length) { charRange.random() })
-
-/**
- * 根据所给 [charRanges] 随机生成长度为 [length] 的 [String].
- */
-@JvmSynthetic
-internal fun getRandomString(length: Int, vararg charRanges: CharRange): String =
-    String(CharArray(length) { charRanges[Random.Default.nextInt(0..charRanges.lastIndex)].random() })

+ 1 - 1
mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt

@@ -264,7 +264,7 @@ internal abstract class QQAndroidBotBase constructor(
             context,
             account,
             bot = @Suppress("LeakingThis") this as QQAndroidBot,
-            device = configuration.deviceInfo?.invoke(context) ?: SystemDeviceInfo(context)
+            device = configuration.deviceInfo?.invoke(context) ?: DeviceInfo.random()
         )
     internal var firstLoginSucceed: Boolean = false
 

+ 1 - 1
mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt

@@ -75,7 +75,7 @@ internal open class QQAndroidClient(
     context: Context,
     val account: BotAccount,
     val ecdh: ECDH = ECDH(),
-    val device: DeviceInfo = SystemDeviceInfo(context),
+    val device: DeviceInfo,
     bot: QQAndroidBot
 ) {
     @Suppress("INVISIBLE_MEMBER")

+ 1 - 0
mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt

@@ -21,6 +21,7 @@ import net.mamoe.mirai.internal.utils.guidFlag
 import net.mamoe.mirai.internal.utils.io.*
 import net.mamoe.mirai.utils.currentTimeSeconds
 import net.mamoe.mirai.utils.error
+import net.mamoe.mirai.utils.generateDeviceInfoData
 
 internal class WtLogin {
     /**