Fix image

This commit is contained in:
Him188 2020-02-04 17:11:57 +08:00
parent c83bf64a8a
commit f244a12b8b
11 changed files with 79 additions and 44 deletions

View File

@ -4,6 +4,7 @@ import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.FriendNameRemark
import net.mamoe.mirai.data.PreviousNameList
import net.mamoe.mirai.data.Profile
import net.mamoe.mirai.message.data.CustomFaceFromFile
import net.mamoe.mirai.message.data.Image
import net.mamoe.mirai.message.data.MessageChain
import net.mamoe.mirai.message.data.NotOnlineImageFromFile
@ -206,14 +207,24 @@ internal class GroupImpl(
}
socket.close()
val resourceId = image.calculateImageResourceId()
return NotOnlineImageFromFile(
resourceId = resourceId,
return CustomFaceFromFile(
md5 = image.md5,
filepath = resourceId,
fileLength = image.inputSize.toInt(),
fileId = response.fileId.toInt(),
fileType = 66, // ?
height = image.height,
width = image.width,
imageType = image.imageType
imageType = image.imageType,
bizType = 0,
serverIp = response.uploadIpList.first(),
serverPort = response.uploadPortList.first(),
signature = image.md5,
size = image.inputSize.toInt(),
useful = 1,
source = 200,
origin = 1,
pbReserve = byteArrayOf(0x78, 0x02)
)
}
}

View File

