Compare commits

..

123 Commits

Author SHA1 Message Date
fumiama
22e23efbdc ✏️ 修复 sql 查询异常 2021-10-26 00:48:13 +08:00
fumiama
38935937ae control 增加还原;调整禁用优先级 2021-10-26 00:05:45 +08:00
fumiama
a3685e2e83 ✏️ 尝试解决win下路径异常 2021-10-24 18:13:12 +08:00
fumiama
3a5e391191 修正代码问题 2021-10-23 11:51:32 +08:00
fumiama
09a9dd53fd 修正代码问题 2021-10-23 01:09:15 +08:00
github-actions[bot]
5e064249be 🎨 改进代码样式 2021-10-22 16:55:19 +00:00
fumiama
67555512e7 搜图下载使用animeapi,将文件判存移至utils 2021-10-23 00:54:38 +08:00
fumiama
591df6439c 更新 goreleaser 2021-10-22 11:37:40 +08:00
fumiama
7dfb7dfe24 更新 goreleaser 2021-10-22 11:20:01 +08:00
Kanri
8e56f137b6 ⬆️ 更新依赖 2021-10-22 09:36:11 +08:00
源文雨
3b61c73c17 Update README.md 2021-10-20 22:56:31 +08:00
fumiama
44dac98b37 Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-10-18 15:25:06 +08:00
fumiama
1a7f98379a ✏️ 修正 acgimage 发图 2021-10-18 15:24:56 +08:00
Kanri
4109ef0612 Update main.go 2021-10-17 23:56:34 +08:00
fumiama
93a9bf6c5b 更新 ZeroBot 到 v1.3.2 2021-10-16 19:07:41 +08:00
fumiama
0b7b35cdcc control 支持全局禁用&个人用户 2021-10-16 14:02:44 +08:00
fumiama
350ef86dd6 ✏️ control 减少 defer 开销 2021-10-16 13:33:12 +08:00
fumiama
2d69ae2e42 ✏️ driver 使用 api 写法 2021-10-16 13:25:13 +08:00
Kanri
e95367f4b2 Merge pull request #70 from Yiwen-Chan/master
⬆️ 更新依赖
2021-10-16 11:11:59 +08:00
Kanri
3101911aa2 ⬆️ 更新依赖 2021-10-16 11:09:26 +08:00
Kanri
ac73087f93 Merge pull request #69 from Yiwen-Chan/master
🎨 ctx.Send -> ctx.SendChain
2021-10-15 22:05:02 +08:00
Kanri
d375a3bbbb 🎨 小修改 2021-10-15 22:02:14 +08:00
Kanri
c46ca1d4c2 🎨 ctx.Send -> ctx.SendChain 2021-10-15 21:43:47 +08:00
fumiama
2a1cca8ebb ✏️ 防止文件名重复 2021-10-15 16:28:31 +08:00
fumiama
d1fdc989b6 ✏️ 防止文件名重复 2021-10-15 16:21:01 +08:00
fumiama
672215f753 ✏️ windows取消arm系 2021-10-15 16:10:58 +08:00
fumiama
4160175fcf ✏️ 修改编译逻辑 2021-10-15 16:02:11 +08:00
fumiama
8f8ba55fc9 ✏️ 改用 gocq 同款 release 2021-10-15 16:00:54 +08:00
fumiama
1dbb4aa837 ✏️ 改用 gocq 同款 release 2021-10-15 15:57:42 +08:00
fumiama
c183c4f17d ✏️ 修正zip缓存位置 2021-10-15 15:27:19 +08:00
fumiama
fa6d14d89a ✏️ 修正zip缓存位置 2021-10-15 15:10:09 +08:00
fumiama
65b92b9da3 更新 README 2021-10-15 14:43:31 +08:00
fumiama
a7056c4601 更新 README 2021-10-14 23:38:52 +08:00
fumiama
1dce0f7859 更新 README 2021-10-14 23:32:49 +08:00
fumiama
bdffbfab67 ✏️ 分离 data 2021-10-14 23:07:13 +08:00
fumiama
98b21d0fdf ✏️ str byte 转换改用 zb 的工具 2021-10-14 19:51:24 +08:00
fumiama
cccea70db1 ✏️ 分离 dyloader 2021-10-14 16:26:01 +08:00
fumiama
d2bcd0bc9f Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-10-14 13:46:44 +08:00
fumiama
08653fd3b6 🚮 删除多余文件 2021-10-14 13:46:30 +08:00
fumiama
75d0671d9b dyloader 缩小插件体积 2021-10-14 13:45:14 +08:00
fumiama
51ec3c32a9 dyloader 缩小插件体积 2021-10-14 13:44:16 +08:00
fumiama
ec0032c5ab dyloader 移除 win,增加加载插件 2021-10-14 00:06:13 +08:00
fumiama
2723f3662c ✏️ 禁用 dyloader 2021-10-13 18:40:40 +08:00
fumiama
539b050b97 ✏️ 完成插件卸载 2021-10-13 18:39:54 +08:00
fumiama
a0b9623a9f dyloader 增加 win,优化 register 2021-10-13 11:07:34 +08:00
fumiama
6b263418a0 升级 zb 到 v1.3.0 2021-10-13 00:34:43 +08:00
fumiama
92989ce9fd control 增加 Delete 2021-10-12 19:16:01 +08:00
fumiama
173925b57a 增加动态加载,添加默认禁用 2021-10-11 21:44:46 +08:00
fumiama
43735722bf ✏️ 收集 max / min 到 data 包 2021-10-11 14:24:22 +08:00
fumiama
d89e7aebec 增加-u参数说明 2021-10-11 13:35:03 +08:00
fumiama
4677d789f2 增加-u参数 2021-10-11 13:32:23 +08:00
fumiama
2fb445746e Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-10-11 13:18:15 +08:00
fumiama
505dfef48c 增加-h参数说明 2021-10-11 13:18:06 +08:00
fumiama
19a9a8ef83 增加-h参数说明 2021-10-11 13:16:30 +08:00
fumiama
119730bada 增加-h参数,优化参数处理 2021-10-11 13:15:38 +08:00
fumiama
c46748524a 增加-w参数 2021-10-10 12:00:23 +08:00
fumiama
29f833db41 Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-10-10 11:52:26 +08:00
fumiama
1232856b21 beautify 2021-10-10 11:52:18 +08:00
github-actions[bot]
770ae6ebd0 🎨 改进代码样式 2021-10-10 03:51:49 +00:00
fumiama
8c9ced0bda ✏️ 解耦 web gui 2021-10-10 11:51:09 +08:00
fumiama
3b3dd3df99 fortune 个人用户也可设置底图 2021-10-10 11:37:41 +08:00
fumiama
0817e6233d 更新时间 2021-10-09 12:51:05 +08:00
fumiama
aa4f428194 更新依赖 2021-10-09 12:50:06 +08:00
fumiama
73717dec73 更新帮助 2021-10-09 12:48:58 +08:00
github-actions[bot]
57e2ef3bab 🎨 改进代码样式 2021-10-09 04:36:26 +00:00
fumiama
a5d0b8db8e fortune 增加设置底图并加速base64 和下载 2021-10-09 12:30:59 +08:00
fumiama
3faec79371 ✏️ 解决hs cache问题 2021-10-07 12:23:59 +08:00
散无友纪
c3e0520aec 修改了搜索结果样式 (#68)
* Update run.go

* Update run.go

* Update run.go

* Update run.go

Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
2021-10-07 12:21:39 +08:00
源文雨
76db0b6fb4 Update keyword.go 2021-10-07 12:21:20 +08:00
Kanri
40a8473ce0 Merge pull request #67 from Yiwen-Chan/master
改进 fortune 插件
2021-10-06 13:15:04 +08:00
Kanri
21c1d104b8 Merge branch 'master' of github.com:Yiwen-Chan/ZeroBot-Plugin 2021-10-06 10:35:36 +08:00
Kanri
0dda861863 🎨 改进 fortune 2021-10-06 10:33:22 +08:00
Kanri
b21f2f7166 Merge pull request #66 from Yiwen-Chan/master
 增加运势图片插件
2021-10-05 12:17:44 +08:00
Kanri
e533170160 🎨 make lint happy 2021-10-05 12:16:36 +08:00
Kanri
8236874779 🎨 make lint happy 2021-10-05 12:10:45 +08:00
Kanri
4cc1dc2d1b 增加 fortune 插件 2021-10-05 12:03:31 +08:00
Kanri
18424bea7c 🙈 增加 fortune 素材文件忽略 2021-10-05 12:02:49 +08:00
Kanri
0cc6251c0d 增加 gg 绘图库直接依赖 2021-10-05 12:02:22 +08:00
Kanri
63d87be789 增加运势图片插件 2021-10-05 00:57:22 +08:00
Kanri
7e3b898383 Merge pull request #65 from starim00/forup
搜图增加浏览器标头
2021-09-30 14:47:05 +08:00
hutiance
217fa62004 用结果数组的长度作为随机数最大值、防止越界 2021-09-30 14:42:09 +08:00
hutiance
e667fb8708 搜图增加浏览器标头 2021-09-30 14:24:56 +08:00
fumiama
2fef6f51b5 ✏️ fix plugin gif 2021-09-27 22:38:24 +08:00
fumiama
81bba8595a Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-09-27 22:10:55 +08:00
fumiama
96aefc3938 ✏️ 调整 log 格式 2021-09-27 22:10:47 +08:00
github-actions[bot]
5bb0493f02 🎨 改进代码样式 2021-09-27 14:10:29 +00:00
fumiama
e8fa6b8b07 ✏️ 增加命令行参数说明 2021-09-27 22:09:51 +08:00
fumiama
ec15178ba7 ✏️ 修正命令行参数 2021-09-27 22:06:46 +08:00
fumiama
1d469a40d5 aifalse 增加 清理缓存 2021-09-27 21:51:05 +08:00
fumiama
4df30a56a3 ✏️ 修复 panic 2021-09-27 21:37:55 +08:00
fumiama
6bc1e407d5 Merge branch 'master' of https://github.com/FloatTech/ZeroBot-Plugin 2021-09-27 21:31:54 +08:00
fumiama
48442330c1 ✏️ 美化 log & 更新 banner 2021-09-27 21:31:38 +08:00
fumiama
3623a88b16 ✏️ 调整 log 格式 2021-09-27 21:27:30 +08:00
github-actions[bot]
ffca19edab 🎨 改进代码样式 2021-09-27 13:20:16 +00:00
fumiama
52a8a9de6f 增加插件 reborn 2021-09-27 21:19:37 +08:00
fumiama
b9e303196f ✏️ gif插件增加缓存 2021-09-27 20:23:15 +08:00
fumiama
da3a7e12bd update ZeroBot-Plugin-Gif to v0.1.6 2021-09-26 10:39:43 +08:00
huoxue1
21013bde98 feat: 添加webui的初步支持 (#63)
* feat: 添加webui的初步支持

使用gin监听server,前端使用vuecli
目前已支持:
   前端发送信息
   前端获取信息
   获取插件列表
预计实现功能:

改变插件状态
  获取日志
  获取配置信息
  改变配置信息
  获取好友请求列表以及群请求列表
  手动同意申请列表

* feat: 继续实现webui功能

改变插件状态
  获取日志
  获取配置信息
  前端仓库位置更改

* fix: 修复golangLint的提示信息

* 🎨 改进代码样式

* Update gui.go

* fix: 修复golangLint的提示信息

* fix: 修复golangLint的提示信息

* feat: 支持通过命令行参数禁用gui

* fix: 设置gin在非debug模式下禁用日志

* Update gui.go

* Update gui.go

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
2021-09-26 10:35:07 +08:00
fumiama
ae6d83c675 mlh 2021-09-26 10:26:23 +08:00
fumiama
f932e24573 mlh 2021-09-26 10:25:26 +08:00
fumiama
a588ec9d18 mlh 2021-09-26 10:24:46 +08:00
fumiama
bc23211f23 make lint happy 2021-09-26 10:23:52 +08:00
源文雨
78ebf39624 Update choose.go 2021-09-26 10:21:41 +08:00
源文雨
bbc2ab5f17 Update register.go 2021-09-26 10:20:57 +08:00
源文雨
2ffe1e9112 Update rule.go 2021-09-26 10:20:40 +08:00
源文雨
1036733fcb Update register.go 2021-09-26 10:19:10 +08:00
源文雨
ebd5555955 Update text.go 2021-09-26 10:18:21 +08:00
源文雨
83199cf3aa Update nbnhhsh.go 2021-09-26 10:15:22 +08:00
源文雨
c724be743d Update sqlite.go 2021-09-26 10:09:04 +08:00
源文雨
42ba65e21b Update nbnhhsh.go 2021-09-26 10:07:57 +08:00
Kanri
3405c1c45a 翻牌改为抽取最近发言的人 2021-09-25 18:11:53 +08:00
Kanri
5cb6608e17 🗃️🍱 更新数据库 2021-09-25 18:03:11 +08:00
fumiama
aa891ad3fa ✏️ 修复某些 gif 制作失败 2021-09-19 19:44:45 +08:00
fumiama
158bda52a8 ✏️ 升级gif 2021-09-19 19:10:49 +08:00
fumiama
57e5ea87d8 ✏️ 修正制图小错误 2021-09-19 18:07:08 +08:00
fumiama
74486f65cf ✏️ 简化&美化日志输出 2021-09-19 17:06:24 +08:00
fumiama
27fcb63601 ✏️ 制图增加 control 2021-09-19 16:48:41 +08:00
github-actions[bot]
8d83d6be2f 🎨 改进代码样式 2021-09-12 10:43:19 +00:00
Kanri
d31e67e598 Merge pull request #61 from DiheChen/master
Introduce new feature: choose
2021-09-12 18:42:53 +08:00
Chendihe4975
629d3c1fa8 帮助选择困难症 2021-09-12 17:52:30 +08:00
Kanri
193d6efa67 Merge pull request #60 from DiheChen/master
Introduce new feature: 拼音首字母缩写释义工具
2021-09-12 15:44:30 +08:00
Chendihe4975
c70dbd219c Update README 2021-09-12 15:37:54 +08:00
Chendihe4975
da289073e2 拼音首字母缩写释义工具 2021-09-12 15:34:38 +08:00
49 changed files with 3137 additions and 421 deletions

View File

@@ -1,55 +0,0 @@
name: 测试版
on:
push:
tags:
- p*
env:
GITHUB_TOKEN: ${{ github.token }}
jobs:
my-job:
name: Build ZeroBot-Plugin on Push Tag 🚀
runs-on: ubuntu-latest
steps:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Cache Go
id: cache
uses: actions/cache@v2
with:
# A list of files, directories, and wildcard patterns to cache and restore
path: ~/go/pkg/mod
key: ${{ runner.os }}-build-${{ hashFiles('**/go.sum') }}
- name: Tidy Go modules
run: go mod tidy
- name: Build linux-x64
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-x64
- name: Build linux-x86
run: CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-x86
- name: Build windows-x64
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-windows-x64.exe
- name: Build windows-x86
run: CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-windows-x86.exe
- name: Build arm64
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GOARM=7 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-arm64
- name: Build armv6
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-armv6
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/zerobot-plugin-*
tag: ${{ github.ref }}
overwrite: true
file_glob: true

View File

@@ -1,55 +1,27 @@
name: 稳定版
name: compile
on:
push:
tags:
- v*
env:
GITHUB_TOKEN: ${{ github.token }}
- 'v*'
jobs:
my-job:
name: Build ZeroBot-Plugin on Push Tag 🚀
goreleaser:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2.3.4
with:
fetch-depth: 0
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: '1.17'
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Cache Go
id: cache
uses: actions/cache@v2
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
# A list of files, directories, and wildcard patterns to cache and restore
path: ~/go/pkg/mod
key: ${{ runner.os }}-build-${{ hashFiles('**/go.sum') }}
- name: Tidy Go modules
run: go mod tidy
- name: Build linux-x64
run: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-x64
- name: Build linux-x86
run: CGO_ENABLED=0 GOOS=linux GOARCH=386 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-x86
- name: Build windows-x64
run: CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-windows-x64.exe
- name: Build windows-x86
run: CGO_ENABLED=0 GOOS=windows GOARCH=386 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-windows-x86.exe
- name: Build arm64
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm64 GOARM=7 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-arm64
- name: Build armv6
run: CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 go build -ldflags="-s -w" -o artifacts/zerobot-plugin-linux-armv6
- name: Upload binaries to release
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: artifacts/zerobot-plugin-*
tag: ${{ github.ref }}
overwrite: true
file_glob: true
version: latest
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

4
.gitignore vendored
View File

@@ -3,9 +3,13 @@ data/control
data/SetuTime/search
data/manager
data/acgimage
data/fortune
data/hs
plugins/*.so
plugins/*.dll
.idea/
.DS_Store
.vscode
go-zero*
nohup.out
zerobot

79
.goreleaser.yml Normal file
View File

@@ -0,0 +1,79 @@
project_name: zbp
env:
- GO111MODULE=on
before:
hooks:
- go mod tidy
builds:
- id: nowin
env:
- CGO_ENABLED=0
- GO111MODULE=on
goos:
- linux
- darwin
goarch:
- 386
- amd64
- arm
- arm64
goarm:
- 6
- 7
ignore:
- goos: darwin
goarch: arm
- goos: darwin
goarch: 386
mod_timestamp: "{{ .CommitTimestamp }}"
flags:
- -trimpath
ldflags:
- -s -w
- id: win
env:
- CGO_ENABLED=0
- GO111MODULE=on
goos:
- windows
goarch:
- 386
- amd64
mod_timestamp: "{{ .CommitTimestamp }}"
flags:
- -trimpath
ldflags:
- -s -w
checksum:
name_template: "zbp_checksums.txt"
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- fix typo
- Merge pull request
- Merge branch
- Merge remote-tracking
- go mod tidy
archives:
- id: nowin
builds:
- nowin
- win
name_template: "zbp_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
format_overrides:
- goos: windows
format: zip
nfpms:
- license: GPL 3.0
homepage: https://github.com/FloatTech/ZeroBot-Plugin
file_name_template: "zbp_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
formats:
- deb
- rpm
maintainer: FloatTech

View File

@@ -10,18 +10,39 @@
[![OICQ](https://img.shields.io/badge/OneBot-OICQ-green.svg?style=social&logo=appveyor)](https://github.com/takayama-lily/node-onebot)
[![MIRAI](https://img.shields.io/badge/OneBot-Mirai-green.svg?style=social&logo=appveyor)](https://github.com/yyuueexxiinngg/onebot-kotlin)
[![Go Report Card](https://goreportcard.com/badge/github.com/Yiwen-Chan/ZeroBot-Plugin?style=flat-square&logo=go)](https://goreportcard.com/report/github.com/github.com/Yiwen-Chan/ZeroBot-Plugin)
[![Go Report Card](https://goreportcard.com/badge/github.com/FloatTech/ZeroBot-Plugin?style=flat-square&logo=go)](https://goreportcard.com/report/github.com/github.com/FloatTech/ZeroBot-Plugin)
[![Badge](https://img.shields.io/badge/onebot-v11-black?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHAAAABwCAMAAADxPgR5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAxQTFRF////29vbr6+vAAAAk1hCcwAAAAR0Uk5T////AEAqqfQAAAKcSURBVHja7NrbctswDATQXfD//zlpO7FlmwAWIOnOtNaTM5JwDMa8E+PNFz7g3waJ24fviyDPgfhz8fHP39cBcBL9KoJbQUxjA2iYqHL3FAnvzhL4GtVNUcoSZe6eSHizBcK5LL7dBr2AUZlev1ARRHCljzRALIEog6H3U6bCIyqIZdAT0eBuJYaGiJaHSjmkYIZd+qSGWAQnIaz2OArVnX6vrItQvbhZJtVGB5qX9wKqCMkb9W7aexfCO/rwQRBzsDIsYx4AOz0nhAtWu7bqkEQBO0Pr+Ftjt5fFCUEbm0Sbgdu8WSgJ5NgH2iu46R/o1UcBXJsFusWF/QUaz3RwJMEgngfaGGdSxJkE/Yg4lOBryBiMwvAhZrVMUUvwqU7F05b5WLaUIN4M4hRocQQRnEedgsn7TZB3UCpRrIJwQfqvGwsg18EnI2uSVNC8t+0QmMXogvbPg/xk+Mnw/6kW/rraUlvqgmFreAA09xW5t0AFlHrQZ3CsgvZm0FbHNKyBmheBKIF2cCA8A600aHPmFtRB1XvMsJAiza7LpPog0UJwccKdzw8rdf8MyN2ePYF896LC5hTzdZqxb6VNXInaupARLDNBWgI8spq4T0Qb5H4vWfPmHo8OyB1ito+AysNNz0oglj1U955sjUN9d41LnrX2D/u7eRwxyOaOpfyevCWbTgDEoilsOnu7zsKhjRCsnD/QzhdkYLBLXjiK4f3UWmcx2M7PO21CKVTH84638NTplt6JIQH0ZwCNuiWAfvuLhdrcOYPVO9eW3A67l7hZtgaY9GZo9AFc6cryjoeFBIWeU+npnk/nLE0OxCHL1eQsc1IciehjpJv5mqCsjeopaH6r15/MrxNnVhu7tmcslay2gO2Z1QfcfX0JMACG41/u0RrI9QAAAABJRU5ErkJggg==)](https://github.com/howmanybots/onebot)
[![Badge](https://img.shields.io/badge/zerobot-v1.2.3-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![Badge](https://img.shields.io/badge/zerobot-v1.3.2-black?style=flat-square&logo=go)](https://github.com/wdvxdr1123/ZeroBot)
[![License](https://img.shields.io/github/license/Yiwen-Chan/OneBot-YaYa.svg?style=flat-square&logo=gnu)](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
[![qq group](https://img.shields.io/badge/group-1048452984-red?style=flat-square&logo=tencent-qq)](https://jq.qq.com/?_wv=1027&k=QMb7x1mM)
</div>
## 命令行参数
```bash
zerobot -h -t token -u url [-d|w] [-g] qq1 qq2 qq3 ...
```
- **-h**: 显示帮助
- **-t token**: 设置`AccessToken`,默认为空
- **-u url**: 设置`Url`,默认为`ws://127.0.0.1:6700`
- **-d|w**: 开启 debug | warning 级别及以上日志输出
- **-g**: 开启 [webgui](https://github.com/FloatTech/bot-manager)
- **qqs**: superusers 的 qq 号
## 功能
> 在编译时,以下功能除插件控制外,均可通过注释`main.go`中的相应`import`而物理禁用,减小插件体积。
> 通过插件控制,还可动态管理某个功能在某个群的打开/关闭。
- **web管理** `import _ "github.com/FloatTech/ZeroBot-Plugin/control/web"`
- 开启后可执行文件大约增加 5M ,默认注释不开启。如需开启请自行编辑`main.go`取消注释
- 需要配合 [webgui](https://github.com/FloatTech/bot-manager) 使用
- **动态加载插件** `import _ github.com/FloatTech/ZeroBot-Plugin-Dynamic/dyloader`
- 本功能需要`cgo`,故已分离出主线。详见[ZeroBot-Plugin-Dynamic](https://github.com/FloatTech/ZeroBot-Plugin-Dynamic)
- **插件控制**
- [x] /启用 xxx
- [x] /禁用 xxx
- [x] /启用 xxx (在发送的群/用户启用xxx)
- [x] /禁用 xxx (在发送的群/用户禁用xxx)
- [x] /全局启用 xxx
- [x] /全局禁用 xxx
- [x] /还原 xxx (在发送的群/用户还原xxx的开启状态到初始状态)
- [x] /用法 xxx
- [x] /服务列表
- **聊天** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_chat"`
@@ -101,8 +122,11 @@
- [x] 设置随机图片网址[url]
- [x] 太涩了(撤回最近发的图)
- [x] 评价图片(发送一张图片让bot评分)
- **浅草寺求签** `github.com/FloatTech/ZeroBot-Plugin/plugin_omikuji`
- [x] 求签|运势|占卜
- **每日运势** `import _ github.com/FloatTech/ZeroBot-Plugin/plugin_fortune`
- [x] 运势|抽签
- [x] 设置底图[车万 DC4 爱因斯坦 星空列车 樱云之恋 富婆妹 李清歌 公主连结 原神 明日方舟 碧蓝航线 碧蓝幻想 战双 阴阳师]
- **浅草寺求签** `import _ github.com/FloatTech/ZeroBot-Plugin/plugin_omikuji`
- [x] 求签|占卜
- **bilibili** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_bilibili"`
- [x] >vup info [名字|uid]
- [x] >user info [名字|uid]
@@ -114,6 +138,7 @@
- [x] [回复]查重
- **AIfalse** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_ai_false"`
- [x] 查询计算机当前活跃度 [身体检查]
- [x] 清理缓存
- [ ] 简易语音
- [ ] 爬图合成 [@xxx]
- **minecraft** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_minecraft"`
@@ -129,6 +154,13 @@
- [x] @Bot 任意文本(任意一句话回复)
- **关键字搜图** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_image_finder"`
- [x] 来张 [xxx]
- **拼音首字母释义工具** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh"`
- [x] ?? [缩写]
- **选择困难症帮手** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_choose"`
- [x] 选择[选择项1]还是[选项2]还是[更多选项]
- **投胎** `import _ "github.com/FloatTech/ZeroBot-Plugin/plugin_reborn"`
- [x] reborn
- 注:本插件来源于[tgbot](https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py)
- **TODO...**
## 使用方法
@@ -148,7 +180,7 @@
### 本地运行
1. 下载安装 [Go](https://studygolang.com/dl) 环境
2. 下载本项目[压缩包](https://github.com/Yiwen-Chan/ZeroBot-Plugin/archive/master.zip),本地解压
2. 下载本项目[压缩包](https://github.com/FloatTech/ZeroBot-Plugin/archive/master.zip),本地解压
3. 编辑 main.go 文件,内容按需修改
4. 双击 build.bat 文件 或 直接双击 run.bat 文件
5. 运行 OneBot 框架,并同时运行本插件
@@ -160,7 +192,7 @@
1. 点击右上角 Fork 本项目,并转跳到自己 Fork 的仓库
2. 点击仓库上方的 Actions 按钮,确认使用 Actions
3. 编辑 main.go 文件,内容按需修改
4. 前往 Release 页面发布一个 Release`tag`形如`vx.y.z`,以触发稳定版编译流程
4. 前往 Release 页面发布一个 Release`tag`形如`v1.2.3`,以触发稳定版编译流程
5. 点击 Actions 按钮,等待编译完成,回到 Release 页面下载编译好的文件
6. 运行 OneBot 框架,并同时运行本插件
7. 啾咪~
@@ -200,4 +232,4 @@ GOOS=linux GOARCH=mips GOMIPS=softfloat CGO_ENABLED=0 go build -ldflags "-s -w"
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FYiwen-Chan%2FZeroBot-Plugin.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FYiwen-Chan%2FZeroBot-Plugin?ref=badge_large)
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2FFloatTech%2FZeroBot-Plugin.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2FFloatTech%2FZeroBot-Plugin?ref=badge_large)

View File

@@ -4,8 +4,28 @@ import (
zero "github.com/wdvxdr1123/ZeroBot"
)
var enmap = make(map[string]*zero.Engine)
// Register 注册插件控制器
func Register(service string, o *Options) *zero.Engine {
engine := zero.New()
engine.UsePreHandler(new(service, o).Handler())
engine.UsePreHandler(newctrl(service, o).Handler())
enmap[service] = engine
return engine
}
// Delete 删除插件控制器,不会删除数据
func Delete(service string) {
engine, ok := enmap[service]
if ok {
engine.Delete()
mu.RLock()
_, ok = managers[service]
mu.RUnlock()
if ok {
mu.Lock()
delete(managers, service)
mu.Unlock()
}
}
}

View File

@@ -4,6 +4,7 @@ package control
import (
"os"
"strconv"
"strings"
"sync"
"github.com/sirupsen/logrus"
@@ -11,11 +12,11 @@ import (
"github.com/wdvxdr1123/ZeroBot/extension"
"github.com/wdvxdr1123/ZeroBot/message"
. "github.com/FloatTech/ZeroBot-Plugin/data"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
var (
db = &Sqlite{DBPath: "data/control/plugins.db"}
db = &sql.Sqlite{DBPath: "data/control/plugins.db"}
// managers 每个插件对应的管理
managers = map[string]*Control{}
mu = sync.RWMutex{}
@@ -29,8 +30,8 @@ type Control struct {
options Options
}
// new returns Manager with settings.
func new(service string, o *Options) *Control {
// newctrl returns Manager with settings.
func newctrl(service string, o *Options) *Control {
m := &Control{service: service,
options: func() Options {
if o == nil {
@@ -40,8 +41,8 @@ func new(service string, o *Options) *Control {
}(),
}
mu.Lock()
defer mu.Unlock()
managers[service] = m
mu.Unlock()
err := db.Create(service, &grpcfg{})
if err != nil {
panic(err)
@@ -49,42 +50,62 @@ func new(service string, o *Options) *Control {
return m
}
// enable enables a group to pass the Manager.
func (m *Control) enable(groupID int64) {
// Enable enables a group to pass the Manager.
// groupID == 0 (ALL) will operate on all grps.
func (m *Control) Enable(groupID int64) {
m.Lock()
err := db.Insert(m.service, &grpcfg{groupID, 0})
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
m.Unlock()
}
// disable disables a group to pass the Manager.
func (m *Control) disable(groupID int64) {
// Disable disables a group to pass the Manager.
// groupID == 0 (ALL) will operate on all grps.
func (m *Control) Disable(groupID int64) {
m.Lock()
err := db.Insert(m.service, &grpcfg{groupID, 1})
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
m.Unlock()
}
func (m *Control) isEnabledIn(gid int64) bool {
m.RLock()
var c grpcfg
err := db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
if err == nil {
m.RUnlock()
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable)
return c.Disable == 0
} else {
logrus.Errorf("[control] %v", err)
// Reset resets the default config of a group.
// groupID == 0 (ALL) is not allowed.
func (m *Control) Reset(groupID int64) {
if groupID != 0 {
m.Lock()
err := db.Del(m.service, "WHERE gid = "+strconv.FormatInt(groupID, 10))
m.Unlock()
if err != nil {
logrus.Errorf("[control] %v", err)
}
}
}
// IsEnabledIn 开启群
func (m *Control) IsEnabledIn(gid int64) bool {
var c grpcfg
var err error
logrus.Debugln("[control] IsEnabledIn recv gid =", gid)
if gid != 0 {
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = "+strconv.FormatInt(gid, 10))
m.RUnlock()
logrus.Debugln("[control] db find gid =", c.GroupID)
if err == nil && gid == c.GroupID {
logrus.Debugf("[control] plugin %s of grp %d : %d", m.service, c.GroupID, c.Disable)
return c.Disable == 0
}
}
m.RLock()
err = db.Find(m.service, &c, "WHERE gid = 0")
m.RUnlock()
if m.options.DisableOnDefault {
m.disable(gid)
} else {
m.enable(gid)
if err == nil {
logrus.Debugf("[control] plugin %s of all : %d", m.service, c.Disable)
return c.Disable == 0
}
return !m.options.DisableOnDefault
}
@@ -93,21 +114,27 @@ func (m *Control) isEnabledIn(gid int64) bool {
func (m *Control) Handler() zero.Rule {
return func(ctx *zero.Ctx) bool {
ctx.State["manager"] = m
return m.isEnabledIn(ctx.Event.GroupID)
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
logrus.Debugln("[control] handler get gid =", grp)
return m.IsEnabledIn(grp)
}
}
// lookup returns a Manager by the service name, if
// Lookup returns a Manager by the service name, if
// not exist, it will returns nil.
func lookup(service string) (*Control, bool) {
func Lookup(service string) (*Control, bool) {
mu.RLock()
defer mu.RUnlock()
m, ok := managers[service]
mu.RUnlock()
return m, ok
}
// forEach iterates through managers.
func forEach(iterator func(key string, manager *Control) bool) {
// ForEach iterates through managers.
func ForEach(iterator func(key string, manager *Control) bool) {
mu.RLock()
m := copyMap(managers)
mu.RUnlock()
@@ -126,6 +153,13 @@ func copyMap(m map[string]*Control) map[string]*Control {
return ret
}
func userOrGrpAdmin(ctx *zero.Ctx) bool {
if zero.OnlyGroup(ctx) {
return zero.AdminPermission(ctx)
}
return zero.OnlyToMe(ctx)
}
func init() {
if !hasinit {
mu.Lock()
@@ -135,60 +169,80 @@ func init() {
panic(err)
} else {
hasinit = true
zero.OnCommandGroup([]string{"启用", "enable"}, zero.AdminPermission, zero.OnlyGroup).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := lookup(model.Args)
if !ok {
ctx.Send("没有找到指定服务!")
}
service.enable(ctx.Event.GroupID)
ctx.Send(message.Text("已启用服务: " + model.Args))
})
zero.OnCommandGroup([]string{
"启用", "enable", "禁用", "disable",
"全局启用", "enableall", "全局禁用", "disableall",
}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
}
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
if strings.Contains(model.Command, "全局") || strings.Contains(model.Command, "all") {
grp = 0
}
if strings.Contains(model.Command, "启用") || strings.Contains(model.Command, "enable") {
service.Enable(grp)
ctx.SendChain(message.Text("已启用服务: " + model.Args))
} else {
service.Disable(grp)
ctx.SendChain(message.Text("已禁用服务: " + model.Args))
}
})
zero.OnCommandGroup([]string{"禁用", "disable"}, zero.AdminPermission, zero.OnlyGroup).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := lookup(model.Args)
if !ok {
ctx.Send("没有找到指定服务!")
}
service.disable(ctx.Event.GroupID)
ctx.Send(message.Text("已关闭服务: " + model.Args))
})
zero.OnCommandGroup([]string{"还原", "reset"}, userOrGrpAdmin).Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := Lookup(model.Args)
if !ok {
ctx.SendChain(message.Text("没有找到指定服务!"))
}
grp := ctx.Event.GroupID
if grp == 0 {
// 个人用户
grp = -ctx.Event.UserID
}
service.Reset(grp)
ctx.SendChain(message.Text("已还原服务的默认启用状态: " + model.Args))
})
zero.OnCommandGroup([]string{"用法", "usage"}, zero.AdminPermission, zero.OnlyGroup).
zero.OnCommandGroup([]string{"用法", "usage"}, userOrGrpAdmin).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
service, ok := lookup(model.Args)
service, ok := Lookup(model.Args)
if !ok {
ctx.Send("没有找到指定服务!")
ctx.SendChain(message.Text("没有找到指定服务!"))
}
if service.options.Help != "" {
ctx.Send(service.options.Help)
ctx.SendChain(message.Text(service.options.Help))
} else {
ctx.Send("该服务无帮助!")
ctx.SendChain(message.Text("该服务无帮助!"))
}
})
zero.OnCommandGroup([]string{"服务列表", "service_list"}, zero.AdminPermission, zero.OnlyGroup).
zero.OnCommandGroup([]string{"服务列表", "service_list"}, userOrGrpAdmin).
Handle(func(ctx *zero.Ctx) {
msg := `---服务列表---`
i := 0
forEach(func(key string, manager *Control) bool {
gid := ctx.Event.GroupID
ForEach(func(key string, manager *Control) bool {
i++
msg += "\n" + strconv.Itoa(i) + `: `
if manager.isEnabledIn(ctx.Event.GroupID) {
if manager.IsEnabledIn(gid) {
msg += "●" + key
} else {
msg += "○" + key
}
return true
})
ctx.Send(message.Text(msg))
ctx.SendChain(message.Text(msg))
})
}
}

481
control/web/gui.go Normal file
View File

@@ -0,0 +1,481 @@
package web
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strconv"
manager "github.com/FloatTech/bot-manager"
// 依赖gin监听server
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
// 前端静态文件
log "github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
ctrl "github.com/FloatTech/ZeroBot-Plugin/control"
)
var (
// 向前端推送消息的ws链接
conn *websocket.Conn
// 向前端推送日志的ws链接
logConn *websocket.Conn
l logWriter
)
// logWriter
// @Description:
//
type logWriter struct {
}
// initGui 初始化gui
func initGui() {
// 将日志重定向到前端hook
writer := io.MultiWriter(l, os.Stderr)
log.SetOutput(writer)
// 监听后端
go controller()
// 注册消息handle
messageHandle()
}
// websocket的协议升级
var upGrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func controller() {
defer func() {
err := recover()
if err != nil {
log.Errorln("[gui]" + "bot-manager出现不可恢复的错误")
log.Errorln("[gui]", err)
}
}()
engine := gin.New()
// 支持跨域
engine.Use(cors())
// 注册静态文件
engine.StaticFS("/dist", http.FS(manager.Dist))
engine.POST("/get_bots", getBots)
engine.POST("/get_group_list", getGroupList)
engine.POST("/get_friend_list", getFriendList)
// 注册主路径路由,使其跳转到主页面
engine.GET("/", func(context *gin.Context) {
context.Redirect(http.StatusMovedPermanently, "/dist/dist/default.html")
})
// 更改某个插件状态
engine.POST("/update_plugin_status", updatePluginStatus)
// 更改某一个插件在所有群的状态
engine.POST("/update_plugin_all_group_status", updatePluginAllGroupStatus)
// 更改所有插件状态
engine.POST("/update_all_plugin_status", updateAllPluginStatus)
// 获取所有插件状态
engine.POST("/get_plugins_status", getPluginsStatus)
// 获取一个插件状态
engine.POST("/get_plugin_status", getPluginStatus)
// 获取插件列表
engine.POST("/get_plugins", func(context *gin.Context) {
var datas []map[string]interface{}
ctrl.ForEach(func(key string, manager *ctrl.Control) bool {
datas = append(datas, map[string]interface{}{"id": 1, "handle_type": "", "name": key, "enable": manager.IsEnabledIn(0)})
return true
})
context.JSON(200, datas)
})
// 链接日志
engine.GET("/get_log", getLogs)
// 获取前端标签
engine.GET("/get_label", func(context *gin.Context) {
context.JSON(200, "ZeroBot-Plugin")
})
// 发送信息
engine.POST("/send_msg", sendMsg)
engine.GET("/data", upgrade)
log.Infoln("[gui] the webui is running http://127.0.0.1:3000")
log.Infoln("[gui] ", "you input the `ZeroBot-Plugin.exe -g` can disable the gui")
if err := engine.Run("127.0.0.1:3000"); err != nil {
log.Debugln("[gui] ", err.Error())
}
}
// updateAllPluginStatus
/**
* @Description: 改变所有插件的状态
* @param context
* example
*/
func updateAllPluginStatus(context *gin.Context) {
enable, err := strconv.ParseBool(context.PostForm("enable"))
if err != nil {
var parse map[string]interface{}
err := context.BindJSON(&parse)
if err != nil {
log.Errorln("[gui] " + err.Error())
return
}
enable = parse["enable"].(bool)
}
var groups []int64
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, group := range ctx.GetGroupList().Array() {
groups = append(groups, group.Get("group_id").Int())
}
return true
})
ctrl.ForEach(func(key string, manager *ctrl.Control) bool {
if enable {
for _, group := range groups {
manager.Enable(group)
}
} else {
for _, group := range groups {
manager.Disable(group)
}
}
return true
})
context.JSON(200, nil)
}
// updatePluginAllGroupStatus
/**
* @Description: 改变插件在所有群的状态
* @param context
* example
*/
func updatePluginAllGroupStatus(context *gin.Context) {
name := context.PostForm("name")
enable, err := strconv.ParseBool(context.PostForm("enable"))
if err != nil {
var parse map[string]interface{}
err := context.BindJSON(&parse)
if err != nil {
log.Errorln("[gui]" + err.Error())
return
}
name = parse["name"].(string)
enable = parse["enable"].(bool)
}
control, b := ctrl.Lookup(name)
if !b {
context.JSON(404, nil)
return
}
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
for _, group := range ctx.GetGroupList().Array() {
if enable {
control.Enable(group.Get("group_id").Int())
} else {
control.Disable(group.Get("group_id").Int())
}
}
return true
})
context.JSON(200, nil)
}
// updatePluginStatus
/**
* @Description: 更改某一个插件状态
* @param context
* example
*/
func updatePluginStatus(context *gin.Context) {
var parse map[string]interface{}
err := context.BindJSON(&parse)
if err != nil {
log.Errorln("[gui] ", err)
return
}
groupID := int64(parse["group_id"].(float64))
name := parse["name"].(string)
enable := parse["enable"].(bool)
fmt.Println(name)
control, b := ctrl.Lookup(name)
if !b {
context.JSON(404, "服务不存在")
return
}
if enable {
control.Enable(groupID)
} else {
control.Disable(groupID)
}
context.JSON(200, nil)
}
// getPluginStatus
/**
* @Description: 获取一个插件的状态
* @param context
* example
*/
func getPluginStatus(context *gin.Context) {
groupID, err := strconv.ParseInt(context.PostForm("group_id"), 10, 64)
name := context.PostForm("name")
if err != nil {
var parse map[string]interface{}
err := context.BindJSON(&parse)
if err != nil {
log.Errorln("[gui]" + err.Error())
return
}
groupID = int64(parse["group_id"].(float64))
name = parse["name"].(string)
}
control, b := ctrl.Lookup(name)
if !b {
context.JSON(404, "服务不存在")
return
}
context.JSON(200, gin.H{"enable": control.IsEnabledIn(groupID)})
}
// getPluginsStatus
/**
* @Description: 获取所有插件的状态
* @param context
* example
*/
func getPluginsStatus(context *gin.Context) {
groupID, err := strconv.ParseInt(context.PostForm("group_id"), 10, 64)
if err != nil {
var parse map[string]interface{}
err := context.BindJSON(&parse)
if err != nil {
log.Errorln("[gui]" + err.Error())
return
}
groupID = int64(parse["group_id"].(float64))
}
var datas []map[string]interface{}
ctrl.ForEach(func(key string, manager *ctrl.Control) bool {
enable := manager.IsEnabledIn(groupID)
datas = append(datas, map[string]interface{}{"name": key, "enable": enable})
return true
})
context.JSON(200, datas)
}
// getLogs
/**
* @Description: 连接日志
* @param context
* example
*/
func getLogs(context *gin.Context) {
con1, err := upGrader.Upgrade(context.Writer, context.Request, nil)
if err != nil {
return
}
logConn = con1
}
// getFriendList
/**
* @Description: 获取好友列表
* @param context
* example
*/
func getFriendList(context *gin.Context) {
selfID, err := strconv.Atoi(context.PostForm("self_id"))
if err != nil {
log.Errorln("[gui]" + err.Error())
var data map[string]interface{}
err := context.BindJSON(&data)
if err != nil {
log.Errorln("[gui]" + err.Error())
log.Errorln("[gui]" + "绑定错误")
return
}
selfID = int(data["self_id"].(float64))
}
bot := zero.GetBot(int64(selfID))
var resp []interface{}
list := bot.GetFriendList().String()
err = json.Unmarshal([]byte(list), &resp)
if err != nil {
log.Errorln("[gui]" + err.Error())
log.Errorln("[gui]" + "解析json错误")
}
context.JSON(200, resp)
}
// getGroupList
/**
* @Description: 获取群列表
* @param context
* example
*/
func getGroupList(context *gin.Context) {
selfID, err := strconv.Atoi(context.PostForm("self_id"))
if err != nil {
var data map[string]interface{}
err := context.BindJSON(&data)
if err != nil {
log.Errorln("[gui]" + err.Error())
return
}
selfID = int(data["self_id"].(float64))
}
bot := zero.GetBot(int64(selfID))
var resp []interface{}
list := bot.GetGroupList().String()
err = json.Unmarshal([]byte(list), &resp)
if err != nil {
log.Errorln("[gui]" + err.Error())
}
context.JSON(200, resp)
}
// getBots
/**
* @Description: 获取机器人qq号
* @param context
* example
*/
func getBots(context *gin.Context) {
var bots []int64
zero.RangeBot(func(id int64, ctx *zero.Ctx) bool {
bots = append(bots, id)
return true
})
context.JSON(200, bots)
}
// MessageHandle
/**
* @Description: 定义一个向前端发送信息的handle
* example
*/
func messageHandle() {
defer func() {
err := recover()
if err != nil {
log.Errorln("[gui]" + "bot-manager出现不可恢复的错误")
log.Errorln("[gui] ", err)
}
}()
matcher := zero.OnMessage().SetBlock(false).SetPriority(1)
matcher.Handle(func(ctx *zero.Ctx) {
if conn != nil {
err := conn.WriteJSON(ctx.Event)
if err != nil {
log.Debugln("[gui] " + "向发送错误")
return
}
}
})
}
// upgrade
/**
* @Description: 连接ws向前端推送message
* @param context
* example
*/
func upgrade(context *gin.Context) {
con, err := upGrader.Upgrade(context.Writer, context.Request, nil)
if err != nil {
return
}
conn = con
}
// sendMsg
/**
* @Description: 前端调用发送信息
* @param context
* example
*/
func sendMsg(context *gin.Context) {
var data map[string]interface{}
err := context.BindJSON(&data)
if err != nil {
context.JSON(404, nil)
return
}
selfID := int64(data["self_id"].(float64))
id := int64(data["id"].(float64))
message1 := data["message"].(string)
messageType := data["message_type"].(string)
bot := zero.GetBot(selfID)
var msgID int64
if messageType == "group" {
msgID = bot.SendGroupMessage(id, message.ParseMessageFromString(message1))
} else {
msgID = bot.SendPrivateMessage(id, message.ParseMessageFromString(message1))
}
context.JSON(200, msgID)
}
// cors
/**
* @Description: 支持跨域访问
* @return gin.HandlerFunc
* example
*/
func cors() gin.HandlerFunc {
return func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin") // 请求头部
if origin != "" {
// 接收客户端发送的origin (重要!)
c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
// 服务器支持的所有跨域请求的方法
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
// 允许跨域设置可以返回其他子段,可以自定义字段
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session, Content-Type")
// 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
// 设置缓存时间
c.Header("Access-Control-Max-Age", "172800")
// 允许客户端传递校验信息比如 cookie (重要)
c.Header("Access-Control-Allow-Credentials", "true")
}
// 允许类型校验
if method == "OPTIONS" {
c.JSON(http.StatusOK, "ok!")
}
defer func() {
if err := recover(); err != nil {
log.Printf("Panic info is: %v", err)
}
}()
c.Next()
}
}
func (l logWriter) Write(p []byte) (n int, err error) {
if logConn != nil {
err := logConn.WriteMessage(websocket.TextMessage, p)
if err != nil {
return len(p), nil
}
}
return len(p), nil
}

