4 Commits

Author SHA1 Message Date
7bfb9b7b61 Shamrock: support /set_guild_member_role 2024-02-03 06:21:34 +08:00
c43689822b Shamrock: support /delete_guild_role 2024-02-03 05:59:49 +08:00
7952453137 Shamrock: support /get_guild_roles 2024-02-03 05:45:25 +08:00
2f61f6da00 Shamrock: support /get_guild_feeds 2024-02-03 03:05:38 +08:00
64 changed files with 999 additions and 140 deletions

View File

@ -1,7 +1,7 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("ArrayInDataClass") @file:Suppress("ArrayInDataClass")
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -12,4 +12,4 @@ data class WeiyunCommonReq (
@ProtoNumber(2009) val addRichMediaReq: WeiyunAddRichMediaReq? = null, @ProtoNumber(2009) val addRichMediaReq: WeiyunAddRichMediaReq? = null,
@ProtoNumber(2010) val fastUploadResourceReq: WeiyunFastUploadResourceReq? = null, @ProtoNumber(2010) val fastUploadResourceReq: WeiyunFastUploadResourceReq? = null,
) )

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,6 +1,6 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,6 +1,6 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,7 +1,7 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
@file:Suppress("ArrayInDataClass") @file:Suppress("ArrayInDataClass")
package moe.whitechi73.protobuf.fav package protobuf.fav
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.group_file_common package protobuf.group_file_common
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -0,0 +1,405 @@
@file:OptIn(ExperimentalSerializationApi::class)
package protobuf.guild
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
import protobuf.qweb.QWebExtInfo
@Serializable
data class GetGuildFeedsReq(
@ProtoNumber(1) var count: Int,
@ProtoNumber(2) var from: Int? = null,
@ProtoNumber(3) var feedAttchInfo: ByteArray? = null,
@ProtoNumber(4) var guildId: ULong? = null,
@ProtoNumber(5) var getType: Int? = null,
@ProtoNumber(6) var sortOption: Int? = null,
@ProtoNumber(7) var u7: Int? = null,
@ProtoNumber(8) var u8: Int? = null,
@ProtoNumber(9) var u9: ByteArray? = null,
)
@Serializable
data class GetGuildFeedsRsp(
@ProtoNumber(1) var vecFeed: List<StFeed>? = null,
@ProtoNumber(2) var isFinish: Int = 0,
//@ProtoNumber(3) var feedAttchInfo: ByteArray? = null,
//@ProtoNumber(4) var traceId: String? = null,
)
@Serializable
data class StFeed(
@SerialName("id") @ProtoNumber(1) var id: String,
@SerialName("title") @ProtoNumber(2) var title: StRichText,
@SerialName("poster") @ProtoNumber(4) var poster: StUser? = null,
@SerialName("videos") @ProtoNumber(5) var videos: List<StVideo>? = null,
@SerialName("contents") @ProtoNumber(6) var contents: StRichText? = null,
@SerialName("create_time") @ProtoNumber(7) var createTime: ULong? = null,
@SerialName("comment_count") @ProtoNumber(9) var commentCount: UInt? = null,
@SerialName("comments") @ProtoNumber(10) var vecComment: List<StComment>? = null,
@SerialName("share") @ProtoNumber(11) var share: StShare? = null,
@SerialName("visitor_info") @ProtoNumber(12) var visitorInfo: StVisitor? = null,
@SerialName("images") @ProtoNumber(13) var images: List<StImage>? = null,
@SerialName("poi") @ProtoNumber(14) var poiInfo: StPoiInfoV2? = null,
@SerialName("op_mask") @ProtoNumber(17) var opMask: List<Int>? = null,
@SerialName("channel_info") @ProtoNumber(21) var channelInfo: StChannelInfo? = null,
@SerialName("create_time_ns") @ProtoNumber(22) var createTimeNs: ULong? = null,
@SerialName("update_time") @ProtoNumber(28) var updateTime: ULong? = null,
@SerialName("total_like") @ProtoNumber(29) var totalLike: StTotalLike? = null,
@SerialName("discussion_mum") @ProtoNumber(31) var discussionMum: UInt? = null,
@SerialName("feed_type") @ProtoNumber(32) var feedType: UInt? = null,
@SerialName("default_background_img") @ProtoNumber(34) var defaultBackgroundImg: String? = null,
@SerialName("group_code") @ProtoNumber(35) var groupCode: ULong? = null,
)
@Serializable
data class StTotalLike (
@SerialName("count") @ProtoNumber(1) var likeCount: UInt? = null,
@SerialName("is_clicked") @ProtoNumber(2) var isClicked: UInt? = null,
)
@Serializable
data class StPoiInfoV2(
@SerialName("poi_id") @ProtoNumber(1) var poiId: String? = null,
@SerialName("name") @ProtoNumber(2) var name: String? = null,
@SerialName("poi_type") @ProtoNumber(3) var poiType: Int? = null,
@SerialName("type_name") @ProtoNumber(4) var typeName: String? = null,
@SerialName("address") @ProtoNumber(5) var address: String? = null,
@SerialName("district_code") @ProtoNumber(6) var districtCode: Int? = null,
@SerialName("gps") @ProtoNumber(7) var gps: StGPSV2? = null,
@SerialName("distance") @ProtoNumber(8) var distance: Int? = null,
@SerialName("hot_value") @ProtoNumber(9) var hotValue: Int? = null,
@SerialName("phone") @ProtoNumber(10) var phone: String? = null,
@SerialName("country") @ProtoNumber(11) var country: String? = null,
@SerialName("province") @ProtoNumber(12) var province: String? = null,
@SerialName("city") @ProtoNumber(13) var city: String? = null,
@SerialName("poi_num") @ProtoNumber(14) var poiNum: Int? = null,
@SerialName("poi_order_type") @ProtoNumber(15) var poiOrderType: Int? = null,
@SerialName("default_name") @ProtoNumber(16) var defaultName: String? = null,
@SerialName("district") @ProtoNumber(17) var district: String? = null,
@SerialName("dian_ping_id") @ProtoNumber(18) var dianPingId: String? = null,
@SerialName("distance_text") @ProtoNumber(19) var distanceText: String? = null,
@SerialName("display_name") @ProtoNumber(20) var displayName: String? = null,
)
@Serializable
data class StGPSV2(
@SerialName("lat") @ProtoNumber(1) var latitude: Long? = null,
@SerialName("lon") @ProtoNumber(2) var longitude: Long? = null,
)
@Serializable
data class StShare(
@SerialName("title") @ProtoNumber(1) var title: String? = null,
@SerialName("desc") @ProtoNumber(2) var desc: String? = null,
@SerialName("type") @ProtoNumber(3) var type: UInt? = null,
@SerialName("url") @ProtoNumber(4) var url: String? = null,
@SerialName("author") @ProtoNumber(5) var author: StUser? = null,
@SerialName("poster") @ProtoNumber(6) var poster: StUser? = null,
@SerialName("videos") @ProtoNumber(7) var videos: List<StVideo>? = null,
@SerialName("short_url") @ProtoNumber(8) var shorturl: String? = null,
@SerialName("share_card_info") @ProtoNumber(9) var shareCardInfo: String? = null,
//@ProtoNumber(10) var shareQzoneInfo: Any? = null,
@SerialName("images") @ProtoNumber(11) var images: List<StImage>? = null,
@SerialName("publish_total_user") @ProtoNumber(12) var publishTotalUser: UInt? = null,
@SerialName("shared_count") @ProtoNumber(13) var sharedCount: UInt? = null,
//@ProtoNumber(14) var channelShareInfo: Any? = null,
)
@Serializable
data class StVisitor(
@SerialName("view_count")
@ProtoNumber(1) val viewCount: UInt? = null,
@SerialName("recome_count")
@ProtoNumber(3) val recomeCount: UInt? = null,
@SerialName("view_desc")
@ProtoNumber(4) val viewDesc: String? = null,
)
@Serializable
data class StComment(
@SerialName("id") @ProtoNumber(1) var id: String? = null,
@SerialName("poster") @ProtoNumber(2) var postUser: StUser? = null,
@SerialName("create_time") @ProtoNumber(3) var createTime: ULong? = null,
@SerialName("content") @ProtoNumber(4) var content: String? = null,
@SerialName("reply_count") @ProtoNumber(5) var replyCount: UInt? = null,
@SerialName("replies") @ProtoNumber(6) var vecReply: List<StReply>? = null,
//@ProtoNumber(7) var busiData: Any? = null,
@SerialName("like_info") @ProtoNumber(8) var likeInfo: StLike? = null,
@SerialName("type_flag") @ProtoNumber(9) var typeFlag: UInt? = null,
@SerialName("at_uin_list") @ProtoNumber(10) var atUinList: List<String>? = null,
@SerialName("type_flag2") @ProtoNumber(11) var typeFlag2: UInt? = null,
@SerialName("create_time_ns") @ProtoNumber(12) var createTimeNs: ULong? = null,
@SerialName("store_ext_info") @ProtoNumber(13) var storeExtInfo: List<QWebExtInfo>? = null,
@SerialName("third_id") @ProtoNumber(14) var thirdId: String? = null,
@SerialName("source_type") @ProtoNumber(15) var sourceType: UInt? = null,
@SerialName("rich_contents") @ProtoNumber(16) var richContents: StRichText? = null,
@SerialName("images") @ProtoNumber(17) var images: List<StImage>? = null,
@SerialName("sequence") @ProtoNumber(18) var sequence: ULong? = null,
@SerialName("next_page_reply") @ProtoNumber(19) var nextPageReply: Boolean? = null,
@SerialName("attach_info") @ProtoNumber(20) var attachInfo: String? = null,
)
@Serializable
data class StReply(
@SerialName("id") @ProtoNumber(1) var id: String? = null,
@SerialName("poster") @ProtoNumber(2) var postUser: StUser? = null,
@SerialName("create_time") @ProtoNumber(3) var createTime: ULong? = null,
@SerialName("content") @ProtoNumber(4) var content: String? = null,
@SerialName("target") @ProtoNumber(5) var targetUser: StUser? = null,
//@ProtoNumber(6) var busiData: ByteArray? = null,
@SerialName("like_info") @ProtoNumber(7) var likeInfo: StLike? = null,
@SerialName("type_flag") @ProtoNumber(8) var typeFlag: UInt? = null,
@SerialName("modify_flag") @ProtoNumber(9) var modifyflag: UInt? = null,
@SerialName("at_uin_list") @ProtoNumber(10) var atUinList: List<String>? = null,
@SerialName("type_flag2") @ProtoNumber(11) var typeFlag2: UInt? = null,
@SerialName("create_time_ns") @ProtoNumber(12) var createTimeNs: ULong? = null,
@SerialName("store_ext_info") @ProtoNumber(13) var storeExtInfo: List<QWebExtInfo>? = null,
@SerialName("third_id") @ProtoNumber(14) var thirdId: String? = null,
@SerialName("target_reply_id") @ProtoNumber(15) var targetReplyID: String? = null,
@SerialName("source_type") @ProtoNumber(16) var sourceType: UInt? = null,
@SerialName("rich_contents") @ProtoNumber(17) var richContents: StRichText? = null,
@SerialName("images") @ProtoNumber(18) var images: List<StImage>? = null,
)
@Serializable
data class StLike(
@SerialName("id")
@ProtoNumber(1) var id: String? = null,
@SerialName("count")
@ProtoNumber(2) var count: UInt? = null,
@SerialName("status")
@ProtoNumber(3) var status: UInt? = null,
@SerialName("like_uin_list")
@ProtoNumber(4) var vecUser: List<StUser>? = null,
@SerialName("poster")
@ProtoNumber(6) var postUser: StUser? = null,
@SerialName("has_liked_count")
@ProtoNumber(7) var hasLikedCount: UInt? = null,
@SerialName("owner_status")
@ProtoNumber(8) var ownerStatus: UInt? = null,
@SerialName("jump_url")
@ProtoNumber(9) var jumpUrl: String? = null,
)
@Serializable
data class StVideo(
@SerialName("file_id") @ProtoNumber(1) var fileId: String? = null,
@SerialName("file_size") @ProtoNumber(2) var fileSize: UInt? = null,
@SerialName("duration") @ProtoNumber(3) var duration: UInt? = null,
@SerialName("width") @ProtoNumber(4) var width: UInt? = null,
@SerialName("height") @ProtoNumber(5) var height: UInt? = null,
@SerialName("play_url") @ProtoNumber(6) var playUrl: String? = null,
@SerialName("trans_status") @ProtoNumber(7) var transStatus: UInt? = null,
@SerialName("video_prior") @ProtoNumber(8) var videoPrior: UInt? = null,
@SerialName("video_rate") @ProtoNumber(9) var videoRate: UInt? = null,
//@ProtoNumber(10) var vecVideoUrl: String? = null,
//@ProtoNumber(11) var busiData: Any? = null,
@SerialName("approval_status") @ProtoNumber(12) var approvalStatus: UInt? = null,
@SerialName("video_source") @ProtoNumber(13) var videoSource: UInt? = null,
@SerialName("media_quality_rank") @ProtoNumber(14) var mediaQualityRank: UInt? = null,
@SerialName("media_quality_score") @ProtoNumber(15) var mediaQualityScore: Float? = null,
@SerialName("md5") @ProtoNumber(16) var videoMD5: String? = null,
@SerialName("is_quic") @ProtoNumber(17) var isQuic: UInt? = null,
@SerialName("orientation") @ProtoNumber(18) var orientation: Int? = null,
@SerialName("cover") @ProtoNumber(19) var cover: StImage? = null,
@SerialName("pattern_id") @ProtoNumber(20) var patternId: String? = null,
@SerialName("display_index") @ProtoNumber(21) var displayIndex: UInt? = null,
)
@Serializable
data class StRichText(
@SerialName("contents") @ProtoNumber(1) var contents: List<StRichTextContent>? = null,
@SerialName("images") @ProtoNumber(2) var images: List<StImage>? = null,
)
@Serializable
data class StRichTextContent(
@SerialName("type") @ProtoNumber(1) var type: Int? = null,
@SerialName("pattern_id") @ProtoNumber(2) var patternId: String? = null,
@SerialName("text") @ProtoNumber(3) var textContent: StRichTextTextContent? = null,
@SerialName("at") @ProtoNumber(4) var atContent: StRichTextAtContent? = null,
@SerialName("url") @ProtoNumber(5) var urlContent: StRichTextURLContent? = null,
@SerialName("emoji") @ProtoNumber(6) var emojiContent: StRichTextEmojiContent? = null,
@SerialName("channel") @ProtoNumber(7) var channelContent: StRichTextChannelContent? = null,
@SerialName("guild") @ProtoNumber(8) var guildContent: StRichTextGuildContent? = null,
@SerialName("icon") @ProtoNumber(9) var iconContent: StRichTextIconContent? = null,
)
@Serializable
data class StRichTextIconContent(
@SerialName("url") @ProtoNumber(1) val url: String? = null
)
@Serializable
data class StRichTextGuildContent(
@SerialName("channel_info") @ProtoNumber(1) val channelInfo: StChannelInfo? = null
)
@Serializable
data class StRichTextChannelContent(
@SerialName("channel_info") @ProtoNumber(1) val channelInfo: StChannelInfo? = null
)
@Serializable
data class StChannelInfo(
//@SerialName("sign") @ProtoNumber(1) var sign: String? = null,
@SerialName("name")
@ProtoNumber(2) var name: String? = null,
@SerialName("icon_url")
@ProtoNumber(3) var iconUrl: String? = null,
@SerialName("type")
@ProtoNumber(4) var privateType: Int? = null,
@SerialName("guild_name")
@ProtoNumber(5) var guildName: String? = null,
@SerialName("hot_icon")
@ProtoNumber(6) var hotIcon: String? = null,
@SerialName("hot_index")
@ProtoNumber(7) var hotIndex: UInt? = null,
)
@Serializable
data class StRichTextEmojiContent(
@ProtoNumber(1) var id: String? = null,
@ProtoNumber(2) var type: String? = null,
@ProtoNumber(3) var name: String? = null,
@ProtoNumber(4) var url: String? = null,
)
@Serializable
data class StRichTextURLContent(
@ProtoNumber(1) var url: String? = null,
@SerialName("display") @ProtoNumber(2) var displayText: String? = null,
@ProtoNumber(3) var type: Int? = null,
@SerialName("play_url") @ProtoNumber(4) var playUrl: String? = null,
@SerialName("platform") @ProtoNumber(5) var thirdPlatform: ThirdPlatform? = null,
@SerialName("third_video_info") @ProtoNumber(6) var thirdVideoInfo: CommThirdVideoInfo? = null,
)
@Serializable
data class CommThirdVideoInfo(
@SerialName("cover") @ProtoNumber(1) val cover: String? = null,
@SerialName("duration") @ProtoNumber(2) val duration: ULong? = null,
)
@Serializable
data class ThirdPlatform(
@ProtoNumber(1) var icon: String? = null,
@ProtoNumber(2) var name: String? = null,
)
@Serializable
data class StRichTextTextContent(
@ProtoNumber(1) var text: String? = null
)
@Serializable
data class StRichTextAtContent(
@ProtoNumber(1) var type: Int? = null,
@SerialName("guild_info") @ProtoNumber(2) var guildInfo: GuildInfo? = null,
@SerialName("role_info") @ProtoNumber(3) var roleGroupId: RoleGroupInfo? = null,
@ProtoNumber(4) var user: StUser? = null,
)
@Serializable
data class StUser(
@ProtoNumber(1) var id: String? = null,
@ProtoNumber(2) var nick: String? = null,
@ProtoNumber(3) var icon: StIconInfo? = null,
@ProtoNumber(4) var desc: String? = null,
@SerialName("follow_state") @ProtoNumber(5) var followState: UInt? = null,
@ProtoNumber(6) var type: UInt? = null,
@ProtoNumber(7) var sex: UInt? = null,
@ProtoNumber(8) var birthday: ULong? = null,
@ProtoNumber(9) var school: String? = null,
@ProtoNumber(11) var location: String? = null,
//@ProtoNumber(12) var busiData: ByteArray? = null,
@SerialName("frd") @ProtoNumber(13) var frdState: UInt? = null,
@SerialName("relation_state") @ProtoNumber(14) var relationState: UInt? = null,
@SerialName("black_state") @ProtoNumber(15) var blackState: UInt? = null,
@ProtoNumber(16) var medal: StTagMedalInfo? = null,
@ProtoNumber(17) var constellation: Int? = null,
@SerialName("jump_url") @ProtoNumber(18) var jumpUrl: String? = null,
@SerialName("location_code") @ProtoNumber(19) var locationCode: String? = null,
@SerialName("third_id") @ProtoNumber(20) var thirdId: String? = null,
@ProtoNumber(21) var company: String? = null,
@SerialName("certification_desc") @ProtoNumber(22) var certificationDesc: String? = null,
@SerialName("desc_type") @ProtoNumber(23) var descType: UInt? = null,
//@ProtoNumber(24) var channelUserInfo: Any? = null,
//@SerialName("login_id") @ProtoNumber(25) var loginId: String? = null,
@ProtoNumber(26) var uin: ULong? = null,
@SerialName("nick_flag") @ProtoNumber(27) var nickFlag: UInt? = null,
@SerialName("manage_tag") @ProtoNumber(28) var manageTag: CustomManageTag? = null,
//@SerialName("personal_medal") @ProtoNumber(29) var personalMedal: PersonalMedal? = null,
)
@Serializable
data class PersonalMedal(
@SerialName("start") @ProtoNumber(1) val startTime: ULong? = null,
@SerialName("end") @ProtoNumber(2) val endTime: ULong? = null,
@ProtoNumber(3) var url: String? = null,
)
@Serializable
data class StTagMedalInfo(
@SerialName("id") @ProtoNumber(1) val tagId: ULong? = null,
@SerialName("name") @ProtoNumber(2) val tagName: String? = null,
@ProtoNumber(3) val rank: ULong? = null,
)
@Serializable
data class CustomManageTag(
@ProtoNumber(3) val color: UInt? = null,
@SerialName("name") @ProtoNumber(2) val tagName: String? = null,
)
@Serializable
data class StIconInfo(
//@SerialName("url_40") @ProtoNumber(1) var iconUrl40: String? = null,
//@SerialName("url_100") @ProtoNumber(2) var iconUrl100: String? = null,
//@SerialName("url_140") @ProtoNumber(3) var iconUrl140: String? = null,
//@SerialName("url_640") @ProtoNumber(4) var iconUrl640: String? = null,
@SerialName("url") @ProtoNumber(5) var iconUrl: String? = null,
)
@Serializable
data class RoleGroupInfo(
@SerialName("role") @ProtoNumber(1) var roleId: ULong? = null,
@ProtoNumber(2) var name: String? = null,
@ProtoNumber(3) var color: ULong? = null,
)
@Serializable
data class GuildInfo(
@SerialName("guild_id") @ProtoNumber(1) var guildId: ULong? = null,
@ProtoNumber(2) var name: String? = null,
@SerialName("join_time") @ProtoNumber(3) var joinTime: ULong? = null,
)
@Serializable
data class StImage(
@ProtoNumber(1) var width: UInt? = null,
@ProtoNumber(2) var height: UInt? = null,
@ProtoNumber(3) var picUrl: String? = null,
@SerialName("image_urls") @ProtoNumber(4) var vecImageUrl: List<StImageUrl>? = null,
@SerialName("id") @ProtoNumber(5) var picId: String? = null,
//@ProtoNumber(6) var busiData: Any? = null,
@SerialName("md5") @ProtoNumber(7) var imageMD5: String? = null,
@SerialName("layer_pic_url") @ProtoNumber(8) var layerPicUrl: String? = null,
@SerialName("pattern_id") @ProtoNumber(9) var patternId: String? = null,
@SerialName("display_index") @ProtoNumber(10) var displayIndex: Int? = null,
@SerialName("size") @ProtoNumber(11) var origSize: UInt? = null,
@SerialName("is_original") @ProtoNumber(12) var isOrig: Boolean? = null,
@SerialName("is_gif") @ProtoNumber(13) var isGif: Boolean? = null,
)
@Serializable
data class StImageUrl(
@SerialName("level_type") @ProtoNumber(1) var levelType: UInt? = null,
@ProtoNumber(2) var url: String? = null,
@ProtoNumber(3) var width: UInt? = null,
@ProtoNumber(4) var height: UInt? = null,
//@ProtoNumber(5) var busiData: Any? = null,
)

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.message package protobuf.message
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,7 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) package protobuf.oidb
package moe.whitechi73.protobuf.oidb
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,11 +1,11 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb.cmd0x6d7 package protobuf.oidb.cmd0x6d7
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.whitechi73.protobuf.group_file_common.FolderInfo import protobuf.group_file_common.FolderInfo
@Serializable @Serializable
data class Oidb0x6d7ReqBody( data class Oidb0x6d7ReqBody(

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.oidb.cmd0x9082 package protobuf.oidb.cmd0x9082
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.oidb.cmd0xf16 package protobuf.oidb.cmd0xf16
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,6 +1,6 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb.cmd0xf88 package protobuf.oidb.cmd0xf88
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,5 +1,5 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb.cmd0xfc2 package protobuf.oidb.cmd0xfc2
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,6 +1,6 @@
@file:OptIn(ExperimentalSerializationApi::class) @file:OptIn(ExperimentalSerializationApi::class)
package moe.whitechi73.protobuf.oidb.cmx0xf57 package protobuf.oidb.cmx0xf57
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,4 +1,4 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber

View File

@ -1,8 +1,8 @@
package moe.whitechi73.protobuf.push package protobuf.push
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber import kotlinx.serialization.protobuf.ProtoNumber
import moe.whitechi73.protobuf.message.MessageBody import protobuf.message.MessageBody
@Serializable @Serializable
data class MessagePush( data class MessagePush(

View File

@ -0,0 +1,37 @@
@file:OptIn(ExperimentalSerializationApi::class)
package protobuf.qweb
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@Serializable
data class QWebReq(
@ProtoNumber(1) val seq: Int = 0,
@ProtoNumber(2) val qua: String = "",
@ProtoNumber(3) val deviceInfo: String = "",
@ProtoNumber(4) val buffer: ByteArray? = null,
@ProtoNumber(5) val traceId: String = "",
@ProtoNumber(6) val module: String = "",
@ProtoNumber(7) var cmdname: String? = null,
//@ProtoNumber(8) var loginSig: Any? = null,
//@ProtoNumber(9) var Crypto: Any? = null,
@ProtoNumber(10) var extinfo: List<QWebExtInfo>? = null,
//@ProtoNumber(11) var contentType: Any? = null,
)
@Serializable
data class QWebExtInfo(
@ProtoNumber(1) val key: String,
@ProtoNumber(2) val value: String,
)
@Serializable
data class QWebRsp(
@ProtoNumber(1) var seq: Int? = null,
//@ProtoNumber(2) var retCode: Int? = null,
//@ProtoNumber(3) var errMsg: String? = null,
@ProtoNumber(4) var buffer: ByteArray? = null,
//@ProtoNumber(5) var Extinfo: List<QWebExtInfo>? = null,
)

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchChannelInvisibleRoleListCallback {
void onFetchChannelInvisibleRoleList(int code, String reason, ArrayList<GProGuildRole> roles);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchChannelLiveableRoleListCallback {
void onFetchChannelLiveableRoleList(int code, String reason, int seq, ArrayList<GProGuildRole> roles);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchRoleListPermissionCallback {
void onFetchRoleListPermissionCallback(int code, String msg, ArrayList<GProGuildRole> roles, ArrayList<GProGuildRole> lvRoles, ArrayList<Long> myRoles, long unused);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchRolePermissionCallback {
void onFetchRolePermissionCallback(int code, String msg, GProGuildRole role, GProRolePermission permission, ArrayList<GProRolePermissionDesc> permissionDescs, ArrayList<GProRolePermissionCategory> permissionCategories);
}

View File

@ -0,0 +1,7 @@
package com.tencent.qqnt.kernel.nativeinterface;
import java.util.ArrayList;
public interface IGProFetchTopFeedsCallback {
void onResult(int code, String msg, ArrayList<GProTopFeed> feeds);
}

View File

@ -0,0 +1,5 @@
package com.tencent.qqnt.kernel.nativeinterface;
public interface IGProResultCallback {
void onResult(int code, String msg, GProSecurityResult result);
}

View File

@ -32,7 +32,7 @@ public interface IKernelGuildService {
//void fetchGuestGuildInfoWithChannelList(String guildId, String str2, int i2, int seq, String str3, //void fetchGuestGuildInfoWithChannelList(String guildId, String str2, int i2, int seq, String str3,
// IGProFetchGuestGuildInfoWithChannelListCallback iGProFetchGuestGuildInfoWithChannelListCallback); // IGProFetchGuestGuildInfoWithChannelListCallback iGProFetchGuestGuildInfoWithChannelListCallback);
GProGuild getGuildInfoFromCache(long j2); GProGuild getGuildInfoFromCache(long guildId);
// 第一次请求: startIndex = 0 , roleIdIndex = 2 // 第一次请求: startIndex = 0 , roleIdIndex = 2
void fetchMemberListWithRole(long guildId, long channelId, long startIndex, long roleIndex, int count, int seq, IGProFetchMemberListWithRoleCallback cb); void fetchMemberListWithRole(long guildId, long channelId, long startIndex, long roleIndex, int count, int seq, IGProFetchMemberListWithRoleCallback cb);
@ -41,12 +41,23 @@ public interface IKernelGuildService {
void refreshGuildInfoOnly(long j2, boolean z, int i2); void refreshGuildInfoOnly(long j2, boolean z, int i2);
void fetchMemberRoles(long guildId, long channelId, long tinyId, int seq, IGProFetchMemberRolesCallback cb);
void refreshGuildUserProfileInfo(long guildId, long tinyId, int seq); void refreshGuildUserProfileInfo(long guildId, long tinyId, int seq);
void fetchUserInfo(long guildId, long channelId, ArrayList<Long> tinyIdList, int seq, IGProGetUserInfoCallback cb); void fetchUserInfo(long guildId, long channelId, ArrayList<Long> tinyIdList, int seq, IGProGetUserInfoCallback cb);
@Deprecated(since = "QQ新版本不支持创建话题子频道")
void fetchTopFeeds(long guildId, long channelId, IGProFetchTopFeedsCallback cb);
void fetchChannelInvisibleRoleList(long guildId, long channelId, IGProFetchChannelInvisibleRoleListCallback cb);
void fetchChannelLiveableRoleList(long guildId, long channelId, IGProFetchChannelLiveableRoleListCallback cb);
void fetchMemberRoles(long guildId, long channelId, long tinyId, int seq, IGProFetchMemberRolesCallback cb);
void fetchRoleListWithPermission(long guildId, int seq, IGProFetchRoleListPermissionCallback cb);
void fetchRoleWithPermission(long guildId, long roleId, int seq, IGProFetchRolePermissionCallback cb);
GProSimpleProfile getSimpleProfile(long guildId, long tinyId, int seq); GProSimpleProfile getSimpleProfile(long guildId, long tinyId, int seq);
GProFaceAuthInfo getFaceAuthInfo(); GProFaceAuthInfo getFaceAuthInfo();
@ -54,4 +65,9 @@ public interface IKernelGuildService {
String getGuildUserAvatarUrl(long guildId, long tinyId, int seq); String getGuildUserAvatarUrl(long guildId, long tinyId, int seq);
String getGuildUserNickname(long guildId); String getGuildUserNickname(long guildId);
void deleteRole(long guild, long role, IGProResultCallback cb);
void setMemberRoles(long guild, long u1, long u2, long tinyId, ArrayList<Long> addRoles, ArrayList<Long> removeRoles, IGProResultCallback cb);
} }

View File

@ -7,6 +7,10 @@ import com.tencent.mobileqq.app.QQAppInterface
import com.tencent.mobileqq.msf.core.MsfCore import com.tencent.mobileqq.msf.core.MsfCore
import com.tencent.mobileqq.pb.ByteStringMicro import com.tencent.mobileqq.pb.ByteStringMicro
import com.tencent.qphone.base.remote.ToServiceMsg import com.tencent.qphone.base.remote.ToServiceMsg
import io.ktor.utils.io.core.BytePacketBuilder
import io.ktor.utils.io.core.readBytes
import io.ktor.utils.io.core.writeFully
import io.ktor.utils.io.core.writeInt
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -15,11 +19,13 @@ import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
import moe.fuqiuluo.shamrock.xposed.helper.internal.DynamicReceiver import moe.fuqiuluo.shamrock.xposed.helper.internal.DynamicReceiver
import moe.fuqiuluo.shamrock.xposed.helper.internal.IPCRequest import moe.fuqiuluo.shamrock.xposed.helper.internal.IPCRequest
import moe.whitechi73.protobuf.oidb.TrpcOidb import protobuf.oidb.TrpcOidb
import mqq.app.MobileQQ import mqq.app.MobileQQ
import tencent.im.oidb.oidb_sso import tencent.im.oidb.oidb_sso
import kotlin.coroutines.resume import kotlin.coroutines.resume
@ -38,7 +44,7 @@ internal abstract class BaseSvc {
suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? { suspend fun sendOidbAW(cmd: String, cmdId: Int, serviceId: Int, data: ByteArray, trpc: Boolean = false, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq() val seq = MsfCore.getNextSeq()
return withTimeoutOrNull(timeout) { val buffer = withTimeoutOrNull(timeout) {
suspendCancellableCoroutine { continuation -> suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) { GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(cmd, seq) { DynamicReceiver.register(IPCRequest(cmd, seq) {
@ -53,11 +59,21 @@ internal abstract class BaseSvc {
if (it == null) if (it == null)
DynamicReceiver.unregister(seq) DynamicReceiver.unregister(seq)
}?.copyOf() }?.copyOf()
try {
if (buffer != null && buffer.size >= 5 && buffer[4] == 120.toByte()) {
val builder = BytePacketBuilder()
val deBuffer = DeflateTools.uncompress(buffer.slice(4))
builder.writeInt(deBuffer.size)
builder.writeFully(deBuffer)
return builder.build().readBytes()
}
} catch (_: Exception) { }
return buffer
} }
suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? { suspend fun sendBufferAW(cmd: String, isPb: Boolean, data: ByteArray, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq() val seq = MsfCore.getNextSeq()
return withTimeoutOrNull<ByteArray?>(timeout) { val buffer = withTimeoutOrNull<ByteArray?>(timeout) {
suspendCancellableCoroutine { continuation -> suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) { GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(cmd, seq) { DynamicReceiver.register(IPCRequest(cmd, seq) {
@ -71,6 +87,16 @@ internal abstract class BaseSvc {
if (it == null) if (it == null)
DynamicReceiver.unregister(seq) DynamicReceiver.unregister(seq)
}?.copyOf() }?.copyOf()
try {
if (buffer != null && buffer.size >= 5 && buffer[4] == 120.toByte()) {
val builder = BytePacketBuilder()
val deBuffer = DeflateTools.uncompress(buffer.slice(4))
builder.writeInt(deBuffer.size)
builder.writeFully(deBuffer)
return builder.build().readBytes()
}
} catch (_: Exception) { }
return buffer
} }
fun sendOidb(cmd: String, cmdId: Int, serviceId: Int, buffer: ByteArray, seq: Int = -1, trpc: Boolean = false) { fun sendOidb(cmd: String, cmdId: Int, serviceId: Int, buffer: ByteArray, seq: Int = -1, trpc: Boolean = false) {
@ -125,7 +151,7 @@ internal abstract class BaseSvc {
protected suspend fun sendAW(toServiceMsg: ToServiceMsg, timeout: Long = 5000L): ByteArray? { protected suspend fun sendAW(toServiceMsg: ToServiceMsg, timeout: Long = 5000L): ByteArray? {
val seq = MsfCore.getNextSeq() val seq = MsfCore.getNextSeq()
return withTimeoutOrNull<ByteArray?>(timeout) { val buffer = withTimeoutOrNull<ByteArray?>(timeout) {
suspendCancellableCoroutine { continuation -> suspendCancellableCoroutine { continuation ->
GlobalScope.launch(Dispatchers.Default) { GlobalScope.launch(Dispatchers.Default) {
DynamicReceiver.register(IPCRequest(toServiceMsg.serviceCmd, seq) { DynamicReceiver.register(IPCRequest(toServiceMsg.serviceCmd, seq) {
@ -139,6 +165,16 @@ internal abstract class BaseSvc {
}.also { }.also {
if (it == null) DynamicReceiver.unregister(seq) if (it == null) DynamicReceiver.unregister(seq)
}?.copyOf() }?.copyOf()
try {
if (buffer != null && buffer.size >= 5 && buffer[4] == 120.toByte()) {
val builder = BytePacketBuilder()
val deBuffer = DeflateTools.uncompress(buffer.slice(4))
builder.writeInt(deBuffer.size)
builder.writeFully(deBuffer)
return builder.build().readBytes()
}
} catch (_: Exception) { }
return buffer
} }
protected fun sendExtra(cmd: String, builder: (Bundle) -> Unit) { protected fun sendExtra(cmd: String, builder: (Bundle) -> Unit) {

View File

@ -2,18 +2,20 @@ package moe.fuqiuluo.qqinterface.servlet
import kotlinx.serialization.encodeToByteArray import kotlinx.serialization.encodeToByteArray
import kotlinx.serialization.protobuf.ProtoBuf import kotlinx.serialization.protobuf.ProtoBuf
import moe.whitechi73.protobuf.oidb.cmd0x9082.Oidb0x9082 import protobuf.oidb.cmd0x9082.Oidb0x9082
internal object ChatSvc: BaseSvc() { internal object ChatSvc: BaseSvc() {
fun setGroupMessageCommentFace(peer: Long, msgSeq: ULong, faceIndex: String, isSet: Boolean) { fun setGroupMessageCommentFace(peer: Long, msgSeq: ULong, faceIndex: String, isSet: Boolean) {
val serviceId = if (isSet) 1 else 2 val serviceId = if (isSet) 1 else 2
sendOidb("OidbSvcTrpcTcp.0x9082_$serviceId", 36994, serviceId, ProtoBuf.encodeToByteArray(Oidb0x9082( sendOidb("OidbSvcTrpcTcp.0x9082_$serviceId", 36994, serviceId, ProtoBuf.encodeToByteArray(
Oidb0x9082(
peer = peer.toULong(), peer = peer.toULong(),
msgSeq = msgSeq, msgSeq = msgSeq,
faceIndex = faceIndex, faceIndex = faceIndex,
flag = 1u, flag = 1u,
u1 = 0u, u1 = 0u,
u2 = 0u u2 = 0u
))) )
))
} }
} }

View File

@ -12,27 +12,29 @@ import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.whitechi73.protobuf.oidb.cmd0x6d7.CreateFolderReq import protobuf.oidb.cmd0x6d7.CreateFolderReq
import moe.whitechi73.protobuf.oidb.cmd0x6d7.DeleteFolderReq import protobuf.oidb.cmd0x6d7.DeleteFolderReq
import moe.whitechi73.protobuf.oidb.cmd0x6d7.MoveFolderReq import protobuf.oidb.cmd0x6d7.MoveFolderReq
import moe.whitechi73.protobuf.oidb.cmd0x6d7.Oidb0x6d7ReqBody import protobuf.oidb.cmd0x6d7.Oidb0x6d7ReqBody
import moe.whitechi73.protobuf.oidb.cmd0x6d7.Oidb0x6d7RespBody import protobuf.oidb.cmd0x6d7.Oidb0x6d7RespBody
import moe.whitechi73.protobuf.oidb.cmd0x6d7.RenameFolderReq import protobuf.oidb.cmd0x6d7.RenameFolderReq
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6 import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
import tencent.im.oidb.cmd0x6d8.oidb_0x6d8 import tencent.im.oidb.cmd0x6d8.oidb_0x6d8
import tencent.im.oidb.oidb_sso import tencent.im.oidb.oidb_sso
import moe.whitechi73.protobuf.group_file_common.FolderInfo as GroupFileCommonFolderInfo import protobuf.group_file_common.FolderInfo as GroupFileCommonFolderInfo
internal object FileSvc: BaseSvc() { internal object FileSvc: BaseSvc() {
suspend fun createFileFolder(groupId: String, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> { suspend fun createFileFolder(groupId: String, folderName: String, parentFolderId: String = "/"): Result<GroupFileCommonFolderInfo> {
val data = ProtoBuf.encodeToByteArray(Oidb0x6d7ReqBody( val data = ProtoBuf.encodeToByteArray(
Oidb0x6d7ReqBody(
createFolder = CreateFolderReq( createFolder = CreateFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
parentFolderId = parentFolderId, parentFolderId = parentFolderId,
folderName = folderName folderName = folderName
) )
)) )
)
val resultBuffer = sendOidbAW("OidbSvc.0x6d7_0", 1751, 0, data) val resultBuffer = sendOidbAW("OidbSvc.0x6d7_0", 1751, 0, data)
?: return Result.failure(Exception("unable to fetch result")) ?: return Result.failure(Exception("unable to fetch result"))
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
@ -45,13 +47,15 @@ internal object FileSvc: BaseSvc() {
} }
suspend fun deleteGroupFolder(groupId: String, folderUid: String): Boolean { suspend fun deleteGroupFolder(groupId: String, folderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, ProtoBuf.encodeToByteArray(Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_1", 1751, 1, ProtoBuf.encodeToByteArray(
Oidb0x6d7ReqBody(
deleteFolder = DeleteFolderReq( deleteFolder = DeleteFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid folderId = folderUid
) )
))) ?: return false )
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray())
@ -59,14 +63,16 @@ internal object FileSvc: BaseSvc() {
} }
suspend fun moveGroupFolder(groupId: String, folderUid: String, newParentFolderUid: String): Boolean { suspend fun moveGroupFolder(groupId: String, folderUid: String, newParentFolderUid: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, ProtoBuf.encodeToByteArray(Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_2", 1751, 2, ProtoBuf.encodeToByteArray(
Oidb0x6d7ReqBody(
moveFolder = MoveFolderReq( moveFolder = MoveFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid, folderId = folderUid,
parentFolderId = "/" parentFolderId = "/"
) )
))) ?: return false )
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray())
@ -74,14 +80,16 @@ internal object FileSvc: BaseSvc() {
} }
suspend fun renameFolder(groupId: String, folderUid: String, name: String): Boolean { suspend fun renameFolder(groupId: String, folderUid: String, name: String): Boolean {
val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, ProtoBuf.encodeToByteArray(Oidb0x6d7ReqBody( val buffer = sendOidbAW("OidbSvc.0x6d7_3", 1751, 3, ProtoBuf.encodeToByteArray(
Oidb0x6d7ReqBody(
renameFolder = RenameFolderReq( renameFolder = RenameFolderReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
appId = 3u, appId = 3u,
folderId = folderUid, folderId = folderUid,
folderName = name folderName = name
) )
))) ?: return false )
)) ?: return false
val oidbPkg = oidb_sso.OIDBSSOPkg() val oidbPkg = oidb_sso.OIDBSSOPkg()
oidbPkg.mergeFrom(buffer.slice(4)) oidbPkg.mergeFrom(buffer.slice(4))
val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray()) val rsp = ProtoBuf.decodeFromByteArray<Oidb0x6d7RespBody>(oidbPkg.bytes_bodybuffer.get().toByteArray())

View File

@ -5,7 +5,8 @@ package moe.fuqiuluo.qqinterface.servlet
import com.tencent.mobileqq.qqguildsdk.api.IGPSService import com.tencent.mobileqq.qqguildsdk.api.IGPSService
import com.tencent.qqnt.kernel.nativeinterface.GProGuildRole import com.tencent.qqnt.kernel.nativeinterface.GProGuildRole
import com.tencent.qqnt.kernel.nativeinterface.GProRoleMemberList import com.tencent.qqnt.kernel.nativeinterface.GProRoleMemberList
import com.tencent.qqnt.kernel.nativeinterface.IGProFetchMemberListWithRoleCallback import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.core.readBytes
import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withTimeoutOrNull import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
@ -19,20 +20,28 @@ import moe.fuqiuluo.qqinterface.servlet.structures.GuildStatus
import moe.fuqiuluo.qqinterface.servlet.structures.SlowModeInfo import moe.fuqiuluo.qqinterface.servlet.structures.SlowModeInfo
import moe.fuqiuluo.shamrock.helper.Level import moe.fuqiuluo.shamrock.helper.Level
import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.helper.LogCenter
import moe.fuqiuluo.shamrock.tools.EMPTY_BYTE_ARRAY
import moe.fuqiuluo.shamrock.tools.slice import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import moe.whitechi73.protobuf.oidb.cmd0xf88.GProFilter import protobuf.guild.GetGuildFeedsReq
import moe.whitechi73.protobuf.oidb.cmd0xf88.GProUserInfo import protobuf.guild.GetGuildFeedsRsp
import moe.whitechi73.protobuf.oidb.cmd0xf88.Oidb0xf88Req import protobuf.oidb.cmd0xf88.GProFilter
import moe.whitechi73.protobuf.oidb.cmd0xf88.Oidb0xf88Rsp import protobuf.oidb.cmd0xf88.GProUserInfo
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57Filter import protobuf.oidb.cmd0xf88.Oidb0xf88Req
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57GuildInfo import protobuf.oidb.cmd0xf88.Oidb0xf88Rsp
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57MetaInfo import protobuf.oidb.cmx0xf57.Oidb0xf57Filter
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57Req import protobuf.oidb.cmx0xf57.Oidb0xf57GuildInfo
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57Rsp import protobuf.oidb.cmx0xf57.Oidb0xf57MetaInfo
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57U1 import protobuf.oidb.cmx0xf57.Oidb0xf57Req
import moe.whitechi73.protobuf.oidb.cmx0xf57.Oidb0xf57U2 import protobuf.oidb.cmx0xf57.Oidb0xf57Rsp
import protobuf.oidb.cmx0xf57.Oidb0xf57U1
import protobuf.oidb.cmx0xf57.Oidb0xf57U2
import protobuf.qweb.QWebExtInfo
import protobuf.qweb.QWebReq
import protobuf.qweb.QWebRsp
import tencent.im.oidb.oidb_sso import tencent.im.oidb.oidb_sso
import kotlin.coroutines.resume import kotlin.coroutines.resume
@ -43,13 +52,15 @@ internal object GProSvc: BaseSvc() {
} }
suspend fun getGuildInfo(guildId: ULong): Result<Oidb0xf57MetaInfo> { suspend fun getGuildInfo(guildId: ULong): Result<Oidb0xf57MetaInfo> {
val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf57_9", 0xf57, 9, ProtoBuf.encodeToByteArray(Oidb0xf57Req( val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf57_9", 0xf57, 9, ProtoBuf.encodeToByteArray(
Oidb0xf57Req(
filter = Oidb0xf57Filter( filter = Oidb0xf57Filter(
u1 = Oidb0xf57U1(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u), u1 = Oidb0xf57U1(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u),
u2 = Oidb0xf57U2(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u) u2 = Oidb0xf57U2(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u)
), ),
guildInfo = Oidb0xf57GuildInfo(guildId = guildId) guildInfo = Oidb0xf57GuildInfo(guildId = guildId)
))) )
))
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
if (respBuffer == null) { if (respBuffer == null) {
return Result.failure(Exception("unable to send packet")) return Result.failure(Exception("unable to send packet"))
@ -62,6 +73,35 @@ internal object GProSvc: BaseSvc() {
} }
} }
suspend fun getGuildFeeds(guildId: ULong, channelId: ULong, startIndex: Int): Result<GetGuildFeedsRsp> {
val buffer = sendBufferAW("QChannelSvr.trpc.qchannel.commreader.ComReader.GetGuildFeeds", true, ProtoBuf.encodeToByteArray(QWebReq(
seq = 10,
qua = PlatformUtils.getQUA(),
deviceInfo = "i=&imsi=&mac=02:00:00:00:00:00&m=Shamrock&o=114514&a=1919810&sd=0&c64=1&sc=1&p=8000*8000&aid=123456789012345678901234567890abcdef&f=Tencent&mm=5610&cf=1726&cc=8&qimei=&qimei36=&sharpP=1&n=nether_world&support_xsj_live=false&client_mod=concise&timezone=America/La_Paz&material_sdk_version=&vh265=&refreshrate=10086&hwlevel=9&suphdr=1&is_teenager_mod=8&liveH265=&bmst=5&AV1=0",
buffer = ProtoBuf.encodeToByteArray(GetGuildFeedsReq(
count = 12,
from = startIndex,
feedAttchInfo = EMPTY_BYTE_ARRAY,
guildId = guildId,
getType = 1,
u7 = 0,
u8 = 1,
u9 = EMPTY_BYTE_ARRAY
)),
traceId = app.account + "_0_0",
extinfo = listOf(
QWebExtInfo("fc-appid", "96"),
QWebExtInfo("environment_id", "shamrock"),
QWebExtInfo("tiny_id", getSelfTinyId().toString()),
)
))) ?: return Result.failure(Exception("unable to send packet"))
val webRsp = ProtoBuf.decodeFromByteArray<QWebRsp>(buffer.slice(4))
if(webRsp.buffer == null) return Result.failure(Exception("server error"))
val wupBuffer = webRsp.buffer!!
val feeds = ProtoBuf.decodeFromByteArray<GetGuildFeedsRsp>(wupBuffer)
return Result.success(feeds)
}
fun getChannelList(guildId: ULong, refresh: Boolean = false): Result<ArrayList<GProChannelInfo>> { fun getChannelList(guildId: ULong, refresh: Boolean = false): Result<ArrayList<GProChannelInfo>> {
if (refresh) { if (refresh) {
refreshGuildInfo(guildId) refreshGuildInfo(guildId)
@ -146,12 +186,14 @@ internal object GProSvc: BaseSvc() {
guildId: ULong, guildId: ULong,
memberTinyId: ULong memberTinyId: ULong
): Result<GProUserInfo> { ): Result<GProUserInfo> {
val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf88_1", 0xf88, 1, ProtoBuf.encodeToByteArray(Oidb0xf88Req( val respBuffer = sendOidbAW("OidbSvcTrpcTcp.0xf88_1", 0xf88, 1, ProtoBuf.encodeToByteArray(
Oidb0xf88Req(
filter = GProFilter(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u), filter = GProFilter(1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u, 1u),
memberId = 0uL, memberId = 0uL,
tinyId = memberTinyId, tinyId = memberTinyId,
guildId = guildId guildId = guildId
))) )
))
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
if (respBuffer == null) { if (respBuffer == null) {
return Result.failure(Exception("unable to send packet")) return Result.failure(Exception("unable to send packet"))
@ -242,4 +284,37 @@ internal object GProSvc: BaseSvc() {
return result return result
} }
suspend fun getGuildRoles(guildId: ULong): Result<List<GProGuildRole>> {
val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService
val roles: List<GProGuildRole> = withTimeoutOrNull(5000) {
suspendCancellableCoroutine {
kernelGProService.fetchRoleListWithPermission(guildId.toLong(), 1) { code, _, roles, _, _, _ ->
if (code != 0) it.resume(null) else it.resume(roles)
}
}
} ?: return Result.failure(Exception("unable to fetch guild roles"))
return Result.success(roles)
}
fun deleteGuildRole(guildId: ULong, roleId: ULong) {
val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService
kernelGProService.deleteRole(guildId.toLong(), roleId.toLong()) { code, msg, result ->
if (code != 0) {
LogCenter.log("deleteGuildRole failed: $code($msg) => $result", Level.WARN)
}
}
}
fun setMemberRole(guildId: ULong, tinyId: ULong, roleId: ULong, isSet: Boolean) {
val kernelGProService = NTServiceFetcher.kernelService.wrapperSession.guildService
val addList = arrayListOf<Long>()
val rmList = arrayListOf<Long>()
(if (isSet) addList else rmList).add(roleId.toLong())
kernelGProService.setMemberRoles(guildId.toLong(), 0, 0, tinyId.toLong(), addList, rmList) { code, msg, result ->
if (code != 0) {
LogCenter.log("setMemberRole failed: $code($msg) => $result", Level.WARN)
}
}
}
} }

View File

@ -14,7 +14,6 @@ import com.tencent.mobileqq.pb.ByteStringMicro
import com.tencent.mobileqq.troop.api.ITroopInfoService import com.tencent.mobileqq.troop.api.ITroopInfoService
import com.tencent.mobileqq.troop.api.ITroopMemberInfoService import com.tencent.mobileqq.troop.api.ITroopMemberInfoService
import com.tencent.protofile.join_group_link.join_group_link import com.tencent.protofile.join_group_link.join_group_link
import com.tencent.qphone.base.remote.FromServiceMsg
import com.tencent.qphone.base.remote.ToServiceMsg import com.tencent.qphone.base.remote.ToServiceMsg
import com.tencent.qqnt.kernel.nativeinterface.MemberInfo import com.tencent.qqnt.kernel.nativeinterface.MemberInfo
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
@ -75,8 +74,8 @@ import moe.fuqiuluo.shamrock.utils.FileUtils
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher import moe.fuqiuluo.shamrock.xposed.helper.NTServiceFetcher
import moe.whitechi73.protobuf.oidb.cmd0xf16.Oidb0xf16 import protobuf.oidb.cmd0xf16.Oidb0xf16
import moe.whitechi73.protobuf.oidb.cmd0xf16.SetGroupRemarkReq import protobuf.oidb.cmd0xf16.SetGroupRemarkReq
import mqq.app.MobileQQ import mqq.app.MobileQQ
import tencent.im.group.group_member_info import tencent.im.group.group_member_info
import tencent.im.oidb.cmd0x88d.oidb_0x88d import tencent.im.oidb.cmd0x88d.oidb_0x88d
@ -272,13 +271,15 @@ internal object GroupSvc: BaseSvc() {
} }
fun modifyGroupRemark(groupId: Long, remark: String): Boolean { fun modifyGroupRemark(groupId: Long, remark: String): Boolean {
sendOidb("OidbSvc.0xf16_1", 3862, 1, ProtoBuf.encodeToByteArray(Oidb0xf16( sendOidb("OidbSvc.0xf16_1", 3862, 1, ProtoBuf.encodeToByteArray(
Oidb0xf16(
setGroupRemarkReq = SetGroupRemarkReq( setGroupRemarkReq = SetGroupRemarkReq(
groupCode = groupId.toULong(), groupCode = groupId.toULong(),
groupUin = groupCode2GroupUin(groupId).toULong(), groupUin = groupCode2GroupUin(groupId).toULong(),
groupRemark = remark groupRemark = remark
) )
))) )
))
return true return true
} }

View File

@ -1,6 +1,5 @@
package moe.fuqiuluo.qqinterface.servlet package moe.fuqiuluo.qqinterface.servlet
import com.tencent.mobileqq.msf.core.MsfCore
import com.tencent.qqnt.kernel.nativeinterface.Contact import com.tencent.qqnt.kernel.nativeinterface.Contact
import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgService import com.tencent.qqnt.kernel.nativeinterface.IKernelMsgService
import com.tencent.qqnt.kernel.nativeinterface.MsgConstant import com.tencent.qqnt.kernel.nativeinterface.MsgConstant
@ -16,14 +15,14 @@ import moe.fuqiuluo.shamrock.remote.action.handlers.GetHistoryMsg
import moe.fuqiuluo.shamrock.remote.service.listener.AioListener import moe.fuqiuluo.shamrock.remote.service.listener.AioListener
import moe.fuqiuluo.shamrock.tools.broadcast import moe.fuqiuluo.shamrock.tools.broadcast
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.whitechi73.protobuf.message.JsonElement import protobuf.message.JsonElement
import moe.whitechi73.protobuf.message.MessageBody import protobuf.message.MessageBody
import moe.whitechi73.protobuf.message.MessageContentHead import protobuf.message.MessageContentHead
import moe.whitechi73.protobuf.message.MessageElement import protobuf.message.MessageElement
import moe.whitechi73.protobuf.message.MessageElementList import protobuf.message.MessageElementList
import moe.whitechi73.protobuf.message.MessageHead import protobuf.message.MessageHead
import moe.whitechi73.protobuf.message.RichMessage import protobuf.message.RichMessage
import moe.whitechi73.protobuf.push.MessagePush import protobuf.push.MessagePush
import mqq.app.MobileQQ import mqq.app.MobileQQ
import kotlin.coroutines.resume import kotlin.coroutines.resume
@ -33,9 +32,11 @@ internal object PacketSvc: BaseSvc() {
*/ */
suspend fun fakeSelfRecvJsonMsg(msgService: IKernelMsgService, content: String): Long { suspend fun fakeSelfRecvJsonMsg(msgService: IKernelMsgService, content: String): Long {
return fakeReceiveSelfMsg(msgService) { return fakeReceiveSelfMsg(msgService) {
listOf(MessageElement( listOf(
MessageElement(
json = JsonElement((byteArrayOf(1) + DeflateTools.compress(content.toByteArray()))) json = JsonElement((byteArrayOf(1) + DeflateTools.compress(content.toByteArray())))
)) )
)
} }
} }

View File

@ -2,7 +2,6 @@
package moe.fuqiuluo.qqinterface.servlet package moe.fuqiuluo.qqinterface.servlet
import android.graphics.BitmapFactory
import com.tencent.mobileqq.app.QQAppInterface import com.tencent.mobileqq.app.QQAppInterface
import com.tencent.mobileqq.transfile.HttpNetReq import com.tencent.mobileqq.transfile.HttpNetReq
import com.tencent.mobileqq.transfile.INetEngineListener import com.tencent.mobileqq.transfile.INetEngineListener
@ -24,18 +23,18 @@ import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.MD5 import moe.fuqiuluo.shamrock.utils.MD5
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
import moe.whitechi73.protobuf.fav.WeiyunAddRichMediaReq import protobuf.fav.WeiyunAddRichMediaReq
import moe.whitechi73.protobuf.fav.WeiyunAuthor import protobuf.fav.WeiyunAuthor
import moe.whitechi73.protobuf.fav.WeiyunCollectCommInfo import protobuf.fav.WeiyunCollectCommInfo
import moe.whitechi73.protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
import moe.whitechi73.protobuf.fav.WeiyunCommonReq import protobuf.fav.WeiyunCommonReq
import moe.whitechi73.protobuf.fav.WeiyunFastUploadResourceReq import protobuf.fav.WeiyunFastUploadResourceReq
import moe.whitechi73.protobuf.fav.WeiyunGetFavContentReq import protobuf.fav.WeiyunGetFavContentReq
import moe.whitechi73.protobuf.fav.WeiyunGetFavListReq import protobuf.fav.WeiyunGetFavListReq
import moe.whitechi73.protobuf.fav.WeiyunMsgHead import protobuf.fav.WeiyunMsgHead
import moe.whitechi73.protobuf.fav.WeiyunPicInfo import protobuf.fav.WeiyunPicInfo
import moe.whitechi73.protobuf.fav.WeiyunRichMediaContent import protobuf.fav.WeiyunRichMediaContent
import moe.whitechi73.protobuf.fav.WeiyunRichMediaSummary import protobuf.fav.WeiyunRichMediaSummary
import mqq.manager.TicketManager import mqq.manager.TicketManager
import oicq.wlogin_sdk.request.Ticket import oicq.wlogin_sdk.request.Ticket
import oicq.wlogin_sdk.request.WtTicketPromise import oicq.wlogin_sdk.request.WtTicketPromise
@ -95,7 +94,8 @@ internal object QFavSvc: BaseSvc() {
getFavContentReq = WeiyunGetFavContentReq( getFavContentReq = WeiyunGetFavContentReq(
cidList = arrayListOf(id) cidList = arrayListOf(id)
) )
)) )
)
} }
suspend fun addImageMsg( suspend fun addImageMsg(
@ -147,9 +147,11 @@ internal object QFavSvc: BaseSvc() {
), ),
contentType = 1u contentType = 1u
), ),
richMediaContent = listOf(WeiyunRichMediaContent( richMediaContent = listOf(
WeiyunRichMediaContent(
rawData = """<img src="$picUrl" />""".toByteArray(), rawData = """<img src="$picUrl" />""".toByteArray(),
picList = listOf(WeiyunPicInfo( picList = listOf(
WeiyunPicInfo(
uri = picUrl, uri = picUrl,
md5 = md5Bytes, md5 = md5Bytes,
sha1 = md5.toByteArray(), sha1 = md5.toByteArray(),
@ -160,10 +162,13 @@ internal object QFavSvc: BaseSvc() {
size = size.toULong(), size = size.toULong(),
type = 0u, type = 0u,
picId = pid picId = pid
)) )
)) )
)
)
) )
)) )
)
} }
suspend fun applyUpImageMsg( suspend fun applyUpImageMsg(
@ -180,7 +185,8 @@ internal object QFavSvc: BaseSvc() {
val md5 = MD5.genFileMd5(image.absolutePath) val md5 = MD5.genFileMd5(image.absolutePath)
return sendWeiyunReq(20010, WeiyunCommonReq( return sendWeiyunReq(20010, WeiyunCommonReq(
fastUploadResourceReq = WeiyunFastUploadResourceReq( fastUploadResourceReq = WeiyunFastUploadResourceReq(
picInfoList = listOf(WeiyunPicInfo( picInfoList = listOf(
WeiyunPicInfo(
md5 = md5, md5 = md5,
name = md5.toHexString(), name = md5.toHexString(),
width = width.toUInt(), width = width.toUInt(),
@ -195,9 +201,11 @@ internal object QFavSvc: BaseSvc() {
groupId = groupId.toULong(), groupId = groupId.toULong(),
groupName = groupName groupName = groupName
) )
)), )
),
) )
)) )
)
} }
suspend fun addRichMediaMsg( suspend fun addRichMediaMsg(
@ -229,11 +237,14 @@ internal object QFavSvc: BaseSvc() {
brief = content, brief = content,
contentType = 1u contentType = 1u
), ),
richMediaContent = listOf(WeiyunRichMediaContent( richMediaContent = listOf(
WeiyunRichMediaContent(
rawData = content.textToHtml().toByteArray(), rawData = content.textToHtml().toByteArray(),
)) )
)
) )
)) )
)
} }
private fun String.textToHtml(): String { private fun String.textToHtml(): String {
@ -318,7 +329,9 @@ internal object QFavSvc: BaseSvc() {
} }
val pSKey = getWeiYunPSKey() val pSKey = getWeiYunPSKey()
httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST httpNetReq.mHttpMethod = HttpNetReq.HTTP_POST
httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), ProtoBuf.encodeToByteArray(WeiyunComm(req = req)))) httpNetReq.mSendData = DeflateTools.gzip(packData(packHead(cmd, pSKey), ProtoBuf.encodeToByteArray(
WeiyunComm(req = req)
)))
httpNetReq.mOutStream = outputStream httpNetReq.mOutStream = outputStream
httpNetReq.mStartDownOffset = 0L httpNetReq.mStartDownOffset = 0L
httpNetReq.mReqProperties["Shamrock"] = "true" httpNetReq.mReqProperties["Shamrock"] = "true"
@ -338,7 +351,8 @@ internal object QFavSvc: BaseSvc() {
} }
private fun packHead(cmd: Int, pskey: String): ByteArray { private fun packHead(cmd: Int, pskey: String): ByteArray {
return ProtoBuf.encodeToByteArray(WeiyunMsgHead( return ProtoBuf.encodeToByteArray(
WeiyunMsgHead(
uin = app.longAccountUin.toULong(), uin = app.longAccountUin.toULong(),
seq = seq++.toUInt(), seq = seq++.toUInt(),
type = 1u, type = 1u,
@ -350,7 +364,8 @@ internal object QFavSvc: BaseSvc() {
key = pskey.toByteArray(), key = pskey.toByteArray(),
majorVersion = MAJOR_VERSION.toUInt(), majorVersion = MAJOR_VERSION.toUInt(),
minorVersion = MINOR_VERSION.toUInt(), minorVersion = MINOR_VERSION.toUInt(),
)) )
)
} }
private fun packData(head: ByteArray, body: ByteArray): ByteArray { private fun packData(head: ByteArray, body: ByteArray): ByteArray {

View File

@ -19,10 +19,10 @@ import moe.fuqiuluo.shamrock.tools.slice
import moe.fuqiuluo.shamrock.tools.toHexString import moe.fuqiuluo.shamrock.tools.toHexString
import moe.fuqiuluo.shamrock.utils.PlatformUtils import moe.fuqiuluo.shamrock.utils.PlatformUtils
import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher import moe.fuqiuluo.shamrock.xposed.helper.AppRuntimeFetcher
import moe.whitechi73.protobuf.oidb.cmd0xfc2.Oidb0xfc2ChannelInfo import protobuf.oidb.cmd0xfc2.Oidb0xfc2ChannelInfo
import moe.whitechi73.protobuf.oidb.cmd0xfc2.Oidb0xfc2MsgApplyDownloadReq import protobuf.oidb.cmd0xfc2.Oidb0xfc2MsgApplyDownloadReq
import moe.whitechi73.protobuf.oidb.cmd0xfc2.Oidb0xfc2ReqBody import protobuf.oidb.cmd0xfc2.Oidb0xfc2ReqBody
import moe.whitechi73.protobuf.oidb.cmd0xfc2.Oidb0xfc2RspBody import protobuf.oidb.cmd0xfc2.Oidb0xfc2RspBody
import mqq.app.MobileQQ import mqq.app.MobileQQ
import tencent.im.cs.cmd0x346.cmd0x346 import tencent.im.cs.cmd0x346.cmd0x346
import tencent.im.oidb.cmd0x6d6.oidb_0x6d6 import tencent.im.oidb.cmd0x6d6.oidb_0x6d6
@ -32,7 +32,8 @@ import kotlin.coroutines.resume
internal object RichProtoSvc: BaseSvc() { internal object RichProtoSvc: BaseSvc() {
suspend fun getGuildFileDownUrl(peerId: String, channelId: String, fileId: String, bizId: Int): String { suspend fun getGuildFileDownUrl(peerId: String, channelId: String, fileId: String, bizId: Int): String {
val buffer = sendOidbAW("OidbSvcTrpcTcp.0xfc2_0", 4034, 0, ProtoBuf.encodeToByteArray(Oidb0xfc2ReqBody( val buffer = sendOidbAW("OidbSvcTrpcTcp.0xfc2_0", 4034, 0, ProtoBuf.encodeToByteArray(
Oidb0xfc2ReqBody(
msgCmd = 1200, msgCmd = 1200,
msgBusType = 4202, msgBusType = 4202,
msgChannelInfo = Oidb0xfc2ChannelInfo( msgChannelInfo = Oidb0xfc2ChannelInfo(
@ -44,7 +45,8 @@ internal object RichProtoSvc: BaseSvc() {
fieldId = fileId, fieldId = fileId,
supportEncrypt = 0 supportEncrypt = 0
) )
))) ?: return "" )
)) ?: return ""
val body = oidb_sso.OIDBSSOPkg() val body = oidb_sso.OIDBSSOPkg()
body.mergeFrom(buffer.slice(4)) body.mergeFrom(buffer.slice(4))
ProtoBuf.decodeFromByteArray<Oidb0xfc2RspBody>(body.bytes_bodybuffer.get().toByteArray()).msgApplyDownloadRsp?.let { ProtoBuf.decodeFromByteArray<Oidb0xfc2RspBody>(body.bytes_bodybuffer.get().toByteArray()).msgApplyDownloadRsp?.let {

View File

@ -0,0 +1,24 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("delete_guild_role")
internal object DeleteGuildRole: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong()
val roleId = session.getString("role_id").toULong()
return invoke(guildId, roleId, session.echo)
}
operator fun invoke(guildId: ULong, roleId: ULong, echo: JsonElement = EmptyJsonString): String {
GProSvc.deleteGuildRole(guildId, roleId)
return ok("success", echo = echo)
}
override val requiredParams: Array<String> = arrayOf("guild_id", "role_id")
}

View File

@ -16,7 +16,7 @@ import moe.fuqiuluo.shamrock.utils.CryptTools
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.shamrock.utils.FileUtils import moe.fuqiuluo.shamrock.utils.FileUtils
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.whitechi73.protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.add_image_msg") @OneBotHandler("fav.add_image_msg")
internal object FavAddImageMsg: IActionHandler() { internal object FavAddImageMsg: IActionHandler() {

View File

@ -13,7 +13,7 @@ import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.whitechi73.protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.add_text_msg") @OneBotHandler("fav.add_text_msg")
internal object FavAddTextMsg: IActionHandler() { internal object FavAddTextMsg: IActionHandler() {

View File

@ -16,7 +16,7 @@ import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.whitechi73.protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.get_item_content") @OneBotHandler("fav.get_item_content")
internal object FavGetItemContent: IActionHandler() { internal object FavGetItemContent: IActionHandler() {

View File

@ -13,7 +13,7 @@ import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.utils.DeflateTools import moe.fuqiuluo.shamrock.utils.DeflateTools
import moe.fuqiuluo.symbols.OneBotHandler import moe.fuqiuluo.symbols.OneBotHandler
import moe.whitechi73.protobuf.fav.WeiyunComm import protobuf.fav.WeiyunComm
@OneBotHandler("fav.get_item_list") @OneBotHandler("fav.get_item_list")
internal object FavGetItemList: IActionHandler() { internal object FavGetItemList: IActionHandler() {

View File

@ -0,0 +1,38 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.symbols.OneBotHandler
import protobuf.guild.StFeed
@OneBotHandler("get_guild_feeds")
internal object GetGuildFeeds: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong()
val channelId = session.getStringOrNull("channel_id")?.toULong() ?: 0uL
val from = session.getIntOrNull("from") ?: 0
return invoke(guildId, channelId, from, session.echo)
}
suspend operator fun invoke(guildId: ULong, channelId: ULong, startIndex: Int, echo: JsonElement = EmptyJsonString): String {
val result = GProSvc.getGuildFeeds(guildId, channelId, startIndex).getOrElse {
GProSvc.getGuildFeeds(guildId, 0uL, startIndex).onFailure {
return error(it.message ?: "server error", echo)
}.getOrThrow()
}
if (result.vecFeed == null) {
return error("server error", echo)
}
return ok(GetGuildFeedsResult(result.isFinish == 1, result.vecFeed!!), echo = echo)
}
@Serializable
data class GetGuildFeedsResult(
val isFinish: Boolean,
val feeds: List<StFeed>
)
}

View File

@ -0,0 +1,61 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile.Permission
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("get_guild_roles")
internal object GetGuildRoles: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong()
return invoke(guildId, session.echo)
}
suspend operator fun invoke(guildId: ULong, echo: JsonElement = EmptyJsonString): String {
val result = GProSvc.getGuildRoles(guildId).onFailure {
return error(it.message ?: "unable to fetch guild roles", echo)
}.getOrThrow()
return ok(GetGuildRolesResult(result.map {
GuildRole(
color = it.color,
disabled = it.count <= 0,
independent = it.isChannelRole,
maxCount = it.memberLimit,
memberCount = it.count,
owned = it.bHoist,
roleId = it.roleId,
roleName = it.name,
permission = it.rolePermissions.permissionList.map {
Permission(it.rootId, it.childIds)
},
)
}), echo = echo)
}
override val requiredParams: Array<String> = arrayOf("guild_id")
@Serializable
data class GetGuildRolesResult(
@SerialName("roles") val roles: List<GuildRole>
)
@Serializable
data class GuildRole(
@SerialName("argb_color") val color: Long,
@SerialName("disabled") val disabled: Boolean,
@SerialName("independent") val independent: Boolean,
@SerialName("max_count") val maxCount: Int,
@SerialName("member_count") val memberCount: Int,
@SerialName("owned") val owned: Boolean,
@SerialName("role_id") val roleId: Long,
@SerialName("role_name") val roleName: String,
@SerialName("permission") val permission: List<Permission>,
)
}

View File

@ -0,0 +1,42 @@
package moe.fuqiuluo.shamrock.remote.action.handlers
import kotlinx.serialization.json.JsonElement
import moe.fuqiuluo.qqinterface.servlet.GProSvc
import moe.fuqiuluo.shamrock.remote.action.ActionSession
import moe.fuqiuluo.shamrock.remote.action.IActionHandler
import moe.fuqiuluo.shamrock.tools.EmptyJsonString
import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.symbols.OneBotHandler
@OneBotHandler("set_guild_member_role")
internal object SetGuildMemberRole: IActionHandler() {
override suspend fun internalHandle(session: ActionSession): String {
val guildId = session.getString("guild_id").toULong()
val role = session.getString("role_id").toULong()
val set = session.getBooleanOrDefault("set", false)
return if (session.has("user_id")) {
val userId = session.getString("user_id").toULong()
invoke(guildId, userId, role, set, echo = session.echo)
} else if (session.isArray("users")) {
invoke(guildId, session.getArray("users").map {
it.asString.toULong()
}, role, set, echo = session.echo)
} else {
logic("missing user_id or users", echo = session.echo)
}
}
operator fun invoke(guildId: ULong, users: List<ULong>, roleId: ULong, set: Boolean, echo: JsonElement = EmptyJsonString): String {
users.forEach {
GProSvc.setMemberRole(guildId, it, roleId, set)
}
return ok("success", echo = echo)
}
operator fun invoke(guildId: ULong, user: ULong, roleId: ULong, set: Boolean, echo: JsonElement = EmptyJsonString): String {
GProSvc.setMemberRole(guildId, user, roleId, set)
return ok("success", echo = echo)
}
override val requiredParams: Array<String> = arrayOf("guild_id", "role_id")
}

View File

@ -8,20 +8,25 @@ import io.ktor.server.routing.get
import io.ktor.server.routing.post import io.ktor.server.routing.post
import io.ktor.server.routing.route import io.ktor.server.routing.route
import moe.fuqiuluo.shamrock.helper.MessageHelper import moe.fuqiuluo.shamrock.helper.MessageHelper
import moe.fuqiuluo.shamrock.remote.action.handlers.DeleteGuildRole
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGProChannelList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGProChannelList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildFeeds
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberList import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberList
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMemberProfile
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMetaByGuest import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildMetaByGuest
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildRoles
import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildServiceProfile import moe.fuqiuluo.shamrock.remote.action.handlers.GetGuildServiceProfile
import moe.fuqiuluo.shamrock.remote.action.handlers.SendGuildMessage import moe.fuqiuluo.shamrock.remote.action.handlers.SendGuildMessage
import moe.fuqiuluo.shamrock.remote.action.handlers.SendMessage import moe.fuqiuluo.shamrock.remote.action.handlers.SendMessage
import moe.fuqiuluo.shamrock.remote.action.handlers.SetGuildMemberRole
import moe.fuqiuluo.shamrock.tools.fetchGetOrNull import moe.fuqiuluo.shamrock.tools.fetchGetOrNull
import moe.fuqiuluo.shamrock.tools.fetchGetOrThrow import moe.fuqiuluo.shamrock.tools.fetchGetOrThrow
import moe.fuqiuluo.shamrock.tools.fetchOrNull import moe.fuqiuluo.shamrock.tools.fetchOrNull
import moe.fuqiuluo.shamrock.tools.fetchOrThrow import moe.fuqiuluo.shamrock.tools.fetchOrThrow
import moe.fuqiuluo.shamrock.tools.fetchPostJsonArray import moe.fuqiuluo.shamrock.tools.fetchPostJsonArray
import moe.fuqiuluo.shamrock.tools.fetchPostJsonObject import moe.fuqiuluo.shamrock.tools.fetchPostJsonObject
import moe.fuqiuluo.shamrock.tools.fetchPostJsonString
import moe.fuqiuluo.shamrock.tools.fetchPostOrNull import moe.fuqiuluo.shamrock.tools.fetchPostOrNull
import moe.fuqiuluo.shamrock.tools.fetchPostOrThrow import moe.fuqiuluo.shamrock.tools.fetchPostOrThrow
import moe.fuqiuluo.shamrock.tools.getOrPost import moe.fuqiuluo.shamrock.tools.getOrPost
@ -109,4 +114,40 @@ fun Routing.guildAction() {
}, ContentType.Application.Json) }, ContentType.Application.Json)
} }
} }
getOrPost("/get_guild_feeds") {
val guildId = fetchOrThrow("guild_id").toULong()
val channelId = fetchOrNull("channel_id")?.toULong() ?: 0uL
val from = fetchOrNull("from")?.toInt() ?: 0
call.respondText(GetGuildFeeds(guildId, channelId, from), ContentType.Application.Json)
}
getOrPost("/get_guild_roles") {
val guildId = fetchOrThrow("guild_id").toULong()
call.respondText(GetGuildRoles(guildId), ContentType.Application.Json)
}
getOrPost("/delete_guild_role") {
val guildId = fetchOrThrow("guild_id").toULong()
val roleId = fetchOrThrow("role_id").toULong()
call.respondText(DeleteGuildRole(guildId, roleId), ContentType.Application.Json)
}
getOrPost("/set_guild_member_role") {
val guildId = fetchOrThrow("guild_id").toULong()
val roleId = fetchOrThrow("role_id").toULong()
val set = fetchOrNull("set")?.toBoolean() ?: false
val userId = fetchOrNull("user_id")?.toULong()
val users = fetchOrNull("users")?.split(",")?.map { it.toULong() }
call.respondText(
if (userId != null) {
SetGuildMemberRole(guildId, userId, roleId, set)
} else if (users != null) {
SetGuildMemberRole(guildId, users, roleId, set)
} else {
throw IllegalArgumentException("missing user_id or users")
},
ContentType.Application.Json
)
}
} }

View File

@ -31,8 +31,21 @@ import moe.fuqiuluo.shamrock.tools.asJsonObject
import moe.fuqiuluo.shamrock.tools.asString import moe.fuqiuluo.shamrock.tools.asString
import moe.fuqiuluo.shamrock.tools.readBuf32Long import moe.fuqiuluo.shamrock.tools.readBuf32Long
import moe.fuqiuluo.shamrock.xposed.helper.PacketHandler import moe.fuqiuluo.shamrock.xposed.helper.PacketHandler
import moe.whitechi73.protobuf.message.* import protobuf.message.MessageContentHead
import moe.whitechi73.protobuf.push.* import protobuf.message.MessageHead
import protobuf.message.RichMessage
import protobuf.push.C2CCommonTipsEvent
import protobuf.push.C2CRecallEvent
import protobuf.push.FriendApplyEvent
import protobuf.push.GroupAdminChangeEvent
import protobuf.push.GroupApplyEvent
import protobuf.push.GroupBanEvent
import protobuf.push.GroupCommonTipsEvent
import protobuf.push.GroupInviteEvent
import protobuf.push.GroupInvitedApplyEvent
import protobuf.push.GroupListChangeEvent
import protobuf.push.MessagePush
import protobuf.push.MessagePushClientInfo
internal object PrimitiveListener { internal object PrimitiveListener {
fun registerListener() { fun registerListener() {
@ -579,7 +592,7 @@ internal object PrimitiveListener {
} }
} }
private suspend fun onInviteGroup(time: Long, msgHead: MessageHead,richMsg: RichMessage) { private suspend fun onInviteGroup(time: Long, msgHead: MessageHead, richMsg: RichMessage) {
val event = ProtoBuf.decodeFromByteArray<GroupInviteEvent>(richMsg.rawBuffer!!) val event = ProtoBuf.decodeFromByteArray<GroupInviteEvent>(richMsg.rawBuffer!!)
val groupCode = event.groupCode val groupCode = event.groupCode
val invitorUid = event.inviterUid val invitorUid = event.inviterUid

View File

@ -18,6 +18,10 @@ import kotlin.random.Random
internal object PlatformUtils { internal object PlatformUtils {
const val QQ_9_0_8_VER = 5540 const val QQ_9_0_8_VER = 5540
fun getQUA(): String {
return "V1_AND_SQ_${getQQVersion(MobileQQ.getContext())}_${getQQVersionCode()}_YYB_D"
}
fun getQQVersion(context: Context): String { fun getQQVersion(context: Context): String {
val packageInfo: PackageInfo = context.packageManager.getPackageInfo(context.packageName, 0) val packageInfo: PackageInfo = context.packageManager.getPackageInfo(context.packageName, 0)
return packageInfo.versionName return packageInfo.versionName