diff --git a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.common.kt b/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.common.kt index 014420b85..4081fbc62 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/BotConfiguration.common.kt +++ b/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() } \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt b/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt index 65216b993..3f7756da8 100644 --- a/mirai-core-api/src/commonMain/kotlin/utils/DeviceInfo.kt +++ b/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 + @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 + ) - 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 - ) - - 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)} (android-build@xxx.xxx.xxx.xxx.com)".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 = "".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 + ) + ) } /* diff --git a/mirai-core-api/src/commonMain/kotlin/utils/SystemDeviceInfo.kt b/mirai-core-api/src/commonMain/kotlin/utils/SystemDeviceInfo.kt deleted file mode 100644 index e7c8259d5..000000000 --- a/mirai-core-api/src/commonMain/kotlin/utils/SystemDeviceInfo.kt +++ /dev/null @@ -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 -} \ No newline at end of file diff --git a/mirai-core-api/src/commonMain/kotlin/utils/internal/RandomUtils.kt b/mirai-core-api/src/commonMain/kotlin/utils/internal/RandomUtils.kt new file mode 100644 index 000000000..2c17e9624 --- /dev/null +++ b/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 = arrayOf('a'..'z', 'A'..'Z', '0'..'9') +private val intCharRanges: Array = 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) \ No newline at end of file diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/BotConfiguration.kt b/mirai-core-api/src/jvmMain/kotlin/utils/BotConfiguration.kt index 43323cafa..686be7d26 100644 --- a/mirai-core-api/src/jvmMain/kotlin/utils/BotConfiguration.kt +++ b/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) } } diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/DeviceInfoUtils.kt b/mirai-core-api/src/jvmMain/kotlin/utils/DeviceInfoUtils.kt new file mode 100644 index 000000000..eb5fd98e3 --- /dev/null +++ b/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()) +} \ No newline at end of file diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt b/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt index 45a50ad84..afdff098a 100644 --- a/mirai-core-api/src/jvmMain/kotlin/utils/LoginSolver.jvm.kt +++ b/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) } } diff --git a/mirai-core-api/src/jvmMain/kotlin/utils/SystemDeviceInfo.kt b/mirai-core-api/src/jvmMain/kotlin/utils/SystemDeviceInfo.kt deleted file mode 100644 index 643783d1a..000000000 --- a/mirai-core-api/src/jvmMain/kotlin/utils/SystemDeviceInfo.kt +++ /dev/null @@ -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)} (android-build@xxx.xxx.xxx.xxx.com)".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? = "".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 = 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() }) diff --git a/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt b/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt index ee7376a05..bd927176c 100644 --- a/mirai-core/src/commonMain/kotlin/QQAndroidBot.common.kt +++ b/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 diff --git a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt b/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt index acb2c5a13..ec1459bba 100644 --- a/mirai-core/src/commonMain/kotlin/network/QQAndroidClient.kt +++ b/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") diff --git a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt b/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt index adaf4cf5e..7f8979570 100644 --- a/mirai-core/src/commonMain/kotlin/network/protocol/packet/login/WtLogin.kt +++ b/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 { /**