11
control/web/init.go Normal file
View File

@@ -0,0 +1,11 @@
// Package web 网页管理后端
package web
import "flag"
func init() {
// 解析命令行参数,输入 `-g` 即可启用 gui
if *flag.Bool("g", false, "Enable web gui.") {
initGui()
}
}

906
data/Reborn/rate.json Normal file
View File

@@ -0,0 +1,906 @@
[
{
"name": "印度",
"weight": 0.179369185
},
{
"weight": 0.116660088,
"name": "中华人民共和国"
},
{
"name": "尼日利亚",
"weight": 0.052104876
},
{
"weight": 0.04490831,
"name": "巴基斯坦"
},
{
"weight": 0.029767875,
"name": "印尼"
},
{
"weight": 0.02917347,
"name": "美国"
},
{
"name": "刚果民主共和国",
"weight": 0.026980482
},
{
"weight": 0.02653533,
"name": "埃塞俄比亚"
},
{
"name": "孟加拉国",
"weight": 0.022001723
},
{
"name": "巴西",
"weight": 0.020641351
},
{
"name": "埃及",
"weight": 0.019722924
},
{
"name": "菲律宾",
"weight": 0.017944256
},
{
"name": "墨西哥",
"weight": 0.015798468
},
{
"weight": 0.015156998,
"name": "坦桑尼亚"
},
{
"weight": 0.013686862,
"name": "乌干达"
},
{
"weight": 0.010405389,
"name": "俄罗斯"
},
{
"weight": 0.010217107,
"name": "苏丹"
},
{
"weight": 0.010079201,
"name": "越南"
},
{
"name": "阿富汗",
"weight": 0.009796745
},
{
"name": "伊朗",
"weight": 0.009789926
},
{
"name": "肯尼亚",
"weight": 0.009216044
},
{
"weight": 0.008870993,
"name": "安哥拉"
},
{
"name": "土耳其",
"weight": 0.008815318
},
{
"weight": 0.008267509,
"name": "莫桑比克"
},
{
"name": "南非",
"weight": 0.007826801
},
{
"weight": 0.00755071,
"name": "尼日尔"
},
{
"name": "伊拉克",
"weight": 0.007350484
},
{
"name": "喀麦隆",
"weight": 0.006786572
},
{
"weight": 0.006782117,
"name": "缅甸"
},
{
"name": "日本",
"weight": 0.006518972
},
{
"weight": 0.006384764,
"name": "加纳"
},
{
"weight": 0.006183538,
"name": "阿尔及利亚"
},
{
"weight": 0.006075416,
"name": "马里"
},
{
"name": "法国",
"weight": 0.00571344
},
{
"name": "英国",
"weight": 0.005662409
},
{
"name": "马达加斯加",
"weight": 0.00559132
},
{
"weight": 0.005562893,
"name": "也门"
},
{
"name": "哥伦比亚",
"weight": 0.005525953
},
{
"name": "布基纳法索",
"weight": 0.005378297
},
{
"name": "科特迪瓦",
"weight": 0.005352997
},
{
"name": "阿根廷",
"weight": 0.005171935
},
{
"name": "赞比亚",
"weight": 0.005147159
},
{
"name": "德国",
"weight": 0.005096501
},
{
"weight": 0.005067552,
"name": "泰国"
},
{
"name": "马拉维",
"weight": 0.005017242
},
{
"name": "乍得",
"weight": 0.004825619
},
{
"name": "摩洛哥",
"weight": 0.004571552
},
{
"weight": 0.004266592,
"name": "马来西亚"
},
{
"weight": 0.004130712,
"name": "南苏丹"
},
{
"name": "委内瑞拉",
"weight": 0.00410843
},
{
"weight": 0.003903682,
"name": "乌兹别克斯坦"
},
{
"weight": 0.003891083,
"name": "秘鲁"
},
{
"weight": 0.003854943,
"name": "尼泊尔"
},
{
"name": "沙特阿拉伯",
"weight": 0.003683713
},
{
"name": "塞内加尔",
"weight": 0.003671814
},
{
"name": "津巴布韦",
"weight": 0.003628572
},
{
"name": "意大利",
"weight": 0.003591173
},
{
"weight": 0.003564036,
"name": "贝宁"
},
{
"weight": 0.003318383,
"name": "索马里"
},
{
"name": "几内亚",
"weight": 0.003229938
},
{
"name": "韩国",
"weight": 0.00302709
},
{
"name": "危地马拉",
"weight": 0.002989448
},
{
"weight": 0.002933277,
"name": "西班牙"
},
{
"name": "布隆迪",
"weight": 0.002916273
},
{
"name": "乌克兰",
"weight": 0.002865519
},
{
"name": "叙利亚",
"weight": 0.002803866
},
{
"name": "加拿大",
"weight": 0.002769376
},
{
"name": "朝鲜",
"weight": 0.002663995
},
{
"name": "柬埔寨",
"weight": 0.002507218
},
{
"weight": 0.002459301,
"name": "卢旺达"
},
{
"weight": 0.002433661,
"name": "波兰"
},
{
"weight": 0.002264484,
"name": "澳大利亚"
},
{
"name": "斯里兰卡",
"weight": 0.002205474
},
{
"weight": 0.00217928,
"name": "哈萨克斯坦"
},
{
"name": "厄瓜多尔",
"weight": 0.002114416
},
{
"name": "塞拉利昂",
"weight": 0.002042686
},
{
"name": "海地",
"weight": 0.001815248
},
{
"name": "智利",
"weight": 0.001761297
},
{
"name": "多哥",
"weight": 0.001756614
},
{
"name": "约旦",
"weight": 0.001738363
},
{
"weight": 0.001716995,
"name": "玻利维亚"
},
{
"weight": 0.001432103,
"name": "巴布亚新几内亚"
},
{
"weight": 0.001424043,
"name": "塔吉克斯坦"
},
{
"name": "多米尼加",
"weight": 0.001376899
},
{
"name": "荷兰",
"weight": 0.001365722
},
{
"name": "罗马尼亚",
"weight": 0.001342703
},
{
"weight": 0.001340039,
"name": "台湾"
},
{
"name": "突尼斯",
"weight": 0.001327688
},
{
"name": "中非",
"weight": 0.001269639
},
{
"name": "洪都拉斯",
"weight": 0.001219191
},
{
"name": "刚果共和国",
"weight": 0.001209073
},
{
"weight": 0.001189154,
"name": "利比里亚"
},
{
"weight": 0.001150376,
"name": "以色列"
},
{
"weight": 0.001149654,
"name": "厄立特里亚"
},
{
"weight": 0.001119049,
"name": "老挝"
},
{
"name": "阿塞拜疆",
"weight": 0.001039837
},
{
"name": "利比亚",
"weight": 0.001029222
},
{
"name": "巴勒斯坦",
"weight": 0.000992651
},
{
"name": "吉尔吉斯斯坦",
"weight": 0.000957294
},
{
"weight": 0.000907425,
"name": "比利时"
},
{
"name": "瑞典",
"weight": 0.000890654
},
{
"name": "巴拉圭",
"weight": 0.00085764
},
{
"name": "毛里塔尼亚",
"weight": 0.000842302
},
{
"weight": 0.000830493,
"name": "古巴"
},
{
"name": "萨尔瓦多",
"weight": 0.000822881
},
{
"name": "尼加拉瓜",
"weight": 0.000782782
},
{
"weight": 0.000764766,
"name": "阿曼"
},
{
"name": "黎巴嫩",
"weight": 0.000751395
},
{
"name": "土库曼斯坦",
"weight": 0.000743841
},
{
"weight": 0.000680867,
"name": "阿联酋"
},
{
"weight": 0.000677997,
"name": "捷克"
},
{
"weight": 0.000643037,
"name": "白俄罗斯"
},
{
"weight": 0.000642255,
"name": "瑞士"
},
{
"name": "匈牙利",
"weight": 0.000612393
},
{
"name": "奥地利",
"weight": 0.000602473
},
{
"name": "希腊",
"weight": 0.000595922
},
{
"weight": 0.000592992,
"name": "葡萄牙"
},
{
"weight": 0.000566764,
"name": "科威特"
},
{
"weight": 0.000538867,
"name": "哥斯达黎加"
},
{
"name": "巴拿马",
"weight": 0.000513904
},
{
"name": "挪威",
"weight": 0.000466485
},
{
"name": "丹麦",
"weight": 0.000460789
},
{
"name": "爱尔兰",
"weight": 0.000455762
},
{
"name": "新西兰",
"weight": 0.000451486
},
{
"name": "纳米比亚",
"weight": 0.000450165
},
{
"name": "香港",
"weight": 0.000448826
},
{
"weight": 0.000441931,
"name": "冈比亚"
},
{
"weight": 0.000436542,
"name": "塞尔维亚"
},
{
"name": "芬兰",
"weight": 0.000417327
},
{
"weight": 0.00041658,
"name": "几内亚比绍"
},
{
"weight": 0.000410456,
"name": "保加利亚"
},
{
"weight": 0.000382945,
"name": "蒙古"
},
{
"name": "莱索托",
"weight": 0.00037228
},
{
"weight": 0.000361607,
"name": "新加坡"
},
{
"name": "斯洛伐克",
"weight": 0.000361482
},
{
"weight": 0.00035722,
"name": "加蓬"
},
{
"name": "博茨瓦纳",
"weight": 0.000348221
},
{
"weight": 0.000323338,
"name": "乌拉圭"
},
{
"name": "赤道几内亚",
"weight": 0.000318155
},
{
"name": "东帝汶",
"weight": 0.000316195
},
{
"name": "牙买加",
"weight": 0.000312724
},
{
"name": "格鲁吉亚",
"weight": 0.000307685
},
{
"weight": 0.000265076,
"name": "阿尔巴尼亚"
},
{
"weight": 0.000252622,
"name": "克罗地亚"
},
{
"weight": 0.000250708,
"name": "亚美尼亚"
},
{
"name": "波黑",
"weight": 0.000232069
},
{
"name": "摩尔多瓦",
"weight": 0.000204405
},
{
"name": "科索沃",
"weight": 0.000196993
},
{
"weight": 0.000189047,
"name": "立陶宛"
},
{
"weight": 0.000182006,
"name": "卡塔尔"
},
{
"name": "波多黎各",
"weight": 0.000182004
},
{
"name": "吉布提",
"weight": 0.000174383
},
{
"name": "北马其顿",
"weight": 0.000158321
},
{
"weight": 0.000146886,
"name": "科摩罗"
},
{
"weight": 0.000144027,
"name": "巴林"
},
{
"weight": 0.000129782,
"name": "斯洛文尼亚"
},
{
"weight": 0.000126232,
"name": "西撒哈拉"
},
{
"name": "拉脱维亚",
"weight": 0.000124966
},
{
"name": "所罗门群岛",
"weight": 0.000120169
},
{
"name": "斐济",
"weight": 0.000110985
},
{
"weight": 0.000110769,
"name": "特立尼达和多巴哥"
},
{
"weight": 0.000109656,
"name": "毛里求斯"
},
{
"weight": 8.8e-5,
"name": "爱沙尼亚"
},
{
"weight": 8.61e-5,
"name": "圭亚那"
},
{
"name": "不丹",
"weight": 8.61e-5
},
{
"weight": 7.49e-5,
"name": "佛得角"
},
{
"name": "塞浦路斯",
"weight": 6.8e-5
},
{
"name": "伯利兹",
"weight": 6.4e-5
},
{
"weight": 6.01e-5,
"name": "苏里南"
},
{
"name": "文莱",
"weight": 5.2e-5
},
{
"weight": 5.1e-5,
"name": "黑山"
},
{
"name": "瓦努阿图",
"weight": 5.1e-5
},
{
"name": "卢森堡",
"weight": 5.07e-5
},
{
"name": "马尔代夫",
"weight": 4.27e-5
},
{
"name": "巴哈马",
"weight": 4.06e-5
},
{
"weight": 3.82e-5,
"name": "澳门"
},
{
"weight": 3.48e-5,
"name": "马耳他"
},
{
"name": "冰岛",
"weight": 3.45e-5
},
{
"weight": 3.03e-5,
"name": "新喀里多尼亚"
},
{
"name": "萨摩亚",
"weight": 2.83e-5
},
{
"weight": 2.8e-5,
"name": "法属波利尼西亚"
},
{
"name": "关岛",
"weight": 2.36e-5
},
{
"weight": 2.32e-5,
"name": "巴巴多斯"
},
{
"name": "基里巴斯",
"weight": 1.83e-5
},
{
"weight": 1.71e-5,
"name": "圣卢西亚"
},
{
"name": "库拉索",
"weight": 1.51e-5
},
{
"weight": 1.5e-5,
"name": "汤加"
},
{
"weight": 1.42e-5,
"name": "密克罗尼西亚联邦"
},
{
"weight": 1.13e-5,
"name": "格林纳达"
},
{
"name": "安提瓜和巴布达",
"weight": 1.05e-5
},
{
"weight": 9.93e-6,
"name": "圣文森特和格林纳丁斯"
},
{
"name": "泽西",
"weight": 9.66e-6
},
{
"weight": 9.64e-6,
"name": "阿鲁巴"
},
{
"weight": 9.15e-6,
"name": "美属维尔京群岛"
},
{
"weight": 9.08e-6,
"name": "马绍尔群岛"
},
{
"weight": 8.9e-6,
"name": "塞舌尔"
},
{
"name": "美属萨摩亚",
"weight": 7.97e-6
},
{
"name": "多米尼克",
"weight": 7.57e-6
},
{
"weight": 6.41e-6,
"name": "马恩岛"
},
{
"weight": 6.09e-6,
"name": "北马里亚纳群岛"
},
{
"name": "开曼群岛",
"weight": 5.77e-6
},
{
"name": "格陵兰",
"weight": 5.63e-6
},
{
"weight": 5.54e-6,
"name": "法罗群岛"
},
{
"weight": 5.17e-6,
"name": "圣基茨和尼维斯"
},
{
"weight": 5.11e-6,
"name": "百慕大"
},
{
"weight": 4.38e-6,
"name": "根西"
},
{
"weight": 4.31e-6,
"name": "特克斯和凯科斯群岛"
},
{
"name": "荷属圣马丁",
"weight": 4.14e-6
},
{
"weight": 3.87e-6,
"name": "安道尔"
},
{
"name": "法国(法属圣马丁)",
"weight": 3.6e-6
},
{
"name": "直布罗陀",
"weight": 3.2e-6
},
{
"weight": 2.87e-6,
"name": "列支敦士登"
},
{
"name": "英属维尔京群岛",
"weight": 2.57e-6
},
{
"weight": 2.1e-6,
"name": "圣马力诺"
},
{
"weight": 1.75e-6,
"name": "瑙鲁"
},
{
"name": "摩纳哥",
"weight": 1.75e-6
},
{
"name": "图瓦卢",
"weight": 1.72e-6
},
{
"name": "库克群岛",
"weight": 1.44e-6
},
{
"name": "帕劳",
"weight": 1.44e-6
},
{
"weight": 1.41e-6,
"name": "安圭拉"
},
{
"weight": 1.05e-6,
"name": "法国(瓦利斯和富图纳)"
},
{
"weight": 6.6e-7,
"name": "法国(圣巴泰勒米)"
},
{
"name": "蒙特塞拉特",
"weight": 4.35e-7
},
{
"weight": 3.77e-7,
"name": "圣赫勒拿、阿森松和特里斯坦-达库尼亚"
},
{
"name": "法国(圣皮埃尔和密克隆)",
"weight": 2.86e-7
},
{
"name": "福克兰群岛",
"weight": 2.48e-7
}
]

