mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
feat: GetTopicChannelFeeds
This commit is contained in:
parent
e8e50b5062
commit
8b4b8269f3
@ -2,6 +2,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/topic"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
@ -525,17 +526,17 @@ func (s *GuildService) FetchChannelInfo(guildId, channelId uint64) (*ChannelInfo
|
|||||||
return convertChannelInfo(body.Info), nil
|
return convertChannelInfo(body.Info), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *GuildService) GetChannelTopics(guildId, channelId uint64) error {
|
func (s *GuildService) GetTopicChannelFeeds(guildId, channelId uint64) ([]*topic.Feed, error) {
|
||||||
guild := s.FindGuild(guildId)
|
guild := s.FindGuild(guildId)
|
||||||
if guild == nil {
|
if guild == nil {
|
||||||
return errors.New("guild not found")
|
return nil, errors.New("guild not found")
|
||||||
}
|
}
|
||||||
channelInfo := guild.FindChannel(channelId)
|
channelInfo := guild.FindChannel(channelId)
|
||||||
if channelInfo == nil {
|
if channelInfo == nil {
|
||||||
return errors.New("channel not found")
|
return nil, errors.New("channel not found")
|
||||||
}
|
}
|
||||||
if channelInfo.ChannelType != ChannelTypeTopic {
|
if channelInfo.ChannelType != ChannelTypeTopic {
|
||||||
return errors.New("channel type error")
|
return nil, errors.New("channel type error")
|
||||||
}
|
}
|
||||||
req, _ := proto.Marshal(&channel.StGetChannelFeedsReq{
|
req, _ := proto.Marshal(&channel.StGetChannelFeedsReq{
|
||||||
Count: proto.Uint32(12),
|
Count: proto.Uint32(12),
|
||||||
@ -571,17 +572,21 @@ func (s *GuildService) GetChannelTopics(guildId, channelId uint64) error {
|
|||||||
packet := packets.BuildUniPacket(s.c.Uin, seq, "QChannelSvr.trpc.qchannel.commreader.ComReader.GetChannelTimelineFeeds", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload)
|
packet := packets.BuildUniPacket(s.c.Uin, seq, "QChannelSvr.trpc.qchannel.commreader.ComReader.GetChannelTimelineFeeds", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload)
|
||||||
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
|
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("send packet error")
|
return nil, errors.New("send packet error")
|
||||||
}
|
}
|
||||||
pkg := new(qweb.QWebRsp)
|
pkg := new(qweb.QWebRsp)
|
||||||
body := new(channel.StGetChannelFeedsRsp)
|
body := new(channel.StGetChannelFeedsRsp)
|
||||||
if err = proto.Unmarshal(rsp, pkg); err != nil {
|
if err = proto.Unmarshal(rsp, pkg); err != nil {
|
||||||
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err = proto.Unmarshal(pkg.BusiBuff, body); err != nil {
|
if err = proto.Unmarshal(pkg.BusiBuff, body); err != nil {
|
||||||
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
return nil
|
feeds := make([]*topic.Feed, 0, len(body.VecFeed))
|
||||||
|
for _, f := range body.VecFeed {
|
||||||
|
feeds = append(feeds, topic.DecodeFeed(f))
|
||||||
|
}
|
||||||
|
return feeds, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need analysis
|
/* need analysis
|
||||||
|
@ -176,6 +176,25 @@ func (x *StChannelSign) GetChannelId() uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StEmotionReactionInfo struct {
|
||||||
|
Id *string `protobuf:"bytes,1,opt"`
|
||||||
|
EmojiReactionList []*EmojiReaction `protobuf:"bytes,2,rep"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *StEmotionReactionInfo) GetId() string {
|
||||||
|
if x != nil && x.Id != nil {
|
||||||
|
return *x.Id
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *StEmotionReactionInfo) GetEmojiReactionList() []*EmojiReaction {
|
||||||
|
if x != nil {
|
||||||
|
return x.EmojiReactionList
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type StCommonExt struct {
|
type StCommonExt struct {
|
||||||
MapInfo []*CommonEntry `protobuf:"bytes,1,rep"`
|
MapInfo []*CommonEntry `protobuf:"bytes,1,rep"`
|
||||||
AttachInfo *string `protobuf:"bytes,2,opt"`
|
AttachInfo *string `protobuf:"bytes,2,opt"`
|
||||||
|
@ -4,6 +4,8 @@ package channel;
|
|||||||
|
|
||||||
option go_package = "pb/channel;channel";
|
option go_package = "pb/channel;channel";
|
||||||
|
|
||||||
|
import "pb/channel/MsgResponsesSvr.proto";
|
||||||
|
|
||||||
message ChannelUserInfo {
|
message ChannelUserInfo {
|
||||||
optional ClientIdentity clientIdentity = 1;
|
optional ClientIdentity clientIdentity = 1;
|
||||||
optional uint32 memberType = 2;
|
optional uint32 memberType = 2;
|
||||||
@ -51,12 +53,13 @@ message StEmojiReaction {
|
|||||||
optional bool isClicked = 4;
|
optional bool isClicked = 4;
|
||||||
optional bool isDefaultEmoji = 10001;
|
optional bool isDefaultEmoji = 10001;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
message StEmotionReactionInfo {
|
message StEmotionReactionInfo {
|
||||||
optional string id = 1;
|
optional string id = 1;
|
||||||
repeated StEmojiReaction emojiReactionList = 2;
|
repeated EmojiReaction emojiReactionList = 2;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
message StCommonExt {
|
message StCommonExt {
|
||||||
repeated CommonEntry mapInfo = 1;
|
repeated CommonEntry mapInfo = 1;
|
||||||
|
@ -580,31 +580,31 @@ func (x *StExternalMedalWallInfo) GetNeedShowEntrance() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StFeed struct {
|
type StFeed struct {
|
||||||
Id *string `protobuf:"bytes,1,opt"`
|
Id *string `protobuf:"bytes,1,opt"`
|
||||||
Title *StRichText `protobuf:"bytes,2,opt"`
|
Title *StRichText `protobuf:"bytes,2,opt"`
|
||||||
Subtitle *StRichText `protobuf:"bytes,3,opt"`
|
Subtitle *StRichText `protobuf:"bytes,3,opt"`
|
||||||
Poster *StUser `protobuf:"bytes,4,opt"`
|
Poster *StUser `protobuf:"bytes,4,opt"`
|
||||||
Videos []*StVideo `protobuf:"bytes,5,rep"`
|
Videos []*StVideo `protobuf:"bytes,5,rep"`
|
||||||
Contents *StRichText `protobuf:"bytes,6,opt"`
|
Contents *StRichText `protobuf:"bytes,6,opt"`
|
||||||
CreateTime *uint64 `protobuf:"varint,7,opt"`
|
CreateTime *uint64 `protobuf:"varint,7,opt"`
|
||||||
EmotionReaction *EmojiReaction `protobuf:"bytes,8,opt"`
|
EmotionReaction *StEmotionReactionInfo `protobuf:"bytes,8,opt"`
|
||||||
CommentCount *uint32 `protobuf:"varint,9,opt"`
|
CommentCount *uint32 `protobuf:"varint,9,opt"`
|
||||||
VecComment []*StComment `protobuf:"bytes,10,rep"`
|
VecComment []*StComment `protobuf:"bytes,10,rep"`
|
||||||
Share *StShare `protobuf:"bytes,11,opt"`
|
Share *StShare `protobuf:"bytes,11,opt"`
|
||||||
VisitorInfo *StVisitor `protobuf:"bytes,12,opt"`
|
VisitorInfo *StVisitor `protobuf:"bytes,12,opt"`
|
||||||
Images []*StImage `protobuf:"bytes,13,rep"`
|
Images []*StImage `protobuf:"bytes,13,rep"`
|
||||||
PoiInfo *StPoiInfoV2 `protobuf:"bytes,14,opt"`
|
PoiInfo *StPoiInfoV2 `protobuf:"bytes,14,opt"`
|
||||||
TagInfos []*StTagInfo `protobuf:"bytes,15,rep"`
|
TagInfos []*StTagInfo `protobuf:"bytes,15,rep"`
|
||||||
BusiReport []byte `protobuf:"bytes,16,opt"`
|
BusiReport []byte `protobuf:"bytes,16,opt"`
|
||||||
OpMask []uint32 `protobuf:"varint,17,rep"`
|
OpMask []uint32 `protobuf:"varint,17,rep"`
|
||||||
Opinfo *StOpinfo `protobuf:"bytes,18,opt"`
|
Opinfo *StOpinfo `protobuf:"bytes,18,opt"`
|
||||||
ExtInfo []*CommonEntry `protobuf:"bytes,19,rep"`
|
ExtInfo []*CommonEntry `protobuf:"bytes,19,rep"`
|
||||||
PatternInfo *string `protobuf:"bytes,20,opt"`
|
PatternInfo *string `protobuf:"bytes,20,opt"`
|
||||||
ChannelInfo *StChannelInfo `protobuf:"bytes,21,opt"`
|
ChannelInfo *StChannelInfo `protobuf:"bytes,21,opt"`
|
||||||
CreateTimeNs *uint64 `protobuf:"varint,22,opt"`
|
CreateTimeNs *uint64 `protobuf:"varint,22,opt"`
|
||||||
Summary *StFeedSummary `protobuf:"bytes,23,opt"`
|
Summary *StFeedSummary `protobuf:"bytes,23,opt"`
|
||||||
RecomInfo *StRecomInfo `protobuf:"bytes,24,opt"`
|
RecomInfo *StRecomInfo `protobuf:"bytes,24,opt"`
|
||||||
Meta *FeedMetaData `protobuf:"bytes,25,opt"`
|
Meta *FeedMetaData `protobuf:"bytes,25,opt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StFeed) GetId() string {
|
func (x *StFeed) GetId() string {
|
||||||
@ -656,7 +656,7 @@ func (x *StFeed) GetCreateTime() uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StFeed) GetEmotionReaction() *EmojiReaction {
|
func (x *StFeed) GetEmotionReaction() *StEmotionReactionInfo {
|
||||||
if x != nil {
|
if x != nil {
|
||||||
return x.EmotionReaction
|
return x.EmotionReaction
|
||||||
}
|
}
|
||||||
@ -1734,9 +1734,10 @@ func (x *StPoiInfoV2) GetDisplayName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type StPrePullCacheFeed struct {
|
type StPrePullCacheFeed struct {
|
||||||
Id *string `protobuf:"bytes,1,opt"`
|
Id *string `protobuf:"bytes,1,opt"`
|
||||||
Poster *StUser `protobuf:"bytes,2,opt"`
|
Poster *StUser `protobuf:"bytes,2,opt"`
|
||||||
CreateTime *uint64 `protobuf:"varint,3,opt"` //repeated GuildCommon.BytesEntry busiTranparent = 4;
|
CreateTime *uint64 `protobuf:"varint,3,opt"`
|
||||||
|
BusiTranparent []*BytesEntry `protobuf:"bytes,4,rep"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *StPrePullCacheFeed) GetId() string {
|
func (x *StPrePullCacheFeed) GetId() string {
|
||||||
@ -1760,6 +1761,13 @@ func (x *StPrePullCacheFeed) GetCreateTime() uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (x *StPrePullCacheFeed) GetBusiTranparent() []*BytesEntry {
|
||||||
|
if x != nil {
|
||||||
|
return x.BusiTranparent
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type StProxyInfo struct {
|
type StProxyInfo struct {
|
||||||
CmdId *int32 `protobuf:"varint,1,opt"`
|
CmdId *int32 `protobuf:"varint,1,opt"`
|
||||||
SubCmdId *int32 `protobuf:"varint,2,opt"`
|
SubCmdId *int32 `protobuf:"varint,2,opt"`
|
||||||
|
@ -4,7 +4,6 @@ package channel;
|
|||||||
|
|
||||||
option go_package = "pb/channel;channel";
|
option go_package = "pb/channel;channel";
|
||||||
|
|
||||||
import "pb/channel/MsgResponsesSvr.proto";
|
|
||||||
import "pb/channel/GuildChannelBase.proto";
|
import "pb/channel/GuildChannelBase.proto";
|
||||||
|
|
||||||
message ContentMetaData {
|
message ContentMetaData {
|
||||||
@ -130,7 +129,7 @@ message StFeed {
|
|||||||
repeated StVideo videos = 5;
|
repeated StVideo videos = 5;
|
||||||
optional StRichText contents = 6;
|
optional StRichText contents = 6;
|
||||||
optional uint64 createTime = 7;
|
optional uint64 createTime = 7;
|
||||||
optional EmojiReaction emotionReaction = 8;
|
optional StEmotionReactionInfo emotionReaction = 8;
|
||||||
optional uint32 commentCount = 9;
|
optional uint32 commentCount = 9;
|
||||||
repeated StComment vecComment = 10;
|
repeated StComment vecComment = 10;
|
||||||
optional StShare share = 11;
|
optional StShare share = 11;
|
||||||
@ -328,7 +327,7 @@ message StPrePullCacheFeed {
|
|||||||
optional string id = 1;
|
optional string id = 1;
|
||||||
optional StUser poster = 2;
|
optional StUser poster = 2;
|
||||||
optional uint64 createTime = 3;
|
optional uint64 createTime = 3;
|
||||||
//repeated GuildCommon.BytesEntry busiTranparent = 4;
|
repeated BytesEntry busiTranparent = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message StProxyInfo {
|
message StProxyInfo {
|
||||||
|
@ -1534,9 +1534,10 @@ func (x *SwitchDetail) GetPlatform() uint32 {
|
|||||||
type SwitchLiveRoom struct {
|
type SwitchLiveRoom struct {
|
||||||
GuildId *uint64 `protobuf:"varint,1,opt"`
|
GuildId *uint64 `protobuf:"varint,1,opt"`
|
||||||
ChannelId *uint64 `protobuf:"varint,2,opt"`
|
ChannelId *uint64 `protobuf:"varint,2,opt"`
|
||||||
RoomId *uint64 `protobuf:"varint,3,opt"`
|
// optional uint64 roomId = 3;
|
||||||
Tinyid *uint64 `protobuf:"varint,4,opt"`
|
// optional uint64 tinyid = 4;
|
||||||
Action *uint32 `protobuf:"varint,5,opt"`
|
UserInfo *SwitchLiveRoomUserInfo `protobuf:"bytes,3,opt"`
|
||||||
|
Action *uint32 `protobuf:"varint,4,opt"` // JOIN = 1 QUIT = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SwitchLiveRoom) GetGuildId() uint64 {
|
func (x *SwitchLiveRoom) GetGuildId() uint64 {
|
||||||
@ -1553,18 +1554,11 @@ func (x *SwitchLiveRoom) GetChannelId() uint64 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SwitchLiveRoom) GetRoomId() uint64 {
|
func (x *SwitchLiveRoom) GetUserInfo() *SwitchLiveRoomUserInfo {
|
||||||
if x != nil && x.RoomId != nil {
|
if x != nil {
|
||||||
return *x.RoomId
|
return x.UserInfo
|
||||||
}
|
}
|
||||||
return 0
|
return nil
|
||||||
}
|
|
||||||
|
|
||||||
func (x *SwitchLiveRoom) GetTinyid() uint64 {
|
|
||||||
if x != nil && x.Tinyid != nil {
|
|
||||||
return *x.Tinyid
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (x *SwitchLiveRoom) GetAction() uint32 {
|
func (x *SwitchLiveRoom) GetAction() uint32 {
|
||||||
@ -1574,6 +1568,25 @@ func (x *SwitchLiveRoom) GetAction() uint32 {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SwitchLiveRoomUserInfo struct {
|
||||||
|
TinyId *uint64 `protobuf:"varint,1,opt"`
|
||||||
|
Nickname *string `protobuf:"bytes,2,opt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SwitchLiveRoomUserInfo) GetTinyId() uint64 {
|
||||||
|
if x != nil && x.TinyId != nil {
|
||||||
|
return *x.TinyId
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *SwitchLiveRoomUserInfo) GetNickname() string {
|
||||||
|
if x != nil && x.Nickname != nil {
|
||||||
|
return *x.Nickname
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type SwitchVoiceChannel struct {
|
type SwitchVoiceChannel struct {
|
||||||
MemberId *uint64 `protobuf:"varint,1,opt"`
|
MemberId *uint64 `protobuf:"varint,1,opt"`
|
||||||
EnterDetail *SwitchDetail `protobuf:"bytes,2,opt"`
|
EnterDetail *SwitchDetail `protobuf:"bytes,2,opt"`
|
||||||
|
@ -286,9 +286,15 @@ message SwitchDetail {
|
|||||||
message SwitchLiveRoom {
|
message SwitchLiveRoom {
|
||||||
optional uint64 guildId = 1;
|
optional uint64 guildId = 1;
|
||||||
optional uint64 channelId = 2;
|
optional uint64 channelId = 2;
|
||||||
optional uint64 roomId = 3;
|
// optional uint64 roomId = 3;
|
||||||
optional uint64 tinyid = 4;
|
// optional uint64 tinyid = 4;
|
||||||
optional uint32 action = 5;
|
optional SwitchLiveRoomUserInfo userInfo = 3;
|
||||||
|
optional uint32 action = 4; // JOIN = 1 QUIT = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
message SwitchLiveRoomUserInfo {
|
||||||
|
optional uint64 tinyId = 1;
|
||||||
|
optional string nickname = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message SwitchVoiceChannel {
|
message SwitchVoiceChannel {
|
||||||
|
@ -607,5 +607,8 @@ func ToReadableString(m []IMessageElement) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func FaceNameById(id int) string {
|
func FaceNameById(id int) string {
|
||||||
return faceMap[id]
|
if name, ok := faceMap[id]; ok {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
return "未知表情"
|
||||||
}
|
}
|
||||||
|
141
topic/elements.go
Normal file
141
topic/elements.go
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
package topic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
TextElement struct {
|
||||||
|
Content string
|
||||||
|
}
|
||||||
|
|
||||||
|
EmojiElement struct {
|
||||||
|
Index int32
|
||||||
|
Id string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
AtElement struct {
|
||||||
|
Id string
|
||||||
|
TinyId uint64
|
||||||
|
Nickname string
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelQuoteElement struct {
|
||||||
|
GuildId uint64
|
||||||
|
ChannelId uint64
|
||||||
|
DisplayText string
|
||||||
|
}
|
||||||
|
|
||||||
|
UrlQuoteElement struct {
|
||||||
|
Url string
|
||||||
|
DisplayText string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func selectContent(b bool, c1, c2 content) content {
|
||||||
|
if b {
|
||||||
|
return c1
|
||||||
|
}
|
||||||
|
return c2
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *TextElement) pack(patternId string, isPatternData bool) content {
|
||||||
|
return selectContent(isPatternData,
|
||||||
|
content{
|
||||||
|
"type": 1,
|
||||||
|
"style": "n",
|
||||||
|
"text": e.Content,
|
||||||
|
"children": make([]int, 0),
|
||||||
|
},
|
||||||
|
content{
|
||||||
|
"type": 1,
|
||||||
|
"text_content": content{
|
||||||
|
"text": e.Content,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *EmojiElement) pack(patternId string, isPatternData bool) content {
|
||||||
|
return selectContent(isPatternData,
|
||||||
|
content{
|
||||||
|
"type": 2,
|
||||||
|
"id": patternId,
|
||||||
|
"emojiType": "1",
|
||||||
|
"emojiId": e.Id,
|
||||||
|
},
|
||||||
|
content{
|
||||||
|
"type": 4,
|
||||||
|
"pattern_id": patternId,
|
||||||
|
"emoji_content": content{
|
||||||
|
"type": "1",
|
||||||
|
"id": e.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *AtElement) pack(patternId string, isPatternData bool) content {
|
||||||
|
return selectContent(isPatternData,
|
||||||
|
content{
|
||||||
|
"type": 3,
|
||||||
|
"id": patternId,
|
||||||
|
"user": content{
|
||||||
|
"id": strconv.FormatUint(e.TinyId, 10),
|
||||||
|
"nick": e.Nickname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
content{
|
||||||
|
"type": 2,
|
||||||
|
"pattern_id": patternId,
|
||||||
|
"at_content": content{
|
||||||
|
"type": 1,
|
||||||
|
"user": content{
|
||||||
|
"id": e.Id,
|
||||||
|
"nick": e.Nickname,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ChannelQuoteElement) pack(patternId string, isPatternData bool) content {
|
||||||
|
return selectContent(isPatternData,
|
||||||
|
content{
|
||||||
|
"type": 4,
|
||||||
|
"id": patternId,
|
||||||
|
"guild_info": content{
|
||||||
|
"channel_id": strconv.FormatUint(e.ChannelId, 10),
|
||||||
|
"name": e.DisplayText,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
content{
|
||||||
|
"type": 5,
|
||||||
|
"pattern_id": patternId,
|
||||||
|
"channel_content": content{
|
||||||
|
"channel_info": content{
|
||||||
|
"name": e.DisplayText,
|
||||||
|
"sign": content{
|
||||||
|
"guild_id": strconv.FormatUint(e.GuildId, 10),
|
||||||
|
"channel_id": strconv.FormatUint(e.ChannelId, 10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *UrlQuoteElement) pack(patternId string, isPatternData bool) content {
|
||||||
|
return selectContent(isPatternData,
|
||||||
|
content{
|
||||||
|
"type": 5,
|
||||||
|
"desc": e.DisplayText,
|
||||||
|
"href": e.Url,
|
||||||
|
"id": patternId,
|
||||||
|
},
|
||||||
|
content{
|
||||||
|
"type": 3,
|
||||||
|
"pattern_id": patternId,
|
||||||
|
"url_content": content{
|
||||||
|
"url": e.Url,
|
||||||
|
"displayText": e.DisplayText,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
193
topic/feed.go
Normal file
193
topic/feed.go
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
package topic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/channel"
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync/atomic"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
Feed struct {
|
||||||
|
Id string
|
||||||
|
Title string
|
||||||
|
SubTitle string
|
||||||
|
CreateTime int64
|
||||||
|
Poster *FeedPoster
|
||||||
|
GuildId uint64
|
||||||
|
ChannelId uint64
|
||||||
|
Images []*FeedImageInfo
|
||||||
|
Videos []*FeedVideoInfo
|
||||||
|
Contents []IFeedRichContentElement
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedPoster struct {
|
||||||
|
TinyId uint64
|
||||||
|
TinyIdStr string
|
||||||
|
Nickname string
|
||||||
|
IconUrl string
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedImageInfo struct {
|
||||||
|
FileId string
|
||||||
|
PatternId string
|
||||||
|
Url string
|
||||||
|
Width uint32
|
||||||
|
Height uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
FeedVideoInfo struct {
|
||||||
|
FileId string
|
||||||
|
PatternId string
|
||||||
|
Url string
|
||||||
|
Width uint32
|
||||||
|
Height uint32
|
||||||
|
// CoverImage FeedImageInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
IFeedRichContentElement interface {
|
||||||
|
pack(patternId string, isPatternData bool) content
|
||||||
|
}
|
||||||
|
|
||||||
|
content map[string]interface{}
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
globalBlockId int64 = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func genBlockId() string {
|
||||||
|
id := atomic.AddInt64(&globalBlockId, 1)
|
||||||
|
return fmt.Sprintf("%v_%v_%v", time.Now().UnixMilli(), utils.RandomStringRange(4, "0123456789"), id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Feed) ToSendingPayload(selfUin int64) string {
|
||||||
|
c := content{ // todo: support media
|
||||||
|
"images": make([]int, 0),
|
||||||
|
"videos": make([]int, 0),
|
||||||
|
"poster": content{
|
||||||
|
"id": f.Poster.TinyIdStr,
|
||||||
|
"nick": f.Poster.Nickname,
|
||||||
|
},
|
||||||
|
"channelInfo": content{
|
||||||
|
"sign": content{
|
||||||
|
"guild_id": strconv.FormatUint(f.GuildId, 10),
|
||||||
|
"channel_id": strconv.FormatUint(f.ChannelId, 10),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"title": content{
|
||||||
|
"contents": []content{
|
||||||
|
(&TextElement{Content: f.Title}).pack("", false),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
patternInfo := []content{
|
||||||
|
{
|
||||||
|
"id": genBlockId(),
|
||||||
|
"type": "blockParagraph",
|
||||||
|
"data": []content{
|
||||||
|
(&TextElement{Content: f.Title}).pack("", true),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
patternData := make([]content, len(f.Contents))
|
||||||
|
contents := make([]content, len(f.Contents))
|
||||||
|
for i, c := range f.Contents {
|
||||||
|
patternId := fmt.Sprintf("o%v_%v_%v", selfUin, time.Now().Format("2006_01_02_15_04_05"), strings.ToLower(utils.RandomStringRange(16, "0123456789abcdef"))) // readCookie("uin")_yyyy_MM_dd_hh_mm_ss_randomHex(16)
|
||||||
|
contents[i] = c.pack(patternId, false)
|
||||||
|
patternData[i] = c.pack(patternId, true)
|
||||||
|
}
|
||||||
|
c["contents"] = content{"contents": contents}
|
||||||
|
patternInfo = append(patternInfo, content{
|
||||||
|
"id": genBlockId(),
|
||||||
|
"type": "blockParagraph",
|
||||||
|
"data": patternData,
|
||||||
|
})
|
||||||
|
packedPattern, _ := json.Marshal(patternInfo)
|
||||||
|
c["patternInfo"] = utils.B2S(packedPattern)
|
||||||
|
packedContent, _ := json.Marshal(c)
|
||||||
|
return utils.B2S(packedContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func DecodeFeed(p *channel.StFeed) *Feed {
|
||||||
|
f := &Feed{
|
||||||
|
Id: p.GetId(),
|
||||||
|
Title: p.Title.Contents[0].TextContent.GetText(),
|
||||||
|
SubTitle: "",
|
||||||
|
CreateTime: int64(p.GetCreateTime()),
|
||||||
|
GuildId: p.ChannelInfo.Sign.GetGuildId(),
|
||||||
|
ChannelId: p.ChannelInfo.Sign.GetChannelId(),
|
||||||
|
}
|
||||||
|
if p.Subtitle != nil && len(p.Subtitle.Contents) > 0 {
|
||||||
|
f.SubTitle = p.Subtitle.Contents[0].TextContent.GetText()
|
||||||
|
}
|
||||||
|
if p.Poster != nil {
|
||||||
|
tinyId, _ := strconv.ParseUint(p.Poster.GetId(), 10, 64)
|
||||||
|
f.Poster = &FeedPoster{
|
||||||
|
TinyId: tinyId,
|
||||||
|
TinyIdStr: p.Poster.GetId(),
|
||||||
|
Nickname: p.Poster.GetNick(),
|
||||||
|
}
|
||||||
|
if p.Poster.Icon != nil {
|
||||||
|
f.Poster.IconUrl = p.Poster.Icon.GetIconUrl()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, video := range p.Videos {
|
||||||
|
f.Videos = append(f.Videos, &FeedVideoInfo{
|
||||||
|
FileId: video.GetFileId(),
|
||||||
|
PatternId: video.GetPatternId(),
|
||||||
|
Url: video.GetPlayUrl(),
|
||||||
|
Width: video.GetWidth(),
|
||||||
|
Height: video.GetHeight(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, image := range p.Images {
|
||||||
|
f.Images = append(f.Images, &FeedImageInfo{
|
||||||
|
FileId: image.GetPicId(),
|
||||||
|
PatternId: image.GetPatternId(),
|
||||||
|
Url: image.GetPicUrl(),
|
||||||
|
Width: image.GetWidth(),
|
||||||
|
Height: image.GetHeight(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, c := range p.Contents.Contents {
|
||||||
|
if c.TextContent != nil {
|
||||||
|
f.Contents = append(f.Contents, &TextElement{Content: c.TextContent.GetText()})
|
||||||
|
}
|
||||||
|
if c.EmojiContent != nil {
|
||||||
|
id, _ := strconv.ParseInt(c.EmojiContent.GetId(), 10, 64)
|
||||||
|
f.Contents = append(f.Contents, &EmojiElement{
|
||||||
|
Index: int32(id),
|
||||||
|
Id: c.EmojiContent.GetId(),
|
||||||
|
Name: message.FaceNameById(int(id)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if c.ChannelContent != nil && c.ChannelContent.ChannelInfo != nil {
|
||||||
|
f.Contents = append(f.Contents, &ChannelQuoteElement{
|
||||||
|
GuildId: c.ChannelContent.ChannelInfo.Sign.GetGuildId(),
|
||||||
|
ChannelId: c.ChannelContent.ChannelInfo.Sign.GetChannelId(),
|
||||||
|
DisplayText: c.ChannelContent.ChannelInfo.GetName(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if c.AtContent != nil && c.AtContent.User != nil {
|
||||||
|
tinyId, _ := strconv.ParseUint(c.AtContent.User.GetId(), 10, 64)
|
||||||
|
f.Contents = append(f.Contents, &AtElement{
|
||||||
|
Id: c.AtContent.User.GetId(),
|
||||||
|
TinyId: tinyId,
|
||||||
|
Nickname: c.AtContent.User.GetNick(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if c.UrlContent != nil {
|
||||||
|
f.Contents = append(f.Contents, &UrlQuoteElement{
|
||||||
|
Url: c.UrlContent.GetUrl(),
|
||||||
|
DisplayText: c.UrlContent.GetDisplayText(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return f
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user