From 7ca9f2158b410730c359e1b71ef165ca68dc613e Mon Sep 17 00:00:00 2001 From: Yiwen-Chan Date: Sat, 19 Jun 2021 20:08:45 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=F0=9F=8E=A8=E2=9A=A1=EF=B8=8F=20?= =?UTF-8?q?=E9=87=8D=E5=A4=A7=E9=87=8D=E6=9E=84=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 +- api/context/pic.go | 59 --- api/msgext/msgext.go | 26 -- api/pixiv/download.go | 92 ----- api/pixiv/pixiv_api.go | 137 ------- api/utils/utils.go | 73 ---- build_arm.sh | 5 - build_mips.sh | 7 - chat/learn.go | 343 ------------------ github/repo_searcher.go | 3 +- go.mod | 15 +- go.sum | 90 ++++- huahua/huahua.go | 210 ----------- main.go | 49 +-- manager/manager.go | 65 ++-- music/music_selecter.go | 3 + picsearcher/pic_searcher.go | 91 ----- picsearcher/utils/ascii2d.go | 99 ----- picsearcher/utils/saucenao.go | 77 ---- run.bat | 2 +- build.bat => run.sh | 5 +- runcode/code_runner.go | 6 +- {api/classify => setutime}/classify.go | 8 +- setutime/pic_searcher.go | 167 +++++++++ .../setu_geter.go => setutime/rand_image.go | 20 +- setutime/setu_geter.go | 238 +++++++----- setutime/{utils => }/sqlite.go | 6 +- setutime/utils/pic_pool.go | 73 ---- setutime/utils/switch.go | 5 - shindan/shindan.go | 153 ++------ 30 files changed, 520 insertions(+), 1612 deletions(-) delete mode 100644 api/context/pic.go delete mode 100644 api/msgext/msgext.go delete mode 100644 api/pixiv/download.go delete mode 100644 api/pixiv/pixiv_api.go delete mode 100644 api/utils/utils.go delete mode 100755 build_arm.sh delete mode 100755 build_mips.sh delete mode 100644 chat/learn.go delete mode 100644 huahua/huahua.go delete mode 100644 picsearcher/pic_searcher.go delete mode 100644 picsearcher/utils/ascii2d.go delete mode 100644 picsearcher/utils/saucenao.go rename build.bat => run.sh (57%) rename {api/classify => setutime}/classify.go (95%) create mode 100644 setutime/pic_searcher.go rename randimg/setu_geter.go => setutime/rand_image.go (74%) rename setutime/{utils => }/sqlite.go (98%) delete mode 100644 setutime/utils/pic_pool.go delete mode 100644 setutime/utils/switch.go diff --git a/.gitignore b/.gitignore index e54b5208..53e4b26e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,2 @@ -data/chat data/SetuTime/cache -data/manager -main.exe -.DS_Store +data/SetuTime/search diff --git a/api/context/pic.go b/api/context/pic.go deleted file mode 100644 index 6cedef66..00000000 --- a/api/context/pic.go +++ /dev/null @@ -1,59 +0,0 @@ -package context - -import ( - "strconv" - "time" - - zero "github.com/wdvxdr1123/ZeroBot" -) - -// HasPicture 消息含有图片返回 true -func HasPicture() zero.Rule { - return func(ctx *zero.Ctx) bool { - msg := ctx.Event.Message - url := []string{} - // 如果是回复信息则将信息替换成被回复的那条 - if msg[0].Type == "reply" { - id, _ := strconv.Atoi(msg[0].Data["id"]) - msg = ctx.GetMessage(int64(id)).Elements - } - // 遍历信息中所有图片 - for _, elem := range msg { - if elem.Type == "image" { - url = append(url, elem.Data["url"]) - } - } - // 如果有图片就返回true - if len(url) > 0 { - ctx.State["image_url"] = url - return true - } - return false - } -} - -// MustHasPicture 消息不存在图片阻塞60秒至有图片,超时返回 false -func MustHasPicture() zero.Rule { - return func(ctx *zero.Ctx) bool { - if HasPicture()(ctx) { - return true - } - // 没有图片就索取 - ctx.Send("请发送一张图片") - next := zero.NewFutureEvent("message", 999, false, zero.CheckUser(ctx.Event.UserID), HasPicture()) - recv, cancel := next.Repeat() - select { - case e := <-recv: - cancel() - newCtx := &zero.Ctx{Event: e, State: zero.State{}} - if HasPicture()(newCtx) { - ctx.State["image_url"] = newCtx.State["image_url"] - ctx.Event.MessageID = newCtx.Event.MessageID - return true - } - return false - case <-time.After(time.Second * 60): - return false - } - } -} diff --git a/api/msgext/msgext.go b/api/msgext/msgext.go deleted file mode 100644 index b0f1dacb..00000000 --- a/api/msgext/msgext.go +++ /dev/null @@ -1,26 +0,0 @@ -package msgext - -import ( - "github.com/wdvxdr1123/ZeroBot/message" -) - -//@全体成员 -func AtAll() message.MessageSegment { - return message.MessageSegment{ - Type: "at", - Data: map[string]string{ - "qq": "all", - }, - } -} - -//无缓存发送图片 -func ImageNoCache(url string) message.MessageSegment { - return message.MessageSegment{ - Type: "image", - Data: map[string]string{ - "file": url, - "cache": "0", - }, - } -} diff --git a/api/pixiv/download.go b/api/pixiv/download.go deleted file mode 100644 index dd92a218..00000000 --- a/api/pixiv/download.go +++ /dev/null @@ -1,92 +0,0 @@ -package pixiv - -import ( - "crypto/md5" - "crypto/tls" - "errors" - "fmt" - "io/ioutil" - "net" - "net/http" - "os" - "strings" - - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/utils" -) - -// urlCache 缓存并返回缓存路径 -func (this *Illust) PixivPicDown(path string) (savePath string, err error) { - url := this.ImageUrls - pid := this.Pid - url = strings.ReplaceAll(url, "img-original", "img-master") - url = strings.ReplaceAll(url, "_p0", "_p0_master1200") - url = strings.ReplaceAll(url, ".png", ".jpg") - // 文件名为url的hash值 - savePath = path + utils.Int2Str(pid) + ".jpg" - // 文件存在或文件大小大于10kb - if utils.PathExists(savePath) && utils.FileSize(savePath) > 10240 { - return savePath, nil - } - - // 模拟QQ客户端请求 - client := &http.Client{ - Transport: &http.Transport{ - DisableKeepAlives: true, - // 绕过sni审查 - TLSClientConfig: &tls.Config{ - ServerName: "-", - InsecureSkipVerify: true, - }, - // 更改dns - Dial: func(network, addr string) (net.Conn, error) { - return net.Dial("tcp", "210.140.92.142:443") - }, - }, - } - reqest, _ := http.NewRequest("GET", url, nil) - reqest.Header.Set("Referer", "https://www.pixiv.net/") - reqest.Header.Set("Host", "i.pximg.net") - reqest.Header.Set("User-Agent", "QQ/8.2.0.1296 CFNetwork/1126") - - resp, err := client.Do(reqest) - if err != nil { - return "", err - } - if resp.StatusCode != 200 { - return "", errors.New(fmt.Sprintf("Download failed, code %d", resp.StatusCode)) - } - defer resp.Body.Close() - // 写入文件 - data, _ := ioutil.ReadAll(resp.Body) - f, _ := os.OpenFile(savePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) - defer f.Close() - f.Write(data) - - return savePath, err -} - -// PicHash 返回图片的 md5 值 -func PicHash(path string) string { - data, err := ioutil.ReadFile(path) - if err != nil { - return "" - } - return strings.ToUpper(fmt.Sprintf("%x", md5.Sum(data))) -} - -// urlCache 缓存并返回缓存路径 -func (this *Illust) RmPic(path string) (err error) { - url := this.ImageUrls - pid := this.Pid - url = strings.ReplaceAll(url, "img-original", "img-master") - url = strings.ReplaceAll(url, "_p0", "_p0_master1200") - url = strings.ReplaceAll(url, ".png", ".jpg") - // 文件名为url的hash值 - savePath := path + utils.Int2Str(pid) + ".jpg" - // 文件存在或文件大小大于10kb - if utils.PathExists(savePath) { - return os.Remove(savePath) - } else { - return nil - } -} diff --git a/api/pixiv/pixiv_api.go b/api/pixiv/pixiv_api.go deleted file mode 100644 index 7b027277..00000000 --- a/api/pixiv/pixiv_api.go +++ /dev/null @@ -1,137 +0,0 @@ -package pixiv - -import ( - "crypto/tls" - "errors" - "fmt" - "io/ioutil" - "net" - "net/http" - "strings" - - "github.com/tidwall/gjson" -) - -// Illust 插画信息 -type Illust struct { - Pid int64 `db:"pid"` - Title string `db:"title"` - Caption string `db:"caption"` - Tags string `db:"tags"` - ImageUrls string `db:"image_urls"` - AgeLimit string `db:"age_limit"` - CreatedTime string `db:"created_time"` - UserId int64 `db:"user_id"` - UserName string `db:"user_name"` -} - -// IllustInfo 根据p站插画id返回插画信息Illust -func (this *Illust) IllustInfo(id int64) (err error) { - api := fmt.Sprintf("https://pixiv.net/ajax/illust/%d", id) - transport := http.Transport{ - DisableKeepAlives: true, - // 绕过sni审查 - TLSClientConfig: &tls.Config{ - ServerName: "-", - InsecureSkipVerify: true, - }, - // 更改dns - Dial: func(network, addr string) (net.Conn, error) { - return net.Dial("tcp", "210.140.131.223:443") - }, - } - client := &http.Client{ - Transport: &transport, - } - - // 网络请求 - req, err := http.NewRequest("GET", api, nil) - if err != nil { - return err - } - req.Header.Set("Host", "pixiv.net") - req.Header.Set("Referer", "pixiv.net") - req.Header.Set("Accept", "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 - } - if code := resp.StatusCode; code != 200 { - return errors.New(fmt.Sprintf("Search illust's info failed, status %d", code)) - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - json := gjson.ParseBytes(body).Get("body") - - // 如果有"R-18"tag则判断为R-18(暂时) - var ageLimit = "all-age" - for _, tag := range json.Get("tags.tags.#.tag").Array() { - if tag.Str == "R-18" { - ageLimit = "r18" - break - } - } - // 解决json返回带html格式 - var caption = strings.ReplaceAll(json.Get("illustComment").Str, "
", "\n") - if index := strings.Index(caption, "<"); index != -1 { - caption = caption[:index] - } - // 解析返回插画信息 - this.Pid = json.Get("illustId").Int() - this.Title = json.Get("illustTitle").Str - this.Caption = caption - this.Tags = fmt.Sprintln(json.Get("tags.tags.#.tag").Array()) - this.ImageUrls = json.Get("urls.original").Str - this.AgeLimit = ageLimit - this.CreatedTime = json.Get("createDate").Str - this.UserId = json.Get("userId").Int() - this.UserName = json.Get("userName").Str - return nil -} - -// BigPic 返回一张XML大图CQ码 -func (i *Illust) BigPic(file string) string { - var hash = PicHash(file) - return fmt.Sprintf(`[CQ:xml,data= - -]`, - hash, - hash, - hash, - i.Title, - i.Pid, - i.UserName, - ) -} - -// NormalPic 返回一张普通图CQ码 -func (i *Illust) NormalPic(file string) string { - return fmt.Sprintf(`[CQ:image,file=file:///%s]`, file) -} - -// DetailPic 返回一张带详细信息的图片CQ码 -func (i *Illust) DetailPic(file string) string { - return fmt.Sprintf(`[SetuTime] %s -标题:%s -插画ID:%d -画师:%s -画师ID:%d -直链:https://pixivel.moe/detail?id=%d`, - i.NormalPic(file), - i.Title, - i.Pid, - i.UserName, - i.UserId, - i.Pid, - ) -} diff --git a/api/utils/utils.go b/api/utils/utils.go deleted file mode 100644 index e4c4013c..00000000 --- a/api/utils/utils.go +++ /dev/null @@ -1,73 +0,0 @@ -package utils - -import ( - "os" - "strconv" - "strings" -) - -// Str2Int string --> int64 -func Str2Int(str string) int64 { - val, _ := strconv.Atoi(str) - return int64(val) -} - -// Int2Str int64 --> string -func Int2Str(val int64) string { - str := strconv.FormatInt(val, 10) - return str -} - -// PathExecute 返回当前运行目录 -func PathExecute() string { - dir, err := os.Getwd() - if err != nil { - panic(err) - } - return dir + "/" -} - -// CreatePath 生成路径或文件所对应的目录 -func CreatePath(path string) { - length := len(path) - switch { - case path[length:] != "/": - path = path[:strings.LastIndex(path, "/")] - case path[length:] != "\\": - path = path[:strings.LastIndex(path, "\\")] - default: - // - } - if !PathExists(path) { - err := os.MkdirAll(path, 0755) - if err != nil { - panic(err) - } - } -} - -// PathExists 判断路径或文件是否存在 -func PathExists(path string) bool { - _, err := os.Stat(path) - return err == nil || os.IsExist(err) -} - -// FileSize 获取文件大小 -func FileSize(file string) int64 { - if fi, err := os.Stat(file); err == nil { - return fi.Size() - } - return 0 -} - -// Min 返回两数最小值 -func Min(a, b int) int { - switch { - default: - return a - case a > b: - return b - case a < b: - return a - } -} diff --git a/build_arm.sh b/build_arm.sh deleted file mode 100755 index 7d0bff70..00000000 --- a/build_arm.sh +++ /dev/null @@ -1,5 +0,0 @@ -go version -go env -w GOPROXY=https://goproxy.cn,direct -go env -w GO111MODULE=auto -go mod tidy -GOOS=linux GOARCH=arm GOARM=6 CGO_ENABLED=0 CC=${CCBIN} CXX=${CXXBIN} go build -ldflags "-s -w" -o zerobot \ No newline at end of file diff --git a/build_mips.sh b/build_mips.sh deleted file mode 100755 index 98abb55e..00000000 --- a/build_mips.sh +++ /dev/null @@ -1,7 +0,0 @@ -go version -go env -w GOPROXY=https://goproxy.cn,direct -go env -w GO111MODULE=auto -go mod tidy -export CCBIN=~/openwrt_with_lean_packages/staging_dir/toolchain-mips_24kc_gcc-8.4.0_musl/bin/mips-openwrt-linux-musl-gcc -export CXXBIN=~/openwrt_with_lean_packages/staging_dir/toolchain-mips_24kc_gcc-8.4.0_musl/bin/mips-openwrt-linux-musl-g++ -GOOS=linux GOARCH=mips GOMIPS=softfloat CGO_ENABLED=0 CC=${CCBIN} CXX=${CXXBIN} go build -ldflags "-s -w" -o zerobot \ No newline at end of file diff --git a/chat/learn.go b/chat/learn.go deleted file mode 100644 index 388d1d46..00000000 --- a/chat/learn.go +++ /dev/null @@ -1,343 +0,0 @@ -package chat - -import ( - "crypto/md5" - "encoding/hex" - "encoding/json" - "fmt" - "io/ioutil" - "math/rand" - "net/http" - "os" - "regexp" - "strings" - "sync" - - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -type QA struct { - Mutex sync.Mutex - Data map[int64]map[string]string - Path string -} - -var ( - BotPath = botPath() - BotQQ = "0" - ImagePath = "data/chat/image/" - - Char = map[int64]string{} // 群对应角色 - CharIndex = map[string]int64{"椛椛": 0, "ATRI": 1} // 角色对应编号 - - // 角色问、有人问、我问 对象 - QACharPool = &QA{Data: map[int64]map[string]string{}, Path: BotPath + "data/chat/char.json"} - QAGroupPool = &QA{Data: map[int64]map[string]string{}, Path: BotPath + "data/chat/group.json"} - QAUserPool = &QA{Data: map[int64]map[string]string{}, Path: BotPath + "data/chat/user.json"} -) - -func init() { - QACharPool.load() - QAGroupPool.load() - QAUserPool.load() - zero.OnRegex(`切换角色(.*)`, zero.AdminPermission).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - if _, ok := CharIndex[ctx.State["regex_matched"].([]string)[1]]; !ok { - ctx.SendChain(message.Text("???")) - return - } - Char[ctx.Event.GroupID] = ctx.State["regex_matched"].([]string)[1] - ctx.SendChain(message.Text("已经切换了哦~")) - }) - zero.OnRegex(`(.{1,2})问(.*)你答\s?\s?([\s\S]*)`, QAMatch(), QAPermission()).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - question := ctx.State["regex_matched"].([]string)[2] - answer := ctx.State["regex_matched"].([]string)[3] - // 根据匹配使用不同池子对象 - pool := ctx.State["qa_pool"].(*QA) - user := ctx.State["qa_user"].(int64) - // 重组艾特 - q := message.ParseMessageFromString(question) - for i := range q { - if q[i].Type == "at" && q[i].Data["qq"] == fmt.Sprint(ctx.Event.SelfID) { - q[i].Data["qq"] = "BOT_QQ" - } - } - question = q.CQString() - - // 对 CQ码 的 "[" 进行正则转义 - question = strings.ReplaceAll(question, "[", "\\[") - question = strings.ReplaceAll(question, "]", "\\]") - question = message.UnescapeCQCodeText(question) - - // 判断 question 是否符合正则表达式 - _, err := regexp.Compile("^" + question + "$") - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - // 保存图片,重组图片信息 - r := message.ParseMessageFromString(answer) - for i := range r { - if r[i].Type == "image" { - if filename, err := down(r[i].Data["url"], BotPath+ImagePath); err == nil { - r[i].Data["file"] = "file:///BOT_PATH/" + ImagePath + filename - delete(r[i].Data, "url") - } else { // 下载图片发生错误 - ctx.SendChain(message.Text("ERROR: ", err)) - return - } - } - } - answer = r.CQString() - - // 如果是BOT主人,则可以CQ码注入 - // 不存在CQ码也需要转义 - if !strings.Contains(answer, "CQ") || zero.SuperUserPermission(ctx) { - answer = message.UnescapeCQCodeText(answer) - } - // 添加到池子 - pool.add(user, question, answer) - ctx.SendChain(message.Text("好的我记住了~")) - }) - zero.OnRegex(`删除(.{1,2})问(.*)`, QAMatch(), QAPermission()).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - question := ctx.State["regex_matched"].([]string)[2] - // 根据匹配使用不同池子对象 - pool := ctx.State["qa_pool"].(*QA) - user := ctx.State["qa_user"].(int64) - if !strings.Contains(question, "CQ") || zero.AdminPermission(ctx) { - question = message.UnescapeCQCodeText(question) - } - // 重组艾特 - q := message.ParseMessageFromString(question) - for i := range q { - if q[i].Type == "at" && q[i].Data["qq"] == fmt.Sprint(ctx.Event.SelfID) { - q[i].Data["qq"] = "BOT_QQ" - } - } - question = q.CQString() - if answer := pool.del(user, question); answer != "" { - ctx.SendChain(message.Text("我不会再回答[", answer, "]了")) - } else { - ctx.SendChain(message.Text("啊咧[", question, "]是什么?")) - } - }) - zero.OnRegex(`看看(.{1,2})问`, QAMatch()).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - title := "" - r := []string{} - switch ctx.State["regex_matched"].([]string)[1] { - case "角色": - char := "椛椛" - if Char[ctx.Event.GroupID] != "" { - char = Char[ctx.Event.GroupID] - } - title = "当前角色[" + char + "] 设置的关键词有:\n" - case "有人": - title = "本群设置的关键词有:\n" - case "我": - title = "你设置的关键词有:\n" - } - // 根据匹配使用不同池子对象 - pool := ctx.State["qa_pool"].(*QA) - user := ctx.State["qa_user"].(int64) - for question := range pool.Data[user] { - r = append(r, question) - } - if len(r) == 0 { - ctx.SendChain(message.Text("啊咧?我忘掉什么了吗")) - return - } - ctx.SendChain(message.Text( - title, - strings.Join(r, " | "), - )) - }) - zero.OnMessage().SetBlock(false).SetPriority(9999). - Handle(func(ctx *zero.Ctx) { - BotQQ = fmt.Sprint(ctx.Event.SelfID) - m := message.UnescapeCQCodeText(ctx.Event.RawEvent.Get("message").Str) - // 角色问 - if answer := QACharPool.get(CharIndex[Char[ctx.Event.GroupID]], m); answer != "" { - ctx.Send(answer) - return - } - // 有人问 - if answer := QAGroupPool.get(ctx.Event.GroupID, m); answer != "" { - ctx.Send(answer) - return - } - // 我问 - if answer := QAUserPool.get(ctx.Event.UserID, m); answer != "" { - ctx.Send(answer) - return - } - }) -} - -func botPath() string { - dir, _ := os.Getwd() - return dir + "/" -} - -func (qa *QA) load() { - path := qa.Path - idx := strings.LastIndex(qa.Path, "/") - if idx != -1 { - path = path[:idx] - } - _, err := os.Stat(path) - if err != nil && !os.IsExist(err) { - os.MkdirAll(path, 0644) - } - f, _ := os.Open(qa.Path) - defer f.Close() - data, _ := ioutil.ReadAll(f) - qa.Mutex.Lock() - defer qa.Mutex.Unlock() - if data == nil { - data = []byte("0: \n test: ok") - } - json.Unmarshal(data, &qa.Data) -} - -func (qa *QA) save() { - path := qa.Path - idx := strings.LastIndex(qa.Path, "/") - if idx != -1 { - path = path[:idx] - } - _, err := os.Stat(path) - if err != nil && !os.IsExist(err) { - os.MkdirAll(path, 0644) - } - data, _ := json.MarshalIndent(&qa.Data, "", "\t") - ioutil.WriteFile(qa.Path, data, 0644) -} - -func (qa *QA) add(user int64, question, answer string) { - qa.Mutex.Lock() - defer qa.Mutex.Unlock() - if qa.Data[user] == nil { // 防止未初始化 - qa.Data[user] = make(map[string]string) - } - qa.Data[user][question] = answer - qa.save() -} - -func (qa *QA) del(user int64, question string) (answer string) { - qa.Mutex.Lock() - defer qa.Mutex.Unlock() - if answer, ok := qa.Data[user][question]; ok { - delete(qa.Data[user], question) - qa.save() - return answer - } - return "" -} - -func (qa *QA) get(user int64, msg string) (answer string) { - for question, answer := range qa.Data[user] { - // 替换BOT - question = strings.ReplaceAll(question, "BOT_QQ", BotQQ) - r := regexp.MustCompile("^" + question + "$") - if r.MatchString(msg) { - match := r.FindStringSubmatch(msg) - // 正则替换参数 - for i, p := range match { - if p == "[" || p == "]" { - continue - } - answer = strings.ReplaceAll(answer, fmt.Sprintf("$%d", i), p) - } - // 替换图片路径 - answer = strings.ReplaceAll(answer, "BOT_PATH", BotPath) - // 随机回复 - if strings.Contains(answer, "|") { - s := strings.Split(answer, "|") - return s[rand.Intn(len(s))] - } - return answer - } - } - return "" -} - -func down(url, path string) (filename string, err error) { - client := &http.Client{} - reqest, _ := http.NewRequest("GET", url, nil) - reqest.Header.Set("User-Agent", "QQ/8.2.0.1296 CFNetwork/1126") - reqest.Header.Set("Net-Type", "Wifi") - resp, err := client.Do(reqest) - if err != nil { - return "", err - } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return "", fmt.Errorf("code %d", resp.StatusCode) - } - data, _ := ioutil.ReadAll(resp.Body) - // 获取文件MD5值 - m := md5.New() - m.Write(data) - filename = strings.ToUpper(hex.EncodeToString(m.Sum(nil))) - // 判断文件类型 - switch resp.Header.Get("Content-Type") { - case "image/jpeg": - filename = filename + ".jpg" - case "image/png": - filename = filename + ".png" - case "image/gif": - filename = filename + ".gif" - } - // 保存文件 - _, err = os.Stat(path) - if err != nil && !os.IsExist(err) { - os.MkdirAll(path, 0644) - } - f, err := os.OpenFile(path+"/"+filename, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644) - if err != nil { - return "", err - } - defer f.Close() - f.Write(data) - return filename, nil -} - -// QAMatch 返回对应的权限 -func QAMatch() zero.Rule { - return func(ctx *zero.Ctx) bool { - switch ctx.State["regex_matched"].([]string)[1] { - case "角色": - ctx.State["qa_pool"] = QACharPool - ctx.State["qa_user"] = CharIndex[Char[ctx.Event.GroupID]] - return true - case "有人": - ctx.State["qa_pool"] = QAGroupPool - ctx.State["qa_user"] = ctx.Event.GroupID - return true - case "我": - ctx.State["qa_pool"] = QAUserPool - ctx.State["qa_user"] = ctx.Event.UserID - return true - } - return false - } -} - -// QAPermission 返回对应的权限 -func QAPermission() zero.Rule { - return func(ctx *zero.Ctx) bool { - switch ctx.State["regex_matched"].([]string)[1] { - case "角色": - return zero.AdminPermission(ctx) - case "有人": - return zero.AdminPermission(ctx) - case "我": - return true - } - return false - } -} diff --git a/github/repo_searcher.go b/github/repo_searcher.go index b2a52075..8dfcf6ed 100644 --- a/github/repo_searcher.go +++ b/github/repo_searcher.go @@ -8,9 +8,10 @@ import ( "net/url" "strings" - "github.com/tidwall/gjson" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/tidwall/gjson" ) func init() { // 插件主体 diff --git a/go.mod b/go.mod index 8e88710a..22ee02da 100644 --- a/go.mod +++ b/go.mod @@ -1,13 +1,18 @@ -module github.com/Yiwen-Chan/ZeroBot-Plugin +module github.com/FloatTech/ZeroBot-Plugin -go 1.15 +go 1.16 require ( - github.com/antchfx/htmlquery v1.2.3 - github.com/fumiama/ZeroBot-Plugin-Timer v0.0.0-20210616151841-d047372a50c2 - github.com/mattn/go-sqlite3 v1.14.7 + github.com/FloatTech/AnimeAPI v0.0.0-20210619082314-946db9a31a27 + github.com/antchfx/xpath v1.2.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/sirupsen/logrus v1.8.1 github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 github.com/tidwall/gjson v1.8.0 + github.com/tidwall/pretty v1.2.0 // indirect github.com/wdvxdr1123/ZeroBot v1.2.0 + golang.org/x/net v0.0.0-20210525063256-abc453219eb5 // indirect + golang.org/x/sys v0.0.0-20210603125802-9665404d3644 // indirect + modernc.org/sqlite v1.10.8 ) diff --git a/go.sum b/go.sum index de1394bc..4bf71939 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -github.com/Yiwen-Chan/ZeroBot-Plugin v0.0.0-20210606065432-ce326ce97753/go.mod h1:54LOXRTKW0iR0BcKwRSUK46KfLPz7hiLcGMD5GGtL0k= -github.com/Yiwen-Chan/ZeroBot-Plugin v0.0.0-20210606082630-29be1bd5eca6/go.mod h1:UfFAgNpRzp1N9HFmYoUlBJ4nvJOMJC9fMBBHQoaHmf8= +github.com/FloatTech/AnimeAPI v0.0.0-20210619082314-946db9a31a27 h1:/KNwMUtZWOzQUZ6UhK3XlkLErH+233dmb6NmJw5UMi8= +github.com/FloatTech/AnimeAPI v0.0.0-20210619082314-946db9a31a27/go.mod h1:GYrQD70HvBzry1XiZ1tHFNOsOqRkR+ao4XGYZqV4I9c= github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M= github.com/antchfx/htmlquery v1.2.3/go.mod h1:B0ABL+F5irhhMWg54ymEZinzMSi0Kt3I2if0BLYa3V0= github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk= @@ -8,30 +8,29 @@ github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwq github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fumiama/ZeroBot-Plugin-Timer v0.0.0-20210606064339-d55b94d71eee/go.mod h1:RN0gCtafWRu2d7lMg9/5UfZDhtsPgdeUovsyuSwl+oQ= -github.com/fumiama/ZeroBot-Plugin-Timer v0.0.0-20210606075146-09f50acdb4de/go.mod h1:vG2ODqgJYFQobphBnhhmNv3TO+j/ZNYvN6FjUP/zkmA= -github.com/fumiama/ZeroBot-Plugin-Timer v0.0.0-20210616151841-d047372a50c2 h1:8gJPxljHfnIFsE0ZfV8DJuI45Y+zTe/o2YtjKQRGYX8= -github.com/fumiama/ZeroBot-Plugin-Timer v0.0.0-20210616151841-d047372a50c2/go.mod h1:/Tv1kgOdp76gvr1VoVmMG2Xu4c76vXngy6P8NFE4pA0= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= -github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -43,6 +42,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= @@ -60,39 +61,88 @@ github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tidwall/pretty v1.1.1 h1:nt6/Ot5LtZnJCWwEFlelOixPo0xhPFsuZlKyOL3Xfnc= -github.com/tidwall/pretty v1.1.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/wdvxdr1123/ZeroBot v1.2.0 h1:GmCkbzMMq3iugViKDtLbsL7joi29uG3/tp1554nboWI= github.com/wdvxdr1123/ZeroBot v1.2.0/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603125802-9665404d3644 h1:CA1DEQ4NdKphKeL70tvsWNdT5oFh1lOjihRcEDROi0I= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 h1:M8tBwCtWD/cZV9DZpFYRUgaymAYAr+aIUTWzDaM3uPs= +golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878= +modernc.org/cc/v3 v3.33.5 h1:gfsIOmcv80EelyQyOHn/Xhlzex8xunhQxWiJRMYmPrI= +modernc.org/cc/v3 v3.33.5/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878= +modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo= +modernc.org/ccgo/v3 v3.9.4 h1:mt2+HyTZKxva27O6T4C9//0xiNQ/MornL3i8itM5cCs= +modernc.org/ccgo/v3 v3.9.4/go.mod h1:19XAY9uOrYnDhOgfHwCABasBvK69jgC4I8+rizbk3Bc= +modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM= +modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM= +modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= +modernc.org/libc v1.9.5 h1:zv111ldxmP7DJ5mOIqzRbza7ZDl3kh4ncKfASB2jIYY= +modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w= +modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY= +modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM= +modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc= +modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A= +modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0= +modernc.org/sqlite v1.10.8 h1:tZzV+/FwlSBddiJAHLR+qxsw2nx7jpLMKOCVu6NTjxI= +modernc.org/sqlite v1.10.8/go.mod h1:k45BYY2DU82vbS/dJ24OzHCtjPeMEcZ1DV2POiE8nRs= +modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc= +modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/tcl v1.5.2 h1:sYNjGr4zK6cDH74USl8wVJRrvDX6UOLpG0j4lFvR0W0= +modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo= +modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk= +modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= +modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc= +modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA= diff --git a/huahua/huahua.go b/huahua/huahua.go deleted file mode 100644 index e269d47d..00000000 --- a/huahua/huahua.go +++ /dev/null @@ -1,210 +0,0 @@ -package huahua - -import ( - "math/rand" - "strings" - - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" -) - -var ( - PRIO = -1 - ENABLE = true - RES = "https://raw.dihe.moe/Yiwen-Chan/ZeroBot-Plugin/master/huahua/" -) - -func init() { - zero.OnFullMatch("椛椛醒醒", zero.AdminPermission).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ENABLE = true - ctx.SendChain(randText("啊……好困啊……")) - }) - zero.OnFullMatch("椛椛睡吧", zero.AdminPermission).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ENABLE = false - ctx.SendChain(randText("那晚安咯……")) - }) - zero.OnRegex("^。{1,6}$", HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - count := strings.Count(ctx.Event.Message.CQString(), "。") - ctx.SendChain(message.Text( - []string{ - "一个泡泡。。", - "两个泡泡。", - "三个泡泡", - "四个泡泡。。", - "五个泡泡", - "六个泡泡", - }[count-1], - )) - }) - zero.OnFullMatchGroup([]string{"!", "!"}, HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("一个感叹号")) - }) - zero.OnFullMatchGroup([]string{"!?", "?!", "!?", "?!"}, HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("惊讶")) - }) - zero.OnFullMatch("…", HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("不知道该说什么", "啊咧?")) - }) - zero.OnKeyword("不记得", HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("忘川河流淌而过")) - }) - zero.OnKeywordGroup([]string{"可怜", "好累啊"}, HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("给你抱抱", "摸摸头(๑•́ωก̀๑)")) - }) - zero.OnKeyword("好冷", HuaHuaSwitch(), HuaHuaChance(80)).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("多穿点", "赶紧躺被窝")) - }) - // 喊道椛椛 - zero.OnFullMatch("啾啾", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("啾啾")) - }) - zero.OnFullMatch("乖", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("好饿……先请我吃饭饭")) - }) - zero.OnKeyword("听话", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("我只听主人的话")) - }) - zero.OnFullMatch("举高高", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("好重,举不动!")) - }) - zero.OnKeyword("何在", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("我在二次元")) - }) - zero.OnFullMatch("傲娇", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("哼")) - }) - zero.OnFullMatch("卖萌", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("(´ฅω•ฅ`)チラッ")) - }) - zero.OnFullMatch("变身", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("人家才不是马猴烧酒呐!")) - }) - zero.OnFullMatch("可爱", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("٩(๑òωó๑)۶")) - }) - zero.OnKeyword("吃饭了吗", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("等你投食")) - }) - zero.OnKeyword("吃鱼", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("姬气人吃不得这些东西")) - }) - zero.OnKeyword("唱歌", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("不唱")) - }) - zero.OnKeyword("在不在", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("好啦好啦")) - }) - zero.OnKeyword("坏掉了", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("我不是我没有")) - }) - zero.OnKeyword("夸人", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("真是太厉害了呢")) - }) - zero.OnKeyword("女仆模式", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("狗修金sama")) - }) - zero.OnKeyword("抱抱", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("请不要乱摸")) - }) - zero.OnKeyword("揉揉", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("不要不可以")) - }) - zero.OnKeyword("摸头", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("不行,你摸不到")) - }) - zero.OnKeyword("摸摸", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("lsp走开")) - }) - zero.OnKeyword("放屁", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("我只是个姬气人,你想多了")) - }) - zero.OnKeyword("数数", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("就不数")) - }) - zero.OnKeyword("爱我", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("才不爱你呢")) - }) - zero.OnKeyword("被玩坏了", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("你才被玩坏了")) - }) - zero.OnKeyword("跳舞", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("跳你妹,我只是姬气人")) - }) - zero.OnKeyword("过肩摔", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("椛椛不会")) - }) - zero.OnKeyword("还能塞得下", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("凑不要脸")) - }) - zero.OnKeyword("钉宫三连", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("八嘎hentai无路赛")) - }) - zero.OnKeyword("攻略", HuaHuaSwitch(), HuaHuaChance(80), zero.OnlyToMe).SetBlock(true).SetPriority(PRIO). - Handle(func(ctx *zero.Ctx) { - ctx.SendChain(randText("lsp别想泡我")) - }) -} - -func randText(text ...string) message.MessageSegment { - length := len(text) - return message.Text(text[rand.Intn(length)]) -} - -func randImage(file ...string) message.MessageSegment { - length := len(file) - return message.Image(RES + file[rand.Intn(length)]) -} - -// HuaHuaSwitch 控制 HuaHua 的开关 -func HuaHuaSwitch() zero.Rule { - return func(ctx *zero.Ctx) bool { - return ENABLE - } -} - -// HuaHuaChance 概率响应,输入回应 1-100 -func HuaHuaChance(percent int) zero.Rule { - return func(ctx *zero.Ctx) bool { - if r := rand.Intn(100); r <= percent-1 { - return true - } - return false - } -} diff --git a/main.go b/main.go index 2d6072c2..7d4b2d21 100644 --- a/main.go +++ b/main.go @@ -2,33 +2,31 @@ package main import ( "fmt" - "os" - - log "github.com/sirupsen/logrus" - easy "github.com/t-tomalak/logrus-easy-formatter" - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/driver" - "github.com/wdvxdr1123/ZeroBot/message" // 注:以下插件均可通过前面加 // 注释,注释后停用并不加载插件 // 下列插件可与 wdvxdr1123/ZeroBot v1.1.2 以上配合单独使用 // 词库类 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/atri" // ATRI词库 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/chat" // 基础词库 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/huahua" // 椛椛词库 + _ "github.com/FloatTech/ZeroBot-Plugin/atri" // ATRI词库 + _ "github.com/FloatTech/ZeroBot-Plugin/chat" // 基础词库 // 实用类 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/github" // 搜索GitHub仓库 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/manager" // 群管 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/runcode" // 在线运行代码 + _ "github.com/FloatTech/ZeroBot-Plugin/github" // 搜索GitHub仓库 + _ "github.com/FloatTech/ZeroBot-Plugin/manager" // 群管 + _ "github.com/FloatTech/ZeroBot-Plugin/runcode" // 在线运行代码 // 娱乐类 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/music" // 点歌 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/picsearcher" // 搜图 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/randimg" //简易随机图片 + _ "github.com/FloatTech/ZeroBot-Plugin/music" // 点歌 + //_ "github.com/Yiwen-Chan/ZeroBot-Plugin/randimg" //简易随机图片 + _ "github.com/FloatTech/ZeroBot-Plugin/setutime" // 涩图 + _ "github.com/FloatTech/ZeroBot-Plugin/shindan" // 测定 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/setutime" // 涩图 - _ "github.com/Yiwen-Chan/ZeroBot-Plugin/shindan" // 测定 + // 以下为内置依赖,勿动 + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/driver" + "github.com/wdvxdr1123/ZeroBot/message" + + log "github.com/sirupsen/logrus" + easy "github.com/t-tomalak/logrus-easy-formatter" ) func init() { @@ -44,16 +42,19 @@ func main() { ====================[ZeroBot-Plugin]==================== * OneBot + ZeroBot + Golang * Version 1.0.3 - 2021-05-02 18:50:40.5489203 +0800 CST -* Copyright © 2021 Kanri, DawnNights, All Rights Reserved -* Project: https://github.com/Yiwen-Chan/ZeroBot-Plugin +* Copyright © 2021 Kanri, DawnNights, Fumiama +* Project: https://github.com/FloatTech/ZeroBot-Plugin ======================================================== `) // 启动打印 zero.Run(zero.Config{ NickName: []string{"椛椛", "ATRI", "atri", "亚托莉", "アトリ"}, CommandPrefix: "/", - SuperUsers: os.Args[1:], // 必须修改,否则无权限 + SuperUsers: []string{"213864964"}, // 必须修改,否则无权限 Driver: []zero.Driver{ - driver.NewWebSocketClient("ws://127.0.0.1:6700/", ""), + &driver.WSClient{ + Url: "ws://127.0.0.1:6700", + AccessToken: "", + }, }, }) // 帮助 @@ -62,8 +63,8 @@ func main() { ctx.SendChain(message.Text( "* OneBot + ZeroBot + Golang ", "\n", "* Version 1.0.3 - 2021-05-02 18:50:40.5489203 +0800 CST", "\n", - "* Copyright © 2021 Kanri, DawnNights, All Rights Reserved ", "\n", - "* Project: https://github.com/Yiwen-Chan/ZeroBot-Plugin", + "* Copyright © 2021 Kanri, DawnNights, Fumiama ", "\n", + "* Project: https://github.com/FloatTech/ZeroBot-Plugin", )) }) select {} diff --git a/manager/manager.go b/manager/manager.go index 4aefdcd5..c6e7f7e7 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -7,7 +7,6 @@ import ( "strings" "time" - timer "github.com/fumiama/ZeroBot-Plugin-Timer" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" ) @@ -234,37 +233,39 @@ func init() { // 插件主体 ctx.SendChain(message.Text("📧 --> " + ctx.State["regex_matched"].([]string)[1])) return }) - // 定时提醒 - zero.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). - Handle(func(ctx *zero.Ctx) { - dateStrs := ctx.State["regex_matched"].([]string) - ts := timer.GetFilledTimeStamp(dateStrs, false) - ts.Grpid = uint64(ctx.Event.GroupID) - if ts.Enable { - go timer.RegisterTimer(ts, true) - ctx.Send("记住了~") - } else { - ctx.Send("参数非法!") - } - return - }) - // 取消定时 - zero.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). - Handle(func(ctx *zero.Ctx) { - dateStrs := ctx.State["regex_matched"].([]string) - ts := timer.GetFilledTimeStamp(dateStrs, true) - ti := timer.GetTimerInfo(ts) - t, ok := (*timer.Timers)[ti] - if ok { - t.Enable = false - delete(*timer.Timers, ti) //避免重复取消 - timer.SaveTimers() - ctx.Send("取消成功~") - } else { - ctx.Send("没有这个定时器哦~") - } - return - }) + /* + // 定时提醒 + zero.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + Handle(func(ctx *zero.Ctx) { + dateStrs := ctx.State["regex_matched"].([]string) + ts := timer.GetFilledTimeStamp(dateStrs, false) + ts.Grpid = uint64(ctx.Event.GroupID) + if ts.Enable { + go timer.RegisterTimer(ts, true) + ctx.Send("记住了~") + } else { + ctx.Send("参数非法!") + } + return + }) + // 取消定时 + zero.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.SuperUserPermission).SetBlock(true).SetPriority(40). + Handle(func(ctx *zero.Ctx) { + dateStrs := ctx.State["regex_matched"].([]string) + ts := timer.GetFilledTimeStamp(dateStrs, true) + ti := timer.GetTimerInfo(ts) + t, ok := (*timer.Timers)[ti] + if ok { + t.Enable = false + delete(*timer.Timers, ti) //避免重复取消 + timer.SaveTimers() + ctx.Send("取消成功~") + } else { + ctx.Send("没有这个定时器哦~") + } + return + }) + */ // 随机点名 zero.OnFullMatchGroup([]string{"翻牌"}).SetBlock(true).SetPriority(40). Handle(func(ctx *zero.Ctx) { diff --git a/music/music_selecter.go b/music/music_selecter.go index e7f387c3..0a1b92ce 100644 --- a/music/music_selecter.go +++ b/music/music_selecter.go @@ -1,3 +1,6 @@ +/* +QQ音乐、网易云、酷狗、酷我 点歌 +*/ package music import ( diff --git a/picsearcher/pic_searcher.go b/picsearcher/pic_searcher.go deleted file mode 100644 index 71c7cbbc..00000000 --- a/picsearcher/pic_searcher.go +++ /dev/null @@ -1,91 +0,0 @@ -package picsearcher - -import ( - "fmt" - "os" - "strings" - - zero "github.com/wdvxdr1123/ZeroBot" - "github.com/wdvxdr1123/ZeroBot/message" - - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/context" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/pixiv" - apiutils "github.com/Yiwen-Chan/ZeroBot-Plugin/api/utils" - utils "github.com/Yiwen-Chan/ZeroBot-Plugin/picsearcher/utils" -) - -var ( - CACHEPATH = os.TempDir() // 缓冲图片路径 -) - -func init() { // 插件主体 - if strings.Contains(CACHEPATH, "\\") { - CACHEPATH += "\\picsch\\" - } else { - CACHEPATH += "/picsch/" - } - apiutils.CreatePath(CACHEPATH) - // 根据PID搜图 - zero.OnRegex(`^搜图(\d+)$`).SetBlock(true).SetPriority(30). - Handle(func(ctx *zero.Ctx) { - id := apiutils.Str2Int(ctx.State["regex_matched"].([]string)[1]) - ctx.Send("少女祈祷中......") - // 获取P站插图信息 - illust := &pixiv.Illust{} - if err := illust.IllustInfo(id); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) - return - } - // 下载P站插图 - savePath, err := illust.PixivPicDown(CACHEPATH) - if err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) - return - } - // 发送搜索结果 - ctx.Send(illust.DetailPic(savePath)) - illust.RmPic(CACHEPATH) - }) - // 以图搜图 - zero.OnMessage(FullMatchText("以图搜图", "搜索图片", "以图识图"), context.MustHasPicture()).SetBlock(true).SetPriority(999). - Handle(func(ctx *zero.Ctx) { - // 开始搜索图片 - ctx.Send("少女祈祷中......") - for _, pic := range ctx.State["image_url"].([]string) { - fmt.Println(pic) - if m, err := utils.SauceNaoSearch(pic); err == nil { - ctx.SendChain(m...) // 返回SauceNAO的结果 - continue - } else { - ctx.SendChain(message.Text("ERROR: ", err)) - } - if m, err := utils.Ascii2dSearch(pic); err == nil { - ctx.SendChain(m...) // 返回Ascii2d的结果 - continue - } else { - ctx.SendChain(message.Text("ERROR: ", err)) - } - } - }) -} - -// FullMatchText 如果信息中文本完全匹配则返回 true -func FullMatchText(src ...string) zero.Rule { - return func(ctx *zero.Ctx) bool { - msg := ctx.Event.Message - for _, elem := range msg { - if elem.Type == "text" { - text := elem.Data["text"] - text = strings.ReplaceAll(text, " ", "") - text = strings.ReplaceAll(text, "\r", "") - text = strings.ReplaceAll(text, "\n", "") - for _, s := range src { - if text == s { - return true - } - } - } - } - return false - } -} diff --git a/picsearcher/utils/ascii2d.go b/picsearcher/utils/ascii2d.go deleted file mode 100644 index 4258b9a6..00000000 --- a/picsearcher/utils/ascii2d.go +++ /dev/null @@ -1,99 +0,0 @@ -package utils - -import ( - "fmt" - "net/http" - "net/url" - "strings" - - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/pixiv" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/utils" - xpath "github.com/antchfx/htmlquery" - "github.com/wdvxdr1123/ZeroBot/message" -) - -// Ascii2dSearch Ascii2d 以图搜图 -// 第一个参数 返回错误 -// 第二个参数 返回的信息 -func Ascii2dSearch(pic string) (message.Message, error) { - var ( - api = "https://ascii2d.net/search/uri" - ) - transport := http.Transport{ - DisableKeepAlives: true, - } - client := &http.Client{ - Transport: &transport, - } - - // 包装请求参数 - data := url.Values{} - data.Set("uri", pic) // 图片链接 - fromData := strings.NewReader(data.Encode()) - - // 网络请求 - req, _ := http.NewRequest("POST", api, fromData) - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("Accept", "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 nil, err - } - // 色合检索改变到特征检索 - var bovwUrl = strings.ReplaceAll(resp.Request.URL.String(), "color", "bovw") - bovwReq, _ := http.NewRequest("POST", bovwUrl, nil) - bovwReq.Header.Set("Content-Type", "application/x-www-form-urlencoded") - bovwReq.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36") - bovwResp, err := client.Do(bovwReq) - if err != nil { - return nil, err - } - defer bovwResp.Body.Close() - // 解析XPATH - doc, err := xpath.Parse(resp.Body) - if err != nil { - return nil, err - } - // 取出每个返回的结果 - list := xpath.Find(doc, `//div[@class="row item-box"]`) - var link string - // 遍历取出第一个返回的PIXIV结果 - for _, n := range list { - linkPath := xpath.Find(n, `//div[2]/div[3]/h6/a[1]`) - picPath := xpath.Find(n, `//div[1]/img`) - if len(linkPath) != 0 && len(picPath) != 0 { - link = xpath.SelectAttr(linkPath[0], "href") - if strings.Contains(link, "www.pixiv.net") { - break - } - } - } - // 链接取出PIXIV id - var index = strings.LastIndex(link, "/") - if link == "" || index == -1 { - return nil, fmt.Errorf("Ascii2d not found") - } - var id = utils.Str2Int(link[index+1:]) - if id == 0 { - return nil, fmt.Errorf("convert to pid error") - } - // 根据PID查询插图信息 - var illust = &pixiv.Illust{} - if err := illust.IllustInfo(id); err != nil { - return nil, err - } - if illust.AgeLimit != "all-age" { - return nil, fmt.Errorf("Ascii2d not found") - } - // 返回插图信息文本 - return message.Message{ - message.Text( - "[SetuTime] emmm大概是这个?", "\n", - "标题:", illust.Title, "\n", - "插画ID:", illust.Pid, "\n", - "画师:", illust.UserName, "\n", - "画师ID:", illust.UserId, "\n", - "直链:", "https://pixivel.moe/detail?id=", illust.Pid, - ), - }, nil -} diff --git a/picsearcher/utils/saucenao.go b/picsearcher/utils/saucenao.go deleted file mode 100644 index 8071cba7..00000000 --- a/picsearcher/utils/saucenao.go +++ /dev/null @@ -1,77 +0,0 @@ -package utils - -import ( - "fmt" - "io/ioutil" - "net/http" - "net/url" - - "github.com/tidwall/gjson" - "github.com/wdvxdr1123/ZeroBot/message" -) - -// SauceNaoSearch SauceNao 以图搜图 需要链接 返回错误和信息 -func SauceNaoSearch(pic string) (message.Message, error) { - var ( - api = "https://saucenao.com/search.php" - apiKey = "2cc2772ca550dbacb4c35731a79d341d1a143cb5" - - minSimilarity = 70.0 // 返回图片结果的最小相似度 - ) - - // 包装请求参数 - link, _ := url.Parse(api) - link.RawQuery = url.Values{ - "url": []string{pic}, - "api_key": []string{apiKey}, - "db": []string{"5"}, - "numres": []string{"1"}, - "output_type": []string{"2"}, - }.Encode() - - // 网络请求 - client := &http.Client{} - req, err := http.NewRequest("GET", link.String(), nil) - if err != nil { - return nil, err - } - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("Accept", "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 nil, err - } - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - if err != nil { - return nil, err - } - - if resp.StatusCode != http.StatusOK { - // 如果返回不是200则立刻抛出错误 - return nil, fmt.Errorf("SauceNAO not found, code %d", resp.StatusCode) - } - content := gjson.ParseBytes(body) - if status := content.Get("header.status").Int(); status != 0 { - // 如果json信息返回status不为0则立刻抛出错误 - return nil, fmt.Errorf("SauceNAO not found, status %d", status) - } - if content.Get("results.0.header.similarity").Float() < minSimilarity { - return nil, fmt.Errorf("SauceNAO not found") - } - result := content.Get("results.0") - // 正常发送 - return message.Message{ - message.Text("[SetuTime] 我有把握是这个!"), - message.Image(result.Get("header.thumbnail").Str), - message.Text( - "\n", - "相似度:", result.Get("header.similarity").Str, "\n", - "标题:", result.Get("data.title").Str, "\n", - "插画ID:", result.Get("data.pixiv_id").Int(), "\n", - "画师:", result.Get("data.member_name").Str, "\n", - "画师ID:", result.Get("data.member_id").Int(), "\n", - "直链:", "https://pixivel.moe/detail?id=", result.Get("data.pixiv_id").Int(), - ), - }, nil -} diff --git a/run.bat b/run.bat index a344365c..31420462 100644 --- a/run.bat +++ b/run.bat @@ -1,7 +1,7 @@ go version -gcc -v go env -w GOPROXY=https://goproxy.cn,direct go env -w GO111MODULE=auto go mod tidy +::go build -ldflags="-s -w" -o ZeroBot-Plugin.exe go run main.go pause diff --git a/build.bat b/run.sh similarity index 57% rename from build.bat rename to run.sh index d89187e3..39afee7e 100644 --- a/build.bat +++ b/run.sh @@ -1,7 +1,6 @@ go version -gcc -v go env -w GOPROXY=https://goproxy.cn,direct go env -w GO111MODULE=auto go mod tidy -go build -ldflags="-s -w" -o ZeroBot-Plugin-windows.exe -pause +#go build -ldflags="-s -w" -o ZeroBot-Plugin +go run main.go \ No newline at end of file diff --git a/runcode/code_runner.go b/runcode/code_runner.go index a7cdab59..3a677102 100644 --- a/runcode/code_runner.go +++ b/runcode/code_runner.go @@ -1,3 +1,6 @@ +/* +基于 https://tool.runoob.com 的在线运行代码 +*/ package runcode import ( @@ -8,10 +11,11 @@ import ( "strings" "time" - "github.com/tidwall/gjson" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/extension/rate" "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/tidwall/gjson" ) var limit = rate.NewManager(time.Minute*3, 5) diff --git a/api/classify/classify.go b/setutime/classify.go similarity index 95% rename from api/classify/classify.go rename to setutime/classify.go index 9eaa15d2..2a8e269c 100644 --- a/api/classify/classify.go +++ b/setutime/classify.go @@ -1,4 +1,4 @@ -package classify +package setutime import ( "fmt" @@ -8,10 +8,10 @@ import ( "os" "strconv" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/msgext" - "github.com/tidwall/gjson" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/tidwall/gjson" ) var ( @@ -88,7 +88,7 @@ func replyClass(ctx *zero.Ctx, dhash string, class int, noimg bool) { } else { var last_message_id int64 if !noimg { - last_message_id = ctx.Send(msgext.ImageNoCache(CACHE_URI)) + last_message_id = ctx.SendChain(message.Image(CACHE_URI).Add("no_cache", "0")) last_group_id := ctx.Event.GroupID MsgofGrp[last_group_id] = last_message_id dhashofmsg[last_message_id] = dhash diff --git a/setutime/pic_searcher.go b/setutime/pic_searcher.go new file mode 100644 index 00000000..7979cf1b --- /dev/null +++ b/setutime/pic_searcher.go @@ -0,0 +1,167 @@ +package setutime + +import ( + "fmt" + "os" + "strconv" + "strings" + "time" + + zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/FloatTech/AnimeAPI/ascii2d" + "github.com/FloatTech/AnimeAPI/pixiv" + "github.com/FloatTech/AnimeAPI/saucenao" +) + +var ( + CACHEPATH = os.TempDir() // 缓冲图片路径 +) + +func init() { // 插件主体 + // 根据PID搜图 + zero.OnRegex(`^搜图(\d+)$`).SetBlock(true).SetPriority(30). + Handle(func(ctx *zero.Ctx) { + id, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64) + ctx.Send("少女祈祷中......") + // 获取P站插图信息 + illust, err := pixiv.Works(id) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + // 下载P站插图 + if _, err := download(illust, "data/SetuTime/search/"); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + return + } + // 发送搜索结果 + ctx.SendChain( + message.Image(file(illust)), + message.Text( + "\n", + "标题:", illust.Title, "\n", + "插画ID:", illust.Pid, "\n", + "画师:", illust.UserName, "\n", + "画师ID:", illust.UserId, "\n", + "直链:", "https://pixivel.moe/detail?id=", illust.Pid, + ), + ) + }) + // 以图搜图 + zero.OnMessage(FullMatchText("以图搜图", "搜索图片", "以图识图"), MustHasPicture()).SetBlock(true).SetPriority(999). + Handle(func(ctx *zero.Ctx) { + // 开始搜索图片 + ctx.Send("少女祈祷中......") + for _, pic := range ctx.State["image_url"].([]string) { + fmt.Println(pic) + if result, err := saucenao.SauceNAO(pic); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + } else { + // 返回SauceNAO的结果 + ctx.SendChain( + message.Text("我有把握是这个!"), + message.Image(result.Thumbnail), + message.Text( + "\n", + "相似度:", result.Similarity, "\n", + "标题:", result.Title, "\n", + "插画ID:", result.PixivID, "\n", + "画师:", result.MemberName, "\n", + "画师ID:", result.MemberID, "\n", + "直链:", "https://pixivel.moe/detail?id=", result.PixivID, + ), + ) + continue + } + if result, err := ascii2d.Ascii2d(pic); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + } else { + // 返回Ascii2d的结果 + ctx.SendChain( + message.Text( + "大概是这个?", "\n", + "标题:", result.Title, "\n", + "插画ID:", result.Pid, "\n", + "画师:", result.UserName, "\n", + "画师ID:", result.UserId, "\n", + "直链:", "https://pixivel.moe/detail?id=", result.Pid, + ), + ) + continue + } + } + }) +} + +// FullMatchText 如果信息中文本完全匹配则返回 true +func FullMatchText(src ...string) zero.Rule { + return func(ctx *zero.Ctx) bool { + msg := ctx.Event.Message + for _, elem := range msg { + if elem.Type == "text" { + text := elem.Data["text"] + text = strings.ReplaceAll(text, " ", "") + text = strings.ReplaceAll(text, "\r", "") + text = strings.ReplaceAll(text, "\n", "") + for _, s := range src { + if text == s { + return true + } + } + } + } + return false + } +} + +// HasPicture 消息含有图片返回 true +func HasPicture() zero.Rule { + return func(ctx *zero.Ctx) bool { + msg := ctx.Event.Message + url := []string{} + // 如果是回复信息则将信息替换成被回复的那条 + if msg[0].Type == "reply" { + id, _ := strconv.Atoi(msg[0].Data["id"]) + msg = ctx.GetMessage(int64(id)).Elements + } + // 遍历信息中所有图片 + for _, elem := range msg { + if elem.Type == "image" { + url = append(url, elem.Data["url"]) + } + } + // 如果有图片就返回true + if len(url) > 0 { + ctx.State["image_url"] = url + return true + } + return false + } +} + +// MustHasPicture 消息不存在图片阻塞60秒至有图片,超时返回 false +func MustHasPicture() zero.Rule { + return func(ctx *zero.Ctx) bool { + if HasPicture()(ctx) { + return true + } + // 没有图片就索取 + ctx.Send("请发送一张图片") + next := zero.NewFutureEvent("message", 999, false, zero.CheckUser(ctx.Event.UserID), HasPicture()) + recv, cancel := next.Repeat() + select { + case e := <-recv: + cancel() + newCtx := &zero.Ctx{Event: e, State: zero.State{}} + if HasPicture()(newCtx) { + ctx.State["image_url"] = newCtx.State["image_url"] + return true + } + return false + case <-time.After(time.Second * 60): + return false + } + } +} diff --git a/randimg/setu_geter.go b/setutime/rand_image.go similarity index 74% rename from randimg/setu_geter.go rename to setutime/rand_image.go index 669b5168..5d8fb42d 100644 --- a/randimg/setu_geter.go +++ b/setutime/rand_image.go @@ -1,13 +1,11 @@ -package randimg +package setutime import ( "fmt" "strings" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/classify" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/context" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/msgext" zero "github.com/wdvxdr1123/ZeroBot" + "github.com/wdvxdr1123/ZeroBot/message" ) var ( @@ -30,7 +28,7 @@ func init() { // 插件主体 zero.OnFullMatch("随机图片").SetBlock(true).SetPriority(24). Handle(func(ctx *zero.Ctx) { if ctx.Event.GroupID > 0 { - classify.Classify(ctx, RANDOM_API_URL, false) + Classify(ctx, RANDOM_API_URL, false) } return }) @@ -42,9 +40,9 @@ func init() { // 插件主体 ctx.Send("请稍后再试哦") } else { BLOCK_REQUEST = true - last_message_id := ctx.Send(msgext.ImageNoCache(RANDOM_API_URL)) + last_message_id := ctx.SendChain(message.Image(RANDOM_API_URL).Add("no_cache", "0")) last_group_id := ctx.Event.GroupID - classify.MsgofGrp[last_group_id] = last_message_id + MsgofGrp[last_group_id] = last_message_id BLOCK_REQUEST = false } } @@ -53,21 +51,21 @@ func init() { // 插件主体 // 撤回最后的随机图片 zero.OnFullMatch("不许好").SetBlock(true).SetPriority(24). Handle(func(ctx *zero.Ctx) { - classify.Vote(ctx, 5) + Vote(ctx, 5) }) // 撤回最后的随机图片 zero.OnFullMatch("太涩了").SetBlock(true).SetPriority(24). Handle(func(ctx *zero.Ctx) { - classify.Vote(ctx, 6) + Vote(ctx, 6) }) // 上传一张图进行评价 - zero.OnFullMatch("评价图片", context.MustHasPicture()).SetBlock(true).SetPriority(24). + zero.OnFullMatch("评价图片", MustHasPicture()).SetBlock(true).SetPriority(24). Handle(func(ctx *zero.Ctx) { if ctx.Event.GroupID > 0 { ctx.Send("少女祈祷中......") for _, pic := range ctx.State["image_url"].([]string) { fmt.Println(pic) - classify.Classify(ctx, pic, true) + Classify(ctx, pic, true) } } return diff --git a/setutime/setu_geter.go b/setutime/setu_geter.go index 7db33b32..64af3912 100644 --- a/setutime/setu_geter.go +++ b/setutime/setu_geter.go @@ -1,140 +1,147 @@ package setutime import ( - "errors" "fmt" + "os" + "strconv" "strings" + "sync" "time" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/extension/rate" + "github.com/wdvxdr1123/ZeroBot/message" - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/pixiv" - apiutils "github.com/Yiwen-Chan/ZeroBot-Plugin/api/utils" - "github.com/Yiwen-Chan/ZeroBot-Plugin/setutime/utils" + "github.com/FloatTech/AnimeAPI/pixiv" ) -var limit = rate.NewManager(time.Minute*1, 5) +// Pools 图片缓冲池 +type Pool struct { + Lock sync.Mutex + DB *Sqlite + Path string + Group int64 + List []string + Max int + Pool map[string][]*pixiv.Illust + Form int64 +} -var ( - BOTPATH = apiutils.PathExecute() // 当前bot运行目录 - DATAPATH = BOTPATH + "data/SetuTime/" // 数据目录 - DBPATH = DATAPATH + "SetuTime.db" // 数据库路径 - - CACHEPATH = DATAPATH + "cache/" // 缓冲图片路径 - CACHEGROUP int64 = 0 // 缓冲图片群,为0即可 - PoolList = []string{"涩图", "二次元", "风景", "车万"} // 可自定义 - - DB = utils.Sqlite{DBPath: DBPATH} // 新建涩图数据库对象 - PoolsCache = utils.NewPoolsCache() // 新建一个缓冲池对象 - - FORM = "PIC" // 默认 PIC 格式 -) - -func init() { - PoolsCache.Group = CACHEGROUP // 图片缓冲群 - PoolsCache.Path = CACHEPATH // 缓冲图片路径 - - apiutils.CreatePath(DBPATH) - apiutils.CreatePath(CACHEPATH) - - for i := range PoolList { - if err := DB.Create(PoolList[i], &pixiv.Illust{}); err != nil { +// NewPoolsCache 返回一个缓冲池对象 +func NewPools() *Pool { + cache := &Pool{ + DB: &Sqlite{DBPath: "data/SetuTime/SetuTime.db"}, + Path: "data/SetuTime/cache/", + Group: 0, + List: []string{"涩图", "二次元", "风景", "车万"}, // 可以自己加类别,得自己加图片进数据库 + Max: 10, + Pool: map[string][]*pixiv.Illust{}, + Form: 0, + } + err := os.MkdirAll(cache.Path, 0644) + if err != nil { + panic(err) + } + for i := range cache.List { + if err := cache.DB.Create(cache.List[i], &pixiv.Illust{}); err != nil { panic(err) } } + return cache } +var ( + POOL = NewPools() + limit = rate.NewManager(time.Minute*1, 5) +) + func init() { // 插件主体 - zero.OnRegex(`^来份(.*)$`, FirstValueInList(PoolList)).SetBlock(true).SetPriority(20). + zero.OnRegex(`^来份(.*)$`, FirstValueInList(POOL.List)).SetBlock(true).SetPriority(20). Handle(func(ctx *zero.Ctx) { if !limit.Load(ctx.Event.UserID).Acquire() { - ctx.Send("请稍后重试0x0...") + ctx.SendChain(message.Text("少女祈祷中......")) return } var type_ = ctx.State["regex_matched"].([]string)[1] // 补充池子 go func() { - times := apiutils.Min(PoolsCache.Max-PoolsCache.Size(type_), 2) + times := Min(POOL.Max-POOL.Size(type_), 2) for i := 0; i < times; i++ { illust := &pixiv.Illust{} // 查询出一张图片 - if err := DB.Select(type_, illust, "ORDER BY RANDOM() limit 1"); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) + if err := POOL.DB.Select(type_, illust, "ORDER BY RANDOM() limit 1"); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) continue } - ctx.SendGroupMessage(PoolsCache.Group, "正在下载"+illust.ImageUrls) - file, err := illust.PixivPicDown(PoolsCache.Path) + // 下载图片 + file, err := download(illust, POOL.Path) if err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) + ctx.SendChain(message.Text("ERROR: ", err)) continue } - ctx.SendGroupMessage(PoolsCache.Group, illust.NormalPic(file)) + ctx.SendGroupMessage(POOL.Group, []message.MessageSegment{message.Image(file)}) // 向缓冲池添加一张图片 - if err := PoolsCache.Push(type_, illust); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) - continue - } + POOL.Push(type_, illust) + time.Sleep(time.Second * 1) } }() // 如果没有缓存,阻塞5秒 - if PoolsCache.Size(type_) == 0 { - ctx.Send("[SetuTime] 正在填充弹药......") + if POOL.Size(type_) == 0 { + ctx.SendChain(message.Text("INFO: 正在填充弹药......")) <-time.After(time.Second * 5) - if PoolsCache.Size(type_) == 0 { - ctx.Send("[SetuTime] 等待填充,请稍后再试......") + if POOL.Size(type_) == 0 { + ctx.SendChain(message.Text("ERROR: 等待填充,请稍后再试......")) return } } // 从缓冲池里抽一张 - if id := ctx.Send(PoolsCache.GetOnePic(type_, FORM)); id == 0 { - ctx.Send(fmt.Sprintf("ERROR: %v", errors.New("可能被风控了"))) + if id := ctx.SendChain(message.Image(file(POOL.Pop(type_)))); id == 0 { + ctx.SendChain(message.Text("ERROR: 可能被风控了")) } return }) - zero.OnRegex(`^添加(.*?)(\d+)$`, FirstValueInList(PoolList), zero.SuperUserPermission).SetBlock(true).SetPriority(21). + zero.OnRegex(`^添加(.*?)(\d+)$`, FirstValueInList(POOL.List), zero.SuperUserPermission).SetBlock(true).SetPriority(21). Handle(func(ctx *zero.Ctx) { var ( - type_ = ctx.State["regex_matched"].([]string)[1] - id = apiutils.Str2Int(ctx.State["regex_matched"].([]string)[2]) - illust = &pixiv.Illust{} + type_ = ctx.State["regex_matched"].([]string)[1] + id, _ = strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) ) - ctx.Send("少女祈祷中......") + ctx.SendChain(message.Text("少女祈祷中......")) // 查询P站插图信息 - - if err := illust.IllustInfo(id); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) + illust, err := pixiv.Works(id) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) return } // 下载插画 - if _, err := illust.PixivPicDown(PoolsCache.Path); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) + if _, err := download(illust, POOL.Path); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) return } - file := fmt.Sprintf("%s%d.jpg", PoolsCache.Path, illust.Pid) - if id := ctx.Send(illust.DetailPic(file)); id == 0 { - ctx.Send(fmt.Sprintf("ERROR: %v", "可能被风控,发送失败")) + // 发送到发送者 + if id := ctx.SendChain(message.Image(file(illust))); id == 0 { + ctx.SendChain(message.Text("ERROR: 可能被风控,发送失败")) return } // 添加插画到对应的数据库table - if err := DB.Insert(type_, illust); err != nil { - ctx.Send(fmt.Sprintf("ERROR: %v", err)) + if err := POOL.DB.Insert(type_, illust); err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) return } ctx.Send("添加成功") return }) - zero.OnRegex(`^删除(.*?)(\d+)$`, FirstValueInList(PoolList), zero.SuperUserPermission).SetBlock(true).SetPriority(22). + zero.OnRegex(`^删除(.*?)(\d+)$`, FirstValueInList(POOL.List), zero.SuperUserPermission).SetBlock(true).SetPriority(22). Handle(func(ctx *zero.Ctx) { var ( type_ = ctx.State["regex_matched"].([]string)[1] - id = apiutils.Str2Int(ctx.State["regex_matched"].([]string)[2]) + id, _ = strconv.ParseInt(ctx.State["regex_matched"].([]string)[2], 10, 64) ) // 查询数据库 - if err := DB.Delete(type_, fmt.Sprintf("WHERE pid=%d", id)); err != nil { + if err := POOL.DB.Delete(type_, fmt.Sprintf("WHERE pid=%d", id)); err != nil { ctx.Send(fmt.Sprintf("ERROR: %v", err)) return } @@ -143,36 +150,22 @@ func init() { // 插件主体 }) // 查询数据库涩图数量 - zero.OnFullMatchGroup([]string{"setu -s", "setu --status", ">setu status"}).SetBlock(true).SetPriority(23). + zero.OnFullMatchGroup([]string{">setu status"}).SetBlock(true).SetPriority(23). Handle(func(ctx *zero.Ctx) { state := []string{"[SetuTime]"} - for i := range PoolList { - num, err := DB.Num(PoolList[i]) + for i := range POOL.List { + num, err := POOL.DB.Num(POOL.List[i]) if err != nil { num = 0 } state = append(state, "\n") - state = append(state, PoolList[i]) + state = append(state, POOL.List[i]) state = append(state, ": ") state = append(state, fmt.Sprintf("%d", num)) } ctx.Send(strings.Join(state, "")) return }) - // 开xml模式 - zero.OnFullMatchGroup([]string{"setu -x", "setu --xml", ">setu xml"}).SetBlock(true).SetPriority(24). - Handle(func(ctx *zero.Ctx) { - FORM = "XML" - ctx.Send("[SetuTime] XML->ON") - return - }) - // 关xml模式 - zero.OnFullMatchGroup([]string{"setu -p", "setu --pic", ">setu pic"}).SetBlock(true).SetPriority(24). - Handle(func(ctx *zero.Ctx) { - FORM = "PIC" - ctx.Send("[SetuTime] XML->OFF") - return - }) } // FirstValueInList 判断正则匹配的第一个参数是否在列表中 @@ -187,3 +180,80 @@ func FirstValueInList(list []string) zero.Rule { return false } } + +// Min 返回两数最小值 +func Min(a, b int) int { + switch { + default: + return a + case a > b: + return b + case a < b: + return a + } +} + +// Size 返回缓冲池指定类型的现有大小 +func (p *Pool) Size(type_ string) int { + return len(p.Pool[type_]) +} + +// IsFull 返回缓冲池指定类型是否已满 +func (p *Pool) IsFull(type_ string) bool { + return len(p.Pool[type_]) >= p.Max +} + +// Push 向缓冲池插入一张图片 +func (p *Pool) Push(type_ string, illust *pixiv.Illust) { + p.Lock.Lock() + defer p.Lock.Unlock() + p.Pool[type_] = append(p.Pool[type_], illust) +} + +// Push 在缓冲池拿出一张图片 +func (p *Pool) Pop(type_ string) (illust *pixiv.Illust) { + p.Lock.Lock() + defer p.Lock.Unlock() + if p.Size(type_) == 0 { + return + } + illust = p.Pool[type_][0] + p.Pool[type_] = p.Pool[type_][1:] + return +} + +func file(i *pixiv.Illust) string { + filename := fmt.Sprint(i.Pid) + pwd, _ := os.Getwd() + filepath := pwd + `\` + POOL.Path + filename + if _, err := os.Stat(filepath + ".jpg"); err == nil || os.IsExist(err) { + return `file:///` + filepath + ".jpg" + } + if _, err := os.Stat(filepath + ".png"); err == nil || os.IsExist(err) { + return `file:///` + filepath + ".png" + } + if _, err := os.Stat(filepath + ".gif"); err == nil || os.IsExist(err) { + return `file:///` + filepath + ".gif" + } + return "" +} + +func download(i *pixiv.Illust, filedir string) (string, error) { + filename := fmt.Sprint(i.Pid) + filepath := filedir + filename + if _, err := os.Stat(filepath + ".jpg"); err == nil || os.IsExist(err) { + return filepath + ".jpg", nil + } + if _, err := os.Stat(filepath + ".png"); err == nil || os.IsExist(err) { + return filepath + ".png", nil + } + if _, err := os.Stat(filepath + ".gif"); err == nil || os.IsExist(err) { + return filepath + ".gif", nil + } + // 下载最大分辨率为 1200 的图片 + link := i.ImageUrls + link = strings.ReplaceAll(link, "img-original", "img-master") + link = strings.ReplaceAll(link, "_p0", "_p0_master1200") + // 下载 + return pixiv.Download(link, filedir, filename) +} diff --git a/setutime/utils/sqlite.go b/setutime/sqlite.go similarity index 98% rename from setutime/utils/sqlite.go rename to setutime/sqlite.go index d47d0ac5..bf7e3f7c 100644 --- a/setutime/utils/sqlite.go +++ b/setutime/sqlite.go @@ -1,4 +1,4 @@ -package utils +package setutime import ( "database/sql" @@ -6,7 +6,7 @@ import ( "reflect" "strings" - _ "github.com/mattn/go-sqlite3" + _ "modernc.org/sqlite" ) // Sqlite 数据库对象 @@ -20,7 +20,7 @@ type Sqlite struct { // 返回错误 func (db *Sqlite) Create(table string, objptr interface{}) (err error) { if db.DB == nil { - database, err := sql.Open("sqlite3", db.DBPath) + database, err := sql.Open("sqlite", db.DBPath) if err != nil { return err } diff --git a/setutime/utils/pic_pool.go b/setutime/utils/pic_pool.go deleted file mode 100644 index 17ab21a0..00000000 --- a/setutime/utils/pic_pool.go +++ /dev/null @@ -1,73 +0,0 @@ -package utils - -import ( - "fmt" - "sync" - - "github.com/Yiwen-Chan/ZeroBot-Plugin/api/pixiv" -) - -// PoolsCache 图片缓冲池 -type PoolsCache struct { - Lock sync.Mutex - Max int - Path string - Group int64 - Pool map[string][]*pixiv.Illust -} - -// NewPoolsCache 返回一个缓冲池对象 -func NewPoolsCache() *PoolsCache { - return &PoolsCache{ - Max: 10, - Path: "./data/SetuTime/cache/", - Group: 1048452984, - Pool: map[string][]*pixiv.Illust{}, - } -} - -// Size 返回缓冲池指定类型的现有大小 -func (p *PoolsCache) Size(type_ string) int { - return len(p.Pool[type_]) -} - -// IsFull 返回缓冲池指定类型是否已满 -func (p *PoolsCache) IsFull(type_ string) bool { - return len(p.Pool[type_]) >= p.Max -} - -// Push 向缓冲池插入一张图片,返回错误 -func (p *PoolsCache) Push(type_ string, illust *pixiv.Illust) (err error) { - p.Lock.Lock() - defer p.Lock.Unlock() - p.Pool[type_] = append(p.Pool[type_], illust) - return nil -} - -// Push 在缓冲池拿出一张图片,返回错误 -func (p *PoolsCache) Pop(type_ string) (illust *pixiv.Illust) { - p.Lock.Lock() - defer p.Lock.Unlock() - if p.Size(type_) == 0 { - return - } - illust = p.Pool[type_][0] - p.Pool[type_] = p.Pool[type_][1:] - return -} - -// Push 在缓冲池拿出一张图片,返回指定格式CQ码 -func (p *PoolsCache) GetOnePic(type_ string, form string) string { - var ( - illust = p.Pop(type_) - file = fmt.Sprintf("%s%d.jpg", p.Path, illust.Pid) - ) - switch form { - case "XML": - return illust.BigPic(file) - case "DETAIL": - return illust.DetailPic(file) - default: - return illust.NormalPic(file) - } -} diff --git a/setutime/utils/switch.go b/setutime/utils/switch.go deleted file mode 100644 index c5774877..00000000 --- a/setutime/utils/switch.go +++ /dev/null @@ -1,5 +0,0 @@ -package utils - -var ( - XML = true // 图片XML开关,默认开启 -) diff --git a/shindan/shindan.go b/shindan/shindan.go index 6801f82c..ffbd701d 100644 --- a/shindan/shindan.go +++ b/shindan/shindan.go @@ -4,144 +4,53 @@ package shindan import ( - "bytes" - "errors" - "fmt" - "mime/multipart" - "net/http" "strconv" - "strings" "time" - xpath "github.com/antchfx/htmlquery" zero "github.com/wdvxdr1123/ZeroBot" "github.com/wdvxdr1123/ZeroBot/extension/rate" "github.com/wdvxdr1123/ZeroBot/message" + + "github.com/FloatTech/AnimeAPI/shindanmaker" ) -var limit = rate.NewManager(time.Minute*5, 5) +var ( + // 限制调用频率 + limit = rate.NewManager(time.Minute*5, 5) +) func init() { - table := map[string]string{ - // 可自行添加,前面为指令名,后面为网页ID - "异世界转生": "587874", - "卖萌": "360578", - "今天是什么少女": "162207", - } - zero.OnMessage(HasTableKey(table), GetName()).SetBlock(true).FirstPriority(). - Handle(func(ctx *zero.Ctx) { - if !limit.Load(ctx.Event.UserID).Acquire() { - ctx.Send("请稍后重试0x0...") - return - } - - type_ := ctx.State["key"].(string) - name := ctx.State["name"].(string) - - text, err := shindanmaker(table[type_], name) - if err != nil { - ctx.SendChain(message.Text("ERROR: ", err)) - } - ctx.SendChain(message.Text(text)) - }) + zero.OnPrefix("异世界转生", number(587874)).SetBlock(true).FirstPriority().Handle(handle) + zero.OnPrefix("今天是什么少女", number(162207)).SetBlock(true).FirstPriority().Handle(handle) + zero.OnPrefix("卖萌", number(360578)).SetBlock(true).FirstPriority().Handle(handle) } -// HasTableKey 如果 ctx.Event.RawMessage 是以 table 的 key 开头,返回真 -func HasTableKey(table map[string]string) func(ctx *zero.Ctx) bool { - return func(ctx *zero.Ctx) bool { - msg := ctx.Event.RawMessage - for key := range table { - if strings.HasPrefix(msg, key) { - temp := strings.TrimPrefix(msg, key) - ctx.State["key"] = key - ctx.State["trim_key"] = temp - return true - } - } - return false +// shindanmaker 处理函数 +var handle = func(ctx *zero.Ctx) { + if !limit.Load(ctx.Event.UserID).Acquire() { + ctx.Send("请稍后重试0x0...") + return } + // 获取名字 + name := ctx.State["args"].(string) + if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" { + qq, _ := strconv.ParseInt(ctx.Event.Message[1].Data["qq"], 10, 64) + name = ctx.GetGroupMemberInfo(ctx.Event.GroupID, qq, false).Get("nickname").Str + } else if name == "" { + name = ctx.Event.Sender.NickName + } + // 调用接口 + text, err := shindanmaker.Shindanmaker(ctx.State["id"].(int64), name) + if err != nil { + ctx.SendChain(message.Text("ERROR: ", err)) + } + ctx.SendChain(message.Text(text)) } -// GetName 获取名字 -// 如果 ctx.State["trim_key"] 为空 -// 则 ctx.State["name"] 为发送者的 名片 昵称 群头衔 -// 如果 rule:HasTableKey 中 ctx.State["trim_key"] 是艾特 -// 则 ctx.State["name"] 为 被艾特的人的 名片 昵称 群头衔 -// 否则 ctx.State["name"] 为 ctx.State["trim_key"] -func GetName() func(ctx *zero.Ctx) bool { +// 传入 shindanmaker id +var number = func(id int64) func(ctx *zero.Ctx) bool { return func(ctx *zero.Ctx) bool { - name := ctx.State["trim_key"].(string) - arr := message.ParseMessageFromString(name) - var qq int64 = 0 - switch { - case name == "": - qq = ctx.Event.UserID - case arr[0].Type == "at": - qq, _ = strconv.ParseInt(arr[0].Data["qq"], 10, 64) - } - // 获取名字 - info := ctx.GetGroupMemberInfo(ctx.Event.GroupID, qq, false) - switch { - case info.Get("nickname").Str != "": - name = info.Get("nickname").Str - case info.Get("card").Str != "": - name = info.Get("card").Str - case info.Get("title").Str != "": - name = info.Get("title").Str - } - temp := []rune(name) - if len(temp) > 20 { - // 防止超长名字 - temp = temp[:20] - } - name = string(temp) - ctx.State["name"] = name + ctx.State["id"] = id return true } } - -// shindanmaker 返回网页 shindanmaker.com 测定结果 -func shindanmaker(id, name string) (string, error) { - url := "https://shindanmaker.com/" + id - // seed 使每一天的结果都不同 - now := time.Now() - seed := fmt.Sprintf("%d%d%d", now.Year(), now.Month(), now.Day()) - name = name + seed - - // 组装参数 - client := &http.Client{} - payload := &bytes.Buffer{} - writer := multipart.NewWriter(payload) - _ = writer.WriteField("_token", "D6Rn2BTOTMht2FBKNhpwOWqymZuoifLNt31RqlLj") - _ = writer.WriteField("name", name) - _ = writer.WriteField("hiddenName", "名無しのV") - _ = writer.Close() - // 发送请求 - req, _ := http.NewRequest("POST", url, payload) - req.Header.Add("Cookie", "_ga=GA1.2.531883706.1618563450; trc_cookie_storage=taboola%20global%3Auser-id=09ef6d7e-ddb2-4a3f-ac71-b75801d11fef-tuct7602eee; dui=eyJpdiI6ImJ0MThXNTFoZ1hVOXNWZXZFeTRDdlE9PSIsInZhbHVlIjoibUF3em14ZzhXbVJsL1k5b284Tzh5QUhHa0VSYWtYZjF3KzZNRkxtRmVIMHBUbnJ1M0JwNTEzaWhWTzZTT1NGcGVxdFhGaG11Y052a3hyUUZVZDRtNFc0ZndiRnVTSHJFL1hzak43QzNhYVd6cEFEZVJxZVNNNytpNHhQbnF0TGpmbXNNdFlUNjFwNVNubnVJbkN5NHNRPT0iLCJtYWMiOiIzOTNmNmU2NmM3ZmNlMWU5OTA1ZDFlZTJlYTRiZThlZDViMzEwN2VmN2Y0NDEyZjNkYmM5ZGJhNTllMGU1ZjE3In0=; _session=XAj6V877yp1DE8Cb405837ySa0t6fYHM21R2HZ8Z; _gid=GA1.2.2089711003.1622961890; _gat_UA-19089743-2=1; _gat_UA-19089743-3=1; __gads=ID=b597940057bf81ba:T=1622961888:S=ALNI_MY9F-63AstFh3E3tS-DTVh08KgjJg; dsr=eyJpdiI6IlhBWTRYdk14SysyNms5VVpoMFUzMFE9PSIsInZhbHVlIjoiZUl2S2ZSL3M5a2RwT253MlpoQnJPb1NJQjZ1RUJLOWtTWnFXeWpvOG9XUnAwSGw4MGMyVDVIZjJiN0VSSUd6Vkt0V0wreEpEb3d6M2ZDZE51UzJDTGc9PSIsIm1hYyI6IjRkZjU5MjJhMTVhZjQwOGY4MjRhYzhiMjJkMzg0YTFhNzQ1YWVkODZmYjEyMjA5ODliNDdkZGQzMzVkOTdjNGIifQ==; name=eyJpdiI6Ilp0TWxIeG1scW80VWlyTFJQUG4yZWc9PSIsInZhbHVlIjoiL1NqMnJyKzhtdW1hUnFBYjhvUVhVeW9EVWdMSjdjSklvdUsrRk5Id0lrOHdtcjVDU010QkovQjAxYkZZT2Q3TSIsIm1hYyI6IjU4ZDc4NGQzNTMyMzJlZjk0YjZmNjBiMjkzNTAyYTQ0ZDg4NGNkZjhmMDY2ODk2YjdkOTdkZTY3MDlmYzdhYjkifQ==; XSRF-TOKEN=eyJpdiI6IjJrRzRiZTVYcldiL09XSURJTDJQYVE9PSIsInZhbHVlIjoicC8yVzV0cnFQQ2RXOG0xeDdUNTc1V2RmYlJIWnNiTjJ5UVFHMGlTOUhPT3VOOWtZbFFLS0d4QUxDTjdYTEdrYWdvbUJ5Y24wOVpmZjNVdTdtUUNkNmMrVDk0U3RoT0NsZmxZVWIveTh3QU9PT25aLzd1UndpUWVvTlZ2Tjd2c3IiLCJtYWMiOiIyYjdlNjFhYTAzYTIyZTdjMDIwNTZkNjIwMDJlMTI3MTZkNzhjYzdkMzIyNjdmNzFmYzI1ZmE5NzczZTVmZWVjIn0=") - req.Header.Set("Content-Type", writer.FormDataContentType()) - resp, err := client.Do(req) - if err != nil { - return "", err - } - defer resp.Body.Close() - // 解析XPATH - doc, err := xpath.Parse(resp.Body) - if err != nil { - return "", err - } - // 取出每个返回的结果 - list := xpath.Find(doc, `//*[@id="shindanResult"]`) - if len(list) == 0 { - return "", errors.New("无法查找到结果,可能 token 失效,请提交 issue") - } - var output = []string{} - for child := list[0].FirstChild; child != nil; child = child.NextSibling { - if text := xpath.InnerText(child); text != "" { - output = append(output, text) - } else { - output = append(output, "\n") - } - } - return strings.ReplaceAll(strings.Join(output, ""), seed, ""), nil -}