diff --git a/README.md b/README.md index 9c8f4c95fb..f38d0c856a 100644 --- a/README.md +++ b/README.md @@ -1272,16 +1272,6 @@ print("run[CQ:image,file="+j["img"]+"]") - [x] 更新vtb - -
- vtb点歌 - - `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbmusic"` - - - [x] vtb点歌 - - - [x] vtb随机点歌 -
钱包 diff --git a/main.go b/main.go index 5e95c10365..e0dbf38203 100644 --- a/main.go +++ b/main.go @@ -131,8 +131,6 @@ import ( _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tracemoe" // 搜番 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vitsnyaru" // vits猫雷 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbmusic" // vtb点歌 - _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbquotation" // vtb语录 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet" // 钱包 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wantquotes" // 据意查句 _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" // warframeAPI插件 diff --git a/plugin/vtbmusic/vtbmusic.go b/plugin/vtbmusic/vtbmusic.go deleted file mode 100644 index 835ff56738..0000000000 --- a/plugin/vtbmusic/vtbmusic.go +++ /dev/null @@ -1,321 +0,0 @@ -// Package vtbmusic vtb点歌 -package vtbmusic - -import ( - "encoding/json" - "fmt" - "math/rand" - "net/http" - "os" - "path" - "strconv" - "strings" - "time" - - "github.com/FloatTech/floatbox/binary" - "github.com/FloatTech/floatbox/file" - "github.com/FloatTech/floatbox/web" - ctrl "github.com/FloatTech/zbpctrl" - "github.com/FloatTech/zbputils/control" - "github.com/FloatTech/zbputils/img/text" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -const ( - getGroupListURL = "https://aqua.chat/v1/GetGroupsList" - getMusicListURL = "https://aqua.chat/v1/GetMusicList" - fileURL = "https://cdn.aqua.chat/" - musicListBody = `{"search":{"condition":"VocalId","keyword":"%v"},"sortField":"CreateTime","sortType":"desc","pageIndex":1,"pageRows":10000}` -) - -type groupsList struct { - Total int `json:"Total"` - Data []struct { - ID string `json:"Id"` - CreateTime string `json:"CreateTime"` - Name string `json:"Name"` - GroupImg string `json:"GroupImg"` - VocalList []struct { - ID string `json:"Id"` - CreateTime string `json:"CreateTime"` - ChineseName string `json:"ChineseName"` - OriginName string `json:"OriginName"` - AvatarImg string `json:"AvatarImg"` - } `json:"VocalList"` - } `json:"Data"` - Success bool `json:"Success"` - ErrorCode int `json:"ErrorCode"` - Msg interface{} `json:"Msg"` -} - -type musicList struct { - Total int `json:"Total"` - Data []struct { - ID string `json:"Id"` - CreateTime string `json:"CreateTime"` - PublishTime interface{} `json:"PublishTime"` - CreatorID interface{} `json:"CreatorId"` - CreatorRealName interface{} `json:"CreatorRealName"` - Deleted bool `json:"Deleted"` - OriginName string `json:"OriginName"` - VocalID string `json:"VocalId"` - VocalName string `json:"VocalName"` - CoverImg string `json:"CoverImg"` - Music string `json:"Music"` - Lyric interface{} `json:"Lyric"` - CDN string `json:"CDN"` - BiliBili interface{} `json:"BiliBili"` - YouTube interface{} `json:"YouTube"` - Twitter interface{} `json:"Twitter"` - Likes interface{} `json:"Likes"` - Length float64 `json:"Length"` - Label interface{} `json:"Label"` - IsLike bool `json:"isLike"` - Duration float64 `json:"Duration"` - Source interface{} `json:"Source"` - SourceName interface{} `json:"SourceName"` - Statis struct { - PlayCount int `json:"PlayCount"` - CommentCount int `json:"CommentCount"` - LikeCount int `json:"LikeCount"` - ShareCount int `json:"ShareCount"` - } `json:"Statis"` - VocalList []struct { - ID string `json:"Id"` - Cn string `json:"cn"` - Jp string `json:"jp"` - En string `json:"en"` - Originlang string `json:"originlang"` - } `json:"VocalList"` - } `json:"Data"` - Success bool `json:"Success"` - ErrorCode int `json:"ErrorCode"` - Msg interface{} `json:"Msg"` -} - -func init() { // 插件主体 - engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{ - DisableOnDefault: false, - Brief: "vtbmusic.com点歌", - Help: "- vtb点歌\n" + - "- vtb随机点歌", - PrivateDataFolder: "vtbmusic", - }) - storePath := engine.DataFolder() - // 开启 - engine.OnFullMatch(`vtb点歌`).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession(), zero.RegexRule(`^\d+$`)) - recv, cancel := next.Repeat() - defer cancel() - i := 0 - paras := [3]int{} - data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`)) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - var ( - gl groupsList - ml musicList - num int - imageBytes []byte - ) - err = json.Unmarshal(data, &gl) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - tex := "请输入群组序号\n" - for i, v := range gl.Data { - tex += fmt.Sprintf("%d. %s\n", i, v.Name) - } - imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - for { - select { - case <-time.After(time.Second * 120): - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb点歌超时")) - return - case c := <-recv: - msg := c.Event.Message.ExtractPlainText() - num, err = strconv.Atoi(msg) - if err != nil { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请输入数字!")) - continue - } - switch i { - case 0: - if num < 0 || num >= len(gl.Data) { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!")) - continue - } - if len(gl.Data[num].VocalList) == 0 { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败")) - return - } - paras[0] = num - tex = "请输入vtb序号\n" - for i, v := range gl.Data[paras[0]].VocalList { - tex += fmt.Sprintf("%d. %s\n", i, v.OriginName) - } - imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - case 1: - if num < 0 || num >= len(gl.Data[paras[0]].VocalList) { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!")) - continue - } - paras[1] = num - data, err := web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID))) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - err = json.Unmarshal(data, &ml) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if len(ml.Data) == 0 { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败")) - return - } - tex = "请输入歌曲序号\n" - for i, v := range ml.Data { - tex += fmt.Sprintf("%d. %s\n", i, v.OriginName) - } - imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - case 2: - if num < 0 || num >= len(ml.Data) { - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!")) - continue - } - paras[2] = num - // 最后播放歌曲 - groupName := gl.Data[paras[0]].Name - vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName - musicName := ml.Data[paras[2]].OriginName - recURL := fileURL + ml.Data[paras[2]].Music - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》")) - recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL) - if file.IsExist(recordFile) { - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - err = dlrec(recordFile, recURL) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - i++ - } - } - }) - engine.OnFullMatch(`vtb随机点歌`).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - var ( - paras = [3]int{} - gl groupsList - ml musicList - ) - data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`)) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - err = json.Unmarshal(data, &gl) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if len(gl.Data) == 0 { - ctx.SendChain(message.Text("ERROR: 数组为空")) - return - } - paras[0] = rand.Intn(len(gl.Data)) - for len(gl.Data[paras[0]].VocalList) == 0 { - paras[0] = rand.Intn(len(gl.Data)) - } - paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList)) - data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID))) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - err = json.Unmarshal(data, &ml) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - for len(ml.Data) == 0 { - paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList)) - data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID))) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - err = json.Unmarshal(data, &ml) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - } - paras[2] = rand.Intn(len(ml.Data)) - // 最后播放歌曲 - groupName := gl.Data[paras[0]].Name - vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName - musicName := ml.Data[paras[2]].OriginName - recURL := fileURL + ml.Data[paras[2]].Music - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》")) - recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL) - if file.IsExist(recordFile) { - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - err = dlrec(recordFile, recURL) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - }) -} - -func dlrec(recordFile, recordURL string) error { - if file.IsNotExist(recordFile) { - data, err := web.RequestDataWithHeaders(web.NewTLS12Client(), recordURL, "GET", func(r *http.Request) error { - r.Header.Set("Content-Type", "application/x-www-form-urlencoded") - r.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0") - return nil - }, nil) - if err != nil { - return err - } - return os.WriteFile(recordFile, data, 0666) - } - return nil -} diff --git a/plugin/vtbquotation/model/model.go b/plugin/vtbquotation/model/model.go deleted file mode 100644 index 01b86c727f..0000000000 --- a/plugin/vtbquotation/model/model.go +++ /dev/null @@ -1,325 +0,0 @@ -// Package model vtb数据库操作 -package model - -import ( - "io" - "math/rand" - "net/http" - "os" - "strconv" - "strings" - - "github.com/FloatTech/floatbox/web" - "github.com/jinzhu/gorm" - log "github.com/sirupsen/logrus" - "github.com/tidwall/gjson" -) - -// VtbDB vtb 数据库 -type VtbDB gorm.DB - -// Initialize ... -func Initialize(dbpath string) *VtbDB { - var err error - if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) { - // 生成文件 - f, err := os.Create(dbpath) - if err != nil { - return nil - } - defer f.Close() - } - gdb, err := gorm.Open("sqlite3", dbpath) - if err != nil { - panic(err) - } - gdb.AutoMigrate(FirstCategory{}).AutoMigrate(SecondCategory{}).AutoMigrate(ThirdCategory{}) - return (*VtbDB)(gdb) -} - -// Open ... -func Open(dbpath string) (*VtbDB, error) { - db, err := gorm.Open("sqlite3", dbpath) - if err != nil { - return nil, err - } - return (*VtbDB)(db), nil -} - -// FirstCategory 第一品类 -type FirstCategory struct { - gorm.Model - FirstCategoryIndex int64 `gorm:"column:first_category_index"` - FirstCategoryName string `gorm:"column:first_category_name"` - FirstCategoryUID string `gorm:"column:first_category_uid"` - FirstCategoryDescription string `gorm:"column:first_category_description;type:varchar(1024)"` - FirstCategoryIconPath string `gorm:"column:first_category_icon_path"` -} - -// TableName ... -func (FirstCategory) TableName() string { - return "first_category" -} - -// SecondCategory 第二品类 -type SecondCategory struct { - gorm.Model - SecondCategoryIndex int64 `gorm:"column:second_category_index"` - FirstCategoryUID string `gorm:"column:first_category_uid;association_foreignkey:first_category_uid"` - SecondCategoryName string `gorm:"column:second_category_name"` - SecondCategoryAuthor string `gorm:"column:second_category_author"` - SecondCategoryDescription string `gorm:"column:second_category_description"` -} - -// TableName ... -func (SecondCategory) TableName() string { - return "second_category" -} - -// ThirdCategory 第三品类 -type ThirdCategory struct { - gorm.Model - ThirdCategoryIndex int64 `gorm:"column:third_category_index"` - SecondCategoryIndex int64 `gorm:"column:second_category_index"` - FirstCategoryUID string `gorm:"column:first_category_uid"` - ThirdCategoryName string `gorm:"column:third_category_name"` - ThirdCategoryPath string `gorm:"column:third_category_path"` - ThirdCategoryAuthor string `gorm:"column:third_category_author"` - ThirdCategoryDescription string `gorm:"column:third_category_description"` -} - -// TableName ... -func (ThirdCategory) TableName() string { - return "third_category" -} - -// GetAllFirstCategoryMessage 取出所有vtb -func (vdb *VtbDB) GetAllFirstCategoryMessage() (string, error) { - db := (*gorm.DB)(vdb) - firstStepMessage := "请选择一个vtb并发送序号:\n" - var fcl []FirstCategory - err := db.Model(&FirstCategory{}).Find(&fcl).Error - if err != nil { - return "", err - } - for _, v := range fcl { - firstStepMessage += strconv.FormatInt(v.FirstCategoryIndex, 10) + ". " + v.FirstCategoryName + "\n" - } - return firstStepMessage, nil -} - -// GetAllSecondCategoryMessageByFirstIndex 取得同一个vtb所有语录类别 -func (vdb *VtbDB) GetAllSecondCategoryMessageByFirstIndex(firstIndex int) (string, error) { - db := (*gorm.DB)(vdb) - secondStepMessage := "请选择一个语录类别并发送序号:\n" - var scl []SecondCategory - var fc FirstCategory - db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) - err := db.Model(&SecondCategory{}).Find(&scl, "first_category_uid = ?", fc.FirstCategoryUID).Error - if err != nil || len(scl) == 0 { - return "", err - } - for _, v := range scl { - secondStepMessage += strconv.FormatInt(v.SecondCategoryIndex, 10) + ". " + v.SecondCategoryName + "\n" - } - return secondStepMessage, nil -} - -// GetAllThirdCategoryMessageByFirstIndexAndSecondIndex 取得同一个vtb同个类别的所有语录 -func (vdb *VtbDB) GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex int) (string, error) { - db := (*gorm.DB)(vdb) - thirdStepMessage := "请选择一个语录并发送序号:\n" - var fc FirstCategory - db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) - var tcl []ThirdCategory - err := db.Model(&ThirdCategory{}).Find(&tcl, "first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUID, secondIndex).Error - if err != nil || len(tcl) == 0 { - return "", err - } - for _, v := range tcl { - thirdStepMessage = thirdStepMessage + strconv.FormatInt(v.ThirdCategoryIndex, 10) + ". " + v.ThirdCategoryName + "\n" - } - return thirdStepMessage, nil -} - -// GetThirdCategory ... -func (vdb *VtbDB) GetThirdCategory(firstIndex, secondIndex, thirdIndex int) ThirdCategory { - db := (*gorm.DB)(vdb) - var fc FirstCategory - db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc) - var tc ThirdCategory - db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", fc.FirstCategoryUID, secondIndex, thirdIndex).Take(&tc) - return tc -} - -// RandomVtb ... -func (vdb *VtbDB) RandomVtb() ThirdCategory { - db := (*gorm.DB)(vdb) - var count int - var tc ThirdCategory - db.Model(&ThirdCategory{}).Count(&count).Offset(rand.Intn(count)).Take(&tc) - return tc -} - -// GetFirstCategoryByFirstUID ... -func (vdb *VtbDB) GetFirstCategoryByFirstUID(firstUID string) FirstCategory { - db := (*gorm.DB)(vdb) - var fc FirstCategory - db.Model(FirstCategory{}).Take(&fc, "first_category_uid = ?", firstUID) - return fc -} - -// Close ... -func (vdb *VtbDB) Close() error { - db := (*gorm.DB)(vdb) - return db.Close() -} - -const vtbURL = "https://vtbkeyboard.moe/api/get_vtb_list" - -// GetVtbList ... -func (vdb *VtbDB) GetVtbList() (uidList []string, err error) { - db := (*gorm.DB)(vdb) - client := &http.Client{} - req, err := http.NewRequest("GET", vtbURL, nil) - if err != nil { - return - } - // 自定义Header - req.Header.Set("User-Agent", web.RandUA()) - resp, err := client.Do(req) - if err != nil { - return - } - - defer resp.Body.Close() - bytes, err := io.ReadAll(resp.Body) - if err != nil { - return - } - - vtbListStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`)) - if err != nil { - return - } - - count := gjson.Get(vtbListStr, "#").Int() - for i := int64(0); i < count; i++ { - item := gjson.Get(vtbListStr, strconv.FormatInt(i, 10)) - log.Debugln(item) - fc := FirstCategory{ - FirstCategoryIndex: i, - FirstCategoryName: item.Get("name").String(), - FirstCategoryDescription: item.Get("description").String(), - FirstCategoryIconPath: item.Get("icon_path").String(), - FirstCategoryUID: item.Get("uid").String(), - } - log.Debugln(fc) - - if err := db.Model(&FirstCategory{}).First(&fc, "first_category_uid = ?", fc.FirstCategoryUID).Error; err != nil { - if gorm.IsRecordNotFoundError(err) { - db.Model(&FirstCategory{}).Create(&fc) // newUser not user - } - } else { - db.Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUID).Update( - map[string]any{ - "first_category_index": i, - "first_category_name": item.Get("name").String(), - "first_category_description": item.Get("description").String(), - "first_category_icon_path": item.Get("icon_path").String(), - }) - } - uidList = append(uidList, fc.FirstCategoryUID) - } - - return -} - -// StoreVtb ... -func (vdb *VtbDB) StoreVtb(uid string) (err error) { - db := (*gorm.DB)(vdb) - vtbURL := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid - client := &http.Client{} - req, err := http.NewRequest("GET", vtbURL, nil) - if err != nil { - return - } - // 自定义Header - req.Header.Set("User-Agent", web.RandUA()) - resp, err := client.Do(req) - if err != nil { - return - } - - defer resp.Body.Close() - bytes, err := io.ReadAll(resp.Body) - if err != nil { - return - } - - vtbStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`)) - if err != nil { - return - } - - secondCount := gjson.Get(vtbStr, "data.voices.#").Int() - log.Debugln("二级品类一共有", secondCount) - for secondIndex := int64(0); secondIndex < secondCount; secondIndex++ { - secondItem := gjson.Get(vtbStr, "data.voices."+strconv.FormatInt(secondIndex, 10)) - log.Debugln(secondItem) - sc := SecondCategory{ - SecondCategoryName: secondItem.Get("categoryName").String(), - SecondCategoryIndex: secondIndex, - SecondCategoryAuthor: secondItem.Get("author").String(), - SecondCategoryDescription: secondItem.Get("categoryDescription.zh-CN").String(), - FirstCategoryUID: uid, - } - - if err := db.Model(&SecondCategory{}).First(&sc, "first_category_uid = ? and second_category_index = ?", uid, secondIndex).Error; err != nil { - // error handling... - if gorm.IsRecordNotFoundError(err) { - db.Model(&SecondCategory{}).Create(&sc) // newUser not user - } - } else { - db.Model(&SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).Update( - map[string]any{ - "second_category_name": secondItem.Get("categoryName").String(), - "second_category_author": secondItem.Get("author").String(), - "second_category_description": secondItem.Get("categoryDescription.zh-CN").String(), - }) - } - thirdCount := secondItem.Get("voiceList.#").Int() - log.Debugln("三级品类一共有", thirdCount) - for thirdIndex := int64(0); thirdIndex < thirdCount; thirdIndex++ { - thirdItem := secondItem.Get("voiceList." + strconv.FormatInt(thirdIndex, 10)) - log.Debugln(thirdItem) - tc := ThirdCategory{ - ThirdCategoryName: thirdItem.Get("name").String(), - ThirdCategoryIndex: thirdIndex, - ThirdCategoryDescription: thirdItem.Get("description.zh-CN").String(), - FirstCategoryUID: uid, - SecondCategoryIndex: secondIndex, - ThirdCategoryPath: thirdItem.Get("path").String(), - ThirdCategoryAuthor: thirdItem.Get("author").String(), - } - log.Debugln(tc) - - if err := db.Model(&ThirdCategory{}).First(&tc, "first_category_uid = ? and second_category_index = ? and third_category_index = ?", - uid, secondIndex, thirdIndex).Error; err != nil { - if gorm.IsRecordNotFoundError(err) { - db.Model(&ThirdCategory{}).Create(&tc) // newUser not user - } - } else { - db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", - uid, secondIndex, thirdIndex).Update( - map[string]any{ - "third_category_name": thirdItem.Get("name").String(), - "third_category_description": thirdItem.Get("description.zh-CN").String(), - "third_category_path": thirdItem.Get("path").String(), - "third_category_author": thirdItem.Get("author").String(), - }) - } - } - } - return -} diff --git a/plugin/vtbquotation/vtb_quotation.go b/plugin/vtbquotation/vtb_quotation.go deleted file mode 100644 index 4aa3e6b720..0000000000 --- a/plugin/vtbquotation/vtb_quotation.go +++ /dev/null @@ -1,297 +0,0 @@ -// Package vtbquotation vtb经典语录 -package vtbquotation - -import ( - "fmt" - "io" - "net/http" - "net/url" - "os" - "path" - "regexp" - "strconv" - "strings" - "time" - - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" - "github.com/wdvxdr1123/ZeroBot/utils/helper" - - fcext "github.com/FloatTech/floatbox/ctxext" - "github.com/FloatTech/floatbox/file" - "github.com/FloatTech/floatbox/web" - ctrl "github.com/FloatTech/zbpctrl" - "github.com/FloatTech/zbputils/control" - "github.com/FloatTech/zbputils/img/text" - - "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbquotation/model" -) - -var reg = regexp.MustCompile(".*/(.*)") - -func init() { - engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{ - DisableOnDefault: false, - Brief: "vtb语录", - Help: "- vtb语录\n- 随机vtb\n- 更新vtb\n来源: vtbkeyboard.moe", - PublicDataFolder: "VtbQuotation", - }) - dbfile := engine.DataFolder() + "vtb.db" - storePath := engine.DataFolder() + "store/" - getdb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool { - err := os.MkdirAll(storePath, 0755) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return false - } - _, err = engine.GetLazyData("vtb.db", false) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return false - } - return true - }) - - engine.OnFullMatch("vtb语录", getdb).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - indexs := [3]int{} - echo, cancel := ctx.FutureEvent("message", - ctx.CheckSession()). // 只复读开启复读模式的人的消息 - Repeat() // 不断监听复读 - db, err := model.Open(dbfile) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - defer db.Close() - defer cancel() - r, err := db.GetAllFirstCategoryMessage() - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - // 步骤0,1,2,依次选择3个类别 - step := 0 - // 错误次数 - errorCount := 0 - for { - select { - case c := <-echo: // 接收到需要复读的消息 - // 错误次数达到3次,结束命令 - if errorCount >= 3 { - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("输入错误太多,请重新发指令")) - return - } - msg := c.Event.Message.ExtractPlainText() - num, err := strconv.Atoi(msg) - if err != nil { - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输")) - errorCount++ - continue - } - switch step { - case 0: - indexs[0] = num - secondStepMessage, err := db.GetAllSecondCategoryMessageByFirstIndex(indexs[0]) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if secondStepMessage == "" { - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输")) - r, err := db.GetAllFirstCategoryMessage() - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - errorCount++ - } else { - secondStepMessageBytes, err := text.RenderToBase64(secondStepMessage, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - step++ - } - - case 1: - indexs[1] = num - thirdStepMessage, err := db.GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(indexs[0], indexs[1]) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if thirdStepMessage == "" { - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输")) - r, err := db.GetAllSecondCategoryMessageByFirstIndex(indexs[0]) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - secondStepMessageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - errorCount++ - } else { - thirdStepMessageBytes, err := text.RenderToBase64(thirdStepMessage, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(thirdStepMessageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - step++ - } - case 2: - indexs[2] = num - tc := db.GetThirdCategory(indexs[0], indexs[1], indexs[2]) - recURL := tc.ThirdCategoryPath - if recURL == "" { - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("没有内容请重新选择,三次输入错误,指令可退出重输")) - r, err := db.GetAllFirstCategoryMessage() - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 { - ctx.SendChain(message.Text("ERROR: 可能被风控了")) - } - errorCount++ - step = 1 - } else { - if reg.MatchString(recURL) { - recURL = strings.ReplaceAll(recURL, reg.FindStringSubmatch(recURL)[1], url.QueryEscape(reg.FindStringSubmatch(recURL)[1])) - recURL = strings.ReplaceAll(recURL, "+", "%20") - } - ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("请欣赏《"+tc.ThirdCategoryName+"》")) - recordFile := storePath + fmt.Sprintf("%d-%d-%d", indexs[0], indexs[1], indexs[2]) + path.Ext(recURL) - if file.IsExist(recordFile) { - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - err = initRecord(recordFile, recURL) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - default: - return - } - case <-time.After(time.Second * 60): - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb语录指令过期")) - return - } - } - }) - engine.OnFullMatch("随机vtb", getdb).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - db, err := model.Open(dbfile) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - defer db.Close() - tc := db.RandomVtb() - fc := db.GetFirstCategoryByFirstUID(tc.FirstCategoryUID) - if (tc != model.ThirdCategory{}) && (fc != model.FirstCategory{}) { - recURL := tc.ThirdCategoryPath - if reg.MatchString(recURL) { - recURL = strings.ReplaceAll(recURL, reg.FindStringSubmatch(recURL)[1], url.QueryEscape(reg.FindStringSubmatch(recURL)[1])) - recURL = strings.ReplaceAll(recURL, "+", "%20") - } - ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏"+fc.FirstCategoryName+"的《"+tc.ThirdCategoryName+"》")) - recordFile := storePath + fmt.Sprintf("%d-%d-%d", fc.FirstCategoryIndex, tc.SecondCategoryIndex, tc.ThirdCategoryIndex) + path.Ext(recURL) - if file.IsExist(recordFile) { - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - return - } - err = initRecord(recordFile, recURL) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile)) - } - }) - engine.OnFullMatch("更新vtb", zero.SuperUserPermission, getdb).SetBlock(true). - Handle(func(ctx *zero.Ctx) { - ctx.Send("少女祈祷中......") - db := model.Initialize(dbfile) - if db != nil { - vl, err := db.GetVtbList() - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - for _, v := range vl { - err = db.StoreVtb(v) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - } - err = db.Close() - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - } - ctx.Send("vtb数据库已更新") - }) -} - -func initRecord(recordFile, recordURL string) error { - if file.IsNotExist(recordFile) { - client := web.NewTLS12Client() - req, _ := http.NewRequest("GET", recordURL, nil) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0") - resp, err := client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - data, err := io.ReadAll(resp.Body) - if err != nil { - return err - } - err = os.WriteFile(recordFile, data, 0666) - if err != nil { - return err - } - } - return nil -}