Compare commits

...

15 Commits

Author SHA1 Message Date
源文雨
f181a4b9cd 🎨 可自行编辑json 2022-03-11 11:40:51 +08:00
源文雨
77e5d8b0c2 ⬆️ update deps 2022-03-11 11:36:55 +08:00
源文雨
edd9feb8f8 🔥 drop ioutil 2022-03-11 11:32:13 +08:00
源文雨
81d6a06dbe 🎨 ascii2d color -> bovw 2022-03-11 10:46:01 +08:00
源文雨
8afbc67bf7 💩👌 make lint happy 2022-03-11 10:26:29 +08:00
源文雨
a27132f907 job可获取网页信息,可代表执行 2022-03-09 12:14:20 +08:00
源文雨
183be05d82 job可编程 2022-03-08 23:18:31 +08:00
源文雨
bccf789714 job增加执行指令 2022-03-08 20:39:02 +08:00
源文雨
55944dddb3 job增加参数读取 2022-03-08 18:14:41 +08:00
源文雨
f67932cc56 job增加参数读取 2022-03-08 18:11:24 +08:00
源文雨
6d633fac6a 🐛 edit readme 2022-03-08 18:10:01 +08:00
源文雨
86fc5c51c8 job增加参数读取 2022-03-08 18:07:59 +08:00
源文雨
156e9f07ad 🐛 job禁止递归触发&增加README 2022-03-08 13:04:44 +08:00
源文雨
1ba4722fc7 💩👌 make lint happy 2022-03-07 23:27:11 +08:00
源文雨
54c9857219 🎉 job增加注入指令结果 2022-03-07 22:49:19 +08:00
25 changed files with 571 additions and 313 deletions

View File

@@ -1,6 +1,6 @@
linters-settings:
errcheck:
ignore: fmt:.*,io/ioutil:^Read.*
ignore: fmt:.*
ignoretests: true
goimports:

View File

