mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2025-12-19 13:59:39 +08:00
🎨 改进代码结构
This commit is contained in:
parent
c7b86e767e
commit
0b9b507740
4
go.mod
4
go.mod
@ -5,8 +5,8 @@ go 1.15
|
||||
require (
|
||||
github.com/antchfx/htmlquery v1.2.3
|
||||
github.com/mattn/go-sqlite3 v1.14.6
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/sirupsen/logrus v1.8.0
|
||||
github.com/tidwall/gjson v1.6.8
|
||||
github.com/wdvxdr1123/ZeroBot v0.0.0-20210214154537-b88c3977a0c1
|
||||
github.com/wdvxdr1123/ZeroBot v1.0.1
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||
)
|
||||
|
||||
22
go.sum
22
go.sum
@ -9,6 +9,7 @@ github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18h
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
@ -16,10 +17,13 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b h1:6Xjqolv/0DDdUqlpnsTomXQvjvvkz7Ux7TcMALvozEw=
|
||||
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
@ -30,6 +34,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
|
||||
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
@ -43,10 +49,10 @@ github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/wdvxdr1123/ZeroBot v0.0.0-20210212165900-0c6c4d79b40e h1:BaUnQOFcCU4l+uf+mifbPdzrBtYfGeDM9RgIFhMBRLs=
|
||||
github.com/wdvxdr1123/ZeroBot v0.0.0-20210212165900-0c6c4d79b40e/go.mod h1:MC6+vOkILANgHlEvZpDMKLNeOWSde5eRgiGFtNGix/4=
|
||||
github.com/wdvxdr1123/ZeroBot v0.0.0-20210214154537-b88c3977a0c1 h1:HxjJ5hOLS1Qmhnd+X0ZFhEspaVqgNs5FR2jR/UBnI10=
|
||||
github.com/wdvxdr1123/ZeroBot v0.0.0-20210214154537-b88c3977a0c1/go.mod h1:MC6+vOkILANgHlEvZpDMKLNeOWSde5eRgiGFtNGix/4=
|
||||
github.com/tidwall/pretty v1.0.5 h1:RlE8xFRj9RrbHWXXNGa4MymvI1Ovlm70omjXQ1sWgFU=
|
||||
github.com/tidwall/pretty v1.0.5/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/wdvxdr1123/ZeroBot v1.0.1 h1:HVTpoOEk41IuW+qm9TiGhmTKNaDddP6VcQa31Xse1tI=
|
||||
github.com/wdvxdr1123/ZeroBot v1.0.1/go.mod h1:BZQGqjw0PX8Aojj3QnVHTXIH9YOEc8ZvLLUosM39Gho=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd h1:QPwSajcTUrFriMF1nJ3XzgoqakqQEsnZf9LdXdi2nkI=
|
||||
@ -56,14 +62,14 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43 h1:SgQ6LNaYJU0JIuEHv9+s6EbhSCwYeAf5Yvj6lpYlqAE=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
18
main.go
18
main.go
@ -6,10 +6,11 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
easy "github.com/t-tomalak/logrus-easy-formatter"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/driver"
|
||||
|
||||
_ "bot/manager"
|
||||
_ "bot/music"
|
||||
_ "bot/setutime"
|
||||
setutime "bot/setutime"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -18,6 +19,9 @@ func init() {
|
||||
LogFormat: "[zero][%time%][%lvl%]: %msg% \n",
|
||||
})
|
||||
log.SetLevel(log.DebugLevel)
|
||||
|
||||
setutime.CACHEGROUP = 868047498 // 涩图缓冲群,必须修改
|
||||
setutime.PoolList = []string{"涩图", "二次元", "风景", "车万"} // 涩图类型,可以不修改
|
||||
}
|
||||
|
||||
func main() {
|
||||
@ -28,13 +32,13 @@ func main() {
|
||||
* Project: https://github.com/Yiwen-Chan/ZeroBot-Plugin
|
||||
========================================================
|
||||
`)
|
||||
zero.Run(zero.Option{
|
||||
Host: "127.0.0.1",
|
||||
Port: "6700",
|
||||
AccessToken: "",
|
||||
NickName: []string{"椛椛"},
|
||||
zero.Run(zero.Config{
|
||||
NickName: []string{"bot"},
|
||||
CommandPrefix: "/",
|
||||
SuperUsers: []string{"825111790", "213864964"},
|
||||
SuperUsers: []string{"825111790", "213864964"}, // 必须修改,否则无权限
|
||||
Driver: []zero.Driver{
|
||||
driver.NewWebSocketClient("127.0.0.1", "6700", ""),
|
||||
},
|
||||
})
|
||||
select {}
|
||||
}
|
||||
|
||||
@ -7,26 +7,11 @@ import (
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
func init() {
|
||||
zero.RegisterPlugin(manager{}) // 注册插件
|
||||
}
|
||||
|
||||
type manager struct{} // pixivSearch 搜索P站插图
|
||||
|
||||
func (_ manager) GetPluginInfo() zero.PluginInfo { // 返回插件信息
|
||||
return zero.PluginInfo{
|
||||
Author: "kanri",
|
||||
PluginName: "Manager",
|
||||
Version: "0.0.1",
|
||||
Details: "群管",
|
||||
}
|
||||
}
|
||||
|
||||
func (_ manager) Start() { // 插件主体
|
||||
func init() { // 插件主体
|
||||
// TODO 菜单
|
||||
zero.OnFullMatch("群管系统").SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.Send(event, `====群管====
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.Send(`====群管====
|
||||
- 禁言@QQ 1
|
||||
- 解除禁言 @QQ
|
||||
- 我要自闭 1
|
||||
@ -39,99 +24,90 @@ func (_ manager) Start() { // 插件主体
|
||||
- 申请头衔 XXX
|
||||
- 群聊转发 1234 XXX
|
||||
- 私聊转发 0000 XXX`)
|
||||
return zero.SuccessResponse
|
||||
return
|
||||
})
|
||||
// TODO 升为管理
|
||||
zero.OnRegex(`^升为管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupAdmin(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被升为管理的人的qq
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupAdmin(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被升为管理的人的qq
|
||||
true,
|
||||
)
|
||||
nickname := zero.GetGroupMemberInfo( // 被升为管理的人的昵称
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被升为管理的人的qq
|
||||
nickname := ctx.GetGroupMemberInfo( // 被升为管理的人的昵称
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被升为管理的人的qq
|
||||
false,
|
||||
).Get("nickname").Str
|
||||
zero.Send(
|
||||
event,
|
||||
nickname+" 升为了管理~",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send(nickname + " 升为了管理~")
|
||||
return
|
||||
})
|
||||
// TODO 取消管理
|
||||
zero.OnRegex(`^取消管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupAdmin(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被取消管理的人的qq
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupAdmin(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被取消管理的人的qq
|
||||
false,
|
||||
)
|
||||
nickname := zero.GetGroupMemberInfo( // 被取消管理的人的昵称
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被取消管理的人的qq
|
||||
nickname := ctx.GetGroupMemberInfo( // 被取消管理的人的昵称
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被取消管理的人的qq
|
||||
false,
|
||||
).Get("nickname").Str
|
||||
zero.Send(
|
||||
event,
|
||||
"残念~ "+nickname+" 暂时失去了管理员的资格",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("残念~ " + nickname + " 暂时失去了管理员的资格")
|
||||
return
|
||||
})
|
||||
// TODO 踢出群聊
|
||||
zero.OnRegex(`^踢出群聊.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupKick(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被踢出群聊的人的qq
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupKick(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被踢出群聊的人的qq
|
||||
false,
|
||||
)
|
||||
nickname := zero.GetGroupMemberInfo( // 被踢出群聊的人的昵称
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被踢出群聊的人的qq
|
||||
nickname := ctx.GetGroupMemberInfo( // 被踢出群聊的人的昵称
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被踢出群聊的人的qq
|
||||
false,
|
||||
).Get("nickname").Str
|
||||
zero.Send(
|
||||
event,
|
||||
"残念~ "+nickname+" 被放逐",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("残念~ " + nickname + " 被放逐")
|
||||
return
|
||||
})
|
||||
// TODO 退出群聊
|
||||
zero.OnRegex(`^退出群聊.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupLeave(
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 要退出的群的群号
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupLeave(
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 要退出的群的群号
|
||||
true,
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
return
|
||||
})
|
||||
// TODO 开启全体禁言
|
||||
zero.OnRegex(`^开启全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupWholeBan(
|
||||
event.GroupID,
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupWholeBan(
|
||||
ctx.Event.GroupID,
|
||||
true,
|
||||
)
|
||||
zero.Send(event, "全员自闭开始~")
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("全员自闭开始~")
|
||||
return
|
||||
})
|
||||
// TODO 解除全员禁言
|
||||
zero.OnRegex(`^解除全员禁言$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupWholeBan(
|
||||
event.GroupID,
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupWholeBan(
|
||||
ctx.Event.GroupID,
|
||||
false,
|
||||
)
|
||||
zero.Send(event, "全员自闭结束~")
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("全员自闭结束~")
|
||||
return
|
||||
})
|
||||
// TODO 禁言
|
||||
zero.OnRegex(`^禁言.*?(\d+).*?\s(\d+)(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
duration := utils.Str2Int(state["regex_matched"].([]string)[2])
|
||||
switch state["regex_matched"].([]string)[3] {
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
duration := utils.Str2Int(ctx.State["regex_matched"].([]string)[2])
|
||||
switch ctx.State["regex_matched"].([]string)[3] {
|
||||
case "分钟":
|
||||
//
|
||||
case "小时":
|
||||
@ -144,30 +120,30 @@ func (_ manager) Start() { // 插件主体
|
||||
if duration >= 43200 {
|
||||
duration = 43199 // qq禁言最大时长为一个月
|
||||
}
|
||||
zero.SetGroupBan(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 要禁言的人的qq
|
||||
ctx.SetGroupBan(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 要禁言的人的qq
|
||||
duration*60, // 要禁言的时间(分钟)
|
||||
)
|
||||
zero.Send(event, "小黑屋收留成功~")
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("小黑屋收留成功~")
|
||||
return
|
||||
})
|
||||
// TODO 解除禁言
|
||||
zero.OnRegex(`^解除禁言.*?(\d+)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupBan(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 要解除禁言的人的qq
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupBan(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 要解除禁言的人的qq
|
||||
0,
|
||||
)
|
||||
zero.Send(event, "小黑屋释放成功~")
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("小黑屋释放成功~")
|
||||
return
|
||||
})
|
||||
// TODO 自闭禁言
|
||||
zero.OnRegex(`^我要自闭.*?(\d+)(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
duration := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
switch state["regex_matched"].([]string)[2] {
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
duration := utils.Str2Int(ctx.State["regex_matched"].([]string)[1])
|
||||
switch ctx.State["regex_matched"].([]string)[2] {
|
||||
case "分钟":
|
||||
//
|
||||
case "小时":
|
||||
@ -180,105 +156,90 @@ func (_ manager) Start() { // 插件主体
|
||||
if duration >= 43200 {
|
||||
duration = 43199 // qq禁言最大时长为一个月
|
||||
}
|
||||
zero.SetGroupBan(
|
||||
event.GroupID,
|
||||
event.UserID,
|
||||
ctx.SetGroupBan(
|
||||
ctx.Event.GroupID,
|
||||
ctx.Event.UserID,
|
||||
duration*60, // 要自闭的时间(分钟)
|
||||
)
|
||||
zero.Send(event, "那我就不手下留情了~")
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("那我就不手下留情了~")
|
||||
return
|
||||
})
|
||||
// TODO 修改名片
|
||||
zero.OnRegex(`^修改名片.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupCard(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被修改群名片的人
|
||||
state["regex_matched"].([]string)[2], // 修改成的群名片
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupCard(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被修改群名片的人
|
||||
ctx.State["regex_matched"].([]string)[2], // 修改成的群名片
|
||||
)
|
||||
zero.Send(
|
||||
event,
|
||||
"嗯!已经修改了",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("嗯!已经修改了")
|
||||
return
|
||||
})
|
||||
// TODO 修改头衔
|
||||
zero.OnRegex(`^修改头衔.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupSpecialTitle(
|
||||
event.GroupID,
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 被修改群头衔的人
|
||||
state["regex_matched"].([]string)[2], // 修改成的群头衔
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupSpecialTitle(
|
||||
ctx.Event.GroupID,
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 被修改群头衔的人
|
||||
ctx.State["regex_matched"].([]string)[2], // 修改成的群头衔
|
||||
)
|
||||
zero.Send(
|
||||
event,
|
||||
"嗯!已经修改了",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("嗯!已经修改了")
|
||||
return
|
||||
})
|
||||
// TODO 申请头衔
|
||||
zero.OnRegex(`^申请头衔(.*)`, zero.OnlyGroup).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SetGroupSpecialTitle(
|
||||
event.GroupID,
|
||||
event.UserID, // 被修改群头衔的人
|
||||
state["regex_matched"].([]string)[1], // 修改成的群头衔
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SetGroupSpecialTitle(
|
||||
ctx.Event.GroupID,
|
||||
ctx.Event.UserID, // 被修改群头衔的人
|
||||
ctx.State["regex_matched"].([]string)[1], // 修改成的群头衔
|
||||
)
|
||||
zero.Send(
|
||||
event,
|
||||
"嗯!不错的头衔呢~",
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("嗯!不错的头衔呢~")
|
||||
return
|
||||
})
|
||||
// TODO 群聊转发
|
||||
zero.OnRegex(`^群聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SendGroupMessage(
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 需要发送的群
|
||||
state["regex_matched"].([]string)[1], // 需要发送的信息
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendGroupMessage(
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 需要发送的群
|
||||
ctx.State["regex_matched"].([]string)[1], // 需要发送的信息
|
||||
)
|
||||
zero.Send(
|
||||
event,
|
||||
"📧 --> "+state["regex_matched"].([]string)[1],
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("📧 --> " + ctx.State["regex_matched"].([]string)[1])
|
||||
return
|
||||
})
|
||||
// TODO 私聊转发
|
||||
zero.OnRegex(`^私聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
zero.SendPrivateMessage(
|
||||
utils.Str2Int(state["regex_matched"].([]string)[1]), // 需要发送的人的qq
|
||||
state["regex_matched"].([]string)[1], // 需要发送的信息
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendPrivateMessage(
|
||||
utils.Str2Int(ctx.State["regex_matched"].([]string)[1]), // 需要发送的人的qq
|
||||
ctx.State["regex_matched"].([]string)[1], // 需要发送的信息
|
||||
)
|
||||
zero.Send(
|
||||
event,
|
||||
"📧 --> "+state["regex_matched"].([]string)[1],
|
||||
)
|
||||
return zero.SuccessResponse
|
||||
ctx.Send("📧 --> " + ctx.State["regex_matched"].([]string)[1])
|
||||
return
|
||||
})
|
||||
// TODO 戳一戳
|
||||
zero.OnNotice().SetBlock(false).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if event.NoticeType == "notify" && event.SubType == "poke" && event.RawEvent.Get("target_id").Int() == utils.Str2Int(zero.BotConfig.SelfID) {
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if ctx.Event.NoticeType == "notify" && ctx.Event.SubType == "poke" && ctx.Event.RawEvent.Get("target_id").Int() == utils.Str2Int(zero.BotConfig.SelfID) {
|
||||
time.Sleep(time.Second * 1)
|
||||
zero.Send(event, "请不要戳我 >_<")
|
||||
ctx.Send("请不要戳我 >_<")
|
||||
}
|
||||
return zero.SuccessResponse
|
||||
return
|
||||
})
|
||||
// TODO 入群欢迎
|
||||
zero.OnNotice().SetBlock(false).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if event.NoticeType == "group_increase" {
|
||||
zero.Send(event, "欢迎~")
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if ctx.Event.NoticeType == "group_increase" {
|
||||
ctx.Send("欢迎~")
|
||||
}
|
||||
return zero.SuccessResponse
|
||||
return
|
||||
})
|
||||
// TODO 退群提醒
|
||||
zero.OnNotice().SetBlock(false).SetPriority(40).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if event.NoticeType == "group_decrease" {
|
||||
zero.Send(event, "有人跑路了~")
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if ctx.Event.NoticeType == "group_decrease" {
|
||||
ctx.Send("有人跑路了~")
|
||||
}
|
||||
return zero.SuccessResponse
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
package setutime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bot/music/utils"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
func init() {
|
||||
zero.RegisterPlugin(musicSelector{}) // 注册插件
|
||||
}
|
||||
|
||||
type musicSelector struct{} // musicSelector 点歌
|
||||
|
||||
func (_ musicSelector) GetPluginInfo() zero.PluginInfo { // 返回插件信息
|
||||
return zero.PluginInfo{
|
||||
Author: "kanri",
|
||||
PluginName: "MusicSelector",
|
||||
Version: "0.0.1",
|
||||
Details: "点歌",
|
||||
}
|
||||
}
|
||||
|
||||
func (_ musicSelector) Start() { // 插件主体
|
||||
// TODO 根据PID搜图
|
||||
zero.OnRegex(`点歌(.*)`).SetBlock(true).SetPriority(50).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
music, err := utils.CloudMusic(state["regex_matched"].([]string)[1])
|
||||
if err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 发送搜索结果
|
||||
zero.Send(
|
||||
event,
|
||||
fmt.Sprintf(
|
||||
"[CQ:music,type=%s,url=%s,audio=%s,title=%s,content=%s,image=%s]",
|
||||
music.Type,
|
||||
music.Url,
|
||||
music.Audio,
|
||||
music.Title,
|
||||
music.Content,
|
||||
music.Image,
|
||||
),
|
||||
)
|
||||
return zero.FinishResponse
|
||||
})
|
||||
}
|
||||
34
music/music_selecter.go
Normal file
34
music/music_selecter.go
Normal file
@ -0,0 +1,34 @@
|
||||
package setutime
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"bot/music/utils"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
func init() { // 插件主体
|
||||
// TODO 根据PID搜图
|
||||
zero.OnRegex(`点歌(.*)`).SetBlock(true).SetPriority(50).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
music, err := utils.CloudMusic(ctx.State["regex_matched"].([]string)[1])
|
||||
if err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
// TODO 发送搜索结果
|
||||
ctx.Send(
|
||||
fmt.Sprintf(
|
||||
"[CQ:music,type=%s,url=%s,audio=%s,title=%s,content=%s,image=%s]",
|
||||
music.Type,
|
||||
music.Url,
|
||||
music.Audio,
|
||||
music.Title,
|
||||
music.Content,
|
||||
music.Image,
|
||||
),
|
||||
)
|
||||
return
|
||||
})
|
||||
}
|
||||
@ -1,11 +1,5 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
type CQMusic struct {
|
||||
Type string
|
||||
Url string
|
||||
@ -14,7 +8,3 @@ type CQMusic struct {
|
||||
Content string
|
||||
Image string
|
||||
}
|
||||
|
||||
func SendError(event zero.Event, err error) {
|
||||
zero.Send(event, fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
|
||||
@ -2,61 +2,47 @@ package setutime
|
||||
|
||||
import (
|
||||
utils "bot/setutime/utils"
|
||||
"fmt"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
func init() {
|
||||
zero.RegisterPlugin(picSearch{}) // 注册插件
|
||||
}
|
||||
|
||||
type picSearch struct{} // pixivSearch 搜索P站插图
|
||||
|
||||
func (_ picSearch) GetPluginInfo() zero.PluginInfo { // 返回插件信息
|
||||
return zero.PluginInfo{
|
||||
Author: "kanri",
|
||||
PluginName: "PicSearch",
|
||||
Version: "0.0.1",
|
||||
Details: "以图搜图",
|
||||
}
|
||||
}
|
||||
|
||||
func (_ picSearch) Start() { // 插件主体
|
||||
func init() { // 插件主体
|
||||
// TODO 根据PID搜图
|
||||
zero.OnRegex(`搜图(\d+)`).SetBlock(true).SetPriority(30).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
id := utils.Str2Int(ctx.State["regex_matched"].([]string)[1])
|
||||
ctx.Send("少女祈祷中......")
|
||||
// TODO 获取P站插图信息
|
||||
illust := &utils.Illust{}
|
||||
if err := illust.IllustInfo(id); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
// TODO 下载P站插图
|
||||
if _, err := illust.PixivPicDown(CACHEPATH); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
// TODO 发送搜索结果
|
||||
zero.Send(event, illust.DetailPic)
|
||||
return zero.FinishResponse
|
||||
ctx.Send(illust.DetailPic)
|
||||
return
|
||||
})
|
||||
// TODO 通过回复以图搜图
|
||||
zero.OnRegex(`\[CQ:reply,id=(.*?)\](.*)搜索图片`).SetBlock(true).SetPriority(32).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var pics []string // 图片搜索池子
|
||||
// TODO 获取回复的上文图片链接
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
for _, elem := range zero.GetMessage(id).Elements {
|
||||
id := utils.Str2Int(ctx.State["regex_matched"].([]string)[1])
|
||||
for _, elem := range ctx.GetMessage(id).Elements {
|
||||
if elem.Type == "image" {
|
||||
pics = append(pics, elem.Data["url"])
|
||||
}
|
||||
}
|
||||
// TODO 没有收到图片则向用户索取
|
||||
if len(pics) == 0 {
|
||||
zero.Send(event, "请发送多张图片!")
|
||||
next := matcher.FutureEvent("message", zero.CheckUser(event.UserID))
|
||||
ctx.Send("请发送多张图片!")
|
||||
next := ctx.FutureEvent("message", ctx.CheckSession())
|
||||
recv, cancel := next.Repeat()
|
||||
for e := range recv { // 循环获取channel发来的信息
|
||||
if len(e.Message) == 1 && e.Message[0].Type == "text" {
|
||||
@ -75,41 +61,41 @@ func (_ picSearch) Start() { // 插件主体
|
||||
}
|
||||
}
|
||||
if len(pics) == 0 {
|
||||
zero.Send(event, "没有收到图片,搜图结束......")
|
||||
return zero.FinishResponse
|
||||
ctx.Send("没有收到图片,搜图结束......")
|
||||
return
|
||||
}
|
||||
// TODO 开始搜索图片
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
ctx.Send("少女祈祷中......")
|
||||
for _, pic := range pics {
|
||||
if text, err := utils.SauceNaoSearch(pic); err == nil {
|
||||
zero.Send(event, text) // 返回SauceNAO的结果
|
||||
ctx.Send(text) // 返回SauceNAO的结果
|
||||
continue
|
||||
} else {
|
||||
utils.SendError(event, err)
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
if text, err := utils.Ascii2dSearch(pic); err == nil {
|
||||
zero.Send(event, text) // 返回Ascii2d的结果
|
||||
ctx.Send(text) // 返回Ascii2d的结果
|
||||
continue
|
||||
} else {
|
||||
utils.SendError(event, err)
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
}
|
||||
return zero.FinishResponse
|
||||
return
|
||||
})
|
||||
// TODO 通过命令以图搜图
|
||||
zero.OnKeywordGroup([]string{"以图识图", "以图搜图", "搜索图片"}).SetBlock(true).SetPriority(33).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var pics []string // 图片搜索池子
|
||||
// TODO 获取信息中图片链接
|
||||
for _, elem := range event.Message {
|
||||
for _, elem := range ctx.Event.Message {
|
||||
if elem.Type == "image" {
|
||||
pics = append(pics, elem.Data["url"])
|
||||
}
|
||||
}
|
||||
// TODO 没有收到图片则向用户索取
|
||||
if len(pics) == 0 {
|
||||
zero.Send(event, "请发送多张图片!")
|
||||
next := matcher.FutureEvent("message", zero.CheckUser(event.UserID))
|
||||
ctx.Send("请发送多张图片!")
|
||||
next := ctx.FutureEvent("message", zero.CheckUser(ctx.Event.UserID))
|
||||
recv, cancel := next.Repeat()
|
||||
for e := range recv { // 循环获取channel发来的信息
|
||||
if len(e.Message) == 1 && e.Message[0].Type == "text" {
|
||||
@ -128,25 +114,25 @@ func (_ picSearch) Start() { // 插件主体
|
||||
}
|
||||
}
|
||||
if len(pics) == 0 {
|
||||
zero.Send(event, "没有收到图片,搜图结束......")
|
||||
return zero.FinishResponse
|
||||
ctx.Send("没有收到图片,搜图结束......")
|
||||
return
|
||||
}
|
||||
// TODO 开始搜索图片
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
ctx.Send("少女祈祷中......")
|
||||
for _, pic := range pics {
|
||||
if text, err := utils.SauceNaoSearch(pic); err == nil {
|
||||
zero.Send(event, text) // 返回SauceNAO的结果
|
||||
ctx.Send(text) // 返回SauceNAO的结果
|
||||
continue
|
||||
} else {
|
||||
utils.SendError(event, err)
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
if text, err := utils.Ascii2dSearch(pic); err == nil {
|
||||
zero.Send(event, text) // 返回Ascii2d的结果
|
||||
ctx.Send(text) // 返回Ascii2d的结果
|
||||
continue
|
||||
} else {
|
||||
utils.SendError(event, err)
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
}
|
||||
return zero.FinishResponse
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package setutime
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
utils "bot/setutime/utils"
|
||||
@ -13,343 +14,179 @@ import (
|
||||
|
||||
var limit = rate.NewManager(time.Minute*1, 5)
|
||||
|
||||
type setuGet struct{} // setuGet 来份色图
|
||||
|
||||
func (_ setuGet) GetPluginInfo() zero.PluginInfo { // 返回插件信息
|
||||
return zero.PluginInfo{
|
||||
Author: "kanri",
|
||||
PluginName: "SetuGet",
|
||||
Version: "0.0.1",
|
||||
Details: "来份色图",
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
BOTPATH = utils.PathExecute() // 当前bot运行目录
|
||||
DATAPATH = BOTPATH + "data/SetuTime/" // 数据目录
|
||||
DBPATH = DATAPATH + "SetuTime.db" // 数据库路径
|
||||
CACHEPATH = DATAPATH + "cache/" // 缓冲图片路径
|
||||
BOTPATH = utils.PathExecute() // 当前bot运行目录
|
||||
DATAPATH = BOTPATH + "data/SetuTime/" // 数据目录
|
||||
DBPATH = DATAPATH + "SetuTime.db" // 数据库路径
|
||||
|
||||
DB = utils.Sqlite{DBPath: DBPATH} // 涩图数据库
|
||||
CACHEPATH = DATAPATH + "cache/" // 缓冲图片路径
|
||||
CACHEGROUP int64 = 868047498 // 缓冲图片群,不修改无法缓存
|
||||
PoolList = []string{"涩图", "二次元", "风景", "车万"} // 可自定义
|
||||
|
||||
pool = utils.PicsCache{Max: 10} // 图片缓冲池子
|
||||
DB = utils.Sqlite{DBPath: DBPATH} // 新建涩图数据库对象
|
||||
PoolsCache = utils.NewPoolsCache() // 新建一个缓冲池对象
|
||||
|
||||
FORM = "PIC" // 默认 PIC 格式
|
||||
)
|
||||
|
||||
func init() {
|
||||
zero.RegisterPlugin(setuGet{}) // 注册插件
|
||||
|
||||
utils.CACHE_GROUP = 868047498 // 图片缓冲群
|
||||
utils.CACHEPATH = CACHEPATH // 缓冲图片路径
|
||||
PoolsCache.Group = CACHEGROUP // 图片缓冲群
|
||||
PoolsCache.Path = CACHEPATH // 缓冲图片路径
|
||||
|
||||
utils.CreatePath(DBPATH)
|
||||
utils.CreatePath(CACHEPATH)
|
||||
|
||||
ecy := &ecy{}
|
||||
setu := &setu{}
|
||||
scenery := &scenery{}
|
||||
DB.DBCreate(ecy)
|
||||
DB.DBCreate(setu)
|
||||
DB.DBCreate(scenery)
|
||||
for i := range PoolList {
|
||||
if err := DB.Create(PoolList[i], &utils.Illust{}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ecy 二次元
|
||||
type ecy struct {
|
||||
utils.Illust
|
||||
}
|
||||
|
||||
// setu 涩图
|
||||
type setu struct {
|
||||
utils.Illust
|
||||
}
|
||||
|
||||
// scenery 风景
|
||||
type scenery struct {
|
||||
utils.Illust
|
||||
}
|
||||
|
||||
func (_ setuGet) Start() { // 插件主体
|
||||
zero.OnFullMatchGroup([]string{"来份涩图", "setu", "来份色图"}).SetBlock(true).SetPriority(20).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if limit.Load(event.UserID).Acquire() == false {
|
||||
zero.Send(event, "请稍后重试0x0...")
|
||||
return zero.FinishResponse
|
||||
func init() { // 插件主体
|
||||
zero.OnRegex(`来份(.*)`, FirstValueInList(PoolList)).SetBlock(true).SetPriority(20).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if limit.Load(ctx.Event.UserID).Acquire() == false {
|
||||
ctx.Send("请稍后重试0x0...")
|
||||
return
|
||||
}
|
||||
var (
|
||||
type_ = "setu"
|
||||
illust = &setu{}
|
||||
type_ = ctx.State["regex_matched"].([]string)[1]
|
||||
illust = &utils.Illust{}
|
||||
)
|
||||
// TODO 池子无图片则立刻下载
|
||||
length := illust.Len(type_, &pool)
|
||||
if length == 0 {
|
||||
zero.Send(event, "[SetuTime] 正在填充弹药......")
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
}
|
||||
// TODO 补充池子
|
||||
go func() {
|
||||
times := utils.Min(pool.Max-length, 2)
|
||||
times := utils.Min(PoolsCache.Max-PoolsCache.Size(type_), 2)
|
||||
for i := 0; i < times; i++ {
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
// 查询出一张图片
|
||||
if err := DB.Select(type_, illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
continue
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
ctx.SendGroupMessage(PoolsCache.Group, "正在下载"+illust.ImageUrls)
|
||||
file, err := illust.PixivPicDown(PoolsCache.Path)
|
||||
if err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
continue
|
||||
}
|
||||
if id := ctx.SendGroupMessage(PoolsCache.Group, illust.NormalPic(file)); id == 0 {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", "发送到缓存群失败,请确认缓存群群号"))
|
||||
continue
|
||||
}
|
||||
// 向缓冲池添加一张图片
|
||||
if err := PoolsCache.Push(type_, illust); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
continue
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
}()
|
||||
// 如果没有缓存,阻塞5秒
|
||||
if PoolsCache.Size(type_) == 0 {
|
||||
ctx.Send("[SetuTime] 正在填充弹药......")
|
||||
<-time.After(time.Second * 5)
|
||||
if PoolsCache.Size(type_) == 0 {
|
||||
ctx.Send("[SetuTime] 等待填充,请稍后再试......")
|
||||
return
|
||||
}
|
||||
}
|
||||
// TODO 从缓冲池里抽一张
|
||||
hash := illust.Get(type_, &pool)
|
||||
if utils.XML {
|
||||
if id := zero.Send(event, illust.BigPic(hash)); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
} else {
|
||||
if id := zero.Send(event, illust.NormalPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
if id := ctx.Send(PoolsCache.GetOnePic(type_, FORM)); id == 0 {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", errors.New("可能被风控了")))
|
||||
}
|
||||
return zero.FinishResponse
|
||||
return
|
||||
})
|
||||
zero.OnFullMatchGroup([]string{"二次元", "ecy", "来份二次元"}).SetBlock(true).SetPriority(20).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if limit.Load(event.UserID).Acquire() == false {
|
||||
zero.Send(event, "请稍后重试0x0...")
|
||||
return zero.FinishResponse
|
||||
}
|
||||
|
||||
zero.OnRegex(`添加(.*?)(\d+)`, FirstValueInList(PoolList), zero.SuperUserPermission).SetBlock(true).SetPriority(21).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var (
|
||||
type_ = "ecy"
|
||||
illust = &ecy{}
|
||||
type_ = ctx.State["regex_matched"].([]string)[1]
|
||||
id = utils.Str2Int(ctx.State["regex_matched"].([]string)[2])
|
||||
illust = &utils.Illust{}
|
||||
file = fmt.Sprintf("%s%d.jpg", PoolsCache.Path, illust.Pid)
|
||||
)
|
||||
// TODO 池子无图片则立刻下载
|
||||
length := illust.Len(type_, &pool)
|
||||
if length == 0 {
|
||||
zero.Send(event, "[SetuTime] 正在填充弹药......")
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
ctx.Send("少女祈祷中......")
|
||||
// TODO 查询P站插图信息
|
||||
|
||||
if err := illust.IllustInfo(id); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
// TODO 补充池子
|
||||
go func() {
|
||||
times := utils.Min(pool.Max-length, 2)
|
||||
for i := 0; i < times; i++ {
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
}
|
||||
}
|
||||
}()
|
||||
// TODO 从缓冲池里抽一张
|
||||
hash := illust.Get(type_, &pool)
|
||||
if utils.XML {
|
||||
if id := zero.Send(event, illust.BigPic(hash)); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
} else {
|
||||
if id := zero.Send(event, illust.NormalPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
// TODO 下载插画
|
||||
if _, err := illust.PixivPicDown(PoolsCache.Path); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
return zero.FinishResponse
|
||||
if id := ctx.Send(illust.DetailPic(file)); id == 0 {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", "可能被风控,发送失败"))
|
||||
return
|
||||
}
|
||||
// TODO 添加插画到对应的数据库table
|
||||
if err := DB.Insert(type_, illust); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
ctx.Send("添加成功")
|
||||
return
|
||||
})
|
||||
zero.OnFullMatchGroup([]string{"风景", "来份风景"}).SetBlock(true).SetPriority(20).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
if limit.Load(event.UserID).Acquire() == false {
|
||||
zero.Send(event, "请稍后重试0x0...")
|
||||
return zero.FinishResponse
|
||||
}
|
||||
|
||||
zero.OnRegex(`删除(.*?)(\d+)`, FirstValueInList(PoolList), zero.SuperUserPermission).SetBlock(true).SetPriority(22).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var (
|
||||
type_ = "scenery"
|
||||
illust = &scenery{}
|
||||
type_ = ctx.State["regex_matched"].([]string)[1]
|
||||
id = utils.Str2Int(ctx.State["regex_matched"].([]string)[2])
|
||||
)
|
||||
// TODO 池子无图片则立刻下载
|
||||
length := illust.Len(type_, &pool)
|
||||
if length == 0 {
|
||||
zero.Send(event, "[SetuTime] 正在填充弹药......")
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
return zero.FinishResponse
|
||||
}
|
||||
}
|
||||
// TODO 补充池子
|
||||
go func() {
|
||||
times := utils.Min(pool.Max-length, 2)
|
||||
for i := 0; i < times; i++ {
|
||||
if err := DB.DBSelect(illust, "ORDER BY RANDOM() limit 1"); err != nil {
|
||||
utils.SendError(event, err) // 查询出一张图片
|
||||
}
|
||||
if err := illust.Add(type_, &pool); err != nil {
|
||||
utils.SendError(event, err) // 向缓冲池添加一张图片
|
||||
}
|
||||
}
|
||||
}()
|
||||
// TODO 从缓冲池里抽一张
|
||||
hash := illust.Get(type_, &pool)
|
||||
if utils.XML {
|
||||
if id := zero.Send(event, illust.BigPic(hash)); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
} else {
|
||||
if id := zero.Send(event, illust.NormalPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
}
|
||||
}
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`添加涩图(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(21).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &setu{}
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
// TODO 查询P站插图信息
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := illust.IllustInfo(id); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 下载插画
|
||||
if _, err := illust.PixivPicDown(CACHEPATH); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if id := zero.Send(event, illust.DetailPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 添加插画到对应的数据库table
|
||||
if err := DB.DBInsert(illust); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
zero.Send(event, "添加成功")
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`添加二次元(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(21).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &ecy{}
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
// TODO 查询P站插图信息
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := illust.IllustInfo(id); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 下载插画
|
||||
if _, err := illust.PixivPicDown(CACHEPATH); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if id := zero.Send(event, illust.DetailPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 添加插画到对应的数据库table
|
||||
if err := DB.DBInsert(illust); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
zero.Send(event, "添加成功")
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`添加风景(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(21).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &scenery{}
|
||||
zero.Send(event, "少女祈祷中......")
|
||||
// TODO 查询P站插图信息
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := illust.IllustInfo(id); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 下载插画
|
||||
if _, err := illust.PixivPicDown(CACHEPATH); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
if id := zero.Send(event, illust.DetailPic()); id == 0 {
|
||||
utils.SendError(event, errors.New("可能被风控了"))
|
||||
return zero.FinishResponse
|
||||
}
|
||||
// TODO 添加插画到对应的数据库table
|
||||
if err := DB.DBInsert(illust); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
zero.Send(event, "添加成功")
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`删除涩图(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(22).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &setu{}
|
||||
// TODO 查询数据库
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := DB.DBDelete(illust, fmt.Sprintf("WHERE pid=%d", id)); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
if err := DB.Delete(type_, fmt.Sprintf("WHERE pid=%d", id)); err != nil {
|
||||
ctx.Send(fmt.Sprintf("ERROR: %v", err))
|
||||
return
|
||||
}
|
||||
zero.Send(event, "删除成功")
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`删除二次元(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(22).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &ecy{}
|
||||
// TODO 查询数据库
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := DB.DBDelete(illust, fmt.Sprintf("WHERE pid=%d", id)); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
zero.Send(event, "删除成功")
|
||||
return zero.FinishResponse
|
||||
})
|
||||
zero.OnRegex(`删除风景(\d+)`, zero.SuperUserPermission).SetBlock(true).SetPriority(22).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
var illust = &scenery{}
|
||||
// TODO 查询数据库
|
||||
id := utils.Str2Int(state["regex_matched"].([]string)[1])
|
||||
if err := DB.DBDelete(illust, fmt.Sprintf("WHERE pid=%d", id)); err != nil {
|
||||
utils.SendError(event, err)
|
||||
return zero.FinishResponse
|
||||
}
|
||||
zero.Send(event, "删除成功")
|
||||
return zero.FinishResponse
|
||||
ctx.Send("删除成功")
|
||||
return
|
||||
})
|
||||
|
||||
// TODO 查询数据库涩图数量
|
||||
zero.OnFullMatchGroup([]string{"setu -s", "setu --status"}, zero.SuperUserPermission).SetBlock(true).SetPriority(23).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
setu, _ := DB.DBNum(&setu{})
|
||||
ecy, _ := DB.DBNum(&ecy{})
|
||||
scenery, _ := DB.DBNum(&scenery{})
|
||||
zero.Send(event, fmt.Sprintf("[SetuTime] \n风景:%d \n二次元:%d \n涩图:%d", scenery, ecy, setu))
|
||||
return zero.FinishResponse
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
state := []string{"[SetuTime]"}
|
||||
for i := range PoolList {
|
||||
num, err := DB.Num(PoolList[i])
|
||||
if err != nil {
|
||||
num = 0
|
||||
}
|
||||
state = append(state, "\n")
|
||||
state = append(state, PoolList[i])
|
||||
state = append(state, ": ")
|
||||
state = append(state, fmt.Sprintf("%d", num))
|
||||
}
|
||||
ctx.Send(strings.Join(state, ""))
|
||||
return
|
||||
})
|
||||
// TODO 开xml模式
|
||||
zero.OnFullMatchGroup([]string{"setu -x", "setu --xml"}, zero.AdminPermission).SetBlock(true).SetPriority(24).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
utils.XML = true
|
||||
zero.Send(event, "[SetuTime] XML->ON")
|
||||
return zero.FinishResponse
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
FORM = "XML"
|
||||
ctx.Send("[SetuTime] XML->ON")
|
||||
return
|
||||
})
|
||||
// TODO 关xml模式
|
||||
zero.OnFullMatchGroup([]string{"setu -p", "setu --pic"}, zero.AdminPermission).SetBlock(true).SetPriority(24).
|
||||
Handle(func(matcher *zero.Matcher, event zero.Event, state zero.State) zero.Response {
|
||||
utils.XML = false
|
||||
zero.Send(event, "[SetuTime] XML->OFF")
|
||||
return zero.FinishResponse
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
FORM = "PIC"
|
||||
ctx.Send("[SetuTime] XML->OFF")
|
||||
return
|
||||
})
|
||||
}
|
||||
|
||||
// FirstValueInList 判断正则匹配的第一个参数是否在列表中
|
||||
func FirstValueInList(list []string) zero.Rule {
|
||||
return func(ctx *zero.Ctx) bool {
|
||||
first := ctx.State["regex_matched"].([]string)[1]
|
||||
for i := range list {
|
||||
if first == list[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,8 +8,6 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
// urlCache 缓存并返回缓存路径
|
||||
@ -26,7 +24,6 @@ func (this *Illust) PixivPicDown(path string) (savePath string, err error) {
|
||||
if PathExists(savePath) && FileSize(savePath) > 10240 {
|
||||
return savePath, nil
|
||||
}
|
||||
zero.SendGroupMessage(CACHE_GROUP, "正在下载"+url)
|
||||
// TODO 模拟QQ客户端请求
|
||||
client := &http.Client{}
|
||||
reqest, _ := http.NewRequest("GET", url, nil)
|
||||
@ -51,6 +48,7 @@ func (this *Illust) PixivPicDown(path string) (savePath string, err error) {
|
||||
return savePath, err
|
||||
}
|
||||
|
||||
// PicHash 返回图片的 md5 值
|
||||
func PicHash(path string) string {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
|
||||
@ -1,128 +1,78 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
var (
|
||||
CACHEPATH string // 图片缓存路径
|
||||
CACHE_GROUP int64 // 图片缓存群,用于上传图片到tx服务器
|
||||
)
|
||||
|
||||
// PicsCache 图片缓冲池
|
||||
type PicsCache struct {
|
||||
Lock sync.Mutex
|
||||
Max int
|
||||
ECY []string
|
||||
IECY []Illust
|
||||
SETU []string
|
||||
ISETU []Illust
|
||||
SCENERY []string
|
||||
ISCENERY []Illust
|
||||
// PoolsCache 图片缓冲池
|
||||
type PoolsCache struct {
|
||||
Lock sync.Mutex
|
||||
Max int
|
||||
Path string
|
||||
Group int64
|
||||
Pool map[string][]*Illust
|
||||
}
|
||||
|
||||
// Len 返回当前缓冲池的图片数量
|
||||
func (this *Illust) Len(type_ string, pool *PicsCache) (length int) {
|
||||
switch type_ {
|
||||
case "ecy":
|
||||
return len(pool.ECY)
|
||||
case "setu":
|
||||
return len(pool.SETU)
|
||||
case "scenery":
|
||||
return len(pool.SCENERY)
|
||||
// NewPoolsCache 返回一个缓冲池对象
|
||||
func NewPoolsCache() *PoolsCache {
|
||||
return &PoolsCache{
|
||||
Max: 10,
|
||||
Path: "./data/SetuTime/cache/",
|
||||
Group: 1048452984,
|
||||
Pool: map[string][]*Illust{},
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Add 添加图片到缓冲池,返回错误
|
||||
func (this Illust) Add(type_ string, pool *PicsCache) (err error) {
|
||||
// TODO 下载图片
|
||||
path, err := this.PixivPicDown(CACHEPATH)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hash := PicHash(path)
|
||||
// TODO 发送到缓存群以上传tx服务器
|
||||
if id := zero.SendGroupMessage(CACHE_GROUP, "[CQ:image,file=file:///"+path+"]"); id == 0 {
|
||||
return errors.New("send failed")
|
||||
}
|
||||
// TODO 把hash和插图信息添加到缓冲池
|
||||
pool.Lock.Lock()
|
||||
defer pool.Lock.Unlock()
|
||||
switch type_ {
|
||||
case "ecy":
|
||||
pool.ECY = append(pool.ECY, hash)
|
||||
pool.IECY = append(pool.IECY, this)
|
||||
case "setu":
|
||||
pool.SETU = append(pool.SETU, hash)
|
||||
pool.ISETU = append(pool.ISETU, this)
|
||||
case "scenery":
|
||||
pool.SCENERY = append(pool.SCENERY, hash)
|
||||
pool.ISCENERY = append(pool.ISCENERY, this)
|
||||
}
|
||||
// Size 返回缓冲池指定类型的现有大小
|
||||
func (p *PoolsCache) Size(type_ string) int {
|
||||
return len(p.Pool[type_])
|
||||
}
|
||||
|
||||
// IsFull 返回缓冲池指定类型是否已满
|
||||
func (p *PoolsCache) IsFull(type_ string) bool {
|
||||
return len(p.Pool[type_]) >= p.Max
|
||||
}
|
||||
|
||||
// Push 向缓冲池插入一张图片,返回错误
|
||||
func (p *PoolsCache) Push(type_ string, illust *Illust) (err error) {
|
||||
p.Lock.Lock()
|
||||
defer p.Lock.Unlock()
|
||||
p.Pool[type_] = append(p.Pool[type_], illust)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get 从缓冲池里取出一张,返回hash,illust值中Pid和UserName会被改变
|
||||
func (this *Illust) Get(type_ string, pool *PicsCache) (hash string) {
|
||||
pool.Lock.Lock()
|
||||
defer pool.Lock.Unlock()
|
||||
switch type_ {
|
||||
case "ecy":
|
||||
if len(pool.ECY) > 0 {
|
||||
hash := pool.ECY[0]
|
||||
this.Pid = pool.IECY[0].Pid
|
||||
this.Title = pool.IECY[0].Title
|
||||
this.UserName = pool.IECY[0].UserName
|
||||
pool.ECY = pool.ECY[1:]
|
||||
pool.IECY = pool.IECY[1:]
|
||||
return hash
|
||||
}
|
||||
case "setu":
|
||||
if len(pool.SETU) > 0 {
|
||||
hash := pool.SETU[0]
|
||||
this.Pid = pool.ISETU[0].Pid
|
||||
this.Title = pool.ISETU[0].Title
|
||||
this.UserName = pool.ISETU[0].UserName
|
||||
pool.SETU = pool.SETU[1:]
|
||||
pool.ISETU = pool.ISETU[1:]
|
||||
return hash
|
||||
}
|
||||
case "scenery":
|
||||
if len(pool.SCENERY) > 0 {
|
||||
hash := pool.SCENERY[0]
|
||||
this.Pid = pool.ISCENERY[0].Pid
|
||||
this.Title = pool.ISCENERY[0].Title
|
||||
this.UserName = pool.ISCENERY[0].UserName
|
||||
pool.SCENERY = pool.SCENERY[1:]
|
||||
pool.ISCENERY = pool.ISCENERY[1:]
|
||||
return hash
|
||||
}
|
||||
default:
|
||||
//
|
||||
// Push 在缓冲池拿出一张图片,返回错误
|
||||
func (p *PoolsCache) Pop(type_ string) (illust *Illust) {
|
||||
p.Lock.Lock()
|
||||
defer p.Lock.Unlock()
|
||||
if p.Size(type_) == 0 {
|
||||
return
|
||||
}
|
||||
return ""
|
||||
illust = p.Pool[type_][0]
|
||||
p.Pool[type_] = p.Pool[type_][1:]
|
||||
return
|
||||
}
|
||||
|
||||
func GetCQcodePicLink(text string) (url string) {
|
||||
text = strings.ReplaceAll(text, "{", "")
|
||||
text = strings.ReplaceAll(text, "{", "")
|
||||
text = strings.ReplaceAll(text, "-", "")
|
||||
if index := strings.Index(text, "."); index != -1 {
|
||||
if hash := text[:index]; len(hash) == 32 {
|
||||
return fmt.Sprintf("http://gchat.qpic.cn/gchatpic_new//--%s/0", hash)
|
||||
}
|
||||
// Push 在缓冲池拿出一张图片,返回指定格式CQ码
|
||||
func (p *PoolsCache) GetOnePic(type_ string, form string) string {
|
||||
var (
|
||||
illust = p.Pop(type_)
|
||||
file = fmt.Sprintf("%s%d.jpg", p.Path, illust.Pid)
|
||||
)
|
||||
switch form {
|
||||
case "XML":
|
||||
return illust.BigPic(file)
|
||||
case "DETAIL":
|
||||
return illust.DetailPic(file)
|
||||
default:
|
||||
return illust.NormalPic(file)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// BigPic 返回一张XML大图CQ码
|
||||
func (this *Illust) BigPic(hash string) string {
|
||||
func (i *Illust) BigPic(file string) string {
|
||||
var hash = PicHash(file)
|
||||
return fmt.Sprintf(`[CQ:xml,data=<?xml version='1.0'
|
||||
encoding='UTF-8' standalone='yes' ?><msg serviceID="5"
|
||||
templateID="12345" action="" brief="不够涩!"
|
||||
@ -135,29 +85,29 @@ action="" appid="-1" /></msg>]`,
|
||||
hash,
|
||||
hash,
|
||||
hash,
|
||||
this.Title,
|
||||
this.Pid,
|
||||
this.UserName,
|
||||
i.Title,
|
||||
i.Pid,
|
||||
i.UserName,
|
||||
)
|
||||
}
|
||||
|
||||
// NormalPic 返回一张普通图CQ码
|
||||
func (this *Illust) NormalPic() string {
|
||||
return fmt.Sprintf(`[CQ:image,file=file:///%s%d.jpg]`, CACHEPATH, this.Pid)
|
||||
func (i *Illust) NormalPic(file string) string {
|
||||
return fmt.Sprintf(`[CQ:image,file=file:///%s]`, file)
|
||||
}
|
||||
|
||||
// DetailPic 返回一张带详细信息的图片CQ码
|
||||
func (this *Illust) DetailPic() string {
|
||||
func (i *Illust) DetailPic(file string) string {
|
||||
return fmt.Sprintf(`[SetuTime] %s 标题:%s
|
||||
插画ID:%d
|
||||
画师:%s
|
||||
画师ID:%d
|
||||
直链:https://pixivel.moe/detail?id=%d`,
|
||||
this.NormalPic(),
|
||||
this.Title,
|
||||
this.Pid,
|
||||
this.UserName,
|
||||
this.UserId,
|
||||
this.Pid,
|
||||
i.NormalPic(file),
|
||||
i.Title,
|
||||
i.Pid,
|
||||
i.UserName,
|
||||
i.UserId,
|
||||
i.Pid,
|
||||
)
|
||||
}
|
||||
|
||||
@ -3,19 +3,22 @@ package utils
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
// Sqlite 数据库对象
|
||||
type Sqlite struct {
|
||||
DB *sql.DB
|
||||
DBPath string
|
||||
}
|
||||
|
||||
// DBCreate 根据结构体生成数据库table,tag为"id"为主键,自增
|
||||
func (db *Sqlite) DBCreate(objptr interface{}) (err error) {
|
||||
// Create 生成数据库
|
||||
// 默认结构体的第一个元素为主键
|
||||
// 返回错误
|
||||
func (db *Sqlite) Create(table string, objptr interface{}) (err error) {
|
||||
if db.DB == nil {
|
||||
database, err := sql.Open("sqlite3", db.DBPath)
|
||||
if err != nil {
|
||||
@ -23,95 +26,127 @@ func (db *Sqlite) DBCreate(objptr interface{}) (err error) {
|
||||
}
|
||||
db.DB = database
|
||||
}
|
||||
|
||||
table := fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (", Struct2name(objptr))
|
||||
for i, column := range strcut2columns(objptr) {
|
||||
table += fmt.Sprintf(" %s %s NULL", column, column2type(objptr, column))
|
||||
if i+1 != len(strcut2columns(objptr)) {
|
||||
table += ","
|
||||
} else {
|
||||
table += " );"
|
||||
var (
|
||||
tags = tags(objptr)
|
||||
kinds = kinds(objptr)
|
||||
top = len(tags) - 1
|
||||
cmd = []string{}
|
||||
)
|
||||
cmd = append(cmd, "CREATE TABLE IF NOT EXISTS")
|
||||
cmd = append(cmd, table)
|
||||
cmd = append(cmd, "(")
|
||||
for i := range tags {
|
||||
cmd = append(cmd, tags[i])
|
||||
cmd = append(cmd, kinds[i])
|
||||
switch i {
|
||||
default:
|
||||
cmd = append(cmd, "NULL,")
|
||||
case 0:
|
||||
cmd = append(cmd, "PRIMARY KEY")
|
||||
cmd = append(cmd, "NOT NULL,")
|
||||
case top:
|
||||
cmd = append(cmd, "NULL);")
|
||||
}
|
||||
}
|
||||
if _, err := db.DB.Exec(table); err != nil {
|
||||
if _, err := db.DB.Exec(strings.Join(cmd, " ")); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DBInsert 根据结构体插入一条数据
|
||||
func (db *Sqlite) DBInsert(objptr interface{}) (err error) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
rows, err := db.DB.Query("SELECT * FROM " + Struct2name(objptr))
|
||||
// Insert 插入数据集
|
||||
// 默认结构体的第一个元素为主键
|
||||
// 返回错误
|
||||
func (db *Sqlite) Insert(table string, objptr interface{}) (err error) {
|
||||
rows, err := db.DB.Query("SELECT * FROM " + table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
columns, _ := rows.Columns()
|
||||
index := -1
|
||||
names := "("
|
||||
insert := "("
|
||||
for i, column := range columns {
|
||||
if column == "id" {
|
||||
index = i
|
||||
continue
|
||||
}
|
||||
if i != len(columns)-1 {
|
||||
names += column + ","
|
||||
insert += "?,"
|
||||
} else {
|
||||
names += column + ")"
|
||||
insert += "?)"
|
||||
tags, _ := rows.Columns()
|
||||
var (
|
||||
values = values(objptr)
|
||||
top = len(tags) - 1
|
||||
cmd = []string{}
|
||||
)
|
||||
cmd = append(cmd, "INSERT INTO")
|
||||
cmd = append(cmd, table)
|
||||
for i := range tags {
|
||||
switch i {
|
||||
default:
|
||||
cmd = append(cmd, tags[i])
|
||||
cmd = append(cmd, ",")
|
||||
case 0:
|
||||
cmd = append(cmd, "(")
|
||||
cmd = append(cmd, tags[i])
|
||||
cmd = append(cmd, ",")
|
||||
case top:
|
||||
cmd = append(cmd, tags[i])
|
||||
cmd = append(cmd, ")")
|
||||
}
|
||||
}
|
||||
stmt, err := db.DB.Prepare("INSERT INTO " + Struct2name(objptr) + names + " values " + insert)
|
||||
for i := range tags {
|
||||
switch i {
|
||||
default:
|
||||
cmd = append(cmd, "?")
|
||||
cmd = append(cmd, ",")
|
||||
case 0:
|
||||
cmd = append(cmd, "VALUES (")
|
||||
cmd = append(cmd, "?")
|
||||
cmd = append(cmd, ",")
|
||||
case top:
|
||||
cmd = append(cmd, "?")
|
||||
cmd = append(cmd, ")")
|
||||
}
|
||||
}
|
||||
stmt, err := db.DB.Prepare(strings.Join(cmd, " "))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value := []interface{}{}
|
||||
if index == -1 {
|
||||
value = append(value, struct2values(objptr, columns)...)
|
||||
} else {
|
||||
value = append(value, append(struct2values(objptr, columns)[:index], struct2values(objptr, columns)[index+1:]...)...)
|
||||
}
|
||||
_, err = stmt.Exec(value...)
|
||||
_, err = stmt.Exec(values...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DBSelect 根据结构体查询对应的表,cmd可为"WHERE id = 0 "
|
||||
func (db *Sqlite) DBSelect(objptr interface{}, cmd string) (err error) {
|
||||
rows, err := db.DB.Query(fmt.Sprintf("SELECT * FROM %s %s", Struct2name(objptr), cmd))
|
||||
// Select 查询数据库
|
||||
// condition 可为"WHERE id = 0"
|
||||
// 默认字段与结构体元素顺序一致
|
||||
// 返回错误
|
||||
func (db *Sqlite) Select(table string, objptr interface{}, condition string) (err 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, " "))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
columns, err := rows.Columns()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = rows.Scan(struct2addrs(objptr, columns)...)
|
||||
err = rows.Scan(addrs(objptr)...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return errors.New("Database no such elem")
|
||||
return errors.New("数据库无此条件项目")
|
||||
}
|
||||
|
||||
// DBDelete 删除struct对应表的一行,返回错误
|
||||
func (db *Sqlite) DBDelete(objptr interface{}, cmd string) (err error) {
|
||||
stmt, err := db.DB.Prepare(fmt.Sprintf("DELETE FROM %s %s", Struct2name(objptr), cmd))
|
||||
// Delete 删除数据库
|
||||
// condition 可为"WHERE id = 0"
|
||||
// 返回错误
|
||||
func (db *Sqlite) Delete(table string, condition string) (err 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, " "))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,9 +157,13 @@ func (db *Sqlite) DBDelete(objptr interface{}, cmd string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
// DBNum 查询struct对应表的行数,返回行数以及错误
|
||||
func (db *Sqlite) DBNum(objptr interface{}) (num int, err error) {
|
||||
rows, err := db.DB.Query(fmt.Sprintf("SELECT * FROM %s", Struct2name(objptr)))
|
||||
// Num 查询数据库行数
|
||||
// 返回行数以及错误
|
||||
func (db *Sqlite) Num(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, " "))
|
||||
if err != nil {
|
||||
return num, err
|
||||
}
|
||||
@ -135,90 +174,72 @@ func (db *Sqlite) DBNum(objptr interface{}) (num int, err error) {
|
||||
return num, nil
|
||||
}
|
||||
|
||||
// strcut2columns 反射得到结构体的 tag 数组
|
||||
func strcut2columns(objptr interface{}) []string {
|
||||
var columns []string
|
||||
// tags 反射 返回结构体对象的 tag 数组
|
||||
func tags(objptr interface{}) []string {
|
||||
var tags []string
|
||||
elem := reflect.ValueOf(objptr).Elem()
|
||||
// TODO 判断第一个元素是否为匿名字段
|
||||
if elem.Type().Field(0).Anonymous {
|
||||
elem = elem.Field(0)
|
||||
}
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
columns = append(columns, elem.Type().Field(i).Tag.Get("db"))
|
||||
tags = append(tags, elem.Type().Field(i).Tag.Get("db"))
|
||||
}
|
||||
return columns
|
||||
return tags
|
||||
}
|
||||
|
||||
// Struct2name 反射得到结构体的名字
|
||||
func Struct2name(objptr interface{}) string {
|
||||
return reflect.ValueOf(objptr).Elem().Type().Name()
|
||||
}
|
||||
|
||||
// column2type 反射得到结构体对应 tag 的 数据库数据类型
|
||||
func column2type(objptr interface{}, column string) string {
|
||||
type_ := ""
|
||||
// kinds 反射 返回结构体对象的 kinds 数组
|
||||
func kinds(objptr interface{}) []string {
|
||||
var kinds []string
|
||||
elem := reflect.ValueOf(objptr).Elem()
|
||||
// TODO 判断第一个元素是否为匿名字段
|
||||
if elem.Type().Field(0).Anonymous {
|
||||
elem = elem.Field(0)
|
||||
}
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
if column == elem.Type().Field(i).Tag.Get("db") {
|
||||
type_ = elem.Field(i).Type().String()
|
||||
switch elem.Field(i).Type().String() {
|
||||
case "int64":
|
||||
kinds = append(kinds, "INT")
|
||||
case "string":
|
||||
kinds = append(kinds, "TEXT")
|
||||
default:
|
||||
kinds = append(kinds, "TEXT")
|
||||
}
|
||||
}
|
||||
if column == "id" {
|
||||
return "INTEGER PRIMARY KEY"
|
||||
}
|
||||
switch type_ {
|
||||
case "int64":
|
||||
return "INT"
|
||||
case "string":
|
||||
return "TEXT"
|
||||
default:
|
||||
return "TEXT"
|
||||
}
|
||||
return kinds
|
||||
}
|
||||
|
||||
// struct2addrs 反射得到结构体对应数据库字段的属性地址
|
||||
func struct2addrs(objptr interface{}, columns []string) []interface{} {
|
||||
var addrs []interface{}
|
||||
elem := reflect.ValueOf(objptr).Elem()
|
||||
// TODO 判断第一个元素是否为匿名字段
|
||||
if elem.Type().Field(0).Anonymous {
|
||||
elem = elem.Field(0)
|
||||
}
|
||||
for _, column := range columns {
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
if column == elem.Type().Field(i).Tag.Get("db") {
|
||||
addrs = append(addrs, elem.Field(i).Addr().Interface())
|
||||
}
|
||||
}
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
// struct2values 反射得到结构体对应数据库字段的属性值
|
||||
func struct2values(objptr interface{}, columns []string) []interface{} {
|
||||
// values 反射 返回结构体对象的 values 数组
|
||||
func values(objptr interface{}) []interface{} {
|
||||
var values []interface{}
|
||||
elem := reflect.ValueOf(objptr).Elem()
|
||||
// TODO 判断第一个元素是否为匿名字段
|
||||
if elem.Type().Field(0).Anonymous {
|
||||
elem = elem.Field(0)
|
||||
}
|
||||
for _, column := range columns {
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
if column == elem.Type().Field(i).Tag.Get("db") {
|
||||
switch elem.Field(i).Type().String() {
|
||||
case "int64":
|
||||
values = append(values, elem.Field(i).Int())
|
||||
case "string":
|
||||
values = append(values, elem.Field(i).String())
|
||||
default:
|
||||
values = append(values, elem.Field(i).String())
|
||||
}
|
||||
}
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
switch elem.Field(i).Type().String() {
|
||||
case "int64":
|
||||
values = append(values, elem.Field(i).Int())
|
||||
case "string":
|
||||
values = append(values, elem.Field(i).String())
|
||||
default:
|
||||
values = append(values, elem.Field(i).String())
|
||||
}
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
// addrs 反射 返回结构体对象的 addrs 数组
|
||||
func addrs(objptr interface{}) []interface{} {
|
||||
var addrs []interface{}
|
||||
elem := reflect.ValueOf(objptr).Elem()
|
||||
// TODO 判断第一个元素是否为匿名字段
|
||||
if elem.Type().Field(0).Anonymous {
|
||||
elem = elem.Field(0)
|
||||
}
|
||||
for i, flen := 0, elem.Type().NumField(); i < flen; i++ {
|
||||
addrs = append(addrs, elem.Field(i).Addr().Interface())
|
||||
}
|
||||
return addrs
|
||||
}
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
// Str2Int string --> int64
|
||||
@ -74,7 +71,3 @@ func Min(a, b int) int {
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
func SendError(event zero.Event, err error) {
|
||||
zero.Send(event, fmt.Sprintf("ERROR: %v", err))
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user