1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00
MiraiGo/topic/feed.go
2023-08-03 23:23:00 +08:00

193 lines
5.0 KiB
Go

package topic
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"sync/atomic"
"time"
"github.com/Mrs4s/MiraiGo/client/pb/channel"
"github.com/Mrs4s/MiraiGo/message"
"github.com/Mrs4s/MiraiGo/utils"
)
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]any
)
var globalBlockId int64
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.Id.Unwrap(),
Title: p.Title.Contents[0].TextContent.Text.Unwrap(),
SubTitle: "",
CreateTime: int64(p.CreateTime.Unwrap()),
GuildId: p.ChannelInfo.Sign.GuildId.Unwrap(),
ChannelId: p.ChannelInfo.Sign.ChannelId.Unwrap(),
}
if p.Subtitle != nil && len(p.Subtitle.Contents) > 0 {
f.SubTitle = p.Subtitle.Contents[0].TextContent.Text.Unwrap()
}
if p.Poster != nil {
tinyId, _ := strconv.ParseUint(p.Poster.Id.Unwrap(), 10, 64)
f.Poster = &FeedPoster{
TinyId: tinyId,
TinyIdStr: p.Poster.Id.Unwrap(),
Nickname: p.Poster.Nick.Unwrap(),
}
if p.Poster.Icon != nil {
f.Poster.IconUrl = p.Poster.Icon.IconUrl.Unwrap()
}
}
for _, video := range p.Videos {
f.Videos = append(f.Videos, &FeedVideoInfo{
FileId: video.FileId.Unwrap(),
PatternId: video.PatternId.Unwrap(),
Url: video.PlayUrl.Unwrap(),
Width: video.Width.Unwrap(),
Height: video.Height.Unwrap(),
})
}
for _, image := range p.Images {
f.Images = append(f.Images, &FeedImageInfo{
FileId: image.PicId.Unwrap(),
PatternId: image.PatternId.Unwrap(),
Url: image.PicUrl.Unwrap(),
Width: image.Width.Unwrap(),
Height: image.Height.Unwrap(),
})
}
for _, c := range p.Contents.Contents {
if c.TextContent != nil {
f.Contents = append(f.Contents, &TextElement{Content: c.TextContent.Text.Unwrap()})
}
if c.EmojiContent != nil {
id, _ := strconv.ParseInt(c.EmojiContent.Id.Unwrap(), 10, 32)
f.Contents = append(f.Contents, &EmojiElement{
Index: int32(id),
Id: c.EmojiContent.Id.Unwrap(),
Name: message.FaceNameById(int(id)),
})
}
if c.ChannelContent != nil && c.ChannelContent.ChannelInfo != nil {
f.Contents = append(f.Contents, &ChannelQuoteElement{
GuildId: c.ChannelContent.ChannelInfo.Sign.GuildId.Unwrap(),
ChannelId: c.ChannelContent.ChannelInfo.Sign.ChannelId.Unwrap(),
DisplayText: c.ChannelContent.ChannelInfo.Name.Unwrap(),
})
}
if c.AtContent != nil && c.AtContent.User != nil {
tinyId, _ := strconv.ParseUint(c.AtContent.User.Id.Unwrap(), 10, 64)
f.Contents = append(f.Contents, &AtElement{
Id: c.AtContent.User.Id.Unwrap(),
TinyId: tinyId,
Nickname: c.AtContent.User.Nick.Unwrap(),
})
}
if c.UrlContent != nil {
f.Contents = append(f.Contents, &UrlQuoteElement{
Url: c.UrlContent.Url.Unwrap(),
DisplayText: c.UrlContent.DisplayText.Unwrap(),
})
}
}
return f
}