@@ -67,10 +67,57 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
- [x] /服务详情
- [x] @Bot 插件冲突检测 (会在本群发送一条消息并在约 1s 后撤回以检测其它同类 bot 中已启用的插件并禁用)
- **定时指令触发器** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/job"`
- [x] 记录以"完全匹配关键词"触发的(代表我执行的)指令
- [x] 取消以"完全匹配关键词"触发的(代表我执行的)指令
- [x] 记录在"cron"触发的指令
- [x] 取消在"cron"触发的指令
- [x] 查看所有触发指令
- [x] 查看在"cron"触发的指令
- [x] 查看以"完全匹配关键词"触发的(代表我执行的)指令
- [x] 注入指令结果:任意指令
- [x] 执行指令:任意指令
- 注:任意指令可以使用形如`?::参数1提示语::1!`,`?::参数2提示语::2!`,`?::?可选参数3提示语不回答将填入空值::3!`,`!::从url获取的参数::4!`,`!::?可选的从url获取的参数出错将填入空值::5!`的未定参数,在注入时一一匹配
- 一些示例
> 每日9:30推送摸鱼人日历
```
记录在"30 9 * * *"触发的指令
run[CQ:image,file=https://api.vvhan.com/api/moyu]
```
> 每日12:00以1/2概率执行coser指令
```python
记录在"0 12 * * *"触发的指令
注入指令结果>runcoderaw py
from random import random
if random() > 0.5: print('coser')
else: print('今天没有coser哦~')
```
> 每日15:00询问设置定时者否想看coser
```python
记录在"0 15 * * *"触发的指令
注入指令结果>runcoderaw py
if '?::想看coser吗::1!' == '': print('coser')
else: print('好吧')
```
> 自行编写简易的选择困难症助手小插件
```python
记录以"简易的选择困难症助手"触发的指令
执行指令>runcoderaw py
from random import random
if random() > 0.5: print('您最终会选?::请输入您的选择1::1!')
else: print('您最终会选?::请输入您的选择2::2!')
简易的选择困难症助手
```
> 自行编写随机b站404页趣图插件
```python
记录以"随机b站404页趣图"触发的代表我执行的指令
注入指令结果>runcoderaw py
import json
j = json.loads(r'''!::https://api.iyk0.com/bili_chart::1!''')
print("run[CQ:image,file="+j["img"]+"]")
随机b站404页趣图
```
![随机b站404页趣图](https://user-images.githubusercontent.com/41315874/157371451-c09ad3bb-c61a-4a42-9c47-fab3305bc0f8.png)
- **聊天** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/chat"`
- [x] [BOT名字]
- [x] [戳一戳BOT]
@@ -120,6 +167,7 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
- **在线代码运行** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/runcode"`
- [x] > runcode [language] help
- [x] > runcode [language] [code block]
- [x] > runcoderaw [language] [code block]
- **点歌** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/music"`
- [x] 点歌[xxx]
- [x] 网易点歌[xxx]
@@ -202,7 +250,6 @@ zerobot [-h] [-t token] [-u url] [-n nickname] [-p prefix] [-d|w] [-g 监听地
- **bilibili** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili"`
- [x] >vup info [名字 | uid]
- [x] >user info [名字 | uid]
- [x] /开启粉丝日报
- **嘉然** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana"`
- [x] 小作文
- [x] 发大病

6
go.mod
View File

@@ -3,9 +3,9 @@ module github.com/FloatTech/ZeroBot-Plugin
go 1.17
require (
github.com/FloatTech/AnimeAPI v1.3.1-0.20220307053346-aa76aec4b635
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e
github.com/FloatTech/sqlite v0.2.1
github.com/FloatTech/zbputils v1.3.1-0.20220307063102-42185420359d
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180
github.com/antchfx/htmlquery v1.2.4
github.com/corona10/goimagehash v1.0.3
github.com/fogleman/gg v1.3.0
@@ -21,7 +21,7 @@ require (
github.com/shirou/gopsutil/v3 v3.22.2
github.com/sirupsen/logrus v1.8.1
github.com/tidwall/gjson v1.14.0
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220304040741-8e53f210618c
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220307142419-a1b34e6da007
golang.org/x/image v0.0.0-20220302094943-723b81ca9867
)

15
go.sum
View File

@@ -1,11 +1,11 @@
github.com/FloatTech/AnimeAPI v1.3.1-0.20220307053346-aa76aec4b635 h1:T7J1wLvSqn8PvkM7X98dgbafW+zG1l0LdX664HbrG0U=
github.com/FloatTech/AnimeAPI v1.3.1-0.20220307053346-aa76aec4b635/go.mod h1:ZNhcnGEchvEjd09WbpLMlmxlmYy4trtLYEAJHRAoKaw=
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e h1:PKm/g1M7rYu6YMOV5k8xCOkgXTKF2Tk9v2exeYyCe+0=
github.com/FloatTech/AnimeAPI v1.3.1-0.20220311024222-ed58ddf6834e/go.mod h1:JNF2O/RdbrsDIccSQ29a4g1pQRrZsN0Jh3ggFZYzZuY=
github.com/FloatTech/bot-manager v1.0.0/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ=
github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8=
github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U=
github.com/FloatTech/zbputils v1.3.1-0.20220307053255-29a0c0203693/go.mod h1:1nzt5KFkggpZaqkW0faY3y0X/qeMKTodqWc8wbVYhoY=
github.com/FloatTech/zbputils v1.3.1-0.20220307063102-42185420359d h1:G5rXr46dJnpVbU2jN5XevX3lhh2TQ+DkSk1n1TLS82o=
github.com/FloatTech/zbputils v1.3.1-0.20220307063102-42185420359d/go.mod h1:nW53pKNJVrbYzSGr89CBuM1vZv/hnQnV8dJSp+NCeAA=
github.com/FloatTech/zbputils v1.3.1-0.20220307143543-1139754cacdf/go.mod h1:u+PiX1khNvtAgfRVTVP4hkA2oUnn5q5dTZSk1Cgp0Gw=
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180 h1:8tE9DYu0+YMk3oKeO0ffl80818ZrPM9afbRgb2ag0tQ=
github.com/FloatTech/zbputils v1.3.1-0.20220311032316-df8ab8b3c180/go.mod h1:u+PiX1khNvtAgfRVTVP4hkA2oUnn5q5dTZSk1Cgp0Gw=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc h1:AAx50/fb/xS4lvsdQg+bFbGvqSDhyV1MF+p2PLCamZ0=
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc/go.mod h1:OMmITAib6POA37xCichWM0aRnoVpSMZO1rB/G01wrr0=
@@ -36,7 +36,6 @@ github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
github.com/fumiama/go-base16384 v1.3.0 h1:J5Xtwh/3alGJt/z/0IFralo5UQA89iFWQqbxj5ZQZi8=
github.com/fumiama/go-base16384 v1.3.0/go.mod h1:RGA715p34BiLoZvPRtaxuo2q25Kq9jFsgUsJb8dwy14=
github.com/fumiama/go-registry v0.1.0/go.mod h1:iJT3DVgH7KXpJZs6waXEjnWtJPUBBGhF+ByJIMRfngk=
github.com/fumiama/go-registry v0.1.1 h1:cmCRizjXHFW2ApwUHCXi8wKLJ6Gtt4GrShJlamGPbVI=
github.com/fumiama/go-registry v0.1.1/go.mod h1:iJT3DVgH7KXpJZs6waXEjnWtJPUBBGhF+ByJIMRfngk=
github.com/fumiama/gofastTEA v0.0.9 h1:adaWz+014vMShnLUNWIHLBs0Yv6JNUohcaXZNtct5J0=
@@ -162,8 +161,8 @@ github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVM
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220304040741-8e53f210618c h1:0ew7cwYvRZUm1nsn4Cn0HBDSxy0YT5JnudeP53JwwjA=
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220304040741-8e53f210618c/go.mod h1:NwXIp7PgjV+kUALMXJ4v4/3QcsRSOodtjhLekuPXFog=
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220307142419-a1b34e6da007 h1:yHCJCj8u3Y0JDgTlrUqPHxIO6KU0WK9+voECZ2im5lo=
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220307142419-a1b34e6da007/go.mod h1:NwXIp7PgjV+kUALMXJ4v4/3QcsRSOodtjhLekuPXFog=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=

View File

@@ -14,10 +14,12 @@ var (
"* Copyright © 2020 - 2022 FloatTech. All Rights Reserved.",
"* Project: https://github.com/FloatTech/ZeroBot-Plugin",
}
// Banner ...
Banner = strings.Join(info[:], "\n")
reg = registry.NewRegReader("reilia.westeurope.cloudapp.azure.com:32664", "fumiama")
)
// PrintBanner ...
func PrintBanner() {
fmt.Print(
"\n======================[ZeroBot-Plugin]======================",
@@ -28,6 +30,7 @@ func PrintBanner() {
)
}
// Kanban ...
func Kanban() string {
err := reg.Connect()
if err != nil {

View File

@@ -1,3 +1,4 @@
// Package kanban 打印版本信息
package kanban
func init() {

View File

@@ -1,165 +0,0 @@
package bilibili
import (
"encoding/json"
"net/http"
"time"
control "github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/process"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/zbputils/control/order"
)
type follower struct {
Mid int `json:"mid"`
Uname string `json:"uname"`
Video int `json:"video"`
Roomid int `json:"roomid"`
Rise int `json:"rise"`
Follower int `json:"follower"`
GuardNum int `json:"guardNum"`
AreaRank int `json:"areaRank"`
}
// 开启日报推送
func init() {
fansDaily()
en := control.Register("fansdaily", order.AcquirePrio(), &control.Options{
DisableOnDefault: true,
Help: "fansdaily\n- /开启粉丝日报\n- /关闭粉丝日报",
})
zero.OnCommand("开启粉丝日报", zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
m, ok := control.Lookup("fansdaily")
if ok {
if m.IsEnabledIn(ctx.Event.GroupID) {
ctx.Send(message.Text("已启用!"))
} else {
m.Enable(ctx.Event.GroupID)
ctx.Send(message.Text("添加成功!"))
}
} else {
ctx.Send(message.Text("找不到该服务!"))
}
})
en.OnCommand("关闭粉丝日报", zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
m, ok := control.Lookup("fansdaily")
if ok {
if m.IsEnabledIn(ctx.Event.GroupID) {
m.Disable(ctx.Event.GroupID)
ctx.Send(message.Text("关闭成功!"))
} else {
ctx.Send(message.Text("未启用!"))
}
} else {
ctx.Send(message.Text("找不到该服务!"))
}
})
}
// 定时任务每天晚上最后2分钟执行一次
func fansDaily() {
_, err := process.CronTab.AddFunc("58 23 * * *", func() { sendNotice() })
if err != nil {
panic(err)
}
}
// 获取数据拼接消息链并发送
func getMsg() message.MessageSegment {
var (
diana = fansapi("672328094")
ava = fansapi("672346917")
eileen = fansapi("672342685")
bella = fansapi("672353429")
carol = fansapi("351609538")
)
return message.Text(
time.Now().Format("2006-01-02"), " Asoul全团粉丝日报如下", "\n\n",
"uid: ", diana.Mid, "\n",
"名字: ", diana.Uname, "\n",
"当前粉丝数: ", diana.Follower, "\n",
"今日涨粉数: ", diana.Rise, "\n",
"视频投稿数: ", diana.Video, "\n",
"直播间id: ", diana.Roomid, "\n",
"舰队: ", diana.GuardNum, "\n",
"直播总排名: ", diana.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672328094", "\n\n",
"uid: ", ava.Mid, "\n",
"名字: ", ava.Uname, "\n",
"当前粉丝数: ", ava.Follower, "\n",
"今日涨粉数: ", ava.Rise, "\n",
"视频投稿数: ", ava.Video, "\n",
"直播间id: ", ava.Roomid, "\n",
"舰队: ", ava.GuardNum, "\n",
"直播总排名: ", ava.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672346917", "\n\n",
"uid: ", eileen.Mid, "\n",
"名字: ", eileen.Uname, "\n",
"当前粉丝数: ", eileen.Follower, "\n",
"今日涨粉数: ", eileen.Rise, "\n",
"视频投稿数: ", eileen.Video, "\n",
"直播间id: ", eileen.Roomid, "\n",
"舰队: ", eileen.GuardNum, "\n",
"直播总排名: ", eileen.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672342685", "\n\n",
"uid: ", bella.Mid, "\n",
"名字: ", bella.Uname, "\n",
"当前粉丝数: ", bella.Follower, "\n",
"今日涨粉数: ", bella.Rise, "\n",
"视频投稿数: ", bella.Video, "\n",
"直播间id: ", bella.Roomid, "\n",
"舰队: ", bella.GuardNum, "\n",
"直播总排名: ", bella.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "672353429", "\n\n",
"uid: ", carol.Mid, "\n",
"名字: ", carol.Uname, "\n",
"当前粉丝数: ", carol.Follower, "\n",
"今日涨粉数: ", carol.Rise, "\n",
"视频投稿数: ", carol.Video, "\n",
"直播间id: ", carol.Roomid, "\n",
"舰队: ", carol.GuardNum, "\n",
"直播总排名: ", carol.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", "351609538",
)
}
// 获取数据拼接消息链并发送
func sendNotice() {
m, ok := control.Lookup("fansdaily")
if ok {
msg := getMsg()
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, g := range ctx.GetGroupList().Array() {
grp := g.Get("group_id").Int()
if m.IsEnabledIn(grp) {
ctx.SendGroupMessage(grp, msg)
}
}
return true
})
}
}
// 请求api
func fansapi(uid string) *follower {
url := "https://api.vtbs.moe/v1/detail/" + uid
resp, err := http.Get(url)
if err != nil {
panic(err)
}
defer resp.Body.Close()
result := &follower{}
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
panic(err)
}
return result
}

View File

@@ -2,7 +2,7 @@
package bilibili
import (
"io/ioutil"
"io"
"net/http"
control "github.com/FloatTech/zbputils/control"
@@ -47,7 +47,7 @@ func init() {
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
body, err := io.ReadAll(res.Body)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return

View File

@@ -1,11 +1,12 @@
package bilibili
import (
"encoding/json"
"errors"
"io/ioutil"
"net/http"
"time"
"github.com/FloatTech/zbputils/web"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
@@ -23,37 +24,62 @@ func init() {
}
id := res.Get("data.result.0.mid").String()
// 获取详情
json := fansapi(id)
fo, err := fansapi(id)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(
"uid: ", json.Mid, "\n",
"名字: ", json.Uname, "\n",
"当前粉丝数: ", json.Follower, "\n",
"24h涨粉数: ", json.Rise, "\n",
"视频投稿数: ", json.Video, "\n",
"直播间id: ", json.Roomid, "\n",
"舰队: ", json.GuardNum, "\n",
"直播总排名: ", json.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", json.Mid, "\n",
"uid: ", fo.Mid, "\n",
"名字: ", fo.Uname, "\n",
"当前粉丝数: ", fo.Follower, "\n",
"24h涨粉数: ", fo.Rise, "\n",
"视频投稿数: ", fo.Video, "\n",
"直播间id: ", fo.Roomid, "\n",
"舰队: ", fo.GuardNum, "\n",
"直播总排名: ", fo.AreaRank, "\n",
"数据来源: ", "https://vtbs.moe/detail/", fo.Mid, "\n",
"数据获取时间: ", time.Now().Format("2006-01-02 15:04:05"),
))
})
}
// 搜索api通过把触发指令传入的昵称找出uid返回
func uid(keyword string) (gjson.Result, error) {
func uid(keyword string) (*gjson.Result, error) {
api := "http://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&&user_type=1&keyword=" + keyword
resp, err := http.Get(api)
data, err := web.GetData(api)
if err != nil {
return gjson.Result{}, err
return nil, err
}
if resp.StatusCode != http.StatusOK {
return gjson.Result{}, errors.New("code not 200")
}
data, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
json := gjson.ParseBytes(data)
if json.Get("data.numResults").Int() == 0 {
return gjson.Result{}, errors.New("查无此人")
return nil, errors.New("查无此人")
}
return json, nil
return &json, nil
}
type follower struct {
Mid int `json:"mid"`
Uname string `json:"uname"`
Video int `json:"video"`
Roomid int `json:"roomid"`
Rise int `json:"rise"`
Follower int `json:"follower"`
GuardNum int `json:"guardNum"`
AreaRank int `json:"areaRank"`
}
// 请求api
func fansapi(uid string) (*follower, error) {
url := "https://api.vtbs.moe/v1/detail/" + uid
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
result := &follower{}
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
return nil, err
}
return result, nil
}

