1
0
mirror of https://github.com/mamoe/mirai.git synced 2025-04-02 05:00:35 +08:00

move to lowLevelApi.kt

This commit is contained in:
luo123 2020-03-14 11:01:21 +08:00
parent 4e7b3b0048
commit 6973488db7
6 changed files with 189 additions and 156 deletions
mirai-core-qqandroid/src/commonMain/kotlin/net/mamoe/mirai/qqandroid
mirai-core/src
commonMain/kotlin/net.mamoe.mirai
jvmMain/kotlin/net/mamoe/mirai/contact

View File

@ -570,102 +570,6 @@ internal class GroupImpl(
TODO("not implemented")
}
@MiraiExperimentalAPI
override suspend fun getAnnouncements(page: Int, amount: Int): GroupAnnouncementList? {
val json = Json(JsonConfiguration(ignoreUnknownKeys = true))
val data = bot.network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/list_announce")
body = MultiPartFormDataContent(formData {
append("qid", id)
append("bkn", getBkn())
append("ft", 23) //好像是一个用来识别应用的参数
append("s", if (page == 1) 0 else -(page * amount + 1)) // 第一页这里的参数应该是-1
append("n", amount)
append("ni", if (page == 1) 1 else 0)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${bot.selfQQ.id}; skey=${bot.client.wLoginSigInfo.sKey.data.encodeToString()}; p_uin=o${bot.selfQQ.id};"
)
}
}
}
val rep = data.await()
// bot.network.logger.error(rep)
return json.parse(GroupAnnouncementList.serializer(), rep)
}
@MiraiExperimentalAPI
override suspend fun sendAnnouncement(announcement: GroupAnnouncement): String {
val json = Json(JsonConfiguration.Stable)
val rep = bot.network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice")
body = MultiPartFormDataContent(formData {
append("qid", id)
append("bkn", getBkn())
append("text", announcement.msg.text)
append("pinned", announcement.pinned)
append(
"settings",
json.stringify(
GroupAnnouncementSettings.serializer(),
announcement.settings ?: GroupAnnouncementSettings()
)
)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${bot.selfQQ.id};" +
" skey=${bot.client.wLoginSigInfo.sKey.data.encodeToString()};" +
" p_uin=o${bot.selfQQ.id};" +
" p_skey=${bot.client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; "
)
}
}
}
val jsonObj = json.parseJson(rep.await())
return jsonObj.jsonObject["new_fid"]?.primitive?.content
?: throw throw IllegalStateException("Send Announcement fail group:$id msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}")
}
@MiraiExperimentalAPI
override suspend fun deleteAnnouncement(fid: String) {
val json = Json(JsonConfiguration.Stable)
val rep = bot.network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/del_feed")
body = MultiPartFormDataContent(formData {
append("qid", id)
append("bkn", getBkn())
append("fid", fid)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${bot.selfQQ.id};" +
" skey=${bot.client.wLoginSigInfo.sKey.data.encodeToString()};" +
" p_uin=o${bot.selfQQ.id};" +
" p_skey=${bot.client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; "
)
}
}
}
val data = rep.await()
val jsonObj = json.parseJson(data)
if (jsonObj.jsonObject["ec"]?.int ?: 1 != 0){
throw throw IllegalStateException("delete Announcement fail group:$id msg:${jsonObj.jsonObject["em"]} fid:$fid")
}
}
@OptIn(MiraiExperimentalAPI::class)
override fun Member(memberInfo: MemberInfo): Member {
return MemberImpl(
@ -827,15 +731,5 @@ internal class GroupImpl(
return this.id == other.id && this.bot == other.bot
}
/**
* 获取 获取群公告 所需的bkn参数
* */
private fun getBkn(): Int {
val str = bot.client.wLoginSigInfo.sKey.data.encodeToString()
var magic = 5381
for (i in str) {
magic += magic.shl(5) + i.toInt()
}
return Int.MAX_VALUE.and(magic)
}
}

View File

@ -9,18 +9,25 @@
package net.mamoe.mirai.qqandroid
import io.ktor.client.HttpClient
import io.ktor.client.request.forms.MultiPartFormDataContent
import io.ktor.client.request.forms.formData
import io.ktor.client.request.get
import io.ktor.client.request.headers
import io.ktor.client.request.post
import io.ktor.client.request.url
import io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.async
import kotlinx.coroutines.io.ByteReadChannel
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.json.int
import net.mamoe.mirai.BotAccount
import net.mamoe.mirai.BotImpl
import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.AddFriendResult
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.data.*
import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.*
@ -33,6 +40,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc
import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.encodeToString
import kotlin.collections.asSequence
import kotlin.coroutines.CoroutineContext
@ -209,6 +217,133 @@ internal abstract class QQAndroidBotBase constructor(
}
}
@OptIn(LowLevelAPI::class)
@MiraiExperimentalAPI
override suspend fun _lowLevelGetAnnouncements(groupId:Long, page: Int, amount: Int): GroupAnnouncementList? {
val json = Json(JsonConfiguration(ignoreUnknownKeys = true))
val data = network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/list_announce")
body = MultiPartFormDataContent(formData {
append("qid", groupId)
append("bkn", getBkn())
append("ft", 23) //好像是一个用来识别应用的参数
append("s", if (page == 1) 0 else -(page * amount + 1)) // 第一页这里的参数应该是-1
append("n", amount)
append("ni", if (page == 1) 1 else 0)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${selfQQ.id}; skey=${client.wLoginSigInfo.sKey.data.encodeToString()}; p_uin=o${selfQQ.id};"
)
}
}
}
val rep = data.await()
// bot.network.logger.error(rep)
return json.parse(GroupAnnouncementList.serializer(), rep)
}
@OptIn(LowLevelAPI::class)
@MiraiExperimentalAPI
override suspend fun _lowLevelSendAnnouncement(groupId:Long, announcement: GroupAnnouncement): String {
val json = Json(JsonConfiguration.Stable)
val rep = network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/add_qun_notice")
body = MultiPartFormDataContent(formData {
append("qid", groupId)
append("bkn", getBkn())
append("text", announcement.msg.text)
append("pinned", announcement.pinned)
append(
"settings",
json.stringify(
GroupAnnouncementSettings.serializer(),
announcement.settings ?: GroupAnnouncementSettings()
)
)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${selfQQ.id};" +
" skey=${client.wLoginSigInfo.sKey.data.encodeToString()};" +
" p_uin=o${selfQQ.id};" +
" p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; "
)
}
}
}
val jsonObj = json.parseJson(rep.await())
return jsonObj.jsonObject["new_fid"]?.primitive?.content
?: throw throw IllegalStateException("Send Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} content:${announcement.msg.text}")
}
@OptIn(LowLevelAPI::class)
@MiraiExperimentalAPI
override suspend fun _lowLevelDeleteAnnouncement(groupId:Long, fid: String) {
val json = Json(JsonConfiguration.Stable)
val rep = network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/del_feed")
body = MultiPartFormDataContent(formData {
append("qid", groupId)
append("bkn", getBkn())
append("fid", fid)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${selfQQ.id};" +
" skey=${client.wLoginSigInfo.sKey.data.encodeToString()};" +
" p_uin=o${selfQQ.id};" +
" p_skey=${client.wLoginSigInfo.psKeyMap["qun.qq.com"]?.data?.encodeToString()}; "
)
}
}
}
val data = rep.await()
val jsonObj = json.parseJson(data)
if (jsonObj.jsonObject["ec"]?.int ?: 1 != 0){
throw throw IllegalStateException("delete Announcement fail group:$groupId msg:${jsonObj.jsonObject["em"]} fid:$fid")
}
}
@OptIn(LowLevelAPI::class)
@MiraiExperimentalAPI
override suspend fun _lowLevelGetAnnouncement(groupId: Long, fid: String): GroupAnnouncement {
val json = Json(JsonConfiguration(ignoreUnknownKeys = true))
val data = network.async {
HttpClient().post<String> {
url("https://web.qun.qq.com/cgi-bin/announce/get_feed")
body = MultiPartFormDataContent(formData {
append("qid", groupId)
append("bkn", getBkn())
append("fid", fid)
append("format", "json")
})
headers {
append(
"cookie",
"uin=o${selfQQ.id}; skey=${client.wLoginSigInfo.sKey.data.encodeToString()}; p_uin=o${selfQQ.id};"
)
}
}
}
val rep = data.await()
// bot.network.logger.error(rep)
return json.parse(GroupAnnouncement.serializer(), rep)
}
override suspend fun queryImageUrl(image: Image): String = when (image) {
is OnlineFriendImageImpl -> image.originUrl
is OnlineGroupImageImpl -> image.originUrl
@ -224,6 +359,18 @@ internal abstract class QQAndroidBotBase constructor(
override suspend fun openChannel(image: Image): ByteReadChannel {
return MiraiPlatformUtils.Http.get<HttpResponse>(queryImageUrl(image)).content.toKotlinByteReadChannel()
}
/**
* 获取 获取群公告 所需的bkn参数
* */
private fun getBkn(): Int {
val str = client.wLoginSigInfo.sKey.data.encodeToString()
var magic = 5381
for (i in str) {
magic += magic.shl(5) + i.toInt()
}
return Int.MAX_VALUE.and(magic)
}
}
@Suppress("DEPRECATION")

View File

@ -153,28 +153,7 @@ expect abstract class Group() : Contact, CoroutineScope {
*/
abstract operator fun contains(id: Long): Boolean
/**
* 获取群公告列表
*
* */
@MiraiExperimentalAPI
abstract suspend fun getAnnouncements(page: Int = 1, amount: Int = 10): GroupAnnouncementList?
/**
* 发送群公告
*
* */
@MiraiExperimentalAPI
abstract suspend fun sendAnnouncement(announcement: GroupAnnouncement): String
/**
* 删除群公告
* fid可以通过发送公告的返回值得到或者获取列表得到
* */
@MiraiExperimentalAPI
abstract suspend fun deleteAnnouncement(fid: String)
/**
* 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败

View File

@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable
* 群公告数据类
* getGroupAnnouncementList时如果page=1那么你可以在inst里拿到一些置顶公告
*
* 发公告时只需要填写text
* 发公告时只需要填写text其他参数可为默认值
*
*/
@Serializable

View File

@ -12,9 +12,7 @@ package net.mamoe.mirai
import kotlinx.coroutines.Job
import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.data.*
import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI
@ -94,6 +92,41 @@ interface LowLevelBotAPIAccessor {
*/
@LowLevelAPI
suspend fun _lowLevelRecallGroupMessage(groupId: Long, messageId: Long)
/**
* 获取群公告列表
* @param page 页码
* */
@LowLevelAPI
@MiraiExperimentalAPI
suspend fun _lowLevelGetAnnouncements(groupId: Long, page: Int = 1, amount: Int = 10): GroupAnnouncementList?
/**
* 发送群公告
*
* @return 公告的fid
* */
@LowLevelAPI
@MiraiExperimentalAPI
suspend fun _lowLevelSendAnnouncement(groupId: Long, announcement: GroupAnnouncement): String
/**
* 删除群公告
* @param fid [GroupAnnouncement.fid]
* */
@LowLevelAPI
@MiraiExperimentalAPI
suspend fun _lowLevelDeleteAnnouncement(groupId: Long, fid: String)
/**
* 获取一条群公告
* @param fid [GroupAnnouncement.fid]
* */
@LowLevelAPI
@MiraiExperimentalAPI
suspend fun _lowLevelGetAnnouncement(groupId: Long,fid:String):GroupAnnouncement
}
/**

View File

@ -149,26 +149,6 @@ actual abstract class Group : Contact(), CoroutineScope {
actual abstract fun getOrNull(id: Long): Member?
/**
* 获取群公告列表
*
* */
@MiraiExperimentalAPI
actual suspend abstract fun getAnnouncements(page: Int, amount: Int): GroupAnnouncementList?
/**
* 删除群公告
* fid可以通过发送公告的返回值得到或者获取列表得到
* */
@MiraiExperimentalAPI
actual abstract suspend fun deleteAnnouncement(fid: String)
/**
* 发送群公告
* */
@MiraiExperimentalAPI
actual suspend abstract fun sendAnnouncement(announcement: GroupAnnouncement):String
/**
* 检查此 id 的群成员是否存在
*/