|
@@ -12,20 +12,28 @@
|
|
package net.mamoe.mirai.utils
|
|
package net.mamoe.mirai.utils
|
|
|
|
|
|
import io.ktor.utils.io.core.*
|
|
import io.ktor.utils.io.core.*
|
|
-import kotlinx.serialization.*
|
|
|
|
-import kotlinx.serialization.builtins.serializer
|
|
|
|
-import kotlinx.serialization.json.Json
|
|
|
|
-import kotlinx.serialization.json.JsonElement
|
|
|
|
-import kotlinx.serialization.json.jsonObject
|
|
|
|
-import kotlinx.serialization.json.jsonPrimitive
|
|
|
|
|
|
+import kotlinx.serialization.ExperimentalSerializationApi
|
|
|
|
+import kotlinx.serialization.KSerializer
|
|
|
|
+import kotlinx.serialization.Serializable
|
|
|
|
+import kotlinx.serialization.Transient
|
|
import kotlinx.serialization.protobuf.ProtoBuf
|
|
import kotlinx.serialization.protobuf.ProtoBuf
|
|
import kotlinx.serialization.protobuf.ProtoNumber
|
|
import kotlinx.serialization.protobuf.ProtoNumber
|
|
-import net.mamoe.mirai.utils.DeviceInfoManager.Version.Companion.trans
|
|
|
|
-import kotlin.jvm.JvmInline
|
|
|
|
import kotlin.jvm.JvmStatic
|
|
import kotlin.jvm.JvmStatic
|
|
|
|
+import kotlin.jvm.JvmSynthetic
|
|
import kotlin.random.Random
|
|
import kotlin.random.Random
|
|
|
|
|
|
-public expect class DeviceInfo(
|
|
|
|
|
|
+internal const val DeviceInfoConstructorDeprecationMessage =
|
|
|
|
+ "Constructor and serializer of DeviceInfo is deprecated and will be removed in the future." +
|
|
|
|
+ "This is because new properties can be added and it requires too much effort to maintain public stability." +
|
|
|
|
+ "Please use DeviceInfo.serializeToString and DeviceInfo.deserializeFromString instead."
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 表示设备信息
|
|
|
|
+ */
|
|
|
|
+public expect class DeviceInfo
|
|
|
|
+@Deprecated(DeviceInfoConstructorDeprecationMessage, level = DeprecationLevel.WARNING)
|
|
|
|
+@DeprecatedSinceMirai(warningSince = "2.15") // planned internal
|
|
|
|
+public constructor(
|
|
display: ByteArray,
|
|
display: ByteArray,
|
|
product: ByteArray,
|
|
product: ByteArray,
|
|
device: ByteArray,
|
|
device: ByteArray,
|
|
@@ -45,9 +53,9 @@ public expect class DeviceInfo(
|
|
wifiSSID: ByteArray,
|
|
wifiSSID: ByteArray,
|
|
imsiMd5: ByteArray,
|
|
imsiMd5: ByteArray,
|
|
imei: String,
|
|
imei: String,
|
|
- apn: ByteArray
|
|
|
|
|
|
+ apn: ByteArray,
|
|
|
|
+ androidId: ByteArray,
|
|
) {
|
|
) {
|
|
-
|
|
|
|
public val display: ByteArray
|
|
public val display: ByteArray
|
|
public val product: ByteArray
|
|
public val product: ByteArray
|
|
public val device: ByteArray
|
|
public val device: ByteArray
|
|
@@ -68,15 +76,14 @@ public expect class DeviceInfo(
|
|
public val imsiMd5: ByteArray
|
|
public val imsiMd5: ByteArray
|
|
public val imei: String
|
|
public val imei: String
|
|
public val apn: ByteArray
|
|
public val apn: ByteArray
|
|
-
|
|
|
|
public val androidId: ByteArray
|
|
public val androidId: ByteArray
|
|
|
|
+
|
|
public val ipAddress: ByteArray
|
|
public val ipAddress: ByteArray
|
|
|
|
|
|
@Transient
|
|
@Transient
|
|
@MiraiInternalApi
|
|
@MiraiInternalApi
|
|
public val guid: ByteArray
|
|
public val guid: ByteArray
|
|
|
|
|
|
-
|
|
|
|
// @Serializable: use DeviceInfoVersionSerializer in commonMain.
|
|
// @Serializable: use DeviceInfoVersionSerializer in commonMain.
|
|
public class Version(
|
|
public class Version(
|
|
incremental: ByteArray = "5891938".toByteArray(),
|
|
incremental: ByteArray = "5891938".toByteArray(),
|
|
@@ -98,6 +105,10 @@ public expect class DeviceInfo(
|
|
* @since 2.9
|
|
* @since 2.9
|
|
*/
|
|
*/
|
|
override fun hashCode(): Int
|
|
override fun hashCode(): Int
|
|
|
|
+
|
|
|
|
+ internal companion object {
|
|
|
|
+ fun serializer(): KSerializer<Version>
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
public companion object {
|
|
public companion object {
|
|
@@ -119,7 +130,27 @@ public expect class DeviceInfo(
|
|
@JvmStatic
|
|
@JvmStatic
|
|
public fun random(random: Random): DeviceInfo
|
|
public fun random(random: Random): DeviceInfo
|
|
|
|
|
|
|
|
+ @Deprecated(DeviceInfoConstructorDeprecationMessage, level = DeprecationLevel.WARNING)
|
|
|
|
+ @DeprecatedSinceMirai(warningSince = "2.15") // planned internal
|
|
public fun serializer(): KSerializer<DeviceInfo>
|
|
public fun serializer(): KSerializer<DeviceInfo>
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将此 [DeviceInfo] 序列化为字符串. 序列化的字符串可以在以后通过 [DeviceInfo.deserializeFromString] 反序列化为 [DeviceInfo].
|
|
|
|
+ *
|
|
|
|
+ * 序列化的字符串有兼容性保证, 在旧版 mirai 序列化的字符串, 可以在新版 mirai 使用. 但新版 mirai 序列化的字符串不一定能在旧版使用.
|
|
|
|
+ *
|
|
|
|
+ * @since 2.15
|
|
|
|
+ */
|
|
|
|
+ @JvmStatic
|
|
|
|
+ public fun serializeToString(deviceInfo: DeviceInfo): String
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 将通过 [serializeToString] 序列化得到的字符串反序列化为 [DeviceInfo].
|
|
|
|
+ * 此函数兼容旧版 mirai 序列化的字符串.
|
|
|
|
+ * @since 2.15
|
|
|
|
+ */
|
|
|
|
+ @JvmStatic
|
|
|
|
+ public fun deserializeFromString(string: String): DeviceInfo
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -134,7 +165,74 @@ public expect class DeviceInfo(
|
|
override fun hashCode(): Int
|
|
override fun hashCode(): Int
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * 将此 [DeviceInfo] 序列化为字符串. 序列化的字符串可以在以后通过 [DeviceInfo.deserializeFromString] 反序列化为 [DeviceInfo].
|
|
|
|
+ *
|
|
|
|
+ * 序列化的字符串有兼容性保证, 在旧版 mirai 序列化的字符串, 可以在新版 mirai 使用. 但新版 mirai 序列化的字符串不一定能在旧版使用.
|
|
|
|
+ *
|
|
|
|
+ * @since 2.15
|
|
|
|
+ */
|
|
|
|
+@JvmSynthetic
|
|
|
|
+public fun DeviceInfo.serializeToString(): String = DeviceInfo.serializeToString(this)
|
|
|
|
+
|
|
|
|
+@Serializable
|
|
|
|
+private class DevInfo @OptIn(ExperimentalSerializationApi::class) constructor(
|
|
|
|
+ @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
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 不要使用这个 API, 此 API 在未来可能会被删除
|
|
|
|
+ */
|
|
|
|
+public fun DeviceInfo.generateDeviceInfoData(): ByteArray { // ?? why is this public?
|
|
|
|
+
|
|
|
|
+ @OptIn(ExperimentalSerializationApi::class)
|
|
|
|
+ return ProtoBuf.encodeToByteArray(
|
|
|
|
+ DevInfo.serializer(), DevInfo(
|
|
|
|
+ bootloader,
|
|
|
|
+ procVersion,
|
|
|
|
+ version.codename,
|
|
|
|
+ version.incremental,
|
|
|
|
+ fingerprint,
|
|
|
|
+ bootId,
|
|
|
|
+ androidId,
|
|
|
|
+ baseBand,
|
|
|
|
+ version.incremental
|
|
|
|
+ )
|
|
|
|
+ )
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * Defaults "%4;7t>;28<fc.5*6".toByteArray()
|
|
|
|
+ */
|
|
|
|
+internal fun generateGuid(androidId: ByteArray, macAddress: ByteArray): ByteArray =
|
|
|
|
+ (androidId + macAddress).md5()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+fun DeviceInfo.toOidb0x769DeviceInfo() : Oidb0x769.DeviceInfo = Oidb0x769.DeviceInfo(
|
|
|
|
+ brand = brand.encodeToString(),
|
|
|
|
+ model = model.encodeToString(),
|
|
|
|
+ os = Oidb0x769.OS(
|
|
|
|
+ version = version.release.encodeToString(),
|
|
|
|
+ sdk = version.sdk.toString(),
|
|
|
|
+ kernel = version.kernel
|
|
|
|
+ )
|
|
|
|
+)
|
|
|
|
+*/
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @see DeviceInfoManager
|
|
|
|
+ */
|
|
internal object DeviceInfoCommonImpl {
|
|
internal object DeviceInfoCommonImpl {
|
|
|
|
+ @Suppress("DEPRECATION")
|
|
fun randomDeviceInfo(random: Random) = DeviceInfo(
|
|
fun randomDeviceInfo(random: Random) = DeviceInfo(
|
|
display = "MIRAI.${getRandomString(6, '0'..'9', random)}.001".toByteArray(),
|
|
display = "MIRAI.${getRandomString(6, '0'..'9', random)}.001".toByteArray(),
|
|
product = "mirai".toByteArray(),
|
|
product = "mirai".toByteArray(),
|
|
@@ -159,7 +257,8 @@ internal object DeviceInfoCommonImpl {
|
|
wifiSSID = "<unknown ssid>".toByteArray(),
|
|
wifiSSID = "<unknown ssid>".toByteArray(),
|
|
imsiMd5 = getRandomByteArray(16, random).md5(),
|
|
imsiMd5 = getRandomByteArray(16, random).md5(),
|
|
imei = "86${getRandomIntString(12, random)}".let { it + luhn(it) },
|
|
imei = "86${getRandomIntString(12, random)}".let { it + luhn(it) },
|
|
- apn = "wifi".toByteArray()
|
|
|
|
|
|
+ apn = "wifi".toByteArray(),
|
|
|
|
+ androidId = getRandomByteArray(8, random).toUHexString("").lowercase().encodeToByteArray()
|
|
)
|
|
)
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -187,6 +286,8 @@ internal object DeviceInfoCommonImpl {
|
|
if (deviceInfo === other) return true
|
|
if (deviceInfo === other) return true
|
|
if (!isSameType(this, other)) return false
|
|
if (!isSameType(this, other)) return false
|
|
|
|
|
|
|
|
+ // also remember to add equal compare to JvmDeviceInfoTest.`can read legacy v1`
|
|
|
|
+ // when adding new field compare here.
|
|
if (!display.contentEquals(other.display)) return false
|
|
if (!display.contentEquals(other.display)) return false
|
|
if (!product.contentEquals(other.product)) return false
|
|
if (!product.contentEquals(other.product)) return false
|
|
if (!device.contentEquals(other.device)) return false
|
|
if (!device.contentEquals(other.device)) return false
|
|
@@ -207,7 +308,10 @@ internal object DeviceInfoCommonImpl {
|
|
if (!imsiMd5.contentEquals(other.imsiMd5)) return false
|
|
if (!imsiMd5.contentEquals(other.imsiMd5)) return false
|
|
if (imei != other.imei) return false
|
|
if (imei != other.imei) return false
|
|
if (!apn.contentEquals(other.apn)) return false
|
|
if (!apn.contentEquals(other.apn)) return false
|
|
- return guid.contentEquals(other.guid)
|
|
|
|
|
|
+ if (!guid.contentEquals(other.guid)) return false
|
|
|
|
+ if (!androidId.contentEquals(other.androidId)) return false
|
|
|
|
+
|
|
|
|
+ return true
|
|
}
|
|
}
|
|
|
|
|
|
@OptIn(MiraiInternalApi::class)
|
|
@OptIn(MiraiInternalApi::class)
|
|
@@ -234,273 +338,7 @@ internal object DeviceInfoCommonImpl {
|
|
result = 31 * result + imei.hashCode()
|
|
result = 31 * result + imei.hashCode()
|
|
result = 31 * result + apn.contentHashCode()
|
|
result = 31 * result + apn.contentHashCode()
|
|
result = 31 * result + guid.contentHashCode()
|
|
result = 31 * result + guid.contentHashCode()
|
|
|
|
+ result = 31 * result + androidId.contentHashCode()
|
|
return result
|
|
return result
|
|
}
|
|
}
|
|
-}
|
|
|
|
-
|
|
|
|
-@Serializable
|
|
|
|
-private class DevInfo @OptIn(ExperimentalSerializationApi::class) constructor(
|
|
|
|
- @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
|
|
|
|
-)
|
|
|
|
-
|
|
|
|
-public fun DeviceInfo.generateDeviceInfoData(): ByteArray {
|
|
|
|
- @OptIn(ExperimentalSerializationApi::class)
|
|
|
|
- return ProtoBuf.encodeToByteArray(
|
|
|
|
- DevInfo.serializer(), DevInfo(
|
|
|
|
- bootloader,
|
|
|
|
- procVersion,
|
|
|
|
- version.codename,
|
|
|
|
- version.incremental,
|
|
|
|
- fingerprint,
|
|
|
|
- bootId,
|
|
|
|
- androidId,
|
|
|
|
- baseBand,
|
|
|
|
- version.incremental
|
|
|
|
- )
|
|
|
|
- )
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-internal object DeviceInfoManager {
|
|
|
|
- sealed interface Info {
|
|
|
|
- fun toDeviceInfo(): DeviceInfo
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Serializable(HexStringSerializer::class)
|
|
|
|
- @JvmInline
|
|
|
|
- value class HexString(
|
|
|
|
- val data: ByteArray
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- object HexStringSerializer : KSerializer<HexString> by String.serializer().map(
|
|
|
|
- String.serializer().descriptor.copy("HexString"),
|
|
|
|
- deserialize = { HexString(it.hexToBytes()) },
|
|
|
|
- serialize = { it.data.toUHexString("").lowercase() }
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- // Note: property names must be kept intact during obfuscation process if applied.
|
|
|
|
- @Serializable
|
|
|
|
- class Wrapper<T : Info>(
|
|
|
|
- @Suppress("unused") val deviceInfoVersion: Int, // used by plain jsonObject
|
|
|
|
- val data: T
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- private object DeviceInfoVersionSerializer : KSerializer<DeviceInfo.Version> by SerialData.serializer().map(
|
|
|
|
- resultantDescriptor = SerialData.serializer().descriptor,
|
|
|
|
- deserialize = {
|
|
|
|
- DeviceInfo.Version(incremental, release, codename, sdk)
|
|
|
|
- },
|
|
|
|
- serialize = {
|
|
|
|
- SerialData(incremental, release, codename, sdk)
|
|
|
|
- }
|
|
|
|
- ) {
|
|
|
|
- @SerialName("Version")
|
|
|
|
- @Serializable
|
|
|
|
- private class SerialData(
|
|
|
|
- val incremental: ByteArray = "5891938".toByteArray(),
|
|
|
|
- val release: ByteArray = "10".toByteArray(),
|
|
|
|
- val codename: ByteArray = "REL".toByteArray(),
|
|
|
|
- val sdk: Int = 29
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Serializable
|
|
|
|
- class V1(
|
|
|
|
- val display: ByteArray,
|
|
|
|
- val product: ByteArray,
|
|
|
|
- val device: ByteArray,
|
|
|
|
- val board: ByteArray,
|
|
|
|
- val brand: ByteArray,
|
|
|
|
- val model: ByteArray,
|
|
|
|
- val bootloader: ByteArray,
|
|
|
|
- val fingerprint: ByteArray,
|
|
|
|
- val bootId: ByteArray,
|
|
|
|
- val procVersion: ByteArray,
|
|
|
|
- val baseBand: ByteArray,
|
|
|
|
- val version: @Serializable(DeviceInfoVersionSerializer::class) DeviceInfo.Version,
|
|
|
|
- val simInfo: ByteArray,
|
|
|
|
- val osType: ByteArray,
|
|
|
|
- val macAddress: ByteArray,
|
|
|
|
- val wifiBSSID: ByteArray,
|
|
|
|
- val wifiSSID: ByteArray,
|
|
|
|
- val imsiMd5: ByteArray,
|
|
|
|
- val imei: String,
|
|
|
|
- val apn: ByteArray
|
|
|
|
- ) : Info {
|
|
|
|
- override fun toDeviceInfo(): DeviceInfo {
|
|
|
|
- return DeviceInfo(
|
|
|
|
- display = display,
|
|
|
|
- product = product,
|
|
|
|
- device = device,
|
|
|
|
- board = board,
|
|
|
|
- brand = brand,
|
|
|
|
- model = model,
|
|
|
|
- bootloader = bootloader,
|
|
|
|
- fingerprint = fingerprint,
|
|
|
|
- bootId = bootId,
|
|
|
|
- procVersion = procVersion,
|
|
|
|
- baseBand = baseBand,
|
|
|
|
- version = version,
|
|
|
|
- simInfo = simInfo,
|
|
|
|
- osType = osType,
|
|
|
|
- macAddress = macAddress,
|
|
|
|
- wifiBSSID = wifiBSSID,
|
|
|
|
- wifiSSID = wifiSSID,
|
|
|
|
- imsiMd5 = imsiMd5,
|
|
|
|
- imei = imei,
|
|
|
|
- apn = apn
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- @Serializable
|
|
|
|
- class V2(
|
|
|
|
- val display: String,
|
|
|
|
- val product: String,
|
|
|
|
- val device: String,
|
|
|
|
- val board: String,
|
|
|
|
- val brand: String,
|
|
|
|
- val model: String,
|
|
|
|
- val bootloader: String,
|
|
|
|
- val fingerprint: String,
|
|
|
|
- val bootId: String,
|
|
|
|
- val procVersion: String,
|
|
|
|
- val baseBand: HexString,
|
|
|
|
- val version: Version,
|
|
|
|
- val simInfo: String,
|
|
|
|
- val osType: String,
|
|
|
|
- val macAddress: String,
|
|
|
|
- val wifiBSSID: String,
|
|
|
|
- val wifiSSID: String,
|
|
|
|
- val imsiMd5: HexString,
|
|
|
|
- val imei: String,
|
|
|
|
- val apn: String
|
|
|
|
- ) : Info {
|
|
|
|
- override fun toDeviceInfo(): DeviceInfo = DeviceInfo(
|
|
|
|
- this.display.toByteArray(),
|
|
|
|
- this.product.toByteArray(),
|
|
|
|
- this.device.toByteArray(),
|
|
|
|
- this.board.toByteArray(),
|
|
|
|
- this.brand.toByteArray(),
|
|
|
|
- this.model.toByteArray(),
|
|
|
|
- this.bootloader.toByteArray(),
|
|
|
|
- this.fingerprint.toByteArray(),
|
|
|
|
- this.bootId.toByteArray(),
|
|
|
|
- this.procVersion.toByteArray(),
|
|
|
|
- this.baseBand.data,
|
|
|
|
- this.version.trans(),
|
|
|
|
- this.simInfo.toByteArray(),
|
|
|
|
- this.osType.toByteArray(),
|
|
|
|
- this.macAddress.toByteArray(),
|
|
|
|
- this.wifiBSSID.toByteArray(),
|
|
|
|
- this.wifiSSID.toByteArray(),
|
|
|
|
- this.imsiMd5.data,
|
|
|
|
- this.imei,
|
|
|
|
- this.apn.toByteArray()
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Serializable
|
|
|
|
- class Version(
|
|
|
|
- val incremental: String,
|
|
|
|
- val release: String,
|
|
|
|
- val codename: String,
|
|
|
|
- val sdk: Int = 29
|
|
|
|
- ) {
|
|
|
|
- companion object {
|
|
|
|
- fun DeviceInfo.Version.trans(): Version {
|
|
|
|
- return Version(incremental.decodeToString(), release.decodeToString(), codename.decodeToString(), sdk)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fun Version.trans(): DeviceInfo.Version {
|
|
|
|
- return DeviceInfo.Version(incremental.toByteArray(), release.toByteArray(), codename.toByteArray(), sdk)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fun DeviceInfo.toCurrentInfo(): V2 = V2(
|
|
|
|
- display.decodeToString(),
|
|
|
|
- product.decodeToString(),
|
|
|
|
- device.decodeToString(),
|
|
|
|
- board.decodeToString(),
|
|
|
|
- brand.decodeToString(),
|
|
|
|
- model.decodeToString(),
|
|
|
|
- bootloader.decodeToString(),
|
|
|
|
- fingerprint.decodeToString(),
|
|
|
|
- bootId.decodeToString(),
|
|
|
|
- procVersion.decodeToString(),
|
|
|
|
- HexString(baseBand),
|
|
|
|
- version.trans(),
|
|
|
|
- simInfo.decodeToString(),
|
|
|
|
- osType.decodeToString(),
|
|
|
|
- macAddress.decodeToString(),
|
|
|
|
- wifiBSSID.decodeToString(),
|
|
|
|
- wifiSSID.decodeToString(),
|
|
|
|
- HexString(imsiMd5),
|
|
|
|
- imei,
|
|
|
|
- apn.decodeToString()
|
|
|
|
- )
|
|
|
|
-
|
|
|
|
- internal val format = Json {
|
|
|
|
- ignoreUnknownKeys = true
|
|
|
|
- isLenient = true
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Throws(IllegalArgumentException::class, NumberFormatException::class) // in case malformed
|
|
|
|
- fun deserialize(string: String, format: Json = this.format): DeviceInfo {
|
|
|
|
- val element = format.parseToJsonElement(string)
|
|
|
|
-
|
|
|
|
- return when (val version = element.jsonObject["deviceInfoVersion"]?.jsonPrimitive?.content?.toInt() ?: 1) {
|
|
|
|
- /**
|
|
|
|
- * @since 2.0
|
|
|
|
- */
|
|
|
|
- 1 -> format.decodeFromJsonElement(V1.serializer(), element)
|
|
|
|
- /**
|
|
|
|
- * @since 2.9
|
|
|
|
- */
|
|
|
|
- 2 -> format.decodeFromJsonElement(Wrapper.serializer(V2.serializer()), element).data
|
|
|
|
- else -> throw IllegalArgumentException("Unsupported deviceInfoVersion: $version")
|
|
|
|
- }.toDeviceInfo()
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fun serialize(info: DeviceInfo, format: Json = this.format): String {
|
|
|
|
- return format.encodeToString(
|
|
|
|
- Wrapper.serializer(V2.serializer()),
|
|
|
|
- Wrapper(2, info.toCurrentInfo())
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- fun toJsonElement(info: DeviceInfo, format: Json = this.format): JsonElement {
|
|
|
|
- return format.encodeToJsonElement(
|
|
|
|
- Wrapper.serializer(V2.serializer()),
|
|
|
|
- Wrapper(2, info.toCurrentInfo())
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/**
|
|
|
|
- * Defaults "%4;7t>;28<fc.5*6".toByteArray()
|
|
|
|
- */
|
|
|
|
-internal fun generateGuid(androidId: ByteArray, macAddress: ByteArray): ByteArray =
|
|
|
|
- (androidId + macAddress).md5()
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-/*
|
|
|
|
-fun DeviceInfo.toOidb0x769DeviceInfo() : Oidb0x769.DeviceInfo = Oidb0x769.DeviceInfo(
|
|
|
|
- brand = brand.encodeToString(),
|
|
|
|
- model = model.encodeToString(),
|
|
|
|
- os = Oidb0x769.OS(
|
|
|
|
- version = version.release.encodeToString(),
|
|
|
|
- sdk = version.sdk.toString(),
|
|
|
|
- kernel = version.kernel
|
|
|
|
- )
|
|
|
|
-)
|
|
|
|
-*/
|
|
|
|
|
|
+}
|