View File

@@ -4,7 +4,7 @@ package github
import (
"errors"
"fmt"
"io/ioutil"
"io"
"net/http"
"net/url"
"strings"
@@ -119,7 +119,7 @@ func netGet(dest string, header http.Header) ([]byte, error) {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

23
plugin/inject/main.go Normal file
View File

@@ -0,0 +1,23 @@
// Package inject 注入指令
package inject
import (
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/control/order"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
func init() {
en := control.Register("inject", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
Help: "注入指令\n" +
"- run[CQ码]",
})
// 运行 CQ 码
en.OnPrefix("run", zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
// 可注入,权限为主人
ctx.Send(message.UnescapeCQCodeText(ctx.State["args"].(string)))
})
}

View File

@@ -2,8 +2,10 @@
package job
import (
"encoding/json"
"hash/crc64"
"strconv"
"strings"
"sync"
"time"
@@ -13,26 +15,29 @@ import (
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/process"
"github.com/FloatTech/zbputils/vevent"
"github.com/FloatTech/zbputils/web"
"github.com/fumiama/cron"
"github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
)
var (
lo map[int64]vevent.Loop
entries map[int64]cron.EntryID // id entryid
mu sync.Mutex
limit = rate.NewLimiter(time.Second*2, 1)
lo map[int64]vevent.Loop
entries = map[int64]cron.EntryID{} // id entryid
matchers = map[int64]*zero.Matcher{}
mu sync.Mutex
limit = rate.NewLimiter(time.Second*2, 1)
en = control.Register("job", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
Help: "定时指令触发器\n- 记录以\"完全匹配关键词\"触发的指令\n- 取消以\"完全匹配关键词\"触发的指令\n- 记录在\"cron\"触发的指令\n- 取消在\"cron\"触发的指令\n- 查看所有触发指令\n- 查看在\"cron\"触发的指令\n- 查看以\"完全匹配关键词\"触发的指令\n- 注入指令结果:任意指令\n- 执行指令:任意指令",
PrivateDataFolder: "job",
})
)
func init() {
en := control.Register("job", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
Help: "定时指令触发器\n- 记录在\"cron\"触发的指令\n- 取消在\"cron\"触发的指令\n- 查看所有触发指令\n- 查看在\"cron\"触发的指令",
PrivateDataFolder: "job",
})
db.DBPath = en.DataFolder() + "job.db"
err := db.Open()
if err != nil {
@@ -42,7 +47,6 @@ func init() {
process.GlobalInitMutex.Lock()
process.SleepAbout1sTo2s()
lo = make(map[int64]vevent.Loop, len(zero.BotConfig.Driver))
entries = map[int64]cron.EntryID{}
for _, drv := range zero.BotConfig.Driver {
id := drv.SelfID()
ids := strconv.FormatInt(id, 36)
@@ -53,9 +57,21 @@ func init() {
if err != nil {
panic(err)
}
db.FindFor(ids, c, "", func() error {
_ = db.FindFor(ids, c, "", func() error {
mu.Lock()
defer mu.Unlock()
if strings.HasPrefix(c.Cron, "fm:") {
m := en.OnFullMatch(c.Cron[3:] /* skip fm: */).SetBlock(true)
m.Handle(generalhandler(c))
matchers[c.ID] = getmatcher(m)
return nil
}
if strings.HasPrefix(c.Cron, "sm:") {
m := en.OnFullMatch(c.Cron[3:] /* skip fm: */).SetBlock(true)
m.Handle(superuserhandler(c))
matchers[c.ID] = getmatcher(m)
return nil
}
eid, err := process.CronTab.AddFunc(c.Cron, inject(id, []byte(c.Cmd)))
if err != nil {
return err
@@ -67,17 +83,7 @@ func init() {
logrus.Infoln("[job]本地环回初始化完成")
process.GlobalInitMutex.Unlock()
}()
en.OnRegex(`^记录在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil, func(ctx *zero.Ctx) bool {
ctx.SendChain(message.Text("您的下一条指令将被记录,在", ctx.State["regex_matched"].([]string)[1], "时触发"))
select {
case <-time.After(time.Second * 120):
ctx.SendChain(message.Text("指令记录超时"))
return false
case e := <-zero.NewFutureEvent("message", 0, false, zero.CheckUser(ctx.Event.UserID)).Next():
ctx.State["job_raw_event"] = e.RawEvent.Raw
return true
}
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
en.OnRegex(`^记录在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
cron := ctx.State["regex_matched"].([]string)[1]
command := ctx.State["job_raw_event"].(string)
c := &cmd{
@@ -92,9 +98,57 @@ func init() {
}
ctx.SendChain(message.Text("成功!"))
})
en.OnRegex(`^取消在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
en.OnRegex(`^记录以"(.*)"触发的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
cron := "fm:" + ctx.State["regex_matched"].([]string)[1]
command := ctx.State["job_new_event"].(gjson.Result).Get("message").Raw
logrus.Debugln("[job] get cmd:", command)
c := &cmd{
ID: idof(cron, command),
Cron: cron,
Cmd: command,
}
err := registercmd(ctx.Event.SelfID, c)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text("成功!"))
})
en.OnRegex(`^记录以"(.*)"触发的代表我执行的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil, logevent).SetBlock(true).Handle(func(ctx *zero.Ctx) {
cron := "sm:" + ctx.State["regex_matched"].([]string)[1]
command := ctx.State["job_raw_event"].(string)
logrus.Debugln("[job] get cmd:", command)
c := &cmd{
ID: idof(cron, command),
Cron: cron,
Cmd: command,
}
err := registercmd(ctx.Event.SelfID, c)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text("成功!"))
})
en.OnRegex(`^取消在"(.*)"触发的指令$`, ctxext.UserOrGrpAdmin, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
cron := ctx.State["regex_matched"].([]string)[1]
err := rmcmd(ctx.Event.SelfID, cron)
err := rmcmd(ctx.Event.SelfID, ctx.Event.UserID, cron)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text("成功!"))
})
en.OnRegex(`^取消以"(.*)"触发的(代表我执行的)?指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
issu := ctx.State["regex_matched"].([]string)[2] != ""
cron := ""
if issu {
cron = "sm:"
} else {
cron = "fm:"
}
cron += ctx.State["regex_matched"].([]string)[1]
err := delcmd(ctx.Event.SelfID, cron)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
@@ -122,7 +176,7 @@ func init() {
}
ctx.SendChain(message.Text(lst))
})
en.OnRegex(`^查看在"(.*)"触发的指令$`, zero.SuperUserPermission, islonotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
en.OnRegex(`^查看在"(.*)"触发的指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
c := &cmd{}
ids := strconv.FormatInt(ctx.Event.SelfID, 36)
cron := ctx.State["regex_matched"].([]string)[1]
@@ -144,12 +198,84 @@ func init() {
}
ctx.SendChain(message.Text(lst))
})
en.OnRegex(`^查看以"(.*)"触发的(代表我执行的)?指令$`, zero.SuperUserPermission, islonotnil, isfirstregmatchnotnil).SetBlock(true).Handle(func(ctx *zero.Ctx) {
c := &cmd{}
ids := strconv.FormatInt(ctx.Event.SelfID, 36)
issu := ctx.State["regex_matched"].([]string)[2] != ""
cron := ""
if issu {
cron = "sm:"
} else {
cron = "fm:"
}
cron += ctx.State["regex_matched"].([]string)[1]
mu.Lock()
defer mu.Unlock()
n, err := db.Count(ids)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
lst := make([]string, 0, n)
err = db.FindFor(ids, c, "WHERE cron='"+cron+"'", func() error {
lst = append(lst, c.Cmd+"\n")
return nil
})
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text(lst))
})
en.OnPrefix("执行指令:", ctxext.UserOrGrpAdmin, islonotnil, func(ctx *zero.Ctx) bool {
return ctx.State["args"].(string) != ""
}, parseArgs).SetBlock(true).Handle(func(ctx *zero.Ctx) {
ev := strings.ReplaceAll(ctx.Event.RawEvent.Raw, "执行指令:", "")
logrus.Debugln("[job] inject:", ev)
inject(ctx.Event.SelfID, binary.StringToBytes(ev))()
})
en.OnPrefix("注入指令结果:", ctxext.UserOrGrpAdmin, islonotnil, func(ctx *zero.Ctx) bool {
return ctx.State["args"].(string) != ""
}, parseArgs).SetBlock(true).Handle(func(ctx *zero.Ctx) {
vevent.NewLoopOf(vevent.NewAPICallerHook(ctx, func(rsp zero.APIResponse, err error) {
if err == nil {
logrus.Debugln("[job] CallerHook returned")
id := message.NewMessageID(rsp.Data.Get("message_id").String())
if id.ID() == 0 {
ctx.SendChain(message.Text("ERROR:未获取到返回结果"))
return
}
msg := ctx.GetMessage(id)
ctx.Event.NativeMessage = json.RawMessage("\"" + msg.Elements.String() + "\"")
ctx.Event.RawMessageID = json.RawMessage(msg.MessageId.String())
ctx.Event.RawMessage = msg.Elements.String()
time.Sleep(time.Second * 5) // 防止风控
ctx.Event.Time = time.Now().Unix()
ctx.DeleteMessage(id)
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
err = json.NewEncoder(w).Encode(ctx.Event)
})
if err != nil {
cl()
ctx.SendChain(message.Text("ERROR:", err))
return
}
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
inject(ctx.Event.SelfID, vev)()
cl()
}
})).Echo(binary.StringToBytes(strings.ReplaceAll(ctx.Event.RawEvent.Raw, "注入指令结果:", "")))
})
}
func islonotnil(ctx *zero.Ctx) bool {
return len(lo) > 0
}
func isfirstregmatchnotnil(ctx *zero.Ctx) bool {
return ctx.State["regex_matched"].([]string)[1] != ""
}
func inject(bot int64, response []byte) func() {
return func() {
if limit.Acquire() {
@@ -173,19 +299,243 @@ func addcmd(bot int64, c *cmd) error {
return db.Insert(strconv.FormatInt(bot, 36), c)
}
func rmcmd(bot int64, cron string) error {
func registercmd(bot int64, c *cmd) error {
mu.Lock()
defer mu.Unlock()
m := en.OnFullMatch(c.Cron[3:] /* skip fm: or sm: */).SetBlock(true)
if strings.HasPrefix(c.Cron, "sm:") {
m.Handle(superuserhandler(c))
} else {
m.Handle(generalhandler(c))
}
matchers[c.ID] = getmatcher(m)
return db.Insert(strconv.FormatInt(bot, 36), c)
}
func generalhandler(c *cmd) zero.Handler {
return func(ctx *zero.Ctx) {
ctx.Event.NativeMessage = json.RawMessage(c.Cmd) // c.Cmd only have message
ctx.Event.Time = time.Now().Unix()
var err error
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
err = json.NewEncoder(w).Encode(ctx.Event)
})
if err != nil {
cl()
ctx.SendChain(message.Text("ERROR:", err))
return
}
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
inject(ctx.Event.SelfID, vev)()
cl()
}
}
func superuserhandler(c *cmd) zero.Handler {
e := &zero.Event{Sender: new(zero.User)}
err := json.Unmarshal(binary.StringToBytes(c.Cmd), e)
return func(ctx *zero.Ctx) {
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.Event.UserID = e.UserID
ctx.Event.RawMessage = e.RawMessage
ctx.Event.Sender = e.Sender
ctx.Event.NativeMessage = e.NativeMessage
vev, cl := binary.OpenWriterF(func(w *binary.Writer) {
err = json.NewEncoder(w).Encode(ctx.Event)
})
if err != nil {
cl()
ctx.SendChain(message.Text("ERROR:", err))
return
}
logrus.Debugln("[job] inject:", binary.BytesToString(vev))
inject(ctx.Event.SelfID, vev)()
cl()
}
}
func rmcmd(bot, caller int64, cron string) error {
c := &cmd{}
mu.Lock()
defer mu.Unlock()
bots := strconv.FormatInt(bot, 36)
e := new(zero.Event)
var delcmd []string
err := db.FindFor(bots, c, "WHERE cron='"+cron+"'", func() error {
err := json.Unmarshal(binary.StringToBytes(c.Cmd), e)
if err != nil {
return err
}
if e.UserID != caller {
return nil
}
eid, ok := entries[c.ID]
if ok {
process.CronTab.Remove(eid)
delete(entries, c.ID)
delcmd = append(delcmd, "id="+strconv.FormatInt(c.ID, 10))
}
return nil
})
db.Del(bots, "WHERE cron='"+cron+"'")
return err
if err != nil {
return err
}
if len(delcmd) > 0 {
return db.Del(bots, "WHERE "+strings.Join(delcmd, " or "))
}
return nil
}
func delcmd(bot int64, cron string) error {
c := &cmd{}
mu.Lock()
defer mu.Unlock()
bots := strconv.FormatInt(bot, 36)
var delcmd []string
err := db.FindFor(bots, c, "WHERE cron='"+cron+"'", func() error {
m, ok := matchers[c.ID]
if ok {
m.Delete()
delete(matchers, c.ID)
delcmd = append(delcmd, "id="+strconv.FormatInt(c.ID, 10))
}
return nil
})
if err != nil {
return err
}
if len(delcmd) > 0 {
return db.Del(bots, "WHERE "+strings.Join(delcmd, " or "))
}
return nil
}
func parseArgs(ctx *zero.Ctx) bool {
cmds := ctx.State["args"].(string)
if !strings.Contains(cmds, "?::") && !strings.Contains(cmds, "!::") {
return true
}
args := make(map[int]string)
for strings.Contains(ctx.Event.RawEvent.Raw, "?::") {
start := strings.Index(ctx.Event.RawEvent.Raw, "?::")
msgend := strings.Index(ctx.Event.RawEvent.Raw[start+3:], "::")
if msgend < 0 {
ctx.SendChain(message.Text("ERROR:找不到结束的::"))
return false
}
msgend += start + 3
numend := strings.Index(ctx.Event.RawEvent.Raw[msgend+2:], "!")
if numend <= 0 {
ctx.SendChain(message.Text("ERROR:找不到结束的!"))
return false
}
numend += msgend + 2
logrus.Debugln("[job]", start, msgend, numend)
msg := ctx.Event.RawEvent.Raw[start+3 : msgend]
arg, err := strconv.Atoi(ctx.Event.RawEvent.Raw[msgend+2 : numend])
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
arr, ok := args[arg]
if !ok {
var id message.MessageID
if msg == "" {
id = ctx.SendChain(message.At(ctx.Event.UserID), message.Text("请输入参数", arg))
} else {
id = ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", arg, "] ", msg))
}
select {
case <-time.After(time.Second * 120):
ctx.Send(message.ReplyWithMessage(id, message.Text("参数读取超时")))
if msg[0] != '?' {
return false
}
case e := <-zero.NewFutureEvent("message", 0, true, zero.CheckUser(ctx.Event.UserID)).Next():
args[arg] = e.Message.String()
arr = args[arg]
process.SleepAbout1sTo2s()
ctx.SendChain(message.Reply(e.MessageID), message.Text("已记录"))
process.SleepAbout1sTo2s()
}
}
ctx.Event.RawEvent.Raw = ctx.Event.RawEvent.Raw[:start] + arr + ctx.Event.RawEvent.Raw[numend+1:]
}
args = make(map[int]string)
for strings.Contains(ctx.Event.RawEvent.Raw, "!::") {
start := strings.Index(ctx.Event.RawEvent.Raw, "!::")
msgend := strings.Index(ctx.Event.RawEvent.Raw[start+3:], "::")
if msgend < 0 {
ctx.SendChain(message.Text("ERROR:找不到结束的::"))
return false
}
msgend += start + 3
numend := strings.Index(ctx.Event.RawEvent.Raw[msgend+2:], "!")
if numend <= 0 {
ctx.SendChain(message.Text("ERROR:找不到结束的!"))
return false
}
numend += msgend + 2
logrus.Debugln("[job]", start, msgend, numend)
u := ctx.Event.RawEvent.Raw[start+3 : msgend]
if u == "" {
return false
}
arg, err := strconv.Atoi(ctx.Event.RawEvent.Raw[msgend+2 : numend])
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
arr, ok := args[arg]
if !ok {
isnilable := u[0] == '?'
if isnilable {
u = u[1:]
if u == "" {
return false
}
}
b, err := web.GetData(u)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
if !isnilable {
return false
}
}
if len(b) > 0 {
type fakejson struct {
Arg string `json:"arg"`
}
f := fakejson{Arg: binary.BytesToString(b)}
w := binary.SelectWriter()
defer binary.PutWriter(w)
_ = json.NewEncoder(w).Encode(&f)
arr = w.String()[8 : w.Len()-3]
args[arg] = arr
}
}
w := binary.SelectWriter()
w.WriteString(ctx.Event.RawEvent.Raw[:start])
w.WriteString(arr)
w.WriteString(ctx.Event.RawEvent.Raw[numend+1:])
ctx.Event.RawEvent.Raw = string(w.Bytes())
binary.PutWriter(w)
}
return true
}
func logevent(ctx *zero.Ctx) bool {
ctx.SendChain(message.Text("您的下一条指令将被记录,在", ctx.State["regex_matched"].([]string)[1], "时触发"))
select {
case <-time.After(time.Second * 120):
ctx.SendChain(message.Text("指令记录超时"))
return false
case e := <-zero.NewFutureEvent("message", 0, true, zero.CheckUser(ctx.Event.UserID)).Next():
ctx.State["job_raw_event"] = e.RawEvent.Raw
ctx.State["job_new_event"] = e.RawEvent
return true
}
}

16
plugin/job/matcher.go Normal file
View File

@@ -0,0 +1,16 @@
package job
import (
"unsafe"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
)
type matcherinstance struct {
m *zero.Matcher
}
func getmatcher(m control.Matcher) *zero.Matcher {
return (*matcherinstance)(unsafe.Pointer(&m)).m
}

View File

@@ -2,8 +2,6 @@
package lolicon
import (
"io/ioutil"
"net/http"
"strings"
"time"
@@ -16,6 +14,7 @@ import (
"github.com/FloatTech/zbputils/img/pool"
"github.com/FloatTech/zbputils/math"
"github.com/FloatTech/zbputils/process"
"github.com/FloatTech/zbputils/web"
"github.com/FloatTech/zbputils/control/order"
)
@@ -38,17 +37,11 @@ func init() {
Handle(func(ctx *zero.Ctx) {
go func() {
for i := 0; i < math.Min(cap(queue)-len(queue), 2); i++ {
resp, err := http.Get(api)
data, err := web.GetData(api)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
continue
}
if resp.StatusCode != http.StatusOK {
ctx.SendChain(message.Text("ERROR: code ", resp.StatusCode))
continue
}
data, _ := ioutil.ReadAll(resp.Body)
resp.Body.Close()
json := gjson.ParseBytes(data)
if e := json.Get("error").Str; e != "" {
ctx.SendChain(message.Text("ERROR: ", e))
@@ -58,7 +51,7 @@ func init() {
url = strings.ReplaceAll(url, "i.pixiv.cat", "i.pixiv.re")
name := url[strings.LastIndex(url, "/")+1 : len(url)-4]
m, err := pool.GetImage(name)
if err != nil && err != pool.ErrImgFileAsync {
if err != nil {
m.SetFile(url)
_, err = m.Push(ctxext.SendToSelf(ctx), ctxext.GetMessage(ctx))
process.SleepAbout1sTo2s()

View File

@@ -509,15 +509,6 @@ func init() { // 插件主体
}
ctx.SendChain(message.Text("找不到服务!"))
})
// 运行 CQ 码
engine.OnRegex(`^run(.*)$`, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
var cmd = ctx.State["regex_matched"].([]string)[1]
cmd = strings.ReplaceAll(cmd, "&#91;", "[")
cmd = strings.ReplaceAll(cmd, "&#93;", "]")
// 可注入,权限为主人
ctx.Send(cmd)
})
// 根据 gist 自动同意加群
// 加群请在github新建一个gist其文件名为本群群号的字符串的md5(小写)内容为一行是当前unix时间戳(10分钟内有效)。
// 然后请将您的用户名和gist哈希(小写)按照username/gisthash的格式填写到回答即可。

View File

@@ -5,7 +5,7 @@ import (
"crypto/md5"
"encoding/hex"
"fmt"
"io/ioutil"
"io"
"net/http"
"net/url"
"strings"
@@ -231,7 +231,7 @@ func netGet(url string, header http.Header) []byte {
return nil
}
defer res.Body.Close()
result, _ := ioutil.ReadAll(res.Body)
result, _ := io.ReadAll(res.Body)
return result
}
@@ -245,6 +245,6 @@ func netPost(url string, data url.Values, header http.Header) []byte {
return nil
}
defer res.Body.Close()
result, _ := ioutil.ReadAll(res.Body)
result, _ := io.ReadAll(res.Body)
return result
}

View File

@@ -2,7 +2,7 @@
package nbnhhsh
import (
"io/ioutil"
"io"
"net/http"
"net/url"
"strings"
@@ -31,7 +31,7 @@ func getValue(text string) []string {
urlValues.Add("text", text)
resp, err := http.PostForm("https://lab.magiconch.com/api/nbnhhsh/guess", urlValues)
if err == nil {
body, err := ioutil.ReadAll(resp.Body)
body, err := io.ReadAll(resp.Body)
if err == nil {
resp.Body.Close()
json := gjson.ParseBytes(body)

View File

@@ -3,7 +3,7 @@ package novel
import (
"fmt"
"io/ioutil"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
@@ -164,7 +164,7 @@ func search(searchKey string) (searchHTML string) {
log.Errorln("[novel]", err)
}
defer searchResp.Body.Close()
searchData, err := ioutil.ReadAll(searchResp.Body)
searchData, err := io.ReadAll(searchResp.Body)
if err != nil {
log.Errorf("[novel] get response for url=%s got error=%s\n", searchURL, err.Error())
}

View File

@@ -3,7 +3,7 @@ package runcode
import (
"errors"
"io/ioutil"
"io"
"net/http"
"net/url"
"strings"
@@ -104,9 +104,10 @@ func init() {
"JavaScript || TypeScript || PHP || Shell \n" +
"Kotlin || Rust || Erlang || Ruby || Swift \n" +
"R || VB || Py2 || Perl || Pascal || Scala",
}).ApplySingle(ctxext.DefaultSingle).OnRegex(`^>runcode\s(.+?)\s([\s\S]+)$`).SetBlock(true).Limit(ctxext.LimitByUser).
}).ApplySingle(ctxext.DefaultSingle).OnRegex(`^>runcode(raw)?\s(.+?)\s([\s\S]+)$`).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
language := ctx.State["regex_matched"].([]string)[1]
israw := ctx.State["regex_matched"].([]string)[1] != ""
language := ctx.State["regex_matched"].([]string)[2]
language = strings.ToLower(language)
if runType, exist := table[language]; !exist {
// 不支持语言
@@ -116,10 +117,9 @@ func init() {
)
} else {
// 执行运行
block := ctx.State["regex_matched"].([]string)[2]
block = message.UnescapeCQCodeText(block)
if block == "help" {
// 输出模板
block := message.UnescapeCQText(ctx.State["regex_matched"].([]string)[3])
switch block {
case "help":
ctx.SendChain(
message.Text("> ", ctx.Event.Sender.NickName, " ", language, "-template:\n"),
message.Text(
@@ -127,7 +127,7 @@ func init() {
templates[language],
),
)
} else {
default:
if output, err := runCode(block, runType); err != nil {
// 运行失败
ctx.SendChain(
@@ -136,10 +136,14 @@ func init() {
)
} else {
// 运行成功
ctx.SendChain(
message.Text("> ", ctx.Event.Sender.NickName, "\n"),
message.Text(output),
)
if israw {
ctx.SendChain(message.Text(output))
} else {
ctx.SendChain(
message.Text("> ", ctx.Event.Sender.NickName, "\n"),
message.Text(output),
)
}
}
}
}
@@ -177,7 +181,7 @@ func runCode(code string, runType [2]string) (string, error) {
if body.StatusCode != http.StatusOK {
return "", errors.New("code not 200")
}
res, err := ioutil.ReadAll(body.Body)
res, err := io.ReadAll(body.Body)
if err != nil {
return "", err
}

View File

@@ -54,7 +54,7 @@ func init() { // 插件主体
}
logrus.Debugln("[sausenao]开始下载", n)
err1 := illust.DownloadToCache(i)
if err != pool.ErrImgFileAsync && err1 == nil {
if err1 == nil {
m.SetFile(f)
_, _ = m.Push(ctxext.SendToSelf(ctx), ctxext.GetMessage(ctx))
}

View File

@@ -163,10 +163,8 @@ func (p *imgpool) push(ctx *zero.Ctx, imgtype string, illust *pixiv.Illust) {
return
}
}
if err != imagepool.ErrImgFileAsync {
m.SetFile(f)
_, _ = m.Push(ctxext.SendToSelf(ctx), ctxext.GetMessage(ctx))
}
m.SetFile(f)
_, _ = m.Push(ctxext.SendToSelf(ctx), ctxext.GetMessage(ctx))
msg = message.Image("file:///" + f)
} else {
msg = message.Image(m.String())

View File

@@ -23,7 +23,7 @@ func init() {
PublicDataFolder: "Chat",
})
go func() {
data, err := file.GetLazyData(engine.DataFolder()+"kimoi.json", true, true)
data, err := file.GetLazyData(engine.DataFolder()+"kimoi.json", true, false)
if err != nil {
panic(err)
}

View File

@@ -2,11 +2,6 @@
package translation
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
@@ -14,29 +9,11 @@ import (
control "github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/process"
"github.com/FloatTech/zbputils/web"
"github.com/FloatTech/zbputils/control/order"
)
func tl(d string) ([]byte, error) {
url := "https://api.cloolc.club/fanyi?data=" + d
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
data, err := ioutil.ReadAll(resp.Body)
_ = resp.Body.Close()
if err != nil {
return nil, err
}
if code := resp.StatusCode; code != 200 {
// 如果返回不是200则立刻抛出错误
errmsg := fmt.Sprintf("code %d", code)
return nil, errors.New(errmsg)
}
return data, err
}
func init() {
control.Register("translation", order.AcquirePrio(), &control.Options{
DisableOnDefault: false,
@@ -45,11 +22,11 @@ func init() {
}).OnRegex(`^>TL\s(-.{1,10}? )?(.*)$`).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
msg := []string{ctx.State["regex_matched"].([]string)[2]}
rely, err := tl(msg[0])
data, err := web.GetData("https://api.cloolc.club/fanyi?data=" + msg[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
}
info := gjson.ParseBytes(rely)
info := gjson.ParseBytes(data)
repo := info.Get("data.0")
process.SleepAbout1sTo2s()
ctx.SendChain(message.Text(repo.Get("value.0")))

View File

@@ -2,7 +2,7 @@
package model
import (
"io/ioutil"
"io"
"math/rand"
"net/http"
"os"
@@ -199,7 +199,7 @@ func (vdb *VtbDB) GetVtbList() (uidList []string) {
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
bytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Errorln(err)
return
@@ -262,7 +262,7 @@ func (vdb *VtbDB) StoreVtb(uid string) {
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
bytes, err := io.ReadAll(resp.Body)
if err != nil {
log.Errorln(err)
return

View File

@@ -3,9 +3,9 @@ package wtf
import (
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"github.com/FloatTech/zbputils/web"
)
/* JS path getter for https://wtf.hiigara.net/ranking
@@ -134,12 +134,7 @@ func (w *wtf) predict(names ...string) (string, error) {
name += "/" + url.QueryEscape(n)
}
u := apiprefix + w.path + name
resp, err := http.Get(u)
if err != nil {
return "", err
}
r, err := io.ReadAll(resp.Body)
resp.Body.Close()
r, err := web.GetData(u)
if err != nil {
return "", err
}