Skip to content

Commit

Permalink
impl essences share link (mirai-core)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrXiaoM committed Dec 4, 2023
1 parent cc2e2fa commit f69b15e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@ package top.mrxiaom.overflow.internal.contact.data

import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.isActive
import net.mamoe.mirai.Mirai
import net.mamoe.mirai.contact.MemberPermission
import net.mamoe.mirai.contact.checkBotPermission
import net.mamoe.mirai.contact.essence.EssenceMessageRecord
import net.mamoe.mirai.contact.essence.Essences
import net.mamoe.mirai.message.data.*
import net.mamoe.mirai.utils.MiraiInternalApi
import top.mrxiaom.overflow.internal.contact.GroupWrapper
import top.mrxiaom.overflow.internal.utils.shareDigest

class EssencesWrapper(
val impl: GroupWrapper,
Expand Down Expand Up @@ -42,7 +41,13 @@ class EssencesWrapper(
}

override suspend fun share(source: MessageSource): String {
TODO("Not yet implemented")
val shareKey = impl.botWrapper.shareDigest(
groupCode = impl.id,
msgSeq = source.ids.first().toLong().and(0xFFFF_FFFF),
msgRandom = source.internalIds.first().toLong().and(0xFFFF_FFFF),
targetGroupCode = 0
)
return "https://qun.qq.com/essence/share?_wv=3&_wwv=128&_wvx=2&sharekey=$shareKey"
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
package top.mrxiaom.overflow.internal.utils

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonNull
import net.mamoe.mirai.utils.CheckableResponseA
import net.mamoe.mirai.utils.ExternalResource
import net.mamoe.mirai.utils.JsonStruct
import net.mamoe.mirai.utils.loadAs
import top.mrxiaom.overflow.internal.contact.BotWrapper
import java.io.*
import java.net.HttpURLConnection
import java.net.URL
import java.util.*

fun ExternalResource.toBase64File(): String {
fun ExternalResource.toBase64File(): String {
return inputStream().use {
"base64://" + Base64.getEncoder().encodeToString(it.readBytes())
}
Expand Down Expand Up @@ -121,3 +135,55 @@ class FastImageInfo private constructor(
}
}
}

internal val defaultJson: Json = Json {
isLenient = true
ignoreUnknownKeys = true
}
@Serializable
data class DigestShare(
@SerialName("share_key")
val shareKey: String = ""
)

@Serializable
internal data class DigestData(
@SerialName("data") val `data`: JsonElement = JsonNull,
@SerialName("wording") val reason: String = "",
@SerialName("retmsg") override val errorMessage: String,
@SerialName("retcode") override val errorCode: Int
) : CheckableResponseA(), JsonStruct

private fun <T> DigestData.loadData(serializer: KSerializer<T>): T {
return try {
defaultJson.decodeFromJsonElement(serializer, this.data)
} catch (cause: Exception) {
throw IllegalStateException("parse digest data error, status: $errorCode - $errorMessage", cause)
}
}
internal suspend fun BotWrapper.shareDigest(
groupCode: Long, msgSeq: Long, msgRandom: Long, targetGroupCode: Long
): DigestShare {
val cookie = impl.getCookies("qun.qq.com").data?.cookies ?: throw IllegalStateException("cookies is empty")
val skey = cookie.replace(" ", "").substringAfter(";skey=").substringBefore(";")
val bkn = bkn(skey)
return withContext(Dispatchers.IO) {
val conn = URL("https://qun.qq.com/cgi-bin/group_digest/share_digest?group_code=$groupCode&msg_seq=$msgSeq&msg_random=$msgRandom&target_group_code=$targetGroupCode&bkn=$bkn").openConnection() as HttpURLConnection

conn.requestMethod = "get"
conn.addRequestProperty("cookie", cookie)
conn.connect()
conn.inputStream.readBytes().toString(Charsets.UTF_8).loadAs(DigestData.serializer()).loadData(DigestShare.serializer())
}
}

fun bkn(skey: String): Int {
var bkn = 5381
var i = 0
val length = skey.length
while (i < length) {
bkn += (bkn shl 5) + skey[i].code
i += 1
}
return bkn and 2147483647
}

0 comments on commit f69b15e

Please sign in to comment.