Skip to content

Commit 5dfaebf

Browse files
committed
string deviceInfo
1 parent fc48e8d commit 5dfaebf

File tree

3 files changed

+223
-3
lines changed

3 files changed

+223
-3
lines changed

build.gradle.kts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ plugins {
2121
id("org.springframework.boot") version "2.3.4.RELEASE"
2222
id("io.spring.dependency-management") version "1.0.10.RELEASE"
2323
id("com.google.protobuf") version "0.8.13"
24+
25+
kotlin("plugin.serialization") version "1.4.10"
2426
kotlin("jvm") version "1.4.0"
2527
kotlin("plugin.spring") version "1.4.0"
2628
}
2729

2830
group = "net.lz1998"
29-
version = "0.0.6"
31+
version = "0.0.7"
3032
java.sourceCompatibility = JavaVersion.VERSION_1_8
3133

3234
configurations {
@@ -46,6 +48,8 @@ repositories {
4648
}
4749

4850
dependencies {
51+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0-RC2")
52+
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.0.0-RC")
4953
implementation("net.mamoe:mirai-core-qqandroid:1.3.1")
5054
implementation("com.squareup.okhttp3:okhttp:4.8.0")
5155
// implementation("com.google.protobuf:protobuf-javalite:3.8.0")
@@ -76,7 +80,7 @@ protobuf {
7680
}
7781
generateProtoTasks {
7882
all().forEach {
79-
it.builtins{
83+
it.builtins {
8084
// remove("java")
8185
// id("java"){
8286
// option("lite")

src/main/kotlin/net/lz1998/mirai/entity/WebSocketBotClient.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import kotlinx.coroutines.launch
66
import kotlinx.coroutines.withContext
77
import net.lz1998.mirai.alias.BFrame
88
import net.lz1998.mirai.alias.BFrameType
9+
import net.lz1998.mirai.ext.fileStrBasedDeviceInfo
910
import net.lz1998.mirai.ext.friendRequestLru
1011
import net.lz1998.mirai.ext.groupRequestLru
1112
import net.lz1998.mirai.ext.messageSourceLru
@@ -97,7 +98,7 @@ class WebsocketBotClient(override var botId: Long, override var password: String
9798
override suspend fun initBot() {
9899
wsClient = httpClient.newWebSocket(wsRequest, wsListener)
99100
bot = Bot(botId, password) {
100-
fileBasedDeviceInfo("device.json")
101+
fileStrBasedDeviceInfo("device.json")
101102
loginSolver = MyLoginSolver
102103
noNetworkLog()
103104
}.alsoLogin()
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
package net.lz1998.mirai.ext
2+
3+
import kotlinx.serialization.Required
4+
import kotlinx.serialization.SerialName
5+
import kotlinx.serialization.Serializable
6+
import kotlinx.serialization.Transient
7+
import kotlinx.serialization.json.Json
8+
import net.mamoe.mirai.utils.BotConfigurationBase
9+
import net.mamoe.mirai.utils.Context
10+
import net.mamoe.mirai.utils.ExternalImage
11+
import net.mamoe.mirai.utils.BotConfiguration
12+
import net.mamoe.mirai.utils.ContextImpl
13+
import net.mamoe.mirai.utils.DeviceInfo
14+
import java.io.File
15+
import java.security.MessageDigest
16+
import kotlin.random.Random
17+
import kotlin.random.nextInt
18+
19+
20+
@Serializable
21+
open class MyDeviceInfo() : DeviceInfo() {
22+
constructor(context: Context) : this() {
23+
this.context = context
24+
}
25+
26+
@Transient
27+
final override lateinit var context: Context
28+
override val androidId: ByteArray
29+
get() = androidIdStr.toByteArray()
30+
31+
override val apn: ByteArray
32+
get() = apnStr.toByteArray()
33+
34+
override val baseBand: ByteArray
35+
get() = byteArrayOf()
36+
37+
override val board: ByteArray
38+
get() = boardStr.toByteArray()
39+
40+
override val bootId: ByteArray
41+
get() = bootIdStr.toByteArray()
42+
43+
override val bootloader: ByteArray
44+
get() = bootloaderStr.toByteArray()
45+
46+
override val brand: ByteArray
47+
get() = brandStr.toByteArray()
48+
49+
override val device: ByteArray
50+
get() = deviceStr.toByteArray()
51+
52+
override val display: ByteArray
53+
get() = displayStr.toByteArray()
54+
55+
override val fingerprint: ByteArray
56+
get() = fingerprintStr.toByteArray()
57+
58+
override val imei: String
59+
get() = imeiStr
60+
61+
override val macAddress: ByteArray
62+
get() = macAddressStr.toByteArray()
63+
64+
override val model: ByteArray
65+
get() = modelStr.toByteArray()
66+
67+
override val osType: ByteArray
68+
get() = osTypeStr.toByteArray()
69+
70+
override val procVersion: ByteArray
71+
get() = procVersionStr.toByteArray()
72+
73+
override val product: ByteArray
74+
get() = productStr.toByteArray()
75+
76+
override val simInfo: ByteArray
77+
get() = simInfoStr.toByteArray()
78+
79+
override val wifiBSSID: ByteArray?
80+
get() = wifiBSSIDStr.toByteArray()
81+
82+
override val wifiSSID: ByteArray?
83+
get() = wifiSSIDStr.toByteArray()
84+
override val version: Version
85+
get() = Version
86+
87+
88+
@Serializable
89+
object Version : DeviceInfo.Version {
90+
override val incremental: ByteArray = "5891938".toByteArray()
91+
override val release: ByteArray = "10".toByteArray()
92+
override val codename: ByteArray = "REL".toByteArray()
93+
override val sdk: Int = 29
94+
}
95+
96+
@Required
97+
@SerialName("androidId")
98+
var androidIdStr: String = "SMC.${getRandomString(6, '0'..'9')}.001"
99+
100+
@Required
101+
@SerialName("apn")
102+
var apnStr: String = "wifi"
103+
104+
@Required
105+
@SerialName("board")
106+
var boardStr: String = "smc"
107+
108+
@SerialName("bootId")
109+
@Required
110+
var bootIdStr: String = ExternalImage.generateUUID(getRandomByteArray(16).md5(0, 16))
111+
112+
@Required
113+
@SerialName("bootloader")
114+
var bootloaderStr: String = "unknown"
115+
116+
@Required
117+
@SerialName("brand")
118+
var brandStr: String = "pbbot"
119+
120+
@Required
121+
@SerialName("device")
122+
var deviceStr: String = "smc"
123+
124+
@Required
125+
@SerialName("display")
126+
var displayStr: String = androidIdStr
127+
128+
@Required
129+
@SerialName("fingerprint")
130+
var fingerprintStr: String = "pbbot/smc/smc:10/SMC.200122.001/${getRandomString(7, '0'..'9')}:user/release-keys"
131+
132+
@Required
133+
@SerialName("macAddress")
134+
var macAddressStr: String = "02:00:00:00:00:00"
135+
136+
@Required
137+
@SerialName("model")
138+
var modelStr: String = "smc"
139+
140+
@Required
141+
@SerialName("osType")
142+
var osTypeStr: String = "android"
143+
144+
@Required
145+
@SerialName("procVersion")
146+
var procVersionStr: String = "Linux version 3.0.31-${getRandomString(8, 'a'..'z')} ([email protected])"
147+
148+
@Required
149+
@SerialName("product")
150+
var productStr: String = "smc"
151+
152+
@Required
153+
@SerialName("simInfo")
154+
var simInfoStr: String = "T-Mobile"
155+
156+
@Required
157+
@SerialName("wifiBSSID")
158+
var wifiBSSIDStr: String = "02:00:00:00:00:00"
159+
160+
@Required
161+
@SerialName("wifiSSID")
162+
var wifiSSIDStr: String = "<unknown ssid>"
163+
164+
@Required
165+
@SerialName("imei")
166+
var imeiStr: String = getRandomString(15, '0'..'9')
167+
168+
@Required
169+
@SerialName("imsiMd5")
170+
override val imsiMd5: ByteArray = getRandomByteArray(16).md5(0, 16)
171+
172+
}
173+
174+
@JvmOverloads
175+
@BotConfigurationBase.ConfigurationDsl
176+
fun BotConfiguration.fileStrBasedDeviceInfo(filepath: String = "device.json") {
177+
deviceInfo = getFileStrBasedDeviceInfoSupplier(filepath)
178+
}
179+
180+
fun BotConfiguration.getFileStrBasedDeviceInfoSupplier(filename: String): ((Context) -> DeviceInfo)? {
181+
return {
182+
File(filename).loadStrAsDeviceInfo(json, it)
183+
}
184+
}
185+
186+
/**
187+
* 加载一个设备信息. 若文件不存在或为空则随机并创建一个设备信息保存.
188+
*/
189+
fun File.loadStrAsDeviceInfo(json: Json, context: Context = ContextImpl()): DeviceInfo {
190+
if (!this.exists() || this.length() == 0L) {
191+
return MyDeviceInfo(context).also {
192+
this.writeText(json.encodeToString(MyDeviceInfo.serializer(), it))
193+
}
194+
}
195+
return json.decodeFromString(MyDeviceInfo.serializer(), this.readText()).also {
196+
it.context = context
197+
}
198+
}
199+
200+
201+
fun getRandomString(length: Int, charRange: CharRange): String =
202+
String(CharArray(length) { charRange.random() })
203+
204+
fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
205+
206+
fun ByteArray.md5(offset: Int, length: Int): ByteArray {
207+
this.checkOffsetAndLength(offset, length)
208+
return MessageDigest.getInstance("MD5").apply { update(this@md5, offset, length) }.digest()
209+
}
210+
211+
fun ByteArray.checkOffsetAndLength(offset: Int, length: Int) {
212+
require(offset >= 0) { "offset shouldn't be negative: $offset" }
213+
require(length >= 0) { "length shouldn't be negative: $length" }
214+
require(offset + length <= this.size) { "offset ($offset) + length ($length) > array.size (${this.size})" }
215+
}

0 commit comments

Comments
 (0)