Binary file not shown.

20
go.mod
View File

@@ -3,18 +3,20 @@ module github.com/FloatTech/ZeroBot-Plugin
go 1.16
require (
github.com/FloatTech/AnimeAPI v1.1.9
github.com/FloatTech/AnimeAPI v1.1.10
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/FloatTech/bot-manager v1.0.0
github.com/fogleman/gg v1.3.0
github.com/gin-gonic/gin v1.7.4
github.com/golang/protobuf v1.5.2
github.com/gorilla/websocket v1.4.2
github.com/imroc/req v0.3.0
github.com/mroth/weightedrand v0.4.1
github.com/robfig/cron v1.2.0
github.com/shirou/gopsutil v3.21.8+incompatible
github.com/shirou/gopsutil v3.21.9+incompatible
github.com/sirupsen/logrus v1.8.1
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816
github.com/tdf1939/ZeroBot-Plugin-Gif v0.0.0-20210828060956-389b1dc33652
github.com/tidwall/gjson v1.9.0
github.com/tklauser/go-sysconf v0.3.9 // indirect
github.com/wdvxdr1123/ZeroBot v1.2.3
modernc.org/sqlite v1.13.0
github.com/tidwall/gjson v1.10.0
github.com/wdvxdr1123/ZeroBot v1.3.2
modernc.org/sqlite v1.13.1
)

