Compare commits

..

19 Commits

Author SHA1 Message Date
fumiama
18def7c624 💩👌 make lint happy 2022-01-03 00:46:49 +08:00
fumiama
59a731df88 升级依赖 2022-01-03 00:36:40 +08:00
github-actions[bot]
6186356496 🎨 改进代码样式 2022-01-02 16:26:49 +00:00
himawari
045ee091a7 增加文字转图片&拟声鸟 (#96)
* feat:添加文字转图片,改造长文字

* fix:修改log

* fix:修改条件

* fix:不保存图片

* fix:增加block和优先级

* fix:文件夹首字母大写

* fix:修改解签为图片

* feat:添加拟声鸟

* fix:清理缓存

* fix:换一个音频

* fix:小修格式

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:修一下lint

* fix:10s一次

* fix:10s一次

* fix:修lint
2022-01-03 00:26:00 +08:00
github-actions[bot]
a69d985139 🎨 改进代码样式 2022-01-02 14:13:19 +00:00
fumiama
c13641dd1d ✏️ 修复 waitgroup 错误 2022-01-02 22:12:40 +08:00
fumiama
f0fc5d6598 同步 data 2022-01-02 22:06:54 +08:00
fumiama
2348039c16 ✏️ 加快 reg 处理速度 2022-01-02 15:06:35 +08:00
fumiama
7f8d34e8a0 ✏️ 修复 kanban panic 2022-01-02 14:09:27 +08:00
fumiama
205036b658 🎨 优化 win logrus 色彩显示 2021-12-30 12:32:31 +08:00
fumiama
9519896d04 remove apple in nightly 2021-12-27 17:10:10 +08:00
fumiama
aa83b63617 win 下 log 支持颜色 2021-12-27 16:59:07 +08:00
源文雨
3e89a372b3 Update main_win.go 2021-12-27 16:53:20 +08:00
源文雨
d464695b66 win 下 log 支持颜色 2021-12-27 16:51:53 +08:00
fumiama
657532f7e5 make lint happy 2021-12-26 22:21:00 +08:00
github-actions[bot]
3f69308603 🎨 改进代码样式 2021-12-26 14:00:48 +00:00
himawari
486160fc57 添加cp短打 (#94)
* feat:添加cp短打插件

* feat:匹配中英文标点符号和中文字符
2021-12-26 22:00:02 +08:00
fumiama
3939e0760f make lint happy 2021-12-26 21:59:48 +08:00
fumiama
16624a9596 ✏️ 修复 manager 定时器错误 2021-12-26 16:05:05 +08:00
44 changed files with 1055 additions and 425 deletions

View File

@@ -15,13 +15,9 @@ jobs:
strategy:
matrix:
# build and publish in parallel: linux/386, linux/amd64, windows/386, windows/amd64, darwin/amd64, darwin/arm64
goos: [linux, windows, darwin]
goos: [linux, windows]
goarch: ["386", amd64, arm, arm64]
exclude:
- goos: darwin
goarch: arm
- goos: darwin
goarch: "386"
- goos: windows
goarch: arm
- goos: windows

View File

@@ -238,6 +238,9 @@ zerobot -h -t token -u url [-d|w] [-g 监听地址:端口] qq1 qq2 qq3 ...
- **藏头诗** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_cangtoushi"`
- [x] 藏头诗[xxx]
- [x] 藏尾诗[xxx]
- **cp短打** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_cpstory"`
- [x] 组cp[@xxx][@xxx]
- [x] 组cp大老师 雪乃
- **TODO...**
## 使用方法

View File

@@ -10,13 +10,14 @@ import (
"strings"
"sync"
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
var (
@@ -73,7 +74,7 @@ func (m *Control) Enable(groupID int64) {
err = db.Insert(m.service, &c)
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
log.Errorf("[control] %v", err)
}
}
@@ -92,7 +93,7 @@ func (m *Control) Disable(groupID int64) {
err = db.Insert(m.service, &c)
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
log.Errorf("[control] %v", err)
}
}
@@ -104,7 +105,7 @@ func (m *Control) Reset(groupID int64) {
err := db.Del(m.service, "WHERE gid = "+strconv.FormatInt(groupID, 10))
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
log.Errorf("[control] %v", err)
}
}
}
@@ -113,13 +114,13 @@ func (m *Control) Reset(groupID int64) {
func (m *Control) IsEnabledIn(gid int64) bool {
var c grpcfg
var err error
logrus.Debugln("[control] IsEnabledIn recv gid =", gid)
log.Debugln("[control] IsEnabledIn recv gid =", gid)
if gid != 0 {
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
m.RUnlock()
if err == nil && gid == c.GroupID {
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable&1)
log.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable&1)
return c.Disable&1 == 0
}
}
@@ -127,7 +128,7 @@ func (m *Control) IsEnabledIn(gid int64) bool {
err = db.Find(m.service, &c, "WHERE gid = 0")
m.RUnlock()
if err == nil && c.GroupID == 0 {
logrus.Debugf("[control] plugin %s of all : %d", m.service, c.Disable&1)
log.Debugf("[control] plugin %s of all : %d", m.service, c.Disable&1)
return c.Disable&1 == 0
}
return !m.options.DisableOnDefault
@@ -137,14 +138,14 @@ func (m *Control) IsEnabledIn(gid int64) bool {
func (m *Control) Ban(uid, gid int64) {
var err error
var digest [16]byte
logrus.Debugln("[control] Ban recv gid =", gid, "uid =", uid)
log.Debugln("[control] Ban recv gid =", gid, "uid =", uid)
if gid != 0 { // 特定群
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
m.RLock()
err = db.Insert(m.service+"ban", &ban{ID: int64(binary.LittleEndian.Uint64(digest[:8])), UserID: uid, GroupID: gid})
m.RUnlock()
if err == nil {
logrus.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, gid, uid)
log.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, gid, uid)
return
}
}
@@ -154,20 +155,20 @@ func (m *Control) Ban(uid, gid int64) {
err = db.Insert(m.service+"ban", &ban{ID: int64(binary.LittleEndian.Uint64(digest[:8])), UserID: uid, GroupID: 0})
m.RUnlock()
if err == nil {
logrus.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, uid)
log.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, uid)
}
}
// Permit 允许某人在某群使用本插件
func (m *Control) Permit(uid, gid int64) {
var digest [16]byte
logrus.Debugln("[control] Permit recv gid =", gid, "uid =", uid)
log.Debugln("[control] Permit recv gid =", gid, "uid =", uid)
if gid != 0 { // 特定群
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
m.RLock()
_ = db.Del(m.service+"ban", "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
m.RUnlock()
logrus.Debugf("[control] plugin %s is permitted in grp %d for usr %d.", m.service, gid, uid)
log.Debugf("[control] plugin %s is permitted in grp %d for usr %d.", m.service, gid, uid)
return
}
// 所有群
@@ -175,7 +176,7 @@ func (m *Control) Permit(uid, gid int64) {
m.RLock()
_ = db.Del(m.service+"ban", "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
m.RUnlock()
logrus.Debugf("[control] plugin %s is permitted in all grp for usr %d.", m.service, uid)
log.Debugf("[control] plugin %s is permitted in all grp for usr %d.", m.service, uid)
}
// IsBannedIn 某人是否在某群被 ban
@@ -183,14 +184,14 @@ func (m *Control) IsBannedIn(uid, gid int64) bool {
var b ban
var err error
var digest [16]byte
logrus.Debugln("[control] IsBannedIn recv gid =", gid, "uid =", uid)
log.Debugln("[control] IsBannedIn recv gid =", gid, "uid =", uid)
if gid != 0 {
digest = md5.Sum(helper.StringToBytes(fmt.Sprintf("%d_%d", uid, gid)))
m.RLock()
err = db.Find(m.service+"ban", &b, "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
m.RUnlock()
if err == nil && gid == b.GroupID && uid == b.UserID {
logrus.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, b.GroupID, b.UserID)
log.Debugf("[control] plugin %s is banned in grp %d for usr %d.", m.service, b.GroupID, b.UserID)
return true
}
}
@@ -199,7 +200,7 @@ func (m *Control) IsBannedIn(uid, gid int64) bool {
err = db.Find(m.service+"ban", &b, "WHERE id = "+strconv.FormatInt(int64(binary.LittleEndian.Uint64(digest[:8])), 10))
m.RUnlock()
if err == nil && b.GroupID == 0 && uid == b.UserID {
logrus.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, b.UserID)
log.Debugf("[control] plugin %s is banned in all grp for usr %d.", m.service, b.UserID)
return true
}
return false
@@ -209,13 +210,13 @@ func (m *Control) IsBannedIn(uid, gid int64) bool {
func (m *Control) GetData(gid int64) int64 {
var c grpcfg
var err error
logrus.Debugln("[control] IsEnabledIn recv gid =", gid)
log.Debugln("[control] IsEnabledIn recv gid =", gid)
if gid != 0 {
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
m.RUnlock()
if err == nil && gid == c.GroupID {
logrus.Debugf("[control] plugin %s of grp %d : %x", m.service, c.GroupID, c.Disable>>1)
log.Debugf("[control] plugin %s of grp %d : %x", m.service, c.GroupID, c.Disable>>1)
return c.Disable >> 1
}
}
@@ -223,7 +224,7 @@ func (m *Control) GetData(gid int64) int64 {
err = db.Find(m.service, &c, "WHERE gid = 0")
m.RUnlock()
if err == nil && c.GroupID == 0 {
logrus.Debugf("[control] plugin %s of all : %x", m.service, c.Disable>>1)
log.Debugf("[control] plugin %s of all : %x", m.service, c.Disable>>1)
return c.Disable >> 1
}
return 0
@@ -242,12 +243,12 @@ func (m *Control) SetData(groupID int64, data int64) error {
}
}
c.Disable |= data << 1
logrus.Debugf("[control] set plugin %s of all : %x", m.service, data)
log.Debugf("[control] set plugin %s of all : %x", m.service, data)
m.Lock()
err = db.Insert(m.service, &c)
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
log.Errorf("[control] %v", err)
}
return err
}
@@ -260,7 +261,7 @@ func (m *Control) Handler(ctx *zero.Ctx) bool {
// 个人用户
return m.IsEnabledIn(-ctx.Event.UserID)
}
logrus.Debugln("[control] handler get gid =", grp)
log.Debugln("[control] handler get gid =", grp)
return m.IsEnabledIn(grp) && !m.IsBannedIn(ctx.Event.UserID, grp)
}
@@ -312,7 +313,7 @@ func init() {
zero.OnCommandGroup([]string{
"启用", "enable", "禁用", "disable",
"全局启用", "enableall", "全局禁用", "disableall",
}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
}, userOrGrpAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
@@ -337,7 +338,7 @@ func init() {
}
})
zero.OnCommandGroup([]string{"还原", "reset"}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
zero.OnCommandGroup([]string{"还原", "reset"}, userOrGrpAdmin).SetBlock(true).FirstPriority().Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
@@ -357,7 +358,7 @@ func init() {
zero.OnCommandGroup([]string{
"禁止", "ban", "允许", "permit",
"全局禁止", "banall", "全局允许", "permitall",
}, zero.OnlyGroup, zero.AdminPermission).Handle(func(ctx *zero.Ctx) {
}, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).FirstPriority().Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
args := strings.Split(model.Args, " ")
@@ -395,7 +396,7 @@ func init() {
ctx.SendChain(message.Text("参数错误!"))
})
zero.OnCommandGroup([]string{"用法", "usage"}, userOrGrpAdmin).
zero.OnCommandGroup([]string{"用法", "usage"}, userOrGrpAdmin).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
@@ -411,7 +412,7 @@ func init() {
}
})
zero.OnCommandGroup([]string{"服务列表", "service_list"}, userOrGrpAdmin).
zero.OnCommandGroup([]string{"服务列表", "service_list"}, userOrGrpAdmin).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
msg := "--------服务列表--------\n发送\"/用法 name\"查看详情"
i := 0
@@ -429,15 +430,9 @@ func init() {
ctx.SendChain(message.Text(msg))
})
zero.OnCommandGroup([]string{"服务详情", "service_detail"}, userOrGrpAdmin, zero.OnlyGroup).
zero.OnCommandGroup([]string{"服务详情", "service_detail"}, userOrGrpAdmin).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
var m message.Message
m = append(m,
message.CustomNode(
zero.BotConfig.NickName[0],
ctx.Event.SelfID,
"---服务详情---",
))
text := "---服务详情---\n"
i := 0
ForEach(func(key string, manager *Control) bool {
service, _ := Lookup(key)
@@ -450,19 +445,14 @@ func init() {
msg += "○" + key
}
msg += "\n" + help
m = append(m,
message.CustomNode(
zero.BotConfig.NickName[0],
ctx.Event.SelfID,
msg,
))
text += msg + "\n\n"
return true
})
if id := ctx.SendGroupForwardMessage(
ctx.Event.GroupID,
m,
).Get("message_id").Int(); id == 0 {
data, err := txt2img.RenderToBase64(text, 40, 20)
if err != nil {
log.Errorf("[control] %v", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
})

2
data

Submodule data updated: 61349e6e05...6749b772b9

52
go.mod
View File

@@ -6,7 +6,7 @@ require (
github.com/FloatTech/AnimeAPI v1.1.11
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4
github.com/FloatTech/bot-manager v1.0.1-0.20211112011524-85b9895271ed
github.com/antchfx/htmlquery v1.2.3
github.com/antchfx/htmlquery v1.2.4
github.com/corona10/goimagehash v1.0.3
github.com/fogleman/gg v1.3.0
github.com/fumiama/cron v1.3.0
@@ -18,62 +18,64 @@ require (
github.com/gorilla/websocket v1.4.2
github.com/jinzhu/gorm v1.9.16
github.com/logoove/sqlite v1.13.0
github.com/mattn/go-runewidth v0.0.13
github.com/mroth/weightedrand v0.4.1
github.com/shirou/gopsutil/v3 v3.21.11
github.com/shirou/gopsutil/v3 v3.21.12
github.com/sirupsen/logrus v1.8.1
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816
github.com/tidwall/gjson v1.12.1
github.com/wdvxdr1123/ZeroBot v1.4.1
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
golang.org/x/text v0.3.6
golang.org/x/text v0.3.7
)
require (
github.com/FloatTech/imgfactory v0.1.1 // indirect
github.com/antchfx/xpath v1.1.6 // indirect
github.com/antchfx/xpath v1.2.0 // indirect
github.com/disintegration/imaging v1.6.2 // indirect
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-playground/validator/v10 v10.4.1 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/leodido/go-urn v1.2.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/tklauser/numcpus v0.3.0 // indirect
github.com/ugorji/go/codec v1.1.7 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/mod v0.3.0 // indirect
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f // indirect
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78 // indirect
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/tools v0.1.8 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.34.0 // indirect
modernc.org/ccgo/v3 v3.11.2 // indirect
modernc.org/libc v1.11.3 // indirect
modernc.org/cc/v3 v3.35.22 // indirect
modernc.org/ccgo/v3 v3.14.0 // indirect
modernc.org/libc v1.13.2 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.0.5 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/sqlite v1.13.0 // indirect
modernc.org/sqlite v1.14.3 // indirect
modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect
)

169
go.sum
View File

@@ -16,10 +16,15 @@ github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
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/htmlquery v1.2.4 h1:qLteofCMe/KGovBI6SQgmou2QNyedFUW+pE+BpeZ494=
github.com/antchfx/htmlquery v1.2.4/go.mod h1:2xO6iu3EVWs7R2JYqBbp8YzG50gj/ofqs5/0VZoDZLc=
github.com/antchfx/xpath v1.1.6 h1:6sVh6hB5T6phw1pFpHRQ+C4bd8sNI+O58flqtg7h0R0=
github.com/antchfx/xpath v1.1.6/go.mod h1:Yee4kTMuNiPYJ7nSNorELQMr1J33uOpXDMByNYhvtNk=
github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/corona10/goimagehash v1.0.3 h1:NZM518aKLmoNluluhfHGxT3LGOnrojrxhGn63DR/CZA=
github.com/corona10/goimagehash v1.0.3/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
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=
@@ -57,10 +62,16 @@ github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBY
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0=
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
@@ -69,6 +80,8 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
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.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
@@ -80,6 +93,8 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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=
@@ -93,12 +108,22 @@ github.com/jinzhu/now v1.0.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
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/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
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/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/logoove/sqlite v1.13.0 h1:XM7QKK9R3tm8o7bI75R3zmwYBFQ5S3Jqg+XCaqsAMQQ=
@@ -107,14 +132,24 @@ github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
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-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
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=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b h1:6Xjqolv/0DDdUqlpnsTomXQvjvvkz7Ux7TcMALvozEw=
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/mroth/weightedrand v0.4.1 h1:rHcbUBopmi/3x4nnrvwGJBhX9d0vk+KgoLUZeDP6YyI=
github.com/mroth/weightedrand v0.4.1/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
@@ -122,6 +157,7 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -130,11 +166,17 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/shirou/gopsutil v3.21.8+incompatible h1:sh0foI8tMRlCidUJR+KzqWYWxrkuuPIGiO6Vp+KXdCU=
github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v3 v3.21.11 h1:d5tOAP5+bmJ8Hf2+4bxOSkQ/64+sjEbjU9nSW9nJgG0=
github.com/shirou/gopsutil/v3 v3.21.11/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA=
github.com/shirou/gopsutil/v3 v3.21.12 h1:VoGxEW2hpmz0Vt3wUvHIl9fquzYLNpVpgNNB7pGJimA=
github.com/shirou/gopsutil/v3 v3.21.12/go.mod h1:BToYZVTlSVlfazpDDYFnsVZLaoRG+g8ufT6fPQLdJzA=
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=
@@ -143,10 +185,10 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
github.com/tdf1939/ZeroBot-Plugin-Gif v0.0.0-20210828060956-389b1dc33652/go.mod h1:bkxKi7un9gCDvUUZAiIJF6k90pyj8rmxiXLJkiHcsMY=
github.com/tdf1939/img v0.0.0-20210827153520-90cb4e9580a3/go.mod h1:FgTEOcosTWrkOr7++gbtPSj1rX5loRWrf/AL+hm3Cnw=
@@ -167,8 +209,12 @@ github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2bi
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/wdvxdr1123/ZeroBot v1.2.2/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
github.com/wdvxdr1123/ZeroBot v1.2.3/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
github.com/wdvxdr1123/ZeroBot v1.2.4/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
@@ -184,12 +230,17 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
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/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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=
@@ -198,8 +249,11 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
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-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/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=
@@ -217,20 +271,30 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/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.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
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/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
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=
@@ -242,14 +306,21 @@ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+Rur
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
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.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
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=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
@@ -257,12 +328,64 @@ modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.34.0 h1:dFhZc/HKR3qp92sYQxKRRaDMz+sr1bwcFD+m7LSCrAs=
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/cc/v3 v3.35.22 h1:BzShpwCAP7TWzFppM4k2t03RhXhgYqaibROWkrWq7lE=
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
modernc.org/ccgo/v3 v3.11.2 h1:gqa8PQ2v7SjrhHCgxUO5dzoAJWSLAveJqZTNkPCN0kc=
modernc.org/ccgo/v3 v3.11.2/go.mod h1:6kii3AptTDI+nUrM9RFBoIEUEisSWCbdczD9ZwQH2FE=
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU=
modernc.org/ccgo/v3 v3.12.88/go.mod h1:0MFzUHIuSIthpVZyMWiFYMwjiFnhrN5MkvBrUwON+ZM=
modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko=
modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA=
modernc.org/ccgo/v3 v3.12.95/go.mod h1:ZcLyvtocXYi8uF+9Ebm3G8EF8HNY5hGomBqthDp4eC8=
modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4=
modernc.org/ccgo/v3 v3.14.0 h1:Zr1Ny9+7r5yAiXpBdgp8XiXqkNA4ARrRphHGHVXeAp0=
modernc.org/ccgo/v3 v3.14.0/go.mod h1:hBrkiBlUwvr5vV/ZH9YzXIp982jKE8Ek8tR1ytoAL6Q=
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
@@ -270,6 +393,46 @@ modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
modernc.org/libc v1.11.3 h1:q//spBhqp23lC/if8/o8hlyET57P8mCZqrqftzT2WmY=
modernc.org/libc v1.11.3/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ=
modernc.org/libc v1.11.90/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
modernc.org/libc v1.11.99/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
modernc.org/libc v1.11.104/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
modernc.org/libc v1.13.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
modernc.org/libc v1.13.2 h1:GCFjY9bmwDZ/TJC4OZOUWaNgxIxwb104C/QZrqpcVEA=
modernc.org/libc v1.13.2/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
@@ -282,9 +445,13 @@ modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.13.0 h1:cwhUj0jTBgPjk/demWheV+T6xi6ifTfsGIFKFq0g3Ck=
modernc.org/sqlite v1.13.0/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
modernc.org/sqlite v1.14.3 h1:psrTwgpEujgWEP3FNdsC9yNh5tSeA77U0GeWhHH4XmQ=
modernc.org/sqlite v1.14.3/go.mod h1:xMpicS1i2MJ4C8+Ap0vYBqTwYfpFvdnPE6brbFOtV2Y=
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/tcl v1.5.9/go.mod h1:bcwjvBJ2u0exY6K35eAmxXBBij5kXb1dHlAWmfhqThE=
modernc.org/tcl v1.9.2/go.mod h1:aw7OnlIoiuJgu1gwbTZtrKnGpDqH9wyH++jZcxdqNsg=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.1.2/go.mod h1:sj9T1AGBG0dm6SCVzldPOHWrif6XBpooJtbttMn1+Js=
modernc.org/z v1.2.20/go.mod h1:zU9FiF4PbHdOTUxw+IF8j7ArBMRPsHgq10uVPt6xTzo=

View File

@@ -35,11 +35,13 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_choose" // 选择困难症帮手
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_chouxianghua" // 说抽象话
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_coser" // 三次元小姐姐
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_cpstory" // cp短打
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_fortune" // 运势
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_funny" // 笑话
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_hs" // 炉石
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_juejuezi" // 绝绝子生成器
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_minecraft" // MCSManager
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_mocking_bird" // 拟声鸟
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_moyu" // 摸鱼
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_music" // 点歌
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_novel" // 铅笔小说网搜索
@@ -128,10 +130,10 @@ func printBanner() {
func getKanban() string {
err := reg.Connect()
defer reg.Close()
if err != nil {
return err.Error()
}
defer reg.Close()
text, err := reg.Get("ZeroBot-Plugin/kanban")
if err != nil {
return err.Error()
@@ -140,7 +142,7 @@ func getKanban() string {
}
func main() {
printBanner()
// printBanner()
// 帮助
zero.OnFullMatchGroup([]string{"/help", ".help", "菜单"}, zero.OnlyToMe).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {

View File

@@ -4,13 +4,67 @@
package main
import (
"bytes"
"strings"
"github.com/sirupsen/logrus"
easy "github.com/t-tomalak/logrus-easy-formatter"
)
func init() {
// windows 不支持带颜色 log,故自定义格式
logrus.SetFormatter(&easy.Formatter{
LogFormat: "[%lvl%] %msg%\n",
})
// windows 带颜色 log 自定义格式
logrus.SetFormatter(&LogFormat{})
}
const (
colorCodePanic = "\x1b[1;31m" // color.Style{color.Bold, color.Red}.String()
colorCodeFatal = "\x1b[1;31m" // color.Style{color.Bold, color.Red}.String()
colorCodeError = "\x1b[31m" // color.Style{color.Red}.String()
colorCodeWarn = "\x1b[33m" // color.Style{color.Yellow}.String()
colorCodeInfo = "\x1b[37m" // color.Style{color.White}.String()
colorCodeDebug = "\x1b[32m" // color.Style{color.Green}.String()
colorCodeTrace = "\x1b[36m" // color.Style{color.Cyan}.String()
colorReset = "\x1b[0m"
)
// LogFormat specialize for zbp
type LogFormat struct{}
// Format implements logrus.Formatter
func (f LogFormat) Format(entry *logrus.Entry) ([]byte, error) {
buf := new(bytes.Buffer)
buf.WriteString(getLogLevelColorCode(entry.Level))
buf.WriteByte('[')
buf.WriteString(strings.ToUpper(entry.Level.String()))
buf.WriteString("] ")
buf.WriteString(entry.Message)
buf.WriteString(" \n")
buf.WriteString(colorReset)
return buf.Bytes(), nil
}
// getLogLevelColorCode 获取日志等级对应色彩code
func getLogLevelColorCode(level logrus.Level) string {
switch level {
case logrus.PanicLevel:
return colorCodePanic
case logrus.FatalLevel:
return colorCodeFatal
case logrus.ErrorLevel:
return colorCodeError
case logrus.WarnLevel:
return colorCodeWarn
case logrus.InfoLevel:
return colorCodeInfo
case logrus.DebugLevel:
return colorCodeDebug
case logrus.TraceLevel:
return colorCodeTrace
default:
return colorCodeInfo
}
}

View File

@@ -2,10 +2,13 @@
package bookreview
import (
log "github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
func init() {
@@ -18,12 +21,24 @@ func init() {
engine.OnRegex("^书评([\u4E00-\u9FA5A-Za-z0-9]{1,25})$").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
b := getBookReviewByKeyword(ctx.State["regex_matched"].([]string)[1])
ctx.SendChain(message.Text(b.BookReview))
data, err := txt2img.RenderToBase64(b.BookReview, 40, 20)
if err != nil {
log.Println("err:", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
})
engine.OnFullMatch("随机书评").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
br := getRandomBookReview()
ctx.SendChain(message.Text(br.BookReview))
data, err := txt2img.RenderToBase64(br.BookReview, 40, 20)
if err != nil {
log.Println("err:", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
})
}

View File

@@ -1,3 +1,4 @@
// Package chouxianghua 抽象话转化
package chouxianghua
import (
@@ -12,8 +13,8 @@ const prio = 10
func init() {
control.Register("chouxianghua", &control.Options{
DisableOnDefault: false,
Help: "抽象话\n- 抽象翻译xxx\n",
}).OnRegex("^抽象翻译((\\s|[\\r\\n]|[\u4E00-\u9FA5A-Za-z0-9“”、。《》=\\x22])+)$").SetBlock(true).SetPriority(prio).
Help: "抽象话\n- 抽象翻译xxx",
}).OnRegex("^抽象翻译((\\s|[\\r\\n]|[\\p{Han}\\p{P}A-Za-z0-9])+)$").SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
r := cx(ctx.State["regex_matched"].([]string)[1])
ctx.SendChain(message.Text(r))

View File

@@ -11,7 +11,7 @@ type emoji struct {
func getPinyinByWord(word string) string {
var p pinyin
db.Find("pinyin", &p, "where word = '"+word+"'")
_ = db.Find("pinyin", &p, "where word = '"+word+"'")
return p.Pronun
}
@@ -21,6 +21,6 @@ func getPronunByDWord(w0, w1 rune) string {
func getEmojiByPronun(pronun string) string {
var e emoji
db.Find("emoji", &e, "where pronunciation = '"+pronun+"'")
_ = db.Find("emoji", &e, "where pronunciation = '"+pronun+"'")
return e.Emoji
}

View File

@@ -19,7 +19,7 @@ import (
var (
engine = control.Register("coser", &control.Options{
DisableOnDefault: false,
Help: "三次元小姐姐\n- coser\n",
Help: "三次元小姐姐\n- coser",
})
prio = 20
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"

49
plugin_cpstory/cpstory.go Normal file
View File

@@ -0,0 +1,49 @@
// Package cpstory cp短打
package cpstory
import (
"strings"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
const (
prio = 20
)
func init() {
engine := control.Register("cpstory", &control.Options{
DisableOnDefault: false,
Help: "cp短打\n- 组cp[@xxx][@xxx]\n- 组cp大老师 雪乃",
})
engine.OnRegex("^组cp.*?(\\d+).*?(\\d+)", zero.OnlyGroup).SetBlock(true).SetPriority(prio).Handle(func(ctx *zero.Ctx) {
cs := getRandomCpStory()
gong := ctxext.CardOrNickName(ctx, math.Str2Int64(ctx.State["regex_matched"].([]string)[1]))
shou := ctxext.CardOrNickName(ctx, math.Str2Int64(ctx.State["regex_matched"].([]string)[2]))
text := strings.ReplaceAll(cs.Story, "<攻>", gong)
text = strings.ReplaceAll(text, "<受>", shou)
text = strings.ReplaceAll(text, cs.Gong, gong)
text = strings.ReplaceAll(text, cs.Shou, gong)
ctx.SendChain(message.Text(text))
})
engine.OnPrefix("组cp").SetBlock(true).SetPriority(prio + 1).Handle(func(ctx *zero.Ctx) {
cs := getRandomCpStory()
params := strings.Split(ctx.State["args"].(string), " ")
if len(params) < 2 {
ctx.SendChain(message.Text(ctx.Event.MessageID), message.Text("请用空格分开两个人名"))
} else {
gong := params[0]
shou := params[1]
text := strings.ReplaceAll(cs.Story, "<攻>", gong)
text = strings.ReplaceAll(text, "<受>", shou)
text = strings.ReplaceAll(text, cs.Gong, gong)
text = strings.ReplaceAll(text, cs.Shou, gong)
ctx.SendChain(message.Text(text))
}
})
}

37
plugin_cpstory/data.go Normal file
View File

@@ -0,0 +1,37 @@
package cpstory
import (
"os"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
const (
dbpath = "data/CpStory/"
dbfile = dbpath + "cp.db"
)
var db = &sql.Sqlite{DBPath: dbfile}
// 加载数据库
func init() {
go func() {
process.SleepAbout1sTo2s()
// os.RemoveAll(dbpath)
_ = os.MkdirAll(dbpath, 0755)
_, _ = file.GetLazyData(dbfile, false, true)
err := db.Create("cp_story", &cpstory{})
if err != nil {
panic(err)
}
n, err := db.Count("cp_story")
if err != nil {
panic(err)
}
log.Printf("[cpstory]读取%d条故事", n)
}()
}

13
plugin_cpstory/model.go Normal file
View File

@@ -0,0 +1,13 @@
package cpstory
type cpstory struct {
ID int64 `db:"id"`
Gong string `db:"gong"`
Shou string `db:"shou"`
Story string `db:"story"`
}
func getRandomCpStory() (cs cpstory) {
_ = db.Pick("cp_story", &cs)
return
}

View File

@@ -1,7 +1,7 @@
// Package funny 冷笑话
package funny
import (
"strconv"
"strings"
"time"
@@ -10,6 +10,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
@@ -17,7 +18,7 @@ var (
engine = control.Register("funny", &control.Options{
DisableOnDefault: false,
Help: "讲个笑话\n" +
"- 讲个笑话[@xxx]|讲个笑话[qq号]\n",
"- 讲个笑话[@xxx]|讲个笑话[qq号]",
})
limit = rate.NewManager(time.Minute, 20)
db = &sql.Sqlite{DBPath: dbfile}
@@ -29,19 +30,7 @@ func init() {
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("card").String()
if name == "" {
name = ctx.GetGroupMemberInfo(ctx.Event.GroupID, qq, false).Get("nickname").String()
}
} else if name == "" {
name = ctx.GetGroupMemberInfo(ctx.Event.GroupID, ctx.Event.UserID, false).Get("card").String()
if name == "" {
name = ctx.GetGroupMemberInfo(ctx.Event.GroupID, ctx.Event.UserID, false).Get("nickname").String()
}
}
name := ctxext.NickName(ctx)
var j joke
err := db.Pick("jokes", &j)
if err != nil {

View File

@@ -70,7 +70,7 @@ func init() {
keyword := ctx.State["regex_matched"].([]string)[1]
soutujson := soutuapi(keyword)
pom1 := "https://i.pixiv.re"
rannum := rintn(len(soutujson.Illusts))
rannum := randintn(len(soutujson.Illusts))
pom2 := soutujson.Illusts[rannum].ImageUrls.Medium[19:]
ctx.SendChain(message.Image(pom1 + pom2))
})
@@ -102,8 +102,8 @@ func soutuapi(keyword string) *resultjson {
return result
}
// rintn 从json里的30条数据中随机获取一条返回
func rintn(len int) int {
// randintn 从json里的30条数据中随机获取一条返回
func randintn(n int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(len)
return rand.Intn(n)
}

View File

@@ -17,6 +17,7 @@ import (
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/plugin_manager/timer"
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
@@ -423,11 +424,7 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
if ctx.Event.NoticeType == "group_decrease" {
userid := ctx.Event.UserID
nickname := ctx.GetGroupMemberInfo(ctx.Event.GroupID, userid, false).Get("card").String()
if nickname == "" {
nickname = ctx.GetGroupMemberInfo(ctx.Event.GroupID, userid, false).Get("nickname").String()
}
ctx.SendChain(message.Text(nickname, "(", userid, ")", "离开了我们..."))
ctx.SendChain(message.Text(ctxext.CardOrNickName(ctx, userid), "(", userid, ")", "离开了我们..."))
}
})
// 设置欢迎语

View File

@@ -5,12 +5,12 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
)
func (ts *Timer) sendmsg(grp int64, ctx *zero.Ctx) {
func (t *Timer) sendmsg(grp int64, ctx *zero.Ctx) {
ctx.Event = new(zero.Event)
ctx.Event.GroupID = grp
if ts.URL == "" {
ctx.SendChain(atall, message.Text(ts.Alert))
if t.URL == "" {
ctx.SendChain(atall, message.Text(t.Alert))
} else {
ctx.SendChain(atall, message.Text(ts.Alert), message.Image(ts.URL).Add("cache", "0"))
ctx.SendChain(atall, message.Text(t.Alert), message.Image(t.URL).Add("cache", "0"))
}
}

View File

@@ -14,29 +14,29 @@ import (
)
// GetTimerInfo 获得标准化定时字符串
func (ts *Timer) GetTimerInfo() string {
if ts.Cron != "" {
return fmt.Sprintf("[%d]%s", ts.GrpID, ts.Cron)
func (t *Timer) GetTimerInfo() string {
if t.Cron != "" {
return fmt.Sprintf("[%d]%s", t.GrpID, t.Cron)
}
return fmt.Sprintf("[%d]%d月%d日%d周%d:%d", ts.GrpID, ts.Month(), ts.Day(), ts.Week(), ts.Hour(), ts.Minute())
return fmt.Sprintf("[%d]%d月%d日%d周%d:%d", t.GrpID, t.Month(), t.Day(), t.Week(), t.Hour(), t.Minute())
}
// GetTimerID 获得标准化 ID
func (ts *Timer) GetTimerID() uint32 {
key := ts.GetTimerInfo()
func (t *Timer) GetTimerID() uint32 {
key := t.GetTimerInfo()
m := md5.Sum(helper.StringToBytes(key))
return binary.LittleEndian.Uint32(m[:4])
}
// GetFilledCronTimer 获得以cron填充好的ts
func GetFilledCronTimer(croncmd string, alert string, img string, botqq, gid int64) *Timer {
var ts Timer
ts.Alert = alert
ts.Cron = croncmd
ts.URL = img
ts.SelfID = botqq
ts.GrpID = gid
return &ts
var t Timer
t.Alert = alert
t.Cron = croncmd
t.URL = img
t.SelfID = botqq
t.GrpID = gid
return &t
}
// GetFilledTimer 获得填充好的ts
@@ -46,79 +46,79 @@ func GetFilledTimer(dateStrs []string, botqq, grp int64, matchDateOnly bool) *Ti
hourStr := []rune(dateStrs[3])
minuteStr := []rune(dateStrs[4])
var ts Timer
var t Timer
mon := time.Month(chineseNum2Int(monthStr))
if (mon != -1 && mon <= 0) || mon > 12 { // 月份非法
ts.Alert = "月份非法!"
return &ts
t.Alert = "月份非法!"
return &t
}
ts.SetMonth(mon)
t.SetMonth(mon)
lenOfDW := len(dayWeekStr)
switch {
case lenOfDW == 4: // 包括末尾的"日"
dayWeekStr = []rune{dayWeekStr[0], dayWeekStr[2]} // 去除中间的十
d := chineseNum2Int(dayWeekStr)
if (d != -1 && d <= 0) || d > 31 { // 日期非法
ts.Alert = "日期非法1"
return &ts
t.Alert = "日期非法1"
return &t
}
ts.SetDay(d)
t.SetDay(d)
case dayWeekStr[lenOfDW-1] == rune('日'): // xx日
dayWeekStr = dayWeekStr[:lenOfDW-1]
d := chineseNum2Int(dayWeekStr)
if (d != -1 && d <= 0) || d > 31 { // 日期非法
ts.Alert = "日期非法2"
return &ts
t.Alert = "日期非法2"
return &t
}
ts.SetDay(d)
t.SetDay(d)
case dayWeekStr[0] == rune('每'): // 每周
ts.SetWeek(-1)
t.SetWeek(-1)
default: // 周x
w := chineseNum2Int(dayWeekStr[1:])
if w == 7 { // 周天是0
w = 0
}
if w < 0 || w > 6 { // 星期非法
ts.Alert = "星期非法!"
return &ts
t.Alert = "星期非法!"
return &t
}
ts.SetWeek(time.Weekday(w))
t.SetWeek(time.Weekday(w))
}
if len(hourStr) == 3 {
hourStr = []rune{hourStr[0], hourStr[2]} // 去除中间的十
}
h := chineseNum2Int(hourStr)
if h < -1 || h > 23 { // 小时非法
ts.Alert = "小时非法!"
return &ts
t.Alert = "小时非法!"
return &t
}
ts.SetHour(h)
t.SetHour(h)
if len(minuteStr) == 3 {
minuteStr = []rune{minuteStr[0], minuteStr[2]} // 去除中间的十
}
min := chineseNum2Int(minuteStr)
if min < -1 || min > 59 { // 分钟非法
ts.Alert = "分钟非法!"
return &ts
t.Alert = "分钟非法!"
return &t
}
ts.SetMinute(min)
t.SetMinute(min)
if !matchDateOnly {
urlStr := dateStrs[5]
if urlStr != "" { // 是图片url
ts.URL = urlStr[3:] // utf-8下用为3字节
logrus.Println("[群管]" + ts.URL)
if !strings.HasPrefix(ts.URL, "http") {
ts.URL = "illegal"
t.URL = urlStr[3:] // utf-8下用为3字节
logrus.Println("[群管]" + t.URL)
if !strings.HasPrefix(t.URL, "http") {
t.URL = "illegal"
logrus.Println("[群管]url非法")
return &ts
return &t
}
}
ts.Alert = dateStrs[6]
ts.SetEn(true)
t.Alert = dateStrs[6]
t.SetEn(true)
}
ts.SelfID = botqq
ts.GrpID = grp
return &ts
t.SelfID = botqq
t.GrpID = grp
return &t
}
// chineseNum2Int 汉字数字转int仅支持-1099最多两位数其中"每"解释为-1"每二"为-2以此类推

View File

@@ -89,7 +89,7 @@ func (ts *Timer) nextWakeTime() (date time.Time) {
}
logrus.Debugln("[timer] stable:", stable)
logrus.Debugln("[timer] m:", m, "d:", d, "h:", h, "mn:", mn, "w:", w)
date = time.Date(date.Year(), time.Month(m), int(d), int(h), int(mn), date.Second(), date.Nanosecond(), date.Location())
date = time.Date(date.Year(), time.Month(m), d, h, mn, date.Second(), date.Nanosecond(), date.Location())
logrus.Debugln("[timer] date original:", date)
if unit > 0 {
date = date.Add(unit)
@@ -111,7 +111,7 @@ func (ts *Timer) nextWakeTime() (date time.Time) {
}
}
logrus.Debugln("[timer] date after fix:", date)
if stable&0x8 != 0 && date.Hour() != int(h) {
if stable&0x8 != 0 && date.Hour() != h {
switch {
case stable&0x4 == 0:
date = date.AddDate(0, 0, 1).Add(-time.Hour)
@@ -124,7 +124,7 @@ func (ts *Timer) nextWakeTime() (date time.Time) {
}
}
logrus.Debugln("[timer] date after s8:", date)
if stable&0x4 != 0 && date.Day() != int(d) {
if stable&0x4 != 0 && date.Day() != d {
switch {
case stable*0x1 == 0:
date = date.AddDate(0, 1, -1)

View File

@@ -78,15 +78,19 @@ func (c *Clock) RegisterTimer(ts *Timer, save bool) bool {
c.entries[key] = eid
c.entmu.Unlock()
if save {
err = c.AddTimer(ts)
err = c.AddTimerIntoDB(ts)
}
if err == nil {
err = c.AddTimerIntoMap(ts)
}
return err == nil
}
ts.Alert = err.Error()
} else {
if save {
_ = c.AddTimer(ts)
_ = c.AddTimerIntoDB(ts)
}
_ = c.AddTimerIntoMap(ts)
for ts.En() {
nextdate := ts.nextWakeTime()
sleepsec := time.Until(nextdate)
@@ -161,11 +165,18 @@ func (c *Clock) GetTimer(key uint32) (t *Timer, ok bool) {
return
}
// AddTimer 添加定时器
func (c *Clock) AddTimer(t *Timer) (err error) {
// AddTimerIntoDB 添加定时器
func (c *Clock) AddTimerIntoDB(t *Timer) (err error) {
c.timersmu.Lock()
err = c.db.Insert("timer", t)
c.timersmu.Unlock()
return
}
// AddTimerIntoMap 添加定时器到缓存
func (c *Clock) AddTimerIntoMap(t *Timer) (err error) {
c.timersmu.Lock()
(*c.timers)[t.ID] = t
err = c.db.Insert("timer", t)
c.timersmu.Unlock()
return
}

View File

@@ -27,7 +27,7 @@ func TestNextWakeTime(t *testing.T) {
func TestClock(t *testing.T) {
db := &sql.Sqlite{DBPath: "test.db"}
c := NewClock(db)
c.AddTimer(GetFilledTimer([]string{"", "12", "-1", "12", "0", "", "test"}, 0, 0, false))
c.AddTimerIntoDB(GetFilledTimer([]string{"", "12", "-1", "12", "0", "", "test"}, 0, 0, false))
t.Log(c.ListTimers(0))
t.Fail()
}

View File

@@ -3,13 +3,13 @@ package timer
import "time"
// En isEnabled 1bit
func (m *Timer) En() (en bool) {
return m.En1Month4Day5Week3Hour5Min6&0x800000 != 0
func (t *Timer) En() (en bool) {
return t.En1Month4Day5Week3Hour5Min6&0x800000 != 0
}
// Month 4bits
func (m *Timer) Month() (mon time.Month) {
mon = time.Month((m.En1Month4Day5Week3Hour5Min6 & 0x780000) >> 19)
func (t *Timer) Month() (mon time.Month) {
mon = time.Month((t.En1Month4Day5Week3Hour5Min6 & 0x780000) >> 19)
if mon == 0b1111 {
mon = -1
}
@@ -17,8 +17,8 @@ func (m *Timer) Month() (mon time.Month) {
}
// Day 5bits
func (m *Timer) Day() (d int) {
d = int((m.En1Month4Day5Week3Hour5Min6 & 0x07c000) >> 14)
func (t *Timer) Day() (d int) {
d = int((t.En1Month4Day5Week3Hour5Min6 & 0x07c000) >> 14)
if d == 0b11111 {
d = -1
}
@@ -26,8 +26,8 @@ func (m *Timer) Day() (d int) {
}
// Week 3bits
func (m *Timer) Week() (w time.Weekday) {
w = time.Weekday((m.En1Month4Day5Week3Hour5Min6 & 0x003800) >> 11)
func (t *Timer) Week() (w time.Weekday) {
w = time.Weekday((t.En1Month4Day5Week3Hour5Min6 & 0x003800) >> 11)
if w == 0b111 {
w = -1
}
@@ -35,8 +35,8 @@ func (m *Timer) Week() (w time.Weekday) {
}
// Hour 5bits
func (m *Timer) Hour() (h int) {
h = int((m.En1Month4Day5Week3Hour5Min6 & 0x0007c0) >> 6)
func (t *Timer) Hour() (h int) {
h = int((t.En1Month4Day5Week3Hour5Min6 & 0x0007c0) >> 6)
if h == 0b11111 {
h = -1
}
@@ -44,8 +44,8 @@ func (m *Timer) Hour() (h int) {
}
// Minute 6bits
func (m *Timer) Minute() (min int) {
min = int(m.En1Month4Day5Week3Hour5Min6 & 0x00003f)
func (t *Timer) Minute() (min int) {
min = int(t.En1Month4Day5Week3Hour5Min6 & 0x00003f)
if min == 0b111111 {
min = -1
}
@@ -53,35 +53,35 @@ func (m *Timer) Minute() (min int) {
}
// SetEn ...
func (m *Timer) SetEn(en bool) {
func (t *Timer) SetEn(en bool) {
if en {
m.En1Month4Day5Week3Hour5Min6 |= 0x800000
t.En1Month4Day5Week3Hour5Min6 |= 0x800000
} else {
m.En1Month4Day5Week3Hour5Min6 &= 0x7fffff
t.En1Month4Day5Week3Hour5Min6 &= 0x7fffff
}
}
// SetMonth ...
func (m *Timer) SetMonth(mon time.Month) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(mon) << 19) & 0x780000) | (m.En1Month4Day5Week3Hour5Min6 & 0x87ffff)
func (t *Timer) SetMonth(mon time.Month) {
t.En1Month4Day5Week3Hour5Min6 = ((int32(mon) << 19) & 0x780000) | (t.En1Month4Day5Week3Hour5Min6 & 0x87ffff)
}
// SetDay ...
func (m *Timer) SetDay(d int) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(d) << 14) & 0x07c000) | (m.En1Month4Day5Week3Hour5Min6 & 0xf83fff)
func (t *Timer) SetDay(d int) {
t.En1Month4Day5Week3Hour5Min6 = ((int32(d) << 14) & 0x07c000) | (t.En1Month4Day5Week3Hour5Min6 & 0xf83fff)
}
// SetWeek ...
func (m *Timer) SetWeek(w time.Weekday) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(w) << 11) & 0x003800) | (m.En1Month4Day5Week3Hour5Min6 & 0xffc7ff)
func (t *Timer) SetWeek(w time.Weekday) {
t.En1Month4Day5Week3Hour5Min6 = ((int32(w) << 11) & 0x003800) | (t.En1Month4Day5Week3Hour5Min6 & 0xffc7ff)
}
// SetHour ...
func (m *Timer) SetHour(h int) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(h) << 6) & 0x0007c0) | (m.En1Month4Day5Week3Hour5Min6 & 0xfff83f)
func (t *Timer) SetHour(h int) {
t.En1Month4Day5Week3Hour5Min6 = ((int32(h) << 6) & 0x0007c0) | (t.En1Month4Day5Week3Hour5Min6 & 0xfff83f)
}
// SetMinute ...
func (m *Timer) SetMinute(min int) {
m.En1Month4Day5Week3Hour5Min6 = (int32(min) & 0x00003f) | (m.En1Month4Day5Week3Hour5Min6 & 0xffffc0)
func (t *Timer) SetMinute(min int) {
t.En1Month4Day5Week3Hour5Min6 = (int32(min) & 0x00003f) | (t.En1Month4Day5Week3Hour5Min6 & 0xffffc0)
}

View File

@@ -0,0 +1,25 @@
package mockingbird
import (
"os"
"github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
// 加载数据库
func init() {
go func() {
process.SleepAbout1sTo2s()
_ = os.MkdirAll(dbpath, 0755)
os.RemoveAll(cachePath)
_ = os.MkdirAll(cachePath, 0755)
_, err := file.GetLazyData(dbfile, false, true)
if err != nil {
panic(err)
}
logrus.Infoln("[mockingbird]加载实例音频")
}()
}

View File

@@ -0,0 +1,140 @@
// Package mockingbird 拟声鸟
package mockingbird
import (
"bytes"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"os"
"strconv"
"time"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
qingyunke "github.com/FloatTech/ZeroBot-Plugin/plugin_qingyunke"
fileutil "github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/web"
)
const (
prio = 250
dbpath = "data/MockingBird/"
cachePath = dbpath + "cache/"
dbfile = dbpath + "降噪3.wav"
baseURL = "http://aaquatri.com/sound/"
synthesizersURL = baseURL + "api/synthesizers/"
synthesizeURL = baseURL + "api/synthesize"
)
var (
engine = control.Register("mockingbird", &control.Options{
DisableOnDefault: false,
Help: "拟声鸟\n- @Bot 任意文本(任意一句话回复)",
})
limit = rate.NewManager(time.Second*10, 1)
vocoderList = []string{"WaveRNN", "HifiGAN"}
)
func init() {
engine.OnMessage(zero.OnlyToMe, getAcquire).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
msg := ctx.ExtractPlainText()
// 调用青云客接口
reply, err := qingyunke.GetMessage(msg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// 挑出 face 表情
textReply, _ := qingyunke.DealReply(reply)
// 拟声器生成音频
syntPath := getSyntPath()
fileName := getWav(textReply, syntPath, vocoderList[1], ctx.Event.UserID)
// 回复
ctx.SendChain(message.Record("file:///" + fileutil.BOTPATH + "/" + cachePath + fileName))
})
}
func getSyntPath() (syntPath string) {
data, err := web.ReqWith(synthesizersURL, "GET", "", "")
if err != nil {
log.Errorln("[mockingbird]:", err)
}
syntPath = gjson.Get(helper.BytesToString(data), "0.path").String()
return
}
func getWav(text, syntPath, vocoder string, uid int64) (fileName string) {
fileName = strconv.FormatInt(uid, 10) + time.Now().Format("20060102150405") + ".wav"
var b bytes.Buffer
w := multipart.NewWriter(&b)
// Add your file
f, err := os.Open(dbfile)
if err != nil {
log.Errorln("[mockingbird]:", err)
}
defer f.Close()
fw, err := w.CreateFormFile("file", dbfile)
if err != nil {
log.Errorln("[mockingbird]:", err)
}
if _, err = io.Copy(fw, f); err != nil {
log.Errorln("[mockingbird]:", err)
}
if fw, err = w.CreateFormField("text"); err != nil {
log.Errorln("[mockingbird]:", err)
}
if _, err = fw.Write([]byte(text)); err != nil {
log.Errorln("[mockingbird]:", err)
}
if fw, err = w.CreateFormField("synt_path"); err != nil {
log.Errorln("[mockingbird]:", err)
}
if _, err = fw.Write([]byte(syntPath)); err != nil {
log.Errorln("[mockingbird]:", err)
}
if fw, err = w.CreateFormField("vocoder"); err != nil {
log.Errorln("[mockingbird]:", err)
}
if _, err = fw.Write([]byte(vocoder)); err != nil {
log.Errorln("[mockingbird]:", err)
}
w.Close()
// Now that you have a form, you can submit it to your handler.
req, err := http.NewRequest("POST", synthesizeURL, &b)
if err != nil {
log.Errorln("[mockingbird]:", err)
}
// Don't forget to set the content type, this will contain the boundary.
req.Header.Set("Content-Type", w.FormDataContentType())
// Submit the request
client := &http.Client{}
res, err := client.Do(req)
if err != nil {
log.Errorln("[mockingbird]:", err)
}
// Check the response
if res.StatusCode != http.StatusOK {
log.Errorf("[mockingbird]bad status: %s", res.Status)
}
defer res.Body.Close()
data, _ := ioutil.ReadAll(res.Body)
err = ioutil.WriteFile(cachePath+fileName, data, 0666)
if err != nil {
log.Errorln("[mockingbird]:", err)
}
return
}
func getAcquire(ctx *zero.Ctx) bool {
return limit.Load(ctx.Event.UserID).Acquire()
}

View File

@@ -46,7 +46,7 @@ func GetHoliday(name string) *Holiday {
return h
}
// 获取两个时间相差
// String 获取两个时间相差
func (h *Holiday) String() string {
d := time.Until(h.date)
switch {

View File

@@ -1,3 +1,4 @@
// Package nativewife 本地老婆
package nativewife
import (
@@ -17,6 +18,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
@@ -49,13 +51,7 @@ func init() {
ctx.SendChain(message.Text("大家的wife都是", wn, "\n"), message.Image(baseuri+"/"+grpf+"/"+wn), message.Text("\n哦~"))
default:
// 获取名字
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
}
name := ctxext.NickName(ctx)
now := time.Now()
s := md5.Sum(helper.StringToBytes(fmt.Sprintf("%s%d%d%d", name, now.Year(), now.Month(), now.Day())))
r := rand.New(rand.NewSource(int64(binary.LittleEndian.Uint64(s[:]))))

View File

@@ -20,6 +20,7 @@ import (
"github.com/FloatTech/ZeroBot-Plugin/control"
ub "github.com/FloatTech/ZeroBot-Plugin/utils/binary"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
const (
@@ -55,7 +56,6 @@ func init() {
login(username, password)
searchKey := ctx.State["regex_matched"].([]string)[1]
searchHTML := search(searchKey)
var m message.Message
doc, err := htmlquery.Parse(strings.NewReader(searchHTML))
if err != nil {
log.Errorln("[novel]", err)
@@ -68,6 +68,7 @@ func init() {
log.Errorln("[novel]", err)
}
if len(list) != 0 {
text := ""
for _, v := range list {
bookName := htmlquery.InnerText(htmlquery.FindOne(v, "/dd[1]/h3/a[1]"))
category := htmlquery.InnerText(htmlquery.FindOne(v, "/dt/span[1]"))
@@ -83,17 +84,13 @@ func init() {
webpageURL := websiteURL + "/book/" + id + "/"
downloadURL := websiteURL + "/modules/article/txtarticle.php?id=" + id
text := fmt.Sprintf("书名:%s\n类型:%s\n作者:%s\n状态:%s\n字数:%s\n简介:%s\n更新时间:%s\n最新章节:%s\n网页链接:%s\n下载地址:%s\n", bookName, category, author, status, wordNumbers, description, updateTime, latestChapter, webpageURL, downloadURL)
m = append(m,
message.CustomNode(
zero.BotConfig.NickName[0],
ctx.Event.SelfID,
text),
)
text += fmt.Sprintf("书名:%s\n类型:%s\n作者:%s\n状态:%s\n字数:%s\n简介:%s\n更新时间:%s\n最新章节:%s\n网页链接:%s\n下载地址:%s\n\n", bookName, category, author, status, wordNumbers, description, updateTime, latestChapter, webpageURL, downloadURL)
}
if id := ctx.SendGroupForwardMessage(
ctx.Event.GroupID,
m).Get("message_id").Int(); id == 0 {
data, err := txt2img.RenderToBase64(text, 40, 20)
if err != nil {
log.Println("err:", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
} else {
@@ -121,7 +118,13 @@ func init() {
webpageURL := websiteURL + "/book/" + id + "/"
downloadURL := websiteURL + "/modules/article/txtarticle.php?id=" + id
text := fmt.Sprintf("书名:%s\n类型:%s\n作者:%s\n状态:%s\n简介:%s\n更新时间:%s\n最新章节:%s\n网页链接:%s\n下载地址:%s\n", bookName, category, author, status, description, updateTime, latestChapter, webpageURL, downloadURL)
ctx.SendChain(message.Text(text))
data, err := txt2img.RenderToBase64(text, 40, 20)
if err != nil {
log.Println("err:", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
}
})
}

View File

@@ -1,46 +0,0 @@
package main
import (
"fmt"
"os"
"strconv"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
type signature struct {
Id uint64 `db:"id"`
Text string `db:"text"`
}
type kuji struct {
Id uint8 `db:"id"`
Text string `db:"text"`
}
func main() {
db := &sql.Sqlite{DBPath: os.Args[1]}
newdb := &sql.Sqlite{DBPath: os.Args[2]}
err := newdb.Create("kuji", &kuji{})
if err != nil {
panic(err)
}
err = db.Create("signature", &signature{})
if err != nil {
panic(err)
}
fmt.Println(db.Count("signature"))
s := &signature{}
k := &kuji{}
for i := 1; i <= 100; i++ {
db.Find("signature", s, "where id = "+strconv.Itoa(i))
fmt.Println("insert: ", s.Text[:57])
k.Id = uint8(i)
k.Text = s.Text
newdb.Insert("kuji", k)
}
db.Close()
newdb.Close()
}

View File

@@ -8,11 +8,12 @@ import (
"time"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
const (
@@ -39,10 +40,13 @@ func init() { // 插件主体
})
engine.OnFullMatchGroup([]string{"解签"}).SetPriority(10).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
ctx.SendChain(
message.At(ctx.Event.UserID),
message.Text(getKujiByBango(bangoToday(ctx.Event.UserID))),
)
kujiBytes, err := txt2img.RenderToBase64(getKujiByBango(bangoToday(ctx.Event.UserID)), 40, 20)
if err != nil {
log.Errorln("[omikuji]:", err)
}
if id := ctx.SendChain(message.At(ctx.Event.UserID), message.Image("base64://"+helper.BytesToString(kujiBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
})
}

View File

@@ -41,23 +41,13 @@ func init() { // 插件主体
}
msg := ctx.ExtractPlainText()
// 调用青云客接口
reply, err := getMessage(msg)
reply, err := GetMessage(msg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// 挑出 face 表情
reg := regexp.MustCompile(`\{face:(\d+)\}(.*)`)
faceReply := -1
var textReply string
if reg.MatchString(reply) {
faceReply, _ = strconv.Atoi(reg.FindStringSubmatch(reply)[1])
textReply = reg.FindStringSubmatch(reply)[2]
} else {
textReply = reply
}
textReply = strings.ReplaceAll(textReply, "菲菲", zero.BotConfig.NickName[0])
textReply = strings.ReplaceAll(textReply, "{br}", "\n")
textReply, faceReply := DealReply(reply)
// 回复
time.Sleep(time.Second * 1)
if ctx.Event.MessageType == "group" {
@@ -103,8 +93,8 @@ const (
appid = "0"
)
// 青云客取消息
func getMessage(msg string) (string, error) {
// GetMessage 青云客取消息
func GetMessage(msg string) (string, error) {
u := fmt.Sprintf(qykURL+"?key=%s&appid=%s&msg=%s", key, appid, url.QueryEscape(msg))
client := &http.Client{}
req, err := http.NewRequest("GET", u, nil)
@@ -133,6 +123,21 @@ func getMessage(msg string) (string, error) {
return dataQYK.Content, nil
}
// DealReply 处理青云客返回文本
func DealReply(reply string) (textReply string, faceReply int) {
reg := regexp.MustCompile(`\{face:(\d+)\}(.*)`)
faceReply = -1
if reg.MatchString(reply) {
faceReply, _ = strconv.Atoi(reg.FindStringSubmatch(reply)[1])
textReply = reg.FindStringSubmatch(reply)[2]
} else {
textReply = reply
}
textReply = strings.ReplaceAll(textReply, "菲菲", zero.BotConfig.NickName[0])
textReply = strings.ReplaceAll(textReply, "{br}", "\n")
return
}
func getAgent() string {
agent := [...]string{
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0",

View File

@@ -10,21 +10,21 @@ import (
)
const (
chpURL = "https://chp.shadiao.app/api.php"
duURL = "https://du.shadiao.app/api.php"
pyqURL = "https://pyq.shadiao.app/api.php"
yduanziURL = "http://www.yduanzi.com/duanzi/getduanzi"
chayiURL = "https://api.lovelive.tools/api/SweetNothings/Web/0"
ganhaiURL = "https://api.lovelive.tools/api/SweetNothings/Web/1"
zuanURL = "https://zuanbot.com/api.php?level=min&lang=zh_cn"
chpURL = "https://chp.shadiao.app/api.php"
duURL = "https://du.shadiao.app/api.php"
pyqURL = "https://pyq.shadiao.app/api.php"
yduanziURL = "http://www.yduanzi.com/duanzi/getduanzi"
chayiURL = "https://api.lovelive.tools/api/SweetNothings/Web/0"
ganhaiURL = "https://api.lovelive.tools/api/SweetNothings/Web/1"
// zuanURL = "https://zuanbot.com/api.php?level=min&lang=zh_cn"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
chpReferer = "https://chp.shadiao.app/"
duReferer = "https://du.shadiao.app/"
pyqReferer = "https://pyq.shadiao.app/"
yduanziReferer = "http://www.yduanzi.com/?utm_source=shadiao.app"
loveliveReferer = "https://lovelive.tools/"
zuanReferer = "https://zuanbot.com/"
prio = 10
// zuanReferer = "https://zuanbot.com/"
prio = 10
)
var (

View File

@@ -22,7 +22,7 @@ func init() {
return
}
text := gjson.Get(helper.BytesToString(data), "duanzi").String()
text = strings.Replace(text, "<br>", "\n", -1)
text = strings.ReplaceAll(text, "<br>", "\n")
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(text))
})
}

View File

@@ -2,15 +2,18 @@
package shindan
import (
"strconv"
"time"
"github.com/FloatTech/AnimeAPI/shindanmaker"
log "github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/ctxext"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
var (
@@ -40,20 +43,25 @@ func handle(ctx *zero.Ctx) {
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
}
name := ctxext.NickName(ctx)
// 调用接口
text, err := shindanmaker.Shindanmaker(ctx.State["id"].(int64), name)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
}
// TODO: 可注入
ctx.Send(text)
switch ctx.State["id"].(int64) {
case 587874, 162207:
data, err := txt2img.RenderToBase64(text, 40, 20)
if err != nil {
log.Errorln("[shindan]:", err)
}
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
default:
ctx.Send(text)
}
}
// 传入 shindanmaker id

View File

@@ -37,9 +37,8 @@ func Open(dbpath string) (*SleepDB, error) {
db, err := gorm.Open("sqlite3", dbpath)
if err != nil {
return nil, err
} else {
return (*SleepDB)(db), nil
}
return (*SleepDB)(db), nil
}
// Close 关闭

View File

@@ -1,3 +1,4 @@
// Package model vtb数据库操作
package model
import (
@@ -10,13 +11,15 @@ import (
"time"
"github.com/jinzhu/gorm"
_ "github.com/logoove/sqlite"
"github.com/sirupsen/logrus"
_ "github.com/logoove/sqlite" // import sql
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
)
// VtbDB vtb 数据库
type VtbDB gorm.DB
// Initialize ...
func Initialize(dbpath string) *VtbDB {
var err error
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
@@ -35,13 +38,13 @@ func Initialize(dbpath string) *VtbDB {
return (*VtbDB)(gdb)
}
// Open ...
func Open(dbpath string) (*VtbDB, error) {
db, err := gorm.Open("sqlite3", dbpath)
if err != nil {
return nil, err
} else {
return (*VtbDB)(db), nil
}
return (*VtbDB)(db), nil
}
// FirstCategory 第一品类
@@ -49,11 +52,12 @@ type FirstCategory struct {
gorm.Model
FirstCategoryIndex int64 `gorm:"column:first_category_index"`
FirstCategoryName string `gorm:"column:first_category_name"`
FirstCategoryUid string `gorm:"column:first_category_uid"`
FirstCategoryUID string `gorm:"column:first_category_uid"`
FirstCategoryDescription string `gorm:"column:first_category_description;type:varchar(1024)"`
FirstCategoryIconPath string `gorm:"column:first_category_icon_path"`
}
// TableName ...
func (FirstCategory) TableName() string {
return "first_category"
}
@@ -62,12 +66,13 @@ func (FirstCategory) TableName() string {
type SecondCategory struct {
gorm.Model
SecondCategoryIndex int64 `gorm:"column:second_category_index"`
FirstCategoryUid string `gorm:"column:first_category_uid;association_foreignkey:first_category_uid"`
FirstCategoryUID string `gorm:"column:first_category_uid;association_foreignkey:first_category_uid"`
SecondCategoryName string `gorm:"column:second_category_name"`
SecondCategoryAuthor string `gorm:"column:second_category_author"`
SecondCategoryDescription string `gorm:"column:second_category_description"`
}
// TableName ...
func (SecondCategory) TableName() string {
return "second_category"
}
@@ -77,13 +82,14 @@ type ThirdCategory struct {
gorm.Model
ThirdCategoryIndex int64 `gorm:"column:third_category_index"`
SecondCategoryIndex int64 `gorm:"column:second_category_index"`
FirstCategoryUid string `gorm:"column:first_category_uid"`
FirstCategoryUID string `gorm:"column:first_category_uid"`
ThirdCategoryName string `gorm:"column:third_category_name"`
ThirdCategoryPath string `gorm:"column:third_category_path"`
ThirdCategoryAuthor string `gorm:"column:third_category_author"`
ThirdCategoryDescription string `gorm:"column:third_category_description"`
}
// TableName ...
func (ThirdCategory) TableName() string {
return "third_category"
}
@@ -92,24 +98,14 @@ func (ThirdCategory) TableName() string {
func (vdb *VtbDB) GetAllFirstCategoryMessage() string {
db := (*gorm.DB)(vdb)
firstStepMessage := "请选择一个vtb并发送序号:\n"
var fc FirstCategory
rows, err := db.Model(&FirstCategory{}).Rows()
var fcl []FirstCategory
err := db.Debug().Model(&FirstCategory{}).Find(&fcl).Error
if err != nil {
logrus.Errorln("[vtb/model]数据库读取错误", err)
log.Errorln("[vtb/model]数据库读取错误", err)
return ""
}
if rows == nil {
return ""
}
defer rows.Close()
for rows.Next() {
err = db.ScanRows(rows, &fc)
if err != nil {
logrus.Errorln("[vtb/model]数据库读取错误", err)
return ""
}
// logrus.Println(fc)
firstStepMessage = firstStepMessage + strconv.FormatInt(fc.FirstCategoryIndex, 10) + ". " + fc.FirstCategoryName + "\n"
for _, v := range fcl {
firstStepMessage += strconv.FormatInt(v.FirstCategoryIndex, 10) + ". " + v.FirstCategoryName + "\n"
}
return firstStepMessage
}
@@ -117,137 +113,126 @@ func (vdb *VtbDB) GetAllFirstCategoryMessage() string {
// GetAllSecondCategoryMessageByFirstIndex 取得同一个vtb所有语录类别
func (vdb *VtbDB) GetAllSecondCategoryMessageByFirstIndex(firstIndex int) string {
db := (*gorm.DB)(vdb)
SecondStepMessage := "请选择一个语录类别并发送序号:\n"
var sc SecondCategory
secondStepMessage := "请选择一个语录类别并发送序号:\n"
var scl []SecondCategory
var count int
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
db.Model(&SecondCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Count(&count)
if count == 0 {
err := db.Debug().Model(&SecondCategory{}).Find(&scl, "first_category_uid = ?", fc.FirstCategoryUID).Count(&count).Error
if err != nil || count == 0 {
log.Errorln("[vtb/model]数据库读取错误", err)
return ""
}
rows, err := db.Model(&SecondCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Rows()
if err != nil {
logrus.Errorln("[vtb/model]数据库读取错误", err)
for _, v := range scl {
secondStepMessage += strconv.FormatInt(v.SecondCategoryIndex, 10) + ". " + v.SecondCategoryName + "\n"
}
for rows.Next() {
db.ScanRows(rows, &sc)
// logrus.Println(sc)
SecondStepMessage = SecondStepMessage + strconv.FormatInt(sc.SecondCategoryIndex, 10) + ". " + sc.SecondCategoryName + "\n"
}
return SecondStepMessage
return secondStepMessage
}
// GetAllThirdCategoryMessageByFirstIndexAndSecondIndex 取得同一个vtb同个类别的所有语录
func (vdb *VtbDB) GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex int) string {
db := (*gorm.DB)(vdb)
ThirdStepMessage := "请选择一个语录并发送序号:\n"
thirdStepMessage := "请选择一个语录并发送序号:\n"
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
var count int
db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUid, secondIndex).Count(&count)
if count == 0 {
var tcl []ThirdCategory
err := db.Debug().Model(&ThirdCategory{}).Find(&tcl, "first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUID, secondIndex).Count(&count).Error
if err != nil || count == 0 {
log.Errorln("[vtb/model]数据库读取错误", err)
return ""
}
var tc ThirdCategory
rows, err := db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUid, secondIndex).Rows()
if err != nil {
logrus.Errorln("[vtb/model]数据库读取错误", err)
for _, v := range tcl {
thirdStepMessage = thirdStepMessage + strconv.FormatInt(v.ThirdCategoryIndex, 10) + ". " + v.ThirdCategoryName + "\n"
}
for rows.Next() {
db.ScanRows(rows, &tc)
// logrus.Println(tc)
ThirdStepMessage = ThirdStepMessage + strconv.FormatInt(tc.ThirdCategoryIndex, 10) + ". " + tc.ThirdCategoryName + "\n"
}
return ThirdStepMessage
return thirdStepMessage
}
// GetThirdCategory
// GetThirdCategory ...
func (vdb *VtbDB) GetThirdCategory(firstIndex, secondIndex, thirdIndex int) ThirdCategory {
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
var tc ThirdCategory
db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", fc.FirstCategoryUid, secondIndex, thirdIndex).Take(&tc)
db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", fc.FirstCategoryUID, secondIndex, thirdIndex).Take(&tc)
return tc
}
// RandomVtb ...
func (vdb *VtbDB) RandomVtb() ThirdCategory {
db := (*gorm.DB)(vdb)
rand.Seed(time.Now().UnixNano())
var count int
db.Model(&ThirdCategory{}).Count(&count)
// logrus.Info("一共有", count, "个")
var tc ThirdCategory
db.Model(&ThirdCategory{}).Offset(rand.Intn(count)).Take(&tc)
// logrus.Info(tc)
db.Model(&ThirdCategory{}).Count(&count).Offset(rand.Intn(count)).Take(&tc)
return tc
}
func (vdb *VtbDB) GetFirstCategoryByFirstUid(firstUid string) FirstCategory {
// GetFirstCategoryByFirstUID ...
func (vdb *VtbDB) GetFirstCategoryByFirstUID(firstUID string) FirstCategory {
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_uid = ?", firstUid).Take(&fc)
// logrus.Info(fc)
db.Model(FirstCategory{}).Where("first_category_uid = ?", firstUID).Take(&fc)
return fc
}
// Close ...
func (vdb *VtbDB) Close() error {
db := (*gorm.DB)(vdb)
return db.Close()
}
const vtbUrl = "https://vtbkeyboard.moe/api/get_vtb_list"
const vtbURL = "https://vtbkeyboard.moe/api/get_vtb_list"
// GetVtbList ...
func (vdb *VtbDB) GetVtbList() (uidList []string) {
db := (*gorm.DB)(vdb)
client := &http.Client{}
req, err := http.NewRequest("GET", vtbUrl, nil)
req, err := http.NewRequest("GET", vtbURL, nil)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
// 自定义Header
req.Header.Set("User-Agent", randua())
resp, err := client.Do(req)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
vtbListStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1))
vtbListStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`))
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
count := gjson.Get(vtbListStr, "#").Int()
for i := int64(0); i < count; i++ {
item := gjson.Get(vtbListStr, strconv.FormatInt(i, 10))
logrus.Println(item)
log.Println(item)
fc := FirstCategory{
FirstCategoryIndex: i,
FirstCategoryName: item.Get("name").String(),
FirstCategoryDescription: item.Get("description").String(),
FirstCategoryIconPath: item.Get("icon_path").String(),
FirstCategoryUid: item.Get("uid").String(),
FirstCategoryUID: item.Get("uid").String(),
}
logrus.Println(fc)
log.Println(fc)
if err := db.Debug().Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).First(&fc).Error; err != nil {
if err := db.Debug().Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUID).First(&fc).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
db.Debug().Model(&FirstCategory{}).Create(&fc) // newUser not user
}
} else {
db.Debug().Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUid).Update(
db.Debug().Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUID).Update(
map[string]interface{}{
"first_category_index": i,
"first_category_name": item.Get("name").String(),
@@ -255,53 +240,54 @@ func (vdb *VtbDB) GetVtbList() (uidList []string) {
"first_category_icon_path": item.Get("icon_path").String(),
})
}
uidList = append(uidList, fc.FirstCategoryUid)
uidList = append(uidList, fc.FirstCategoryUID)
}
return uidList
}
// StoreVtb ...
func (vdb *VtbDB) StoreVtb(uid string) {
db := (*gorm.DB)(vdb)
vtbUrl := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid
vtbURL := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid
client := &http.Client{}
req, err := http.NewRequest("GET", vtbUrl, nil)
req, err := http.NewRequest("GET", vtbURL, nil)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
// 自定义Header
req.Header.Set("User-Agent", randua())
resp, err := client.Do(req)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
vtbStr, err := strconv.Unquote(strings.Replace(strconv.Quote(string(bytes)), `\\u`, `\u`, -1))
vtbStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`))
if err != nil {
logrus.Errorln(err)
log.Errorln(err)
return
}
secondCount := gjson.Get(vtbStr, "data.voices.#").Int()
logrus.Println("二级品类一共有", secondCount)
log.Println("二级品类一共有", secondCount)
for secondIndex := int64(0); secondIndex < secondCount; secondIndex++ {
secondItem := gjson.Get(vtbStr, "data.voices."+strconv.FormatInt(secondIndex, 10))
logrus.Println(secondItem)
log.Println(secondItem)
sc := SecondCategory{
SecondCategoryName: secondItem.Get("categoryName").String(),
SecondCategoryIndex: secondIndex,
SecondCategoryAuthor: secondItem.Get("author").String(),
SecondCategoryDescription: secondItem.Get("categoryDescription.zh-CN").String(),
FirstCategoryUid: uid,
FirstCategoryUID: uid,
}
if err := db.Debug().Model(&SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).First(&sc).Error; err != nil {
@@ -318,20 +304,20 @@ func (vdb *VtbDB) StoreVtb(uid string) {
})
}
thirdCount := secondItem.Get("voiceList.#").Int()
logrus.Println("三级品类一共有", thirdCount)
log.Println("三级品类一共有", thirdCount)
for thirdIndex := int64(0); thirdIndex < thirdCount; thirdIndex++ {
thirdItem := secondItem.Get("voiceList." + strconv.FormatInt(thirdIndex, 10))
logrus.Println(thirdItem)
log.Println(thirdItem)
tc := ThirdCategory{
ThirdCategoryName: thirdItem.Get("name").String(),
ThirdCategoryIndex: thirdIndex,
ThirdCategoryDescription: thirdItem.Get("description.zh-CN").String(),
FirstCategoryUid: uid,
FirstCategoryUID: uid,
SecondCategoryIndex: secondIndex,
ThirdCategoryPath: thirdItem.Get("path").String(),
ThirdCategoryAuthor: thirdItem.Get("author").String(),
}
logrus.Println(tc)
log.Println(tc)
if err := db.Debug().Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?",
uid, secondIndex, thirdIndex).First(&tc).Error; err != nil {

View File

@@ -1,3 +1,4 @@
// Package vtbquotation vtb经典语录
package vtbquotation
import (
@@ -8,17 +9,21 @@ import (
"time"
_ "github.com/logoove/sqlite" // use sql
"github.com/sirupsen/logrus"
log "github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/plugin_vtb_quotation/model"
"github.com/FloatTech/ZeroBot-Plugin/utils/txt2img"
)
const regStr = ".*/(.*)"
const dbpath = "data/VtbQuotation/"
const dbfile = dbpath + "vtb.db"
const (
regStr = ".*/(.*)"
dbpath = "data/VtbQuotation/"
dbfile = dbpath + "vtb.db"
)
var engine = control.Register("vtbquotation", &control.Options{
DisableOnDefault: false,
@@ -36,13 +41,16 @@ func init() {
Repeat() // 不断监听复读
db, err := model.Open(dbfile)
if err != nil {
logrus.Errorln(err)
log.Errorln("[vtb]:", err)
return
}
defer db.Close()
defer cancel()
firstStepMessage := db.GetAllFirstCategoryMessage()
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(firstStepMessage)); id == 0 {
firstStepImageBytes, err := txt2img.RenderToBase64(db.GetAllFirstCategoryMessage(), 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
// 步骤012依次选择3个类别
@@ -66,14 +74,26 @@ func init() {
ctx.SendChain(message.Reply(e.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输"))
errorCount++
} else {
SecondStepMessage := db.GetAllSecondCategoryMessageByFirstIndex(firstIndex)
// log.Println(SecondStepMessage)
if SecondStepMessage == "" {
secondStepMessage := db.GetAllSecondCategoryMessageByFirstIndex(firstIndex)
// log.Println(secondStepMessage)
if secondStepMessage == "" {
ctx.SendChain(message.Reply(e.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输"))
ctx.SendChain(message.Reply(e.MessageID), message.Text(db.GetAllFirstCategoryMessage()))
firstStepImageBytes, err := txt2img.RenderToBase64(db.GetAllFirstCategoryMessage(), 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
} else {
ctx.SendChain(message.Reply(e.MessageID), message.Text(SecondStepMessage))
secondStepMessageBytes, err := txt2img.RenderToBase64(secondStepMessage, 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
step++
}
}
@@ -85,14 +105,26 @@ func init() {
ctx.SendChain(message.Reply(e.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输"))
errorCount++
} else {
ThirdStepMessage := db.GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex)
// log.Println(ThirdStepMessage)
if ThirdStepMessage == "" {
thirdStepMessage := db.GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex)
// log.Println(thirdStepMessage)
if thirdStepMessage == "" {
ctx.SendChain(message.Reply(e.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输"))
ctx.SendChain(message.Reply(e.MessageID), message.Text(db.GetAllSecondCategoryMessageByFirstIndex(firstIndex)))
secondStepMessageBytes, err := txt2img.RenderToBase64(db.GetAllSecondCategoryMessageByFirstIndex(firstIndex), 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
} else {
ctx.SendChain(message.Reply(e.MessageID), message.Text(ThirdStepMessage))
thirdStepMessageBytes, err := txt2img.RenderToBase64(thirdStepMessage, 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(thirdStepMessageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
step++
}
}
@@ -109,7 +141,13 @@ func init() {
recURL := tc.ThirdCategoryPath
if recURL == "" {
ctx.SendChain(message.Reply(e.MessageID), message.Text("没有内容请重新选择,三次输入错误,指令可退出重输"))
ctx.SendChain(message.Reply(e.MessageID), message.Text(db.GetAllFirstCategoryMessage()))
firstStepImageBytes, err := txt2img.RenderToBase64(db.GetAllFirstCategoryMessage(), 40, 20)
if err != nil {
log.Errorln("[vtb]:", err)
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
step = 1
} else {
@@ -138,20 +176,17 @@ func init() {
Handle(func(ctx *zero.Ctx) {
db, err := model.Open(dbfile)
if err != nil {
logrus.Errorln(err)
log.Errorln("[vtb]:", err)
return
}
tc := db.RandomVtb()
fc := db.GetFirstCategoryByFirstUid(tc.FirstCategoryUid)
fc := db.GetFirstCategoryByFirstUID(tc.FirstCategoryUID)
if (tc != model.ThirdCategory{}) && (fc != model.FirstCategory{}) {
reg := regexp.MustCompile(regStr)
recURL := tc.ThirdCategoryPath
if reg.MatchString(recURL) {
// log.Println(reg.FindStringSubmatch(recordUrl)[1])
// log.Println(url.QueryEscape(reg.FindStringSubmatch(recordUrl)[1]))
recURL = strings.ReplaceAll(recURL, reg.FindStringSubmatch(recURL)[1], url.QueryEscape(reg.FindStringSubmatch(recURL)[1]))
recURL = strings.ReplaceAll(recURL, "+", "%20")
// log.Println(recordUrl)
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏"+fc.FirstCategoryName+"的《"+tc.ThirdCategoryName+"》"))
ctx.SendChain(message.Record(recURL))

View File

@@ -31,7 +31,7 @@ func init() {
}
ctx.SendChain(message.Text(s))
})
en.OnRegex(`^查询鬼东西(\d*)`).SetBlock(true).SetPriority(30).
en.OnRegex(`^查询鬼东西(\d*)`, zero.OnlyGroup).SetBlock(true).SetPriority(30).
Handle(func(ctx *zero.Ctx) {
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.SendChain(message.Text("请稍后重试0x0..."))

29
utils/ctxext/name.go Normal file
View File

@@ -0,0 +1,29 @@
// Package ctxext zero ctx 扩展
package ctxext
import (
"strconv"
zero "github.com/wdvxdr1123/ZeroBot"
)
// NickName 从 args 获取名字
func NickName(ctx *zero.Ctx) (name string) {
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
}
return
}
// CardOrNickName 从 uid 获取名字
func CardOrNickName(ctx *zero.Ctx, uid int64) (name string) {
name = ctx.GetGroupMemberInfo(ctx.Event.GroupID, uid, false).Get("card").String()
if name == "" {
name = ctx.GetStrangerInfo(uid, false).Get("nickname").String()
}
return
}

View File

@@ -8,10 +8,13 @@ import (
"net/http"
"os"
"sync"
"time"
"unsafe"
reg "github.com/fumiama/go-registry"
"github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
const (
@@ -19,8 +22,11 @@ const (
)
var (
registry = reg.NewRegReader("reilia.eastasia.azurecontainer.io:32664", "fumiama")
lzmu sync.Mutex
registry = reg.NewRegReader("reilia.eastasia.azurecontainer.io:32664", "fumiama")
connmu, getmu sync.Mutex
processes sync.WaitGroup
connerr error
isconnected bool
)
// GetLazyData 获取懒加载数据
@@ -32,24 +38,46 @@ func GetLazyData(path string, isReturnDataBytes, isDataMustEqual bool) ([]byte,
var resp *http.Response
var filemd5 *[16]byte
var ms string
var err error
u := dataurl + path[5:]
lzmu.Lock()
logrus.Infoln("[file]检查懒加载文件:", path)
err := registry.Connect()
if err != nil {
logrus.Errorln("[file]无法连接md5验证服务器,请自行确保下载文件的正确性:", err)
if !isconnected {
connmu.Lock()
if !isconnected && connerr == nil {
logrus.Infoln("[file]连接md5验证服务器...")
connerr = registry.ConnectIn(time.Second * 4)
if connerr == nil {
isconnected = true
go func() {
process.SleepAbout1sTo2s()
processes.Wait()
_ = registry.Close()
isconnected = false
logrus.Infoln("[file]关闭到md5验证服务器的连接")
}()
} else {
logrus.Warnln("[file]连接md5验证服务器失败:", connerr)
}
}
connmu.Unlock()
}
if connerr != nil {
logrus.Warnln("[file]无法连接到md5验证服务器请自行确保下载文件", path, "的正确性")
} else {
processes.Add(1)
getmu.Lock()
ms, err = registry.Get(path)
getmu.Unlock()
processes.Done()
if err != nil || len(ms) != 16 {
logrus.Errorln("[file]获取md5失败请自行确保下载文件", path, "的正确性:", err)
logrus.Warnln("[file]获取md5失败请自行确保下载文件", path, "的正确性:", err)
} else {
filemd5 = (*[16]byte)(*(*unsafe.Pointer)(unsafe.Pointer(&ms)))
logrus.Infoln("[file]从验证服务器获得文件md5:", hex.EncodeToString(filemd5[:]))
logrus.Infoln("[file]从验证服务器获得文件", path, "md5:", hex.EncodeToString(filemd5[:]))
}
}
_ = registry.Close()
lzmu.Unlock()
if IsExist(path) {
data, err = os.ReadFile(path)

View File

@@ -2,6 +2,7 @@ package math
import "strconv"
// Str2Int64 string to int64
func Str2Int64(str string) int64 {
val, _ := strconv.ParseInt(str, 10, 64)
return val

91
utils/txt2img/txt2img.go Normal file
View File

@@ -0,0 +1,91 @@
// Package txt2img 文字转图片
package txt2img
import (
"bytes"
"encoding/base64"
"image/jpeg"
"os"
"strings"
"github.com/fogleman/gg"
"github.com/mattn/go-runewidth"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
const (
whitespace = "\t\n\r\x0b\x0c"
fontpath = "data/Font/"
fontfile = fontpath + "regular.ttf"
)
// 加载数据库
func init() {
go func() {
process.SleepAbout1sTo2s()
_ = os.MkdirAll(fontpath, 0755)
_, _ = file.GetLazyData(fontfile, false, true)
}()
}
// RenderToBase64 文字转base64
func RenderToBase64(text string, width, fontSize int) (base64Bytes []byte, err error) {
canvas, err := Render(text, width, fontSize)
if err != nil {
log.Println("err:", err)
return nil, err
}
// 转成 base64
buffer := new(bytes.Buffer)
encoder := base64.NewEncoder(base64.StdEncoding, buffer)
var opt jpeg.Options
opt.Quality = 70
if err = jpeg.Encode(encoder, canvas.Image(), &opt); err != nil {
return nil, err
}
encoder.Close()
base64Bytes = buffer.Bytes()
return
}
// Render 文字转图片
func Render(text string, width, fontSize int) (canvas *gg.Context, err error) {
buff := make([]string, 0)
line := ""
count := 0
for _, v := range text {
c := string(v)
if strings.Contains(whitespace, c) {
buff = append(buff, strings.TrimSpace(line))
count = 0
line = ""
continue
}
if count <= width {
line += c
count += runewidth.StringWidth(c)
} else {
buff = append(buff, line)
line = c
count = runewidth.StringWidth(c)
}
}
canvas = gg.NewContext((fontSize+3)*width/2, (len(buff)+2)*fontSize)
canvas.SetRGB(1, 1, 1)
canvas.Clear()
canvas.SetRGB(0, 0, 0)
if err = canvas.LoadFontFace(fontfile, float64(fontSize)); err != nil {
log.Println("err:", err)
return nil, err
}
for i, v := range buff {
if v != "" {
canvas.DrawString(v, float64(width/2), float64((i+2)*fontSize))
}
}
return
}