Commit 6973488d authored by luo123's avatar luo123

move to lowLevelApi.kt

parent 4e7b3b00
...@@ -570,102 +570,6 @@ internal class GroupImpl( ...@@ -570,102 +570,6 @@ internal class GroupImpl(
TODO("not implemented") 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) @OptIn(MiraiExperimentalAPI::class)
override fun Member(memberInfo: MemberInfo): Member { override fun Member(memberInfo: MemberInfo): Member {
return MemberImpl( return MemberImpl(
...@@ -827,15 +731,5 @@ internal class GroupImpl( ...@@ -827,15 +731,5 @@ internal class GroupImpl(
return this.id == other.id && this.bot == other.bot 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)
}
} }
\ No newline at end of file
...@@ -9,18 +9,25 @@ ...@@ -9,18 +9,25 @@
package net.mamoe.mirai.qqandroid 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.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 io.ktor.client.statement.HttpResponse
import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.async
import kotlinx.coroutines.io.ByteReadChannel 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.BotAccount
import net.mamoe.mirai.BotImpl import net.mamoe.mirai.BotImpl
import net.mamoe.mirai.LowLevelAPI import net.mamoe.mirai.LowLevelAPI
import net.mamoe.mirai.contact.* import net.mamoe.mirai.contact.*
import net.mamoe.mirai.data.AddFriendResult import net.mamoe.mirai.data.*
import net.mamoe.mirai.data.FriendInfo
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.event.broadcast import net.mamoe.mirai.event.broadcast
import net.mamoe.mirai.event.events.MessageRecallEvent import net.mamoe.mirai.event.events.MessageRecallEvent
import net.mamoe.mirai.message.data.* import net.mamoe.mirai.message.data.*
...@@ -33,6 +40,7 @@ import net.mamoe.mirai.qqandroid.network.protocol.packet.chat.PbMessageSvc ...@@ -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.chat.TroopManagement
import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList import net.mamoe.mirai.qqandroid.network.protocol.packet.list.FriendList
import net.mamoe.mirai.utils.* import net.mamoe.mirai.utils.*
import net.mamoe.mirai.utils.io.encodeToString
import kotlin.collections.asSequence import kotlin.collections.asSequence
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
...@@ -209,6 +217,133 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -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) { override suspend fun queryImageUrl(image: Image): String = when (image) {
is OnlineFriendImageImpl -> image.originUrl is OnlineFriendImageImpl -> image.originUrl
is OnlineGroupImageImpl -> image.originUrl is OnlineGroupImageImpl -> image.originUrl
...@@ -224,6 +359,18 @@ internal abstract class QQAndroidBotBase constructor( ...@@ -224,6 +359,18 @@ internal abstract class QQAndroidBotBase constructor(
override suspend fun openChannel(image: Image): ByteReadChannel { override suspend fun openChannel(image: Image): ByteReadChannel {
return MiraiPlatformUtils.Http.get<HttpResponse>(queryImageUrl(image)).content.toKotlinByteReadChannel() 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") @Suppress("DEPRECATION")
......
...@@ -153,28 +153,7 @@ expect abstract class Group() : Contact, CoroutineScope { ...@@ -153,28 +153,7 @@ expect abstract class Group() : Contact, CoroutineScope {
*/ */
abstract operator fun contains(id: Long): Boolean 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)
/** /**
* 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败 * 让机器人退出这个群. 机器人必须为非群主才能退出. 否则将会失败
......
...@@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable ...@@ -7,7 +7,7 @@ import kotlinx.serialization.Serializable
* 群公告数据类 * 群公告数据类
* getGroupAnnouncementList时,如果page=1,那么你可以在inst里拿到一些置顶公告 * getGroupAnnouncementList时,如果page=1,那么你可以在inst里拿到一些置顶公告
* *
* 发公告时只需要填写text, * 发公告时只需要填写text,其他参数可为默认值
* *
*/ */
@Serializable @Serializable
......
...@@ -12,9 +12,7 @@ package net.mamoe.mirai ...@@ -12,9 +12,7 @@ package net.mamoe.mirai
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import net.mamoe.mirai.contact.Group import net.mamoe.mirai.contact.Group
import net.mamoe.mirai.contact.QQ import net.mamoe.mirai.contact.QQ
import net.mamoe.mirai.data.FriendInfo import net.mamoe.mirai.data.*
import net.mamoe.mirai.data.GroupInfo
import net.mamoe.mirai.data.MemberInfo
import net.mamoe.mirai.message.data.MessageSource import net.mamoe.mirai.message.data.MessageSource
import net.mamoe.mirai.utils.MiraiExperimentalAPI import net.mamoe.mirai.utils.MiraiExperimentalAPI
import net.mamoe.mirai.utils.MiraiInternalAPI import net.mamoe.mirai.utils.MiraiInternalAPI
...@@ -94,6 +92,41 @@ interface LowLevelBotAPIAccessor { ...@@ -94,6 +92,41 @@ interface LowLevelBotAPIAccessor {
*/ */
@LowLevelAPI @LowLevelAPI
suspend fun _lowLevelRecallGroupMessage(groupId: Long, messageId: Long) 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
} }
/** /**
......
...@@ -149,26 +149,6 @@ actual abstract class Group : Contact(), CoroutineScope { ...@@ -149,26 +149,6 @@ actual abstract class Group : Contact(), CoroutineScope {
actual abstract fun getOrNull(id: Long): Member? 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 的群成员是否存在 * 检查此 id 的群成员是否存在
*/ */
......
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