61
go.sum
View File

@@ -1,7 +1,15 @@
github.com/FloatTech/AnimeAPI v1.1.9 h1:H1hZmgwZPNHdx39K9JvY3awT8TTsCl9kKA1uVMyCjRg=
github.com/FloatTech/AnimeAPI v1.1.9/go.mod h1:CC+vF30UGBlcIUxwFOcXIEHoJ4r7c5x2iLQsnUCVdDI=
github.com/FloatTech/AnimeAPI v1.1.10 h1:fYkv65P1HBukHi3GpzYulGx/xLshEL9635QXALDryf0=
github.com/FloatTech/AnimeAPI v1.1.10/go.mod h1:CC+vF30UGBlcIUxwFOcXIEHoJ4r7c5x2iLQsnUCVdDI=
github.com/FloatTech/ZeroBot-Plugin v1.1.5/go.mod h1:kWuUARvU7gs4xLggi8Sy37ja2GRL6k0X6kewe5TiZRs=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4 h1:WW0BmmLLqAg+m6qGkrKbsfSIm91fkj3/udt3R7Myodo=
github.com/FloatTech/ZeroBot-Plugin-Gif v0.2.4/go.mod h1:W7ag6hml1pZTNzRXKU74OMr6rS8awQKSU+o2g7Gj4O0=
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3 h1:jn/dH+OwPSRozkmeCeQQPrAGJRBudcm3OK5tXhGItRk=
github.com/FloatTech/ZeroBot-Plugin-Timer v1.4.3/go.mod h1:MVOQQ4e6AVGFm993blXXU4Sd6bAsLY2+Zb+/HMrEeEc=
github.com/FloatTech/bot-manager v1.0.0 h1:d63J5htLhVBc2ITG09WBJI+qAB0ubPjYhfXl6hljBNk=
github.com/FloatTech/bot-manager v1.0.0/go.mod h1:8YYRJ16oroGHQGD2En0oVnmcKJkxR9O/jd5BPSfWfOQ=
github.com/FloatTech/imgfactory v0.1.1 h1:ooL2+fV8yrMhv1ShGGKsN0Rm/flWoKnvqXaUD+dC3DQ=
github.com/FloatTech/imgfactory v0.1.1/go.mod h1:ThDALab8aOuU6KVYESVWFqmjcqtm03e0SvGlTw6s+aw=
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
github.com/antchfx/htmlquery v1.2.3 h1:sP3NFDneHx2stfNXCKbhHFo8XgNjCACnU/4AO5gWz6M=
@@ -20,13 +28,26 @@ github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4/go.mod h1:H
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY=
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
@@ -40,11 +61,14 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imroc/req v0.3.0 h1:3EioagmlSG+z+KySToa+Ylo3pTFZs+jh3Brl7ngU12U=
github.com/imroc/req v0.3.0/go.mod h1:F+NZ+2EFSo6EFXdeIbpfE9hcC233id70kf0byW97Caw=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU=
@@ -54,6 +78,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b h1:6Xjqolv/0DDdUqlpnsTomXQvjvvkz7Ux7TcMALvozEw=
github.com/modern-go/reflect2 v1.0.2-0.20210109003243-333559e1834b/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mroth/weightedrand v0.4.1 h1:rHcbUBopmi/3x4nnrvwGJBhX9d0vk+KgoLUZeDP6YyI=
github.com/mroth/weightedrand v0.4.1/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
@@ -63,8 +89,9 @@ github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6O
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ=
github.com/robfig/cron v1.2.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/shirou/gopsutil v3.21.8+incompatible h1:sh0foI8tMRlCidUJR+KzqWYWxrkuuPIGiO6Vp+KXdCU=
github.com/shirou/gopsutil v3.21.8+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil v3.21.9+incompatible h1:LTLpUnfX81MkHeCtSrwNKZwuW5Id6kCa7/P43NdcNn4=
github.com/shirou/gopsutil v3.21.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
@@ -72,32 +99,40 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
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=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816 h1:J6v8awz+me+xeb/cUTotKgceAYouhIB3pjzgRd6IlGk=
github.com/t-tomalak/logrus-easy-formatter v0.0.0-20190827215021-c074f06c5816/go.mod h1:tzym/CEb5jnFI+Q0k4Qq3+LvRF4gO3E2pxS8fHP8jcA=
github.com/tdf1939/ZeroBot-Plugin-Gif v0.0.0-20210828060956-389b1dc33652 h1:ZMZGgo6hboOetoExFZBecloH1zmQYJlWQWuhCeR0FiY=
github.com/tdf1939/ZeroBot-Plugin-Gif v0.0.0-20210828060956-389b1dc33652/go.mod h1:bkxKi7un9gCDvUUZAiIJF6k90pyj8rmxiXLJkiHcsMY=
github.com/tdf1939/img v0.0.0-20210827153520-90cb4e9580a3 h1:DUQxv4Ua1sb0/zOkExNJ/MSJcSnbZ7WT9thXCPWTh5U=
github.com/tdf1939/img v0.0.0-20210827153520-90cb4e9580a3/go.mod h1:FgTEOcosTWrkOr7++gbtPSj1rX5loRWrf/AL+hm3Cnw=
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
github.com/tidwall/gjson v1.9.0 h1:+Od7AE26jAaMgVC31cQV/Ope5iKXulNMflrlB7k+F9E=
github.com/tidwall/gjson v1.9.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
github.com/tidwall/gjson v1.10.0 h1:FcpcxUhNwjb4ppKSlz5Bv8V1jc9ncrVAySohlNBrPUk=
github.com/tidwall/gjson v1.10.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tklauser/go-sysconf v0.3.9 h1:JeUVdAOWhhxVcU6Eqr/ATFHgXk/mmiItdKeJPev3vTo=
github.com/tklauser/go-sysconf v0.3.9/go.mod h1:11DU/5sG7UexIrp/O6g35hrWzu0JxlwQ3LSFUzyeuhs=
github.com/tklauser/numcpus v0.3.0 h1:ILuRUQBtssgnxw0XXIjKUC56fgnOrFoQQ/4+DeU2biQ=
github.com/tklauser/numcpus v0.3.0/go.mod h1:yFGUr7TUHQRAhyqBcEg0Ge34zDBAsIvJJcyE6boqnA8=
github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/wdvxdr1123/ZeroBot v1.2.2/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
github.com/wdvxdr1123/ZeroBot v1.2.3 h1:Fu6aHr+91NRN48G9szJwyR0MhnTjG5lNMS0Wy0QX1Uo=
github.com/wdvxdr1123/ZeroBot v1.2.3/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
github.com/wdvxdr1123/ZeroBot v1.2.4/go.mod h1:83nHtG8V5TAxPwH/LCDxLpZk4khIgs29dkr5TBWf7fc=
github.com/wdvxdr1123/ZeroBot v1.3.2 h1:EFZNb3awNbwxRtmDkWv3PH6Z9rUV6ZLFa3hBmRMRRCA=
github.com/wdvxdr1123/ZeroBot v1.3.2/go.mod h1:i2DIqQjtjE+3gvVi9r9sc+QpNaUuyTXx/HNXXayIpwI=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
@@ -127,6 +162,7 @@ golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b h1:S7hKs0Flbq0bbc9xgYt4stIEG1zNDFqyrPwAX2Wj/sE=
golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -142,10 +178,14 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
@@ -179,8 +219,9 @@ modernc.org/memory v1.0.5 h1:XRch8trV7GgvTec2i7jc33YlUI0RKVDBvZ5eZ5m8y14=
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.13.0 h1:cwhUj0jTBgPjk/demWheV+T6xi6ifTfsGIFKFq0g3Ck=
modernc.org/sqlite v1.13.0/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
modernc.org/sqlite v1.13.1 h1:s/qk6VTTVyQIyhVNWa50whBBcI3+2oREbx85t227iOo=
modernc.org/sqlite v1.13.1/go.mod h1:2qO/6jZJrcQaxFUHxOwa6Q6WfiGSsiVj6GXX0Ker+Jg=
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/tcl v1.5.9 h1:DZMfR+RDJRhcrmMEMTJgVIX+Wf5qhfVX0llI0rsc20w=

