mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
🎨 修改bilibili,bilibiliparse插件结构,添加bilibili动态直播专栏解析 (#319)
* 🎨 修改bilibili,bilibiliparse插件结构,添加bilibili动态直播专栏解析 * 💩 修改大小写 * 🎨 正则全局,错误处理 * 🎨 使用json.NewDecoder() * 💚 空使用 * 💚 修lint
This commit is contained in:
parent
31555cbf2f
commit
1c9a7eb158
@ -387,11 +387,11 @@ print("run[CQ:image,file="+j["img"]+"]")
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>b站视频链接解析</summary>
|
<summary>b站动态、专栏、视频、直播解析</summary>
|
||||||
|
|
||||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili_parse"`
|
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili"`
|
||||||
|
|
||||||
- [x] https://www.bilibili.com/video/BV1xx411c7BF | https://www.bilibili.com/video/av1605 | https://b23.tv/I8uzWCA | https://www.bilibili.com/video/bv1xx411c7BF
|
- [x] t.bilibili.com/642277677329285174 | bilibili.com/read/cv17134450 | bilibili.com/video/BV13B4y1x7pS | live.bilibili.com/22603245
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
117
main.go
117
main.go
@ -55,65 +55,64 @@ import (
|
|||||||
// vvvvvvvvvvvvvv //
|
// vvvvvvvvvvvvvv //
|
||||||
// vvvv //
|
// vvvv //
|
||||||
|
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ai_false" // 服务器监控
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ai_false" // 服务器监控
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiwife" // 随机老婆
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiwife" // 随机老婆
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/b14" // base16384加解密
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/b14" // base16384加解密
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu" // 百度一下
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu" // 百度一下
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili" // 查询b站用户信息
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili" // b站相关
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili_parse" // b站视频链接解析
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/book_review" // 哀伤雪刃吧推书记录
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/book_review" // 哀伤雪刃吧推书记录
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cangtoushi" // 藏头诗
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cangtoushi" // 藏头诗
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/choose" // 选择困难症帮手
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/choose" // 选择困难症帮手
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chouxianghua" // 说抽象话
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chouxianghua" // 说抽象话
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/coser" // 三次元小姐姐
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/coser" // 三次元小姐姐
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cpstory" // cp短打
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cpstory" // cp短打
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/danbooru" // DeepDanbooru二次元图标签识别
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/danbooru" // DeepDanbooru二次元图标签识别
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drift_bottle" // 漂流瓶
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drift_bottle" // 漂流瓶
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic" // 城市疫情查询
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic" // 城市疫情查询
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/font" // 渲染任意文字到图片
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/font" // 渲染任意文字到图片
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/fortune" // 运势
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/fortune" // 运势
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/funny" // 笑话
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/funny" // 笑话
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/genshin" // 原神抽卡
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/genshin" // 原神抽卡
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/gif" // 制图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/gif" // 制图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/github" // 搜索GitHub仓库
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/github" // 搜索GitHub仓库
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/guessmusic" // 猜歌
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/guessmusic" // 猜歌
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hs" // 炉石
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hs" // 炉石
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hyaku" // 百人一首
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hyaku" // 百人一首
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder" // 关键字搜图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder" // 关键字搜图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi" // 绝绝子生成器
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi" // 绝绝子生成器
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolicon" // lolicon 随机图片
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolicon" // lolicon 随机图片
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/midicreate" // 简易midi音乐制作
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/midicreate" // 简易midi音乐制作
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu" // 摸鱼
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu" // 摸鱼
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu_calendar" // 摸鱼人日历
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/moyu_calendar" // 摸鱼人日历
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/music" // 点歌
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/music" // 点歌
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativesetu" // 本地涩图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativesetu" // 本地涩图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativewife" // 本地老婆
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativewife" // 本地老婆
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nbnhhsh" // 拼音首字母缩写释义工具
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nbnhhsh" // 拼音首字母缩写释义工具
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/novel" // 铅笔小说网搜索
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/novel" // 铅笔小说网搜索
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nsfw" // nsfw图片识别
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nsfw" // nsfw图片识别
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/omikuji" // 浅草寺求签
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/omikuji" // 浅草寺求签
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/qqwife" // 一群一天一夫一妻制群老婆
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/qqwife" // 一群一天一夫一妻制群老婆
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/reborn" // 投胎
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/reborn" // 投胎
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/runcode" // 在线运行代码
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/runcode" // 在线运行代码
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/saucenao" // 以图搜图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/saucenao" // 以图搜图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/scale" // 叔叔的AI二次元图片放大
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/scale" // 叔叔的AI二次元图片放大
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/score" // 分数
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/score" // 分数
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime" // 来份涩图
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime" // 来份涩图
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/shadiao" // 沙雕app
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/shadiao" // 沙雕app
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/shindan" // 测定
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/shindan" // 测定
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tarot" // 抽塔罗牌
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tarot" // 抽塔罗牌
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou" // 舔狗日记
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou" // 舔狗日记
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tracemoe" // 搜番
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tracemoe" // 搜番
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
|
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
|
||||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
|
|
||||||
|
|
||||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
||||||
|
|
||||||
|
|||||||
@ -3,8 +3,9 @@ package bilibili
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/FloatTech/zbputils/binary"
|
"github.com/FloatTech/zbputils/binary"
|
||||||
"github.com/FloatTech/zbputils/web"
|
"github.com/FloatTech/zbputils/web"
|
||||||
@ -15,18 +16,9 @@ var (
|
|||||||
errNeedCookie = errors.New("该api需要设置b站cookie,请发送命令设置cookie,例如\"设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\"")
|
errNeedCookie = errors.New("该api需要设置b站cookie,请发送命令设置cookie,例如\"设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\"")
|
||||||
)
|
)
|
||||||
|
|
||||||
type searchResult struct {
|
// searchUser 查找b站用户
|
||||||
Mid int64 `json:"mid"`
|
func searchUser(keyword string) (r []searchResult, err error) {
|
||||||
Uname string `json:"uname"`
|
data, err := web.GetData(fmt.Sprintf(searchUserURL, keyword))
|
||||||
Gender int64 `json:"gender"`
|
|
||||||
Usign string `json:"usign"`
|
|
||||||
Level int64 `json:"level"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 搜索api:通过把触发指令传入的昵称找出uid返回
|
|
||||||
func search(keyword string) (r []searchResult, err error) {
|
|
||||||
searchURL := "http://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&keyword=" + keyword
|
|
||||||
data, err := web.GetData(searchURL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -42,21 +34,9 @@ func search(keyword string) (r []searchResult, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type follower struct {
|
// getVtbDetail 查找vtb信息
|
||||||
Mid int `json:"mid"`
|
func getVtbDetail(uid string) (result vtbDetail, err error) {
|
||||||
Uname string `json:"uname"`
|
data, err := web.GetData(fmt.Sprintf(vtbDetailURL, uid))
|
||||||
Video int `json:"video"`
|
|
||||||
Roomid int `json:"roomid"`
|
|
||||||
Rise int `json:"rise"`
|
|
||||||
Follower int `json:"follower"`
|
|
||||||
GuardNum int `json:"guardNum"`
|
|
||||||
AreaRank int `json:"areaRank"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 请求api
|
|
||||||
func fansapi(uid string) (result follower, err error) {
|
|
||||||
fanURL := "https://api.vtbs.moe/v1/detail/" + uid
|
|
||||||
data, err := web.GetData(fanURL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -66,76 +46,9 @@ func fansapi(uid string) (result follower, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func followings(uid string) (s string, err error) {
|
// getMemberCard 获取b站个人详情
|
||||||
followingURL := "https://api.bilibili.com/x/relation/same/followings?vmid=" + uid
|
func getMemberCard(uid interface{}) (result memberCard, err error) {
|
||||||
method := "GET"
|
data, err := web.GetData(fmt.Sprintf(memberCardURL, uid))
|
||||||
client := &http.Client{}
|
|
||||||
req, err := http.NewRequest(method, followingURL, nil)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
c := vdb.getBilibiliCookie()
|
|
||||||
req.Header.Add("cookie", c.Value)
|
|
||||||
res, err := client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer res.Body.Close()
|
|
||||||
body, err := io.ReadAll(res.Body)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
j := gjson.ParseBytes(body)
|
|
||||||
s = j.Get("data.list.#.uname").Raw
|
|
||||||
if j.Get("code").Int() == -101 {
|
|
||||||
err = errNeedCookie
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if j.Get("code").Int() != 0 {
|
|
||||||
err = errors.New(j.Get("message").String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type userinfo struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Mid string `json:"mid"`
|
|
||||||
Face string `json:"face"`
|
|
||||||
Fans int64 `json:"fans"`
|
|
||||||
Regtime int64 `json:"regtime"`
|
|
||||||
Attentions []int64 `json:"attentions"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type medalInfo struct {
|
|
||||||
Mid int64 `json:"target_id"`
|
|
||||||
MedalName string `json:"medal_name"`
|
|
||||||
Level int64 `json:"level"`
|
|
||||||
MedalColorStart int64 `json:"medal_color_start"`
|
|
||||||
MedalColorEnd int64 `json:"medal_color_end"`
|
|
||||||
MedalColorBorder int64 `json:"medal_color_border"`
|
|
||||||
}
|
|
||||||
type medal struct {
|
|
||||||
Uname string `json:"target_name"`
|
|
||||||
medalInfo `json:"medal_info"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type medalSlice []medal
|
|
||||||
|
|
||||||
func (m medalSlice) Len() int {
|
|
||||||
return len(m)
|
|
||||||
}
|
|
||||||
func (m medalSlice) Swap(i, j int) {
|
|
||||||
m[i], m[j] = m[j], m[i]
|
|
||||||
}
|
|
||||||
func (m medalSlice) Less(i, j int) bool {
|
|
||||||
return m[i].Level > m[j].Level
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取详情
|
|
||||||
func card(uid string) (result userinfo, err error) {
|
|
||||||
cardURL := "https://account.bilibili.com/api/member/getCardByMid?mid=" + uid
|
|
||||||
data, err := web.GetData(cardURL)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -146,12 +59,10 @@ func card(uid string) (result userinfo, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获得牌子
|
// getMedalwall 用b站uid获得牌子
|
||||||
func medalwall(uid string) (result []medal, err error) {
|
func getMedalwall(uid string) (result []medal, err error) {
|
||||||
medalwallURL := "https://api.live.bilibili.com/xlive/web-ucenter/user/MedalWall?target_id=" + uid
|
|
||||||
method := "GET"
|
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
req, err := http.NewRequest(method, medalwallURL, nil)
|
req, err := http.NewRequest("GET", fmt.Sprintf(medalwallURL, uid), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -162,18 +73,56 @@ func medalwall(uid string) (result []medal, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
data, err := io.ReadAll(res.Body)
|
var md medalData
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&md)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
j := gjson.ParseBytes(data)
|
if md.Code == -101 {
|
||||||
if j.Get("code").Int() == -101 {
|
|
||||||
err = errNeedCookie
|
err = errNeedCookie
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if j.Get("code").Int() != 0 {
|
if md.Code != 0 {
|
||||||
err = errors.New(j.Get("message").String())
|
err = errors.New(md.Message)
|
||||||
}
|
}
|
||||||
_ = json.Unmarshal(binary.StringToBytes(j.Get("data.list").Raw), &result)
|
result = md.Data.List
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getArticleInfo 用id查专栏信息
|
||||||
|
func getArticleInfo(id string) (card Card, err error) {
|
||||||
|
var data []byte
|
||||||
|
data, err = web.GetData(fmt.Sprintf(articleInfoURL, id))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(gjson.ParseBytes(data).Get("data").Raw), &card)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLiveRoomInfo 用直播间id查直播间信息
|
||||||
|
func getLiveRoomInfo(roomID string) (card roomCard, err error) {
|
||||||
|
var data []byte
|
||||||
|
data, err = web.GetData(fmt.Sprintf(liveRoomInfoURL, roomID))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(gjson.ParseBytes(data).Get("data").Raw), &card)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// getVideoInfo 用av或bv查视频信息
|
||||||
|
func getVideoInfo(id string) (card Card, err error) {
|
||||||
|
var data []byte
|
||||||
|
_, err = strconv.Atoi(id)
|
||||||
|
if err == nil {
|
||||||
|
data, err = web.GetData(fmt.Sprintf(videoInfoURL, id, ""))
|
||||||
|
} else {
|
||||||
|
data, err = web.GetData(fmt.Sprintf(videoInfoURL, "", id))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(gjson.ParseBytes(data).Get("data").Raw), &card)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,20 +27,20 @@ import (
|
|||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
var engine = control.Register("bilibili", &ctrl.Options[*zero.Ctx]{
|
|
||||||
DisableOnDefault: false,
|
|
||||||
Help: "bilibili\n" +
|
|
||||||
"- >vup info [xxx]\n" +
|
|
||||||
"- >user info [xxx]\n" +
|
|
||||||
"- 查成分 [xxx]\n" +
|
|
||||||
"- 设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\n" +
|
|
||||||
"- 更新vup",
|
|
||||||
PublicDataFolder: "Bilibili",
|
|
||||||
})
|
|
||||||
var re = regexp.MustCompile(`^\d+$`)
|
var re = regexp.MustCompile(`^\d+$`)
|
||||||
|
|
||||||
// 查成分的
|
// 查成分的
|
||||||
func init() {
|
func init() {
|
||||||
|
engine := control.Register("bilibili", &ctrl.Options[*zero.Ctx]{
|
||||||
|
DisableOnDefault: false,
|
||||||
|
Help: "bilibili\n" +
|
||||||
|
"- >vup info [xxx]\n" +
|
||||||
|
"- >user info [xxx]\n" +
|
||||||
|
"- 查成分 [xxx]\n" +
|
||||||
|
"- 设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\n" +
|
||||||
|
"- 更新vup",
|
||||||
|
PublicDataFolder: "Bilibili",
|
||||||
|
})
|
||||||
cachePath := engine.DataFolder() + "cache/"
|
cachePath := engine.DataFolder() + "cache/"
|
||||||
_ = os.RemoveAll(cachePath)
|
_ = os.RemoveAll(cachePath)
|
||||||
_ = os.MkdirAll(cachePath, 0755)
|
_ = os.MkdirAll(cachePath, 0755)
|
||||||
@ -55,46 +55,35 @@ func init() {
|
|||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
|
||||||
engine.OnRegex(`^>user info\s?(.{1,25})$`, getdb).SetBlock(true).
|
engine.OnRegex(`^>user info\s?(.{1,25})$`, getPara).SetBlock(true).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
id := ctx.State["uid"].(string)
|
||||||
uidRes, err := search(keyword)
|
card, err := getMemberCard(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
id := strconv.FormatInt(uidRes[0].Mid, 10)
|
|
||||||
follwings, err := followings(id)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
}
|
|
||||||
ctx.SendChain(message.Text(
|
ctx.SendChain(message.Text(
|
||||||
"search: ", uidRes[0].Mid, "\n",
|
"uid: ", card.Mid, "\n",
|
||||||
"name: ", uidRes[0].Uname, "\n",
|
"name: ", card.Name, "\n",
|
||||||
"sex: ", []string{"", "男", "女", "未知"}[uidRes[0].Gender], "\n",
|
"sex: ", card.Sex, "\n",
|
||||||
"sign: ", uidRes[0].Usign, "\n",
|
"sign: ", card.Sign, "\n",
|
||||||
"level: ", uidRes[0].Level, "\n",
|
"level: ", card.LevelInfo.CurrentLevel, "\n",
|
||||||
"follow: ", follwings,
|
"birthday: ", card.Birthday,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
||||||
engine.OnRegex(`^>vup info\s?(.{1,25})$`).SetBlock(true).
|
engine.OnRegex(`^>vup info\s?(.{1,25})$`, getPara).SetBlock(true).
|
||||||
Handle(func(ctx *zero.Ctx) {
|
Handle(func(ctx *zero.Ctx) {
|
||||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
id := ctx.State["uid"].(string)
|
||||||
res, err := search(keyword)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id := strconv.FormatInt(res[0].Mid, 10)
|
|
||||||
// 获取详情
|
// 获取详情
|
||||||
fo, err := fansapi(id)
|
fo, err := getVtbDetail(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.SendChain(message.Text(
|
ctx.SendChain(message.Text(
|
||||||
"search: ", fo.Mid, "\n",
|
"b站id: ", fo.Mid, "\n",
|
||||||
"名字: ", fo.Uname, "\n",
|
"名字: ", fo.Uname, "\n",
|
||||||
"当前粉丝数: ", fo.Follower, "\n",
|
"当前粉丝数: ", fo.Follower, "\n",
|
||||||
"24h涨粉数: ", fo.Rise, "\n",
|
"24h涨粉数: ", fo.Rise, "\n",
|
||||||
@ -116,7 +105,7 @@ func init() {
|
|||||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
u, err := card(id)
|
u, err := getMemberCard(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
return
|
return
|
||||||
@ -127,7 +116,7 @@ func init() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
vupLen := len(vups)
|
vupLen := len(vups)
|
||||||
medals, err := medalwall(id)
|
medals, err := getMedalwall(id)
|
||||||
sort.Sort(medalSlice(medals))
|
sort.Sort(medalSlice(medals))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
@ -312,7 +301,7 @@ func int2rbg(t int64) (int64, int64, int64) {
|
|||||||
func getPara(ctx *zero.Ctx) bool {
|
func getPara(ctx *zero.Ctx) bool {
|
||||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
keyword := ctx.State["regex_matched"].([]string)[1]
|
||||||
if !re.MatchString(keyword) {
|
if !re.MatchString(keyword) {
|
||||||
searchRes, err := search(keyword)
|
searchRes, err := searchUser(keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
return false
|
return false
|
||||||
@ -345,7 +334,7 @@ func getPara(ctx *zero.Ctx) bool {
|
|||||||
ctx.State["uid"] = keyword
|
ctx.State["uid"] = keyword
|
||||||
return true
|
return true
|
||||||
} else if num == 1 {
|
} else if num == 1 {
|
||||||
searchRes, err := search(keyword)
|
searchRes, err := searchUser(keyword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.SendChain(message.Text("ERROR:", err))
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
return false
|
return false
|
||||||
105
plugin/bilibili/bilibili_parse.go
Normal file
105
plugin/bilibili/bilibili_parse.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package bilibili
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ctrl "github.com/FloatTech/zbpctrl"
|
||||||
|
"github.com/FloatTech/zbputils/control"
|
||||||
|
"github.com/FloatTech/zbputils/ctxext"
|
||||||
|
zero "github.com/wdvxdr1123/ZeroBot"
|
||||||
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
limit = ctxext.NewLimiterManager(time.Second*10, 1)
|
||||||
|
searchVideo = `bilibili.com/video/(?:av(\d+)|([bB][vV][0-9a-zA-Z]+))`
|
||||||
|
searchDynamic = `(t.bilibili.com|m.bilibili.com/dynamic)/(\d+)`
|
||||||
|
searchArticle = `bilibili.com/read/(?:cv|mobile/)(\d+)`
|
||||||
|
searchLiveRoom = `live.bilibili.com/(\d+)`
|
||||||
|
searchVideoRe = regexp.MustCompile(searchVideo)
|
||||||
|
searchDynamicRe = regexp.MustCompile(searchDynamic)
|
||||||
|
searchArticleRe = regexp.MustCompile(searchArticle)
|
||||||
|
searchLiveRoomRe = regexp.MustCompile(searchLiveRoom)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 插件主体
|
||||||
|
func init() {
|
||||||
|
en := control.Register("bilibiliparse", &ctrl.Options[*zero.Ctx]{
|
||||||
|
DisableOnDefault: false,
|
||||||
|
Help: "b站动态、专栏、视频、直播解析\n" +
|
||||||
|
"- t.bilibili.com/642277677329285174 | bilibili.com/read/cv17134450 | bilibili.com/video/BV13B4y1x7pS | live.bilibili.com/22603245 ",
|
||||||
|
})
|
||||||
|
en.OnRegex(`((b23|acg).tv|bili2233.cn)/[0-9a-zA-Z]+`).SetBlock(true).Limit(limit.LimitByGroup).
|
||||||
|
Handle(func(ctx *zero.Ctx) {
|
||||||
|
url := ctx.State["regex_matched"].([]string)[0]
|
||||||
|
realurl, err := getrealurl("https://" + url)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR: ", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case searchVideoRe.MatchString(realurl):
|
||||||
|
ctx.State["regex_matched"] = searchVideoRe.FindStringSubmatch(realurl)
|
||||||
|
handleVideo(ctx)
|
||||||
|
case searchDynamicRe.MatchString(realurl):
|
||||||
|
ctx.State["regex_matched"] = searchDynamicRe.FindStringSubmatch(realurl)
|
||||||
|
handleDynamic(ctx)
|
||||||
|
case searchArticleRe.MatchString(realurl):
|
||||||
|
ctx.State["regex_matched"] = searchArticleRe.FindStringSubmatch(realurl)
|
||||||
|
handleArticle(ctx)
|
||||||
|
case searchLiveRoomRe.MatchString(realurl):
|
||||||
|
ctx.State["regex_matched"] = searchLiveRoomRe.FindStringSubmatch(realurl)
|
||||||
|
handleLive(ctx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
en.OnRegex(searchVideo).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleVideo)
|
||||||
|
en.OnRegex(searchDynamic).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleDynamic)
|
||||||
|
en.OnRegex(searchArticle).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleArticle)
|
||||||
|
en.OnRegex(searchLiveRoom).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleLive)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleVideo(ctx *zero.Ctx) {
|
||||||
|
id := ctx.State["regex_matched"].([]string)[1]
|
||||||
|
if id == "" {
|
||||||
|
id = ctx.State["regex_matched"].([]string)[2]
|
||||||
|
}
|
||||||
|
card, err := getVideoInfo(id)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg, err := videoCard2msg(card)
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(msg...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDynamic(ctx *zero.Ctx) {
|
||||||
|
msg, err := dynamicDetail(ctx.State["regex_matched"].([]string)[2])
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(msg...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleArticle(ctx *zero.Ctx) {
|
||||||
|
card, err := getArticleInfo(ctx.State["regex_matched"].([]string)[1])
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(articleCard2msg(card, ctx.State["regex_matched"].([]string)[1])...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleLive(ctx *zero.Ctx) {
|
||||||
|
card, err := getLiveRoomInfo(ctx.State["regex_matched"].([]string)[1])
|
||||||
|
if err != nil {
|
||||||
|
ctx.SendChain(message.Text("ERROR:", err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ctx.SendChain(liveCard2msg(card)...)
|
||||||
|
}
|
||||||
233
plugin/bilibili/card2msg.go
Normal file
233
plugin/bilibili/card2msg.go
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
package bilibili
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/FloatTech/zbputils/binary"
|
||||||
|
"github.com/FloatTech/zbputils/web"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
"github.com/wdvxdr1123/ZeroBot/message"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
typeMsg = map[int]string{
|
||||||
|
1: "转发了动态",
|
||||||
|
2: "有图营业",
|
||||||
|
4: "无图营业",
|
||||||
|
8: "投稿了视频",
|
||||||
|
16: "投稿了短视频",
|
||||||
|
64: "投稿了文章",
|
||||||
|
256: "投稿了音频",
|
||||||
|
2048: "发布了简报",
|
||||||
|
4200: "发布了直播",
|
||||||
|
4308: "发布了直播",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// dynamicCard2msg cType=0时,处理DynCard字符串,cType=1, 2, 4, 8, 16, 64, 256, 2048, 4200, 4308时,处理Card字符串,cType为card类型
|
||||||
|
func dynamicCard2msg(str string, cType int) (msg []message.MessageSegment, err error) {
|
||||||
|
var (
|
||||||
|
dynamicCard dynamicCard
|
||||||
|
card Card
|
||||||
|
vote Vote
|
||||||
|
)
|
||||||
|
msg = make([]message.MessageSegment, 0, 16)
|
||||||
|
// 初始化结构体
|
||||||
|
switch cType {
|
||||||
|
case 0:
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(str), &dynamicCard)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(dynamicCard.Card), &card)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dynamicCard.Extension.Vote != "" {
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(dynamicCard.Extension.Vote), &vote)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cType = dynamicCard.Desc.Type
|
||||||
|
case 1, 2, 4, 8, 16, 64, 256, 2048, 4200, 4308:
|
||||||
|
err = json.Unmarshal(binary.StringToBytes(str), &card)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err = errors.New("只有0, 1, 2, 4, 8, 16, 64, 256, 2048, 4200, 4308模式")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 生成消息
|
||||||
|
switch cType {
|
||||||
|
case 1:
|
||||||
|
msg = append(msg, message.Text(card.User.Uname, typeMsg[cType], "\n",
|
||||||
|
card.Item.Content, "\n",
|
||||||
|
"转发的内容: \n"))
|
||||||
|
var originMsg []message.MessageSegment
|
||||||
|
originMsg, err = dynamicCard2msg(card.Origin, card.Item.OrigType)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg = append(msg, originMsg...)
|
||||||
|
case 2:
|
||||||
|
msg = append(msg, message.Text(card.User.Name, "在", time.Unix(int64(card.Item.UploadTime), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Item.Description))
|
||||||
|
for i := 0; i < len(card.Item.Pictures); i++ {
|
||||||
|
msg = append(msg, message.Image(card.Item.Pictures[i].ImgSrc))
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
msg = append(msg, message.Text(card.User.Uname, "在", time.Unix(int64(card.Item.Timestamp), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Item.Content, "\n"))
|
||||||
|
if dynamicCard.Extension.Vote != "" {
|
||||||
|
msg = append(msg, message.Text("【投票】", vote.Desc, "\n",
|
||||||
|
"截止日期: ", time.Unix(int64(vote.Endtime), 0).Format("2006-01-02 15:04:05"), "\n",
|
||||||
|
"参与人数: ", humanNum(vote.JoinNum), "\n",
|
||||||
|
"投票选项( 最多选择", vote.ChoiceCnt, "项 )\n"))
|
||||||
|
for i := 0; i < len(vote.Options); i++ {
|
||||||
|
msg = append(msg, message.Text("- ", vote.Options[i].Idx, ". ", vote.Options[i].Desc, "\n"))
|
||||||
|
if vote.Options[i].ImgURL != "" {
|
||||||
|
msg = append(msg, message.Image(vote.Options[i].ImgURL))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 8:
|
||||||
|
msg = append(msg, message.Text(card.Owner.Name, "在", time.Unix(int64(card.Pubdate), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Title))
|
||||||
|
msg = append(msg, message.Image(card.Pic))
|
||||||
|
msg = append(msg, message.Text(card.Desc, "\n",
|
||||||
|
card.ShareSubtitle, "\n",
|
||||||
|
"视频链接: ", card.ShortLink, "\n"))
|
||||||
|
case 16:
|
||||||
|
msg = append(msg, message.Text(card.User.Name, "在", time.Unix(int64(card.Item.UploadTime), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Item.Description))
|
||||||
|
msg = append(msg, message.Image(card.Item.Cover.Default))
|
||||||
|
case 64:
|
||||||
|
msg = append(msg, message.Text(card.Author.(map[string]interface{})["name"], "在", time.Unix(int64(card.PublishTime), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Title, "\n",
|
||||||
|
card.Summary))
|
||||||
|
for i := 0; i < len(card.ImageUrls); i++ {
|
||||||
|
msg = append(msg, message.Image(card.ImageUrls[i]))
|
||||||
|
}
|
||||||
|
if card.ID != 0 {
|
||||||
|
msg = append(msg, message.Text("文章链接: https://www.bilibili.com/read/cv", card.ID, "\n"))
|
||||||
|
}
|
||||||
|
case 256:
|
||||||
|
msg = append(msg, message.Text(card.Upper, "在", time.Unix(int64(card.Ctime), 0).Format("2006-01-02 15:04:05"), typeMsg[cType], "\n",
|
||||||
|
card.Title))
|
||||||
|
msg = append(msg, message.Image(card.Cover))
|
||||||
|
msg = append(msg, message.Text(card.Intro, "\n"))
|
||||||
|
if card.ID != 0 {
|
||||||
|
msg = append(msg, message.Text("音频链接: https://www.bilibili.com/audio/au", card.ID, "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2048:
|
||||||
|
msg = append(msg, message.Text(card.User.Uname, typeMsg[cType], "\n",
|
||||||
|
card.Vest.Content, "\n",
|
||||||
|
card.Sketch.Title, "\n",
|
||||||
|
card.Sketch.DescText, "\n"))
|
||||||
|
msg = append(msg, message.Image(card.Sketch.CoverURL))
|
||||||
|
msg = append(msg, message.Text("分享链接: ", card.Sketch.TargetURL, "\n"))
|
||||||
|
case 4308:
|
||||||
|
if dynamicCard.Desc.UserProfile.Info.Uname != "" {
|
||||||
|
msg = append(msg, message.Text(dynamicCard.Desc.UserProfile.Info.Uname, typeMsg[cType], "\n"))
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Image(card.LivePlayInfo.Cover))
|
||||||
|
msg = append(msg, message.Text(card.LivePlayInfo.Title, "\n",
|
||||||
|
"房间号: ", card.LivePlayInfo.RoomID, "\n",
|
||||||
|
"分区: ", card.LivePlayInfo.ParentAreaName))
|
||||||
|
if card.LivePlayInfo.ParentAreaName != card.LivePlayInfo.AreaName {
|
||||||
|
msg = append(msg, message.Text("-", card.LivePlayInfo.AreaName))
|
||||||
|
}
|
||||||
|
if card.LivePlayInfo.LiveStatus == 0 {
|
||||||
|
msg = append(msg, message.Text("未开播 \n"))
|
||||||
|
} else {
|
||||||
|
msg = append(msg, message.Text("直播中 ", card.LivePlayInfo.WatchedShow, "\n"))
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Text("直播链接: ", card.LivePlayInfo.Link))
|
||||||
|
default:
|
||||||
|
msg = append(msg, message.Text("动态id: ", dynamicCard.Desc.DynamicIDStr, "未知动态类型: ", cType, "\n"))
|
||||||
|
}
|
||||||
|
if dynamicCard.Desc.DynamicIDStr != "" {
|
||||||
|
msg = append(msg, message.Text("动态链接: ", tURL, dynamicCard.Desc.DynamicIDStr))
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// dynamicDetail 用动态id查动态信息
|
||||||
|
func dynamicDetail(dynamicIDStr string) (msg []message.MessageSegment, err error) {
|
||||||
|
var data []byte
|
||||||
|
data, err = web.GetData(fmt.Sprintf(dynamicDetailURL, dynamicIDStr))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return dynamicCard2msg(gjson.ParseBytes(data).Get("data.card").Raw, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// articleCard2msg 专栏转消息
|
||||||
|
func articleCard2msg(card Card, defaultID string) (msg []message.MessageSegment) {
|
||||||
|
msg = make([]message.MessageSegment, 0, 16)
|
||||||
|
for i := 0; i < len(card.OriginImageUrls); i++ {
|
||||||
|
msg = append(msg, message.Image(card.OriginImageUrls[i]))
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Text(card.Title, "\n", "UP主: ", card.AuthorName, "\n",
|
||||||
|
"阅读: ", humanNum(card.Stats.View), " 评论: ", humanNum(card.Stats.Reply), "\n",
|
||||||
|
cvURL, defaultID))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// liveCard2msg 直播卡片转消息
|
||||||
|
func liveCard2msg(card roomCard) (msg []message.MessageSegment) {
|
||||||
|
msg = make([]message.MessageSegment, 0, 16)
|
||||||
|
msg = append(msg, message.Image(card.RoomInfo.Keyframe))
|
||||||
|
msg = append(msg, message.Text(card.RoomInfo.Title, "\n",
|
||||||
|
"主播: ", card.AnchorInfo.BaseInfo.Uname, "\n",
|
||||||
|
"房间号: ", card.RoomInfo.RoomID, "\n"))
|
||||||
|
if card.RoomInfo.ShortID != 0 {
|
||||||
|
msg = append(msg, message.Text("短号: ", card.RoomInfo.ShortID, "\n"))
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Text("分区: ", card.RoomInfo.ParentAreaName))
|
||||||
|
if card.RoomInfo.ParentAreaName != card.RoomInfo.AreaName {
|
||||||
|
msg = append(msg, message.Text("-", card.RoomInfo.AreaName))
|
||||||
|
}
|
||||||
|
if card.RoomInfo.LiveStatus == 0 {
|
||||||
|
msg = append(msg, message.Text("未开播 \n"))
|
||||||
|
} else {
|
||||||
|
msg = append(msg, message.Text("直播中 ", humanNum(card.RoomInfo.Online), "人气\n"))
|
||||||
|
}
|
||||||
|
if card.RoomInfo.ShortID != 0 {
|
||||||
|
msg = append(msg, message.Text("直播间链接: ", lURL, card.RoomInfo.ShortID))
|
||||||
|
} else {
|
||||||
|
msg = append(msg, message.Text("直播间链接: ", lURL, card.RoomInfo.RoomID))
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// videoCard2msg 视频卡片转消息
|
||||||
|
func videoCard2msg(card Card) (msg []message.MessageSegment, err error) {
|
||||||
|
var mCard memberCard
|
||||||
|
msg = make([]message.MessageSegment, 0, 16)
|
||||||
|
mCard, err = getMemberCard(card.Owner.Mid)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Text("标题: ", card.Title, "\n"))
|
||||||
|
if card.Rights.IsCooperation == 1 {
|
||||||
|
for i := 0; i < len(card.Staff); i++ {
|
||||||
|
msg = append(msg, message.Text(card.Staff[i].Title, ": ", card.Staff[i].Name, " 粉丝: ", humanNum(card.Staff[i].Follower), "\n"))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg = append(msg, message.Text("UP主: ", card.Owner.Name, " 粉丝: ", humanNum(mCard.Fans), "\n"))
|
||||||
|
}
|
||||||
|
msg = append(msg, message.Text("播放: ", humanNum(card.Stat.View), " 弹幕: ", humanNum(card.Stat.Danmaku)))
|
||||||
|
msg = append(msg, message.Image(card.Pic))
|
||||||
|
msg = append(msg, message.Text("点赞: ", humanNum(card.Stat.Like), " 投币: ", humanNum(card.Stat.Coin), "\n",
|
||||||
|
"收藏: ", humanNum(card.Stat.Favorite), " 分享: ", humanNum(card.Stat.Share), "\n",
|
||||||
|
vURL, card.BvID))
|
||||||
|
return
|
||||||
|
}
|
||||||
82
plugin/bilibili/card2msg_test.go
Normal file
82
plugin/bilibili/card2msg_test.go
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
package bilibili
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestArticleInfo(t *testing.T) {
|
||||||
|
card, err := getArticleInfo("17279244")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(articleCard2msg(card, "17279244"))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDynamicDetail(t *testing.T) {
|
||||||
|
t.Log("cType = 1")
|
||||||
|
t.Log(dynamicDetail("642279068898689029"))
|
||||||
|
|
||||||
|
t.Log("cType = 2")
|
||||||
|
t.Log(dynamicDetail("642470680290394121"))
|
||||||
|
|
||||||
|
t.Log("cType = 2048")
|
||||||
|
t.Log(dynamicDetail("642277677329285174"))
|
||||||
|
|
||||||
|
t.Log("cType = 4")
|
||||||
|
t.Log(dynamicDetail("642154347357011968"))
|
||||||
|
|
||||||
|
t.Log("cType = 8")
|
||||||
|
t.Log(dynamicDetail("675892999274627104"))
|
||||||
|
|
||||||
|
t.Log("cType = 4308")
|
||||||
|
t.Log(dynamicDetail("668598718656675844"))
|
||||||
|
|
||||||
|
t.Log("cType = 64")
|
||||||
|
t.Log(dynamicDetail("675966082178088963"))
|
||||||
|
|
||||||
|
t.Log("cType = 256")
|
||||||
|
t.Log(dynamicDetail("599253048535707632"))
|
||||||
|
|
||||||
|
t.Log("cType = 4,投票类型")
|
||||||
|
t.Log(dynamicDetail("677231070435868704"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMemberCard(t *testing.T) {
|
||||||
|
card, err := getMemberCard(2)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Logf("%+v\n", card)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVideoInfo(t *testing.T) {
|
||||||
|
card, err := getVideoInfo("10007")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(videoCard2msg(card))
|
||||||
|
card, err = getVideoInfo("BV1xx411c7mD")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(videoCard2msg(card))
|
||||||
|
card, err = getVideoInfo("bv1xx411c7mD")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(videoCard2msg(card))
|
||||||
|
card, err = getVideoInfo("BV1mF411j7iU")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(videoCard2msg(card))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLiveRoomInfo(t *testing.T) {
|
||||||
|
card, err := getLiveRoomInfo("83171")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
t.Log(liveCard2msg(card))
|
||||||
|
}
|
||||||
267
plugin/bilibili/types.go
Normal file
267
plugin/bilibili/types.go
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
package bilibili
|
||||||
|
|
||||||
|
const (
|
||||||
|
// tURL bilibili动态前缀
|
||||||
|
tURL = "https://t.bilibili.com/"
|
||||||
|
// dynamicDetailURL 当前动态信息,一个card
|
||||||
|
dynamicDetailURL = "https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/get_dynamic_detail?dynamic_id=%v"
|
||||||
|
// memberCardURL 个人信息
|
||||||
|
memberCardURL = "https://account.bilibili.com/api/member/getCardByMid?mid=%v"
|
||||||
|
// articleInfoURL 查看专栏信息
|
||||||
|
articleInfoURL = "https://api.bilibili.com/x/article/viewinfo?id=%v"
|
||||||
|
// cvURL b站专栏前缀
|
||||||
|
cvURL = "https://www.bilibili.com/read/cv"
|
||||||
|
// liveRoomInfoURL 查看直播间信息
|
||||||
|
liveRoomInfoURL = "https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id=%v"
|
||||||
|
// lURL b站直播间前缀
|
||||||
|
lURL = "https://live.bilibili.com/"
|
||||||
|
// videoInfoURL 查看视频信息
|
||||||
|
videoInfoURL = "https://api.bilibili.com/x/web-interface/view?aid=%v&bvid=%v"
|
||||||
|
// vURL 视频网址前缀
|
||||||
|
vURL = "https://www.bilibili.com/video/"
|
||||||
|
// searchUserURL 查找b站用户
|
||||||
|
searchUserURL = "http://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&keyword=%v"
|
||||||
|
// vtbDetailURL 查找vtb信息
|
||||||
|
vtbDetailURL = "https://api.vtbs.moe/v1/detail/%v"
|
||||||
|
// medalwallURL 查找牌子
|
||||||
|
medalwallURL = "https://api.live.bilibili.com/xlive/web-ucenter/user/MedalWall?target_id=%v"
|
||||||
|
)
|
||||||
|
|
||||||
|
// dynamicCard 总动态结构体,包括desc,card
|
||||||
|
type dynamicCard struct {
|
||||||
|
Desc Desc `json:"desc"`
|
||||||
|
Card string `json:"card"`
|
||||||
|
Extension struct {
|
||||||
|
VoteCfg struct {
|
||||||
|
VoteID int `json:"vote_id"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
JoinNum int `json:"join_num"`
|
||||||
|
} `json:"vote_cfg"`
|
||||||
|
Vote string `json:"vote"`
|
||||||
|
} `json:"extension"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Card 卡片结构体
|
||||||
|
type Card struct {
|
||||||
|
Item struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
UploadTime int `json:"upload_time"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Pictures []struct {
|
||||||
|
ImgSrc string `json:"img_src"`
|
||||||
|
} `json:"pictures"`
|
||||||
|
Timestamp int `json:"timestamp"`
|
||||||
|
Cover struct {
|
||||||
|
Default string `json:"default"`
|
||||||
|
} `json:"cover"`
|
||||||
|
OrigType int `json:"orig_type"`
|
||||||
|
} `json:"item"`
|
||||||
|
AID interface{} `json:"aid"`
|
||||||
|
BvID interface{} `json:"bvid"`
|
||||||
|
Dynamic interface{} `json:"dynamic"`
|
||||||
|
Pic string `json:"pic"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Summary string `json:"summary"`
|
||||||
|
ImageUrls []string `json:"image_urls"`
|
||||||
|
OriginImageUrls []string `json:"origin_image_urls"`
|
||||||
|
Sketch struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
DescText string `json:"desc_text"`
|
||||||
|
CoverURL string `json:"cover_url"`
|
||||||
|
TargetURL string `json:"target_url"`
|
||||||
|
} `json:"sketch"`
|
||||||
|
Stat struct {
|
||||||
|
Aid int `json:"aid"`
|
||||||
|
View int `json:"view"`
|
||||||
|
Danmaku int `json:"danmaku"`
|
||||||
|
Reply int `json:"reply"`
|
||||||
|
Favorite int `json:"favorite"`
|
||||||
|
Coin int `json:"coin"`
|
||||||
|
Share int `json:"share"`
|
||||||
|
Like int `json:"like"`
|
||||||
|
} `json:"stat"`
|
||||||
|
Stats struct {
|
||||||
|
Aid int `json:"aid"`
|
||||||
|
View int `json:"view"`
|
||||||
|
Danmaku int `json:"danmaku"`
|
||||||
|
Reply int `json:"reply"`
|
||||||
|
Favorite int `json:"favorite"`
|
||||||
|
Coin int `json:"coin"`
|
||||||
|
Share int `json:"share"`
|
||||||
|
Like int `json:"like"`
|
||||||
|
} `json:"stats"`
|
||||||
|
Owner struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Pubdate int `json:"pubdate"`
|
||||||
|
Mid int `json:"mid"`
|
||||||
|
} `json:"owner"`
|
||||||
|
Cover string `json:"cover"`
|
||||||
|
ShortID interface{} `json:"short_id"`
|
||||||
|
LivePlayInfo struct {
|
||||||
|
ParentAreaName string `json:"parent_area_name"`
|
||||||
|
AreaName string `json:"area_name"`
|
||||||
|
Cover string `json:"cover"`
|
||||||
|
Link string `json:"link"`
|
||||||
|
Online int `json:"online"`
|
||||||
|
RoomID int `json:"room_id"`
|
||||||
|
LiveStatus int `json:"live_status"`
|
||||||
|
WatchedShow string `json:"watched_show"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
} `json:"live_play_info"`
|
||||||
|
Intro string `json:"intro"`
|
||||||
|
Schema string `json:"schema"`
|
||||||
|
Author interface{} `json:"author"`
|
||||||
|
AuthorName string `json:"author_name"`
|
||||||
|
PlayCnt int `json:"play_cnt"`
|
||||||
|
ReplyCnt int `json:"reply_cnt"`
|
||||||
|
TypeInfo string `json:"type_info"`
|
||||||
|
User struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Uname string `json:"uname"`
|
||||||
|
} `json:"user"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
ShareSubtitle string `json:"share_subtitle"`
|
||||||
|
ShortLink string `json:"short_link"`
|
||||||
|
PublishTime int `json:"publish_time"`
|
||||||
|
BannerURL string `json:"banner_url"`
|
||||||
|
Ctime int `json:"ctime"`
|
||||||
|
Vest struct {
|
||||||
|
Content string `json:"content"`
|
||||||
|
} `json:"vest"`
|
||||||
|
Upper string `json:"upper"`
|
||||||
|
Origin string `json:"origin"`
|
||||||
|
Pubdate int `json:"pubdate"`
|
||||||
|
Rights struct {
|
||||||
|
IsCooperation int `json:"is_cooperation"`
|
||||||
|
} `json:"rights"`
|
||||||
|
Staff []struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Follower int `json:"follower"`
|
||||||
|
} `json:"staff"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Desc 描述结构体
|
||||||
|
type Desc struct {
|
||||||
|
Type int `json:"type"`
|
||||||
|
DynamicIDStr string `json:"dynamic_id_str"`
|
||||||
|
OrigType int `json:"orig_type"`
|
||||||
|
Timestamp int `json:"timestamp"`
|
||||||
|
Origin struct {
|
||||||
|
DynamicIDStr string `json:"dynamic_id_str"`
|
||||||
|
} `json:"origin"`
|
||||||
|
UserProfile struct {
|
||||||
|
Info struct {
|
||||||
|
Uname string `json:"uname"`
|
||||||
|
} `json:"info"`
|
||||||
|
} `json:"user_profile"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vote 投票结构体
|
||||||
|
type Vote struct {
|
||||||
|
ChoiceCnt int `json:"choice_cnt"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
Endtime int `json:"endtime"`
|
||||||
|
JoinNum int `json:"join_num"`
|
||||||
|
Options []struct {
|
||||||
|
Idx int `json:"idx"`
|
||||||
|
Desc string `json:"desc"`
|
||||||
|
ImgURL string `json:"img_url"`
|
||||||
|
} `json:"options"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// memberCard 个人信息卡片
|
||||||
|
type memberCard struct {
|
||||||
|
Mid string `json:"mid"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Sex string `json:"sex"`
|
||||||
|
Face string `json:"face"`
|
||||||
|
Coins float64 `json:"coins"`
|
||||||
|
Regtime int64 `json:"regtime"`
|
||||||
|
Birthday string `json:"birthday"`
|
||||||
|
Sign string `json:"sign"`
|
||||||
|
Attentions []int64 `json:"attentions"`
|
||||||
|
Fans int `json:"fans"`
|
||||||
|
Friend int `json:"friend"`
|
||||||
|
Attention int `json:"attention"`
|
||||||
|
LevelInfo struct {
|
||||||
|
CurrentLevel int `json:"current_level"`
|
||||||
|
} `json:"level_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// roomCard 直播间卡片
|
||||||
|
type roomCard struct {
|
||||||
|
RoomInfo struct {
|
||||||
|
RoomID int `json:"room_id"`
|
||||||
|
ShortID int `json:"short_id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
LiveStatus int `json:"live_status"`
|
||||||
|
AreaName string `json:"area_name"`
|
||||||
|
ParentAreaName string `json:"parent_area_name"`
|
||||||
|
Keyframe string `json:"keyframe"`
|
||||||
|
Online int `json:"online"`
|
||||||
|
} `json:"room_info"`
|
||||||
|
AnchorInfo struct {
|
||||||
|
BaseInfo struct {
|
||||||
|
Uname string `json:"uname"`
|
||||||
|
} `json:"base_info"`
|
||||||
|
} `json:"anchor_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// searchResult 查找b站用户结果
|
||||||
|
type searchResult struct {
|
||||||
|
Mid int64 `json:"mid"`
|
||||||
|
Uname string `json:"uname"`
|
||||||
|
Gender int64 `json:"gender"`
|
||||||
|
Usign string `json:"usign"`
|
||||||
|
Level int64 `json:"level"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// medalData 牌子接口返回结构体
|
||||||
|
type medalData struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Data struct {
|
||||||
|
List []medal `json:"list"`
|
||||||
|
} `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// medalInfo b站牌子信息
|
||||||
|
type medalInfo struct {
|
||||||
|
Mid int64 `json:"target_id"`
|
||||||
|
MedalName string `json:"medal_name"`
|
||||||
|
Level int64 `json:"level"`
|
||||||
|
MedalColorStart int64 `json:"medal_color_start"`
|
||||||
|
MedalColorEnd int64 `json:"medal_color_end"`
|
||||||
|
MedalColorBorder int64 `json:"medal_color_border"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type medal struct {
|
||||||
|
Uname string `json:"target_name"`
|
||||||
|
medalInfo `json:"medal_info"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type medalSlice []medal
|
||||||
|
|
||||||
|
func (m medalSlice) Len() int {
|
||||||
|
return len(m)
|
||||||
|
}
|
||||||
|
func (m medalSlice) Swap(i, j int) {
|
||||||
|
m[i], m[j] = m[j], m[i]
|
||||||
|
}
|
||||||
|
func (m medalSlice) Less(i, j int) bool {
|
||||||
|
return m[i].Level > m[j].Level
|
||||||
|
}
|
||||||
|
|
||||||
|
// vtb信息
|
||||||
|
type vtbDetail struct {
|
||||||
|
Mid int `json:"mid"`
|
||||||
|
Uname string `json:"uname"`
|
||||||
|
Video int `json:"video"`
|
||||||
|
Roomid int `json:"roomid"`
|
||||||
|
Rise int `json:"rise"`
|
||||||
|
Follower int `json:"follower"`
|
||||||
|
GuardNum int `json:"guardNum"`
|
||||||
|
AreaRank int `json:"areaRank"`
|
||||||
|
}
|
||||||
24
plugin/bilibili/util.go
Normal file
24
plugin/bilibili/util.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package bilibili
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// humanNum 格式化人数
|
||||||
|
func humanNum(res int) string {
|
||||||
|
if res/10000 != 0 {
|
||||||
|
return strconv.FormatFloat(float64(res)/10000, 'f', 2, 64) + "万"
|
||||||
|
}
|
||||||
|
return strconv.Itoa(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getrealurl 获取跳转后的链接
|
||||||
|
func getrealurl(url string) (realurl string, err error) {
|
||||||
|
data, err := http.Head(url)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
realurl = data.Request.URL.String()
|
||||||
|
return
|
||||||
|
}
|
||||||
@ -1,190 +0,0 @@
|
|||||||
// Package bilibiliparse b站视频链接解析
|
|
||||||
package bilibiliparse
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/http"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
ctrl "github.com/FloatTech/zbpctrl"
|
|
||||||
"github.com/FloatTech/zbputils/control"
|
|
||||||
"github.com/FloatTech/zbputils/ctxext"
|
|
||||||
"github.com/FloatTech/zbputils/web"
|
|
||||||
zero "github.com/wdvxdr1123/ZeroBot"
|
|
||||||
"github.com/wdvxdr1123/ZeroBot/message"
|
|
||||||
)
|
|
||||||
|
|
||||||
type result struct {
|
|
||||||
Data struct {
|
|
||||||
Bvid string `json:"bvid"`
|
|
||||||
Aid int `json:"aid"`
|
|
||||||
Copyright int `json:"copyright"`
|
|
||||||
Pic string `json:"pic"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Pubdate int `json:"pubdate"`
|
|
||||||
Ctime int `json:"ctime"`
|
|
||||||
Rights struct {
|
|
||||||
IsCooperation int `json:"is_cooperation"`
|
|
||||||
} `json:"rights"`
|
|
||||||
Owner struct {
|
|
||||||
Mid int `json:"mid"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
} `json:"owner"`
|
|
||||||
Stat struct {
|
|
||||||
Aid int `json:"aid"`
|
|
||||||
View int `json:"view"`
|
|
||||||
Danmaku int `json:"danmaku"`
|
|
||||||
Reply int `json:"reply"`
|
|
||||||
Favorite int `json:"favorite"`
|
|
||||||
Coin int `json:"coin"`
|
|
||||||
Share int `json:"share"`
|
|
||||||
Like int `json:"like"`
|
|
||||||
} `json:"stat"`
|
|
||||||
Staff []struct {
|
|
||||||
Title string `json:"title"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
Follower int `json:"follower"`
|
|
||||||
} `json:"staff"`
|
|
||||||
} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type owner struct {
|
|
||||||
Data struct {
|
|
||||||
Card struct {
|
|
||||||
Fans int `json:"fans"`
|
|
||||||
} `json:"card"`
|
|
||||||
} `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
videoapi = "https://api.bilibili.com/x/web-interface/view?"
|
|
||||||
cardapi = "http://api.bilibili.com/x/web-interface/card?"
|
|
||||||
origin = "https://www.bilibili.com/video/"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
reg = regexp.MustCompile(`https://www.bilibili.com/video/([0-9a-zA-Z]+)`)
|
|
||||||
limit = ctxext.NewLimiterManager(time.Second*10, 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
// 插件主体
|
|
||||||
func init() {
|
|
||||||
en := control.Register("bilibiliparse", &ctrl.Options[*zero.Ctx]{
|
|
||||||
DisableOnDefault: false,
|
|
||||||
Help: "b站视频链接解析\n" +
|
|
||||||
"- https://www.bilibili.com/video/BV1xx411c7BF | https://www.bilibili.com/video/av1605 | https://b23.tv/I8uzWCA | https://www.bilibili.com/video/bv1xx411c7BF",
|
|
||||||
})
|
|
||||||
en.OnRegex(`(av[0-9]+|BV[0-9a-zA-Z]{10}){1}`).SetBlock(true).Limit(limit.LimitByGroup).
|
|
||||||
Handle(func(ctx *zero.Ctx) {
|
|
||||||
if strings.Contains(ctx.MessageString(), "[CQ:forward") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
id := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
m, err := parse(id)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Send(m)
|
|
||||||
})
|
|
||||||
en.OnRegex(`https://www.bilibili.com/video/([0-9a-zA-Z]+)`).SetBlock(true).Limit(limit.LimitByGroup).
|
|
||||||
Handle(func(ctx *zero.Ctx) {
|
|
||||||
id := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
m, err := parse(id)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Send(m)
|
|
||||||
})
|
|
||||||
en.OnRegex(`(https://b23.tv/[0-9a-zA-Z]+)`).SetBlock(true).Limit(limit.LimitByGroup).
|
|
||||||
Handle(func(ctx *zero.Ctx) {
|
|
||||||
url := ctx.State["regex_matched"].([]string)[1]
|
|
||||||
realurl, err := getrealurl(url)
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m, err := parse(cuturl(realurl))
|
|
||||||
if err != nil {
|
|
||||||
ctx.SendChain(message.Text("ERROR: ", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.Send(m)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse 解析视频数据
|
|
||||||
func parse(id string) (m message.Message, err error) {
|
|
||||||
var vid string
|
|
||||||
switch id[:2] {
|
|
||||||
case "av":
|
|
||||||
vid = "aid=" + id[2:]
|
|
||||||
case "BV":
|
|
||||||
vid = "bvid=" + id
|
|
||||||
}
|
|
||||||
data, err := web.GetData(videoapi + vid)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var r result
|
|
||||||
err = json.Unmarshal(data, &r)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
m = make(message.Message, 0, 16)
|
|
||||||
m = append(m, message.Text("标题: ", r.Data.Title, "\n"))
|
|
||||||
if r.Data.Rights.IsCooperation == 1 {
|
|
||||||
for i := 0; i < len(r.Data.Staff); i++ {
|
|
||||||
m = append(m, message.Text(r.Data.Staff[i].Title, ": ", r.Data.Staff[i].Name, ", 粉丝: ", row(r.Data.Staff[i].Follower), "\n"))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
o, err := getcard(r.Data.Owner.Mid)
|
|
||||||
if err != nil {
|
|
||||||
return m, err
|
|
||||||
}
|
|
||||||
m = append(m, message.Text("UP主: ", r.Data.Owner.Name, ", 粉丝: ", row(o.Data.Card.Fans), "\n"))
|
|
||||||
}
|
|
||||||
m = append(m, message.Text("播放: ", row(r.Data.Stat.View), ", 弹幕: ", row(r.Data.Stat.Danmaku), "\n"),
|
|
||||||
message.Image(r.Data.Pic),
|
|
||||||
message.Text("\n点赞: ", row(r.Data.Stat.Like), ", 投币: ", row(r.Data.Stat.Coin), "\n收藏: ", row(r.Data.Stat.Favorite), ", 分享: ", row(r.Data.Stat.Share), "\n", origin, id))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// getrealurl 获取跳转后的链接
|
|
||||||
func getrealurl(url string) (realurl string, err error) {
|
|
||||||
data, err := http.Head(url)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
realurl = data.Request.URL.String()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// cuturl 获取aid或者bvid
|
|
||||||
func cuturl(url string) (id string) {
|
|
||||||
if !reg.MatchString(url) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return reg.FindStringSubmatch(url)[1]
|
|
||||||
}
|
|
||||||
|
|
||||||
// getcard 获取个人信息
|
|
||||||
func getcard(mid int) (o owner, err error) {
|
|
||||||
data, err := web.GetData(cardapi + "mid=" + strconv.Itoa(mid))
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
err = json.Unmarshal(data, &o)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func row(res int) string {
|
|
||||||
if res/10000 != 0 {
|
|
||||||
return strconv.FormatFloat(float64(res)/10000, 'f', 2, 64) + "万"
|
|
||||||
}
|
|
||||||
return strconv.Itoa(res)
|
|
||||||
}
|
|
||||||
@ -12,6 +12,7 @@ import (
|
|||||||
|
|
||||||
// mo 摸
|
// mo 摸
|
||||||
func mo(cc *context, value ...string) (string, error) {
|
func mo(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -48,6 +49,7 @@ func mo(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// cuo 搓
|
// cuo 搓
|
||||||
func cuo(cc *context, value ...string) (string, error) {
|
func cuo(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -88,6 +90,7 @@ func cuo(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// qiao 敲
|
// qiao 敲
|
||||||
func qiao(cc *context, value ...string) (string, error) {
|
func qiao(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -121,6 +124,7 @@ func qiao(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// chi 吃
|
// chi 吃
|
||||||
func chi(cc *context, value ...string) (string, error) {
|
func chi(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -155,6 +159,7 @@ func chi(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// ceng 蹭
|
// ceng 蹭
|
||||||
func ceng(cc *context, value ...string) (string, error) {
|
func ceng(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -196,6 +201,7 @@ func ceng(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// ken 啃
|
// ken 啃
|
||||||
func ken(cc *context, value ...string) (string, error) {
|
func ken(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -243,6 +249,7 @@ func ken(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// pai 拍
|
// pai 拍
|
||||||
func pai(cc *context, value ...string) (string, error) {
|
func pai(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -276,6 +283,7 @@ func pai(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// xqe 冲
|
// xqe 冲
|
||||||
func xqe(cc *context, value ...string) (string, error) {
|
func xqe(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -309,6 +317,7 @@ func xqe(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// diu 丢
|
// diu 丢
|
||||||
func diu(cc *context, value ...string) (string, error) {
|
func diu(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -348,6 +357,7 @@ func diu(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// kiss 亲
|
// kiss 亲
|
||||||
func kiss(cc *context, value ...string) (string, error) {
|
func kiss(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -386,6 +396,7 @@ func kiss(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// garbage 垃圾 垃圾桶
|
// garbage 垃圾 垃圾桶
|
||||||
func garbage(cc *context, value ...string) (string, error) {
|
func garbage(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -418,6 +429,7 @@ func garbage(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// thump 捶
|
// thump 捶
|
||||||
func thump(cc *context, value ...string) (string, error) {
|
func thump(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -450,6 +462,7 @@ func thump(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// jiujiu 啾啾
|
// jiujiu 啾啾
|
||||||
func jiujiu(cc *context, value ...string) (string, error) {
|
func jiujiu(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -481,6 +494,7 @@ func jiujiu(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// knock 2敲
|
// knock 2敲
|
||||||
func knock(cc *context, value ...string) (string, error) {
|
func knock(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -513,6 +527,7 @@ func knock(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// 听音乐 listenMusic
|
// 听音乐 listenMusic
|
||||||
func listenMusic(cc *context, value ...string) (string, error) {
|
func listenMusic(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -544,6 +559,7 @@ func listenMusic(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// loveYou 永远爱你
|
// loveYou 永远爱你
|
||||||
func loveYou(cc *context, value ...string) (string, error) {
|
func loveYou(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -576,6 +592,7 @@ func loveYou(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// pat 2拍
|
// pat 2拍
|
||||||
func pat(cc *context, value ...string) (string, error) {
|
func pat(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -617,6 +634,7 @@ func pat(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// jackUp 顶
|
// jackUp 顶
|
||||||
func jackUp(cc *context, value ...string) (string, error) {
|
func jackUp(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -659,6 +677,7 @@ func jackUp(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// pound 捣
|
// pound 捣
|
||||||
func pound(cc *context, value ...string) (string, error) {
|
func pound(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -691,6 +710,7 @@ func pound(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// punch 打拳
|
// punch 打拳
|
||||||
func punch(cc *context, value ...string) (string, error) {
|
func punch(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -723,6 +743,7 @@ func punch(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// roll 滚
|
// roll 滚
|
||||||
func roll(cc *context, value ...string) (string, error) {
|
func roll(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -755,6 +776,7 @@ func roll(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// suck 吸 嗦
|
// suck 吸 嗦
|
||||||
func suck(cc *context, value ...string) (string, error) {
|
func suck(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -787,6 +809,7 @@ func suck(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// hammer 锤
|
// hammer 锤
|
||||||
func hammer(cc *context, value ...string) (string, error) {
|
func hammer(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -819,6 +842,7 @@ func hammer(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// tightly 紧贴 紧紧贴着
|
// tightly 紧贴 紧紧贴着
|
||||||
func tightly(cc *context, value ...string) (string, error) {
|
func tightly(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var err error
|
var err error
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
@ -851,6 +875,7 @@ func tightly(cc *context, value ...string) (string, error) {
|
|||||||
|
|
||||||
// turn 转
|
// turn 转
|
||||||
func turn(cc *context, value ...string) (string, error) {
|
func turn(cc *context, value ...string) (string, error) {
|
||||||
|
_ = value
|
||||||
name := cc.usrdir + "Turn.gif"
|
name := cc.usrdir + "Turn.gif"
|
||||||
face, err := cc.getLogo(0, 0)
|
face, err := cc.getLogo(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import (
|
|||||||
|
|
||||||
// pa 爬
|
// pa 爬
|
||||||
func pa(cc *context, args ...string) (string, error) {
|
func pa(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "爬.png"
|
name := cc.usrdir + "爬.png"
|
||||||
tou, err := cc.getLogo(0, 0)
|
tou, err := cc.getLogo(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -43,6 +44,7 @@ func pa(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// si 撕
|
// si 撕
|
||||||
func si(cc *context, args ...string) (string, error) {
|
func si(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "撕.png"
|
name := cc.usrdir + "撕.png"
|
||||||
tou, err := cc.getLogo(0, 0)
|
tou, err := cc.getLogo(0, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -69,6 +71,7 @@ func si(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// flipV 上翻,下翻
|
// flipV 上翻,下翻
|
||||||
func flipV(cc *context, args ...string) (string, error) {
|
func flipV(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "FlipV.png"
|
name := cc.usrdir + "FlipV.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -81,6 +84,7 @@ func flipV(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// flipH 左翻,右翻
|
// flipH 左翻,右翻
|
||||||
func flipH(cc *context, args ...string) (string, error) {
|
func flipH(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "FlipH.png"
|
name := cc.usrdir + "FlipH.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -93,6 +97,7 @@ func flipH(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// invert 反色
|
// invert 反色
|
||||||
func invert(cc *context, args ...string) (string, error) {
|
func invert(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "Invert.png"
|
name := cc.usrdir + "Invert.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -105,6 +110,7 @@ func invert(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// blur 反色
|
// blur 反色
|
||||||
func blur(cc *context, args ...string) (string, error) {
|
func blur(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "Blur.png"
|
name := cc.usrdir + "Blur.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -117,6 +123,7 @@ func blur(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// grayscale 灰度
|
// grayscale 灰度
|
||||||
func grayscale(cc *context, args ...string) (string, error) {
|
func grayscale(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "Grayscale.png"
|
name := cc.usrdir + "Grayscale.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -129,6 +136,7 @@ func grayscale(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// invertAndGrayscale 负片
|
// invertAndGrayscale 负片
|
||||||
func invertAndGrayscale(cc *context, args ...string) (string, error) {
|
func invertAndGrayscale(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "InvertAndGrayscale.png"
|
name := cc.usrdir + "InvertAndGrayscale.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -141,6 +149,7 @@ func invertAndGrayscale(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// convolve3x3 浮雕
|
// convolve3x3 浮雕
|
||||||
func convolve3x3(cc *context, args ...string) (string, error) {
|
func convolve3x3(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
name := cc.usrdir + "Convolve3x3.png"
|
name := cc.usrdir + "Convolve3x3.png"
|
||||||
// 加载图片
|
// 加载图片
|
||||||
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
im, err := img.LoadFirstFrame(cc.headimgsdir[0], 0, 0)
|
||||||
@ -186,6 +195,7 @@ func deformation(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// alike 你像个xxx一样
|
// alike 你像个xxx一样
|
||||||
func alike(cc *context, args ...string) (string, error) {
|
func alike(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -213,6 +223,7 @@ func alike(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// marriage
|
// marriage
|
||||||
func marriage(cc *context, args ...string) (string, error) {
|
func marriage(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -331,6 +342,7 @@ func alwaysLike(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// decentKiss 像样的亲亲
|
// decentKiss 像样的亲亲
|
||||||
func decentKiss(cc *context, args ...string) (string, error) {
|
func decentKiss(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -358,6 +370,7 @@ func decentKiss(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// chinaFlag 国旗
|
// chinaFlag 国旗
|
||||||
func chinaFlag(cc *context, args ...string) (string, error) {
|
func chinaFlag(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -385,6 +398,7 @@ func chinaFlag(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// dontTouch 不要靠近
|
// dontTouch 不要靠近
|
||||||
func dontTouch(cc *context, args ...string) (string, error) {
|
func dontTouch(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -490,6 +504,7 @@ func interview(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// need 需要 你可能需要
|
// need 需要 你可能需要
|
||||||
func need(cc *context, args ...string) (string, error) {
|
func need(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -517,6 +532,7 @@ func need(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// paint 这像画吗
|
// paint 这像画吗
|
||||||
func paint(cc *context, args ...string) (string, error) {
|
func paint(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -544,6 +560,7 @@ func paint(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// painter 小画家
|
// painter 小画家
|
||||||
func painter(cc *context, args ...string) (string, error) {
|
func painter(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -571,6 +588,7 @@ func painter(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// perfect 完美
|
// perfect 完美
|
||||||
func perfect(cc *context, args ...string) (string, error) {
|
func perfect(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -643,6 +661,7 @@ func playGame(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// police 出警
|
// police 出警
|
||||||
func police(cc *context, args ...string) (string, error) {
|
func police(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -670,6 +689,7 @@ func police(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// police1 警察
|
// police1 警察
|
||||||
func police1(cc *context, args ...string) (string, error) {
|
func police1(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -697,6 +717,7 @@ func police1(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// prpr 舔 舔屏 prpr
|
// prpr 舔 舔屏 prpr
|
||||||
func prpr(cc *context, args ...string) (string, error) {
|
func prpr(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -771,6 +792,7 @@ func safeSense(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// support 精神支柱
|
// support 精神支柱
|
||||||
func support(cc *context, args ...string) (string, error) {
|
func support(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -798,6 +820,7 @@ func support(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// thinkwhat 想什么
|
// thinkwhat 想什么
|
||||||
func thinkwhat(cc *context, args ...string) (string, error) {
|
func thinkwhat(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -825,6 +848,7 @@ func thinkwhat(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// wallpaper 墙纸
|
// wallpaper 墙纸
|
||||||
func wallpaper(cc *context, args ...string) (string, error) {
|
func wallpaper(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -852,6 +876,7 @@ func wallpaper(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// whyatme 为什么at我
|
// whyatme 为什么at我
|
||||||
func whyatme(cc *context, args ...string) (string, error) {
|
func whyatme(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -927,6 +952,7 @@ func makeFriend(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// backToWork 打工人, 继续干活
|
// backToWork 打工人, 继续干活
|
||||||
func backToWork(cc *context, args ...string) (string, error) {
|
func backToWork(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -1004,6 +1030,7 @@ func coupon(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// distracted 注意力涣散
|
// distracted 注意力涣散
|
||||||
func distracted(cc *context, args ...string) (string, error) {
|
func distracted(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
@ -1031,6 +1058,7 @@ func distracted(cc *context, args ...string) (string, error) {
|
|||||||
|
|
||||||
// throw 扔
|
// throw 扔
|
||||||
func throw(cc *context, args ...string) (string, error) {
|
func throw(cc *context, args ...string) (string, error) {
|
||||||
|
_ = args
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
var m sync.Mutex
|
var m sync.Mutex
|
||||||
var err error
|
var err error
|
||||||
|
|||||||
@ -61,9 +61,9 @@ func init() { // 插件主体
|
|||||||
"Star/Fork/Issue: ",
|
"Star/Fork/Issue: ",
|
||||||
repo.Get("watchers").Int(), "/", repo.Get("forks").Int(), "/", repo.Get("open_issues").Int(), "\n",
|
repo.Get("watchers").Int(), "/", repo.Get("forks").Int(), "/", repo.Get("open_issues").Int(), "\n",
|
||||||
"Language: ",
|
"Language: ",
|
||||||
notnull(repo.Get("language").Str, "None"), "\n",
|
notnull(repo.Get("language").Str), "\n",
|
||||||
"License: ",
|
"License: ",
|
||||||
notnull(strings.ToUpper(repo.Get("license.key").Str), "None"), "\n",
|
notnull(strings.ToUpper(repo.Get("license.key").Str)), "\n",
|
||||||
"Last pushed: ",
|
"Last pushed: ",
|
||||||
repo.Get("pushed_at").Str, "\n",
|
repo.Get("pushed_at").Str, "\n",
|
||||||
"Jump: ",
|
"Jump: ",
|
||||||
@ -79,9 +79,9 @@ func init() { // 插件主体
|
|||||||
"Star/Fork/Issue: ",
|
"Star/Fork/Issue: ",
|
||||||
repo.Get("watchers").Int(), "/", repo.Get("forks").Int(), "/", repo.Get("open_issues").Int(), "\n",
|
repo.Get("watchers").Int(), "/", repo.Get("forks").Int(), "/", repo.Get("open_issues").Int(), "\n",
|
||||||
"Language: ",
|
"Language: ",
|
||||||
notnull(repo.Get("language").Str, "None"), "\n",
|
notnull(repo.Get("language").Str), "\n",
|
||||||
"License: ",
|
"License: ",
|
||||||
notnull(strings.ToUpper(repo.Get("license.key").Str), "None"), "\n",
|
notnull(strings.ToUpper(repo.Get("license.key").Str)), "\n",
|
||||||
"Last pushed: ",
|
"Last pushed: ",
|
||||||
repo.Get("pushed_at").Str, "\n",
|
repo.Get("pushed_at").Str, "\n",
|
||||||
"Jump: ",
|
"Jump: ",
|
||||||
@ -97,9 +97,9 @@ func init() { // 插件主体
|
|||||||
|
|
||||||
// notnull 如果传入文本为空,则返回默认值
|
// notnull 如果传入文本为空,则返回默认值
|
||||||
|
|
||||||
func notnull(text, defstr string) string {
|
func notnull(text string) string {
|
||||||
if text == "" {
|
if text == "" {
|
||||||
return defstr
|
return "None"
|
||||||
}
|
}
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user