Commit 7f338edc authored by Him188's avatar Him188

Move files, modularize project

parent 43daf0f1
# UpdateLog # Major version 0
## Major version 0
开发版本. 频繁更新, 不保证高稳定性 开发版本. 频繁更新, 不保证高稳定性
### `0.10.0` *2019/12/23* ## `0.10.1` 还未发布
**Bot 构造**
`Bot` 构造时修改 `BotConfiguration` 而不是登录时.
移除 `CoroutineScope.Bot`
移除 `suspend Bot(...)`
添加 `Bot(..., BotConfiguration.() -> Unit)`
**其他**
移动部分文件, 模块化
## `0.10.0` *2019/12/23*
**事件优化** **事件优化**
更快的监听过程 更快的监听过程
现在监听不再是 `suspend`, 而必须显式指定 `CoroutineScope`. 详见 [`Subscribers.kt`](mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt#L69) 现在监听不再是 `suspend`, 而必须显式指定 `CoroutineScope`. 详见 [`Subscribers.kt`](mirai-core/src/commonMain/kotlin/net.mamoe.mirai/event/Subscribers.kt#L69)
...@@ -13,7 +21,7 @@ ...@@ -13,7 +21,7 @@
**其他** **其他**
`Contact` 现在实现接口 `CoroutineScope` `Contact` 现在实现接口 `CoroutineScope`
### `0.9.0` *2019/12/20* ## `0.9.0` *2019/12/20*
**协议模块独立** **协议模块独立**
现在 `mirai-core` 只提供基础的抽象类. 具体的各协议实现为 `mirai-core-PROTOCOL`. 现在 `mirai-core` 只提供基础的抽象类. 具体的各协议实现为 `mirai-core-PROTOCOL`.
这些模块都继承自 `mirai-core`. 这些模块都继承自 `mirai-core`.
...@@ -35,15 +43,15 @@ ...@@ -35,15 +43,15 @@
**此为 API 不兼容更新**, 请将所有无符号标志 `u` 删除即可. 如 `123456u` 改为 `123456` **此为 API 不兼容更新**, 请将所有无符号标志 `u` 删除即可. 如 `123456u` 改为 `123456`
另还有其他 API 的包名或签名修改. 请使用 IDE 自动修补 import 即可. 另还有其他 API 的包名或签名修改. 请使用 IDE 自动修补 import 即可.
### `0.8.2` *2019/12/15* ## `0.8.2` *2019/12/15*
- 修复 GroupId.toGroupInternalId 错误 - 修复 GroupId.toGroupInternalId 错误
- 修复解析群消息时小概率出现的一个错误 - 修复解析群消息时小概率出现的一个错误
### `0.8.1` *2019/12/15* ## `0.8.1` *2019/12/15*
- 修复有时群资料无法获取的情况 - 修复有时群资料无法获取的情况
- 现在 `At.qq`, `Long.qq` 等函数不再是 `suspend` - 现在 `At.qq`, `Long.qq` 等函数不再是 `suspend`
### `0.8.0` *2019/12/14* ## `0.8.0` *2019/12/14*
协议 协议
- 现在查询群资料时可处理群号无效的情况 - 现在查询群资料时可处理群号无效的情况
- 现在能正常分辨禁言事件包 - 现在能正常分辨禁言事件包
...@@ -56,28 +64,28 @@ ...@@ -56,28 +64,28 @@
优化 优化
- 日志中, 发送给服务器的包将会被以名字记录, 而不是 id - 日志中, 发送给服务器的包将会被以名字记录, 而不是 id
### `0.7.5` *2019/12/09* ## `0.7.5` *2019/12/09*
- 修复验证码包发出后无回复 (错误的验证码包) - 修复验证码包发出后无回复 (错误的验证码包)
### `0.7.4` *2019/12/08* ## `0.7.4` *2019/12/08*
- 修复 bug - 修复 bug
- 优化 JVM 平台上需要验证码时的提示 - 优化 JVM 平台上需要验证码时的提示
### `0.7.3` *2019/12/07* ## `0.7.3` *2019/12/07*
- 删除 klock 依赖, 添加 Time.kt. 待将来 kotlin Duration 稳定后替换为 Duration - 删除 klock 依赖, 添加 Time.kt. 待将来 kotlin Duration 稳定后替换为 Duration
### `0.7.2` *2019/12/07* ## `0.7.2` *2019/12/07*
- 使所有协议相关类 `internal` - 使所有协议相关类 `internal`
- 去掉一些 `close` 的不应该有的 `suspend` - 去掉一些 `close` 的不应该有的 `suspend`
- `QQ`, `Member`, `Group` 现在继承接口 `CoroutineScope` - `QQ`, `Member`, `Group` 现在继承接口 `CoroutineScope`
-`LoginResult``inline class` 修改为 `enum class` -`LoginResult``inline class` 修改为 `enum class`
- 添加和修改了 `BotAccount``Bot` 的构造器 - 添加和修改了 `BotAccount``Bot` 的构造器
### `0.7.1` *2019/12/05* ## `0.7.1` *2019/12/05*
- 修复禁言时间范围错误的问题 - 修复禁言时间范围错误的问题
- 禁言的扩展函数现在会传递实际函数的返回值 - 禁言的扩展函数现在会传递实际函数的返回值
### `0.7.0` *2019/12/04* ## `0.7.0` *2019/12/04*
协议 协议
- 重新分析验证码包, 解决一些无法解析的情况. (这可能会产生新的问题, 遇到后请提交 issue) - 重新分析验证码包, 解决一些无法解析的情况. (这可能会产生新的问题, 遇到后请提交 issue)
- 重新分析提交密码包 - 重新分析提交密码包
...@@ -97,11 +105,11 @@ ...@@ -97,11 +105,11 @@
- 2 个 Contact.sendMessage 重载改为内联扩展函数 **(需要添加 import)** - 2 个 Contact.sendMessage 重载改为内联扩展函数 **(需要添加 import)**
- 其他小优化 - 其他小优化
### `0.6.1` *2019/12/03* ## `0.6.1` *2019/12/03*
- 新增: 无法解析密码包/验证码包时的调试输出. 以兼容更多的设备情况 - 新增: 无法解析密码包/验证码包时的调试输出. 以兼容更多的设备情况
- 新增: `MessagePacket``At.qq()` 捷径获取 QQ - 新增: `MessagePacket``At.qq()` 捷径获取 QQ
### `0.6.0` *2019/12/02* ## `0.6.0` *2019/12/02*
- 新增: 禁言群成员 (`Member.mute(TimeSpan|Duration|MonthsSpan|Int|UInt)`) - 新增: 禁言群成员 (`Member.mute(TimeSpan|Duration|MonthsSpan|Int|UInt)`)
- 新增: 解禁群成员 (`Member.unmute()`) - 新增: 解禁群成员 (`Member.unmute()`)
- 修复: ContactList key 无法匹配 (Kotlin 内联类型泛型投影错误) - 修复: ContactList key 无法匹配 (Kotlin 内联类型泛型投影错误)
...@@ -104,7 +104,7 @@ kotlin { ...@@ -104,7 +104,7 @@ kotlin {
api(kotlin("test-junit", kotlinVersion)) api(kotlin("test-junit", kotlinVersion))
implementation("org.pcap4j:pcap4j-distribution:1.8.2") implementation("org.pcap4j:pcap4j-distribution:1.8.2")
//runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE runtimeOnly(files("build/classes/kotlin/jvm/test")) // classpath is not properly set by IDE
} }
} }
} }
......
...@@ -11,9 +11,6 @@ import net.mamoe.mirai.data.Packet ...@@ -11,9 +11,6 @@ import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.message.data.Image import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.ImageId0x03 import net.mamoe.mirai.message.data.ImageId0x03
import net.mamoe.mirai.message.data.ImageId0x06 import net.mamoe.mirai.message.data.ImageId0x06
import net.mamoe.mirai.network.packet.KnownPacketId
import net.mamoe.mirai.network.packet.OutgoingPacket
import net.mamoe.mirai.network.packet.SessionKey
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.internal.RawGroupInfo import net.mamoe.mirai.timpc.internal.RawGroupInfo
import net.mamoe.mirai.timpc.network.GroupImpl import net.mamoe.mirai.timpc.network.GroupImpl
...@@ -21,13 +18,15 @@ import net.mamoe.mirai.timpc.network.MemberImpl ...@@ -21,13 +18,15 @@ import net.mamoe.mirai.timpc.network.MemberImpl
import net.mamoe.mirai.timpc.network.QQImpl import net.mamoe.mirai.timpc.network.QQImpl
import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler
import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler
import net.mamoe.mirai.timpc.network.packet.KnownPacketId
import net.mamoe.mirai.timpc.network.packet.OutgoingPacket
import net.mamoe.mirai.timpc.network.packet.SessionKey
import net.mamoe.mirai.timpc.network.packet.action.* import net.mamoe.mirai.timpc.network.packet.action.*
import net.mamoe.mirai.timpc.network.packet.event.EventPacketFactory import net.mamoe.mirai.timpc.network.packet.event.EventPacketFactory
import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket
import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.timpc.network.packet.login.*
import net.mamoe.mirai.timpc.utils.assertUnreachable import net.mamoe.mirai.timpc.utils.assertUnreachable
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
import net.mamoe.mirai.utils.io.logStacktrace import net.mamoe.mirai.utils.io.logStacktrace
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
......
...@@ -20,10 +20,14 @@ import net.mamoe.mirai.timpc.network.packet.action.* ...@@ -20,10 +20,14 @@ import net.mamoe.mirai.timpc.network.packet.action.*
import net.mamoe.mirai.timpc.network.packet.event.MemberJoinEventPacket import net.mamoe.mirai.timpc.network.packet.event.MemberJoinEventPacket
import net.mamoe.mirai.timpc.network.packet.event.MemberQuitEvent import net.mamoe.mirai.timpc.network.packet.event.MemberQuitEvent
import net.mamoe.mirai.timpc.sendPacket import net.mamoe.mirai.timpc.sendPacket
import net.mamoe.mirai.utils.OverFileSizeMaxException
import net.mamoe.mirai.timpc.utils.assertUnreachable import net.mamoe.mirai.timpc.utils.assertUnreachable
import net.mamoe.mirai.timpc.withTIMPCBot import net.mamoe.mirai.timpc.withTIMPCBot
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.Http
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.unsafeWeakRef
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
internal sealed class ContactImpl : Contact { internal sealed class ContactImpl : Contact {
......
...@@ -7,6 +7,7 @@ import kotlinx.io.core.* ...@@ -7,6 +7,7 @@ import kotlinx.io.core.*
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.LoginResult import net.mamoe.mirai.data.LoginResult
import net.mamoe.mirai.data.OnlineStatus
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.event.BroadcastControllable import net.mamoe.mirai.event.BroadcastControllable
import net.mamoe.mirai.event.Cancellable import net.mamoe.mirai.event.Cancellable
...@@ -14,15 +15,17 @@ import net.mamoe.mirai.event.Subscribable ...@@ -14,15 +15,17 @@ import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.BotLoginSucceedEvent import net.mamoe.mirai.event.events.BotLoginSucceedEvent
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.TIMPCBot import net.mamoe.mirai.timpc.TIMPCBot
import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter
import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler import net.mamoe.mirai.timpc.network.handler.TemporaryPacketHandler
import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.timpc.network.packet.login.*
import net.mamoe.mirai.utils.LockFreeLinkedList import net.mamoe.mirai.utils.LockFreeLinkedList
import net.mamoe.mirai.utils.LoginFailedException import net.mamoe.mirai.utils.LoginFailedException
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.utils.cryptor.Decrypter
import net.mamoe.mirai.utils.cryptor.NoDecrypter
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.unsafeWeakRef import net.mamoe.mirai.utils.unsafeWeakRef
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused", "MemberVisibilityCanBePrivate") @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS", "unused", "MemberVisibilityCanBePrivate")
package net.mamoe.mirai.network.packet package net.mamoe.mirai.timpc.network.packet
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
...@@ -63,17 +65,14 @@ inline fun PacketFactory<*, *>.buildOutgoingPacket0( ...@@ -63,17 +65,14 @@ inline fun PacketFactory<*, *>.buildOutgoingPacket0(
callsInPlace(block, InvocationKind.EXACTLY_ONCE) callsInPlace(block, InvocationKind.EXACTLY_ONCE)
} }
BytePacketBuilder(headerSizeHint).use { return OutgoingPacket(name, id, sequenceId, buildPacket(headerSizeHint) {
with(it) { writeFully(head)
writeFully(head) writeFully(ver)
writeFully(ver) writeUShort(id.value.toUShort())
writeUShort(id.value) writeUShort(sequenceId)
writeUShort(sequenceId) block(this)
block(this) writeFully(tail)
writeFully(tail) })
}
return OutgoingPacket(name, id, sequenceId, it.build())
}
} }
......
...@@ -2,7 +2,7 @@ package net.mamoe.mirai.timpc.network.packet ...@@ -2,7 +2,7 @@ package net.mamoe.mirai.timpc.network.packet
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.SerializationStrategy
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
......
package net.mamoe.mirai.network.packet package net.mamoe.mirai.timpc.network.packet
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
package net.mamoe.mirai.network.packet package net.mamoe.mirai.timpc.network.packet
import kotlinx.atomicfu.AtomicInt
import kotlinx.atomicfu.atomic import kotlinx.atomicfu.atomic
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
...@@ -9,14 +10,16 @@ import kotlinx.io.core.readBytes ...@@ -9,14 +10,16 @@ import kotlinx.io.core.readBytes
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.utils.cryptor.Decrypter
import net.mamoe.mirai.utils.cryptor.DecrypterType
import net.mamoe.mirai.utils.cryptor.readProtoMap
import net.mamoe.mirai.utils.io.ByteArrayPool import net.mamoe.mirai.utils.io.ByteArrayPool
import net.mamoe.mirai.utils.io.debugPrint import net.mamoe.mirai.utils.io.debugPrint
import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.readProtoMap
/** /**
* 一种数据包的处理工厂. 它可以解密解码服务器发来的这个包, 也可以编码加密要发送给服务器的这个包 * 一种数据包的处理工厂. 它可以解密解码服务器发来的这个包, 也可以编码加密要发送给服务器的这个包
...@@ -40,7 +43,6 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d ...@@ -40,7 +43,6 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
*/ */
abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler): TPacket abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler): TPacket
@Suppress("DEPRECATION")
fun <T> ByteReadPacket.decodeProtoPacket( fun <T> ByteReadPacket.decodeProtoPacket(
deserializer: DeserializationStrategy<T>, deserializer: DeserializationStrategy<T>,
debuggingTag: String? = null debuggingTag: String? = null
...@@ -63,10 +65,16 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d ...@@ -63,10 +65,16 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
} }
companion object { companion object {
private val sequenceIdInternal = atomic(1) private val sequenceId: AtomicInt = atomic(1)
@MiraiInternalAPI fun atomicNextSequenceId(): UShort {
fun atomicNextSequenceId(): UShort = sequenceIdInternal.getAndIncrement().toUShort() val id = sequenceId.getAndAdd(1)
if (id > Short.MAX_VALUE.toInt() * 2) {
sequenceId.value = 0
return atomicNextSequenceId()
}
return id.toUShort()
}
} }
} }
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") @file:Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS")
package net.mamoe.mirai.network.packet package net.mamoe.mirai.timpc.network.packet
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
/**
* 包 ID.
*/
interface PacketId {
val value: UShort
val factory: PacketFactory<*, *>
}
/** /**
* 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId]. * 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId].
*/ */
...@@ -13,13 +22,6 @@ fun matchPacketId(value: UShort): PacketId = ...@@ -13,13 +22,6 @@ fun matchPacketId(value: UShort): PacketId =
?: KnownPacketId.entries.firstOrNull { it.value.value == value }?.value ?: KnownPacketId.entries.firstOrNull { it.value.value == value }?.value
?: UnknownPacketId(value) ?: UnknownPacketId(value)
/**
* 包 ID.
*/
interface PacketId {
val value: UShort
val factory: PacketFactory<*, *>
}
/** /**
* 用于代表 `null`. 调用任何属性时都将会得到一个 [error] * 用于代表 `null`. 调用任何属性时都将会得到一个 [error]
...@@ -49,7 +51,8 @@ inline class IgnoredPacketId constructor(override val value: UShort) : PacketId ...@@ -49,7 +51,8 @@ inline class IgnoredPacketId constructor(override val value: UShort) : PacketId
override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})" override fun toString(): String = "IgnoredPacketId(${value.toUHexString()})"
} }
class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) : PacketId { class KnownPacketId(override val value: UShort, override val factory: PacketFactory<*, *>) :
PacketId {
companion object : MutableMap<UShort, KnownPacketId> by mutableMapOf() { companion object : MutableMap<UShort, KnownPacketId> by mutableMapOf() {
operator fun set(key: UShort, factory: PacketFactory<*, *>) { operator fun set(key: UShort, factory: PacketFactory<*, *>) {
this[key] = KnownPacketId(key, factory) this[key] = KnownPacketId(key, factory)
...@@ -65,7 +68,8 @@ class KnownPacketId(override val value: UShort, override val factory: PacketFact ...@@ -65,7 +68,8 @@ class KnownPacketId(override val value: UShort, override val factory: PacketFact
return null return null
} }
inline fun <reified PF : PacketFactory<*, *>> get(): KnownPacketId = getOrNull<PF>() ?: throw NoSuchElementException() inline fun <reified PF : PacketFactory<*, *>> get(): KnownPacketId = getOrNull<PF>()
?: throw NoSuchElementException()
} }
override fun toString(): String = (factory::class.simpleName ?: factory::class.simpleName) + "(${value.toUHexString()})" override fun toString(): String = (factory::class.simpleName ?: factory::class.simpleName) + "(${value.toUHexString()})"
......
package net.mamoe.mirai.timpc.network.packet
import net.mamoe.mirai.utils.cryptor.DecrypterByteArray
import net.mamoe.mirai.utils.cryptor.DecrypterType
/**
* 会话密匙
*/
inline class SessionKey(override val value: ByteArray) : DecrypterByteArray {
companion object Type : DecrypterType<SessionKey>
}
...@@ -8,9 +8,10 @@ import net.mamoe.mirai.network.BotNetworkHandler ...@@ -8,9 +8,10 @@ import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.data.PreviousNameList import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
...@@ -10,10 +10,10 @@ import net.mamoe.mirai.message.data.ImageId ...@@ -10,10 +10,10 @@ import net.mamoe.mirai.message.data.ImageId
import net.mamoe.mirai.message.data.ImageId0x06 import net.mamoe.mirai.message.data.ImageId0x06
import net.mamoe.mirai.message.data.requireLength import net.mamoe.mirai.message.data.requireLength
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
...@@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action ...@@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.network.packet.SessionPacketFactory
import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory
// 0001 // 0001
......
...@@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully ...@@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully
import kotlinx.io.core.writeUByte import kotlinx.io.core.writeUByte
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
......
...@@ -11,8 +11,9 @@ import net.mamoe.mirai.message.data.requireLength ...@@ -11,8 +11,9 @@ import net.mamoe.mirai.message.data.requireLength
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.data.ImageLink import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.network.packet.buildSessionProtoPacket import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.timpc.utils.assertUnreachable import net.mamoe.mirai.timpc.utils.assertUnreachable
import net.mamoe.mirai.utils.ExternalImage import net.mamoe.mirai.utils.ExternalImage
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
......
...@@ -10,12 +10,13 @@ import net.mamoe.mirai.data.Packet ...@@ -10,12 +10,13 @@ import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.message.data.MessageChain import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.internal.RawGroupInfo import net.mamoe.mirai.timpc.internal.RawGroupInfo
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.utils.unsupportedFlag import net.mamoe.mirai.timpc.utils.unsupportedFlag
import net.mamoe.mirai.timpc.utils.unsupportedType import net.mamoe.mirai.timpc.utils.unsupportedType
import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import kotlin.collections.set import kotlin.collections.set
......
...@@ -8,8 +8,9 @@ import net.mamoe.mirai.data.Gender ...@@ -8,8 +8,9 @@ import net.mamoe.mirai.data.Gender
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.data.Profile import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
inline class AvatarLink(val value: String) : Packet inline class AvatarLink(val value: String) : Packet
......
...@@ -6,8 +6,9 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,8 +6,9 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.FriendNameRemark import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.readUShortLVString import net.mamoe.mirai.utils.io.readUShortLVString
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
import net.mamoe.mirai.utils.io.writeZero import net.mamoe.mirai.utils.io.writeZero
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
package net.mamoe.mirai.timpc.network.packet.action package net.mamoe.mirai.timpc.network.packet.action
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.writeZero import net.mamoe.mirai.utils.io.writeZero
class FriendList : Packet class FriendList : Packet
......
...@@ -7,9 +7,11 @@ import net.mamoe.mirai.message.data.MessageChain ...@@ -7,9 +7,11 @@ import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.internal.toPacket import net.mamoe.mirai.message.internal.toPacket
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.md5 import net.mamoe.mirai.utils.md5
......
...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.readBoolean import net.mamoe.mirai.utils.io.readBoolean
......
...@@ -6,10 +6,10 @@ import kotlinx.io.core.* ...@@ -6,10 +6,10 @@ import kotlinx.io.core.*
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler
import net.mamoe.mirai.qqAccount import net.mamoe.mirai.qqAccount
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.io.readIoBuffer import net.mamoe.mirai.utils.io.readIoBuffer
/** /**
......
...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readQQ
import net.mamoe.mirai.utils.io.readUShortLVString import net.mamoe.mirai.utils.io.readUShortLVString
......
...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket ...@@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readQQ
......
...@@ -5,11 +5,12 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -5,11 +5,12 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUByte import kotlinx.io.core.readUByte
import net.mamoe.mirai.data.OnlineStatus
import net.mamoe.mirai.event.events.FriendStatusChanged import net.mamoe.mirai.event.events.FriendStatusChanged
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.network.packet.SessionPacketFactory
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory
import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readQQ
/** /**
...@@ -21,7 +22,8 @@ internal object FriendOnlineStatusChangedPacket : SessionPacketFactory<FriendSta ...@@ -21,7 +22,8 @@ internal object FriendOnlineStatusChangedPacket : SessionPacketFactory<FriendSta
val qq = readQQ() val qq = readQQ()
discardExact(8) discardExact(8)
val statusId = readUByte() val statusId = readUByte()
val status = OnlineStatus(statusId)
val status = OnlineStatus.ofId(statusId.toInt())
return FriendStatusChanged(handler.bot.getQQ(qq), status) return FriendStatusChanged(handler.bot.getQQ(qq), status)
} }
......
...@@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event ...@@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.debugPrint import net.mamoe.mirai.utils.io.debugPrint
......
...@@ -8,7 +8,7 @@ import net.mamoe.mirai.Bot ...@@ -8,7 +8,7 @@ import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.io.readQQ import net.mamoe.mirai.utils.io.readQQ
......
...@@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission ...@@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.message.GroupMessage import net.mamoe.mirai.message.GroupMessage
import net.mamoe.mirai.message.internal.readMessageChain import net.mamoe.mirai.message.internal.readMessageChain
import net.mamoe.mirai.message.FriendMessage import net.mamoe.mirai.message.FriendMessage
import net.mamoe.mirai.network.packet.PacketVersion import net.mamoe.mirai.utils.PacketVersion
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
......
...@@ -5,9 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login ...@@ -5,9 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.OutgoingPacket
import net.mamoe.mirai.timpc.network.packet.PacketFactory
import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
import net.mamoe.mirai.utils.cryptor.DecrypterByteArray
import net.mamoe.mirai.utils.cryptor.DecrypterType
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
internal object CaptchaKey : DecrypterByteArray, internal object CaptchaKey : DecrypterByteArray,
......
...@@ -5,21 +5,20 @@ package net.mamoe.mirai.timpc.network.packet.login ...@@ -5,21 +5,20 @@ package net.mamoe.mirai.timpc.network.packet.login
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import kotlinx.io.core.writeUByte import kotlinx.io.core.writeUByte
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.data.OnlineStatus
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.utils.cryptor.NoDecrypter
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
/** /**
* 改变在线状态: "我在线上", "隐身" 等 * 改变在线状态: "我在线上", "隐身" 等
*/ */
internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>( internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>(NoDecrypter) {
NoDecrypter
) {
operator fun invoke( operator fun invoke(
bot: Long, bot: Long,
sessionKey: SessionKey, sessionKey: SessionKey,
...@@ -29,7 +28,7 @@ internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacke ...@@ -29,7 +28,7 @@ internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacke
writeFully(TIMProtocol.fixVer2) writeFully(TIMProtocol.fixVer2)
encryptAndWrite(sessionKey) { encryptAndWrite(sessionKey) {
writeHex("01 00") writeHex("01 00")
writeUByte(loginStatus.id) writeUByte(loginStatus.id.toUByte())
writeHex("00 01 00 01 00 04 00 00 00 00") writeHex("00 01 00 01 00 04 00 00 00 00")
} }
} }
......
...@@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully ...@@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully
import net.mamoe.mirai.event.Subscribable import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.* import net.mamoe.mirai.utils.NoLog
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.writeHex import net.mamoe.mirai.utils.io.writeHex
import net.mamoe.mirai.utils.io.writeQQ import net.mamoe.mirai.utils.io.writeQQ
......
...@@ -7,10 +7,13 @@ import net.mamoe.mirai.data.Gender ...@@ -7,10 +7,13 @@ import net.mamoe.mirai.data.Gender
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.LoginResult import net.mamoe.mirai.data.LoginResult
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.OutgoingPacket
import net.mamoe.mirai.timpc.network.packet.PacketFactory
import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.cryptor.*
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
internal object ShareKey : DecrypterByteArray, internal object ShareKey : DecrypterByteArray,
...@@ -366,4 +369,9 @@ private fun BytePacketBuilder.writePart2() { ...@@ -366,4 +369,9 @@ private fun BytePacketBuilder.writePart2() {
this.writeCRC32() this.writeCRC32()
} }
internal fun BytePacketBuilder.writeCRC32() = writeCRC32(getRandomByteArray(16))
internal fun BytePacketBuilder.writeCRC32(key: ByteArray) {
writeFully(key)//key
writeInt(crc32(key))
}
...@@ -7,9 +7,9 @@ import kotlinx.io.core.discardExact ...@@ -7,9 +7,9 @@ import kotlinx.io.core.discardExact
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
internal inline class SKey( internal inline class SKey(
......
...@@ -5,10 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.login ...@@ -5,10 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.login
import kotlinx.io.core.* import kotlinx.io.core.*
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.packet.PacketFactory
import net.mamoe.mirai.network.packet.PacketId
import net.mamoe.mirai.network.packet.SessionKey
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.PacketFactory
import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.SessionKey
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import net.mamoe.mirai.utils.localIpAddress import net.mamoe.mirai.utils.localIpAddress
......
...@@ -8,9 +8,13 @@ import kotlinx.io.core.readBytes ...@@ -8,9 +8,13 @@ import kotlinx.io.core.readBytes
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.data.Packet import net.mamoe.mirai.data.Packet
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.OutgoingPacket
import net.mamoe.mirai.timpc.network.packet.PacketFactory
import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
import net.mamoe.mirai.utils.cryptor.DecrypterByteArray
import net.mamoe.mirai.utils.cryptor.DecrypterType
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
internal object TouchKey : DecrypterByteArray, internal object TouchKey : DecrypterByteArray,
......
package net.mamoe.mirai.timpc.utils
import kotlinx.io.core.toByteArray
private const val GTK_BASE_VALUE: Int = 5381
fun getGTK(sKey: String): Int {
var value = GTK_BASE_VALUE
for (c in sKey.toByteArray()) {
value += (value shl 5) + c.toInt()
}
value = value and Int.MAX_VALUE
return value
}
package net.mamoe.mirai.timpc.utils
import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.writeFully
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf
fun <T> BytePacketBuilder.writeProto(serializer: SerializationStrategy<T>, obj: T) = writeFully(ProtoBuf.dump(serializer, obj))
...@@ -16,14 +16,17 @@ import kotlinx.serialization.internal.ArrayListSerializer ...@@ -16,14 +16,17 @@ import kotlinx.serialization.internal.ArrayListSerializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.network.BotNetworkHandler import net.mamoe.mirai.network.BotNetworkHandler
import net.mamoe.mirai.network.packet.*
import net.mamoe.mirai.timpc.TIMPC import net.mamoe.mirai.timpc.TIMPC
import net.mamoe.mirai.timpc.network.TIMProtocol import net.mamoe.mirai.timpc.network.TIMProtocol
import net.mamoe.mirai.timpc.network.packet.*
import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket
import net.mamoe.mirai.timpc.network.packet.event.IgnoredEventPacket import net.mamoe.mirai.timpc.network.packet.event.IgnoredEventPacket
import net.mamoe.mirai.timpc.network.packet.login.* import net.mamoe.mirai.timpc.network.packet.login.*
import net.mamoe.mirai.utils.DecryptionFailedException import net.mamoe.mirai.utils.cryptor.Decrypter
import net.mamoe.mirai.utils.decryptBy import net.mamoe.mirai.utils.cryptor.DecryptionFailedException
import net.mamoe.mirai.utils.cryptor.NoDecrypter
import net.mamoe.mirai.utils.cryptor.decryptBy
import net.mamoe.mirai.utils.io.* import net.mamoe.mirai.utils.io.*
import org.pcap4j.core.BpfProgram.BpfCompileMode import org.pcap4j.core.BpfProgram.BpfCompileMode
import org.pcap4j.core.PacketListener import org.pcap4j.core.PacketListener
...@@ -181,13 +184,13 @@ internal object PacketDebugger { ...@@ -181,13 +184,13 @@ internal object PacketDebugger {
* 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey` * 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `sessionKey`
*/ */
val sessionKey: SessionKey = val sessionKey: SessionKey =
SessionKey("95 F3 24 8E 7B B6 62 AA 98 C0 EE 45 CE CE 2B 69".hexToBytes()) SessionKey("D8 D0 B0 DE 37 53 9B 05 A5 E7 AB 96 B2 AC AD EC".hexToBytes())
// TODO: 2019/12/7 无法访问 internal 是 kotlin bug, KT-34849 // TODO: 2019/12/7 无法访问 internal 是 kotlin bug, KT-34849
/** /**
* null 则不筛选 * null 则不筛选
*/ */
val qq: Long? = 761025446 val qq: Long? = null
/** /**
* 打开后则记录每一个包到文件. * 打开后则记录每一个包到文件.
*/ */
...@@ -204,7 +207,7 @@ internal object PacketDebugger { ...@@ -204,7 +207,7 @@ internal object PacketDebugger {
//println("raw = " + data.toUHexString()) //println("raw = " + data.toUHexString())
data.read { data.read {
discardExact(3) discardExact(3)
val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort()) val id = matchPacketId(readUShort())
val sequenceId = readUShort() val sequenceId = readUShort()
val packetQQ = readQQ() val packetQQ = readQQ()
if (id == KnownPacketId.get<HeartbeatPacket>() || (qq != null && packetQQ != qq)) if (id == KnownPacketId.get<HeartbeatPacket>() || (qq != null && packetQQ != qq))
...@@ -301,7 +304,7 @@ internal object PacketDebugger { ...@@ -301,7 +304,7 @@ internal object PacketDebugger {
// 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35 // 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35
discardExact(3)//head discardExact(3)//head
val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort()) val id = net.mamoe.mirai.timpc.network.packet.matchPacketId(readUShort())
val sequence = readUShort().toUHexString() val sequence = readUShort().toUHexString()
if (IgnoredPacketIdList.contains(id)) { if (IgnoredPacketIdList.contains(id)) {
return return
......
...@@ -3,8 +3,9 @@ package packetdebugger ...@@ -3,8 +3,9 @@ package packetdebugger
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.discardExact import kotlinx.io.core.discardExact
import kotlinx.io.core.readUShort import kotlinx.io.core.readUShort
import net.mamoe.mirai.network.packet.PacketId import net.mamoe.mirai.timpc.network.packet.PacketId
import net.mamoe.mirai.network.packet.matchPacketId
import net.mamoe.mirai.timpc.network.packet.matchPacketId
import kotlin.contracts.ExperimentalContracts import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
package net.mamoe.mirai package net.mamoe.mirai
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.network.packet.NullPacketId.factory
import net.mamoe.mirai.utils.BotConfiguration import net.mamoe.mirai.utils.BotConfiguration
import net.mamoe.mirai.utils.MiraiLogger import net.mamoe.mirai.utils.MiraiLogger
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
......
...@@ -4,7 +4,7 @@ package net.mamoe.mirai.contact ...@@ -4,7 +4,7 @@ package net.mamoe.mirai.contact
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import net.mamoe.mirai.data.GroupInfo import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail import net.mamoe.mirai.utils.coerceAtLeastOrFail
/** /**
......
package net.mamoe.mirai.data
/**
* 在线状态
*/
enum class OnlineStatus(val id: Int) {
/**
* 我在线上
*/
ONLINE(11), // 0x0A
/**
* 离线
*/
OFFLINE(21), // 0x02
/**
* 离开
*/
AWAY(31),
/**
* 隐身
*/
INVISIABLE(41),
/**
* 忙碌
*/
BUSY(50), // 0x32
/**
* Q 我吧
*/
Q_ME(60),
/**
* 请勿打扰
*/
DND(70),
/**
* 离线但接收消息
*/
RECEIVE_OFFLINE_MESSAGE(95);
companion object {
fun ofId(id: Int): OnlineStatus = values().first { it.id == id }
fun ofIdOrNull(id: Int): OnlineStatus? = values().firstOrNull { it.id == id }
}
}
\ No newline at end of file
...@@ -2,7 +2,7 @@ package net.mamoe.mirai.event.events ...@@ -2,7 +2,7 @@ package net.mamoe.mirai.event.events
import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.EventPacket import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.utils.OnlineStatus import net.mamoe.mirai.data.OnlineStatus
data class FriendStatusChanged( data class FriendStatusChanged(
val qq: QQ, val qq: QQ,
......
...@@ -10,7 +10,7 @@ import net.mamoe.mirai.data.ImageLink ...@@ -10,7 +10,7 @@ import net.mamoe.mirai.data.ImageLink
import net.mamoe.mirai.event.events.BotEvent import net.mamoe.mirai.event.events.BotEvent
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail import net.mamoe.mirai.utils.coerceAtLeastOrFail
import kotlin.jvm.JvmName import kotlin.jvm.JvmName
/** /**
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused")
package net.mamoe.mirai.network.packet
/**
* 包的最后一次修改时间, 和分析时使用的 TIM 版本
*/
@MustBeDocumented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class PacketVersion(val date: String, val timVersion: String)
/**
* 带有这个注解的 [Packet] 将不会被记录在 log 中.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class NoLog
\ No newline at end of file
...@@ -36,3 +36,18 @@ annotation class MiraiExperimentalAPI( ...@@ -36,3 +36,18 @@ annotation class MiraiExperimentalAPI(
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
@MustBeDocumented @MustBeDocumented
annotation class SinceMirai(val version: String) annotation class SinceMirai(val version: String)
/**
* 包的最后一次修改时间, 和分析时使用的 TIM 版本
*/
@MustBeDocumented
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS, AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class PacketVersion(val date: String, val timVersion: String)
/**
* 带有这个注解的 [Packet] 将不会被记录在 log 中.
*/
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class NoLog
\ No newline at end of file
...@@ -5,24 +5,4 @@ import kotlinx.io.core.toByteArray ...@@ -5,24 +5,4 @@ import kotlinx.io.core.toByteArray
import kotlinx.io.core.writeFully import kotlinx.io.core.writeFully
import net.mamoe.mirai.utils.io.getRandomByteArray import net.mamoe.mirai.utils.io.getRandomByteArray
private const val GTK_BASE_VALUE: Int = 5381
fun getGTK(sKey: String): Int {
var value = GTK_BASE_VALUE
for (c in sKey.toByteArray()) {
value += (value shl 5) + c.toInt()
}
value = value and Int.MAX_VALUE
return value
}
@Tested
fun BytePacketBuilder.writeCRC32() = writeCRC32(getRandomByteArray(16))
fun BytePacketBuilder.writeCRC32(key: ByteArray) {
writeFully(key)//key
writeInt(crc32(key))
}
fun md5(str: String): ByteArray = md5(str.toByteArray()) fun md5(str: String): ByteArray = md5(str.toByteArray())
\ No newline at end of file
package net.mamoe.mirai.utils.internal package net.mamoe.mirai.utils
/** /**
* 要求 [this] 最小为 [min]. * 要求 [this] 最小为 [min].
......
@file:Suppress("EXPERIMENTAL_UNSIGNED_LITERALS", "EXPERIMENTAL_API_USAGE", "unused")
package net.mamoe.mirai.utils
import kotlin.jvm.JvmStatic
/**
* QQ 在线状态
*
* @author Him188moe
* @see net.mamoe.mirai.timpc.network.packet.login.ChangeOnlineStatusPacket
*/
inline class OnlineStatus(
inline val id: UByte
) {
companion object {
/**
* 我在线上
*/
@JvmStatic
val ONLINE = OnlineStatus(0x0Au)
/**
* 忙碌
*/
@JvmStatic
val BUSY = OnlineStatus(0x32u)
/**
* 离线 ? 也可能是被删好友 TODO confirm that
*/
@JvmStatic
val OFFLINE = OnlineStatus(0x02u)
@JvmStatic
val UNKNOWN1 = OnlineStatus(0x20u)
@JvmStatic
val UNKNOWN2 = OnlineStatus(0x46u)
@JvmStatic
val UNKNOWN3 = OnlineStatus(0x14u)
@JvmStatic
val UNKNOWN4 = OnlineStatus(0xC9u)
@JvmStatic
val UNKNOWN5 = OnlineStatus(0x1Eu)
}
// TODO: 2019/10/29 what is 0x20u
// TODO: 2019/11/11 what is 0x46u
// TODO: 2019/11/11 what is 0x14u
// TODO: 2019/11/11 0xC9u
// TODO: 2019/11/11 0x1Eu
}
package net.mamoe.mirai.network.packet package net.mamoe.mirai.utils.cryptor
import kotlinx.io.core.BytePacketBuilder import kotlinx.io.core.BytePacketBuilder
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.IoBuffer import kotlinx.io.core.IoBuffer
import net.mamoe.mirai.utils.decryptBy
import net.mamoe.mirai.utils.io.encryptAndWrite import net.mamoe.mirai.utils.io.encryptAndWrite
/**
* 会话密匙
*/
inline class SessionKey(override val value: ByteArray) : DecrypterByteArray {
companion object Type : DecrypterType<SessionKey>
}
/** /**
* [ByteArray] 解密器 * [ByteArray] 解密器
*/ */
......
@file:Suppress("EXPERIMENTAL_API_USAGE", "unused") @file:Suppress("EXPERIMENTAL_API_USAGE", "unused")
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.cryptor
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.readBytes import kotlinx.io.core.readBytes
...@@ -24,7 +24,11 @@ import kotlin.jvm.JvmStatic ...@@ -24,7 +24,11 @@ import kotlin.jvm.JvmStatic
* *
* https://www.jianshu.com/p/f888907adaeb * https://www.jianshu.com/p/f888907adaeb
*/ */
fun ProtoFieldId(serializedId: UInt): ProtoFieldId = ProtoFieldId(protoFieldNumber(serializedId), protoType(serializedId)) fun ProtoFieldId(serializedId: UInt): ProtoFieldId =
ProtoFieldId(
protoFieldNumber(serializedId),
protoType(serializedId)
)
data class ProtoFieldId( data class ProtoFieldId(
val fieldNumber: Int, val fieldNumber: Int,
...@@ -78,7 +82,8 @@ enum class ProtoType(val value: Byte, private val typeName: String) { ...@@ -78,7 +82,8 @@ enum class ProtoType(val value: Byte, private val typeName: String) {
* *
* serializedId = (fieldNumber << 3) | wireType * serializedId = (fieldNumber << 3) | wireType
*/ */
fun protoType(number: UInt): ProtoType = ProtoType.valueOf(number.toInt().shl(29).ushr(29).toByte()) fun protoType(number: UInt): ProtoType =
ProtoType.valueOf(number.toInt().shl(29).ushr(29).toByte())
/** /**
* ProtoBuf 序列化后的 id 转为序列前标记的 id * ProtoBuf 序列化后的 id 转为序列前标记的 id
......
package net.mamoe.mirai.utils package net.mamoe.mirai.utils.cryptor
import kotlinx.io.core.ByteReadPacket import kotlinx.io.core.ByteReadPacket
import kotlinx.io.core.IoBuffer import kotlinx.io.core.IoBuffer
...@@ -29,7 +29,8 @@ class DecryptionFailedException : Exception { ...@@ -29,7 +29,8 @@ class DecryptionFailedException : Exception {
* @param key 长度至少为 16 * @param key 长度至少为 16
* @throws DecryptionFailedException 解密错误时 * @throws DecryptionFailedException 解密错误时
*/ */
fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray = TEA.encrypt(this, key, sourceLength = length) fun ByteArray.encryptBy(key: ByteArray, length: Int = this.size): ByteArray =
TEA.encrypt(this, key, sourceLength = length)
/** /**
* 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密. * 在 [ByteArrayPool] 缓存 [this], 然后使用 [key] 加密.
...@@ -339,11 +340,13 @@ private object TEA { ...@@ -339,11 +340,13 @@ private object TEA {
@PublishedApi @PublishedApi
@JvmStatic @JvmStatic
internal fun encrypt(source: ByteArray, key: ByteArray, sourceLength: Int = source.size): ByteArray = doOption(source, key, sourceLength, true) internal fun encrypt(source: ByteArray, key: ByteArray, sourceLength: Int = source.size): ByteArray =
doOption(source, key, sourceLength, true)
@PublishedApi @PublishedApi
@JvmStatic @JvmStatic
internal fun decrypt(source: ByteArray, key: ByteArray, sourceLength: Int = source.size): ByteArray = doOption(source, key, sourceLength, false) internal fun decrypt(source: ByteArray, key: ByteArray, sourceLength: Int = source.size): ByteArray =
doOption(source, key, sourceLength, false)
private fun ByteArray.pack(offset: Int, len: Int): Long { private fun ByteArray.pack(offset: Int, len: Int): Long {
var result: Long = 0 var result: Long = 0
......
@file:JvmName("IterableUtil")
package net.mamoe.mirai.utils.internal
import kotlin.jvm.JvmName
internal inline fun <T> MutableIterable<T>.inlinedRemoveIf(predicate: (T) -> Boolean) = iterator().inlinedRemoveIf(predicate)
internal inline fun <T> MutableIterator<T>.inlinedRemoveIf(predicate: (T) -> Boolean) {
while (this.hasNext()) {
if (predicate(this.next())) {
this.remove()
}
}
}
\ No newline at end of file
...@@ -4,15 +4,13 @@ package net.mamoe.mirai.utils.io ...@@ -4,15 +4,13 @@ package net.mamoe.mirai.utils.io
import kotlinx.io.core.* import kotlinx.io.core.*
import kotlinx.io.pool.useInstance import kotlinx.io.pool.useInstance
import kotlinx.serialization.SerializationStrategy
import kotlinx.serialization.protobuf.ProtoBuf
import net.mamoe.mirai.contact.GroupId import net.mamoe.mirai.contact.GroupId
import net.mamoe.mirai.contact.GroupInternalId import net.mamoe.mirai.contact.GroupInternalId
import net.mamoe.mirai.utils.Tested import net.mamoe.mirai.utils.Tested
import net.mamoe.mirai.utils.coerceAtMostOrFail
import net.mamoe.mirai.utils.cryptor.encryptBy
import net.mamoe.mirai.utils.currentTime import net.mamoe.mirai.utils.currentTime
import net.mamoe.mirai.utils.deviceName import net.mamoe.mirai.utils.deviceName
import net.mamoe.mirai.utils.encryptBy
import net.mamoe.mirai.utils.internal.coerceAtMostOrFail
import kotlin.random.Random import kotlin.random.Random
import kotlin.random.nextInt import kotlin.random.nextInt
...@@ -28,6 +26,18 @@ fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) // same bi ...@@ -28,6 +26,18 @@ fun BytePacketBuilder.writeQQ(qq: Long) = this.writeUInt(qq.toUInt()) // same bi
fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value.toUInt()) fun BytePacketBuilder.writeGroup(groupId: GroupId) = this.writeUInt(groupId.value.toUInt())
fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value.toUInt()) fun BytePacketBuilder.writeGroup(groupInternalId: GroupInternalId) = this.writeUInt(groupInternalId.value.toUInt())
fun BytePacketBuilder.writeShortLVByteArrayLimitedLength(array: ByteArray, maxLength: Int) {
if (array.size <= maxLength) {
writeShort(array.size.toShort())
writeFully(array)
} else {
writeShort(maxLength.toShort())
repeat(maxLength) {
writeByte(array[it])
}
}
}
fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) { fun BytePacketBuilder.writeShortLVByteArray(byteArray: ByteArray) {
this.writeShort(byteArray.size.toShort()) this.writeShort(byteArray.size.toShort())
this.writeFully(byteArray) this.writeFully(byteArray)
...@@ -63,8 +73,6 @@ fun BytePacketBuilder.writeHex(uHex: String) { ...@@ -63,8 +73,6 @@ fun BytePacketBuilder.writeHex(uHex: String) {
} }
} }
fun <T> BytePacketBuilder.writeProto(serializer: SerializationStrategy<T>, obj: T) = writeFully(ProtoBuf.dump(serializer, obj))
fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) { fun BytePacketBuilder.writeTLV(tag: UByte, values: UByteArray) {
writeUByte(tag) writeUByte(tag)
......
...@@ -92,6 +92,12 @@ fun String.hexToBytes(): ByteArray = ...@@ -92,6 +92,12 @@ fun String.hexToBytes(): ByteArray =
.map { s -> s.toUByte(16).toByte() } .map { s -> s.toUByte(16).toByte() }
.toByteArray() .toByteArray()
/**
* 每 2 char 为一组, 转换 Hex 为 [ByteArray]
*/
fun String.chunkedHexToBytes(): ByteArray =
this.chunked(2).map { it.toUByte(16).toByte() }.toByteArray()
/** /**
* 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存. * 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
*/ */
......
package mirai.test.testCaptchaPacket package mirai.test.testCaptchaPacket
import net.mamoe.mirai.utils.decryptBy import net.mamoe.mirai.utils.cryptor.decryptBy
import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
......
...@@ -41,7 +41,7 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version" ...@@ -41,7 +41,7 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
dependencies { dependencies {
implementation(files("../mirai-core-timpc/build/classes/kotlin/jvm/main")) // IDE bug runtimeOnly(files("../mirai-core-timpc/build/classes/kotlin/jvm/main")) // IDE bug
implementation(project(":mirai-core-timpc")) implementation(project(":mirai-core-timpc"))
// runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) // classpath is not added correctly by IDE // runtimeOnly(files("../mirai-core/build/classes/kotlin/jvm/main")) // classpath is not added correctly by IDE
......
...@@ -7,10 +7,10 @@ import kotlinx.serialization.protobuf.ProtoBuf ...@@ -7,10 +7,10 @@ import kotlinx.serialization.protobuf.ProtoBuf
import kotlinx.serialization.protobuf.ProtoNumberType import kotlinx.serialization.protobuf.ProtoNumberType
import kotlinx.serialization.protobuf.ProtoType import kotlinx.serialization.protobuf.ProtoType
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.cryptor.readProtoMap
import net.mamoe.mirai.utils.io.hexToBytes import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.read import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.toUHexString import net.mamoe.mirai.utils.io.toUHexString
import net.mamoe.mirai.utils.readProtoMap
import kotlin.reflect.KClass import kotlin.reflect.KClass
@Serializable @Serializable
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment