mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 22:00:11 +08:00
299 lines
10 KiB
Go
299 lines
10 KiB
Go
// Package vtbquotation vtb经典语录
|
||
package vtbquotation
|
||
|
||
import (
|
||
"fmt"
|
||
"io"
|
||
"net/http"
|
||
"net/url"
|
||
"os"
|
||
"path"
|
||
"regexp"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
_ "github.com/fumiama/sqlite3" // use sql
|
||
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/vtb_quotation/model"
|
||
)
|
||
|
||
var reg = regexp.MustCompile(".*/(.*)")
|
||
|
||
func init() {
|
||
engine := control.Register("vtbquotation", &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
|
||
}
|