76
main.go
View File

@@ -1,30 +1,38 @@
package main
import (
"flag"
"fmt"
"os"
"strings"
// 注:以下插件均可通过前面加 // 注释,注释后停用并不加载插件
// 下列插件可与 wdvxdr1123/ZeroBot v1.1.2 以上配合单独使用
// 插件控制
// _ "github.com/FloatTech/ZeroBot-Plugin/control/web" // web 后端控制
// 词库类
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_atri" // ATRI词库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_chat" // 基础词库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_qingyunke" //青云客
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_qingyunke" // 青云客
// 实用类
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_github" // 搜索GitHub仓库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_manager" // 群管
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_nbnhhsh" // 拼音首字母缩写释义工具
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_runcode" // 在线运行代码
// 娱乐类
_ "github.com/tdf1939/ZeroBot-Plugin-Gif/plugin_gif" // 制图
_ "github.com/FloatTech/ZeroBot-Plugin-Gif" // 制图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_ai_false" // 服务器监控
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_choose" // 选择困难症帮手
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_fortune" // 运势
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_hs" // 炉石
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_minecraft" // MCSManager
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_music" // 点歌
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_omikuji" // 浅草寺求签
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_reborn" // 投胎
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_shindan" // 测定
// b站相关
@@ -40,58 +48,76 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin_setutime" // 来份涩图
// 以下为内置依赖,勿动
log "github.com/sirupsen/logrus"
easy "github.com/t-tomalak/logrus-easy-formatter"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/driver"
"github.com/wdvxdr1123/ZeroBot/message"
)
var (
contents = []string{
"* OneBot + ZeroBot + Golang",
"* Version 1.1.5 - 2021-09-09 20:52:33 +0800 CST",
"* Copyright © 2020 - 2021 Kanri, DawnNights, Fumiama, Suika",
"* Version 1.1.7 - 2021-10-09 12:50:23 +0800 CST",
"* Copyright © 2020 - 2021 FloatTech. All Rights Reserved.",
"* Project: https://github.com/FloatTech/ZeroBot-Plugin",
}
banner = strings.Join(contents, "\n")
token *string
url *string
)
func init() {
log.SetFormatter(&easy.Formatter{
TimestampFormat: "2006-01-02 15:04:05",
LogFormat: "[zero][%time%][%lvl%]: %msg% \n",
})
log.SetLevel(log.DebugLevel)
// 解析命令行参数
d := flag.Bool("d", false, "Enable debug level log and higher.")
w := flag.Bool("w", false, "Enable warning level log and higher.")
h := flag.Bool("h", false, "Display this help.")
// 直接写死 AccessToken 时,请更改下面第二个参数
token = flag.String("t", "", "Set AccessToken of WSClient.")
// 直接写死 URL 时,请更改下面第二个参数
url = flag.String("u", "ws://127.0.0.1:6700", "Set Url of WSClient.")
flag.Parse()
if *h {
printBanner()
fmt.Println("Usage:")
flag.PrintDefaults()
os.Exit(0)
} else {
if *d && !*w {
logrus.SetLevel(logrus.DebugLevel)
}
if *w {
logrus.SetLevel(logrus.WarnLevel)
}
}
}
func main() {
func printBanner() {
fmt.Print(
"\n======================[ZeroBot-Plugin]======================",
"\n", banner, "\n",
"============================================================\n",
) // 启动打印
)
}
func main() {
printBanner()
zero.Run(zero.Config{
NickName: []string{"椛椛", "ATRI", "atri", "亚托莉", "アトリ"},
CommandPrefix: "/",
// SuperUsers 某些功能需要主人权限,可通过以下两种方式修改
// []string{}:通过代码写死的方式添加主人账号
// os.Args[1:]:通过命令行参数的方式添加主人账号
SuperUsers: append([]string{"12345678", "87654321"}, os.Args[1:]...),
// flag.Args():通过命令行参数的方式添加主人账号
SuperUsers: append([]string{"12345678", "87654321"}, flag.Args()...),
Driver: []zero.Driver{
&driver.WSClient{
// OneBot 正向WS 默认使用 6700 端口
Url: "ws://127.0.0.1:6700",
AccessToken: "",
},
driver.NewWebSocketClient(*url, *token),
},
})
},
)
// 帮助
zero.OnFullMatchGroup([]string{"/help", ".help", "菜单"}, zero.OnlyToMe).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
ctx.Send(banner)
ctx.SendChain(message.Text(banner))
})
select {}
}

View File

@@ -3,7 +3,6 @@ package acgimage
import (
"net/url"
"os"
"strconv"
"strings"
@@ -13,6 +12,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
const (
@@ -21,9 +21,8 @@ const (
)
var (
botpath, _ = os.Getwd()
datapath = botpath + "/data/acgimage/"
cacheuri = "file:///" + datapath + "cache"
datapath = file.BOT_PATH + "/data/acgimage/"
cacheuri = "file:///" + datapath + "cache"
// r18有一定保护一般不会发出图片
randapi = "&loli=true&r18=true"
msgof = make(map[int64]int64)
@@ -46,10 +45,10 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
url := ctx.State["regex_matched"].([]string)[1]
if !strings.HasPrefix(url, "http") {
ctx.Send("URL非法!")
ctx.SendChain(message.Text("URL非法!"))
} else {
randapi = url
ctx.Send("设置好啦")
ctx.SendChain(message.Text("设置好啦"))
}
})
// 有保护的随机图片
@@ -61,14 +60,14 @@ func init() { // 插件主体
replyClass(ctx, dhash, class, false, lastvisit, comment)
}()
} else {
ctx.Send("你太快啦!")
ctx.SendChain(message.Text("你太快啦!"))
}
})
// 直接随机图片无r18保护后果自负。如果出r18图可尽快通过发送"太涩了"撤回
engine.OnFullMatch("直接随机", zero.OnlyGroup, zero.AdminPermission).SetBlock(true).SetPriority(24).
Handle(func(ctx *zero.Ctx) {
if block {
ctx.Send("请稍后再试哦")
ctx.SendChain(message.Text("请稍后再试哦"))
} else if randapi != "" {
block = true
var url string
@@ -77,7 +76,7 @@ func init() { // 插件主体
} else {
url = randapi
}
setLastMsg(ctx.Event.GroupID, ctx.Send(message.Image(url).Add("cache", "0")))
setLastMsg(ctx.Event.GroupID, ctx.SendChain(message.Image(url).Add("cache", "0")))
block = false
}
})
@@ -89,7 +88,7 @@ func init() { // 插件主体
// 上传一张图进行评价
engine.OnKeywordGroup([]string{"评价图片"}, zero.OnlyGroup, picture.CmdMatch, picture.MustGiven).SetBlock(true).SetPriority(24).
Handle(func(ctx *zero.Ctx) {
ctx.Send("少女祈祷中...")
ctx.SendChain(message.Text("少女祈祷中..."))
for _, url := range ctx.State["image_url"].([]string) {
go func(target string) {
class, lastvisit, dhash, comment := classify.Classify(target, true)
@@ -101,7 +100,7 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
dhash := ctx.State["regex_matched"].([]string)[1]
if len(dhash) == 5*3 {
ctx.Send(message.Image(apihead + dhash))
ctx.SendChain(message.Image(apihead + dhash))
}
})
}
@@ -124,19 +123,18 @@ func replyClass(ctx *zero.Ctx, dhash string, class int, noimg bool, lv int64, co
if dhash != "" && !noimg {
b14, err3 := url.QueryUnescape(dhash)
if err3 == nil {
ctx.Send(comment + "\n给你点提示哦" + b14)
ctx.SendChain(message.Text(comment + "\n给你点提示哦" + b14))
ctx.Event.GroupID = 0
ctx.Send(img)
ctx.SendChain(img)
}
} else {
ctx.Send(comment)
ctx.SendChain(message.Text(comment))
}
} else {
comment := message.Text(comment)
if !noimg {
ctx.SendChain(img, comment)
ctx.SendChain(img, message.Text(comment))
} else {
ctx.SendChain(message.Reply(ctx.Event.MessageID), comment)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(comment))
}
}
}

View File