@ -140,8 +140,8 @@ internal class stTroopMemberInfo(
@SerialId(3) val gender: Byte,
@SerialId(4) val nick: String = "",
@SerialId(5) val status: Byte = 20,
@SerialId(6) val sShowName: String? = "",
@SerialId(8) val sName: String? = "",
@SerialId(6) val sShowName: String? = null,
@SerialId(8) val sName: String? = null,
@SerialId(9) val cGender: Byte? = null,
@SerialId(10) val sPhone: String? = "",
@SerialId(11) val sEmail: String? = "",

View File

@ -40,6 +40,7 @@ internal class OnlinePush {
val group = bot.getGroup(pbPushMsg.msg.msgHead.groupInfo!!.groupCode)
// println(pbPushMsg.msg.msgBody.richText.contentToString())
val flags = extraInfo?.flags ?: 0
return GroupMessageOrNull(
GroupMessage(

View File

@ -1,9 +1,23 @@
package net.mamoe.mirai.qqandroid.utils
import net.mamoe.mirai.data.ImageLink
import kotlinx.io.core.readUInt
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.qqandroid.network.protocol.data.proto.ImMsgBody
import net.mamoe.mirai.utils.MiraiInternalAPI
import net.mamoe.mirai.utils.io.discardExact
import net.mamoe.mirai.utils.io.hexToBytes
import net.mamoe.mirai.utils.io.read
import net.mamoe.mirai.utils.io.toByteArray
private val AT_BUF_1 = byteArrayOf(0x00, 0x01, 0x00, 0x00, 0x00, 0x0A, 0x00)
private val AT_BUF_2 = ByteArray(2)
internal fun At.toJceData(): ImMsgBody.Text {
return ImMsgBody.Text(
str = this.toString(),
attr6Buf = AT_BUF_1 + this.target.toInt().toByteArray() + AT_BUF_2
)
}
internal fun NotOnlineImageFromFile.toJceData(): ImMsgBody.NotOnlineImage {
return ImMsgBody.NotOnlineImage(
@ -36,6 +50,7 @@ internal fun CustomFaceFromFile.toJceData(): ImMsgBody.CustomFace {
height = this.height,
source = this.source,
size = this.size,
origin = this.origin,
pbReserve = this.pbReserve
)
}
@ -116,9 +131,7 @@ internal fun MessageChain.toRichTextElems(): MutableList<ImMsgBody.Elem> {
this.forEach {
when (it) {
is PlainText -> elements.add(ImMsgBody.Elem(text = ImMsgBody.Text(str = it.stringValue)))
is At -> {
}
is At -> elements.add(ImMsgBody.Elem(text = it.toJceData()))
is CustomFaceFromFile -> elements.add(ImMsgBody.Elem(customFace = it.toJceData()))
is CustomFaceFromServer -> elements.add(ImMsgBody.Elem(customFace = it.delegate))
is NotOnlineImageFromServer -> elements.add(ImMsgBody.Elem(notOnlineImage = it.delegate))
@ -152,33 +165,25 @@ internal class CustomFaceFromServer(
override val height: Int get() = delegate.height
override val source: Int get() = delegate.source
override val size: Int get() = delegate.size
override val origin: Int get() = delegate.origin
override val pbReserve: ByteArray get() = delegate.pbReserve
}
internal class NotOnlineImageFromServer(
internal val delegate: ImMsgBody.NotOnlineImage
) : NotOnlineImage() {
override val resourceId: String
get() = delegate.resId
override val md5: ByteArray
get() = delegate.picMd5
override val filepath: String
get() = delegate.filePath
override val fileLength: Int
get() = delegate.fileLen
override val height: Int
get() = delegate.picHeight
override val width: Int
get() = delegate.picWidth
override val bizType: Int
get() = delegate.bizType
override val imageType: Int
get() = delegate.imgType
override val downloadPath: String
get() = delegate.downloadPath
override val resourceId: String get() = delegate.resId
override val md5: ByteArray get() = delegate.picMd5
override val filepath: String get() = delegate.filePath
override val fileLength: Int get() = delegate.fileLen
override val height: Int get() = delegate.picHeight
override val width: Int get() = delegate.picWidth
override val bizType: Int get() = delegate.bizType
override val imageType: Int get() = delegate.imgType
override val downloadPath: String get() = delegate.downloadPath
}
@UseExperimental(ExperimentalUnsignedTypes::class, MiraiInternalAPI::class)
internal fun ImMsgBody.RichText.toMessageChain(): MessageChain {
val message = MessageChain(initialCapacity = elems.size)
@ -186,12 +191,17 @@ internal fun ImMsgBody.RichText.toMessageChain(): MessageChain {
when {
it.notOnlineImage != null -> message.add(NotOnlineImageFromServer(it.notOnlineImage))
it.customFace != null -> message.add(CustomFaceFromServer(it.customFace))
it.text != null -> message.add(it.text.str.toMessage())
it.text != null -> {
if (it.text.attr6Buf.isEmpty()) {
message.add(it.text.str.toMessage())
} else {
//00 01 00 00 00 0A 00 3E 03 3F A2 00 00
val id = it.text.attr6Buf.read { discardExact(7); readUInt().toLong() }
message.add(At(id, it.text.str))
}
}
}
}
return message
}
internal inline class ImageLinkQQA(override val original: String) : ImageLink
}

View File

@ -6,6 +6,7 @@ import kotlinx.io.core.ByteReadPacket
import net.mamoe.mirai.Bot
import net.mamoe.mirai.contact.Contact
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.EventPacket
import net.mamoe.mirai.event.events.BotEvent
@ -19,6 +20,7 @@ import kotlin.jvm.JvmName
@UseExperimental(MiraiInternalAPI::class)
expect abstract class MessagePacket<TSender : QQ, TSubject : Contact>(bot: Bot) : MessagePacketBase<TSender, TSubject>
@Suppress("NOTHING_TO_INLINE")
@MiraiInternalAPI
abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) : EventPacket, BotEvent() {
override val bot: Bot by _bot.unsafeWeakRef()
@ -69,6 +71,8 @@ abstract class MessagePacketBase<TSender : QQ, TSubject : Contact>(_bot: Bot) :
suspend inline fun Message.send() = this.sendTo(subject)
suspend inline fun String.send() = this.toMessage().sendTo(subject)
inline fun QQ.at(): At = At(this as Member)
// endregion
// region Image download

View File

@ -2,16 +2,18 @@
package net.mamoe.mirai.message.data
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.utils.MiraiInternalAPI
/**
* At 一个人. 只能发送给一个群.
*/
inline class At(val target: Long) : Message {
constructor(target: QQ) : this(target.id)
class At @MiraiInternalAPI constructor(val target: Long, val display: String) : Message {
@UseExperimental(MiraiInternalAPI::class)
constructor(member: Member) : this(member.id, member.groupCard)
override fun toString(): String = "[@$target]" // TODO: 2019/11/25 使用群名称进行 at. 因为手机端只会显示这个文字
override fun toString(): String = display
companion object Key : Message.Key<At>
@ -24,4 +26,4 @@ inline class At(val target: Long) : Message {
* At 这个成员
*/
@Suppress("NOTHING_TO_INLINE")
inline fun QQ.at(): At = At(this)
inline fun Member.at(): At = At(this)

View File

@ -31,6 +31,7 @@ abstract class CustomFace : Image() {
abstract val source: Int
abstract val size:Int
abstract val pbReserve: ByteArray
abstract val origin: Int
override fun toString(): String {
return "[CustomFace]"
@ -57,6 +58,7 @@ data class CustomFaceFromFile(
override val height: Int,
override val source: Int,
override val size: Int,
override val origin: Int,
override val pbReserve: ByteArray
) : CustomFace() {
override fun equals(other: Any?): Boolean {
@ -79,6 +81,7 @@ data class CustomFaceFromFile(
if (height != other.height) return false
if (source != other.source) return false
if (size != other.size) return false
if (origin != this.origin) return false
if (!pbReserve.contentEquals(other.pbReserve)) return false
return true
@ -114,6 +117,9 @@ abstract class NotOnlineImage : Image() {
open val bizType: Int get() = 0
open val imageType: Int get() = 1000
open val downloadPath: String get() = resourceId
open val origin: Int get()= 1
open val signature: ByteArray get() = md5
open val fileType: Int get()= 66
override fun toString(): String {
return "[NotOnlineImage $resourceId]"

View File

@ -39,7 +39,7 @@ class ExternalImage(
): ExternalImage = ExternalImage(width, height, md5, format, data, data.remaining, filename)
}
private val format: String = when (val it =imageFormat.toLowerCase()) {
private val format: String = when (val it = imageFormat.toLowerCase()) {
"jpeg" -> "jpg" //必须转换
else -> it
}
@ -56,7 +56,7 @@ class ExternalImage(
* SHARPP: 1004
*/
val imageType: Int
get() = when (format){
get() = when (format) {
"jpg" -> 1000
"png" -> 1001
"webp" -> 1002

View File

@ -1,6 +1,7 @@
apply plugin: "kotlin"
apply plugin: "java"
apply plugin: "application"
apply plugin: "kotlinx-serialization"
dependencies {
implementation files("../../mirai-core-qqandroid/build/classes/kotlin/jvm/main") // IDE bug

View File

@ -9,6 +9,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import net.mamoe.mirai.Bot
import net.mamoe.mirai.alsoLogin
import net.mamoe.mirai.contact.Member
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.event.Subscribable
import net.mamoe.mirai.event.events.ReceiveFriendAddRequestEvent
@ -67,7 +68,7 @@ suspend fun main() {
always {
}
case("at me") { At(sender).reply() }
case("at me") { At(sender as Member).reply() }
// 等同于 "at me" reply { At(sender) }
"你好" reply "你好!"

View File

@ -5,7 +5,6 @@ import kotlinx.coroutines.GlobalScope
import net.mamoe.mirai.event.events.BotLoginSucceedEvent
import net.mamoe.mirai.event.subscribeAlways
import net.mamoe.mirai.event.subscribeMessages
import net.mamoe.mirai.message.data.At
import net.mamoe.mirai.plugin.PluginBase
import net.mamoe.mirai.utils.MiraiExperimentalAPI
@ -19,7 +18,7 @@ class ImageSenderMain : PluginBase() {
this.bot.subscribeMessages {
case("at me") {
(At(sender) + " ? ").reply()
reply(sender.at() + " ? ")
}
(contains("image") or contains("")) {