mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-20 17:54:52 +08:00
Use Klock
This commit is contained in:
parent
244996ac28
commit
cf052614f5
@ -19,6 +19,7 @@ allprojects {
|
||||
version = "1.0"
|
||||
|
||||
repositories {
|
||||
jcenter()//klock
|
||||
google()
|
||||
maven { url "https://mirrors.huaweicloud.com/repository/maven/" }
|
||||
}
|
||||
|
@ -30,4 +30,5 @@ ext {
|
||||
kotlinxIOJS = "org.jetbrains.kotlinx:kotlinx-io-js:$kotlinx_io_version"
|
||||
kotlinxIONative = "org.jetbrains.kotlinx:kotlinx-io-native:$kotlinx_io_version"
|
||||
|
||||
klock = "com.soywiz.korlibs.klock:klock:1.7.0"
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ kotlin {
|
||||
implementation rootProject.ext.atomicFUCommon
|
||||
|
||||
implementation rootProject.ext.kotlinxIOCommon
|
||||
implementation rootProject.ext.klock
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +52,7 @@ kotlin {
|
||||
implementation 'org.yaml:snakeyaml:1.18'
|
||||
implementation 'org.jsoup:jsoup:1.12.1'
|
||||
implementation 'org.ini4j:ini4j:0.5.2'
|
||||
implementation rootProject.ext.klock
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,6 @@ import net.mamoe.mirai.utils.toUHexString
|
||||
|
||||
/**
|
||||
* The mirror of functions in inner classes of [Bot]
|
||||
*
|
||||
* @author Him188moe
|
||||
*/
|
||||
|
||||
//Contacts
|
||||
|
@ -147,7 +147,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
|
||||
val expect = expectPacket<ServerTouchResponsePacket>()
|
||||
NetworkScope.launch { processReceive() }
|
||||
NetworkScope.launch {
|
||||
if (withTimeoutOrNull(configuration.touchTimeoutMillis) { expect.join() } == null) {
|
||||
if (withTimeoutOrNull(configuration.touchTimeout.millisecondsLong) { expect.join() } == null) {
|
||||
loginResult.complete(LoginResult.TIMEOUT)
|
||||
}
|
||||
}
|
||||
@ -342,7 +342,7 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
|
||||
this.token00BA = packet.token00BA
|
||||
this.captchaCache = packet.captchaPart1
|
||||
|
||||
if (packet.unknownBoolean == true) {
|
||||
if (packet.unknownBoolean) {
|
||||
this.captchaSectionId = 1
|
||||
socket.sendPacket(ClientCaptchaTransmissionRequestPacket(bot.qqAccount, this.token0825, this.captchaSectionId++, packet.token00BA))
|
||||
}
|
||||
@ -403,11 +403,11 @@ internal class TIMBotNetworkHandler internal constructor(private val bot: Bot) :
|
||||
|
||||
heartbeatJob = NetworkScope.launch {
|
||||
while (socket.isOpen) {
|
||||
delay(configuration.heartbeatPeriodMillis)
|
||||
delay(configuration.heartbeatPeriod.millisecondsLong)
|
||||
with(session) {
|
||||
class HeartbeatTimeoutException : CancellationException("heartbeat timeout")
|
||||
|
||||
if (withTimeoutOrNull(configuration.heartbeatTimeoutMillis) {
|
||||
if (withTimeoutOrNull(configuration.heartbeatTimeout.millisecondsLong) {
|
||||
ClientHeartbeatPacket(bot.qqAccount, sessionKey).sendAndExpect<ServerHeartbeatResponsePacket> {}
|
||||
} == null) {
|
||||
bot.logPurple("Heartbeat timed out")
|
||||
|
@ -20,7 +20,7 @@ object TIMProtocol {
|
||||
).forEach { list.add(solveIpAddress(it)) }
|
||||
|
||||
list.toList()
|
||||
}()
|
||||
}()//不使用lazy是为了在启动时就加载.
|
||||
|
||||
const val head = "02"
|
||||
const val ver = "37 13"
|
||||
@ -36,6 +36,9 @@ object TIMProtocol {
|
||||
const val constantData1 = "00 18 00 16 00 01 "
|
||||
const val constantData2 = "00 00 04 53 00 00 00 01 00 00 15 85 "
|
||||
|
||||
|
||||
//todo 使用 byte array
|
||||
|
||||
/**
|
||||
* Touch 发出时写入, 并用于加密, 接受 sendTouch response 时解密.
|
||||
*/
|
||||
|
@ -22,22 +22,23 @@ class ClientPasswordSubmissionPacket constructor(
|
||||
private val loginIP: String,
|
||||
private val privateKey: ByteArray,
|
||||
private val token0825: ByteArray,
|
||||
private val token00BA: ByteArray? = null,//
|
||||
private val token00BA: ByteArray? = null,
|
||||
private val randomDeviceName: Boolean = false,
|
||||
private val tlv0006: IoBuffer? = null
|
||||
) : ClientPacket() {
|
||||
override fun encode(builder: BytePacketBuilder) = with(builder) {
|
||||
this.writeQQ(bot)
|
||||
this.writeHex(TIMProtocol.passwordSubmissionTLV1)
|
||||
writeQQ(bot)
|
||||
writeHex(TIMProtocol.passwordSubmissionTLV1)
|
||||
|
||||
this.writeShort(25)
|
||||
this.writeHex(TIMProtocol.publicKey)//25
|
||||
writeShort(25)
|
||||
writeHex(TIMProtocol.publicKey)//=25
|
||||
|
||||
this.writeHex("00 00 00 10")//=16
|
||||
this.writeHex(TIMProtocol.key0836)//16
|
||||
writeZero(2)
|
||||
writeShort(16)
|
||||
writeHex(TIMProtocol.key0836)//=16
|
||||
|
||||
//TODO shareKey 极大可能为 publicKey, key0836 计算得到
|
||||
this.encryptAndWrite(TIMProtocol.shareKey.hexToBytes()) {
|
||||
encryptAndWrite(TIMProtocol.shareKey) {
|
||||
writePart1(bot, password, loginTime, loginIP, privateKey, token0825, randomDeviceName, tlv0006)
|
||||
|
||||
if (token00BA != null) {
|
||||
|
@ -127,7 +127,7 @@ class ServerLoginResponseCaptchaInitPacket(input: ByteReadPacket) : ServerLoginR
|
||||
|
||||
lateinit var captchaPart1: IoBuffer
|
||||
lateinit var token00BA: ByteArray
|
||||
var unknownBoolean: Boolean? = null
|
||||
var unknownBoolean: Boolean by Delegates.notNull()
|
||||
|
||||
|
||||
@Tested
|
||||
|
@ -1,5 +1,7 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import com.soywiz.klock.TimeSpan
|
||||
import com.soywiz.klock.seconds
|
||||
import net.mamoe.mirai.network.protocol.tim.packet.login.ServerTouchResponsePacket
|
||||
|
||||
/**
|
||||
@ -9,7 +11,7 @@ class BotNetworkConfiguration {
|
||||
/**
|
||||
* 等待 [ServerTouchResponsePacket] 的时间
|
||||
*/
|
||||
var touchTimeoutMillis: Long = 2000
|
||||
var touchTimeout: TimeSpan = 2.seconds
|
||||
|
||||
/**
|
||||
* 是否使用随机的设备名.
|
||||
@ -21,13 +23,13 @@ class BotNetworkConfiguration {
|
||||
/**
|
||||
* 心跳周期. 过长会导致被服务器断开连接.
|
||||
*/
|
||||
var heartbeatPeriodMillis: Long = 1 * 60 * 1000
|
||||
var heartbeatPeriod: TimeSpan = 60.seconds
|
||||
|
||||
/**
|
||||
* 每次心跳时等待结果的时间.
|
||||
* 一旦心跳超时, 整个网络服务将会重启 (将消耗约 1s). 除正在进行的任务 (如图片上传) 会被中断外, 事件和插件均不受影响.
|
||||
*/
|
||||
var heartbeatTimeoutMillis: Long = 2000
|
||||
var heartbeatTimeout: TimeSpan = 2.seconds
|
||||
|
||||
companion object {
|
||||
val Default = BotNetworkConfiguration()
|
||||
|
@ -1,9 +1,11 @@
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
import com.soywiz.klock.DateTime
|
||||
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
expect val currentTime: Long
|
||||
val currentTime: Long = DateTime.nowUnixLong()
|
||||
|
||||
/**
|
||||
* 设备名
|
||||
|
@ -41,13 +41,22 @@ fun UInt.toByteArray(): ByteArray = byteArrayOf(
|
||||
fun Int.toUHexString(separator: String = " "): String = this.toByteArray().toUHexString(separator)
|
||||
fun Byte.toUHexString(): String = this.toUByte().toString(16).toUpperCase()
|
||||
fun String.hexToBytes(): ByteArray = HexCache.hexToBytes(this)
|
||||
|
||||
/**
|
||||
* 将 Hex 转为 UByteArray, 有根据 hex 的 [hashCode] 建立的缓存.
|
||||
*/
|
||||
fun String.hexToUBytes(): UByteArray = HexCache.hexToUBytes(this)
|
||||
|
||||
fun String.hexToInt(): Int = hexToBytes().toUInt().toInt()
|
||||
fun getRandomByteArray(length: Int): ByteArray = ByteArray(length) { Random.nextInt(0..255).toByte() }
|
||||
fun ByteArray.toUInt(): UInt = this[0].toUInt().and(255u).shl(24) + this[1].toUInt().and(255u).shl(16) + this[2].toUInt().and(255u).shl(8) + this[3].toUInt().and(255u).shl(0)
|
||||
|
||||
fun ByteArray.toIoBuffer(): IoBuffer = IoBuffer.Pool.borrow().let { it.writeFully(this); it }
|
||||
|
||||
/**
|
||||
* Hex 转换 [ByteArray] 和 [UByteArray] 缓存.
|
||||
* 为 [net.mamoe.mirai.network.protocol.tim.TIMProtocol] 的 hex 常量使用
|
||||
*/
|
||||
internal object HexCache {
|
||||
private val hexToByteArrayCacheMap: MutableMap<Int, ByteArray> = mutableMapOf()
|
||||
|
||||
|
@ -8,8 +8,6 @@ import java.net.InetAddress
|
||||
import java.security.MessageDigest
|
||||
import java.util.zip.CRC32
|
||||
|
||||
actual val currentTime: Long = System.currentTimeMillis()
|
||||
|
||||
actual val deviceName: String = InetAddress.getLocalHost().hostName
|
||||
|
||||
|
||||
|
@ -5,9 +5,9 @@ dependencies {
|
||||
implementation project(':mirai-core')
|
||||
compile files('./lib/jpcap.jar')
|
||||
|
||||
compile rootProject.ext.coroutineCommon
|
||||
compile rootProject.ext.kotlinJvm
|
||||
compile rootProject.ext.kotlinxIOJvm
|
||||
implementation rootProject.ext.coroutineCommon
|
||||
implementation rootProject.ext.kotlinJvm
|
||||
implementation rootProject.ext.kotlinxIOJvm
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
|
@ -23,32 +23,11 @@ object Main {
|
||||
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
/*-------------- 第一步绑定网络设备 --------------*/
|
||||
val devices = JpcapCaptor.getDeviceList()
|
||||
|
||||
/*
|
||||
\Device\NPF_{0E7103E4-BF96-4B66-A23B-F6F630D814CD} | Microsoft
|
||||
\Device\NPF_{2CCA31E2-93D5-42F2-92C1-5882E18A8E95} | VMware Virtual Ethernet Adapter
|
||||
\Device\NPF_{A12C8971-858B-4BC8-816C-4077E1636AC5} | VMware Virtual Ethernet Adapter
|
||||
\Device\NPF_{231C4E27-AF20-4362-BCA3-107236CB8A2E} | MS NDIS 6.0 LoopBack Driver
|
||||
\Device\NPF_{500B5537-AA10-4E2F-8F7D-E6BD365BDCD1} | Microsoft
|
||||
\Device\NPF_{A177317B-903A-45B5-8AEA-3698E423ABD6} | Microsoft
|
||||
*/
|
||||
/*
|
||||
for (n in devices) {
|
||||
println(n.name + " | " + n.description)
|
||||
}
|
||||
println("-------------------------------------------")
|
||||
exitProcess(0)*/
|
||||
|
||||
val jpcap: JpcapCaptor?
|
||||
val caplen = 4096
|
||||
val promiscCheck = true
|
||||
|
||||
jpcap = JpcapCaptor.openDevice(devices[0], caplen, promiscCheck, 50)
|
||||
|
||||
|
||||
/*----------第二步抓包-----------------*/
|
||||
while (true) {
|
||||
assert(jpcap != null)
|
||||
val pk = jpcap!!.packet
|
||||
@ -60,7 +39,11 @@ object Main {
|
||||
}
|
||||
|
||||
if (localIp in pk.dst_ip.hostAddress) {//接受
|
||||
dataReceived(pk.data)
|
||||
try {
|
||||
dataReceived(pk.data)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
dataSent(pk.data)
|
||||
@ -88,7 +71,7 @@ object Main {
|
||||
* 6. 运行到 `mov eax,dword ptr ss:[ebp+10]`
|
||||
* 7. 查看内存, 从 `eax` 开始的 16 bytes 便是 `sessionKey`
|
||||
*/
|
||||
val sessionKey: ByteArray = "F1 68 24 ED A8 6D 33 6E 5C B7 E0 F4 45 77 21 04".hexToBytes()
|
||||
val sessionKey: ByteArray = "99 91 B9 8B 79 45 FD CF 51 4A B9 DE 14 61 ED E3".hexToBytes()
|
||||
|
||||
fun dataReceived(data: ByteArray) {
|
||||
println("--------------")
|
||||
|
@ -24,7 +24,6 @@ suspend fun main() {
|
||||
), Console())
|
||||
|
||||
bot.login {
|
||||
touchTimeoutMillis = 2000
|
||||
randomDeviceName = true
|
||||
}.let {
|
||||
if (it != LoginResult.SUCCESS) {
|
||||
|
@ -5,4 +5,6 @@ include(':mirai-api')
|
||||
include(':mirai-demos:mirai-demo-1')
|
||||
include(':mirai-demos')
|
||||
include(':mirai-debug')
|
||||
project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1')
|
||||
project(':mirai-demos:mirai-demo-1').projectDir = file('mirai-demos/mirai-demo-1')
|
||||
|
||||
enableFeaturePreview('GRADLE_METADATA')
|
||||
|
Loading…
Reference in New Issue
Block a user