mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2026-02-08 08:00:25 +00:00
Compare commits
14 Commits
v1.3.2-bet
...
v1.3.2-fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b409ff3de | ||
|
|
a9e13d3a92 | ||
|
|
0698d8e3b1 | ||
|
|
8e4c496b54 | ||
|
|
27054b9722 | ||
|
|
bcad2c4998 | ||
|
|
aae2bd4884 | ||
|
|
006ef6f672 | ||
|
|
7be1a61347 | ||
|
|
1ef48f6cd6 | ||
|
|
a9a061a4bb | ||
|
|
14ed8b7af7 | ||
|
|
d17b8fa720 | ||
|
|
68980a69b5 |
16
README.md
16
README.md
@@ -148,7 +148,7 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
- [x] 退出群聊[群号]@Bot
|
||||
- [x] *入群欢迎
|
||||
- [x] *退群通知
|
||||
- [x] 设置欢迎语[欢迎~] 可选添加 [{at}] [{nickname}] [{avatar}]
|
||||
- [x] 设置欢迎语[欢迎~] 可选添加 [{at}] [{nickname}] [{avatar}] [{id}]
|
||||
- [x] 在[MM]月[dd]日的[hh]点[mm]分时(用[url])提醒大家[xxx]
|
||||
- [x] 在[MM]月[每周 | 周几]的[hh]点[mm]分时(用[url])提醒大家[xxx]
|
||||
- [x] 取消在[MM]月[dd]日的[hh]点[mm]分的提醒
|
||||
@@ -234,6 +234,9 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
- [x] 搜番 | 搜索番剧[图片]
|
||||
- **百度一下** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu"`
|
||||
- [x] 百度下[xxx]
|
||||
- **百人一首** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/hyaku"`
|
||||
- [x] 百人一首
|
||||
- [x] 百人一首之n
|
||||
- **随机图片与AI点评** `import _ github.com/FloatTech/ZeroBot-Plugin/plugin/acgimage`
|
||||
- [x] 随机图片(评级大于6的图将私发)
|
||||
- [x] 直接随机(无r18检测,务必小心,仅管理可用)
|
||||
@@ -265,8 +268,11 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
- [x] 个人猜单词
|
||||
- [x] 团队猜单词
|
||||
- **bilibili** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili"`
|
||||
- [x] >vup info [名字 | uid]
|
||||
- [x] >user info [名字 | uid]
|
||||
- [x] >vup info [xxx]
|
||||
- [x] >user info [xxx]
|
||||
- [x] 查成分 [xxx]
|
||||
- [x] 设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31
|
||||
- [x] 更新vup
|
||||
- **嘉然** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana"`
|
||||
- [x] 小作文
|
||||
- [x] 发大病
|
||||
@@ -368,12 +374,12 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
- api早上8点更新,推荐定时在8点30后。配合插件`job`中的记录在"cron"触发的指令使用
|
||||
- [x] /启用 zaobao
|
||||
- [x] /禁用 zaobao
|
||||
- **舔狗日记** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou"`
|
||||
- [x] 舔狗日记
|
||||
```
|
||||
记录在"00 9 * * *"触发的指令
|
||||
今日早报
|
||||
```
|
||||
- **舔狗日记** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/tiangou"`
|
||||
- [x] 舔狗日记
|
||||
- **TODO...**
|
||||
|
||||
## 使用方法
|
||||
|
||||
2
data
2
data
Submodule data updated: 9fc3ca233b...5155c7318a
14
go.mod
14
go.mod
@@ -3,15 +3,15 @@ module github.com/FloatTech/ZeroBot-Plugin
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/FloatTech/AnimeAPI v1.3.2-0.20220326161751-d0d2797b91da
|
||||
github.com/FloatTech/AnimeAPI v1.3.2
|
||||
github.com/FloatTech/sqlite v0.2.1
|
||||
github.com/FloatTech/zbputils v1.3.2-0.20220327063325-1389d5a92fff
|
||||
github.com/FloatTech/zbputils v1.3.2
|
||||
github.com/antchfx/htmlquery v1.2.4
|
||||
github.com/corona10/goimagehash v1.0.3
|
||||
github.com/fogleman/gg v1.3.0
|
||||
github.com/fumiama/cron v1.3.0
|
||||
github.com/fumiama/go-base16384 v1.4.0
|
||||
github.com/fumiama/go-registry v0.1.1
|
||||
github.com/fumiama/go-registry v0.1.3
|
||||
github.com/fumiama/gofastTEA v0.0.10
|
||||
github.com/fumiama/gotracemoe v0.0.3
|
||||
github.com/fumiama/sqlite3 v1.14.6
|
||||
@@ -22,7 +22,7 @@ require (
|
||||
github.com/shirou/gopsutil/v3 v3.22.2
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/tidwall/gjson v1.14.0
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220326160643-893d4e910785
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220330050111-d962c23b4f4d
|
||||
golang.org/x/image v0.0.0-20220321031419-a8550c1d254a
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ require (
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20220326011226-f1430873d8db // indirect
|
||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.12 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
@@ -46,8 +46,8 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
|
||||
golang.org/x/sys v0.0.0-20220325203850-36772127a21f // indirect
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect
|
||||
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
|
||||
29
go.sum
29
go.sum
@@ -1,9 +1,9 @@
|
||||
github.com/FloatTech/AnimeAPI v1.3.2-0.20220326161751-d0d2797b91da h1:KbJujP8k2/3BYRb+F292zLmDOV79uTOu/24n3fhIwRU=
|
||||
github.com/FloatTech/AnimeAPI v1.3.2-0.20220326161751-d0d2797b91da/go.mod h1:aC3EOKpb0R0VOdW9QIQCfqN6ZFymOfvCgzVY1/Fz3Og=
|
||||
github.com/FloatTech/AnimeAPI v1.3.2 h1:5RmNOIi8QSwFjTgB9KxIjdbDdXUCe1+MLe+7R633ero=
|
||||
github.com/FloatTech/AnimeAPI v1.3.2/go.mod h1:IKFBpKHgFAzo6cU4wOaRdb1ywa5mQ4NFc0mJk/wzgyY=
|
||||
github.com/FloatTech/sqlite v0.2.1 h1:9t6Me48XJJCIoPy4nLRvcdhcVKfT0c2lilp7SEKROG8=
|
||||
github.com/FloatTech/sqlite v0.2.1/go.mod h1:6NfHRzqOo9RWeMJEoAQVuo51Omd5LFNxCNQhMF02/9U=
|
||||
github.com/FloatTech/zbputils v1.3.2-0.20220327063325-1389d5a92fff h1:h72B2RgFc4ObczhlS38+seue7/6CLhQBcOAwMe3TBmw=
|
||||
github.com/FloatTech/zbputils v1.3.2-0.20220327063325-1389d5a92fff/go.mod h1:qZlHzG1s1giQrXaosjOAA2utGNaPZjwJsVZfBog2bhg=
|
||||
github.com/FloatTech/zbputils v1.3.2 h1:TxQ6SjT/f+iHLoz+IlQ3Hk2dUb2P9SIs4DvjGWLjZYs=
|
||||
github.com/FloatTech/zbputils v1.3.2/go.mod h1:V2Y8jkxjwACWuJsDCyNVKc+qABfMAUh/mgBYdWBxOPo=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc h1:AAx50/fb/xS4lvsdQg+bFbGvqSDhyV1MF+p2PLCamZ0=
|
||||
github.com/RomiChan/websocket v1.4.3-0.20220123145318-307a86b127bc/go.mod h1:OMmITAib6POA37xCichWM0aRnoVpSMZO1rB/G01wrr0=
|
||||
@@ -33,8 +33,8 @@ 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.4.0 h1:4KrtewnmAChrZjPA7/QYc72t+vvsKF+DYB0q1iRPdpo=
|
||||
github.com/fumiama/go-base16384 v1.4.0/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
|
||||
github.com/fumiama/go-registry v0.1.1 h1:cmCRizjXHFW2ApwUHCXi8wKLJ6Gtt4GrShJlamGPbVI=
|
||||
github.com/fumiama/go-registry v0.1.1/go.mod h1:iJT3DVgH7KXpJZs6waXEjnWtJPUBBGhF+ByJIMRfngk=
|
||||
github.com/fumiama/go-registry v0.1.3 h1:WvUN2wdziB2+LyYs4zNy1FHGQOvZeto7lbADfSqbMPw=
|
||||
github.com/fumiama/go-registry v0.1.3/go.mod h1:iJT3DVgH7KXpJZs6waXEjnWtJPUBBGhF+ByJIMRfngk=
|
||||
github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ=
|
||||
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=
|
||||
github.com/fumiama/gotracemoe v0.0.3 h1:iI5EbE9A3UUbfukG6+/soYPjp1S31eCNYf4tw7s6/Jc=
|
||||
@@ -72,8 +72,9 @@ github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:C
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
|
||||
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
|
||||
github.com/lufia/plan9stats v0.0.0-20220326011226-f1430873d8db h1:m2s7Fwo4OwmcheIWUc/Nw9/MZ0eFtP3to0ovTpqOiCQ=
|
||||
github.com/lufia/plan9stats v0.0.0-20220326011226-f1430873d8db/go.mod h1:VgrrWVwBO2+6XKn8ypT3WUqvoxCa8R2M5to2tRzGovI=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
@@ -122,8 +123,8 @@ github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYa
|
||||
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
|
||||
github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o=
|
||||
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220326160643-893d4e910785 h1:alVsiLOu9H0GCriAkTMqn310izMNEzg9y1Z9FqAV1DY=
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220326160643-893d4e910785/go.mod h1:NwXIp7PgjV+kUALMXJ4v4/3QcsRSOodtjhLekuPXFog=
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220330050111-d962c23b4f4d h1:NGea1vhhGuvv7E6sPeUyPyTxCtCkEVn8ShNniZY9bQA=
|
||||
github.com/wdvxdr1123/ZeroBot v1.4.2-0.20220330050111-d962c23b4f4d/go.mod h1:NwXIp7PgjV+kUALMXJ4v4/3QcsRSOodtjhLekuPXFog=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
@@ -145,8 +146,8 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -168,8 +169,8 @@ golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220325203850-36772127a21f h1:TrmogKRsSOxRMJbLYGrB4SBbW+LJcEllYBLME5Zk5pU=
|
||||
golang.org/x/sys v0.0.0-20220325203850-36772127a21f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY=
|
||||
golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -187,8 +188,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
|
||||
1
main.go
1
main.go
@@ -80,6 +80,7 @@ import (
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/gif" // 制图
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/github" // 搜索GitHub仓库
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hs" // 炉石
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hyaku" // 百人一首
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder" // 关键字搜图
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
|
||||
|
||||
@@ -23,20 +23,7 @@ import (
|
||||
|
||||
const ttsServiceName = "tts"
|
||||
|
||||
var (
|
||||
t = &ttsInstances{
|
||||
m: map[string]tts.TTS{
|
||||
"百度女声": baidutts.NewBaiduTTS(0),
|
||||
"百度男声": baidutts.NewBaiduTTS(1),
|
||||
"百度度逍遥": baidutts.NewBaiduTTS(3),
|
||||
"百度度丫丫": baidutts.NewBaiduTTS(4),
|
||||
"拟声鸟阿梓": mockingbird.NewMockingBirdTTS(0),
|
||||
"拟声鸟药水哥": mockingbird.NewMockingBirdTTS(1),
|
||||
},
|
||||
l: []string{"拟声鸟阿梓", "拟声鸟药水哥", "百度女声", "百度男声", "百度度逍遥", "百度度丫丫"},
|
||||
}
|
||||
re = regexp.MustCompile(`(\-|\+)?\d+(\.\d+)?`)
|
||||
)
|
||||
var re = regexp.MustCompile(`(\-|\+)?\d+(\.\d+)?`)
|
||||
|
||||
type ttsInstances struct {
|
||||
sync.RWMutex
|
||||
@@ -53,6 +40,17 @@ func (t *ttsInstances) List() []string {
|
||||
}
|
||||
|
||||
func init() {
|
||||
t := &ttsInstances{
|
||||
m: map[string]tts.TTS{
|
||||
"百度女声": baidutts.NewBaiduTTS(0),
|
||||
"百度男声": baidutts.NewBaiduTTS(1),
|
||||
"百度度逍遥": baidutts.NewBaiduTTS(3),
|
||||
"百度度丫丫": baidutts.NewBaiduTTS(4),
|
||||
"拟声鸟阿梓": nil,
|
||||
"拟声鸟药水哥": nil,
|
||||
},
|
||||
l: []string{"拟声鸟阿梓", "拟声鸟药水哥", "百度女声", "百度男声", "百度度逍遥", "百度度丫丫"},
|
||||
}
|
||||
engine := control.Register(ttsServiceName, order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: true,
|
||||
Help: "语音回复(包括拟声鸟和百度)\n" +
|
||||
@@ -65,19 +63,21 @@ func init() {
|
||||
msg := ctx.ExtractPlainText()
|
||||
r := aireply.NewAIReply(getReplyMode(ctx))
|
||||
tts := t.new(t.getSoundMode(ctx))
|
||||
ctx.SendChain(message.Record(tts.Speak(ctx.Event.UserID, func() string {
|
||||
reply := r.TalkPlain(msg, zero.BotConfig.NickName[0])
|
||||
reply = re.ReplaceAllStringFunc(reply, func(s string) string {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
log.Errorln("[tts]:", err)
|
||||
return s
|
||||
}
|
||||
return numcn.EncodeFromFloat64(f)
|
||||
})
|
||||
log.Println("[tts]:", reply)
|
||||
return reply
|
||||
})))
|
||||
if tts != nil {
|
||||
ctx.SendChain(message.Record(tts.Speak(ctx.Event.UserID, func() string {
|
||||
reply := r.TalkPlain(msg, zero.BotConfig.NickName[0])
|
||||
reply = re.ReplaceAllStringFunc(reply, func(s string) string {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
log.Errorln("[tts]:", err)
|
||||
return s
|
||||
}
|
||||
return numcn.EncodeFromFloat64(f)
|
||||
})
|
||||
log.Println("[tts]:", reply)
|
||||
return reply
|
||||
})))
|
||||
}
|
||||
})
|
||||
engine.OnRegex(`^设置语音模式(.*)$`, ctxext.FirstValueInList(t)).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
@@ -98,8 +98,23 @@ func init() {
|
||||
}
|
||||
|
||||
// new 语音简单工厂
|
||||
func (t *ttsInstances) new(name string) tts.TTS {
|
||||
return t.m[name]
|
||||
func (t *ttsInstances) new(name string) (ts tts.TTS) {
|
||||
t.RLock()
|
||||
ts = t.m[name]
|
||||
t.RUnlock()
|
||||
if ts == nil {
|
||||
switch name {
|
||||
case "拟声鸟阿梓":
|
||||
t.Lock()
|
||||
ts, _ = mockingbird.NewMockingBirdTTS(0)
|
||||
t.Unlock()
|
||||
case "拟声鸟药水哥":
|
||||
t.Lock()
|
||||
ts, _ = mockingbird.NewMockingBirdTTS(1)
|
||||
t.Unlock()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *ttsInstances) setSoundMode(ctx *zero.Ctx, name string) error {
|
||||
|
||||
180
plugin/bilibili/api.go
Normal file
180
plugin/bilibili/api.go
Normal file
@@ -0,0 +1,180 @@
|
||||
package bilibili
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/FloatTech/zbputils/binary"
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
var (
|
||||
errNeedCookie = errors.New("该api需要设置b站cookie,请发送命令设置cookie,例如\"设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\"")
|
||||
)
|
||||
|
||||
type searchResult struct {
|
||||
Mid int64 `json:"mid"`
|
||||
Uname string `json:"uname"`
|
||||
Gender int64 `json:"gender"`
|
||||
Usign string `json:"usign"`
|
||||
Level int64 `json:"level"`
|
||||
}
|
||||
|
||||
// 搜索api:通过把触发指令传入的昵称找出uid返回
|
||||
func search(keyword string) (r []searchResult, err error) {
|
||||
searchURL := "http://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&keyword=" + keyword
|
||||
data, err := web.GetData(searchURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
j := gjson.ParseBytes(data)
|
||||
if j.Get("data.numResults").Int() == 0 {
|
||||
err = errors.New("查无此人")
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(binary.StringToBytes(j.Get("data.result").Raw), &r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type follower struct {
|
||||
Mid int `json:"mid"`
|
||||
Uname string `json:"uname"`
|
||||
Video int `json:"video"`
|
||||
Roomid int `json:"roomid"`
|
||||
Rise int `json:"rise"`
|
||||
Follower int `json:"follower"`
|
||||
GuardNum int `json:"guardNum"`
|
||||
AreaRank int `json:"areaRank"`
|
||||
}
|
||||
|
||||
// 请求api
|
||||
func fansapi(uid string) (result follower, err error) {
|
||||
fanURL := "https://api.vtbs.moe/v1/detail/" + uid
|
||||
data, err := web.GetData(fanURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if err = json.Unmarshal(data, &result); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func followings(uid string) (s string, err error) {
|
||||
followingURL := "https://api.bilibili.com/x/relation/same/followings?vmid=" + uid
|
||||
method := "GET"
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(method, followingURL, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c := vdb.getBilibiliCookie()
|
||||
req.Header.Add("cookie", c.Value)
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
json := gjson.ParseBytes(body)
|
||||
s = json.Get("data.list.#.uname").Raw
|
||||
if json.Get("code").Int() == -101 {
|
||||
err = errNeedCookie
|
||||
return
|
||||
}
|
||||
if json.Get("code").Int() != 0 {
|
||||
err = errors.New(json.Get("message").String())
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type userinfo struct {
|
||||
Name string `json:"name"`
|
||||
Mid string `json:"mid"`
|
||||
Face string `json:"face"`
|
||||
Fans int64 `json:"fans"`
|
||||
Attentions []int64 `json:"attentions"`
|
||||
}
|
||||
|
||||
type medalInfo struct {
|
||||
Mid int64 `json:"target_id"`
|
||||
MedalName string `json:"medal_name"`
|
||||
Level int64 `json:"level"`
|
||||
MedalColorStart int64 `json:"medal_color_start"`
|
||||
MedalColorEnd int64 `json:"medal_color_end"`
|
||||
MedalColorBorder int64 `json:"medal_color_border"`
|
||||
}
|
||||
type medal struct {
|
||||
Uname string `json:"target_name"`
|
||||
medalInfo `json:"medal_info"`
|
||||
}
|
||||
|
||||
type medalSlice []medal
|
||||
|
||||
func (m medalSlice) Len() int {
|
||||
return len(m)
|
||||
}
|
||||
func (m medalSlice) Swap(i, j int) {
|
||||
m[i], m[j] = m[j], m[i]
|
||||
}
|
||||
func (m medalSlice) Less(i, j int) bool {
|
||||
return m[i].Level > m[j].Level
|
||||
}
|
||||
|
||||
// 获取详情
|
||||
func card(uid string) (result userinfo, err error) {
|
||||
cardURL := "https://account.bilibili.com/api/member/getCardByMid?mid=" + uid
|
||||
data, err := web.GetData(cardURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(binary.StringToBytes(gjson.ParseBytes(data).Get("card").Raw), &result)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 获得牌子
|
||||
func medalwall(uid string) (result []medal, err error) {
|
||||
medalwallURL := "https://api.live.bilibili.com/xlive/web-ucenter/user/MedalWall?target_id=" + uid
|
||||
method := "GET"
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(method, medalwallURL, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
c := vdb.getBilibiliCookie()
|
||||
req.Header.Add("cookie", c.Value)
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
data, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fmt.Println("medalwall:", binary.BytesToString(data))
|
||||
j := gjson.ParseBytes(data)
|
||||
if j.Get("code").Int() == -101 {
|
||||
err = errNeedCookie
|
||||
return
|
||||
}
|
||||
if j.Get("code").Int() != 0 {
|
||||
err = errors.New(j.Get("message").String())
|
||||
}
|
||||
_ = json.Unmarshal(binary.StringToBytes(j.Get("data.list").Raw), &result)
|
||||
return
|
||||
}
|
||||
@@ -2,64 +2,290 @@
|
||||
package bilibili
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"image/color"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
control "github.com/FloatTech/zbputils/control"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/FloatTech/zbputils/control/order"
|
||||
"github.com/FloatTech/zbputils/file"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
"github.com/FloatTech/zbputils/img/writer"
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
"github.com/fogleman/gg"
|
||||
log "github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
"github.com/FloatTech/zbputils/control/order"
|
||||
)
|
||||
|
||||
var engine = control.Register("bilibili", order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: false,
|
||||
Help: "bilibili\n" +
|
||||
"- >vup info [名字 | uid]\n" +
|
||||
"- >user info [名字 | uid]",
|
||||
"- >vup info [xxx]\n" +
|
||||
"- >user info [xxx]\n" +
|
||||
"- 查成分 [xxx]\n" +
|
||||
"- 设置b站cookie SESSDATA=82da790d,1663822823,06ecf*31\n" +
|
||||
"- 更新vup",
|
||||
PublicDataFolder: "Bilibili",
|
||||
})
|
||||
|
||||
// 查成分的
|
||||
func init() {
|
||||
engine.OnRegex(`^>(?:user|vup)\s?info\s?(.{1,25})$`).SetBlock(true).
|
||||
cachePath := engine.DataFolder() + "cache/"
|
||||
dbfile := engine.DataFolder() + "bilibili.db"
|
||||
go func() {
|
||||
_ = os.MkdirAll(cachePath, 0755)
|
||||
_, _ = file.GetLazyData(dbfile, false, false)
|
||||
vdb = initialize(dbfile)
|
||||
}()
|
||||
|
||||
engine.OnRegex(`^>user info\s?(.{1,25})$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
||||
rest, err := uid(keyword)
|
||||
uidRes, err := search(keyword)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
id := rest.Get("data.result.0.mid").String()
|
||||
url := "https://api.bilibili.com/x/relation/same/followings?vmid=" + id
|
||||
method := "GET"
|
||||
client := &http.Client{}
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
id := strconv.FormatInt(uidRes[0].Mid, 10)
|
||||
follwings, err := followings(id)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
req.Header.Add("cookie", "CURRENT_FNVAL=80; _uuid=772B88E8-3ED1-D589-29BB-F6CB5214239A06137infoc; blackside_state=1; bfe_id=6f285c892d9d3c1f8f020adad8bed553; rpdid=|(umY~Jkl|kJ0J'uYkR|)lu|); fingerprint=0ec2b1140fb30b56d7b5e415bc3b5fb1; buvid_fp=C91F5265-3DF4-4D5A-9FF3-C546370B14C0143096infoc; buvid_fp_plain=C91F5265-3DF4-4D5A-9FF3-C546370B14C0143096infoc; SESSDATA=9e0266f6%2C1639637127%2Cb0172%2A61; bili_jct=96ddbd7e22d527abdc0501339a12d4d3; DedeUserID=695737880; DedeUserID__ckMd5=0117660e75db7b01; sid=5labuhaf; PVID=1; bfe_id=1e33d9ad1cb29251013800c68af42315")
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
data := string(body)
|
||||
ctx.SendChain(message.Text(
|
||||
"uid: ", rest.Get("data.result.0.mid").Int(), "\n",
|
||||
"name: ", rest.Get("data.result.0.uname").Str, "\n",
|
||||
"sex: ", []string{"", "", "女", "男"}[rest.Get("data.result.0.gender").Int()], "\n",
|
||||
"sign: ", rest.Get("data.result.0.usign").Str, "\n",
|
||||
"level: ", rest.Get("data.result.0.level").Int(), "\n",
|
||||
"follow: ", gjson.Get(data, "data.list.#.uname"),
|
||||
"search: ", uidRes[0].Mid, "\n",
|
||||
"name: ", uidRes[0].Uname, "\n",
|
||||
"sex: ", []string{"", "男", "女", "未知"}[uidRes[0].Gender], "\n",
|
||||
"sign: ", uidRes[0].Usign, "\n",
|
||||
"level: ", uidRes[0].Level, "\n",
|
||||
"follow: ", follwings,
|
||||
))
|
||||
})
|
||||
|
||||
engine.OnRegex(`^>vup info\s?(.{1,25})$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
||||
res, err := search(keyword)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
id := strconv.FormatInt(res[0].Mid, 10)
|
||||
// 获取详情
|
||||
fo, err := fansapi(id)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text(
|
||||
"search: ", fo.Mid, "\n",
|
||||
"名字: ", fo.Uname, "\n",
|
||||
"当前粉丝数: ", fo.Follower, "\n",
|
||||
"24h涨粉数: ", fo.Rise, "\n",
|
||||
"视频投稿数: ", fo.Video, "\n",
|
||||
"直播间id: ", fo.Roomid, "\n",
|
||||
"舰队: ", fo.GuardNum, "\n",
|
||||
"直播总排名: ", fo.AreaRank, "\n",
|
||||
"数据来源: ", "https://vtbs.moe/detail/", fo.Mid, "\n",
|
||||
"数据获取时间: ", time.Now().Format("2006-01-02 15:04:05"),
|
||||
))
|
||||
})
|
||||
|
||||
engine.OnRegex(`^查成分\s?(.{1,25})$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
||||
searchRes, err := search(keyword)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
id := strconv.FormatInt(searchRes[0].Mid, 10)
|
||||
today := time.Now().Format("20060102")
|
||||
drawedFile := cachePath + id + today + "vupLike.png"
|
||||
if file.IsExist(drawedFile) {
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
return
|
||||
}
|
||||
u, err := card(id)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
vups, err := vdb.filterVup(u.Attentions)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
vupLen := len(vups)
|
||||
medals, err := medalwall(id)
|
||||
sort.Sort(medalSlice(medals))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
}
|
||||
frontVups := make([]vup, 0)
|
||||
medalMap := make(map[int64]medal)
|
||||
for _, v := range medals {
|
||||
up := vup{
|
||||
Mid: v.Mid,
|
||||
Uname: v.Uname,
|
||||
}
|
||||
frontVups = append(frontVups, up)
|
||||
medalMap[v.Mid] = v
|
||||
}
|
||||
vups = append(vups, frontVups...)
|
||||
copy(vups[len(frontVups):], vups)
|
||||
copy(vups, frontVups)
|
||||
for i := len(frontVups); i < len(vups); i++ {
|
||||
if _, ok := medalMap[vups[i].Mid]; ok {
|
||||
vups = append(vups[:i], vups[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
facePath := cachePath + id + "vupFace.png"
|
||||
initFacePic(facePath, u.Face)
|
||||
var backX int
|
||||
var backY int
|
||||
back, err := gg.LoadImage(facePath)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
backX = 500
|
||||
backY = 500
|
||||
} else {
|
||||
back = img.Limit(back, 500, 500)
|
||||
backX = back.Bounds().Size().X
|
||||
backY = back.Bounds().Size().Y
|
||||
}
|
||||
if len(vups) > 50 {
|
||||
ctx.SendChain(message.Text(u.Name + "关注的up主太多了,只展示前50个up"))
|
||||
vups = vups[:50]
|
||||
}
|
||||
canvas := gg.NewContext(backX*3, int(float64(backY)*(1.1+float64(len(vups))/3)))
|
||||
fontSize := float64(backX) * 0.1
|
||||
canvas.SetColor(color.White)
|
||||
canvas.Clear()
|
||||
if back != nil {
|
||||
canvas.DrawImage(back, 0, 0)
|
||||
}
|
||||
canvas.SetColor(color.Black)
|
||||
if err = canvas.LoadFontFace(text.BoldFontFile, fontSize); err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
sl, _ := canvas.MeasureString("好")
|
||||
length, h := canvas.MeasureString(u.Mid)
|
||||
n, _ := canvas.MeasureString(u.Name)
|
||||
canvas.DrawString(u.Name, float64(backX)*1.1, float64(backY)/3-h)
|
||||
canvas.DrawRoundedRectangle(float64(backX)*1.2+n-length*0.1, float64(backY)/3-h*2.5, length*1.2, h*2, fontSize*0.2)
|
||||
canvas.SetRGB255(221, 221, 221)
|
||||
canvas.Fill()
|
||||
canvas.SetColor(color.Black)
|
||||
canvas.DrawString(u.Mid, float64(backX)*1.2+n, float64(backY)/3-h)
|
||||
canvas.DrawString(fmt.Sprintf("粉丝:%d", u.Fans), float64(backX)*1.1, float64(backY)/3*2-2.5*h)
|
||||
canvas.DrawString(fmt.Sprintf("关注:%d", len(u.Attentions)), float64(backX)*2, float64(backY)/3*2-2.5*h)
|
||||
canvas.DrawString(fmt.Sprintf("管人痴成分:%.2f%%(%d/%d)", float64(vupLen)/float64(len(u.Attentions))*100, vupLen, len(u.Attentions)), float64(backX)*1.1, float64(backY)-4*h)
|
||||
canvas.DrawString("日期:"+time.Now().Format("2006-01-02"), float64(backX)*1.1, float64(backY)-h)
|
||||
for i, v := range vups {
|
||||
if i%2 == 1 {
|
||||
canvas.SetRGB255(245, 245, 245)
|
||||
canvas.DrawRectangle(0, float64(backY)*1.1+float64(i)*float64(backY)/3, float64(backX*3), float64(backY)/3)
|
||||
canvas.Fill()
|
||||
}
|
||||
canvas.SetColor(color.Black)
|
||||
nl, _ := canvas.MeasureString(v.Uname)
|
||||
canvas.DrawString(v.Uname, float64(backX)*0.1, float64(backY)*1.1+float64(i+1)*float64(backY)/3-2*h)
|
||||
ml, _ := canvas.MeasureString(strconv.FormatInt(v.Mid, 10))
|
||||
canvas.DrawRoundedRectangle(nl-0.1*ml+float64(backX)*0.2, float64(backY)*1.1+float64(i+1)*float64(backY)/3-h*3.5, ml*1.2, h*2, fontSize*0.2)
|
||||
canvas.SetRGB255(221, 221, 221)
|
||||
canvas.Fill()
|
||||
canvas.SetColor(color.Black)
|
||||
canvas.DrawString(strconv.FormatInt(v.Mid, 10), nl+float64(backX)*0.2, float64(backY)*1.1+float64(i+1)*float64(backY)/3-2*h)
|
||||
if m, ok := medalMap[v.Mid]; ok {
|
||||
mnl, _ := canvas.MeasureString(m.MedalName)
|
||||
grad := gg.NewLinearGradient(nl+ml-sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-3.5*h, nl+ml+mnl+sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-1.5*h)
|
||||
r, g, b := int2rbg(m.MedalColorStart)
|
||||
grad.AddColorStop(0, color.RGBA{uint8(r), uint8(g), uint8(b), 255})
|
||||
r, g, b = int2rbg(m.MedalColorEnd)
|
||||
grad.AddColorStop(1, color.RGBA{uint8(r), uint8(g), uint8(b), 255})
|
||||
canvas.SetFillStyle(grad)
|
||||
canvas.SetLineWidth(4)
|
||||
canvas.MoveTo(nl+ml-sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-3.5*h)
|
||||
canvas.LineTo(nl+ml+mnl+sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-3.5*h)
|
||||
canvas.LineTo(nl+ml+mnl+sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-1.5*h)
|
||||
canvas.LineTo(nl+ml-sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-1.5*h)
|
||||
canvas.ClosePath()
|
||||
canvas.Fill()
|
||||
canvas.SetColor(color.White)
|
||||
canvas.DrawString(m.MedalName, nl+ml+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-2*h)
|
||||
r, g, b = int2rbg(m.MedalColorBorder)
|
||||
canvas.SetRGB255(int(r), int(g), int(b))
|
||||
canvas.DrawString(strconv.FormatInt(m.Level, 10), nl+ml+mnl+sl+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-2*h)
|
||||
mll, _ := canvas.MeasureString(strconv.FormatInt(m.Level, 10))
|
||||
canvas.SetLineWidth(4)
|
||||
canvas.MoveTo(nl+ml-sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-3.5*h)
|
||||
canvas.LineTo(nl+ml+mnl+mll+sl/2+float64(backX)*0.5, float64(backY)*1.1+float64(i+1)*float64(backY)/3-3.5*h)
|
||||
canvas.LineTo(nl+ml+mnl+mll+sl/2+float64(backX)*0.5, float64(backY)*1.1+float64(i+1)*float64(backY)/3-1.5*h)
|
||||
canvas.LineTo(nl+ml-sl/2+float64(backX)*0.4, float64(backY)*1.1+float64(i+1)*float64(backY)/3-1.5*h)
|
||||
canvas.ClosePath()
|
||||
canvas.Stroke()
|
||||
}
|
||||
}
|
||||
f, err := os.Create(drawedFile)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibili]", err)
|
||||
data, cl := writer.ToBytes(canvas.Image())
|
||||
ctx.SendChain(message.ImageBytes(data))
|
||||
cl()
|
||||
return
|
||||
}
|
||||
_, err = writer.WriteTo(canvas.Image(), f)
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
})
|
||||
|
||||
engine.OnRegex(`^设置b站cookie?\s+(.{1,100})$`, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
cookie := ctx.State["regex_matched"].([]string)[1]
|
||||
err := vdb.setBilibiliCookie(cookie)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功设置b站cookie为" + cookie))
|
||||
})
|
||||
|
||||
engine.OnFullMatch("更新vup", zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text("少女祈祷中..."))
|
||||
updateVup()
|
||||
ctx.SendChain(message.Text("vup已更新"))
|
||||
})
|
||||
}
|
||||
|
||||
func initFacePic(filename, faceURL string) {
|
||||
if file.IsNotExist(filename) {
|
||||
data, err := web.GetData(faceURL)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibili]", err)
|
||||
}
|
||||
err = os.WriteFile(filename, data, 0666)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibili]", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func int2rbg(t int64) (int64, int64, int64) {
|
||||
var buf [8]byte
|
||||
binary.LittleEndian.PutUint64(buf[:], uint64(t))
|
||||
b, g, r := int64(buf[0]), int64(buf[1]), int64(buf[2])
|
||||
return r, g, b
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
package bilibili
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
"github.com/tidwall/gjson"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
// 查vup粉丝数据
|
||||
func init() {
|
||||
engine.OnRegex(`^>vup info\s?(.{1,25})$`).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
keyword := ctx.State["regex_matched"].([]string)[1]
|
||||
res, err := uid(keyword)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
id := res.Get("data.result.0.mid").String()
|
||||
// 获取详情
|
||||
fo, err := fansapi(id)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text(
|
||||
"uid: ", fo.Mid, "\n",
|
||||
"名字: ", fo.Uname, "\n",
|
||||
"当前粉丝数: ", fo.Follower, "\n",
|
||||
"24h涨粉数: ", fo.Rise, "\n",
|
||||
"视频投稿数: ", fo.Video, "\n",
|
||||
"直播间id: ", fo.Roomid, "\n",
|
||||
"舰队: ", fo.GuardNum, "\n",
|
||||
"直播总排名: ", fo.AreaRank, "\n",
|
||||
"数据来源: ", "https://vtbs.moe/detail/", fo.Mid, "\n",
|
||||
"数据获取时间: ", time.Now().Format("2006-01-02 15:04:05"),
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
// 搜索api:通过把触发指令传入的昵称找出uid返回
|
||||
func uid(keyword string) (*gjson.Result, error) {
|
||||
api := "http://api.bilibili.com/x/web-interface/search/type?search_type=bili_user&&user_type=1&keyword=" + keyword
|
||||
data, err := web.GetData(api)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
json := gjson.ParseBytes(data)
|
||||
if json.Get("data.numResults").Int() == 0 {
|
||||
return nil, errors.New("查无此人")
|
||||
}
|
||||
return &json, nil
|
||||
}
|
||||
|
||||
type follower struct {
|
||||
Mid int `json:"mid"`
|
||||
Uname string `json:"uname"`
|
||||
Video int `json:"video"`
|
||||
Roomid int `json:"roomid"`
|
||||
Rise int `json:"rise"`
|
||||
Follower int `json:"follower"`
|
||||
GuardNum int `json:"guardNum"`
|
||||
AreaRank int `json:"areaRank"`
|
||||
}
|
||||
|
||||
// 请求api
|
||||
func fansapi(uid string) (*follower, error) {
|
||||
url := "https://api.vtbs.moe/v1/detail/" + uid
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
result := &follower{}
|
||||
if err := json.NewDecoder(resp.Body).Decode(result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
130
plugin/bilibili/model.go
Normal file
130
plugin/bilibili/model.go
Normal file
@@ -0,0 +1,130 @@
|
||||
package bilibili
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/FloatTech/zbputils/binary"
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
_ "github.com/fumiama/sqlite3" // use sql
|
||||
"github.com/jinzhu/gorm"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
const (
|
||||
bilibiliCookie = "bilbili_cookie"
|
||||
)
|
||||
|
||||
var (
|
||||
vtbURLs = [...]string{"https://api.vtbs.moe/v1/short", "https://api.tokyo.vtbs.moe/v1/short", "https://vtbs.musedash.moe/v1/short"}
|
||||
vdb *vupdb
|
||||
)
|
||||
|
||||
// vupdb 分数数据库
|
||||
type vupdb gorm.DB
|
||||
|
||||
type vup struct {
|
||||
Mid int64 `gorm:"column:mid;primary_key"`
|
||||
Uname string `gorm:"column:uname"`
|
||||
Roomid int64 `gorm:"column:roomid"`
|
||||
}
|
||||
|
||||
func (vup) TableName() string {
|
||||
return "vup"
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Key string `gorm:"column:key;primary_key"`
|
||||
Value string `gorm:"column:value"`
|
||||
}
|
||||
|
||||
func (config) TableName() string {
|
||||
return "config"
|
||||
}
|
||||
|
||||
// initialize 初始化vtb数据库
|
||||
func initialize(dbpath string) *vupdb {
|
||||
if _, err := os.Stat(dbpath); err != nil || os.IsNotExist(err) {
|
||||
// 生成文件
|
||||
f, err := os.Create(dbpath)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer f.Close()
|
||||
}
|
||||
gdb, err := gorm.Open("sqlite3", dbpath)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
gdb.Debug().AutoMigrate(&vup{}).AutoMigrate(&config{})
|
||||
return (*vupdb)(gdb)
|
||||
}
|
||||
|
||||
func (vdb *vupdb) insertVupByMid(mid int64, uname string, roomid int64) (err error) {
|
||||
db := (*gorm.DB)(vdb)
|
||||
v := vup{
|
||||
Mid: mid,
|
||||
Uname: uname,
|
||||
Roomid: roomid,
|
||||
}
|
||||
if err = db.Debug().Model(&vup{}).First(&v, "mid = ? ", mid).Error; err != nil {
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
err = db.Debug().Model(&vup{}).Create(&v).Error
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// filterVup 筛选vup
|
||||
func (vdb *vupdb) filterVup(ids []int64) (vups []vup, err error) {
|
||||
db := (*gorm.DB)(vdb)
|
||||
if err = db.Debug().Model(&vup{}).Find(&vups, "mid in (?)", ids).Error; err != nil {
|
||||
return vups, err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func updateVup() {
|
||||
for _, v := range vtbURLs {
|
||||
data, err := web.GetData(v)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibili]:", err)
|
||||
}
|
||||
gjson.Get(binary.BytesToString(data), "@this").ForEach(func(key, value gjson.Result) bool {
|
||||
mid := value.Get("mid").Int()
|
||||
uname := value.Get("uname").String()
|
||||
roomid := value.Get("roomid").Int()
|
||||
err = vdb.insertVupByMid(mid, uname, roomid)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibili]:", err)
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (vdb *vupdb) setBilibiliCookie(cookie string) (err error) {
|
||||
db := (*gorm.DB)(vdb)
|
||||
c := config{
|
||||
Key: bilibiliCookie,
|
||||
Value: cookie,
|
||||
}
|
||||
if err = db.Debug().Model(&config{}).First(&c, "key = ? ", bilibiliCookie).Error; err != nil {
|
||||
// error handling...
|
||||
if gorm.IsRecordNotFoundError(err) {
|
||||
err = db.Debug().Model(&config{}).Create(&c).Error
|
||||
}
|
||||
} else {
|
||||
err = db.Debug().Model(&config{}).Where("key = ? ", bilibiliCookie).Update(
|
||||
map[string]interface{}{
|
||||
"value": cookie,
|
||||
}).Error
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (vdb *vupdb) getBilibiliCookie() (c config) {
|
||||
db := (*gorm.DB)(vdb)
|
||||
db.Debug().Model(&config{}).First(&c, "key = ?", bilibiliCookie)
|
||||
return
|
||||
}
|
||||
@@ -5,8 +5,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -300,20 +298,7 @@ func getLiveList(uids ...int64) string {
|
||||
m := make(map[string]interface{})
|
||||
m["uids"] = uids
|
||||
b, _ := json.Marshal(m)
|
||||
client := &http.Client{}
|
||||
// 提交请求
|
||||
request, err := http.NewRequest("POST", liveListURL, bytes.NewBuffer(b))
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
request.Header.Add("Referer", referer)
|
||||
request.Header.Add("User-Agent", ua)
|
||||
response, err := client.Do(request)
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
defer response.Body.Close()
|
||||
data, err := io.ReadAll(response.Body)
|
||||
data, err := web.PostData(liveListURL, "application/json", bytes.NewReader(b))
|
||||
if err != nil {
|
||||
log.Errorln("[bilibilipush]:", err)
|
||||
}
|
||||
|
||||
@@ -3,106 +3,87 @@ package diana
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/zbputils/binary"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/FloatTech/zbputils/web"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
)
|
||||
|
||||
type zhiwang struct {
|
||||
Code int `json:"code"`
|
||||
Data struct {
|
||||
EndTime int `json:"end_time"`
|
||||
Rate float64 `json:"rate"`
|
||||
Related [][]interface{} `json:"related"`
|
||||
StartTime int `json:"start_time"`
|
||||
} `json:"data"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// 小作文查重: 回复要查的消息 查重
|
||||
func init() {
|
||||
engine.OnMessage(fullmatch("查重")).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
msg := ctx.Event.Message
|
||||
if msg[0].Type == "reply" {
|
||||
msg := ctx.GetMessage(message.NewMessageID(msg[0].Data["id"])).Elements[0].Data["text"]
|
||||
zhiwangjson := zhiwangapi(msg)
|
||||
|
||||
if zhiwangjson == nil || zhiwangjson.Code != 0 {
|
||||
ctx.SendChain(message.Text("api返回错误"))
|
||||
return
|
||||
}
|
||||
|
||||
if len(zhiwangjson.Data.Related) == 0 {
|
||||
ctx.SendChain(message.Text("枝网没搜到,查重率为0%,我的评价是:一眼真"))
|
||||
return
|
||||
}
|
||||
|
||||
related := zhiwangjson.Data.Related[0][1].(map[string]interface{})
|
||||
ctx.SendChain(message.Text(
|
||||
"枝网文本复制检测报告(简洁)", "\n",
|
||||
"查重时间: ", time.Now().Format("2006-01-02 15:04:05"), "\n",
|
||||
"总文字复制比: ", math.Floor(zhiwangjson.Data.Rate*100), "%", "\n",
|
||||
"相似小作文:", "\n",
|
||||
related["content"].(string)[:102]+".....", "\n",
|
||||
"获赞数", related["like_num"], "\n",
|
||||
zhiwangjson.Data.Related[0][2].(string), "\n",
|
||||
"作者: ", related["m_name"], "\n",
|
||||
"发表时间: ", time.Unix(int64(related["ctime"].(float64)), 0).Format("2006-01-02 15:04:05"), "\n",
|
||||
"查重结果仅作参考,请注意辨别是否为原创", "\n",
|
||||
"数据来源: https://asoulcnki.asia/",
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 发起api请求并把返回body交由json库解析
|
||||
func zhiwangapi(text string) *zhiwang {
|
||||
url := "https://asoulcnki.asia/v1/api/check"
|
||||
post := "{\n\"text\":\"" + text + "\"\n}"
|
||||
var jsonStr = []byte(post)
|
||||
|
||||
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStr))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := &http.Client{}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
result := &zhiwang{}
|
||||
if err1 := json.NewDecoder(resp.Body).Decode(result); err1 != nil {
|
||||
return nil
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func fullmatch(src ...string) zero.Rule {
|
||||
return func(ctx *zero.Ctx) bool {
|
||||
engine.OnMessage(func(ctx *zero.Ctx) bool {
|
||||
msg := ctx.Event.Message
|
||||
if msg[0].Type != "reply" {
|
||||
return false
|
||||
}
|
||||
for _, elem := range msg {
|
||||
if elem.Type == "text" {
|
||||
text := elem.Data["text"]
|
||||
text = strings.ReplaceAll(text, " ", "")
|
||||
text = strings.ReplaceAll(text, "\r", "")
|
||||
text = strings.ReplaceAll(text, "\n", "")
|
||||
for _, s := range src {
|
||||
if text == s {
|
||||
return true
|
||||
}
|
||||
if text == "查重" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
msg := ctx.GetMessage(message.NewMessageID(ctx.Event.Message[0].Data["id"])).Elements[0].Data["text"]
|
||||
result, err := zhiwangapi(msg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
if result.Get("code").Int() != 0 {
|
||||
ctx.SendChain(message.Text("api返回错误:", result.Get("code").Int()))
|
||||
return
|
||||
}
|
||||
if result.Get("data.related.#").Int() == 0 {
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("枝网没搜到,查重率为0%,鉴定为原创")))
|
||||
return
|
||||
}
|
||||
related := result.Get("data.related.0.reply").Map()
|
||||
rate := result.Get("data.related.0.rate").Float()
|
||||
relatedcontent := related["content"].String()
|
||||
if len(relatedcontent) > 102 {
|
||||
relatedcontent = relatedcontent[:102] + "....."
|
||||
}
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(
|
||||
"枝网文本复制检测报告(简洁)", "\n",
|
||||
"查重时间: ", time.Now().Format("2006-01-02 15:04:05"), "\n",
|
||||
"总文字复制比: ", math.Floor(rate*100), "%", "\n",
|
||||
"相似小作文:", "\n", relatedcontent, "\n",
|
||||
"获赞数:", related["like_num"].String(), "\n",
|
||||
result.Get("data.related.0.reply_url").String(), "\n",
|
||||
"作者: ", related["m_name"].String(), "\n",
|
||||
"发表时间: ", time.Unix(int64(related["ctime"].Float()), 0).Format("2006-01-02 15:04:05"), "\n",
|
||||
"查重结果仅作参考,请注意辨别是否为原创", "\n",
|
||||
"数据来源: https://asoulcnki.asia/",
|
||||
)))
|
||||
})
|
||||
}
|
||||
|
||||
func zhiwangapi(text string) (*gjson.Result, error) {
|
||||
b, cl := binary.OpenWriterF(func(w *binary.Writer) {
|
||||
w.WriteString("{\n\"text\":\"")
|
||||
w.WriteString(text)
|
||||
w.WriteString("\"\n}")
|
||||
})
|
||||
|
||||
data, err := web.PostData("https://asoulcnki.asia/v1/api/check", "application/json", bytes.NewReader(b))
|
||||
cl()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := gjson.ParseBytes(data)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -58,15 +58,15 @@ func init() {
|
||||
"- 设置底图[车万 | DC4 | 爱因斯坦 | 星空列车 | 樱云之恋 | 富婆妹 | 李清歌 | 公主连结 | 原神 | 明日方舟 | 碧蓝航线 | 碧蓝幻想 | 战双 | 阴阳师 | 赛马娘 | 东方归言录]",
|
||||
PublicDataFolder: "Fortune",
|
||||
})
|
||||
_ = os.RemoveAll(cache)
|
||||
err := os.MkdirAll(cache, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
for i, s := range table {
|
||||
index[s] = uint8(i)
|
||||
}
|
||||
_ = os.RemoveAll(cache)
|
||||
err := os.MkdirAll(cache, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data, err := file.GetLazyData(omikujson, true, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -75,7 +75,9 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = file.GetLazyData(font, false, true)
|
||||
}()
|
||||
go func() {
|
||||
_, err := file.GetLazyData(font, false, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
122
plugin/hyaku/main.go
Normal file
122
plugin/hyaku/main.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package hyaku
|
||||
|
||||
import (
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
||||
"github.com/FloatTech/zbputils/binary"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/control/order"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/FloatTech/zbputils/file"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
const bed = "https://gitcode.net/u011570312/OguraHyakuninIsshu/-/raw/master/"
|
||||
|
||||
//nolint: asciicheck
|
||||
type line struct {
|
||||
番号, 歌人, 上の句, 下の句, 上の句ひらがな, 下の句ひらがな string
|
||||
}
|
||||
|
||||
func (l *line) String() string {
|
||||
b := binary.NewWriterF(func(w *binary.Writer) {
|
||||
r := reflect.ValueOf(l).Elem().Type()
|
||||
for i := 0; i < r.NumField(); i++ {
|
||||
switch i {
|
||||
case 0:
|
||||
w.WriteString("●")
|
||||
case 1:
|
||||
w.WriteString("◉")
|
||||
case 2, 3:
|
||||
w.WriteString("○")
|
||||
case 4, 5:
|
||||
w.WriteString("◎")
|
||||
}
|
||||
w.WriteString(r.Field(i).Name)
|
||||
w.WriteString(":")
|
||||
w.WriteString((*[6]string)(unsafe.Pointer(l))[i])
|
||||
w.WriteString("\n")
|
||||
}
|
||||
})
|
||||
return binary.BytesToString(b)
|
||||
}
|
||||
|
||||
var lines [100]*line
|
||||
|
||||
func init() {
|
||||
engine := control.Register("hyaku", order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: false,
|
||||
Help: "百人一首\n" +
|
||||
"- 百人一首(随机发一首)\n" +
|
||||
"- 百人一首之n",
|
||||
PrivateDataFolder: "hyaku",
|
||||
})
|
||||
csvfile := engine.DataFolder() + "hyaku.csv"
|
||||
go func() {
|
||||
if file.IsNotExist(csvfile) {
|
||||
err := file.DownloadTo(bed+"小倉百人一首.csv", csvfile, true)
|
||||
if err != nil {
|
||||
_ = os.Remove(csvfile)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
f, err := os.Open(csvfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
records, err := csv.NewReader(f).ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = f.Close()
|
||||
records = records[1:] // skip title
|
||||
if len(records) != 100 {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
for j, r := range records {
|
||||
if len(r) != 6 {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
i, err := strconv.Atoi(r[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
i--
|
||||
if j != i {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
lines[i] = (*line)(*(*unsafe.Pointer)(unsafe.Pointer(&r)))
|
||||
}
|
||||
}()
|
||||
engine.OnFullMatch("百人一首").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
i := rand.Intn(100)
|
||||
ctx.SendChain(
|
||||
message.Image(fmt.Sprintf(bed+"img/%03d.jpg", i+1)),
|
||||
message.Text("\n", lines[i]),
|
||||
message.Image(fmt.Sprintf(bed+"img/%03d.png", i+1)),
|
||||
)
|
||||
})
|
||||
engine.OnRegex(`^百人一首之\s?(\d+)$`).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
i, err := strconv.Atoi(ctx.State["regex_matched"].([]string)[1])
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
if i > 100 || i < 1 {
|
||||
ctx.SendChain(message.Text("ERROR:超出范围"))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(
|
||||
message.Image(fmt.Sprintf(bed+"img/%03d.jpg", i)),
|
||||
message.Text("\n", lines[i-1]),
|
||||
message.Image(fmt.Sprintf(bed+"img/%03d.png", i)),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
"github.com/FloatTech/zbputils/control/order"
|
||||
)
|
||||
|
||||
const hso = "https://gchat.qpic.cn/gchatpic_new//--4234EDEC5F147A4C319A41149D7E0EA9/0"
|
||||
|
||||
func init() {
|
||||
engine := control.Register("nsfw", order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: false,
|
||||
@@ -31,11 +33,10 @@ func init() {
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(judge(p[0]))))
|
||||
}
|
||||
})
|
||||
en := control.Register("nsfwauto", order.AcquirePrio(), &control.Options{
|
||||
control.Register("nsfwauto", order.AcquirePrio(), &control.Options{
|
||||
DisableOnDefault: true,
|
||||
Help: "nsfw图片自动识别\n- 当图片属于非 neutral 类别时自动发送评价",
|
||||
})
|
||||
en.OnMessage(zero.IsPicExists).SetBlock(false).
|
||||
}).OnMessage(zero.HasPicture).SetBlock(false).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
url := ctx.State["image_url"].([]string)
|
||||
if len(url) > 0 {
|
||||
@@ -96,6 +97,6 @@ func autojudge(ctx *zero.Ctx, p nsfw.Picture) {
|
||||
i++
|
||||
}
|
||||
if i > 0 {
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(c)))
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text(c, "\n"), message.Image(hso)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,14 +47,6 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = file.GetLazyData(text.BoldFontFile, false, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, err = file.GetLazyData(text.FontFile, false, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sdb = initialize(engine.DataFolder() + "score.db")
|
||||
log.Println("[score]加载score数据库")
|
||||
}()
|
||||
@@ -99,6 +91,11 @@ func init() {
|
||||
|
||||
monthWord := now.Format("01/02")
|
||||
hourWord := getHourWord(now)
|
||||
_, err = file.GetLazyData(text.BoldFontFile, false, true)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
if err = canvas.LoadFontFace(text.BoldFontFile, float64(back.Bounds().Size().X)*0.1); err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
@@ -107,6 +104,11 @@ func init() {
|
||||
canvas.DrawString(hourWord, float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.2)
|
||||
canvas.DrawString(monthWord, float64(back.Bounds().Size().X)*0.6, float64(back.Bounds().Size().Y)*1.2)
|
||||
nickName := ctx.CardOrNickName(uid)
|
||||
_, err = file.GetLazyData(text.FontFile, false, true)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
}
|
||||
if err = canvas.LoadFontFace(text.FontFile, float64(back.Bounds().Size().X)*0.04); err != nil {
|
||||
ctx.SendChain(message.Text("ERROR:", err))
|
||||
return
|
||||
|
||||
@@ -76,7 +76,7 @@ func init() { // 插件主体
|
||||
}
|
||||
}()
|
||||
|
||||
engine.OnRegex(`^来份(.*)$`, ctxext.FirstValueInList(pool)).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
engine.OnRegex(`^来份(.+)$`, ctxext.FirstValueInList(pool)).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var imgtype = ctx.State["regex_matched"].([]string)[1]
|
||||
// 补充池子
|
||||
@@ -96,7 +96,7 @@ func init() { // 插件主体
|
||||
}
|
||||
})
|
||||
|
||||
engine.OnRegex(`^添加(.*?)(\d+)$`, zero.SuperUserPermission).SetBlock(true).
|
||||
engine.OnRegex(`^添加(.+)\s?(\d+)$`, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var (
|
||||
imgtype = ctx.State["regex_matched"].([]string)[1]
|
||||
@@ -110,7 +110,7 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("成功向分类", imgtype, "添加图片", id))
|
||||
})
|
||||
|
||||
engine.OnRegex(`^删除(.*?)(\d+)$`, ctxext.FirstValueInList(pool), zero.SuperUserPermission).SetBlock(true).
|
||||
engine.OnRegex(`^删除(.+)\s?(\d+)$`, ctxext.FirstValueInList(pool), zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
var (
|
||||
imgtype = ctx.State["regex_matched"].([]string)[1]
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
@@ -53,7 +54,10 @@ type dictionary map[int]struct {
|
||||
cet4 []string
|
||||
}
|
||||
|
||||
var words = make(dictionary)
|
||||
var (
|
||||
words = make(dictionary)
|
||||
wordsmu sync.Mutex
|
||||
)
|
||||
|
||||
func init() {
|
||||
en := control.Register("wordle", order.AcquirePrio(), &control.Options{
|
||||
@@ -72,26 +76,34 @@ func init() {
|
||||
)
|
||||
}),
|
||||
))
|
||||
go func() {
|
||||
for i := 5; i <= 7; i++ {
|
||||
for i := 5; i <= 7; i++ {
|
||||
go func(i int) {
|
||||
dc, err := file.GetLazyData(fmt.Sprintf("%scet-4_%d.txt", en.DataFolder(), i), true, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
c := strings.Split(string(dc), "\n")
|
||||
sort.Strings(c)
|
||||
wordsmu.Lock()
|
||||
tmp := words[i]
|
||||
tmp.cet4 = c
|
||||
words[i] = tmp
|
||||
wordsmu.Unlock()
|
||||
}(i)
|
||||
go func(i int) {
|
||||
dd, err := file.GetLazyData(fmt.Sprintf("%sdict_%d.txt", en.DataFolder(), i), true, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
d := strings.Split(string(dd), "\n")
|
||||
sort.Strings(d)
|
||||
words[i] = struct {
|
||||
dict []string
|
||||
cet4 []string
|
||||
}{d, c}
|
||||
}
|
||||
}()
|
||||
wordsmu.Lock()
|
||||
tmp := words[i]
|
||||
tmp.dict = d
|
||||
words[i] = tmp
|
||||
wordsmu.Unlock()
|
||||
}(i)
|
||||
}
|
||||
en.OnRegex(`(个人|团队)(五阶|六阶|七阶)?猜单词`, zero.OnlyGroup).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
class := classdict[ctx.State["regex_matched"].([]string)[2]]
|
||||
|
||||
Reference in New Issue
Block a user