Compare commits

..

39 Commits

Author SHA1 Message Date
fumiama
d6b81d0363 ✏️ v1.1.8 -> v1.2.0 2021-10-29 13:15:50 +08:00
fumiama
fdd1135a66 ✏️ 修正 timer 2021-10-29 12:54:11 +08:00
fumiama
f9ce439e56 ✏️ 修正正则与cd认证 2021-10-29 12:48:56 +08:00
fumiama
9608d1e736 ✏️ 小修正 2021-10-28 21:24:01 +08:00
fumiama
776d7fbbd9 ✏️ 小修正 2021-10-28 21:06:39 +08:00
fumiama
7c69c24362 ✏️ 在 main.go 引入 b14 2021-10-28 21:04:48 +08:00
fumiama
d205d48166 新增 插件冲突检测、b14 加解密 添加随机等待 1~2s 工具函数 2021-10-28 21:03:09 +08:00
fumiama
dd32aec462 新增插件翻译 by @sky-rainy 2021-10-28 17:05:59 +08:00
fumiama
c0327fe733 manager cron 完善 2021-10-28 11:40:30 +08:00
fumiama
6f4c40f450 差异化 pb 2021-10-27 23:55:54 +08:00
fumiama
022ee6cd95 manager 增加 cron 2021-10-27 23:50:46 +08:00
Kanri
085e04c9ba 🎨 改进结构 2021-10-27 22:28:19 +08:00
fumiama
19f58acb79 改用增强版 cron 2021-10-27 20:45:08 +08:00
fumiama
90dd60b942 升级依赖 & hs drop req 2021-10-27 19:35:57 +08:00
fumiama
755bfeaa5b fortune 增加下载锁;优化 gui 插件控制 2021-10-27 12:42:34 +08:00
fumiama
82ee2f6b0a 更改版本号到 v1.1.8 2021-10-27 10:34:18 +08:00
fumiama
500d03f293 ✏️ 优化打印 2021-10-27 00:19:17 +08:00
fumiama
ee99abe6ff 修复 timer 计时错误 2021-10-27 00:10:33 +08:00
fumiama
0563006c55 修复 timer 计时错误 2021-10-26 22:24:28 +08:00
fumiama
31db6fa4fb 修复 timer 计时错误 2021-10-26 22:09:01 +08:00
fumiama
043b543cfa 修复 timer 计时错误 2021-10-26 16:05:28 +08:00
fumiama
7b52599da7 修复 timer 计时错误 2021-10-26 15:22:00 +08:00
fumiama
4dc8e5619c 优化 timer 资源消耗 2021-10-26 15:05:32 +08:00
fumiama
21ff752322 ✏️ 离散化加载时间 2021-10-26 13:18:48 +08:00
fumiama
0f687d6e95 🔙 合并 timer 2021-10-26 13:11:45 +08:00
fumiama
22e23efbdc ✏️ 修复 sql 查询异常 2021-10-26 00:48:13 +08:00
fumiama
38935937ae control 增加还原;调整禁用优先级 2021-10-26 00:05:45 +08:00
fumiama
a3685e2e83 ✏️ 尝试解决win下路径异常 2021-10-24 18:13:12 +08:00
fumiama
3a5e391191 修正代码问题 2021-10-23 11:51:32 +08:00
fumiama
09a9dd53fd 修正代码问题 2021-10-23 01:09:15 +08:00
github-actions[bot]
5e064249be 🎨 改进代码样式 2021-10-22 16:55:19 +00:00
fumiama
67555512e7 搜图下载使用animeapi,将文件判存移至utils 2021-10-23 00:54:38 +08:00
fumiama
591df6439c 更新 goreleaser 2021-10-22 11:37:40 +08:00
fumiama
7dfb7dfe24 更新 goreleaser 2021-10-22 11:20:01 +08:00
Kanri
8e56f137b6 ⬆️ 更新依赖 2021-10-22 09:36:11 +08:00
源文雨
3b61c73c17 Update README.md 2021-10-20 22:56:31 +08:00
fumiama
44dac98b37 Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-10-18 15:25:06 +08:00
fumiama
1a7f98379a ✏️ 修正 acgimage 发图 2021-10-18 15:24:56 +08:00
Kanri
4109ef0612 Update main.go 2021-10-17 23:56:34 +08:00
42 changed files with 4146 additions and 333 deletions

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@ data/control
data/SetuTime/search
data/manager
data/acgimage
data/saucenao
data/fortune
data/hs
plugins/*.so

View File

@@ -1,3 +1,4 @@
project_name: zbp
env:
- GO111MODULE=on
before:
@@ -59,13 +60,6 @@ changelog:
- go mod tidy
archives:
- id: binary
builds:
- win
name_template: "zbp_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
format_overrides:
- goos: windows
format: binary
- id: nowin
builds:
- nowin
@@ -77,9 +71,9 @@ archives:
nfpms:
- license: GPL 3.0
homepage: https://go-cqhttp.org
homepage: https://github.com/FloatTech/ZeroBot-Plugin
file_name_template: "zbp_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
formats:
- deb
- rpm
maintainer: Kanri, DawnNights, Fumiama, Suika
maintainer: FloatTech

View File

@@ -12,7 +12,7 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/FloatTech/ZeroBot-Plugin?style=flat-square&logo=go)](https://goreportcard.com/report/github.com/github.com/FloatTech/ZeroBot-Plugin)
[![Badge](https://img.shields.io/badge/onebot-v11-black?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABwCAMAAADxPgR5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAxQTFRF////29vbr6+vAAAAk1hCcwAAAAR0Uk5T////AEAqqfQAAAKcSURBVHja7NrbctswDATQXfD//zlpO7FlmwAWIOnOtNaTM5JwDMa8E+PNFz7g3waJ24fviyDPgfhz8fHP39cBcBL9KoJbQUxjA2iYqHL3FAnvzhL4GtVNUcoSZe6eSHizBcK5LL7dBr2AUZlev1ARRHCljzRALIEog6H3U6bCIyqIZdAT0eBuJYaGiJaHSjmkYIZd+qSGWAQnIaz2OArVnX6vrItQvbhZJtVGB5qX9wKqCMkb9W7aexfCO/rwQRBzsDIsYx4AOz0nhAtWu7bqkEQBO0Pr+Ftjt5fFCUEbm0Sbgdu8WSgJ5NgH2iu46R/o1UcBXJsFusWF/QUaz3RwJMEgngfaGGdSxJkE/Yg4lOBryBiMwvAhZrVMUUvwqU7F05b5WLaUIN4M4hRocQQRnEedgsn7TZB3UCpRrIJwQfqvGwsg18EnI2uSVNC8t+0QmMXogvbPg/xk+Mnw/6kW/rraUlvqgmFreAA09xW5t0AFlHrQZ3CsgvZm0FbHNKyBmheBKIF2cCA8A600aHPmFtRB1XvMsJAiza7LpPog0UJwccKdzw8rdf8MyN2ePYF896LC5hTzdZqxb6VNXInaupARLDNBWgI8spq4T0Qb5H4vWfPmHo8OyB1ito+AysNNz0oglj1U955sjUN9d41LnrX2D/u7eRwxyOaOpfyevCWbTgDEoilsOnu7zsKhjRCsnD/QzhdkYLBLXjiK4f3UWmcx2M7PO21CKVTH84638NTplt6JIQH0ZwCNuiWAfvuLhdrcOYPVO9eW3A67l7hZtgaY9GZo9AFc6cryjoeFBIWeU+npnk/nLE0OxCHL1eQsc1IciehjpJv5mqCsjeopaH6r15/MrxNnVhu7tmcslay2gO2Z1QfcfX0JMACG41/u0RrI9QAAAABJRU5ErkJggg==)](https://github.com/howmanybots/onebot)
[![Badge](https://img.shields.io/badge/zerobot-v1.3.0-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![Badge](https://img.shields.io/badge/zerobot-v1.3.2-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![License](https://img.shields.io/github/license/Yiwen-Chan/OneBot-YaYa.svg?style=flat-square&logo=gnu)](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
[![qq group](https://img.shields.io/badge/group-1048452984-red?style=flat-square&logo=tencent-qq)](https://jq.qq.com/?_wv=1027&k=QMb7x1mM)
@@ -42,8 +42,10 @@ zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ...
- [x] /禁用 xxx (在发送的群/用户禁用xxx)
- [x] /全局启用 xxx
- [x] /全局禁用 xxx
- [x] /还原 xxx (在发送的群/用户还原xxx的开启状态到初始状态)
- [x] /用法 xxx
- [x] /服务列表
- [x] @Bot 插件冲突检测 (会在本群发送一条消息并在约 1s 后撤回以检测其它同类 bot 中已启用的插件并禁用)
- **聊天** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_chat"`
- [x] [BOT名字]
- [x] [戳一戳BOT]
@@ -74,6 +76,8 @@ zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ...
- [x] 在[MM]月[每周|周几]的[hh]点[mm]分时(用[url])提醒大家[xxx]
- [x] 取消在[MM]月[dd]日的[hh]点[mm]分的提醒
- [x] 取消在[MM]月[每周|周几]的[hh]点[mm]分的提醒
- [x] 在"cron"时(用[url])提醒大家[xxx]
- [x] 取消在"cron"的提醒
- [x] 列出所有提醒
- [x] 翻牌
- [x] [开启|关闭]入群验证
@@ -105,6 +109,9 @@ zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ...
- [x] 摸[@xxx]
- [x] 搓[@xxx]
- 注:更多指令见项目 --> https://github.com/tdf1939/ZeroBot-Plugin-Gif
- **base16384加解密** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_b14"`
- [x] 加密xxx
- [x] 解密xxx
- **涩图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_setutime"`
- [x] 来份[涩图/二次元/风景/车万]
- [x] 添加[涩图/二次元/风景/车万][P站图片ID]
@@ -160,6 +167,8 @@ zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ...
- **投胎** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_reborn"`
- [x] reborn
- 注:本插件来源于[tgbot](https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py)
- **翻译** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation"`
- [x] >TL 你好
- **TODO...**
## 使用方法

93
control/cd.go Normal file
View File

@@ -0,0 +1,93 @@
package control
import (
"encoding/binary"
"strings"
"time"
b14 "github.com/fumiama/go-base16384"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
var startTime int64
func init() {
// 插件冲突检测 会在本群发送一条消息并在约 1s 后撤回
zero.OnFullMatch("插件冲突检测", zero.OnlyGroup, zero.AdminPermission, zero.OnlyToMe).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
tok, err := genToken()
if err != nil {
return
}
t := message.Text("●cd" + tok)
startTime = time.Now().Unix()
id := ctx.SendChain(t)
process.SleepAbout1sTo2s()
ctx.DeleteMessage(id)
})
zero.OnRegex("^●cd([\u4e00-\u8e00]{4})$", zero.OnlyGroup).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
if isValidToken(ctx.State["regex_matched"].([]string)[1]) {
msg := ""
gid := ctx.Event.GroupID
ForEach(func(key string, manager *Control) bool {
if manager.IsEnabledIn(gid) {
msg += "\xfe\xff" + key
}
return true
})
if len(msg) > 2 {
my, err := b14.UTF16be2utf8(b14.EncodeString(msg[2:]))
mys := "●cd●" + helper.BytesToString(my)
if err == nil {
id := ctx.SendChain(message.Text(mys))
process.SleepAbout1sTo2s()
ctx.DeleteMessage(id)
}
}
}
})
zero.OnRegex("^●cd●(([\u4e00-\u8e00]*[\u3d01-\u3d06]?))", zero.OnlyGroup).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
if time.Now().Unix()-startTime < 10 {
msg, err := b14.UTF82utf16be(helper.StringToBytes(ctx.State["regex_matched"].([]string)[1]))
if err == nil {
gid := ctx.Event.GroupID
for _, s := range strings.Split(b14.DecodeString(msg), "\xfe\xff") {
mu.RLock()
c, ok := managers[s]
mu.RUnlock()
if ok && c.IsEnabledIn(gid) {
c.Disable(gid)
}
}
}
}
})
}
func genToken() (tok string, err error) {
timebytes := make([]byte, 8)
binary.BigEndian.PutUint64(timebytes, uint64(time.Now().Unix()))
timebytes, err = b14.UTF16be2utf8(b14.Encode(timebytes[1:]))
if err == nil {
tok = helper.BytesToString(timebytes)
}
return
}
func isValidToken(tok string) (yes bool) {
s, err := b14.UTF82utf16be(helper.StringToBytes(tok))
if err == nil {
timebytes := make([]byte, 1, 8)
timebytes = append(timebytes, b14.Decode(s)...)
yes = time.Now().Unix()-int64(binary.BigEndian.Uint64(timebytes)) < 10
}
return
}

19
control/cd_test.go Normal file
View File

@@ -0,0 +1,19 @@
package control
import "testing"
func TestGenToken(t *testing.T) {
tok, err := genToken()
if err == nil {
t.Log(tok)
t.Log(isValidToken(tok))
t.Fail()
} else {
t.Fatal(err)
}
}
func TestMaru(t *testing.T) {
t.Log(len("\xff"))
t.Fail()
}

View File

@@ -15,8 +15,6 @@ import (
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
const ALL int64 = 0
var (
db = &sql.Sqlite{DBPath: "data/control/plugins.db"}
// managers 每个插件对应的管理
@@ -57,10 +55,10 @@ func newctrl(service string, o *Options) *Control {
func (m *Control) Enable(groupID int64) {
m.Lock()
err := db.Insert(m.service, &grpcfg{groupID, 0})
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
m.Unlock()
}
// Disable disables a group to pass the Manager.
@@ -68,36 +66,46 @@ func (m *Control) Enable(groupID int64) {
func (m *Control) Disable(groupID int64) {
m.Lock()
err := db.Insert(m.service, &grpcfg{groupID, 1})
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
m.Unlock()
}
// Reset resets the default config of a group.
// groupID == 0 (ALL) is not allowed.
func (m *Control) Reset(groupID int64) {
if groupID != 0 {
m.Lock()
err := db.Del(m.service, "WHERE gid = "+strconv.FormatInt(groupID, 10))
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
}
}
// IsEnabledIn 开启群
func (m *Control) IsEnabledIn(gid int64) bool {
m.RLock()
var c grpcfg
err := db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(ALL, 10))
if err == nil {
logrus.Debugf("[control] plugin %s of all : %d", m.service, c.GroupID, c.Disable)
if c.Disable != 0 {
m.RUnlock()
return false
var err error
logrus.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()
logrus.Debugln("[control] db find gid =", c.GroupID)
if err == nil && gid == c.GroupID {
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable)
return c.Disable == 0
}
}
err = db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
if err == nil {
m.RUnlock()
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable)
return c.Disable == 0
}
logrus.Errorf("[control] %v", err)
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = 0")
m.RUnlock()
if m.options.DisableOnDefault {
m.Disable(gid)
} else {
m.Enable(gid)
if err == nil {
logrus.Debugf("[control] plugin %s of all : %d", m.service, c.Disable)
return c.Disable == 0
}
return !m.options.DisableOnDefault
}
@@ -111,6 +119,7 @@ func (m *Control) Handler() zero.Rule {
// 个人用户
grp = -ctx.Event.UserID
}
logrus.Debugln("[control] handler get gid =", grp)
return m.IsEnabledIn(grp)
}
}
@@ -144,6 +153,13 @@ func copyMap(m map[string]*Control) map[string]*Control {
return ret
}
func userOrGrpAdmin(ctx *zero.Ctx) bool {
if zero.OnlyGroup(ctx) {
return zero.AdminPermission(ctx)
}
return zero.OnlyToMe(ctx)
}
func init() {
if !hasinit {
mu.Lock()
@@ -156,37 +172,47 @@ func init() {
zero.OnCommandGroup([]string{
"启用", "enable", "禁用", "disable",
"全局启用", "enableall", "全局禁用", "disableall",
}, func(ctx *zero.Ctx) bool {
if zero.OnlyGroup(ctx) {
return zero.AdminPermission(ctx)
}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
}
return zero.OnlyToMe(ctx)
}).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
}
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
if strings.Contains(model.Command, "全局") || strings.Contains(model.Command, "all") {
grp = 0
}
if strings.Contains(model.Command, "启用") || strings.Contains(model.Command, "enable") {
service.Enable(grp)
ctx.SendChain(message.Text("已启用服务: " + model.Args))
} else {
service.Disable(grp)
ctx.SendChain(message.Text("已禁用服务: " + model.Args))
}
})
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
if strings.Contains(model.Command, "全局") || strings.Contains(model.Command, "all") {
grp = 0
}
if strings.Contains(model.Command, "启用") || strings.Contains(model.Command, "enable") {
service.Enable(grp)
ctx.SendChain(message.Text("已启用服务: " + model.Args))
} else {
service.Disable(grp)
ctx.SendChain(message.Text("已禁用服务: " + model.Args))
}
})
zero.OnCommandGroup([]string{"用法", "usage"}, zero.AdminPermission, zero.OnlyGroup).
zero.OnCommandGroup([]string{"还原", "reset"}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
}
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
service.Reset(grp)
ctx.SendChain(message.Text("已还原服务的默认启用状态: " + model.Args))
})
zero.OnCommandGroup([]string{"用法", "usage"}, userOrGrpAdmin).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
@@ -201,14 +227,15 @@ func init() {
}
})
zero.OnCommandGroup([]string{"服务列表", "service_list"}, zero.AdminPermission, zero.OnlyGroup).
zero.OnCommandGroup([]string{"服务列表", "service_list"}, userOrGrpAdmin).
Handle(func(ctx *zero.Ctx) {
msg := `---服务列表---`
i := 0
gid := ctx.Event.GroupID
ForEach(func(key string, manager *Control) bool {
i++
msg += "\n" + strconv.Itoa(i) + `: `
if manager.IsEnabledIn(ctx.Event.GroupID) {
if manager.IsEnabledIn(gid) {
msg += "●" + key
} else {
msg += "○" + key

View File

@@ -128,23 +128,11 @@ func updateAllPluginStatus(context *gin.Context) {
}
enable = parse["enable"].(bool)
}
var groups []int64
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, group := range ctx.GetGroupList().Array() {
groups = append(groups, group.Get("group_id").Int())
}
return true
})
ctrl.ForEach(func(key string, manager *ctrl.Control) bool {
if enable {
for _, group := range groups {
manager.Enable(group)
}
manager.Enable(0)
} else {
for _, group := range groups {
manager.Disable(group)
}
manager.Disable(0)
}
return true
})
@@ -175,18 +163,11 @@ func updatePluginAllGroupStatus(context *gin.Context) {
context.JSON(404, nil)
return
}
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, group := range ctx.GetGroupList().Array() {
if enable {
control.Enable(group.Get("group_id").Int())
} else {
control.Disable(group.Get("group_id").Int())
}
}
return true
})
if enable {
control.Enable(0)
} else {
control.Disable(0)
}
context.JSON(200, nil)
}

13
go.mod
View File

@@ -3,20 +3,19 @@ module github.com/FloatTech/ZeroBot-Plugin
go 1.16
require (
github.com/FloatTech/AnimeAPI v1.1.9
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.3
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3
github.com/FloatTech/AnimeAPI v1.1.10
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4
github.com/FloatTech/bot-manager v1.0.0
github.com/fogleman/gg v1.3.0
github.com/fumiama/cron v1.3.0
github.com/fumiama/go-base16384 v1.2.1
github.com/gin-gonic/gin v1.7.4
github.com/golang/protobuf v1.5.2
github.com/gorilla/websocket v1.4.2
github.com/imroc/req v0.3.0
github.com/mroth/weightedrand v0.4.1
github.com/robfig/cron v1.2.0
github.com/shirou/gopsutil v3.21.9+incompatible
github.com/sirupsen/logrus v1.8.1
github.com/tidwall/gjson v1.9.4
github.com/tidwall/gjson v1.10.2
github.com/wdvxdr1123/ZeroBot v1.3.2
modernc.org/sqlite v1.13.1
modernc.org/sqlite v1.13.3
)

76
go.sum
View File

@@ -1,9 +1,9 @@
github.com/FloatTech/AnimeAPI v1.1.9 h1:H1hZmgwZPNHdx39K9JvY3awT8TTsCl9kKA1uVMyCjRg=
github.com/FloatTech/AnimeAPI v1.1.9/go.mod h1:CC+vF30UGBlcIUxwFOcXIEHoJ4r7c5x2iLQsnUCVdDI=
github.com/FloatTech/AnimeAPI v1.1.10 h1:fYkv65P1HBukHi3GpzYulGx/xLshEL9635QXALDryf0=
github.com/FloatTech/AnimeAPI v1.1.10/go.mod h1:CC+vF30UGBlcIUxwFOcXIEHoJ4r7c5x2iLQsnUCVdDI=
github.com/FloatTech/ZeroBot-Plugin v1.1.5/go.mod h1:kWuUARvU7gs4xLggi8Sy37ja2GRL6k0X6kewe5TiZRs=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.3 h1:TGQHhiPR/XIxYYoB6IxOzgMhsZs2tDYQlaJHT04gkQ8=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.3/go.mod h1:W7ag6hml1pZTNzRXKU74OMr6rS8awQKSU+o2g7Gj4O0=
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3 h1:jn/dH+OwPSRozkmeCeQQPrAGJRBudcm3OK5tXhGItRk=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4 h1:WW0BmmLLqAg+m6qGkrKbsfSIm91fkj3/udt3R7Myodo=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4/go.mod h1:W7ag6hml1pZTNzRXKU74OMr6rS8awQKSU+o2g7Gj4O0=
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3/go.mod h1:MVOQQ4e6AVGFm993blXXU4Sd6bAsLY2+Zb+/HMrEeEc=
github.com/FloatTech/bot-manager v1.0.0 h1:d63J5htLhVBc2ITG09WBJI+qAB0ubPjYhfXl6hljBNk=
github.com/FloatTech/bot-manager v1.0.0/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ=
@@ -27,6 +27,10 @@ github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4/go.mod h1:H
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
github.com/fumiama/go-base16384 v1.2.1 h1:6OGprW8g/95m2ocmryHi8mipZ7bx9StFMZDKEqLvMiA=
github.com/fumiama/go-base16384 v1.2.1/go.mod h1:1HTC0QFL7BjS0DuO5Qm+fBYKQkHqmAapLbRpCxrhPXQ=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
@@ -55,10 +59,11 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/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=
github.com/imroc/req v0.3.0 h1:3EioagmlSG+z+KySToa+Ylo3pTFZs+jh3Brl7ngU12U=
github.com/imroc/req v0.3.0/go.mod h1:F+NZ+2EFSo6EFXdeIbpfE9hcC233id70kf0byW97Caw=
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=
@@ -86,7 +91,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.9+incompatible h1:LTLpUnfX81MkHeCtSrwNKZwuW5Id6kCa7/P43NdcNn4=
@@ -107,8 +111,8 @@ github.com/tdf1939/ZeroBot-Plugin-Gif v0.0.0-20210828060956-389b1dc33652/go.mod
github.com/tdf1939/img v0.0.0-20210827153520-90cb4e9580a3/go.mod h1:FgTEOcosTWrkOr7++gbtPSj1rX5loRWrf/AL+hm3Cnw=
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
github.com/tidwall/gjson v1.9.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
github.com/tidwall/gjson v1.9.4 h1:oNis7dk9Rs3dKJNNigXZT1MTOiJeBtpurn+IpCB75MY=
github.com/tidwall/gjson v1.9.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.10.2 h1:APbLGOM0rrEkd8WBw9C24nllro4ajFuJu0Sc9hRz8Bo=
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
@@ -158,8 +162,9 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b h1:S7hKs0Flbq0bbc9xgYt4stIEG1zNDFqyrPwAX2Wj/sE=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
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=
@@ -192,22 +197,59 @@ lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
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 h1:hb4dYlebd23NPxULTgLPoM5pI3QBgInCOHPJQiff5PA=
modernc.org/cc/v3 v3.35.15/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.39 h1:a5VerUVWhtfhVTiLDKIcebmVzXY1U9PeUrKJ71unE9w=
modernc.org/ccgo/v3 v3.12.39/go.mod h1:0r9ejJghrz/33dA6cF6m6m6Glk1uWs0pwagU5T4wOf8=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
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=
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.40 h1:kzLVEt6LvBF9KrFgHDVzd597oqgRcBfMN8x5OidNN90=
modernc.org/libc v1.11.40/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
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=
@@ -219,13 +261,15 @@ modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
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/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
modernc.org/sqlite v1.13.1 h1:s/qk6VTTVyQIyhVNWa50whBBcI3+2oREbx85t227iOo=
modernc.org/sqlite v1.13.1/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
modernc.org/sqlite v1.13.3 h1:YBJFhSWRjWQzu7nt0ge/YrRck04eRnGPsarJFZcmHiI=
modernc.org/sqlite v1.13.3/go.mod h1:Y8WjcK0WOWYeA5jN3V9IqtrZdm4iEUxxCebCngP/08M=
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 h1:DZMfR+RDJRhcrmMEMTJgVIX+Wf5qhfVX0llI0rsc20w=
modernc.org/tcl v1.5.9/go.mod h1:bcwjvBJ2u0exY6K35eAmxXBBij5kXb1dHlAWmfhqThE=
modernc.org/tcl v1.8.1 h1:siVlE4O6t06k8CFftpJyb5T76O1uWzDus5hWScEF1F4=
modernc.org/tcl v1.8.1/go.mod h1:7SlzI6/UneYHe4xn3QCyvbHnj6A//hDZVkAWSGHnowg=
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 h1:IjjzDsIFbl0wuF2KfwvdyUAJVwxD4iwZ6akLNiDoClM=
modernc.org/z v1.1.2/go.mod h1:sj9T1AGBG0dm6SCVzldPOHWrif6XBpooJtbttMn1+Js=
modernc.org/z v1.2.7 h1:N0BrQ6wWlEkF+jj1phyav9guASZcWb5j+TuwHcWLWzY=
modernc.org/z v1.2.7/go.mod h1:+L7Vxulgf/QRxha9syRObResxBwvPEDs53Cy43g47Ls=

38
main.go
View File

@@ -18,10 +18,12 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_qingyunke" // 青云客
// 实用类
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_github" // 搜索GitHub仓库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_manager" // 群管
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh" // 拼音首字母缩写释义工具
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_runcode" // 在线运行代码
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_b14" // base16384加解密
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_github" // 搜索GitHub仓库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_manager" // 群管
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh" // 拼音首字母缩写释义工具
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_runcode" // 在线运行代码
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_translation" // 翻译
// 娱乐类
_ "github.com/FloatTech/ZeroBot-Plugin-Gif" // 制图
@@ -57,8 +59,8 @@ import (
var (
contents = []string{
"* OneBot + ZeroBot + Golang",
"* Version 1.1.7 - 2021-10-09 12:50:23 +0800 CST",
"* Copyright © 2020 - 2021 Kanri, DawnNights, Fumiama, Suika",
"* Version 1.2.0 - 2021-10-29 13:08:45 +0800 CST",
"* Copyright © 2020 - 2021 FloatTech. All Rights Reserved.",
"* Project: https://github.com/FloatTech/ZeroBot-Plugin",
}
banner = strings.Join(contents, "\n")
@@ -101,23 +103,21 @@ func printBanner() {
func main() {
printBanner()
zero.Run(zero.Config{
NickName: []string{"椛椛", "ATRI", "atri", "亚托莉", "アトリ"},
CommandPrefix: "/",
// SuperUsers 某些功能需要主人权限,可通过以下两种方式修改
// []string{}:通过代码写死的方式添加主人账号
// flag.Args():通过命令行参数的方式添加主人账号
SuperUsers: append([]string{"12345678", "87654321"}, flag.Args()...),
Driver: []zero.Driver{
driver.NewWebSocketClient(*url, *token),
},
},
)
// 帮助
zero.OnFullMatchGroup([]string{"/help", ".help", "菜单"}, zero.OnlyToMe).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
ctx.SendChain(message.Text(banner))
})
zero.Run(
zero.Config{
NickName: []string{"椛椛", "ATRI", "atri", "亚托莉", "アトリ"},
CommandPrefix: "/",
// SuperUsers 某些功能需要主人权限,可通过以下两种方式修改
// "12345678", "87654321":通过代码写死的方式添加主人账号
// flag.Args():通过命令行参数的方式添加主人账号,无需修改下方任何代码
SuperUsers: append([]string{"12345678", "87654321"}, flag.Args()...),
Driver: []zero.Driver{driver.NewWebSocketClient(*url, *token)},
},
)
select {}
}

View File

@@ -3,7 +3,6 @@ package acgimage
import (
"net/url"
"os"
"strconv"
"strings"
@@ -13,6 +12,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
const (
@@ -21,9 +21,8 @@ const (
)
var (
botpath, _ = os.Getwd()
datapath = botpath + "/data/acgimage/"
cacheuri = "file:///" + datapath + "cache"
datapath = file.BOT_PATH + "/data/acgimage/"
cacheuri = "file:///" + datapath + "cache"
// r18有一定保护一般不会发出图片
randapi = "&loli=true&r18=true"
msgof = make(map[int64]int64)
@@ -126,7 +125,7 @@ func replyClass(ctx *zero.Ctx, dhash string, class int, noimg bool, lv int64, co
if err3 == nil {
ctx.SendChain(message.Text(comment + "\n给你点提示哦" + b14))
ctx.Event.GroupID = 0
ctx.SendChain(message.Text(img))
ctx.SendChain(img)
}
} else {
ctx.SendChain(message.Text(comment))

View File

@@ -11,6 +11,8 @@ import (
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
var (
@@ -26,18 +28,18 @@ func init() { // 插件主体
zero.OnFullMatch("ATRI醒醒", zero.AdminPermission).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
enable = true
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randText("嗯呜呜……夏生先生……?"))
})
zero.OnFullMatch("ATRI睡吧", zero.AdminPermission).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
enable = false
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randText("Zzz……Zzz……"))
})
zero.OnFullMatch("萝卜子", atriSwitch(), atriSleep()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
switch rand.Intn(2) {
case 0:
ctx.SendChain(randText("萝卜子是对机器人的蔑称!", "是亚托莉......萝卜子可是对机器人的蔑称"))
@@ -47,18 +49,18 @@ func init() { // 插件主体
})
zero.OnFullMatchGroup([]string{"喜欢", "爱你", "爱", "suki", "daisuki", "すき", "好き", "贴贴", "老婆", "亲一个", "mua"}, atriSwitch(), atriSleep(), zero.OnlyToMe).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randImage("SUKI.jpg", "SUKI1.jpg", "SUKI2.png"))
})
zero.OnKeywordGroup([]string{"草你妈", "操你妈", "脑瘫", "废柴", "fw", "five", "废物", "战斗", "爬", "爪巴", "sb", "SB", "傻B"}, atriSwitch(), atriSleep(), zero.OnlyToMe).SetBlock(true).SetPriority(prio - 1).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randImage("FN.jpg", "WQ.jpg", "WQ1.jpg"))
})
zero.OnFullMatchGroup([]string{"早安", "早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早"}, atriSwitch()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
now := time.Now().Hour()
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
switch {
case now < 6: // 凌晨
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
@@ -99,7 +101,7 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
now := time.Now().Hour()
if now > 11 && now < 15 { // 中午
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
"午安w",
"午觉要好好睡哦ATRI会陪伴在你身旁的w",
@@ -111,7 +113,7 @@ func init() { // 插件主体
zero.OnFullMatchGroup([]string{"晚安", "oyasuminasai", "おやすみなさい", "晚好", "晚上好"}, atriSwitch()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
now := time.Now().Hour()
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
switch {
case now < 6: // 凌晨
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
@@ -153,7 +155,7 @@ func init() { // 插件主体
})
zero.OnKeywordGroup([]string{"高性能", "太棒了", "すごい", "sugoi", "斯国一", "よかった"}, atriSwitch(), atriSleep(), zero.OnlyToMe).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randText(
"当然,我是高性能的嘛~",
"小事一桩,我是高性能的嘛",
@@ -174,7 +176,7 @@ func init() { // 插件主体
})
zero.OnKeywordGroup([]string{"没事", "没关系", "大丈夫", "还好", "不要紧", "没出大问题", "没伤到哪"}, atriSwitch(), atriSleep(), zero.OnlyToMe).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randText(
"当然,我是高性能的嘛~",
"没事没事,因为我是高性能的嘛!嗯哼!",
@@ -189,26 +191,26 @@ func init() { // 插件主体
zero.OnKeywordGroup([]string{"好吗", "是吗", "行不行", "能不能", "可不可以"}, atriSwitch(), atriSleep()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
if rand.Intn(2) == 0 {
ctx.SendChain(randImage("YES.png", "NO.jpg"))
}
})
zero.OnKeywordGroup([]string{"啊这"}, atriSwitch(), atriSleep()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
if rand.Intn(2) == 0 {
ctx.SendChain(randImage("AZ.jpg", "AZ1.jpg"))
}
})
zero.OnKeywordGroup([]string{"我好了"}, atriSwitch(), atriSleep()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText("不许好!", "憋回去!"))
})
zero.OnFullMatchGroup([]string{"", "?", "¿"}, atriSwitch(), atriSleep()).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
switch rand.Intn(5) {
case 0:
ctx.SendChain(randText("?", "", "嗯?", "(。´・ω・)ん?", "ん?"))
@@ -227,7 +229,7 @@ func init() { // 插件主体
})
zero.OnKeyword("答应我", atriSwitch(), atriSleep(), zero.OnlyToMe).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
time.Sleep(time.Second * 1)
process.SleepAbout1sTo2s()
ctx.SendChain(randText("我无法回应你的请求"))
})
}

38
plugin_b14/main.go Normal file
View File

@@ -0,0 +1,38 @@
package b14coder
import (
base14 "github.com/fumiama/go-base16384"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
)
func init() {
en := control.Register("base16384", &control.Options{
DisableOnDefault: false,
Help: "base16384加解密\n" +
"- 加密xxx\n- 解密xxx",
})
en.OnRegex(`^加密(.*)`).SetBlock(true).ThirdPriority().
Handle(func(ctx *zero.Ctx) {
str := ctx.State["regex_matched"].([]string)[1]
es, err := base14.UTF16be2utf8(base14.EncodeString(str))
if err == nil {
ctx.SendChain(message.Text(helper.BytesToString(es)))
} else {
ctx.SendChain(message.Text("加密失败!"))
}
})
en.OnRegex("^解密([\u4e00-\u8e00]*[\u3d01-\u3d06]?)$").SetBlock(true).ThirdPriority().
Handle(func(ctx *zero.Ctx) {
str := ctx.State["regex_matched"].([]string)[1]
es, err := base14.UTF82utf16be(helper.StringToBytes(str))
if err == nil {
ctx.SendChain(message.Text(base14.DecodeString(es)))
} else {
ctx.SendChain(message.Text("解密失败!"))
}
})
}

View File

@@ -5,7 +5,7 @@ import (
"net/http"
"time"
"github.com/robfig/cron"
"github.com/fumiama/cron"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
@@ -32,12 +32,15 @@ func init() {
// 定时任务每天晚上最后2分钟执行一次
func fansDaily(groupID int64) {
c := cron.New()
_ = c.AddFunc("0 58 23 * * ?", func() { fansData(groupID) })
c.Start()
_, err := c.AddFunc("0 58 23 * * ?", func() { fansData(groupID) })
if err == nil {
c.Start()
}
}
// 获取数据拼接消息链并发送
func fansData(groupID int64) {
// TODO: 更改为 GetBot
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
var (
diana = fansapi("672328094")

View File

@@ -3,14 +3,17 @@ package data
import (
"crypto/md5"
"errors"
"io"
"net/http"
"os"
"sync"
"time"
log "github.com/sirupsen/logrus"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
const (
@@ -31,7 +34,7 @@ var (
func init() {
go func() {
time.Sleep(time.Second)
process.SleepAbout1sTo2s()
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
@@ -53,7 +56,7 @@ func init() {
// LoadText 加载小作文
func LoadText() error {
if _, err := os.Stat(pbfile); err == nil || os.IsExist(err) {
if file.IsExist(pbfile) {
f, err := os.Open(pbfile)
if err == nil {
defer f.Close()
@@ -116,7 +119,7 @@ func isin(sum *[16]byte) bool {
func savecompo() error {
data, err := compo.Marshal()
if err == nil {
if _, err := os.Stat(datapath); err == nil || os.IsExist(err) {
if file.IsExist(datapath) {
f, err1 := os.OpenFile(pbfile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 == nil {
_, err2 := f.Write(data)
@@ -125,6 +128,7 @@ func savecompo() error {
}
return err1
}
return errors.New("datapath is not exist")
}
return err
}

View File

@@ -1,9 +1,12 @@
package fortune
import (
"errors"
io "io"
"os"
"sync"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
var (
@@ -13,7 +16,7 @@ var (
func loadcfg(name string) error {
name = base + name
if _, err := os.Stat(name); err == nil || os.IsExist(err) {
if file.IsExist(name) {
f, err := os.Open(name)
if err == nil {
defer f.Close()
@@ -35,7 +38,7 @@ func savecfg(name string) error {
name = base + name
data, err := conf.Marshal()
if err == nil {
if _, err := os.Stat(base); err == nil || os.IsExist(err) {
if file.IsExist(base) {
f, err1 := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 == nil {
mu.Lock()
@@ -46,6 +49,7 @@ func savecfg(name string) error {
}
return err1
}
return errors.New("base dir is not exist")
}
return err
}

View File

@@ -12,6 +12,7 @@ import (
"math/rand"
"os"
"strconv"
"sync"
"time"
"github.com/fogleman/gg"
@@ -21,7 +22,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/dl"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
@@ -35,6 +36,8 @@ var (
table = [...]string{"车万", "DC4", "爱因斯坦", "星空列车", "樱云之恋", "富婆妹", "李清歌", "公主连结", "原神", "明日方舟", "碧蓝航线", "碧蓝幻想", "战双", "阴阳师"}
// 映射底图与 index
index = make(map[string]uint32)
// 下载锁
dlmu sync.Mutex
)
func init() {
@@ -76,25 +79,33 @@ func init() {
Handle(func(ctx *zero.Ctx) {
// 检查签文文件是否存在
mikuji := base + "运势签文.json"
if _, err := os.Stat(mikuji); err != nil && !os.IsExist(err) {
ctx.SendChain(message.Text("正在下载签文文件,请稍后..."))
err := dl.DownloadTo(site+"运势签文.json", mikuji)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
if file.IsNotExist(mikuji) {
dlmu.Lock()
if file.IsNotExist(mikuji) {
ctx.SendChain(message.Text("正在下载签文文件,请稍后..."))
err := file.DownloadTo(site+"运势签文.json", mikuji)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载签文文件完毕"))
}
ctx.SendChain(message.Text("下载签文文件完毕"))
dlmu.Unlock()
}
// 检查字体文件是否存在
ttf := base + "sakura.ttf"
if _, err := os.Stat(ttf); err != nil && !os.IsExist(err) {
ctx.SendChain(message.Text("正在下载字体文件,请稍后..."))
err := dl.DownloadTo(site+"sakura.ttf", ttf)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
if file.IsNotExist(ttf) {
dlmu.Lock()
if file.IsNotExist(ttf) {
ctx.SendChain(message.Text("正在下载字体文件,请稍后..."))
err := file.DownloadTo(site+"sakura.ttf", ttf)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载字体文件完毕"))
}
ctx.SendChain(message.Text("下载字体文件完毕"))
dlmu.Unlock()
}
// 获取该群背景类型,默认车万
kind := "车万"
@@ -109,24 +120,28 @@ func init() {
}
// 检查背景图片是否存在
folder := base + kind
if _, err := os.Stat(folder); err != nil && !os.IsExist(err) {
ctx.SendChain(message.Text("正在下载背景图片,请稍后..."))
zipfile := kind + ".zip"
zipcache := base + zipfile
err := dl.DownloadTo(site+zipfile, zipcache)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
if file.IsNotExist(folder) {
dlmu.Lock()
if file.IsNotExist(folder) {
ctx.SendChain(message.Text("正在下载背景图片,请稍后..."))
zipfile := kind + ".zip"
zipcache := base + zipfile
err := file.DownloadTo(site+zipfile, zipcache)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载背景图片完毕"))
err = unpack(zipcache, folder+"/")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("解压背景图片完毕"))
// 释放空间
os.Remove(zipcache)
}
ctx.SendChain(message.Text("下载背景图片完毕"))
err = unpack(zipcache, folder+"/")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("解压背景图片完毕"))
// 释放空间
os.Remove(zipcache)
dlmu.Unlock()
}
// 生成种子
t, _ := strconv.ParseInt(time.Now().Format("20060102"), 10, 64)
@@ -160,7 +175,7 @@ func init() {
// @return 错误信息
func unpack(tgt, dest string) error {
// 路径目录不存在则创建目录
if _, err := os.Stat(dest); err != nil && !os.IsExist(err) {
if file.IsNotExist(dest) {
if err := os.MkdirAll(dest, 0755); err != nil {
panic(err)
}

View File

@@ -3,26 +3,44 @@ package hs
import (
"fmt"
"io"
"os"
"strconv"
"strings"
"github.com/imroc/req"
"github.com/tidwall/gjson"
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/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/web"
)
var botpath, _ = os.Getwd()
var cachedir = botpath + "/data/hs/"
var (
cachedir = file.BOT_PATH + "/data/hs/"
reqconf = [...]string{"GET", "https://hs.fbigame.com",
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36"}
)
var header = req.Header{
"user-agent": `Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36`,
"referer": `https://hs.fbigame.com`,
}
const (
hs = `https://hs.fbigame.com/ajax.php?`
para = "mod=get_cards_list&" +
"mode=-1&" +
"extend=-1&" +
"mutil_extend=&" +
"hero=-1&" +
"rarity=-1&" +
"cost=-1&" +
"mutil_cost=&" +
"techlevel=-1&" +
"type=-1&" +
"collectible=-1&" +
"isbacon=-1&" +
"page=1&" +
"search_type=1&" +
"deckmode=normal"
)
func init() {
os.RemoveAll(cachedir)
@@ -48,24 +66,17 @@ func init() {
return
}
var sk message.Message
var data []byte
for i := 0; i < t && i < 5; i++ {
cid := gjson.Get(g, `list.`+strconv.Itoa(i)+`.CardID`).String()
cachefile := cachedir + cid
imgcq := `[CQ:image,file=` + "file:///" + cachefile + `]`
if _, err := os.Stat(cachefile); err != nil {
im, err := req.Get(`https://res.fbigame.com/hs/v13/`+cid+
`.png?auth_key=`+gjson.Get(g, `list.`+strconv.Itoa(i)+`.auth_key`).String(),
header,
)
if file.IsNotExist(cachefile) {
data, err := web.ReqWith(
`https://res.fbigame.com/hs/v13/`+cid+`.png?auth_key=`+
gjson.Get(g, `list.`+strconv.Itoa(i)+`.auth_key`).String(),
reqconf[0], reqconf[1], reqconf[2])
if err == nil {
data, err = io.ReadAll(im.Response().Body)
if err == nil {
err = im.Response().Body.Close()
if err == nil {
err = os.WriteFile(cachefile, data, 0644)
}
}
err = os.WriteFile(cachefile, data, 0644)
}
if err != nil {
imgcq = err.Error()
@@ -97,39 +108,25 @@ func init() {
}
func sh(s string) string {
var hs = `https://hs.fbigame.com/ajax.php`
h, _ := req.Get("https://hs.fbigame.com", header)
var param = req.Param{
"mod": `get_cards_list`,
"mode": `-1`,
"extend": `-1`,
"mutil_extend": ``,
"hero": `-1`,
"rarity": `-1`,
"cost": `-1`,
"mutil_cost": ``,
"techlevel": `-1`,
"type": `-1`,
"collectible": `-1`,
"isbacon": `-1`,
"page": `1`,
"search_type": `1`,
"deckmode": "normal",
"hash": strings.SplitN(strings.SplitN(h.String(), `var hash = "`, 2)[1], `"`, 2)[0],
data, err := web.ReqWith("https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2])
if err == nil {
url := hs + para + "&hash=" + strings.SplitN(strings.SplitN(helper.BytesToString(data), `var hash = "`, 2)[1], `"`, 2)[0] + "&search=" + s
r, err := web.ReqWith(url, reqconf[0], reqconf[1], reqconf[2])
if err == nil {
return helper.BytesToString(r)
}
}
r, _ := req.Get(hs, header, param, req.Param{"search": s})
return r.String()
return ""
}
func kz(s string) string {
h, _ := req.Get("https://hs.fbigame.com")
param := req.Param{
"mod": `general_deck_image`,
"deck_code": s,
"deck_text": ``,
"hash": strings.SplitN(strings.SplitN(h.String(), `var hash = "`, 2)[1], `"`, 2)[0],
data, err := web.ReqWith("https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2])
if err == nil {
url := hs + para + "mod=general_deck_image&deck_code=" + s + "&deck_text=&hash=" + strings.SplitN(strings.SplitN(helper.BytesToString(data), `var hash = "`, 2)[1], `"`, 2)[0] + "&search=" + s
r, err := web.ReqWith(url, reqconf[0], reqconf[1], reqconf[2])
if err == nil {
return "base64://" + gjson.Get(helper.BytesToString(r), "img").String()
}
}
r, _ := req.Get(`https://hs.fbigame.com/ajax.php`, param, h.Request().Header)
im := gjson.Get(r.String(), "img").String()
return `base64://` + im
return ""
}

View File

@@ -11,19 +11,21 @@ import (
"strings"
"time"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
timer "github.com/FloatTech/ZeroBot-Plugin-Timer"
"github.com/FloatTech/ZeroBot-Plugin/plugin_manager/timer"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
const (
datapath = "data/manager/"
confile = datapath + "config.pb"
hint = "====群管====\n" +
datapath = "data/manager/"
confile = datapath + "config.pb"
timerfile = datapath + "timers.pb"
hint = "====群管====\n" +
"- 禁言@QQ 1分钟\n" +
"- 解除禁言 @QQ\n" +
"- 我要自闭 1分钟\n" +
@@ -51,10 +53,15 @@ const (
var (
config Config
limit = rate.NewManager(time.Minute*5, 2)
clock timer.Clock
)
func init() { // 插件主体
loadConfig()
go func() {
time.Sleep(time.Second + time.Millisecond*time.Duration(rand.Intn(1000)))
clock = timer.NewClock(timerfile)
}()
// 菜单
zero.OnFullMatch("群管系统", zero.AdminPermission).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
@@ -246,45 +253,70 @@ func init() { // 插件主体
ctx.SendChain(message.Text("📧 --> " + ctx.State["regex_matched"].([]string)[1]))
})
// 定时提醒
zero.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.AdminPermission).SetBlock(true).SetPriority(40).
zero.OnRegex(`^在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
if ctx.Event.GroupID > 0 {
dateStrs := ctx.State["regex_matched"].([]string)
ts := timer.GetFilledTimeStamp(dateStrs, false)
ts.Grpid = uint64(ctx.Event.GroupID)
if ts.Enable {
go timer.RegisterTimer(ts, true)
ctx.SendChain(message.Text("记住了~"))
} else {
ctx.SendChain(message.Text("参数非法!"))
}
dateStrs := ctx.State["regex_matched"].([]string)
ts := timer.GetFilledTimer(dateStrs, ctx.Event.SelfID, false)
if ts.En() {
go clock.RegisterTimer(ts, ctx.Event.GroupID, true)
ctx.SendChain(message.Text("记住了~"))
} else {
ctx.SendChain(message.Text("参数非法:" + ts.Alert))
}
})
// 定时 cron 提醒
zero.OnRegex(`^在"(.*)"时(用.+)?提醒大家(.*)`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
dateStrs := ctx.State["regex_matched"].([]string)
var url, alert string
switch len(dateStrs) {
case 4:
url = dateStrs[2]
alert = dateStrs[3]
case 3:
alert = dateStrs[2]
default:
ctx.SendChain(message.Text("参数非法!"))
return
}
logrus.Debugln("[manager] cron:", dateStrs[1])
ts := timer.GetFilledCronTimer(dateStrs[1], alert, url, ctx.Event.SelfID)
if clock.RegisterTimer(ts, ctx.Event.GroupID, true) {
ctx.SendChain(message.Text("记住了~"))
} else {
ctx.SendChain(message.Text("参数非法:" + ts.Alert))
}
})
// 取消定时
zero.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.AdminPermission).SetBlock(true).SetPriority(40).
zero.OnRegex(`^取消在(.{1,2})月(.{1,3}日|每?周.?)的(.{1,3})点(.{1,3})分的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
if ctx.Event.GroupID > 0 {
dateStrs := ctx.State["regex_matched"].([]string)
ts := timer.GetFilledTimeStamp(dateStrs, true)
ts.Grpid = uint64(ctx.Event.GroupID)
ti := timer.GetTimerInfo(ts)
t, ok := (*timer.Timers)[ti]
if ok {
t.Enable = false
delete(*timer.Timers, ti) // 避免重复取消
_ = timer.SaveTimers()
ctx.SendChain(message.Text("取消成功~"))
} else {
ctx.SendChain(message.Text("没有这个定时器哦~"))
}
dateStrs := ctx.State["regex_matched"].([]string)
ts := timer.GetFilledTimer(dateStrs, ctx.Event.SelfID, true)
ti := ts.GetTimerInfo(ctx.Event.GroupID)
ok := clock.CancelTimer(ti)
if ok {
ctx.SendChain(message.Text("取消成功~"))
} else {
ctx.SendChain(message.Text("没有这个定时器哦~"))
}
})
// 取消 cron 定时
zero.OnRegex(`^取消在"(.*)"的提醒`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
dateStrs := ctx.State["regex_matched"].([]string)
ts := timer.Timer{Cron: dateStrs[1]}
ti := ts.GetTimerInfo(ctx.Event.GroupID)
ok := clock.CancelTimer(ti)
if ok {
ctx.SendChain(message.Text("取消成功~"))
} else {
ctx.SendChain(message.Text("没有这个定时器哦~"))
}
})
// 列出本群所有定时
zero.OnFullMatch("列出所有提醒", zero.AdminPermission).SetBlock(true).SetPriority(40).
zero.OnFullMatch("列出所有提醒", zero.AdminPermission, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
if ctx.Event.GroupID > 0 {
ctx.SendChain(message.Text(timer.ListTimers(uint64(ctx.Event.GroupID))))
}
ctx.SendChain(message.Text(clock.ListTimers(uint64(ctx.Event.GroupID))))
})
// 随机点名
zero.OnFullMatchGroup([]string{"翻牌"}, zero.OnlyGroup).SetBlock(true).SetPriority(40).
@@ -427,7 +459,7 @@ func strToInt(str string) int64 {
func loadConfig() {
mkdirerr := os.MkdirAll(datapath, 0755)
if mkdirerr == nil {
if _, err := os.Stat(confile); err == nil || os.IsExist(err) {
if file.IsExist(confile) {
f, err := os.Open(confile)
if err == nil {
data, err1 := io.ReadAll(f)
@@ -452,7 +484,7 @@ func saveConfig() error {
data, err := config.Marshal()
if err != nil {
return err
} else if _, err := os.Stat(datapath); err == nil || os.IsExist(err) {
} else if file.IsExist(datapath) {
f, err1 := os.OpenFile(confile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 != nil {
return err1

View File

@@ -0,0 +1,71 @@
package main
import (
"fmt"
io "io"
"os"
"time"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
var timersmap TimersMapOld
var timersmapnew TimersMap
func loadTimers(pbfile string) bool {
if file.IsExist(pbfile) {
f, err := os.Open(pbfile)
if err == nil {
data, err1 := io.ReadAll(f)
if err1 == nil {
if len(data) > 0 {
err1 = timersmap.Unmarshal(data)
if err1 == nil {
return true
}
}
}
}
}
return false
}
// saveTimers 保存当前计时器
func saveTimers(pbfile string) error {
data, err := timersmapnew.Marshal()
if err == nil {
f, err1 := os.OpenFile(pbfile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 != nil {
return err1
} else {
_, err2 := f.Write(data)
f.Close()
return err2
}
}
return err
}
func main() {
if len(os.Args) == 3 {
if loadTimers(os.Args[1]) {
timersmapnew.Timers = make(map[string]*Timer)
for s, t := range timersmap.Timers {
tm := &Timer{
Alert: t.Alert,
Url: t.Url,
}
tm.SetMonth(time.Month(t.Month))
tm.SetDay(int(t.Day))
tm.SetHour(int(t.Hour))
tm.SetMinute(int(t.Minute))
tm.SetWeek(time.Weekday(t.Week))
tm.SetEn(t.Enable)
timersmapnew.Timers[s] = tm
}
saveTimers(os.Args[2])
}
} else {
fmt.Println("用法:旧文件路径 新文件路径")
}
}

View File

@@ -0,0 +1,946 @@
package main
import (
fmt "fmt"
io "io"
math "math"
math_bits "math/bits"
proto "github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type TimerOld struct {
Enable bool `protobuf:"varint,1,opt,name=enable,proto3" json:"enable,omitempty"`
Alert string `protobuf:"bytes,2,opt,name=alert,proto3" json:"alert,omitempty"`
Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"`
Month int32 `protobuf:"zigzag32,4,opt,name=month,proto3" json:"month,omitempty"`
Day int32 `protobuf:"zigzag32,5,opt,name=day,proto3" json:"day,omitempty"`
Week int32 `protobuf:"zigzag32,6,opt,name=week,proto3" json:"week,omitempty"`
Hour int32 `protobuf:"zigzag32,7,opt,name=hour,proto3" json:"hour,omitempty"`
Minute int32 `protobuf:"zigzag32,8,opt,name=minute,proto3" json:"minute,omitempty"`
Grpid uint64 `protobuf:"varint,9,opt,name=grpid,proto3" json:"grpid,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TimerOld) Reset() { *m = TimerOld{} }
func (m *TimerOld) String() string { return proto.CompactTextString(m) }
func (*TimerOld) ProtoMessage() {}
func (*TimerOld) Descriptor() ([]byte, []int) {
return fileDescriptor_old, []int{0}
}
func (m *TimerOld) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TimerOld) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Timer.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TimerOld) XXX_Merge(src proto.Message) {
xxx_messageInfo_Timer.Merge(m, src)
}
func (m *TimerOld) XXX_Size() int {
return m.Size()
}
func (m *TimerOld) XXX_DiscardUnknown() {
xxx_messageInfo_Timer.DiscardUnknown(m)
}
func (m *TimerOld) GetEnable() bool {
if m != nil {
return m.Enable
}
return false
}
func (m *TimerOld) GetAlert() string {
if m != nil {
return m.Alert
}
return ""
}
func (m *TimerOld) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
func (m *TimerOld) GetMonth() int32 {
if m != nil {
return m.Month
}
return 0
}
func (m *TimerOld) GetDay() int32 {
if m != nil {
return m.Day
}
return 0
}
func (m *TimerOld) GetWeek() int32 {
if m != nil {
return m.Week
}
return 0
}
func (m *TimerOld) GetHour() int32 {
if m != nil {
return m.Hour
}
return 0
}
func (m *TimerOld) GetMinute() int32 {
if m != nil {
return m.Minute
}
return 0
}
func (m *TimerOld) GetGrpid() uint64 {
if m != nil {
return m.Grpid
}
return 0
}
type TimersMapOld struct {
Timers map[string]*TimerOld `protobuf:"bytes,1,rep,name=timers,proto3" json:"timers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TimersMapOld) Reset() { *m = TimersMapOld{} }
func (m *TimersMapOld) String() string { return proto.CompactTextString(m) }
func (*TimersMapOld) ProtoMessage() {}
func (*TimersMapOld) Descriptor() ([]byte, []int) {
return fileDescriptor_old, []int{1}
}
func (m *TimersMapOld) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TimersMapOld) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TimersMap.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TimersMapOld) XXX_Merge(src proto.Message) {
xxx_messageInfo_TimersMap.Merge(m, src)
}
func (m *TimersMapOld) XXX_Size() int {
return m.Size()
}
func (m *TimersMapOld) XXX_DiscardUnknown() {
xxx_messageInfo_TimersMap.DiscardUnknown(m)
}
func (m *TimersMapOld) GetTimers() map[string]*TimerOld {
if m != nil {
return m.Timers
}
return nil
}
func init() {
proto.RegisterType((*TimerOld)(nil), "timer.Timer")
proto.RegisterType((*TimersMapOld)(nil), "timer.TimersMap")
proto.RegisterMapType((map[string]*TimerOld)(nil), "timer.TimersMap.TimersEntry")
}
func init() { proto.RegisterFile("timer.proto", fileDescriptor_old) }
var fileDescriptor_old = []byte{
// 278 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x4c, 0x90, 0xcd, 0x4a, 0xc3, 0x40,
0x10, 0xc7, 0x9d, 0xe6, 0xc3, 0x66, 0xe3, 0xa1, 0x2e, 0x22, 0x83, 0x48, 0x08, 0x39, 0xe5, 0xd4,
0x43, 0xf5, 0x20, 0x1e, 0x05, 0xf1, 0xe4, 0x65, 0xf1, 0x05, 0x52, 0xba, 0xd8, 0xd0, 0x7c, 0xb1,
0xdd, 0x28, 0x79, 0x05, 0x9f, 0xc0, 0x17, 0x12, 0x3c, 0xfa, 0x08, 0x12, 0x5f, 0x44, 0x66, 0x36,
0x94, 0xde, 0x7e, 0xff, 0x5f, 0xfe, 0x64, 0x67, 0x46, 0xc4, 0xb6, 0xac, 0xb5, 0x59, 0x76, 0xa6,
0xb5, 0xad, 0x0c, 0x38, 0x64, 0x5f, 0x20, 0x82, 0x17, 0x22, 0x79, 0x29, 0x42, 0xdd, 0x14, 0xeb,
0x4a, 0x23, 0xa4, 0x90, 0xcf, 0xd5, 0x94, 0xe4, 0x85, 0x08, 0x8a, 0x4a, 0x1b, 0x8b, 0xb3, 0x14,
0xf2, 0x48, 0xb9, 0x20, 0x17, 0xc2, 0xeb, 0x4d, 0x85, 0x1e, 0x3b, 0x42, 0xea, 0xd5, 0x6d, 0x63,
0xb7, 0xe8, 0xa7, 0x90, 0x9f, 0x2b, 0x17, 0xa8, 0xb7, 0x29, 0x06, 0x0c, 0xd8, 0x11, 0x4a, 0x29,
0xfc, 0x77, 0xad, 0x77, 0x18, 0xb2, 0x62, 0x26, 0xb7, 0x6d, 0x7b, 0x83, 0xa7, 0xce, 0x11, 0xd3,
0x3c, 0x75, 0xd9, 0xf4, 0x56, 0xe3, 0x9c, 0xed, 0x94, 0xe8, 0x9d, 0x57, 0xd3, 0x95, 0x1b, 0x8c,
0x52, 0xc8, 0x7d, 0xe5, 0x42, 0xf6, 0x01, 0x22, 0xe2, 0x3d, 0xf6, 0xcf, 0x45, 0x27, 0x6f, 0x45,
0xc8, 0xeb, 0xed, 0x11, 0x52, 0x2f, 0x8f, 0x57, 0xd7, 0x4b, 0xb7, 0xfa, 0xa1, 0x31, 0xd1, 0x63,
0x63, 0xcd, 0xa0, 0xa6, 0xee, 0xd5, 0x93, 0x88, 0x8f, 0x34, 0x8d, 0xbe, 0xd3, 0x03, 0x5f, 0x23,
0x52, 0x84, 0x32, 0x13, 0xc1, 0x5b, 0x51, 0xf5, 0x9a, 0x4f, 0x11, 0xaf, 0xce, 0x8e, 0xff, 0xaa,
0xdc, 0xa7, 0xfb, 0xd9, 0x1d, 0x3c, 0x2c, 0xbe, 0xc7, 0x04, 0x7e, 0xc6, 0x04, 0x7e, 0xc7, 0x04,
0x3e, 0xff, 0x92, 0x93, 0x75, 0xc8, 0x47, 0xbf, 0xf9, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xc7,
0xad, 0xf8, 0x83, 0x01, 0x00, 0x00,
}
func (m *TimerOld) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TimerOld) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TimerOld) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.Grpid != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64(m.Grpid))
i--
dAtA[i] = 0x48
}
if m.Minute != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64((uint32(m.Minute)<<1)^uint32((m.Minute>>31))))
i--
dAtA[i] = 0x40
}
if m.Hour != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64((uint32(m.Hour)<<1)^uint32((m.Hour>>31))))
i--
dAtA[i] = 0x38
}
if m.Week != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64((uint32(m.Week)<<1)^uint32((m.Week>>31))))
i--
dAtA[i] = 0x30
}
if m.Day != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64((uint32(m.Day)<<1)^uint32((m.Day>>31))))
i--
dAtA[i] = 0x28
}
if m.Month != 0 {
i = encodeVarintTimerOld(dAtA, i, uint64((uint32(m.Month)<<1)^uint32((m.Month>>31))))
i--
dAtA[i] = 0x20
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarintTimerOld(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0x1a
}
if len(m.Alert) > 0 {
i -= len(m.Alert)
copy(dAtA[i:], m.Alert)
i = encodeVarintTimerOld(dAtA, i, uint64(len(m.Alert)))
i--
dAtA[i] = 0x12
}
if m.Enable {
i--
if m.Enable {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *TimersMapOld) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TimersMapOld) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TimersMapOld) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Timers) > 0 {
for k := range m.Timers {
v := m.Timers[k]
baseI := i
if v != nil {
{
size, err := v.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTimerOld(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintTimerOld(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintTimerOld(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintTimerOld(dAtA []byte, offset int, v uint64) int {
offset -= sovTimerOld(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *TimerOld) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.Enable {
n += 2
}
l = len(m.Alert)
if l > 0 {
n += 1 + l + sovTimerOld(uint64(l))
}
l = len(m.Url)
if l > 0 {
n += 1 + l + sovTimerOld(uint64(l))
}
if m.Month != 0 {
n += 1 + sozTimerOld(uint64(m.Month))
}
if m.Day != 0 {
n += 1 + sozTimerOld(uint64(m.Day))
}
if m.Week != 0 {
n += 1 + sozTimerOld(uint64(m.Week))
}
if m.Hour != 0 {
n += 1 + sozTimerOld(uint64(m.Hour))
}
if m.Minute != 0 {
n += 1 + sozTimerOld(uint64(m.Minute))
}
if m.Grpid != 0 {
n += 1 + sovTimerOld(uint64(m.Grpid))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *TimersMapOld) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Timers) > 0 {
for k, v := range m.Timers {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
l += 1 + sovTimerOld(uint64(l))
}
mapEntrySize := 1 + len(k) + sovTimerOld(uint64(len(k))) + l
n += mapEntrySize + 1 + sovTimerOld(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovTimerOld(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozTimerOld(x uint64) (n int) {
return sovTimerOld(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *TimerOld) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Timer: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Timer: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Enable", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Enable = bool(v != 0)
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Alert", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimerOld
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimerOld
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Alert = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimerOld
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimerOld
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Month", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))
m.Month = v
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Day", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))
m.Day = v
case 6:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Week", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))
m.Week = v
case 7:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Hour", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))
m.Hour = v
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Minute", wireType)
}
var v int32
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
v = int32((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))
m.Minute = v
case 9:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Grpid", wireType)
}
m.Grpid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Grpid |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipTimerOld(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimerOld
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *TimersMapOld) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TimersMap: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TimersMap: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Timers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTimerOld
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTimerOld
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Timers == nil {
m.Timers = make(map[string]*TimerOld)
}
var mapkey string
var mapvalue *TimerOld
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthTimerOld
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthTimerOld
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimerOld
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthTimerOld
}
postmsgIndex := iNdEx + mapmsglen
if postmsgIndex < 0 {
return ErrInvalidLengthTimerOld
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = &TimerOld{}
if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipTimerOld(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimerOld
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Timers[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTimerOld(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimerOld
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTimerOld(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimerOld
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimerOld
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimerOld
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthTimerOld
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupTimerOld
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthTimerOld
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthTimerOld = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTimerOld = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTimerOld = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,810 @@
package main
import (
fmt "fmt"
io "io"
math "math"
math_bits "math/bits"
proto "github.com/golang/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Timer struct {
Alert string `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"`
Cron string `protobuf:"bytes,2,opt,name=cron,proto3" json:"cron,omitempty"`
En1Month4Day5Week3Hour5Min6 int32 `protobuf:"varint,4,opt,name=en1month4day5week3hour5min6,proto3" json:"en1month4day5week3hour5min6,omitempty"`
Selfid int64 `protobuf:"varint,8,opt,name=selfid,proto3" json:"selfid,omitempty"`
Url string `protobuf:"bytes,16,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Timer) Reset() { *m = Timer{} }
func (m *Timer) String() string { return proto.CompactTextString(m) }
func (*Timer) ProtoMessage() {}
func (*Timer) Descriptor() ([]byte, []int) {
return fileDescriptor_ad0307ee16b652d2, []int{0}
}
func (m *Timer) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Timer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Timer.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Timer) XXX_Merge(src proto.Message) {
xxx_messageInfo_Timer.Merge(m, src)
}
func (m *Timer) XXX_Size() int {
return m.Size()
}
func (m *Timer) XXX_DiscardUnknown() {
xxx_messageInfo_Timer.DiscardUnknown(m)
}
var xxx_messageInfo_Timer proto.InternalMessageInfo
func (m *Timer) GetAlert() string {
if m != nil {
return m.Alert
}
return ""
}
func (m *Timer) GetCron() string {
if m != nil {
return m.Cron
}
return ""
}
func (m *Timer) GetEn1Month4Day5Week3Hour5Min6() int32 {
if m != nil {
return m.En1Month4Day5Week3Hour5Min6
}
return 0
}
func (m *Timer) GetSelfid() int64 {
if m != nil {
return m.Selfid
}
return 0
}
func (m *Timer) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
type TimersMap struct {
Timers map[string]*Timer `protobuf:"bytes,1,rep,name=timers,proto3" json:"timers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TimersMap) Reset() { *m = TimersMap{} }
func (m *TimersMap) String() string { return proto.CompactTextString(m) }
func (*TimersMap) ProtoMessage() {}
func (*TimersMap) Descriptor() ([]byte, []int) {
return fileDescriptor_ad0307ee16b652d2, []int{1}
}
func (m *TimersMap) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TimersMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TimersMap.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TimersMap) XXX_Merge(src proto.Message) {
xxx_messageInfo_TimersMap.Merge(m, src)
}
func (m *TimersMap) XXX_Size() int {
return m.Size()
}
func (m *TimersMap) XXX_DiscardUnknown() {
xxx_messageInfo_TimersMap.DiscardUnknown(m)
}
var xxx_messageInfo_TimersMap proto.InternalMessageInfo
func (m *TimersMap) GetTimers() map[string]*Timer {
if m != nil {
return m.Timers
}
return nil
}
func init() {
proto.RegisterType((*Timer)(nil), "timer.Timer")
proto.RegisterType((*TimersMap)(nil), "timer.TimersMap")
proto.RegisterMapType((map[string]*Timer)(nil), "timer.TimersMap.TimersEntry")
}
func init() { proto.RegisterFile("timer.proto", fileDescriptor_ad0307ee16b652d2) }
var fileDescriptor_ad0307ee16b652d2 = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0xc9, 0xcc, 0x4d,
0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0x94, 0xe6, 0x32, 0x72, 0xb1,
0x86, 0x80, 0x58, 0x42, 0x22, 0x5c, 0xac, 0x89, 0x39, 0xa9, 0x45, 0x25, 0x12, 0x8c, 0x0a, 0x8c,
0x1a, 0x9c, 0x41, 0x10, 0x8e, 0x90, 0x10, 0x17, 0x4b, 0x72, 0x51, 0x7e, 0x9e, 0x04, 0x13, 0x58,
0x10, 0xcc, 0x16, 0x72, 0xe0, 0x92, 0x4e, 0xcd, 0x33, 0xcc, 0xcd, 0xcf, 0x2b, 0xc9, 0x30, 0x49,
0x49, 0xac, 0x34, 0x2d, 0x4f, 0x4d, 0xcd, 0x36, 0xce, 0xc8, 0x2f, 0x2d, 0x32, 0xcd, 0xcd, 0xcc,
0x33, 0x93, 0x60, 0x51, 0x60, 0xd4, 0x60, 0x0d, 0xc2, 0xa7, 0x44, 0x48, 0x8c, 0x8b, 0xad, 0x38,
0x35, 0x27, 0x2d, 0x33, 0x45, 0x82, 0x43, 0x81, 0x51, 0x83, 0x39, 0x08, 0xca, 0x13, 0x12, 0xe0,
0x62, 0x2e, 0x2d, 0xca, 0x91, 0x10, 0x00, 0x5b, 0x06, 0x62, 0x2a, 0x75, 0x31, 0x72, 0x71, 0x82,
0xdd, 0x57, 0xec, 0x9b, 0x58, 0x20, 0x64, 0xc2, 0xc5, 0x06, 0x76, 0x76, 0xb1, 0x04, 0xa3, 0x02,
0xb3, 0x06, 0xb7, 0x91, 0x8c, 0x1e, 0xc4, 0x4b, 0x70, 0x15, 0x50, 0x96, 0x6b, 0x5e, 0x49, 0x51,
0x65, 0x10, 0x54, 0xad, 0x94, 0x3b, 0x17, 0x37, 0x92, 0x30, 0xc8, 0x92, 0xec, 0xd4, 0x4a, 0xa8,
0x37, 0x41, 0x4c, 0x21, 0x25, 0x2e, 0xd6, 0xb2, 0xc4, 0x9c, 0xd2, 0x54, 0xb0, 0x2f, 0xb9, 0x8d,
0x78, 0x90, 0x4d, 0x0d, 0x82, 0x48, 0x59, 0x31, 0x59, 0x30, 0x3a, 0x09, 0x9c, 0x78, 0x24, 0xc7,
0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81,
0x03, 0xd3, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xc1, 0x9e, 0x44, 0x5b, 0x01, 0x00, 0x00,
}
func (m *Timer) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Timer) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Timer) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x82
}
if m.Selfid != 0 {
i = encodeVarintTimer(dAtA, i, uint64(m.Selfid))
i--
dAtA[i] = 0x40
}
if m.En1Month4Day5Week3Hour5Min6 != 0 {
i = encodeVarintTimer(dAtA, i, uint64(m.En1Month4Day5Week3Hour5Min6))
i--
dAtA[i] = 0x20
}
if len(m.Cron) > 0 {
i -= len(m.Cron)
copy(dAtA[i:], m.Cron)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Cron)))
i--
dAtA[i] = 0x12
}
if len(m.Alert) > 0 {
i -= len(m.Alert)
copy(dAtA[i:], m.Alert)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Alert)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *TimersMap) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TimersMap) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TimersMap) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Timers) > 0 {
for k := range m.Timers {
v := m.Timers[k]
baseI := i
if v != nil {
{
size, err := v.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTimer(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintTimer(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintTimer(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintTimer(dAtA []byte, offset int, v uint64) int {
offset -= sovTimer(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Timer) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Alert)
if l > 0 {
n += 1 + l + sovTimer(uint64(l))
}
l = len(m.Cron)
if l > 0 {
n += 1 + l + sovTimer(uint64(l))
}
if m.En1Month4Day5Week3Hour5Min6 != 0 {
n += 1 + sovTimer(uint64(m.En1Month4Day5Week3Hour5Min6))
}
if m.Selfid != 0 {
n += 1 + sovTimer(uint64(m.Selfid))
}
l = len(m.Url)
if l > 0 {
n += 2 + l + sovTimer(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *TimersMap) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Timers) > 0 {
for k, v := range m.Timers {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
l += 1 + sovTimer(uint64(l))
}
mapEntrySize := 1 + len(k) + sovTimer(uint64(len(k))) + l
n += mapEntrySize + 1 + sovTimer(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovTimer(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozTimer(x uint64) (n int) {
return sovTimer(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Timer) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Timer: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Timer: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Alert", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Alert = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Cron", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Cron = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field En1Month4Day5Week3Hour5Min6", wireType)
}
m.En1Month4Day5Week3Hour5Min6 = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.En1Month4Day5Week3Hour5Min6 |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Selfid", wireType)
}
m.Selfid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Selfid |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 16:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *TimersMap) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TimersMap: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TimersMap: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Timers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Timers == nil {
m.Timers = make(map[string]*Timer)
}
var mapkey string
var mapvalue *Timer
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthTimer
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthTimer
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthTimer
}
postmsgIndex := iNdEx + mapmsglen
if postmsgIndex < 0 {
return ErrInvalidLengthTimer
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = &Timer{}
if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Timers[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTimer(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthTimer
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupTimer
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthTimer
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthTimer = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTimer = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTimer = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,75 @@
package main
import "time"
func (m *Timer) En() (en bool) {
return m.En1Month4Day5Week3Hour5Min6&0x800000 != 0
}
func (m *Timer) Month() (mon time.Month) {
mon = time.Month((m.En1Month4Day5Week3Hour5Min6 & 0x780000) >> 19)
if mon == 0b1111 {
mon = -1
}
return
}
func (m *Timer) Day() (d int) {
d = int((m.En1Month4Day5Week3Hour5Min6 & 0x07c000) >> 14)
if d == 0b11111 {
d = -1
}
return
}
func (m *Timer) Week() (w time.Weekday) {
w = time.Weekday((m.En1Month4Day5Week3Hour5Min6 & 0x003800) >> 11)
if w == 0b111 {
w = -1
}
return
}
func (m *Timer) Hour() (h int) {
h = int((m.En1Month4Day5Week3Hour5Min6 & 0x0007c0) >> 6)
if h == 0b11111 {
h = -1
}
return
}
func (m *Timer) Minute() (min int) {
min = int(m.En1Month4Day5Week3Hour5Min6 & 0x00003f)
if min == 0b111111 {
min = -1
}
return
}
func (m *Timer) SetEn(en bool) {
if en {
m.En1Month4Day5Week3Hour5Min6 |= 0x800000
} else {
m.En1Month4Day5Week3Hour5Min6 &= 0x7fffff
}
}
func (m *Timer) SetMonth(mon time.Month) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(mon) << 19) & 0x780000) | (m.En1Month4Day5Week3Hour5Min6 & 0x87ffff)
}
func (m *Timer) SetDay(d int) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(d) << 14) & 0x07c000) | (m.En1Month4Day5Week3Hour5Min6 & 0xf83fff)
}
func (m *Timer) SetWeek(w time.Weekday) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(w) << 11) & 0x003800) | (m.En1Month4Day5Week3Hour5Min6 & 0xffc7ff)
}
func (m *Timer) SetHour(h int) {
m.En1Month4Day5Week3Hour5Min6 = ((int32(h) << 6) & 0x0007c0) | (m.En1Month4Day5Week3Hour5Min6 & 0xfff83f)
}
func (m *Timer) SetMinute(min int) {
m.En1Month4Day5Week3Hour5Min6 = (int32(min) & 0x00003f) | (m.En1Month4Day5Week3Hour5Min6 & 0xffffc0)
}

View File

@@ -0,0 +1,16 @@
package timer
import (
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
func (ts *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))
} else {
ctx.SendChain(atall, message.Text(ts.Alert), message.Image(ts.Url).Add("cache", "0"))
}
}

View File

@@ -0,0 +1,153 @@
package timer
import (
"fmt"
"strconv"
"strings"
"time"
"unicode"
"github.com/sirupsen/logrus"
)
// GetTimerInfo 获得标准化定时字符串
func (ts *Timer) GetTimerInfo(grp int64) string {
if ts.Cron != "" {
return fmt.Sprintf("[%d]%s", grp, ts.Cron)
}
return fmt.Sprintf("[%d]%d月%d日%d周%d:%d", grp, ts.Month(), ts.Day(), ts.Week(), ts.Hour(), ts.Minute())
}
// GetFilledCronTimer 获得以cron填充好的ts
func GetFilledCronTimer(croncmd string, alert string, img string, botqq int64) *Timer {
var ts Timer
ts.Alert = alert
ts.Cron = croncmd
ts.Url = img
ts.Selfid = botqq
return &ts
}
// GetFilledTimer 获得填充好的ts
func GetFilledTimer(dateStrs []string, botqq int64, matchDateOnly bool) *Timer {
monthStr := []rune(dateStrs[1])
dayWeekStr := []rune(dateStrs[2])
hourStr := []rune(dateStrs[3])
minuteStr := []rune(dateStrs[4])
var ts Timer
mon := time.Month(chineseNum2Int(monthStr))
if (mon != -1 && mon <= 0) || mon > 12 { // 月份非法
ts.Alert = "月份非法!"
return &ts
}
ts.SetMonth(mon)
lenOfDW := len(dayWeekStr)
if lenOfDW == 4 { // 包括末尾的"日"
dayWeekStr = []rune{dayWeekStr[0], dayWeekStr[2]} // 去除中间的十
d := chineseNum2Int(dayWeekStr)
if (d != -1 && d <= 0) || d > 31 { // 日期非法
ts.Alert = "日期非法1"
return &ts
}
ts.SetDay(d)
} else if dayWeekStr[lenOfDW-1] == rune('日') { // xx日
dayWeekStr = dayWeekStr[:lenOfDW-1]
d := chineseNum2Int(dayWeekStr)
if (d != -1 && d <= 0) || d > 31 { // 日期非法
ts.Alert = "日期非法2"
return &ts
}
ts.SetDay(d)
} else if dayWeekStr[0] == rune('每') { // 每周
ts.SetWeek(-1)
} else { // 周x
w := chineseNum2Int(dayWeekStr[1:])
if w == 7 { // 周天是0
w = 0
}
if w < 0 || w > 6 { // 星期非法
ts.Alert = "星期非法!"
return &ts
}
ts.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
}
ts.SetHour(h)
if len(minuteStr) == 3 {
minuteStr = []rune{minuteStr[0], minuteStr[2]} // 去除中间的十
}
min := chineseNum2Int(minuteStr)
if min < -1 || min > 59 { // 分钟非法
ts.Alert = "分钟非法!"
return &ts
}
ts.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"
logrus.Println("[群管]url非法")
return &ts
}
}
ts.Alert = dateStrs[6]
ts.SetEn(true)
}
ts.Selfid = botqq
return &ts
}
// chineseNum2Int 汉字数字转int仅支持-1099最多两位数其中"每"解释为-1"每二"为-2以此类推
func chineseNum2Int(rs []rune) int {
r := -1
l := len(rs)
mai := rune('每')
if unicode.IsDigit(rs[0]) { // 默认可能存在的第二位也为int
r, _ = strconv.Atoi(string(rs))
} else {
if rs[0] == mai {
if l == 2 {
r = -chineseChar2Int(rs[1])
}
} else if l == 1 {
r = chineseChar2Int(rs[0])
} else {
ten := chineseChar2Int(rs[0])
if ten != 10 {
ten *= 10
}
ge := chineseChar2Int(rs[1])
if ge == 10 {
ge = 0
}
r = ten + ge
}
}
return r
}
// chineseChar2Int 处理单个字符的映射0~10
func chineseChar2Int(c rune) int {
if c == rune('日') || c == rune('天') { // 周日/周天
return 7
} else {
match := []rune("零一二三四五六七八九十")
for i, m := range match {
if c == m {
return i
}
}
return 0
}
}

View File

@@ -0,0 +1,164 @@
package timer
import (
"time"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
)
func firstWeek(date *time.Time, week time.Weekday) (d time.Time) {
d = date.AddDate(0, 0, 1-date.Day())
for d.Weekday() != week {
d = d.AddDate(0, 0, 1)
}
return
}
func (ts *Timer) nextWakeTime() (date time.Time) {
date = time.Now()
m := ts.Month()
d := ts.Day()
h := ts.Hour()
mn := ts.Minute()
w := ts.Week()
var unit time.Duration
logrus.Debugln("[timer] unit init:", unit)
if mn >= 0 {
switch {
case h < 0:
if unit <= time.Second {
unit = time.Hour
}
case d < 0 || w < 0:
if unit <= time.Second {
unit = time.Hour * 24
}
case d == 0 && w >= 0:
delta := time.Hour * 24 * time.Duration(int(w)-int(date.Weekday()))
if delta < 0 {
delta = time.Hour * 24 * 7
}
unit += delta
case m < 0:
unit = -1
}
} else {
unit = time.Minute
}
logrus.Debugln("[timer] unit:", unit)
stable := 0
if mn < 0 {
mn = date.Minute()
}
if h < 0 {
h = date.Hour()
} else {
stable |= 0x8
}
if d < 0 {
d = date.Day()
} else if d > 0 {
stable |= 0x4
} else {
d = date.Day()
if w >= 0 {
stable |= 0x2
}
}
if m < 0 {
m = date.Month()
} else {
stable |= 0x1
}
switch stable {
case 0b0101:
if ts.Day() != time.Now().Day() || ts.Month() != time.Now().Month() {
h = 0
}
case 0b1001:
if ts.Month() != time.Now().Month() {
d = 0
}
case 0b0001:
if ts.Month() != time.Now().Month() {
d = 0
h = 0
}
}
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())
logrus.Debugln("[timer] date original:", date)
if unit > 0 {
date = date.Add(unit)
}
logrus.Debugln("[timer] date after add:", date)
if time.Until(date) <= 0 {
if ts.Month() < 0 {
if ts.Day() > 0 || (ts.Day() == 0 && ts.Week() >= 0) {
date = date.AddDate(0, 1, 0)
} else if ts.Day() < 0 || ts.Week() < 0 {
if ts.Hour() > 0 {
date = date.AddDate(0, 0, 1)
} else if ts.Minute() > 0 {
date = date.Add(time.Hour)
}
}
} else {
date = date.AddDate(1, 0, 0)
}
}
logrus.Debugln("[timer] date after fix:", date)
if stable&0x8 != 0 && date.Hour() != int(h) {
switch {
case stable&0x4 == 0:
date = date.AddDate(0, 0, 1).Add(-time.Hour)
case stable&0x2 == 0:
date = date.AddDate(0, 0, 7).Add(-time.Hour)
case stable*0x1 == 0:
date = date.AddDate(0, 1, 0).Add(-time.Hour)
default:
date = date.AddDate(1, 0, 0).Add(-time.Hour)
}
}
logrus.Debugln("[timer] date after s8:", date)
if stable&0x4 != 0 && date.Day() != int(d) {
switch {
case stable*0x1 == 0:
date = date.AddDate(0, 1, -1)
default:
date = date.AddDate(1, 0, -1)
}
}
logrus.Debugln("[timer] date after s4:", date)
if stable&0x2 != 0 && date.Weekday() != w {
switch {
case stable*0x1 == 0:
date = date.AddDate(0, 1, 0)
default:
date = date.AddDate(1, 0, 0)
}
date = firstWeek(&date, time.Weekday(w))
}
logrus.Debugln("[timer] date after s2:", date)
if time.Until(date) <= 0 {
date = time.Now().Add(time.Minute)
}
return date
}
func (ts *Timer) judgeHM(grp int64) {
if ts.Hour() < 0 || ts.Hour() == time.Now().Hour() {
if ts.Minute() < 0 || ts.Minute() == time.Now().Minute() {
if ts.Selfid != 0 {
ts.sendmsg(grp, zero.GetBot(ts.Selfid))
} else {
zero.RangeBot(func(id int64, ctx *zero.Ctx) (_ bool) {
ts.sendmsg(grp, ctx)
return
})
}
}
}
}

View File

@@ -0,0 +1,209 @@
// Package timer 群管定时器
package timer
import (
"io"
"os"
"strconv"
"strings"
"sync"
"time"
"github.com/fumiama/cron"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
type Clock struct {
// 记录每个定时器以便取消
timersmap TimersMap
// 定时器map
timers *(map[string]*Timer)
timersmu sync.RWMutex
// 定时器存储位置
pbfile *string
// cron 定时器
cron *cron.Cron
// entries key <-> cron
entries map[string]cron.EntryID
entmu sync.Mutex
}
var (
// @全体成员
atall = message.MessageSegment{
Type: "at",
Data: map[string]string{
"qq": "all",
},
}
)
func NewClock(pbfile string) (c Clock) {
c.loadTimers(pbfile)
c.timers = &c.timersmap.Timers
c.pbfile = &pbfile
c.cron = cron.New()
c.entries = make(map[string]cron.EntryID)
c.cron.Start()
return
}
// RegisterTimer 注册计时器
func (c *Clock) RegisterTimer(ts *Timer, grp int64, save bool) bool {
key := ts.GetTimerInfo(grp)
t, ok := c.GetTimer(key)
if t != ts && ok { // 避免重复注册定时器
t.SetEn(false)
}
c.timersmu.Lock()
(*c.timers)[key] = ts
c.timersmu.Unlock()
logrus.Println("[群管]注册计时器", key)
if ts.Cron != "" {
var ctx *zero.Ctx
if ts.Selfid != 0 {
ctx = zero.GetBot(ts.Selfid)
} else {
zero.RangeBot(func(id int64, c *zero.Ctx) bool {
ctx = c
ts.Selfid = id
return false
})
}
eid, err := c.cron.AddFunc(ts.Cron, func() { ts.sendmsg(grp, ctx) })
if err == nil {
c.entmu.Lock()
c.entries[key] = eid
c.entmu.Unlock()
if save {
c.SaveTimers()
}
return true
}
ts.Alert = err.Error()
} else {
if save {
c.SaveTimers()
}
for ts.En() {
nextdate := ts.nextWakeTime()
sleepsec := time.Until(nextdate)
logrus.Printf("[群管]计时器%s将睡眠%ds", key, sleepsec/time.Second)
time.Sleep(sleepsec)
if ts.En() {
if ts.Month() < 0 || ts.Month() == time.Now().Month() {
if ts.Day() < 0 || ts.Day() == time.Now().Day() {
ts.judgeHM(grp)
} else if ts.Day() == 0 {
if ts.Week() < 0 || ts.Week() == time.Now().Weekday() {
ts.judgeHM(grp)
}
}
}
}
}
}
return false
}
// CancelTimer 取消计时器
func (c *Clock) CancelTimer(key string) bool {
t, ok := (*c.timers)[key]
if ok {
if t.Cron != "" {
c.entmu.Lock()
e := c.entries[key]
c.cron.Remove(e)
delete(c.entries, key)
c.entmu.Unlock()
} else {
t.SetEn(false)
}
c.timersmu.Lock()
delete(*c.timers, key) // 避免重复取消
c.timersmu.Unlock()
_ = c.SaveTimers()
}
return ok
}
// SaveTimers 保存当前计时器
func (c *Clock) SaveTimers() error {
c.timersmu.RLock()
data, err := c.timersmap.Marshal()
c.timersmu.RUnlock()
if err == nil {
c.timersmu.Lock()
defer c.timersmu.Unlock()
f, err1 := os.OpenFile(*c.pbfile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 != nil {
return err1
} else {
_, err2 := f.Write(data)
f.Close()
return err2
}
}
return err
}
// ListTimers 列出本群所有计时器
func (c *Clock) ListTimers(grpID uint64) []string {
// 数组默认长度为map长度,后面append时,不需要重新申请内存和拷贝,效率很高
if c.timers != nil {
g := strconv.FormatUint(grpID, 10)
c.timersmu.RLock()
keys := make([]string, 0, len(*c.timers))
for k := range *c.timers {
if strings.Contains(k, g) {
start := strings.Index(k, "]")
msg := strings.ReplaceAll(k[start+1:]+"\n", "-1", "每")
msg = strings.ReplaceAll(msg, "月0日0周", "月周天")
msg = strings.ReplaceAll(msg, "月0日", "月")
msg = strings.ReplaceAll(msg, "日0周", "日")
keys = append(keys, msg)
}
}
c.timersmu.RUnlock()
return keys
} else {
return nil
}
}
func (c *Clock) GetTimer(key string) (t *Timer, ok bool) {
c.timersmu.RLock()
t, ok = (*c.timers)[key]
c.timersmu.RUnlock()
return
}
func (c *Clock) loadTimers(pbfile string) {
if file.IsExist(pbfile) {
f, err := os.Open(pbfile)
if err == nil {
data, err := io.ReadAll(f)
if err == nil {
if len(data) > 0 {
err = c.timersmap.Unmarshal(data)
if err == nil {
for str, t := range c.timersmap.Timers {
grp, err := strconv.ParseInt(str[1:strings.Index(str, "]")], 10, 64)
if err == nil {
go c.RegisterTimer(t, grp, false)
}
}
return
}
logrus.Errorln("[群管]读取定时器文件失败将在下一次保存时覆盖原文件。err:", err)
logrus.Errorln("[群管]如不希望被覆盖请运行源码plugin_manager/timers/migrate下的程序将timers.pb刷新为新版")
}
}
}
}
c.timersmap.Timers = make(map[string]*Timer)
}

View File

@@ -0,0 +1,812 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: timer.proto
package timer
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Timer struct {
Alert string `protobuf:"bytes,1,opt,name=alert,proto3" json:"alert,omitempty"`
Cron string `protobuf:"bytes,2,opt,name=cron,proto3" json:"cron,omitempty"`
En1Month4Day5Week3Hour5Min6 int32 `protobuf:"varint,4,opt,name=en1month4day5week3hour5min6,proto3" json:"en1month4day5week3hour5min6,omitempty"`
Selfid int64 `protobuf:"varint,8,opt,name=selfid,proto3" json:"selfid,omitempty"`
Url string `protobuf:"bytes,16,opt,name=url,proto3" json:"url,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Timer) Reset() { *m = Timer{} }
func (m *Timer) String() string { return proto.CompactTextString(m) }
func (*Timer) ProtoMessage() {}
func (*Timer) Descriptor() ([]byte, []int) {
return fileDescriptor_ad0307ee16b652d2, []int{0}
}
func (m *Timer) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Timer) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Timer.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Timer) XXX_Merge(src proto.Message) {
xxx_messageInfo_Timer.Merge(m, src)
}
func (m *Timer) XXX_Size() int {
return m.Size()
}
func (m *Timer) XXX_DiscardUnknown() {
xxx_messageInfo_Timer.DiscardUnknown(m)
}
var xxx_messageInfo_Timer proto.InternalMessageInfo
func (m *Timer) GetAlert() string {
if m != nil {
return m.Alert
}
return ""
}
func (m *Timer) GetCron() string {
if m != nil {
return m.Cron
}
return ""
}
func (m *Timer) GetEn1Month4Day5Week3Hour5Min6() int32 {
if m != nil {
return m.En1Month4Day5Week3Hour5Min6
}
return 0
}
func (m *Timer) GetSelfid() int64 {
if m != nil {
return m.Selfid
}
return 0
}
func (m *Timer) GetUrl() string {
if m != nil {
return m.Url
}
return ""
}
type TimersMap struct {
Timers map[string]*Timer `protobuf:"bytes,1,rep,name=timers,proto3" json:"timers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *TimersMap) Reset() { *m = TimersMap{} }
func (m *TimersMap) String() string { return proto.CompactTextString(m) }
func (*TimersMap) ProtoMessage() {}
func (*TimersMap) Descriptor() ([]byte, []int) {
return fileDescriptor_ad0307ee16b652d2, []int{1}
}
func (m *TimersMap) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *TimersMap) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_TimersMap.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *TimersMap) XXX_Merge(src proto.Message) {
xxx_messageInfo_TimersMap.Merge(m, src)
}
func (m *TimersMap) XXX_Size() int {
return m.Size()
}
func (m *TimersMap) XXX_DiscardUnknown() {
xxx_messageInfo_TimersMap.DiscardUnknown(m)
}
var xxx_messageInfo_TimersMap proto.InternalMessageInfo
func (m *TimersMap) GetTimers() map[string]*Timer {
if m != nil {
return m.Timers
}
return nil
}
func init() {
proto.RegisterType((*Timer)(nil), "timer.Timer")
proto.RegisterType((*TimersMap)(nil), "timer.TimersMap")
proto.RegisterMapType((map[string]*Timer)(nil), "timer.TimersMap.TimersEntry")
}
func init() { proto.RegisterFile("timer.proto", fileDescriptor_ad0307ee16b652d2) }
var fileDescriptor_ad0307ee16b652d2 = []byte{
// 256 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2e, 0xc9, 0xcc, 0x4d,
0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x05, 0x73, 0x94, 0xe6, 0x32, 0x72, 0xb1,
0x86, 0x80, 0x58, 0x42, 0x22, 0x5c, 0xac, 0x89, 0x39, 0xa9, 0x45, 0x25, 0x12, 0x8c, 0x0a, 0x8c,
0x1a, 0x9c, 0x41, 0x10, 0x8e, 0x90, 0x10, 0x17, 0x4b, 0x72, 0x51, 0x7e, 0x9e, 0x04, 0x13, 0x58,
0x10, 0xcc, 0x16, 0x72, 0xe0, 0x92, 0x4e, 0xcd, 0x33, 0xcc, 0xcd, 0xcf, 0x2b, 0xc9, 0x30, 0x49,
0x49, 0xac, 0x34, 0x2d, 0x4f, 0x4d, 0xcd, 0x36, 0xce, 0xc8, 0x2f, 0x2d, 0x32, 0xcd, 0xcd, 0xcc,
0x33, 0x93, 0x60, 0x51, 0x60, 0xd4, 0x60, 0x0d, 0xc2, 0xa7, 0x44, 0x48, 0x8c, 0x8b, 0xad, 0x38,
0x35, 0x27, 0x2d, 0x33, 0x45, 0x82, 0x43, 0x81, 0x51, 0x83, 0x39, 0x08, 0xca, 0x13, 0x12, 0xe0,
0x62, 0x2e, 0x2d, 0xca, 0x91, 0x10, 0x00, 0x5b, 0x06, 0x62, 0x2a, 0x75, 0x31, 0x72, 0x71, 0x82,
0xdd, 0x57, 0xec, 0x9b, 0x58, 0x20, 0x64, 0xc2, 0xc5, 0x06, 0x76, 0x76, 0xb1, 0x04, 0xa3, 0x02,
0xb3, 0x06, 0xb7, 0x91, 0x8c, 0x1e, 0xc4, 0x4b, 0x70, 0x15, 0x50, 0x96, 0x6b, 0x5e, 0x49, 0x51,
0x65, 0x10, 0x54, 0xad, 0x94, 0x3b, 0x17, 0x37, 0x92, 0x30, 0xc8, 0x92, 0xec, 0xd4, 0x4a, 0xa8,
0x37, 0x41, 0x4c, 0x21, 0x25, 0x2e, 0xd6, 0xb2, 0xc4, 0x9c, 0xd2, 0x54, 0xb0, 0x2f, 0xb9, 0x8d,
0x78, 0x90, 0x4d, 0x0d, 0x82, 0x48, 0x59, 0x31, 0x59, 0x30, 0x3a, 0x09, 0x9c, 0x78, 0x24, 0xc7,
0x78, 0xe1, 0x91, 0x1c, 0xe3, 0x83, 0x47, 0x72, 0x8c, 0x33, 0x1e, 0xcb, 0x31, 0x24, 0xb1, 0x81,
0x03, 0xd3, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0xf5, 0xc1, 0x9e, 0x44, 0x5b, 0x01, 0x00, 0x00,
}
func (m *Timer) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Timer) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Timer) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Url) > 0 {
i -= len(m.Url)
copy(dAtA[i:], m.Url)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Url)))
i--
dAtA[i] = 0x1
i--
dAtA[i] = 0x82
}
if m.Selfid != 0 {
i = encodeVarintTimer(dAtA, i, uint64(m.Selfid))
i--
dAtA[i] = 0x40
}
if m.En1Month4Day5Week3Hour5Min6 != 0 {
i = encodeVarintTimer(dAtA, i, uint64(m.En1Month4Day5Week3Hour5Min6))
i--
dAtA[i] = 0x20
}
if len(m.Cron) > 0 {
i -= len(m.Cron)
copy(dAtA[i:], m.Cron)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Cron)))
i--
dAtA[i] = 0x12
}
if len(m.Alert) > 0 {
i -= len(m.Alert)
copy(dAtA[i:], m.Alert)
i = encodeVarintTimer(dAtA, i, uint64(len(m.Alert)))
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *TimersMap) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *TimersMap) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *TimersMap) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Timers) > 0 {
for k := range m.Timers {
v := m.Timers[k]
baseI := i
if v != nil {
{
size, err := v.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintTimer(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
i -= len(k)
copy(dAtA[i:], k)
i = encodeVarintTimer(dAtA, i, uint64(len(k)))
i--
dAtA[i] = 0xa
i = encodeVarintTimer(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintTimer(dAtA []byte, offset int, v uint64) int {
offset -= sovTimer(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Timer) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
l = len(m.Alert)
if l > 0 {
n += 1 + l + sovTimer(uint64(l))
}
l = len(m.Cron)
if l > 0 {
n += 1 + l + sovTimer(uint64(l))
}
if m.En1Month4Day5Week3Hour5Min6 != 0 {
n += 1 + sovTimer(uint64(m.En1Month4Day5Week3Hour5Min6))
}
if m.Selfid != 0 {
n += 1 + sovTimer(uint64(m.Selfid))
}
l = len(m.Url)
if l > 0 {
n += 2 + l + sovTimer(uint64(l))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *TimersMap) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Timers) > 0 {
for k, v := range m.Timers {
_ = k
_ = v
l = 0
if v != nil {
l = v.Size()
l += 1 + sovTimer(uint64(l))
}
mapEntrySize := 1 + len(k) + sovTimer(uint64(len(k))) + l
n += mapEntrySize + 1 + sovTimer(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovTimer(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozTimer(x uint64) (n int) {
return sovTimer(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Timer) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Timer: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Timer: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Alert", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Alert = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Cron", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Cron = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
case 4:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field En1Month4Day5Week3Hour5Min6", wireType)
}
m.En1Month4Day5Week3Hour5Min6 = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.En1Month4Day5Week3Hour5Min6 |= int32(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 8:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Selfid", wireType)
}
m.Selfid = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Selfid |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
case 16:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Url", wireType)
}
var stringLen uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLen |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLen := int(stringLen)
if intStringLen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + intStringLen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Url = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *TimersMap) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: TimersMap: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: TimersMap: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Timers", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthTimer
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthTimer
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Timers == nil {
m.Timers = make(map[string]*Timer)
}
var mapkey string
var mapvalue *Timer
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
var stringLenmapkey uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
stringLenmapkey |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
intStringLenmapkey := int(stringLenmapkey)
if intStringLenmapkey < 0 {
return ErrInvalidLengthTimer
}
postStringIndexmapkey := iNdEx + intStringLenmapkey
if postStringIndexmapkey < 0 {
return ErrInvalidLengthTimer
}
if postStringIndexmapkey > l {
return io.ErrUnexpectedEOF
}
mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
iNdEx = postStringIndexmapkey
} else if fieldNum == 2 {
var mapmsglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTimer
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapmsglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if mapmsglen < 0 {
return ErrInvalidLengthTimer
}
postmsgIndex := iNdEx + mapmsglen
if postmsgIndex < 0 {
return ErrInvalidLengthTimer
}
if postmsgIndex > l {
return io.ErrUnexpectedEOF
}
mapvalue = &Timer{}
if err := mapvalue.Unmarshal(dAtA[iNdEx:postmsgIndex]); err != nil {
return err
}
iNdEx = postmsgIndex
} else {
iNdEx = entryPreIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Timers[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipTimer(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthTimer
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipTimer(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowTimer
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthTimer
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupTimer
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthTimer
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthTimer = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowTimer = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupTimer = fmt.Errorf("proto: unexpected end of group")
)

View File

@@ -0,0 +1,14 @@
syntax = "proto3";
package timer;
message Timer {
string alert = 1;
string cron = 2;
int32 en1month4day5week3hour5min6 = 4;
int64 selfid = 8;
string url = 16;
}
message TimersMap {
map<string, Timer> timers = 1;
}

View File

@@ -0,0 +1,24 @@
package timer
import (
"testing"
"time"
"github.com/sirupsen/logrus"
)
func TestNextWakeTime(t *testing.T) {
logrus.SetLevel(logrus.DebugLevel)
ts := &Timer{}
ts.SetMonth(-1)
ts.SetWeek(6)
ts.SetHour(16)
ts.SetMinute(30)
t1 := time.Until(ts.nextWakeTime())
if t1 < 0 {
t.Log(t1)
t.Fail()
}
t.Log(t1)
t.Fail()
}

View File

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

View File

@@ -5,10 +5,12 @@ import (
"io"
"net/http"
"os"
"time"
wr "github.com/mroth/weightedrand"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
const (
@@ -28,7 +30,7 @@ var (
func init() {
go func() {
time.Sleep(time.Second)
process.SleepAbout1sTo2s()
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
@@ -53,7 +55,7 @@ func init() {
// load 加载rate数据
func load(area *rate) error {
if _, err := os.Stat(jsonfile); err == nil || os.IsExist(err) {
if file.IsExist(jsonfile) {
f, err := os.Open(jsonfile)
if err == nil {
defer f.Close()

View File

@@ -3,20 +3,31 @@ package saucenao
import (
"fmt"
"os"
"strconv"
"strings"
"github.com/FloatTech/AnimeAPI/ascii2d"
"github.com/FloatTech/AnimeAPI/picture"
"github.com/FloatTech/AnimeAPI/pixiv"
"github.com/FloatTech/AnimeAPI/saucenao"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
var (
datapath = file.BOT_PATH + "/data/saucenao/"
)
func init() { // 插件主体
_ = os.RemoveAll(datapath)
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
}
engine := control.Register("saucenao", &control.Options{
DisableOnDefault: false,
Help: "搜图\n" +
@@ -35,21 +46,39 @@ func init() { // 插件主体
return
}
if illust.Pid > 0 {
// 改用 i.pixiv.cat 镜像站
link := illust.ImageUrls
link = strings.ReplaceAll(link, "i.pximg.net", "i.pixiv.cat")
// 发送搜索结果
ctx.SendChain(
message.Image(link),
message.Text(
"\n",
"标题:", illust.Title, "\n",
"插画ID", illust.Pid, "\n",
"画师:", illust.UserName, "\n",
"画师ID", illust.UserId, "\n",
"直链:", "https://pixivel.moe/detail?id=", illust.Pid,
),
name := strconv.FormatInt(illust.Pid, 10)
filepath := datapath + name
switch {
case file.IsExist(filepath + ".jpg"):
filepath = "file:///" + filepath + ".jpg"
case file.IsExist(filepath + ".png"):
filepath = "file:///" + filepath + ".png"
case file.IsExist(filepath + ".gif"):
filepath = "file:///" + filepath + ".gif"
default:
filepath = ""
}
if filepath == "" {
logrus.Debug("[sausenao]开始下载", name)
filepath, err = pixiv.Download(illust.ImageUrls, datapath, name)
if err == nil {
filepath = "file:///" + filepath
}
}
txt := message.Text(
"标题:", illust.Title, "\n",
"插画ID", illust.Pid, "\n",
"画师:", illust.UserName, "\n",
"画师ID", illust.UserId, "\n",
"直链:", "https://pixivel.moe/detail?id=", illust.Pid,
)
if filepath != "" {
// 发送搜索结果
ctx.SendChain(message.Image(filepath), message.Text("\n"), txt)
} else {
// 图片下载失败,仅发送文字结果
ctx.SendChain(txt)
}
} else {
ctx.SendChain(message.Text("图片不存在!"))
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
fileutil "github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
@@ -57,23 +58,36 @@ func newPools() *imgpool {
}
// 如果数据库不存在则下载
if _, err := os.Stat(cache.DB.DBPath); err != nil || os.IsNotExist(err) {
f, err := os.Create(cache.DB.DBPath)
if err == nil {
down := func() (err error) {
// 下载
resp, err := http.Get(dburl)
if err == nil {
defer resp.Body.Close()
if resp.ContentLength > 0 {
logrus.Printf("[Setu]从镜像下载数据库%d字节...", resp.ContentLength)
data, err := io.ReadAll(resp.Body)
if err == nil && len(data) > 0 {
_, err = f.Write(data)
if err != nil {
logrus.Errorf("[Setu]写入数据库失败: %v", err)
}
}
}
if err != nil {
return
}
f.Close()
defer resp.Body.Close()
if resp.ContentLength > 0 {
return
}
logrus.Printf("[Setu]从镜像下载数据库%d字节...", resp.ContentLength)
// 生成文件
f, err := os.Create(cache.DB.DBPath)
if err != nil {
return
}
defer f.Close()
// 读取数据
data, err := io.ReadAll(resp.Body)
if err != nil || len(data) > 0 {
return
}
// 写入数据
if _, err = f.Write(data); err != nil {
return
}
return nil
}
if err := down(); err != nil {
logrus.Printf("[Setu]下载数据库失败%v", err)
}
}
for i := range cache.List {
@@ -249,8 +263,7 @@ func (p *imgpool) pop(imgtype string) (illust *pixiv.Illust) {
func file(i *pixiv.Illust) string {
filename := fmt.Sprint(i.Pid)
pwd, _ := os.Getwd()
filepath := pwd + `/` + pool.Path + filename
filepath := fileutil.BOT_PATH + `/` + pool.Path + filename
if _, err := os.Stat(filepath + ".jpg"); err == nil || os.IsExist(err) {
return `file:///` + filepath + ".jpg"
}

64
plugin_translation/tl.go Normal file
View File

@@ -0,0 +1,64 @@
package translation
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/process"
)
var (
prio = 100
bucket = rate.NewManager(time.Minute, 20) // 接口回复
)
func tl(d string) ([]byte, error) {
url := "https://api.cloolc.club/fanyi?data=" + d
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
}
data, err := ioutil.ReadAll(resp.Body)
_ = resp.Body.Close()
if err != nil {
return nil, err
}
if code := resp.StatusCode; code != 200 {
// 如果返回不是200则立刻抛出错误
errmsg := fmt.Sprintf("code %d", code)
return nil, errors.New(errmsg)
}
return data, err
}
func init() {
control.Register("translation", &control.Options{
DisableOnDefault: false,
Help: "翻译\n" +
">TL 你好",
}).OnRegex(`^>TL\s(-.{1,10}? )?(.*)$`).SetBlock(true).SetPriority(prio).
Handle(func(ctx *zero.Ctx) {
if !bucket.Load(ctx.Event.UserID).Acquire() {
// 频繁触发,不回复
return
}
msg := []string{ctx.State["regex_matched"].([]string)[2]}
rely, err := tl(msg[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
}
info := gjson.ParseBytes(rely)
repo := info.Get("data.0")
process.SleepAbout1sTo2s()
ctx.SendChain(message.Text(repo.Get("value.0")))
})
}

11
utils/file/dir_nowin.go Normal file
View File

@@ -0,0 +1,11 @@
//go:build !windows
// +build !windows
package file
import "os"
func Pwd() (path string) {
path, _ = os.Getwd()
return
}

14
utils/file/dir_win.go Normal file
View File

@@ -0,0 +1,14 @@
//go:build windows
// +build windows
package file
import (
"os"
"strings"
)
func Pwd() string {
path, _ := os.Getwd()
return strings.ReplaceAll(path, "\\", "/")
}

View File

@@ -1,5 +1,5 @@
// Package dl 下载实用工具
package dl
// Package file 文件实用工具
package file
import (
"io"

17
utils/file/f.go Normal file
View File

@@ -0,0 +1,17 @@
package file
import "os"
var BOT_PATH = Pwd()
// IsExist 文件/路径存在
func IsExist(path string) bool {
_, err := os.Stat(path)
return err == nil || os.IsExist(err)
}
// IsExist 文件/路径不存在
func IsNotExist(path string) bool {
_, err := os.Stat(path)
return err != nil && os.IsNotExist(err)
}

10
utils/process/sleep.go Normal file
View File

@@ -0,0 +1,10 @@
package process
import (
"math/rand"
"time"
)
func SleepAbout1sTo2s() {
time.Sleep(time.Second + time.Millisecond*time.Duration(rand.Intn(1000)))
}

View File

@@ -48,17 +48,15 @@ func (db *Sqlite) Create(table string, objptr interface{}) (err error) {
cmd = append(cmd, "NULL);")
}
}
if _, err := db.DB.Exec(strings.Join(cmd, " ")); err != nil {
return err
}
return nil
_, err = db.DB.Exec(strings.Join(cmd, " ") + ";")
return
}
// Insert 插入数据集
// 默认结构体的第一个元素为主键
// 返回错误
func (db *Sqlite) Insert(table string, objptr interface{}) (err error) {
rows, err := db.DB.Query("SELECT * FROM " + table)
func (db *Sqlite) Insert(table string, objptr interface{}) error {
rows, err := db.DB.Query("SELECT * FROM " + table + ";")
if err != nil {
return err
}
@@ -102,7 +100,7 @@ func (db *Sqlite) Insert(table string, objptr interface{}) (err error) {
cmd = append(cmd, ")")
}
}
stmt, err := db.DB.Prepare(strings.Join(cmd, " "))
stmt, err := db.DB.Prepare(strings.Join(cmd, " ") + ";")
if err != nil {
return err
}
@@ -110,19 +108,19 @@ func (db *Sqlite) Insert(table string, objptr interface{}) (err error) {
if err != nil {
return err
}
return nil
return stmt.Close()
}
// Find 查询数据库
// condition 可为"WHERE id = 0"
// 默认字段与结构体元素顺序一致
// 返回错误
func (db *Sqlite) Find(table string, objptr interface{}, condition string) (err error) {
func (db *Sqlite) Find(table string, objptr interface{}, condition string) error {
var cmd = []string{}
cmd = append(cmd, "SELECT * FROM ")
cmd = append(cmd, table)
cmd = append(cmd, condition)
rows, err := db.DB.Query(strings.Join(cmd, " "))
rows, err := db.DB.Query(strings.Join(cmd, " ") + ";")
if err != nil {
return err
}
@@ -171,12 +169,12 @@ func (db *Sqlite) ListTables() (s []string, err error) {
// Del 删除数据库
// condition 可为"WHERE id = 0"
// 返回错误
func (db *Sqlite) Del(table string, condition string) (err error) {
func (db *Sqlite) Del(table string, condition string) error {
var cmd = []string{}
cmd = append(cmd, "DELETE FROM")
cmd = append(cmd, table)
cmd = append(cmd, condition)
stmt, err := db.DB.Prepare(strings.Join(cmd, " "))
stmt, err := db.DB.Prepare(strings.Join(cmd, " ") + ";")
if err != nil {
return err
}
@@ -184,7 +182,7 @@ func (db *Sqlite) Del(table string, condition string) (err error) {
if err != nil {
return err
}
return nil
return stmt.Close()
}
// Count 查询数据库行数
@@ -193,17 +191,17 @@ func (db *Sqlite) Count(table string) (num int, err error) {
var cmd = []string{}
cmd = append(cmd, "SELECT * FROM")
cmd = append(cmd, table)
rows, err := db.DB.Query(strings.Join(cmd, " "))
rows, err := db.DB.Query(strings.Join(cmd, " ") + ";")
if err != nil {
return num, err
}
if rows.Err() != nil {
return num, rows.Err()
}
defer rows.Close()
for rows.Next() {
num++
}
rows.Close()
return num, nil
}

25
utils/web/http.go Normal file
View File

@@ -0,0 +1,25 @@
package web
import (
"io"
"net/http"
)
func ReqWith(url string, method string, referer string, ua string) (data []byte, err error) {
client := &http.Client{}
//提交请求
var reqest *http.Request
reqest, err = http.NewRequest(method, url, nil)
if err == nil {
//增加header选项
reqest.Header.Add("Referer", referer)
reqest.Header.Add("User-Agent", ua)
var response *http.Response
response, err = client.Do(reqest)
if err == nil {
data, err = io.ReadAll(response.Body)
response.Body.Close()
}
}
return
}