mirror of
https://github.com/mamoe/mirai.git
synced 2025-01-05 07:30:09 +08:00
Move files, modularize project
This commit is contained in:
parent
43daf0f1ca
commit
7f338edcba
40
UpdateLog.md
40
UpdateLog.md
@ -1,10 +1,18 @@
|
||||
# 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)
|
||||
@ -13,7 +21,7 @@
|
||||
**其他**
|
||||
`Contact` 现在实现接口 `CoroutineScope`
|
||||
|
||||
### `0.9.0` *2019/12/20*
|
||||
## `0.9.0` *2019/12/20*
|
||||
**协议模块独立**
|
||||
现在 `mirai-core` 只提供基础的抽象类. 具体的各协议实现为 `mirai-core-PROTOCOL`.
|
||||
这些模块都继承自 `mirai-core`.
|
||||
@ -35,15 +43,15 @@
|
||||
**此为 API 不兼容更新**, 请将所有无符号标志 `u` 删除即可. 如 `123456u` 改为 `123456`
|
||||
|
||||
另还有其他 API 的包名或签名修改. 请使用 IDE 自动修补 import 即可.
|
||||
### `0.8.2` *2019/12/15*
|
||||
## `0.8.2` *2019/12/15*
|
||||
- 修复 GroupId.toGroupInternalId 错误
|
||||
- 修复解析群消息时小概率出现的一个错误
|
||||
|
||||
### `0.8.1` *2019/12/15*
|
||||
## `0.8.1` *2019/12/15*
|
||||
- 修复有时群资料无法获取的情况
|
||||
- 现在 `At.qq`, `Long.qq` 等函数不再是 `suspend`
|
||||
|
||||
### `0.8.0` *2019/12/14*
|
||||
## `0.8.0` *2019/12/14*
|
||||
协议
|
||||
- 现在查询群资料时可处理群号无效的情况
|
||||
- 现在能正常分辨禁言事件包
|
||||
@ -56,28 +64,28 @@
|
||||
优化
|
||||
- 日志中, 发送给服务器的包将会被以名字记录, 而不是 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
|
||||
- 优化 JVM 平台上需要验证码时的提示
|
||||
|
||||
### `0.7.3` *2019/12/07*
|
||||
## `0.7.3` *2019/12/07*
|
||||
- 删除 klock 依赖, 添加 Time.kt. 待将来 kotlin Duration 稳定后替换为 Duration
|
||||
|
||||
### `0.7.2` *2019/12/07*
|
||||
## `0.7.2` *2019/12/07*
|
||||
- 使所有协议相关类 `internal`
|
||||
- 去掉一些 `close` 的不应该有的 `suspend`
|
||||
- `QQ`, `Member`, `Group` 现在继承接口 `CoroutineScope`
|
||||
- 将 `LoginResult` 由 `inline class` 修改为 `enum class`
|
||||
- 添加和修改了 `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)
|
||||
- 重新分析提交密码包
|
||||
@ -97,11 +105,11 @@
|
||||
- 2 个 Contact.sendMessage 重载改为内联扩展函数 **(需要添加 import)**
|
||||
- 其他小优化
|
||||
|
||||
### `0.6.1` *2019/12/03*
|
||||
## `0.6.1` *2019/12/03*
|
||||
- 新增: 无法解析密码包/验证码包时的调试输出. 以兼容更多的设备情况
|
||||
- 新增: `MessagePacket` 下 `At.qq()` 捷径获取 QQ
|
||||
|
||||
### `0.6.0` *2019/12/02*
|
||||
## `0.6.0` *2019/12/02*
|
||||
- 新增: 禁言群成员 (`Member.mute(TimeSpan|Duration|MonthsSpan|Int|UInt)`)
|
||||
- 新增: 解禁群成员 (`Member.unmute()`)
|
||||
- 修复: ContactList key 无法匹配 (Kotlin 内联类型泛型投影错误)
|
||||
|
@ -104,7 +104,7 @@ kotlin {
|
||||
api(kotlin("test-junit", kotlinVersion))
|
||||
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
|
||||
import net.mamoe.mirai.message.data.Image
|
||||
import net.mamoe.mirai.message.data.ImageId0x03
|
||||
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.timpc.internal.RawGroupInfo
|
||||
import net.mamoe.mirai.timpc.network.GroupImpl
|
||||
@ -21,13 +18,15 @@ import net.mamoe.mirai.timpc.network.MemberImpl
|
||||
import net.mamoe.mirai.timpc.network.QQImpl
|
||||
import net.mamoe.mirai.timpc.network.TIMPCBotNetworkHandler
|
||||
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.event.EventPacketFactory
|
||||
import net.mamoe.mirai.timpc.network.packet.event.FriendOnlineStatusChangedPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.login.*
|
||||
import net.mamoe.mirai.timpc.utils.assertUnreachable
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import net.mamoe.mirai.utils.io.logStacktrace
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
|
@ -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.MemberQuitEvent
|
||||
import net.mamoe.mirai.timpc.sendPacket
|
||||
import net.mamoe.mirai.utils.OverFileSizeMaxException
|
||||
import net.mamoe.mirai.timpc.utils.assertUnreachable
|
||||
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.unsafeWeakRef
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
||||
internal sealed class ContactImpl : Contact {
|
||||
|
@ -7,6 +7,7 @@ import kotlinx.io.core.*
|
||||
import kotlinx.io.pool.useInstance
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.data.LoginResult
|
||||
import net.mamoe.mirai.data.OnlineStatus
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.event.BroadcastControllable
|
||||
import net.mamoe.mirai.event.Cancellable
|
||||
@ -14,15 +15,17 @@ import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.event.broadcast
|
||||
import net.mamoe.mirai.event.events.BotLoginSucceedEvent
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
import net.mamoe.mirai.qqAccount
|
||||
import net.mamoe.mirai.timpc.TIMPCBot
|
||||
import net.mamoe.mirai.timpc.network.handler.DataPacketSocketAdapter
|
||||
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.utils.LockFreeLinkedList
|
||||
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.unsafeWeakRef
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
@ -1,13 +1,15 @@
|
||||
@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.serialization.SerializationStrategy
|
||||
import kotlinx.serialization.protobuf.ProtoBuf
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
|
||||
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.writeQQ
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
@ -63,17 +65,14 @@ inline fun PacketFactory<*, *>.buildOutgoingPacket0(
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
|
||||
BytePacketBuilder(headerSizeHint).use {
|
||||
with(it) {
|
||||
writeFully(head)
|
||||
writeFully(ver)
|
||||
writeUShort(id.value)
|
||||
writeUShort(sequenceId)
|
||||
block(this)
|
||||
writeFully(tail)
|
||||
}
|
||||
return OutgoingPacket(name, id, sequenceId, it.build())
|
||||
}
|
||||
return OutgoingPacket(name, id, sequenceId, buildPacket(headerSizeHint) {
|
||||
writeFully(head)
|
||||
writeFully(ver)
|
||||
writeUShort(id.value.toUShort())
|
||||
writeUShort(sequenceId)
|
||||
block(this)
|
||||
writeFully(tail)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ package net.mamoe.mirai.timpc.network.packet
|
||||
|
||||
import kotlinx.io.core.BytePacketBuilder
|
||||
import kotlinx.serialization.SerializationStrategy
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
|
||||
import net.mamoe.mirai.timpc.network.TIMProtocol
|
||||
import net.mamoe.mirai.utils.MiraiInternalAPI
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.mamoe.mirai.network.packet
|
||||
package net.mamoe.mirai.timpc.network.packet
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.readBytes
|
@ -1,7 +1,8 @@
|
||||
@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.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
@ -9,14 +10,16 @@ import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.pool.useInstance
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.protobuf.ProtoBuf
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.debugPrint
|
||||
import net.mamoe.mirai.utils.io.read
|
||||
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
|
||||
*/
|
||||
abstract suspend fun ByteReadPacket.decode(id: PacketId, sequenceId: UShort, handler: BotNetworkHandler): TPacket
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
fun <T> ByteReadPacket.decodeProtoPacket(
|
||||
deserializer: DeserializationStrategy<T>,
|
||||
debuggingTag: String? = null
|
||||
@ -63,10 +65,16 @@ abstract class PacketFactory<out TPacket : Packet, TDecrypter : Decrypter>(val d
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val sequenceIdInternal = atomic(1)
|
||||
private val sequenceId: AtomicInt = atomic(1)
|
||||
|
||||
@MiraiInternalAPI
|
||||
fun atomicNextSequenceId(): UShort = sequenceIdInternal.getAndIncrement().toUShort()
|
||||
fun atomicNextSequenceId(): UShort {
|
||||
val id = sequenceId.getAndAdd(1)
|
||||
if (id > Short.MAX_VALUE.toInt() * 2) {
|
||||
sequenceId.value = 0
|
||||
return atomicNextSequenceId()
|
||||
}
|
||||
return id.toUShort()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,19 @@
|
||||
@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
|
||||
|
||||
|
||||
/**
|
||||
* 包 ID.
|
||||
*/
|
||||
interface PacketId {
|
||||
val value: UShort
|
||||
val factory: PacketFactory<*, *>
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过 [value] 匹配一个 [IgnoredPacketId] 或 [KnownPacketId], 无匹配则返回一个 [UnknownPacketId].
|
||||
*/
|
||||
@ -13,13 +22,6 @@ fun matchPacketId(value: UShort): PacketId =
|
||||
?: KnownPacketId.entries.firstOrNull { it.value.value == value }?.value
|
||||
?: UnknownPacketId(value)
|
||||
|
||||
/**
|
||||
* 包 ID.
|
||||
*/
|
||||
interface PacketId {
|
||||
val value: UShort
|
||||
val factory: PacketFactory<*, *>
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于代表 `null`. 调用任何属性时都将会得到一个 [error]
|
||||
@ -49,7 +51,8 @@ inline class IgnoredPacketId constructor(override val value: UShort) : PacketId
|
||||
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() {
|
||||
operator fun set(key: UShort, factory: PacketFactory<*, *>) {
|
||||
this[key] = KnownPacketId(key, factory)
|
||||
@ -65,7 +68,8 @@ class KnownPacketId(override val value: UShort, override val factory: PacketFact
|
||||
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()})"
|
@ -0,0 +1,11 @@
|
||||
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
|
||||
import net.mamoe.mirai.data.EventPacket
|
||||
import net.mamoe.mirai.data.Packet
|
||||
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.packet.buildSessionPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
|
||||
|
@ -10,10 +10,10 @@ import net.mamoe.mirai.message.data.ImageId
|
||||
import net.mamoe.mirai.message.data.ImageId0x06
|
||||
import net.mamoe.mirai.message.data.requireLength
|
||||
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.packet.buildSessionPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.PacketVersion
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
|
||||
|
@ -5,8 +5,9 @@ package net.mamoe.mirai.timpc.network.packet.action
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.network.packet.SessionPacketFactory
|
||||
import net.mamoe.mirai.timpc.network.packet.PacketId
|
||||
|
||||
import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory
|
||||
|
||||
|
||||
// 0001
|
||||
|
@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully
|
||||
import kotlinx.io.core.writeUByte
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.packet.buildOutgoingPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
|
||||
import net.mamoe.mirai.utils.io.writeQQ
|
||||
|
||||
/**
|
||||
|
@ -11,8 +11,9 @@ import net.mamoe.mirai.message.data.requireLength
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.data.EventPacket
|
||||
import net.mamoe.mirai.data.ImageLink
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
import net.mamoe.mirai.timpc.network.packet.buildSessionProtoPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.PacketVersion
|
||||
|
||||
import net.mamoe.mirai.timpc.utils.assertUnreachable
|
||||
import net.mamoe.mirai.utils.ExternalImage
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
|
@ -10,12 +10,13 @@ import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.internal.toPacket
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
import net.mamoe.mirai.timpc.internal.RawGroupInfo
|
||||
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.unsupportedType
|
||||
import net.mamoe.mirai.utils.NoLog
|
||||
import net.mamoe.mirai.utils.PacketVersion
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
import kotlin.collections.set
|
||||
|
||||
|
@ -8,8 +8,9 @@ import net.mamoe.mirai.data.Gender
|
||||
import net.mamoe.mirai.data.Packet
|
||||
import net.mamoe.mirai.data.Profile
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
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.*
|
||||
|
||||
inline class AvatarLink(val value: String) : Packet
|
||||
|
@ -6,8 +6,9 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.data.FriendNameRemark
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
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.readUShortLVString
|
||||
import net.mamoe.mirai.utils.io.writeQQ
|
||||
import net.mamoe.mirai.utils.io.writeZero
|
||||
|
@ -3,11 +3,11 @@
|
||||
package net.mamoe.mirai.timpc.network.packet.action
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.packet.buildSessionPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.PacketVersion
|
||||
import net.mamoe.mirai.utils.io.writeZero
|
||||
|
||||
class FriendList : Packet
|
||||
|
@ -7,9 +7,11 @@ import net.mamoe.mirai.message.data.MessageChain
|
||||
import net.mamoe.mirai.message.internal.toPacket
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.packet.buildSessionPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
import net.mamoe.mirai.utils.md5
|
||||
|
||||
|
@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import net.mamoe.mirai.Bot
|
||||
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
|
||||
|
||||
|
||||
|
@ -6,10 +6,10 @@ import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.qqAccount
|
||||
import net.mamoe.mirai.timpc.network.packet.buildSessionPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.io.readIoBuffer
|
||||
|
||||
/**
|
||||
|
@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import net.mamoe.mirai.Bot
|
||||
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.readUShortLVString
|
||||
|
||||
|
@ -6,7 +6,7 @@ import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import net.mamoe.mirai.Bot
|
||||
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
|
||||
|
||||
|
||||
|
@ -5,11 +5,12 @@ package net.mamoe.mirai.timpc.network.packet.event
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUByte
|
||||
import net.mamoe.mirai.data.OnlineStatus
|
||||
import net.mamoe.mirai.event.events.FriendStatusChanged
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.network.packet.SessionPacketFactory
|
||||
import net.mamoe.mirai.utils.OnlineStatus
|
||||
import net.mamoe.mirai.timpc.network.packet.PacketId
|
||||
|
||||
import net.mamoe.mirai.timpc.network.packet.SessionPacketFactory
|
||||
import net.mamoe.mirai.utils.io.readQQ
|
||||
|
||||
/**
|
||||
@ -21,7 +22,8 @@ internal object FriendOnlineStatusChangedPacket : SessionPacketFactory<FriendSta
|
||||
val qq = readQQ()
|
||||
discardExact(8)
|
||||
val statusId = readUByte()
|
||||
val status = OnlineStatus(statusId)
|
||||
|
||||
val status = OnlineStatus.ofId(statusId.toInt())
|
||||
return FriendStatusChanged(handler.bot.getQQ(qq), status)
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ package net.mamoe.mirai.timpc.network.packet.event
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import net.mamoe.mirai.Bot
|
||||
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
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.contact.Group
|
||||
import net.mamoe.mirai.contact.Member
|
||||
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
|
||||
|
||||
|
||||
|
@ -7,7 +7,7 @@ import net.mamoe.mirai.contact.MemberPermission
|
||||
import net.mamoe.mirai.message.GroupMessage
|
||||
import net.mamoe.mirai.message.internal.readMessageChain
|
||||
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.io.*
|
||||
|
||||
|
@ -5,9 +5,13 @@ package net.mamoe.mirai.timpc.network.packet.login
|
||||
import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.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.utils.cryptor.DecrypterByteArray
|
||||
import net.mamoe.mirai.utils.cryptor.DecrypterType
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
internal object CaptchaKey : DecrypterByteArray,
|
||||
|
@ -5,21 +5,20 @@ package net.mamoe.mirai.timpc.network.packet.login
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.writeFully
|
||||
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.network.packet.*
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.timpc.network.TIMProtocol
|
||||
import net.mamoe.mirai.timpc.network.packet.buildOutgoingPacket
|
||||
import net.mamoe.mirai.utils.OnlineStatus
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
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.writeQQ
|
||||
|
||||
/**
|
||||
* 改变在线状态: "我在线上", "隐身" 等
|
||||
*/
|
||||
internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>(
|
||||
NoDecrypter
|
||||
) {
|
||||
internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacket.ChangeOnlineStatusResponse, NoDecrypter>(NoDecrypter) {
|
||||
operator fun invoke(
|
||||
bot: Long,
|
||||
sessionKey: SessionKey,
|
||||
@ -29,7 +28,7 @@ internal object ChangeOnlineStatusPacket : PacketFactory<ChangeOnlineStatusPacke
|
||||
writeFully(TIMProtocol.fixVer2)
|
||||
encryptAndWrite(sessionKey) {
|
||||
writeHex("01 00")
|
||||
writeUByte(loginStatus.id)
|
||||
writeUByte(loginStatus.id.toUByte())
|
||||
writeHex("00 01 00 01 00 04 00 00 00 00")
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,11 @@ import kotlinx.io.core.writeFully
|
||||
import net.mamoe.mirai.event.Subscribable
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.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.writeQQ
|
||||
|
||||
|
@ -7,10 +7,13 @@ import net.mamoe.mirai.data.Gender
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.data.LoginResult
|
||||
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.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.utils.*
|
||||
import net.mamoe.mirai.utils.cryptor.*
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
internal object ShareKey : DecrypterByteArray,
|
||||
@ -366,4 +369,9 @@ private fun BytePacketBuilder.writePart2() {
|
||||
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
|
||||
import kotlinx.io.core.writeFully
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.packet.buildOutgoingPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.*
|
||||
import net.mamoe.mirai.utils.cryptor.encryptAndWrite
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
internal inline class SKey(
|
||||
|
@ -5,10 +5,10 @@ package net.mamoe.mirai.timpc.network.packet.login
|
||||
import kotlinx.io.core.*
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
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.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.utils.io.*
|
||||
import net.mamoe.mirai.utils.localIpAddress
|
||||
|
@ -8,9 +8,13 @@ import kotlinx.io.core.readBytes
|
||||
import kotlinx.io.core.writeFully
|
||||
import net.mamoe.mirai.data.Packet
|
||||
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.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.utils.cryptor.DecrypterByteArray
|
||||
import net.mamoe.mirai.utils.cryptor.DecrypterType
|
||||
import net.mamoe.mirai.utils.io.*
|
||||
|
||||
internal object TouchKey : DecrypterByteArray,
|
||||
|
@ -0,0 +1,15 @@
|
||||
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
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
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
|
||||
import kotlinx.serialization.json.Json
|
||||
import net.mamoe.mirai.Bot
|
||||
import net.mamoe.mirai.network.BotNetworkHandler
|
||||
import net.mamoe.mirai.network.packet.*
|
||||
|
||||
import net.mamoe.mirai.timpc.TIMPC
|
||||
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.IgnoredEventPacket
|
||||
import net.mamoe.mirai.timpc.network.packet.login.*
|
||||
import net.mamoe.mirai.utils.DecryptionFailedException
|
||||
import net.mamoe.mirai.utils.decryptBy
|
||||
import net.mamoe.mirai.utils.cryptor.Decrypter
|
||||
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 org.pcap4j.core.BpfProgram.BpfCompileMode
|
||||
import org.pcap4j.core.PacketListener
|
||||
@ -181,13 +184,13 @@ internal object PacketDebugger {
|
||||
* 8. 查看内存, `eax` 到 `eax+10` 的 16 字节就是 `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
|
||||
|
||||
/**
|
||||
* null 则不筛选
|
||||
*/
|
||||
val qq: Long? = 761025446
|
||||
val qq: Long? = null
|
||||
/**
|
||||
* 打开后则记录每一个包到文件.
|
||||
*/
|
||||
@ -204,7 +207,7 @@ internal object PacketDebugger {
|
||||
//println("raw = " + data.toUHexString())
|
||||
data.read {
|
||||
discardExact(3)
|
||||
val id = net.mamoe.mirai.network.packet.matchPacketId(readUShort())
|
||||
val id = matchPacketId(readUShort())
|
||||
val sequenceId = readUShort()
|
||||
val packetQQ = readQQ()
|
||||
if (id == KnownPacketId.get<HeartbeatPacket>() || (qq != null && packetQQ != qq))
|
||||
@ -301,7 +304,7 @@ internal object PacketDebugger {
|
||||
// 3E 03 3F A2 02 00 00 00 01 2E 01 00 00 69 35
|
||||
|
||||
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()
|
||||
if (IgnoredPacketIdList.contains(id)) {
|
||||
return
|
||||
|
@ -3,8 +3,9 @@ package packetdebugger
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.discardExact
|
||||
import kotlinx.io.core.readUShort
|
||||
import net.mamoe.mirai.network.packet.PacketId
|
||||
import net.mamoe.mirai.network.packet.matchPacketId
|
||||
import net.mamoe.mirai.timpc.network.packet.PacketId
|
||||
|
||||
import net.mamoe.mirai.timpc.network.packet.matchPacketId
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.InvocationKind
|
||||
import kotlin.contracts.contract
|
||||
|
@ -3,7 +3,7 @@
|
||||
package net.mamoe.mirai
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.network.packet.NullPacketId.factory
|
||||
|
||||
import net.mamoe.mirai.utils.BotConfiguration
|
||||
import net.mamoe.mirai.utils.MiraiLogger
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
|
@ -4,7 +4,7 @@ package net.mamoe.mirai.contact
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import net.mamoe.mirai.data.GroupInfo
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import net.mamoe.mirai.utils.coerceAtLeastOrFail
|
||||
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,44 @@
|
||||
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 }
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package net.mamoe.mirai.event.events
|
||||
|
||||
import net.mamoe.mirai.contact.QQ
|
||||
import net.mamoe.mirai.data.EventPacket
|
||||
import net.mamoe.mirai.utils.OnlineStatus
|
||||
import net.mamoe.mirai.data.OnlineStatus
|
||||
|
||||
data class FriendStatusChanged(
|
||||
val qq: QQ,
|
||||
|
@ -10,7 +10,7 @@ import net.mamoe.mirai.data.ImageLink
|
||||
import net.mamoe.mirai.event.events.BotEvent
|
||||
import net.mamoe.mirai.message.data.*
|
||||
import net.mamoe.mirai.utils.*
|
||||
import net.mamoe.mirai.utils.internal.coerceAtLeastOrFail
|
||||
import net.mamoe.mirai.utils.coerceAtLeastOrFail
|
||||
import kotlin.jvm.JvmName
|
||||
|
||||
/**
|
||||
|
@ -1,18 +0,0 @@
|
||||
@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
|
@ -36,3 +36,18 @@ annotation class MiraiExperimentalAPI(
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@MustBeDocumented
|
||||
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
|
@ -5,24 +5,4 @@ import kotlinx.io.core.toByteArray
|
||||
import kotlinx.io.core.writeFully
|
||||
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())
|
@ -1,4 +1,4 @@
|
||||
package net.mamoe.mirai.utils.internal
|
||||
package net.mamoe.mirai.utils
|
||||
|
||||
/**
|
||||
* 要求 [this] 最小为 [min].
|
@ -1,52 +0,0 @@
|
||||
@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
|
||||
}
|
@ -1,19 +1,11 @@
|
||||
package net.mamoe.mirai.network.packet
|
||||
package net.mamoe.mirai.utils.cryptor
|
||||
|
||||
import kotlinx.io.core.BytePacketBuilder
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.IoBuffer
|
||||
import net.mamoe.mirai.utils.decryptBy
|
||||
import net.mamoe.mirai.utils.io.encryptAndWrite
|
||||
|
||||
|
||||
/**
|
||||
* 会话密匙
|
||||
*/
|
||||
inline class SessionKey(override val value: ByteArray) : DecrypterByteArray {
|
||||
companion object Type : DecrypterType<SessionKey>
|
||||
}
|
||||
|
||||
/**
|
||||
* [ByteArray] 解密器
|
||||
*/
|
@ -1,6 +1,6 @@
|
||||
@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.readBytes
|
||||
@ -24,7 +24,11 @@ import kotlin.jvm.JvmStatic
|
||||
*
|
||||
* 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(
|
||||
val fieldNumber: Int,
|
||||
@ -78,7 +82,8 @@ enum class ProtoType(val value: Byte, private val typeName: String) {
|
||||
*
|
||||
* 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
|
@ -1,4 +1,4 @@
|
||||
package net.mamoe.mirai.utils
|
||||
package net.mamoe.mirai.utils.cryptor
|
||||
|
||||
import kotlinx.io.core.ByteReadPacket
|
||||
import kotlinx.io.core.IoBuffer
|
||||
@ -29,7 +29,8 @@ class DecryptionFailedException : Exception {
|
||||
* @param key 长度至少为 16
|
||||
* @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] 加密.
|
||||
@ -339,11 +340,13 @@ private object TEA {
|
||||
|
||||
@PublishedApi
|
||||
@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
|
||||
@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 {
|
||||
var result: Long = 0
|
@ -1,15 +0,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()
|
||||
}
|
||||
}
|
||||
}
|
@ -4,15 +4,13 @@ package net.mamoe.mirai.utils.io
|
||||
|
||||
import kotlinx.io.core.*
|
||||
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.GroupInternalId
|
||||
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.deviceName
|
||||
import net.mamoe.mirai.utils.encryptBy
|
||||
import net.mamoe.mirai.utils.internal.coerceAtMostOrFail
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextInt
|
||||
|
||||
@ -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(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) {
|
||||
this.writeShort(byteArray.size.toShort())
|
||||
this.writeFully(byteArray)
|
||||
@ -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) {
|
||||
writeUByte(tag)
|
||||
|
@ -92,6 +92,12 @@ fun String.hexToBytes(): ByteArray =
|
||||
.map { s -> s.toUByte(16).toByte() }
|
||||
.toByteArray()
|
||||
|
||||
/**
|
||||
* 每 2 char 为一组, 转换 Hex 为 [ByteArray]
|
||||
*/
|
||||
fun String.chunkedHexToBytes(): ByteArray =
|
||||
this.chunked(2).map { it.toUByte(16).toByte() }.toByteArray()
|
||||
|
||||
/**
|
||||
* 将无符号 Hex 转为 [UByteArray], 有根据 hex 的 [hashCode] 建立的缓存.
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.toUHexString
|
||||
|
||||
|
@ -41,7 +41,7 @@ fun ktor(id: String, version: String) = "io.ktor:ktor-$id:$version"
|
||||
|
||||
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"))
|
||||
// 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
|
||||
import kotlinx.serialization.protobuf.ProtoNumberType
|
||||
import kotlinx.serialization.protobuf.ProtoType
|
||||
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.read
|
||||
import net.mamoe.mirai.utils.io.toUHexString
|
||||
import net.mamoe.mirai.utils.readProtoMap
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Serializable
|
||||
|
Loading…
Reference in New Issue
Block a user