@@ -3,6 +3,7 @@ package aifalse
import (
"math"
"os"
"time"
"github.com/shirou/gopsutil/cpu"
@@ -30,6 +31,15 @@ func init() { // 插件主体
),
)
})
engine.OnFullMatch("清理缓存", zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := os.RemoveAll("data/cache/*")
if err != nil {
ctx.SendChain(message.Text("错误: ", err.Error()))
} else {
ctx.SendChain(message.Text("成功!"))
}
})
}
func cpuPercent() float64 {

View File

@@ -12,17 +12,16 @@ import (
"github.com/FloatTech/ZeroBot-Plugin/control"
)
var engine *zero.Engine
var engine = control.Register("bilibili", &control.Options{
DisableOnDefault: false,
Help: "bilibili\n" +
"- >vup info [名字|uid]\n" +
"- >user info [名字|uid]\n" +
"- /开启粉丝日报",
})
// 查成分的
func init() {
engine = control.Register("bilibili", &control.Options{
DisableOnDefault: false,
Help: "bilibili\n" +
"- >vup info [名字|uid]\n" +
"- >user info [名字|uid]\n" +
"- /开启粉丝日报",
})
engine.OnRegex(`^>user info\s(.{1,25})$`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
keyword := ctx.State["regex_matched"].([]string)[1]

37
plugin_choose/choose.go Normal file
View File

@@ -0,0 +1,37 @@
// Package choose 选择困难症帮手
package choose
import (
"math/rand"
"strconv"
"strings"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
)
func init() {
engine := control.Register("choose", &control.Options{
DisableOnDefault: false,
Help: "choose\n" +
"- 选择可口可乐还是百事可乐\n" +
"- 选择肯德基还是麦当劳还是必胜客\n",
})
engine.OnPrefix("选择").SetBlock(true).FirstPriority().Handle(handle)
}
func handle(ctx *zero.Ctx) {
rawOptions := strings.Split(ctx.State["args"].(string), "还是")
var options = make([]string, 0)
for count, option := range rawOptions {
options = append(options, strconv.Itoa(count+1)+", "+option)
}
result := rawOptions[rand.Intn(len(rawOptions))]
name := ctx.Event.Sender.NickName
ctx.SendChain(message.Text("> ", name, "\n",
"你的选项有:", "\n",
strings.Join(options, "\n"), "\n",
"你最终会选: ", result,
))
}

View File

@@ -2,11 +2,11 @@
package diana
import (
fmt "fmt"
"math/rand"
"time"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/plugin_diana/data"
@@ -28,22 +28,22 @@ func init() {
Handle(func(ctx *zero.Ctx) {
rand.Seed(time.Now().UnixNano())
// 绕过第一行发病
ctx.Send((*data.Array)[rand.Intn(len(*data.Array)-1)+1])
ctx.SendChain(message.Text((*data.Array)[rand.Intn(len(*data.Array)-1)+1]))
})
// 逆天
engine.OnFullMatch("发大病").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
// 第一行是发病
ctx.Send((*data.Array)[0])
ctx.SendChain(message.Text((*data.Array)[0]))
})
// 增加小作文
engine.OnRegex(`^教你一篇小作文(.*)$`, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := data.AddText(ctx.State["regex_matched"].([]string)[1])
if err != nil {
ctx.Send(fmt.Sprintf("ERROR: %v", err))
ctx.SendChain(message.Text("ERROR: ", err))
} else {
ctx.Send("记住啦!")
ctx.SendChain(message.Text("记住啦!"))
}
})
}

View File

@@ -3,20 +3,23 @@ package data
import (
"crypto/md5"
"errors"
"io"
"net/http"
"os"
"sync"
"time"
"unsafe"
log "github.com/sirupsen/logrus"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
const (
datapath = "data/Diana"
pbfile = datapath + "/text.pb"
pburl = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/data/Diana/text.pb"
pburl = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/" + pbfile
)
var (
@@ -26,7 +29,7 @@ var (
// m 小作文保存锁
m sync.Mutex
// md5s 验证重复
md5s [][16]byte
md5s []*[16]byte
)
func init() {
@@ -40,9 +43,10 @@ func init() {
if err1 == nil {
arrl := len(*Array)
log.Printf("[Diana]读取%d条小作文", arrl)
md5s = make([][16]byte, arrl)
md5s = make([]*[16]byte, arrl)
for i, t := range *Array {
md5s[i] = md5.Sum(str2bytes(t))
m := md5.Sum(helper.StringToBytes(t))
md5s[i] = &m
}
} else {
log.Printf("[Diana]读取小作文错误:%v", err1)
@@ -52,7 +56,7 @@ func init() {
// LoadText 加载小作文
func LoadText() error {
if _, err := os.Stat(pbfile); err == nil || os.IsExist(err) {
if file.IsExist(pbfile) {
f, err := os.Open(pbfile)
if err == nil {
defer f.Close()
@@ -91,20 +95,20 @@ func LoadText() error {
// AddText 添加小作文
func AddText(txt string) error {
sum := md5.Sum(str2bytes(txt))
if txt != "" && !isin(sum) {
sum := md5.Sum(helper.StringToBytes(txt))
if txt != "" && !isin(&sum) {
m.Lock()
defer m.Unlock()
compo.Array = append(compo.Array, txt)
md5s = append(md5s, sum)
md5s = append(md5s, &sum)
return savecompo()
}
return nil
}
func isin(sum [16]byte) bool {
func isin(sum *[16]byte) bool {
for _, t := range md5s {
if t == sum {
if *t == *sum {
return true
}
}
@@ -115,7 +119,7 @@ func isin(sum [16]byte) bool {
func savecompo() error {
data, err := compo.Marshal()
if err == nil {
if _, err := os.Stat(datapath); err == nil || os.IsExist(err) {
if file.IsExist(datapath) {
f, err1 := os.OpenFile(pbfile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 == nil {
_, err2 := f.Write(data)
@@ -124,13 +128,7 @@ func savecompo() error {
}
return err1
}
return errors.New("datapath is not exist")
}
return err
}
// str2bytes Fast convert
func str2bytes(s string) []byte {
x := (*[2]uintptr)(unsafe.Pointer(&s))
h := [3]uintptr{x[0], x[1], x[1]}
return *(*[]byte)(unsafe.Pointer(&h))
}

View File

@@ -1,3 +1,4 @@
// Package diana 嘉然相关
package diana
import (
@@ -37,12 +38,12 @@ func init() {
zhiwangjson := zhiwangapi(msg)
if zhiwangjson == nil || zhiwangjson.Code != 0 {
ctx.Send("api返回错误")
ctx.SendChain(message.Text("api返回错误"))
return
}
if len(zhiwangjson.Data.Related) == 0 {
ctx.Send("枝网没搜到查重率为0%,我的评价是:一眼真")
ctx.SendChain(message.Text("枝网没搜到查重率为0%,我的评价是:一眼真"))
return
}

405
plugin_fortune/cfg.pb.go Normal file
View File

@@ -0,0 +1,405 @@
// Code generated by protoc-gen-gogo. DO NOT EDIT.
// source: cfg.proto
package fortune
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
io "io"
math "math"
math_bits "math/bits"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Conf struct {
Kind map[int64]uint32 `protobuf:"bytes,1,rep,name=kind,proto3" json:"kind,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Conf) Reset() { *m = Conf{} }
func (m *Conf) String() string { return proto.CompactTextString(m) }
func (*Conf) ProtoMessage() {}
func (*Conf) Descriptor() ([]byte, []int) {
return fileDescriptor_f81ba022997f8a9d, []int{0}
}
func (m *Conf) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *Conf) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_Conf.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *Conf) XXX_Merge(src proto.Message) {
xxx_messageInfo_Conf.Merge(m, src)
}
func (m *Conf) XXX_Size() int {
return m.Size()
}
func (m *Conf) XXX_DiscardUnknown() {
xxx_messageInfo_Conf.DiscardUnknown(m)
}
var xxx_messageInfo_Conf proto.InternalMessageInfo
func (m *Conf) GetKind() map[int64]uint32 {
if m != nil {
return m.Kind
}
return nil
}
func init() {
proto.RegisterType((*Conf)(nil), "fortune.conf")
proto.RegisterMapType((map[int64]uint32)(nil), "fortune.conf.KindEntry")
}
func init() { proto.RegisterFile("cfg.proto", fileDescriptor_f81ba022997f8a9d) }
var fileDescriptor_f81ba022997f8a9d = []byte{
// 154 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4c, 0x4e, 0x4b, 0xd7,
0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4f, 0xcb, 0x2f, 0x2a, 0x29, 0xcd, 0x4b, 0x55, 0xca,
0xe1, 0x62, 0x49, 0xce, 0xcf, 0x4b, 0x13, 0xd2, 0xe6, 0x62, 0xc9, 0xce, 0xcc, 0x4b, 0x91, 0x60,
0x54, 0x60, 0xd6, 0xe0, 0x36, 0x12, 0xd7, 0x83, 0xca, 0xeb, 0x81, 0x24, 0xf5, 0xbc, 0x33, 0xf3,
0x52, 0x5c, 0xf3, 0x4a, 0x8a, 0x2a, 0x83, 0xc0, 0x8a, 0xa4, 0xcc, 0xb9, 0x38, 0xe1, 0x42, 0x42,
0x02, 0x5c, 0xcc, 0xd9, 0xa9, 0x95, 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x20, 0xa6, 0x90,
0x08, 0x17, 0x6b, 0x59, 0x62, 0x4e, 0x69, 0xaa, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6f, 0x10, 0x84,
0x63, 0xc5, 0x64, 0xc1, 0xe8, 0x24, 0x70, 0xe2, 0x91, 0x1c, 0xe3, 0x85, 0x47, 0x72, 0x8c, 0x0f,
0x1e, 0xc9, 0x31, 0xce, 0x78, 0x2c, 0xc7, 0x90, 0xc4, 0x06, 0x76, 0x8f, 0x31, 0x20, 0x00, 0x00,
0xff, 0xff, 0x8a, 0xa2, 0xbe, 0x9e, 0x9c, 0x00, 0x00, 0x00,
}
func (m *Conf) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *Conf) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Conf) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if len(m.Kind) > 0 {
for k := range m.Kind {
v := m.Kind[k]
baseI := i
i = encodeVarintCfg(dAtA, i, uint64(v))
i--
dAtA[i] = 0x10
i = encodeVarintCfg(dAtA, i, uint64(k))
i--
dAtA[i] = 0x8
i = encodeVarintCfg(dAtA, i, uint64(baseI-i))
i--
dAtA[i] = 0xa
}
}
return len(dAtA) - i, nil
}
func encodeVarintCfg(dAtA []byte, offset int, v uint64) int {
offset -= sovCfg(v)
base := offset
for v >= 1<<7 {
dAtA[offset] = uint8(v&0x7f | 0x80)
v >>= 7
offset++
}
dAtA[offset] = uint8(v)
return base
}
func (m *Conf) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if len(m.Kind) > 0 {
for k, v := range m.Kind {
_ = k
_ = v
mapEntrySize := 1 + sovCfg(uint64(k)) + 1 + sovCfg(uint64(v))
n += mapEntrySize + 1 + sovCfg(uint64(mapEntrySize))
}
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func sovCfg(x uint64) (n int) {
return (math_bits.Len64(x|1) + 6) / 7
}
func sozCfg(x uint64) (n int) {
return sovCfg(uint64((x << 1) ^ uint64((int64(x) >> 63))))
}
func (m *Conf) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCfg
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: conf: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: conf: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Kind", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCfg
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthCfg
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthCfg
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.Kind == nil {
m.Kind = make(map[int64]uint32)
}
var mapkey int64
var mapvalue uint32
for iNdEx < postIndex {
entryPreIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCfg
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
if fieldNum == 1 {
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCfg
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapkey |= int64(b&0x7F) << shift
if b < 0x80 {
break
}
}
} else if fieldNum == 2 {
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowCfg
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
mapvalue |= uint32(b&0x7F) << shift
if b < 0x80 {
break
}
}
} else {
iNdEx = entryPreIndex
skippy, err := skipCfg(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthCfg
}
if (iNdEx + skippy) > postIndex {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
m.Kind[mapkey] = mapvalue
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipCfg(dAtA[iNdEx:])
if err != nil {
return err
}
if (skippy < 0) || (iNdEx+skippy) < 0 {
return ErrInvalidLengthCfg
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func skipCfg(dAtA []byte) (n int, err error) {
l := len(dAtA)
iNdEx := 0
depth := 0
for iNdEx < l {
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCfg
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= (uint64(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
wireType := int(wire & 0x7)
switch wireType {
case 0:
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCfg
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
iNdEx++
if dAtA[iNdEx-1] < 0x80 {
break
}
}
case 1:
iNdEx += 8
case 2:
var length int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowCfg
}
if iNdEx >= l {
return 0, io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
length |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
if length < 0 {
return 0, ErrInvalidLengthCfg
}
iNdEx += length
case 3:
depth++
case 4:
if depth == 0 {
return 0, ErrUnexpectedEndOfGroupCfg
}
depth--
case 5:
iNdEx += 4
default:
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
}
if iNdEx < 0 {
return 0, ErrInvalidLengthCfg
}
if depth == 0 {
return iNdEx, nil
}
}
return 0, io.ErrUnexpectedEOF
}
var (
ErrInvalidLengthCfg = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowCfg = fmt.Errorf("proto: integer overflow")
ErrUnexpectedEndOfGroupCfg = fmt.Errorf("proto: unexpected end of group")
)

6
plugin_fortune/cfg.proto Normal file
View File

@@ -0,0 +1,6 @@
syntax = "proto3";
package fortune;
message conf {
map<int64, uint32> kind = 1;
}

55
plugin_fortune/data.go Normal file
View File

@@ -0,0 +1,55 @@
package fortune
import (
"errors"
io "io"
"os"
"sync"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
var (
conf Conf
mu sync.Mutex
)
func loadcfg(name string) error {
name = base + name
if file.IsExist(name) {
f, err := os.Open(name)
if err == nil {
defer f.Close()
data, err1 := io.ReadAll(f)
if err1 == nil {
if len(data) > 0 {
return conf.Unmarshal(data)
}
}
return err1
}
} else { // 如果没有 cfg则使用空 map
conf.Kind = make(map[int64]uint32)
}
return nil
}
func savecfg(name string) error {
name = base + name
data, err := conf.Marshal()
if err == nil {
if file.IsExist(base) {
f, err1 := os.OpenFile(name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 == nil {
mu.Lock()
_, err2 := f.Write(data)
f.Close()
mu.Unlock()
return err2
}
return err1
}
return errors.New("base dir is not exist")
}
return err
}

306
plugin_fortune/fortune.go Normal file
View File

@@ -0,0 +1,306 @@
// Package fortune 每日运势
package fortune
import (
"archive/zip"
"bytes"
"encoding/base64"
"encoding/json"
"image/jpeg"
"io"
"io/ioutil"
"math/rand"
"os"
"strconv"
"time"
"github.com/fogleman/gg"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
var (
// 底图缓存位置
base = "data/fortune/"
// 素材下载网站
site = "https://pan.dihe.moe/fortune/"
// 底图类型列表:车万 DC4 爱因斯坦 星空列车 樱云之恋 富婆妹 李清歌
// 公主连结 原神 明日方舟 碧蓝航线 碧蓝幻想 战双 阴阳师
table = [...]string{"车万", "DC4", "爱因斯坦", "星空列车", "樱云之恋", "富婆妹", "李清歌", "公主连结", "原神", "明日方舟", "碧蓝航线", "碧蓝幻想", "战双", "阴阳师"}
// 映射底图与 index
index = make(map[string]uint32)
)
func init() {
err := loadcfg("cfg.pb")
if err != nil {
panic(err)
}
for i, s := range table {
index[s] = uint32(i)
}
err = os.MkdirAll(base, 0755)
if err != nil {
panic(err)
}
// 插件主体
en := control.Register("fortune", &control.Options{
DisableOnDefault: false,
Help: "每日运势: \n" +
"- 运势|抽签\n" +
"- 设置底图[车万 DC4 爱因斯坦 星空列车 樱云之恋 富婆妹 李清歌 公主连结 原神 明日方舟 碧蓝航线 碧蓝幻想 战双 阴阳师]",
})
en.OnRegex(`^设置底图(.*)`).SetBlock(true).SecondPriority().
Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
if gid <= 0 {
// 个人用户设为负数
gid = -ctx.Event.UserID
}
i, ok := index[ctx.State["regex_matched"].([]string)[1]]
if ok {
conf.Kind[gid] = i
savecfg("cfg.pb")
ctx.SendChain(message.Text("设置成功~"))
} else {
ctx.SendChain(message.Text("没有这个底图哦~"))
}
})
en.OnFullMatchGroup([]string{"运势", "抽签"}).SetBlock(true).SecondPriority().
Handle(func(ctx *zero.Ctx) {
// 检查签文文件是否存在
mikuji := base + "运势签文.json"
if file.IsNotExist(mikuji) {
ctx.SendChain(message.Text("正在下载签文文件,请稍后..."))
err := file.DownloadTo(site+"运势签文.json", mikuji)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载签文文件完毕"))
}
// 检查字体文件是否存在
ttf := base + "sakura.ttf"
if file.IsNotExist(ttf) {
ctx.SendChain(message.Text("正在下载字体文件,请稍后..."))
err := file.DownloadTo(site+"sakura.ttf", ttf)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载字体文件完毕"))
}
// 获取该群背景类型,默认车万
kind := "车万"
gid := ctx.Event.GroupID
if gid <= 0 {
// 个人用户设为负数
gid = -ctx.Event.UserID
}
logrus.Debugln("[fortune]gid:", ctx.Event.GroupID, "uid:", ctx.Event.UserID)
if v, ok := conf.Kind[gid]; ok {
kind = table[v]
}
// 检查背景图片是否存在
folder := base + kind
if file.IsNotExist(folder) {
ctx.SendChain(message.Text("正在下载背景图片,请稍后..."))
zipfile := kind + ".zip"
zipcache := base + zipfile
err := file.DownloadTo(site+zipfile, zipcache)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("下载背景图片完毕"))
err = unpack(zipcache, folder+"/")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("解压背景图片完毕"))
// 释放空间
os.Remove(zipcache)
}
// 生成种子
t, _ := strconv.ParseInt(time.Now().Format("20060102"), 10, 64)
seed := ctx.Event.UserID + t
// 随机获取背景
background, err := randimage(folder+"/", seed)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// 随机获取签文
title, text, err := randtext(mikuji, seed)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// 绘制背景
d, err := draw(background, title, text)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
// 发送图片
ctx.SendChain(message.Image("base64://" + helper.BytesToString(d)))
})
}
// @function unpack 解压资源包
// @param tgt 压缩文件位置
// @param dest 解压位置
// @return 错误信息
func unpack(tgt, dest string) error {
// 路径目录不存在则创建目录
if file.IsNotExist(dest) {
if err := os.MkdirAll(dest, 0755); err != nil {
panic(err)
}
}
reader, err := zip.OpenReader(tgt)
if err != nil {
return err
}
defer reader.Close()
// 遍历解压到文件
for _, file := range reader.File {
// 打开解压文件
rc, err := file.Open()
if err != nil {
return err
}
// 打开目标文件
w, err := os.OpenFile(dest+file.Name, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err != nil {
rc.Close()
return err
}
// 复制到文件
_, err = io.Copy(w, rc)
rc.Close()
w.Close()
if err != nil {
return err
}
}
return nil
}
// @function randimage 随机选取文件夹下的文件
// @param path 文件夹路径
// @param seed 随机数种子
// @return 文件路径 & 错误信息
func randimage(path string, seed int64) (string, error) {
rd, err := ioutil.ReadDir(path)
if err != nil {
return "", err
}
rand.Seed(seed)
return path + rd[rand.Intn(len(rd))].Name(), nil
}
// @function randtext 随机选取签文
// @param file 文件路径
// @param seed 随机数种子
// @return 签名 & 签文 & 错误信息
func randtext(file string, seed int64) (string, string, error) {
data, err := ioutil.ReadFile(file)
if err != nil {
return "", "", err
}
temp := []map[string]string{}
if err := json.Unmarshal(data, &temp); err != nil {
return "", "", err
}
rand.Seed(seed)
r := rand.Intn(len(temp))
return temp[r]["title"], temp[r]["content"], nil
}
// @function draw 绘制运势图
// @param background 背景图片路径
// @param seed 随机数种子
// @param title 签名
// @param text 签文
// @return 错误信息
func draw(background, title, text string) ([]byte, error) {
// 加载背景
back, err := gg.LoadImage(background)
if err != nil {
return nil, err
}
canvas := gg.NewContext(back.Bounds().Size().Y, back.Bounds().Size().X)
canvas.DrawImage(back, 0, 0)
// 写标题
canvas.SetRGB(1, 1, 1)
if err := canvas.LoadFontFace(base+"sakura.ttf", 45); err != nil {
return nil, err
}
sw, _ := canvas.MeasureString(title)
canvas.DrawString(title, 140-sw/2, 112)
// 写正文
canvas.SetRGB(0, 0, 0)
if err := canvas.LoadFontFace(base+"sakura.ttf", 23); err != nil {
return nil, err
}
tw, th := canvas.MeasureString("测")
tw, th = tw+10, th+10
r := []rune(text)
xsum := rowsnum(len(r), 9)
switch xsum {
default:
for i, o := range r {
xnow := rowsnum(i+1, 9)
ysum := math.Min(len(r)-(xnow-1)*9, 9)
ynow := i%9 + 1
canvas.DrawString(string(o), -offest(xsum, xnow, tw)+115, offest(ysum, ynow, th)+320.0)
}
case 2:
div := rowsnum(len(r), 2)
for i, o := range r {
xnow := rowsnum(i+1, div)
ysum := math.Min(len(r)-(xnow-1)*div, div)
ynow := i%div + 1
switch xnow {
case 1:
canvas.DrawString(string(o), -offest(xsum, xnow, tw)+115, offest(9, ynow, th)+320.0)
case 2:
canvas.DrawString(string(o), -offest(xsum, xnow, tw)+115, offest(9, ynow+(9-ysum), th)+320.0)
}
}
}
// 转成 base64
buffer := new(bytes.Buffer)
encoder := base64.NewEncoder(base64.StdEncoding, buffer)
var opt jpeg.Options
opt.Quality = 70
err = jpeg.Encode(encoder, canvas.Image(), &opt)
if err != nil {
return nil, err
}
encoder.Close()
return buffer.Bytes(), nil
}
func offest(total, now int, distance float64) float64 {
if total%2 == 0 {
return (float64(now-total/2) - 1) * distance
}
return (float64(now-total/2) - 1.5) * distance
}
func rowsnum(total, div int) int {
temp := total / div
if total%div != 0 {
temp++
}
return temp
}

View File

@@ -3,10 +3,10 @@ package hs
import (
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
"github.com/imroc/req"
"github.com/tidwall/gjson"
@@ -14,9 +14,10 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
const cachedir = "data/hs/"
var cachedir = file.BOT_PATH + "/data/hs/"
var header = req.Header{
"user-agent": `Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Mobile Safari/537.36`,
@@ -41,40 +42,48 @@ func init() {
SetBlock(true).SetPriority(20).Handle(func(ctx *zero.Ctx) {
List := ctx.State["regex_matched"].([]string)[1]
g := sh(List)
im, _ := req.Get(`https://res.fbigame.com/hs/v13/`+
gjson.Get(g, `list.0.CardID`).String()+
`.png?auth_key=`+
gjson.Get(g, `list.0.auth_key`).String(), header)
cachefile := cachedir + strconv.Itoa(int(time.Now().Unix()))
err := im.ToFile(cachefile)
if err == nil {
file, err := os.Open(cachefile)
if err == nil {
defer file.Close()
sg, _ := req.Post("https://pic.sogou.com/pic/upload_pic.jsp", req.FileUpload{
File: file,
FieldName: "image", // FieldName 是表单字段名
FileName: "avatar.png", // Filename 是要上传的文件的名称我们使用它来猜测mimetype并将其上传到服务器上
})
var tx string
t := int(gjson.Get(g, `list.#`).Int())
if t == 0 {
ctx.Send("查询为空!")
return
}
for i := 0; i < t && i < 10; i++ {
tx += strconv.Itoa(i+1) + ". 法力:" +
gjson.Get(g, `list.`+strconv.Itoa(i)+`.COST`).String() +
" " +
gjson.Get(g, `list.`+strconv.Itoa(i)+`.CARDNAME`).String() +
"\n"
}
ctx.SendChain(
message.Image(sg.String()),
message.Text(tx),
)
}
t := int(gjson.Get(g, `list.#`).Int())
if t == 0 {
ctx.SendChain(message.Text("查询为空!"))
return
}
var sk message.Message
var data []byte
for i := 0; i < t && i < 5; i++ {
cid := gjson.Get(g, `list.`+strconv.Itoa(i)+`.CardID`).String()
cachefile := cachedir + cid
imgcq := `[CQ:image,file=` + "file:///" + cachefile + `]`
if file.IsNotExist(cachefile) {
im, err := req.Get(`https://res.fbigame.com/hs/v13/`+cid+
`.png?auth_key=`+gjson.Get(g, `list.`+strconv.Itoa(i)+`.auth_key`).String(),
header,
)
if err == nil {
data, err = io.ReadAll(im.Response().Body)
if err == nil {
err = im.Response().Body.Close()
if err == nil {
err = os.WriteFile(cachefile, data, 0644)
}
}
}
if err != nil {
imgcq = err.Error()
}
}
sk = append(
sk,
message.CustomNode(
ctx.Event.Sender.NickName,
ctx.Event.UserID,
imgcq, // 图片
),
)
}
ctx.SendGroupForwardMessage(
ctx.Event.GroupID,
sk,
)
})
// 卡组
engine.OnRegex(`^[\s\S]*?(AAE[a-zA-Z0-9/\+=]{70,})[\s\S]*$`).

View File

@@ -70,7 +70,7 @@ func init() {
keyword := ctx.State["regex_matched"].([]string)[1]
soutujson := soutuapi(keyword)
pom1 := "https://i.pixiv.cat"
rannum := randint()
rannum := randintn(len(soutujson.Illusts))
pom2 := soutujson.Illusts[rannum].ImageUrls.Large[19:]
ctx.SendChain(message.Image(pom1 + pom2))
})
@@ -88,7 +88,7 @@ func soutuapi(keyword string) *resultjson {
fmt.Println(err)
}
req.Header.Add("accept", "application/json, text/plain, */*")
req.Header.Add("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
@@ -102,8 +102,8 @@ func soutuapi(keyword string) *resultjson {
return result
}
// randint 从json里的30条数据中随机获取一条返回
func randint() int {
// randintn 从json里的30条数据中随机获取一条返回
func randintn(len int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(30)
return rand.Intn(len)
}

View File

@@ -11,6 +11,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
const (
@@ -30,7 +31,7 @@ func init() {
}).OnFullMatch("来份萝莉").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
go func() {
for i := 0; i < min(cap(queue)-len(queue), 2); i++ {
for i := 0; i < math.Min(cap(queue)-len(queue), 2); i++ {
resp, err := http.Get(api)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
@@ -60,10 +61,3 @@ func init() {
}
})
}
func min(a, b int) int {
if a < b {
return a
}
return b
}

View File

@@ -6,14 +6,19 @@ import (
"io"
"math/rand"
"os"
"sort"
"strconv"
"strings"
"time"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
timer "github.com/FloatTech/ZeroBot-Plugin-Timer"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
)
const (
@@ -46,6 +51,7 @@ const (
var (
config Config
limit = rate.NewManager(time.Minute*5, 2)
)
func init() { // 插件主体
@@ -53,7 +59,7 @@ func init() { // 插件主体
// 菜单
zero.OnFullMatch("群管系统", zero.AdminPermission).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
ctx.Send(hint)
ctx.SendChain(message.Text(hint))
})
// 升为管理
zero.OnRegex(`^升为管理.*?(\d+)`, zero.OnlyGroup, zero.SuperUserPermission).SetBlock(true).SetPriority(40).
@@ -249,9 +255,9 @@ func init() { // 插件主体
ts.Grpid = uint64(ctx.Event.GroupID)
if ts.Enable {
go timer.RegisterTimer(ts, true)
ctx.Send("记住了~")
ctx.SendChain(message.Text("记住了~"))
} else {
ctx.Send("参数非法!")
ctx.SendChain(message.Text("参数非法!"))
}
}
})
@@ -268,9 +274,9 @@ func init() { // 插件主体
t.Enable = false
delete(*timer.Timers, ti) // 避免重复取消
_ = timer.SaveTimers()
ctx.Send("取消成功~")
ctx.SendChain(message.Text("取消成功~"))
} else {
ctx.Send("没有这个定时器哦~")
ctx.SendChain(message.Text("没有这个定时器哦~"))
}
}
})
@@ -278,22 +284,46 @@ func init() { // 插件主体
zero.OnFullMatch("列出所有提醒", zero.AdminPermission).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
if ctx.Event.GroupID > 0 {
ctx.Send(fmt.Sprint(timer.ListTimers(uint64(ctx.Event.GroupID))))
ctx.SendChain(message.Text(timer.ListTimers(uint64(ctx.Event.GroupID))))
}
})
// 随机点名
zero.OnFullMatchGroup([]string{"翻牌"}).SetBlock(true).SetPriority(40).
zero.OnFullMatchGroup([]string{"翻牌"}, zero.OnlyGroup).SetBlock(true).SetPriority(40).
Handle(func(ctx *zero.Ctx) {
if ctx.Event.GroupID > 0 {
list := ctx.GetGroupMemberList(ctx.Event.GroupID)
rand.Seed(time.Now().UnixNano())
randIndex := fmt.Sprint(rand.Intn(int(list.Get("#").Int())))
randCard := list.Get(randIndex + ".card").String()
if randCard == "" {
randCard = list.Get(randIndex + ".nickname").String()
}
ctx.Send(randCard + ",就是你啦!")
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.SendChain(message.Text("少女祈祷中......"))
return
}
// 无缓存获取群员列表
list := ctx.CallAction("get_group_member_list", zero.Params{
"group_id": ctx.Event.GroupID,
"no_cache": true,
}).Data
temp := list.Array()
sort.SliceStable(temp, func(i, j int) bool {
return temp[i].Get("last_sent_time").Int() < temp[j].Get("last_sent_time").Int()
})
temp = temp[math.Max(0, len(temp)-10):]
rand.Seed(time.Now().UnixNano())
who := temp[rand.Intn(len(temp))]
if who.Get("user_id").Int() == ctx.Event.SelfID {
ctx.SendChain(message.Text("幸运儿居然是我自己"))
return
}
if who.Get("user_id").Int() == ctx.Event.UserID {
ctx.SendChain(message.Text("哎呀,就是你自己了"))
return
}
nick := who.Get("card").Str
if nick == "" {
nick = who.Get("nickname").Str
}
ctx.SendChain(
message.Text(
nick,
" 就是你啦!",
),
)
})
// 入群欢迎
zero.OnNotice().SetBlock(false).FirstPriority().
@@ -301,9 +331,9 @@ func init() { // 插件主体
if ctx.Event.NoticeType == "group_increase" {
word, ok := config.Welcome[uint64(ctx.Event.GroupID)]
if ok {
ctx.Send(word)
ctx.SendChain(message.Text(word))
} else {
ctx.Send("欢迎~")
ctx.SendChain(message.Text("欢迎~"))
}
enable, ok1 := config.Checkin[uint64(ctx.Event.GroupID)]
if ok1 && enable {
@@ -320,7 +350,7 @@ func init() { // 插件主体
ans, err := strconv.Atoi(text)
if err == nil {
if ans != r {
ctx.Send("答案不对哦,再想想吧~")
ctx.SendChain(message.Text("答案不对哦,再想想吧~"))
return false
}
return true
@@ -333,12 +363,12 @@ func init() { // 插件主体
recv, cancel := next.Repeat()
select {
case <-time.After(time.Minute):
ctx.Send("拜拜啦~")
ctx.SendChain(message.Text("拜拜啦~"))
ctx.SetGroupKick(ctx.Event.GroupID, uid, false)
cancel()
case <-recv:
cancel()
ctx.Send("答对啦~")
ctx.SendChain(message.Text("答对啦~"))
}
}
}
@@ -355,9 +385,9 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
config.Welcome[uint64(ctx.Event.GroupID)] = ctx.State["regex_matched"].([]string)[1]
if saveConfig() == nil {
ctx.Send("记住啦!")
ctx.SendChain(message.Text("记住啦!"))
} else {
ctx.Send("出错啦!")
ctx.SendChain(message.Text("出错啦!"))
}
})
// 入群验证开关
@@ -373,9 +403,9 @@ func init() { // 插件主体
return
}
if saveConfig() == nil {
ctx.Send("已" + option)
ctx.SendChain(message.Text("已", option))
} else {
ctx.Send("出错啦!")
ctx.SendChain(message.Text("出错啦!"))
}
})
// 运行 CQ 码
@@ -384,6 +414,7 @@ func init() { // 插件主体
var cmd = ctx.State["regex_matched"].([]string)[1]
cmd = strings.ReplaceAll(cmd, "&#91;", "[")
cmd = strings.ReplaceAll(cmd, "&#93;", "]")
// 可注入,权限为主人
ctx.Send(cmd)
})
}
@@ -397,7 +428,7 @@ func strToInt(str string) int64 {
func loadConfig() {
mkdirerr := os.MkdirAll(datapath, 0755)
if mkdirerr == nil {
if _, err := os.Stat(confile); err == nil || os.IsExist(err) {
if file.IsExist(confile) {
f, err := os.Open(confile)
if err == nil {
data, err1 := io.ReadAll(f)
@@ -422,7 +453,7 @@ func saveConfig() error {
data, err := config.Marshal()
if err != nil {
return err
} else if _, err := os.Stat(datapath); err == nil || os.IsExist(err) {
} else if file.IsExist(datapath) {
f, err1 := os.OpenFile(confile, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0644)
if err1 != nil {
return err1

View File

@@ -19,24 +19,23 @@ import (
const api = "http://your.addr:23333/api/start_server/%s/?apikey=apikey"
var engine *zero.Engine
var engine = control.Register("minecraft", &control.Options{
DisableOnDefault: false,
Help: "minecraft\n" +
"- /mcstart xxx\n" +
"- /mcstop xxx\n" +
"- /mclist servername\n" +
"- https://github.com/Suwings/MCSManager",
})
func init() {
engine = control.Register("minecraft", &control.Options{
DisableOnDefault: false,
Help: "minecraft\n" +
"- /mcstart xxx\n" +
"- /mcstop xxx\n" +
"- /mclist servername\n" +
"- https://github.com/Suwings/MCSManager",
})
engine.OnCommand("mcstart").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
model := extension.CommandModel{}
_ = ctx.Parse(&model)
ctx.SendChain(message.Text("开启服务器: ", model.Args, "....."))
result := start(model.Args)
ctx.Send(result)
ctx.SendChain(message.Text(result))
})
engine.OnCommand("mcstop").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
@@ -44,7 +43,7 @@ func init() {
_ = ctx.Parse(&model)
ctx.SendChain(message.Text("开启服务器: ", model.Args, "....."))
result := stop(model.Args)
ctx.Send(result)
ctx.SendChain(message.Text(result))
})
}

View File

@@ -32,7 +32,7 @@ func init() {
}).OnRegex("^(.{0,2})点歌(.{1,25})$").SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.Send("请稍后重试0x0...")
ctx.SendChain(message.Text("请稍后重试0x0..."))
return
}
// switch 平台

47
plugin_nbnhhsh/nbnhhsh.go Normal file
View File

@@ -0,0 +1,47 @@
// Package nbnhhsh 能不能好好说话
package nbnhhsh
import (
"io/ioutil"
"net/http"
"net/url"
"strings"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
func init() {
zero.OnRegex(`^[?]{1,2} ?([a-z0-9]+)$`).SetBlock(false).
Handle(func(ctx *zero.Ctx) {
keyword := ctx.State["regex_matched"].([]string)[1]
ctx.SendChain(message.Text(keyword + ": " + strings.Join(getValue(keyword), ", ")))
})
}
func getValue(text string) []string {
urlValues := url.Values{}
urlValues.Add("text", text)
resp, err := http.PostForm("https://lab.magiconch.com/api/nbnhhsh/guess", urlValues)
if err == nil {
body, err := ioutil.ReadAll(resp.Body)
if err == nil {
resp.Body.Close()
json := gjson.ParseBytes(body)
res := make([]string, 0)
var jsonPath string
if json.Get("0.trans").Exists() {
jsonPath = "0.trans"
} else {
jsonPath = "0.inputting"
}
for _, value := range json.Get(jsonPath).Array() {
res = append(res, value.String())
}
return res
}
return []string{err.Error()}
}
return []string{err.Error()}
}

View File

@@ -17,14 +17,12 @@ const (
)
func init() { // 插件主体
// TODO: 1.17 特性暂不增加
// rand.Seed(time.Now().UnixMicro())
rand.Seed(time.Now().UnixNano())
control.Register("omikuji", &control.Options{
DisableOnDefault: false,
Help: "浅草寺求签\n" +
"- 求签|运势|占卜",
}).OnFullMatchGroup([]string{"求签", "运势", "占卜"}).SetPriority(10).SetBlock(true).
"- 求签|占卜",
}).OnFullMatchGroup([]string{"求签", "占卜"}).SetPriority(10).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
miku := rand.Intn(100) + 1
ctx.SendChain(

View File

@@ -1,6 +1,7 @@
// TODO: 待优化
package qingyunke
// TODO: 待优化
/*
import (
"fmt"

View File

@@ -1,6 +1,4 @@
/*
基于青云客接口的聊天对话功能
*/
// Package qingyunke 基于青云客接口的聊天对话功能
package qingyunke
import (

View File

@@ -1,6 +1,7 @@
// TODO: 移动到 manager 搭配自动验证使用
package qingyunke
// TODO: 移动到 manager 搭配自动验证使用
/*
import (
zero "github.com/wdvxdr1123/ZeroBot"

21
plugin_reborn/born.go Normal file
View File

@@ -0,0 +1,21 @@
package reborn
import (
wr "github.com/mroth/weightedrand"
)
var (
gender, _ = wr.NewChooser(
wr.Choice{Item: "男孩子", Weight: 50707},
wr.Choice{Item: "女孩子", Weight: 48292},
wr.Choice{Item: "雌雄同体", Weight: 1001},
)
)
func randcoun() string {
return areac.Pick().(string)
}
func randgen() string {
return gender.Pick().(string)
}

93
plugin_reborn/load.go Normal file
View File

@@ -0,0 +1,93 @@
package reborn
import (
"encoding/json"
"io"
"net/http"
"os"
"time"
wr "github.com/mroth/weightedrand"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
const (
datapath = "data/Reborn"
jsonfile = datapath + "/rate.json"
pburl = "https://codechina.csdn.net/u011570312/ZeroBot-Plugin/-/raw/master/" + jsonfile
)
type rate []struct {
Name string `json:"name"`
Weight float64 `json:"weight"`
}
var (
areac *wr.Chooser
)
func init() {
go func() {
time.Sleep(time.Second)
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
}
area := make(rate, 226)
err = load(&area)
if err != nil {
panic(err)
}
choices := make([]wr.Choice, len(area))
for i, a := range area {
choices[i].Item = a.Name
choices[i].Weight = uint(a.Weight * 1e9)
}
areac, err = wr.NewChooser(choices...)
if err != nil {
panic(err)
}
log.Printf("[Reborn]读取%d个国家/地区", len(area))
}()
}
// load 加载rate数据
func load(area *rate) error {
if file.IsExist(jsonfile) {
f, err := os.Open(jsonfile)
if err == nil {
defer f.Close()
data, err1 := io.ReadAll(f)
if err1 == nil {
if len(data) > 0 {
return json.Unmarshal(data, area)
}
}
return err1
}
} else { // 如果没有小作文,则从 url 下载
f, err := os.Create(jsonfile)
if err != nil {
return err
}
defer f.Close()
resp, err := http.Get(pburl)
if err == nil {
defer resp.Body.Close()
if resp.ContentLength > 0 {
log.Printf("[Reborn]从镜像下载国家和地区%d字节...", resp.ContentLength)
data, err := io.ReadAll(resp.Body)
if err == nil && len(data) > 0 {
_, _ = f.Write(data)
return json.Unmarshal(data, area)
}
return err
}
return nil
}
return err
}
return nil
}

28
plugin_reborn/main.go Normal file
View File

@@ -0,0 +1,28 @@
// Package reborn 投胎 来自 https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py
package reborn
import (
"fmt"
"math/rand"
"time"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
)
func init() {
rand.Seed(time.Now().UnixNano())
control.Register("reborn", &control.Options{
DisableOnDefault: false,
Help: "投胎\n- reborn",
}).OnFullMatch("reborn").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
if rand.Int31() > 1<<27 {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text(fmt.Sprintf("投胎成功!\n您出生在 %s, 是 %s。", randcoun(), randgen())))
} else {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("投胎失败!\n您没能活到出生祝您下次好运"))
}
})
}

View File

@@ -107,7 +107,7 @@ func init() {
}).OnRegex(`^>runcode\s(.+?)\s([\s\S]+)$`).SetBlock(true).SecondPriority().
Handle(func(ctx *zero.Ctx) {
if !limit.Load(ctx.Event.UserID).Acquire() {
ctx.Send("请稍后重试0x0...")
ctx.SendChain(message.Text("请稍后重试0x0..."))
} else {
language := ctx.State["regex_matched"].([]string)[1]
language = strings.ToLower(language)

View File

@@ -3,21 +3,31 @@ package saucenao
import (
"fmt"
"os"
"strconv"
"strings"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/AnimeAPI/ascii2d"
"github.com/FloatTech/AnimeAPI/picture"
"github.com/FloatTech/AnimeAPI/pixiv"
"github.com/FloatTech/AnimeAPI/saucenao"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
"github.com/FloatTech/ZeroBot-Plugin/utils/file"
)
var (
datapath = file.BOT_PATH + "/data/saucenao/"
)
func init() { // 插件主体
_ = os.RemoveAll(datapath)
err := os.MkdirAll(datapath, 0755)
if err != nil {
panic(err)
}
engine := control.Register("saucenao", &control.Options{
DisableOnDefault: false,
Help: "搜图\n" +
@@ -28,7 +38,7 @@ func init() { // 插件主体
engine.OnRegex(`^搜图(\d+)$`).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
id, _ := strconv.ParseInt(ctx.State["regex_matched"].([]string)[1], 10, 64)
ctx.Send("少女祈祷中......")
ctx.SendChain(message.Text("少女祈祷中......"))
// 获取P站插图信息
illust, err := pixiv.Works(id)
if err != nil {
@@ -36,30 +46,48 @@ func init() { // 插件主体
return
}
if illust.Pid > 0 {
// 改用 i.pixiv.cat 镜像站
link := illust.ImageUrls
link = strings.ReplaceAll(link, "i.pximg.net", "i.pixiv.cat")
// 发送搜索结果
ctx.SendChain(
message.Image(link),
message.Text(
"\n",
"标题:", illust.Title, "\n",
"插画ID", illust.Pid, "\n",
"画师:", illust.UserName, "\n",
"画师ID", illust.UserId, "\n",
"直链:", "https://pixivel.moe/detail?id=", illust.Pid,
),
name := strconv.FormatInt(illust.Pid, 10)
filepath := datapath + name
switch {
case file.IsExist(filepath + ".jpg"):
filepath = "file:///" + filepath + ".jpg"
case file.IsExist(filepath + ".png"):
filepath = "file:///" + filepath + ".png"
case file.IsExist(filepath + ".gif"):
filepath = "file:///" + filepath + ".gif"
default:
filepath = ""
}
if filepath == "" {
logrus.Debug("[sausenao]开始下载", name)
filepath, err = pixiv.Download(illust.ImageUrls, datapath, name)
if err == nil {
filepath = "file:///" + filepath
}
}
txt := message.Text(
"标题:", illust.Title, "\n",
"插画ID", illust.Pid, "\n",
"画师:", illust.UserName, "\n",
"画师ID", illust.UserId, "\n",
"直链:", "https://pixivel.moe/detail?id=", illust.Pid,
)
if filepath != "" {
// 发送搜索结果
ctx.SendChain(message.Image(filepath), message.Text("\n"), txt)
} else {
// 图片下载失败,仅发送文字结果
ctx.SendChain(txt)
}
} else {
ctx.Send("图片不存在!")
ctx.SendChain(message.Text("图片不存在!"))
}
})
// 以图搜图
engine.OnKeywordGroup([]string{"以图搜图", "搜索图片", "以图识图"}, picture.CmdMatch, picture.MustGiven).SetBlock(true).FirstPriority().
Handle(func(ctx *zero.Ctx) {
// 开始搜索图片
ctx.Send("少女祈祷中......")
ctx.SendChain(message.Text("少女祈祷中......"))
for _, pic := range ctx.State["image_url"].([]string) {
fmt.Println(pic)
if result, err := saucenao.SauceNAO(pic); err != nil {

View File

@@ -18,13 +18,15 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/ZeroBot-Plugin/control"
. "github.com/FloatTech/ZeroBot-Plugin/data"
fileutil "github.com/FloatTech/ZeroBot-Plugin/utils/file"
"github.com/FloatTech/ZeroBot-Plugin/utils/math"
"github.com/FloatTech/ZeroBot-Plugin/utils/sql"
)
// Pools 图片缓冲池
type imgpool struct {
Lock sync.Mutex
DB *Sqlite
DB *sql.Sqlite
Path string
Group int64
List []string
@@ -40,7 +42,7 @@ const (
// NewPoolsCache 返回一个缓冲池对象
func newPools() *imgpool {
cache := &imgpool{
DB: &Sqlite{DBPath: "data/SetuTime/SetuTime.db"},
DB: &sql.Sqlite{DBPath: "data/SetuTime/SetuTime.db"},
Path: "data/SetuTime/cache/",
Group: 0,
List: []string{"涩图", "二次元", "风景", "车万"}, // 可以自己加类别,得自己加图片进数据库
@@ -48,6 +50,8 @@ func newPools() *imgpool {
Pool: map[string][]*pixiv.Illust{},
Form: 0,
}
// 每次启动清理缓存
os.RemoveAll(cache.Path)
err := os.MkdirAll(cache.Path, 0755)
if err != nil {
panic(err)
@@ -104,7 +108,7 @@ func init() { // 插件主体
var imgtype = ctx.State["regex_matched"].([]string)[1]
// 补充池子
go func() {
times := min(pool.Max-pool.size(imgtype), 2)
times := math.Min(pool.Max-pool.size(imgtype), 2)
for i := 0; i < times; i++ {
illust := &pixiv.Illust{}
// 查询出一张图片
@@ -120,7 +124,6 @@ func init() { // 插件主体
ctx.SendGroupMessage(pool.Group, []message.MessageSegment{message.Image(file(illust))})
// 向缓冲池添加一张图片
pool.push(imgtype, illust)
time.Sleep(time.Second * 1)
}
}()
@@ -167,7 +170,7 @@ func init() { // 插件主体
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.Send("添加成功")
ctx.SendChain(message.Text("添加成功"))
})
engine.OnRegex(`^删除(.*?)(\d+)$`, firstValueInList(pool.List), zero.SuperUserPermission).SetBlock(true).SetPriority(22).
@@ -178,10 +181,10 @@ func init() { // 插件主体
)
// 查询数据库
if err := pool.DB.Del(imgtype, fmt.Sprintf("WHERE pid=%d", id)); err != nil {
ctx.Send(fmt.Sprintf("ERROR: %v", err))
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.Send("删除成功")
ctx.SendChain(message.Text("删除成功"))
})
// 查询数据库涩图数量
@@ -198,7 +201,7 @@ func init() { // 插件主体
state = append(state, ": ")
state = append(state, fmt.Sprintf("%d", num))
}
ctx.Send(strings.Join(state, ""))
ctx.SendChain(message.Text(state))
})
}
@@ -215,18 +218,6 @@ func firstValueInList(list []string) zero.Rule {
}
}
// min 返回两数最小值
func min(a, b int) int {
switch {
default:
return a
case a > b:
return b
case a < b:
return a
}
}
// size 返回缓冲池指定类型的现有大小
func (p *imgpool) size(imgtype string) int {
return len(p.Pool[imgtype])
@@ -259,8 +250,7 @@ func (p *imgpool) pop(imgtype string) (illust *pixiv.Illust) {
func file(i *pixiv.Illust) string {
filename := fmt.Sprint(i.Pid)
pwd, _ := os.Getwd()
filepath := pwd + `/` + pool.Path + filename
filepath := fileutil.BOT_PATH + `/` + pool.Path + filename
if _, err := os.Stat(filepath + ".jpg"); err == nil || os.IsExist(err) {
return `file:///` + filepath + ".jpg"
}

View File

@@ -1,3 +1,10 @@
/*
* @Author: Kanri
* @Date: 2021-10-15 21:23:14
* @LastEditors: Kanri
* @LastEditTime: 2021-10-15 21:42:51
* @Description:
*/
// Package shindan 基于 https://shindanmaker.com 的测定小功能
package shindan
@@ -52,6 +59,7 @@ func handle(ctx *zero.Ctx) {
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
}
// TODO: 可注入
ctx.Send(text)
}

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

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

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

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

23
utils/file/dl.go Normal file
View File

@@ -0,0 +1,23 @@
// Package file 文件实用工具
package file
import (
"io"
"net/http"
"os"
)
// DownloadTo 下载到路径
func DownloadTo(url, file string) error {
resp, err := http.Get(url)
if err == nil {
var f *os.File
f, err = os.Create(file)
if err == nil {
_, err = io.Copy(f, resp.Body)
resp.Body.Close()
f.Close()
}
}
return err
}

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

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

18
utils/math/math.go Normal file
View File

@@ -0,0 +1,18 @@
// Package math 计算实用工具
package math
// Max 返回两数最大值,该函数将被内联
func Max(a, b int) int {
if a > b {
return a
}
return b
}
// Min 返回两数最小值,该函数将被内联
func Min(a, b int) int {
if a > b {
return b
}
return a
}

View File

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