Compare commits

..

164 Commits

Author SHA1 Message Date
源文雨
a248bb1420 🔖 v1.8.4 2024-10-05 21:11:57 +09:00
方柳煜
95451f96d8 optimize(mcfish): 限制鱼贩的垄断 (#992) 2024-10-05 21:10:30 +09:00
YumeMichi
f3a841fc60 fix: aireply: 修复文字回复模式 (#991)
更新桑帛云api,添加key设置

Signed-off-by: Sean Du <do4suki@gmail.com>
2024-10-05 21:09:47 +09:00
源文雨
e4cfcef05b fix(manager): forward send 2024-10-01 17:00:00 +09:00
github-actions[bot]
be26b052a6 chore: bump deps (#989)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-01 16:52:26 +09:00
源文雨
c2b7ae31cc chore: update deps 2024-10-01 16:42:50 +09:00
github-actions[bot]
7d48916d2c chore: bump deps (#987)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-01 16:26:08 +09:00
源文雨
a15c241bd6 fix(manager): remove fake sender 2024-10-01 16:24:24 +09:00
源文雨
5e91bd7a63 chore: update deps 2024-10-01 16:14:07 +09:00
源文雨
817c4fab61 feat(manager): add slow send (#985) 2024-10-01 16:11:37 +09:00
github-actions[bot]
fbadd8924f chore(lint): 改进代码样式 (#986)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-01 14:50:41 +09:00
宇~
c008214be4 fix: 牛牛为负数时jj时的错误 (#984) 2024-10-01 14:48:08 +09:00
github-actions[bot]
54471d16e4 chore(lint): 改进代码样式 (#982)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-27 14:51:57 +09:00
宇~
6f7d4beb17 fix: 修正niuniu的部分逻辑 (#981) 2024-09-27 14:49:51 +09:00
源文雨
2cee275771 🔖 v1.8.3 2024-09-26 16:48:55 +09:00
github-actions[bot]
9de8092416 chore(lint): 改进代码样式 (#980)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-26 16:34:36 +09:00
宇~
3cffc36dec fix&feat(niuniu): 修复已知问题,添加新玩法牛牛商店 (#974) 2024-09-26 07:30:16 +00:00
vatebur
7d5c770398 fix(score): 签到图片余额为0(#978) (#979) 2024-09-26 16:25:46 +09:00
vatebur
13ef54ef62 fix:修改niuniu插件at功能正则,提高兼容性 (#973) 2024-09-06 21:13:27 +09:00
github-actions[bot]
6ec3dff78a chore: bump deps (#972)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-05 01:24:50 +09:00
源文雨
158baea605 chore: update deps 2024-09-05 01:05:08 +09:00
github-actions[bot]
e861b66ace chore(lint): 改进代码样式 (#971)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-09-04 00:25:13 +09:00
源文雨
3866ff8a46 🔖 v1.8.2 2024-09-04 00:23:58 +09:00
小宇宇
863f99cb05 fix&feat(niuniu): 添加新玩法赎牛牛 (#970) 2024-09-04 00:22:09 +09:00
源文雨
badd65a207 chore(doc): update README 2024-08-30 18:05:10 +08:00
github-actions[bot]
ff62723e91 chore(lint): 改进代码样式 (#968)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-30 18:04:14 +08:00
github-actions[bot]
7b45374310 chore: bump deps (#967)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-30 18:00:23 +08:00
小宇宇
3da55c4b75 feat: 新插件 牛牛大作战 (#944) 2024-08-30 17:59:51 +08:00
源文雨
a7d2a31bb8 chore: update deps 2024-08-30 17:57:54 +08:00
copurxia
074e77dfa2 fix: regex error (#965)
* fix regex

* fix regex error
2024-08-23 11:29:39 +08:00
github-actions[bot]
ac909f95db chore: bump deps (#962)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-22 14:58:41 +08:00
源文雨
4fd923c731 chore: update deps 2024-08-22 14:56:26 +08:00
copurxia
4b771f2809 fix(qqwife&robbery): at 解析问题 (#961)
* fix(gif, qqwife): at 解析问题

适配买礼物的at解析问题

* fix(robbery): at 解析问题

robbery同样的@解析问题

* Update robbery.go

* Update favorSystem.go
2024-08-22 14:38:34 +08:00
starim00
89a5b68601 fix(gif, qqwife): at 解析问题 (#960)
Co-authored-by: hutiance <hutiance@newings.net.cn>
Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
2024-08-21 03:08:20 +00:00
源文雨
adbcb3956d chore: make lint happy 2024-08-21 11:05:15 +08:00
github-actions[bot]
293859460b chore: bump deps (#958)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-20 00:30:58 +08:00
源文雨
c8594cfc54 chore: update deps 2024-08-20 00:11:43 +08:00
vatebur
31b70179f9 fix(wallet): 修复钱包余额判断逻辑 (#957)
- ”管理钱包余额“里的amount变量带符号
- “钱包转账”里的amount变量不带符号
2024-08-19 23:56:04 +08:00
github-actions[bot]
5d2898bc53 chore(lint): 改进代码样式 (#956)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-19 20:16:41 +08:00
github-actions[bot]
47f176a56e chore(lint): 改进代码样式 (#955)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-08-19 19:54:08 +08:00
源文雨
fa02189fad fix(workflow): build docker 2024-08-19 19:52:38 +08:00
源文雨
de558dc87b chore: make lint happy 2024-08-19 19:50:35 +08:00
源文雨
c9939d145b chore: make lint happy 2024-08-19 19:49:48 +08:00
vatebur
852c5f2f35 feat(wallet): 完善钱包管理和查询功能 (#954)
1. 新增“管理钱包余额”功能,仅超级用户可用
2. 重构“查看我的钱包功能”,可以查看任意群员的钱包
3. 增加“钱包转账”功能

有问题的地方:
1.任何人的钱包都可查,群友钱包余额泄露
2. ”管理钱包余额“和“钱包转账”代码高度相似,是否有必要优化

* chore: update readme
2024-08-19 19:46:45 +08:00
源文雨
1c0f8ffadb chore: update zbpdata 2024-08-09 01:05:52 +08:00
Eat Hatsune Shallots
2a4aa39bab feat: configurable custom coin name (#950) 2024-08-08 18:02:53 +08:00
CUU_rooooo!
26fcb5aad5 fix(mcfish): 合成的鱼竿可能多给 (#949)
* fix(mcfish): 合成的鱼竿可能多给

- 不使用梭哈功能合成鱼竿时,生成鱼竿仍然按梭哈合成计算,导致鱼竿可能多给
- 完善提示文本

* fix(mcfish): 出售所有垃圾功能不给钱

出售所有垃圾没有对钱包金额进行更新

* fix(mcfish): 使用美西螈钓鱼,吞鱼异常的问题

fishInfo.Number = 0 位置不对,导致海豚和鳕鱼都吃了100条。会一直吃到某种鱼数量够为止,并且前面数量不够的鱼都白吃了
2024-08-08 13:11:54 +08:00
源文雨
9119ded754 fix(kfccrazythursday): api cert 2024-08-07 00:12:12 +08:00
CUU_rooooo!
f6ef326495 fix(mcfish): 鱼竿Number大于1,合成时少鱼竿的情况 (#947)
合成鱼竿未考虑鱼竿articles.Number>1的情况。
如果要修复这个问题,需要重构这块代码
所以梭哈功能直接按照原有思路,生成多个Number=1的鱼竿。
2024-08-06 17:40:16 +08:00
源文雨
4ffa18c511 fix: use https logo url (fix #937) 2024-08-05 20:15:08 +08:00
源文雨
2710074f00 💩👌 make lint happy 2024-08-05 20:11:49 +08:00
CUU_rooooo!
0afe577b1b typo: mcfish Modify Text (#945)
1. 去除README文件中gocqhttp相关内容
2. 修正mcfish中鱼竿名写死的问题
2024-08-05 18:45:31 +08:00
源文雨
7329426fa4 chore: sync data 2024-08-03 11:51:50 +08:00
CUU_rooooo!
97a647a620 [mcfish] add Synthesize all pole (#942)
* [mcfish] add Synthesize all pole

1. 提升程序便利性,添加合成所有鱼竿功能(梭哈)。
2. 完善附魔功能的用户提示

* [mcfish] 更新合成相关说明
2024-08-03 11:42:07 +08:00
github-actions[bot]
61501d8ed9 chore(lint): 改进代码样式 (#936)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-07-24 16:01:02 +08:00
CUU_rooooo!
289e74a619 typo: robbery spelling mistakes (#932)
修正单词拼写错误
2024-07-24 15:29:46 +08:00
CUU_rooooo!
18f77165ec Improve the judgment of robbery failure (#931)
* Improve the judgment of robbery failure

完善打劫失败判断,会返回更详细的提示信息。
打劫失败
- case1:受害者已经被打劫过了
tip:对方今天已经被打劫了,给人家的钱包留点后路吧

- case2:劫匪已经打劫过人了
tip:你今天已经成功打劫过了,贪心没有好果汁吃

-  case3:受害者已经被打劫过了&&劫匪已经打劫过人了
tip:同case2

* Update README.md : remove go-cqhttp

去掉readme里go-cqhttp相关介绍
2024-07-18 16:49:18 +09:00
github-actions[bot]
7a3589e26d chore: bump deps (#928)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-28 00:19:38 +09:00
源文雨
ca12560d29 ⬆️ update deps 2024-06-28 00:14:37 +09:00
github-actions[bot]
c70766a989 chore(lint): 改进代码样式 (#925)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-12 15:02:26 +09:00
himawari
b637fe18e9 添加水群时长统计 (#913)
*  添加水群时长统计

* 🐛 优化名片逻辑

* 🐛 更新发言时间

* 🎨 格式化

* 🐛 添加锁

* 🎨 改成at

* 🎨 添加map

* 🎨 修lint

* 🐛 修改排序问题

* 🎨 优化lint
2024-06-11 21:53:11 +09:00
vatebur
81e255eb3a (fix #914) mcfish bug:out of range (#923)
修复 mcfish 数组越界问题
2024-06-11 21:52:37 +09:00
源文雨
3b3b17aa33 💩👌 make lint happy 2024-06-06 15:38:36 +09:00
源文雨
4d7b7835e8 💩👌 make lint happy 2024-06-06 15:31:33 +09:00
Nobody6825
180f7564f3 feat: add workflow to build docker image (#921)
* feat: add all platform to build with nix

* fix: action do not work because pr confilct

* feat: add workflow to build docker

* chore: bump deps

* feat: add workflow to build docker

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-06-06 15:15:12 +09:00
源文雨
835ba2617f fix: workflow panic 2024-05-30 17:25:24 +09:00
源文雨
286caaca8c fix: workflow panic 2024-05-30 17:22:52 +09:00
源文雨
445d82b090 chore: downgrade indirect deps 2024-05-30 17:00:26 +09:00
源文雨
487cd4db20 chore: drop win386 supports 2024-05-30 16:56:59 +09:00
源文雨
07122bbbf7 chore: update sqlite3 to 1.29.10 2024-05-30 16:55:39 +09:00
源文雨
018f6c4008 fix(workflow): nightly cache 2024-05-30 16:52:44 +09:00
github-actions[bot]
fdb291d1d7 chore: bump deps (#917)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-05-30 16:48:43 +09:00
源文雨
dc0d7c4151 🔖 v1.8.1 2024-05-30 16:47:53 +09:00
源文雨
e55c1fbd3d chore: update deps 2024-05-30 16:47:07 +09:00
源文雨
8c1f4e2d2f chore: update deps 2024-05-29 01:24:28 +09:00
vatebur
502693e222 fix robbery bug:Wallet is negative (#914)
fix robbery bug:Wallet is negative。
修复了打劫失败可能导致钱包为负数的情况。
2024-05-29 01:12:08 +09:00
源文雨
23e567f2b1 chore: update deps 2024-05-29 01:10:50 +09:00
源文雨
a5a24e748e fix(aireply): autoregistered with midfix _ 2024-05-19 13:56:57 +09:00
Nobody6825
6210ed9496 feat: add docker builder use nix (#911)
* fix(typo): no -> not

* fix: update version

* feat: use nix to build docker image

* feat: ignore nix result

* fix(nix docker builder): failed to verify certificate
2024-05-19 13:50:50 +09:00
Nobody6825
a29b116f0d feat: add an action to make gomod2nix.toml auto update when go.mod/go.sum update (#909)
* feat: add an action to make gomod2nix.toml auto update when go.mod/go.sum update

* chore: bump deps

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-05-18 15:16:53 +09:00
Aimer Neige
3faabc4fd8 feat: add plugin 抽扑克牌 (#906) 2024-05-13 15:14:56 +09:00
源文雨
7c47a55d74 fix(workflow): pr not work properly 2024-05-13 00:54:11 +09:00
源文雨
94efc8a1af Revert "feat: add plugin 抽扑克! (#903)" (#905)
This reverts commit cda583e7b6.
2024-05-13 00:50:46 +09:00
Aimer Neige
cda583e7b6 feat: add plugin 抽扑克! (#903) 2024-05-13 00:37:39 +09:00
昔音幻离
e62c86a740 [dish] fix: 关键词搜寻功能 (#904)
* [dish] 修复关键词搜寻功能

* [dish] 增加关键词未搜索到的提示
2024-05-12 00:00:19 +09:00
昔音幻离
a9dfbdb54b 修复 FullMatchRule 中调用 ctx.NickName() 的 panic 问题 (#902) 2024-05-10 13:40:51 +09:00
vatebur
8fa928d37f optimize: gif plugin for image cache (#901) (fix #900)
修改gif插件图片保存方式
2024-05-09 16:29:20 +09:00
vatebur
d832f9aaea Update guessmusic plugin (#898)
1.修复:正确答案变小写的问题。
2.抽选歌曲的时候,只抽选本地已经下载好的歌曲
3.将插件改为默认禁用
4.新功能:提供猜歌选项
2024-05-07 21:50:06 +09:00
源文雨
5e047cafb0 make lint happy 2024-05-07 21:48:59 +09:00
vatebur
baaef6cb7f add robbery plugin (#893)
* add robbery plugin

add robbery plugin
添加打劫插件,打劫群友的Atri币

* Update README.md, add robbery plugin

add robbery plugin
添加打劫功能的说明

* chore(lint): 改进代码样式

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-05-06 19:44:33 +09:00
vatebur
d1b83f4764 [mcfish] Add one click selling (#894)
* [mcfish]  Add one click selling

Add one click waste selling function to mcfish plugin

给mcfish 添加一键售卖垃圾功能

* 🔖 v1.7.8

* chore: del aipaint due to 过气

* chore: del baidu due to 使えない

* chore: del cangtoushi due to 使えない

* chore: del dress due to 删库

* chore: del heisi due to 跑路

* chore: del jiami due to 跑路

* chore: del jiuejuezi due to 跑路

* chore: del quan due to 跑路

* chore: del wangyiyun due to 跑路

* chore: del wenben due to 跑路

* fix: atri 早安 conflict with sleep_manage & add 回应表情

* fix: version limit

* fix: version limit

* fix: version limit

* chore: update deps

* fix(searcher): forward node

* 💩👌 make lint happy

* revert: fix(searcher): forward node

* fix(github): get api method

* chore: del imgfinder due to 跑路

* optimize: saucenao head

* chore: tidy

* chore: del vtbxxx due to 跑路

* fix(drawlots): draw gif noise

* fix(emojimix): connection issue in some regions

* 💩👌 make lint happy

* fix(drawlots): draw gif noise

* fix(emojimix): add more logs

* feat: add uwu logo

* optimize: README uwu icon

* chore: update deps

* optimize: 赞我 触发失败时静默

* fix: update img pool

* fix: imgpool on LLOB

* fix(manager): 回应表情

*  修复b站小程序解析 (#895)

* add control for saucenao & bilibili_parse (#839)

* add control for saucenao&bilibili_parse

* not only group

* update control

* reuse variables

---------

Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>

* fix(bilibili): parse config

* fix(manager): 撤回

* fix: reply face

* fix: reply face

* 💩👌 make lint happy

* feat: add option `-mirror`

* chore: update deps

* chore: update deps

* chore: update deps

* chore: update deps

* chore: update deps

* chore: update deps

* chore: update deps

* 🔖 v1.8.0

* revert: emojimix http2

* 📝 update README

* [mcfish]  Add one click selling

Add one click waste selling function to mcfish plugin

给mcfish 添加一键售卖垃圾功能

* Update robbery plugin

Update robbery plugin
修改打劫功能

---------

Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
Co-authored-by: himawari <54976075+guohuiyuan@users.noreply.github.com>
Co-authored-by: 莫思潋 <55676105+shudorcl@users.noreply.github.com>
2024-05-06 19:43:26 +09:00
源文雨
78c64ac310 📝 update README 2024-05-05 17:36:30 +09:00
源文雨
0a45fafb1b revert: emojimix http2 2024-05-05 17:30:59 +09:00
源文雨
509c462c8d 🔖 v1.8.0 2024-05-05 16:48:59 +09:00
源文雨
61b70a86de chore: update deps 2024-05-05 16:47:04 +09:00
源文雨
8d0279fec7 chore: update deps 2024-05-05 16:24:54 +09:00
源文雨
8e5fbbae15 chore: update deps 2024-05-05 16:15:05 +09:00
源文雨
995f37ce17 chore: update deps 2024-05-05 04:05:16 +09:00
源文雨
97950bebcc chore: update deps 2024-05-05 03:59:06 +09:00
源文雨
a0e9816ea4 chore: update deps 2024-05-05 03:48:13 +09:00
源文雨
15df65af7b chore: update deps 2024-05-05 03:35:37 +09:00
源文雨
1351a7edbe feat: add option -mirror 2024-05-05 03:06:56 +09:00
源文雨
4f193f4251 💩👌 make lint happy 2024-05-05 02:30:17 +09:00
源文雨
71109f23fb fix: reply face 2024-05-05 02:25:53 +09:00
源文雨
ec00251972 fix: reply face 2024-05-05 02:19:40 +09:00
源文雨
79f1beac53 fix(manager): 撤回 2024-05-05 02:09:25 +09:00
源文雨
1a20ecb634 fix(bilibili): parse config 2024-05-05 01:09:30 +09:00
莫思潋
3225a2d6c7 add control for saucenao & bilibili_parse (#839)
* add control for saucenao&bilibili_parse

* not only group

* update control

* reuse variables

---------

Co-authored-by: 源文雨 <41315874+fumiama@users.noreply.github.com>
2024-05-05 01:07:34 +09:00
himawari
0e3c025b80 修复b站小程序解析 (#895) 2024-05-05 01:04:25 +09:00
源文雨
2a820cfc54 fix(manager): 回应表情 2024-05-04 23:51:42 +09:00
源文雨
d57d7a7abf fix: imgpool on LLOB 2024-05-04 21:46:00 +09:00
源文雨
ad9a74e159 fix: update img pool 2024-05-04 18:23:52 +09:00
源文雨
4c0c06ab1b optimize: 赞我 触发失败时静默 2024-05-04 18:00:14 +09:00
源文雨
c287ae7d92 chore: update deps 2024-05-04 17:56:16 +09:00
源文雨
c8d846d747 optimize: README uwu icon 2024-05-04 04:11:55 +09:00
源文雨
ff898b86ed feat: add uwu logo 2024-05-04 04:04:40 +09:00
源文雨
a4094cca64 fix(emojimix): add more logs 2024-05-02 22:57:33 +09:00
源文雨
803c027264 fix(drawlots): draw gif noise 2024-05-02 22:48:06 +09:00
源文雨
63784b4ed0 💩👌 make lint happy 2024-05-02 22:37:15 +09:00
源文雨
1971e2274a fix(emojimix): connection issue in some regions 2024-05-02 22:35:04 +09:00
源文雨
68fee3532b fix(drawlots): draw gif noise 2024-05-02 22:26:26 +09:00
源文雨
c29b1238c2 chore: del vtbxxx due to 跑路 2024-05-02 21:45:40 +09:00
源文雨
a72bec15a9 chore: tidy 2024-05-02 21:39:49 +09:00
源文雨
f4e9d3e4dd optimize: saucenao head 2024-05-02 21:39:33 +09:00
源文雨
6e54d214f0 chore: del imgfinder due to 跑路 2024-05-02 21:35:42 +09:00
源文雨
f54b9adf84 fix(github): get api method 2024-05-02 21:12:26 +09:00
源文雨
cd91373215 revert: fix(searcher): forward node 2024-05-02 19:11:01 +09:00
源文雨
a497609340 💩👌 make lint happy 2024-05-02 19:01:31 +09:00
源文雨
75d91b3d45 fix(searcher): forward node 2024-05-02 18:42:52 +09:00
源文雨
06fd754cc5 chore: update deps 2024-05-02 18:26:42 +09:00
源文雨
8e8c51a263 fix: version limit 2024-05-02 00:49:20 +09:00
源文雨
33580ab947 fix: version limit 2024-05-02 00:43:52 +09:00
源文雨
9531347292 fix: version limit 2024-05-02 00:01:52 +09:00
源文雨
717446ae6c fix: atri 早安 conflict with sleep_manage & add 回应表情 2024-05-01 23:51:55 +09:00
源文雨
786b5055c2 chore: del wenben due to 跑路 2024-05-01 03:19:46 +09:00
源文雨
9eadefba73 chore: del wangyiyun due to 跑路 2024-05-01 03:18:31 +09:00
源文雨
730ab28d92 chore: del quan due to 跑路 2024-05-01 03:11:20 +09:00
源文雨
83b46dd071 chore: del jiuejuezi due to 跑路 2024-05-01 02:59:06 +09:00
源文雨
a7d07ecf60 chore: del jiami due to 跑路 2024-05-01 02:56:04 +09:00
源文雨
4334f4dd22 chore: del heisi due to 跑路 2024-05-01 02:49:56 +09:00
源文雨
879948a5c4 chore: del dress due to 删库 2024-05-01 02:42:09 +09:00
源文雨
b09025a330 chore: del cangtoushi due to 使えない 2024-05-01 02:27:18 +09:00
源文雨
d95760a534 chore: del baidu due to 使えない 2024-05-01 02:22:56 +09:00
源文雨
a5130cd7f6 chore: del aipaint due to 过气 2024-05-01 02:17:46 +09:00
源文雨
bab5c4c308 🔖 v1.7.8 2024-04-30 17:51:36 +09:00
github-actions[bot]
e0891200af chore(lint): 改进代码样式 (#891)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-23 16:12:34 +09:00
himawari
b050b5d5b5 🐛 修复tts语音切换问题 (#890)
* 🐛 修复tts语音切换问题

* 🎨 文案不变化

* 🎨 语音放到上层方法

*  添加新回复模式

*  优化回复内容

* 🐛 调整顺序
2024-04-23 16:11:30 +09:00
源文雨
2ff164c2df chore(plugin): remove moegoe due to deletion 2024-04-14 15:28:03 +09:00
github-actions[bot]
cab917d054 chore(lint): 改进代码样式 (#888)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-04-13 17:52:33 +09:00
himawari
dfe6d347a5 添加两个api接口 (#886)
*  添加两个api接口

*  让代码简洁

*  一起处理

*  修改成map

* 🎨 删掉空
2024-04-13 17:51:13 +09:00
源文雨
5c6af1af61 chore(plugin): remove scale due to deletion 2024-04-11 16:35:39 +09:00
himawari
d7cdfb1544 Fix bilibilipush 20240404 (#884)
*  添加cookie

*  添加签名

* 🐛 修改嵌套错误

* 🐛 优化infoURL

*  添加cookie
2024-04-05 14:03:17 +09:00
源文雨
cf0e87ab9a 🔖 v1.7.7 2024-04-01 21:35:41 +09:00
源文雨
0a33224571 💩👌 make lint happy 2024-04-01 21:33:31 +09:00
源文雨
dd878f7dfe 💩👌 make lint happy 2024-04-01 21:31:04 +09:00
himawari
ac52c9cfca 🎨 修复查弹幕问题 (#883) 2024-04-01 21:26:12 +09:00
源文雨
ece68dae9b chore(revive): make lint happy 2024-03-04 15:38:26 +09:00
Eat Hatsune Shallots
6c20f22548 baidu: 对要查询的内容进行URI编码 (#866) 2024-03-04 15:33:36 +09:00
Nobody6825
6f2c9f7fc0 Initial Commit for nix (#856)
* Initial Commit for nix

* Update description

* nix fmt

* update version

---------

Co-authored-by: anonymous <anonymous@anonymous.anonymous44>
2024-01-27 16:11:24 +09:00
vatebur
b8858f0acd [issues 840] Modify the "score" of the Image send type add base64 (#853)
Modify the "score":Image send type add base64
适配shamrock,以路径发送图片失败后,使用base64发送图片。
2024-01-25 17:44:06 +09:00
vatebur
9c65383a7c update guessmusic:Reduce the difficulty (#854)
* update guessmusic:Reduce the difficulty

猜歌时忽略大小写和简繁体,降低猜歌难度

* chore(lint): 改进代码样式

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-01-25 17:40:11 +09:00
源文雨
a006b30392 Update pull.yml 2023-12-28 16:34:06 +09:00
源文雨
54c67e30f4 fix: danbooru 2023-11-19 19:03:28 +09:00
Jiang-Red
61168adb2e fix chess & kfc && optimize lolicon & bilibili (#817)
* fix chess & kfc && optimize bilibili & lolicon

* chore(lint): 改进代码样式 (#27)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-11-12 14:21:37 +09:00
104 changed files with 3772 additions and 3405 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
use flake

43
.github/workflows/gomod2nix.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: 自动更新 nix 依赖
on:
push:
paths:
- 'go.mod'
- 'go.sum'
- '.github/workflows/gomod2nix.yml'
jobs:
gomod2nix:
name: gomod2nix update
runs-on: ubuntu-latest
steps:
- name: Set up nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Set up Go
uses: actions/setup-go@master
with:
go-version: "1.20"
- name: Check out code into the Go module directory
uses: actions/checkout@master
- name: gomod2nix update
run: |
nix run github:nix-community/gomod2nix
- name: Commit back
if: ${{ !github.head_ref }}
continue-on-error: true
run: |
git config --local user.name 'github-actions[bot]'
git config --local user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add --all
git commit -m "chore: bump deps"
- name: Create Pull Request
if: ${{ !github.head_ref }}
continue-on-error: true
uses: peter-evans/create-pull-request@v4
with:
delete-branch: true
branch-suffix: short-commit-hash

42
.github/workflows/nightly-docker.yml vendored Normal file
View File

@@ -0,0 +1,42 @@
name: 打包最新版为 Docker Image
on: [push]
jobs:
docker-builder:
name: build docker
runs-on: ubuntu-23.04
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@master
- run: sudo apt-get install -y qemu-user-static
- name: Set up nix
uses: cachix/install-nix-action@v27
with:
nix_path: nixpkgs=channel:nixos-unstable
extra_nix_config: |
sandbox = true
- name: Speed Up nix
uses: DeterminateSystems/magic-nix-cache-action@main
- name: build docker
run: |
mkdir output/
# https://discourse.nixos.org/t/nix-github-actions-aarch64/11034
nix build .#packages.aarch64-linux.docker_builder -o aarch64-linux.docker --print-out-paths --option system aarch64-linux --extra-platforms aarch64-linux
cp $(readlink aarch64-linux.docker) ./output/aarch64-linux.docker.tar.gz
nix build .#packages.x86_64-linux.docker_builder -o x86_64-linux.docker --print-out-paths --option system x86_64-linux --extra-platforms x86_64-linux
cp $(readlink x86_64-linux.docker) ./output/x86_64-linux.docker.tar.gz
# gomod2nix did not provide this
# nix build .#packages.i686-linux.docker_builder -o i686-linux.docker --print-out-paths --option system i686-linux --extra-platforms i686-linux
# cp $(readlink i686-linux.docker) ./output/i686-linux.docker.tar.gz
- name: Upload artifact
uses: actions/upload-artifact@master
if: ${{ !github.head_ref }}
with:
path: output/

View File

@@ -22,6 +22,8 @@ jobs:
goarch: arm
- goos: windows
goarch: arm64
- goos: windows
goarch: 386
fail-fast: true
steps:
- uses: actions/checkout@master
@@ -31,6 +33,7 @@ jobs:
go-version: '1.20'
- name: Cache downloaded module
uses: actions/cache@master
continue-on-error: true
with:
path: |
~/.cache/go-build
@@ -52,4 +55,4 @@ jobs:
if: ${{ !github.head_ref }}
with:
name: ${{ matrix.goos }}_${{ matrix.goarch }}
path: output/
path: output/

View File

@@ -17,7 +17,7 @@ jobs:
uses: superbrothers/close-pull-request@v3
with:
# Optional. Post a issue comment just before closing a pull request.
comment: "非法PR. 请`fork`后修改自己的仓库, 而不是向主仓库提交更改. 如果您确信您的PR是为了给主仓库新增功能或修复bug, 请更改默认PR标题."
comment: "非法PR. 请`fork`后修改自己的仓库, 而不是向主仓库提交更改. 如果您确信您的PR是为了给主仓库新增功能或修复bug, 请更改默认PR标题. **注意**: 如果您再次触发本提示, 则有可能导致账号被封禁."
golangci:
name: lint
@@ -29,7 +29,12 @@ jobs:
go-version: '1.20'
- name: Check out code into the Go module directory
uses: actions/checkout@master
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Tidy Modules
run: go mod tidy
- name: golangci-lint
uses: golangci/golangci-lint-action@master

View File

@@ -13,6 +13,9 @@ jobs:
- name: Check out code into the Go module directory
uses: actions/checkout@master
- name: Tidy Modules
run: go mod tidy
- name: Run Lint
uses: golangci/golangci-lint-action@master
with:

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ nohup.out
zerobot
ZeroBot-Plugin*
*.syso
/.direnv
/result

View File

@@ -1,6 +1,5 @@
linters-settings:
errcheck:
ignore: fmt:.*
ignoretests: true
goimports:
@@ -57,13 +56,12 @@ run:
deadline: 5m
issues-exit-code: 1
tests: false
skip-dirs:
- order
go: '1.20'
# output configuration options
output:
format: "colored-line-number"
formats:
- format: "colored-line-number"
print-issued-lines: true
print-linter-name: true
uniq-by-line: true

View File

@@ -33,7 +33,6 @@ builds:
goos:
- windows
goarch:
- 386
- amd64
mod_timestamp: "{{ .CommitTimestamp }}"
flags:

348
README.md
View File

@@ -1,5 +1,6 @@
<div align="center">
<img src=".github/hua_nobg_512.gif" alt="椛" width = "400">
<img src=".github/hua_nobg_512.gif" alt="椛" width = "256">
<img src="https://github.com/FloatTech/ZeroBot-Plugin/assets/41315874/93fb795d-e519-45a6-a654-076fd6ac54ae" alt="zbp-uwu" width = "400">
<br>
<h1>ZeroBot-Plugin</h1>
@@ -29,11 +30,12 @@
[![telegram](https://img.shields.io/badge/Telegram-click%20me-informational?style=flat-square&logo=telegram)](https://t.me/zerobotplugin)
本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互
| 项目地址 | 平台 | 核心作者 |
| --- | --- | --- |
| [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) | [MiraiGo](https://github.com/Mrs4s/MiraiGo) | Mrs4s |
| [onebot-kotlin](https://github.com/yyuueexxiinngg/onebot-kotlin) | [Mirai](https://github.com/mamoe/mirai) | yyuueexxiinngg |
| [oicq/http-api](https://github.com/takayama-lily/oicq/tree/master/http-api) | [OICQ](https://github.com/takayama-lily/oicq) | takayama |
| 项目地址 | 平台 | 核心作者 | 备注 |
| :---: | :---: | :---: | :---: |
| [LLOneBot](https://github.com/LLOneBot/LLOneBot) | NTQQ | linyuchen | 目前推荐使用 |
| [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) | [MiraiGo](https://github.com/Mrs4s/MiraiGo) | Mrs4s | 因签名原因不再维护 |
| [onebot-kotlin](https://github.com/yyuueexxiinngg/onebot-kotlin) | [Mirai](https://github.com/mamoe/mirai) | yyuueexxiinngg | 不再积极维护 |
| [oicq/http-api](https://github.com/takayama-lily/oicq/tree/master/http-api) | [OICQ](https://github.com/takayama-lily/oicq) | takayama | 已归档不再维护 |
[![Star Trend](https://api.star-history.com/svg?repos=FloatTech/ZeroBot-Plugin&type=Timeline)](https://seladb.github.io/StarTrack-js/#/preload?r=FloatTech,ZeroBot-Plugin)
@@ -41,8 +43,6 @@
> 专为[后 go-cqhttp 时代](https://github.com/Mrs4s/go-cqhttp/issues/2471)开发迁移的`类zbp`新机器人现已出炉基于官方api稳定不风控: [NanoBot-Plugin](https://github.com/FloatTech/NanoBot-Plugin)
> 如果您不知道什么是 [OneBot](https://github.com/howmanybots/onebot) 或不希望运行多个程序,还可以直接前往 [gocqzbp](https://github.com/FloatTech/gocqzbp) 的 [Release](https://github.com/FloatTech/gocqzbp/releases) 页面下载单一可执行文件或前往 [Packages](https://github.com/FloatTech/gocqzbp/pkgs/container/gocqzbp) 页面使用`docker`,运行后按提示登录即可。
> 如果您对开发插件感兴趣,欢迎加入[ZeroBot-Plugin-Playground](https://github.com/FloatTech/ZeroBot-Plugin-Playground)
> webui持续开发中, 欢迎加入[ZeroBot-Plugin-Webui](https://github.com/FloatTech/ZeroBot-Plugin-Webui)
@@ -50,7 +50,7 @@
## 命令行参数
> `[]`代表是可选参数
```bash
zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w] [-c|s config.json] [-l latency] [-r ringlen] [-x max process time] [qq1 qq2 qq3 ...] [&]
zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w] [-c|s config.json] [-l latency] [-r ringlen] [-x max process time] [-mirror] [qq1 qq2 qq3 ...] [&]
```
- **-h**: 显示帮助
- **-m**: 不自动标记消息为已读
@@ -65,6 +65,7 @@ zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w]
- **-l latency**: 全局处理延时 (ms)
- **-r ringlen**: 接收消息环缓冲区大小,`0`为不设缓冲,并发处理
- **-x max process time**: 最大处理时间 (min)
- **-mirror**: 直接使用镜像懒加载数据站而不尝试访问源站
- **qqs**: superusers 的 qq 号
- **&**: 驻留在后台,必须放在最后,仅`Linux`下有效
@@ -173,6 +174,16 @@ zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w]
- [x] 设置温度[正整数]
</details>
<details>
<summary>聊天时长统计</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/chatcount"`
- [x] 查询水群@xxx
- [x] 查看水群排名
</details>
<details>
<summary>睡眠管理</summary>
@@ -242,6 +253,8 @@ zerobot [-h] [-m] [-n nickname] [-t token] [-u url] [-g url] [-p prefix] [-d|w]
- [x] 列出所有提醒
- [x] 翻牌
- [x] 赞我
- [x] [开启 | 关闭]入群验证
@@ -371,30 +384,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 设置默认限速为每 m [分钟 | 秒] n 次触发
</details>
<details>
<summary>ai绘图</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/aipaint"`
- [x] [ ai绘图 | 生成色图 | 生成涩图 | ai画图 ] xxx
- [x] [ ai高级绘图 | 高级生成色图 | 高级生成涩图 | ai高级画图 ] xxx
- [x] [ 以图绘图 | 以图生图 | 以图画图 ] xxx [图片]|@xxx|[qq号]
- [x] 设置ai绘图配置 [server] [token]
- [x] 设置ai绘图撤回时间90s
- [x] 查看ai绘图配置
例: 设置ai绘图配置 http://91.216.169.75:5010 abc
参考服务器 http://91.217.139.190:5010, http://91.216.169.75:5010, http://185.80.202.180:5010
通过 http://91.217.139.190:5010/token 获取token
</details>
<details>
<summary>AIWife</summary>
@@ -433,14 +422,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 用yyy解密xxx
</details>
<details>
<summary>百科</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu"`
- [x] 百度/百科/维基/wiki[xxx]
</details>
<details>
<summary>百度内容审核</summary>
@@ -570,16 +551,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 随机书评
</details>
<details>
<summary>藏头诗</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/cangtoushi"`
- [x] 藏头诗[xxx]
- [x] 藏尾诗[xxx]
</details>
<details>
<summary>选择困难症帮手</summary>
@@ -678,20 +649,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 删签[gif签名]
</details>
<details>
<summary>女装</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress"`
- [x] 女装
- [x] 男装
- [x] 随机女装
- [x] 随机男装
</details>
<details>
<summary>漂流瓶</summary>
@@ -815,14 +772,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 下载歌单[网易云歌单链接/ID]到[歌单名称]
- [x] 解除绑定 [歌单名称]
</details>
<details>
<summary>黑丝</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/heisi"`
- [x] 来点黑丝/白丝/jk/巨乳/足控/网红
</details>
<details>
<summary>一言</summary>
@@ -855,14 +804,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 百人一首之n
</details>
<details>
<summary>关键字搜图</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/image_finder"`
- [x] 来张 [xxx]
</details>
<details>
<summary>注入指令</summary>
@@ -881,24 +822,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 更新[屌|弔|吊]图
</details>
<details>
<summary>兽语加密(嗷呜~)</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/jiami"`
- [x] 兽语加密xxx
- [x] 兽语解密xxx
</details>
<details>
<summary>小鸡词典</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/jikipedia"`
- [x] [查梗|小鸡词典][梗]
</details>
<details>
<summary>日语听力学习材料</summary>
@@ -913,14 +836,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 日语歌曲 xxx
</details>
<details>
<summary>绝绝子</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi"`
- [x] 喝奶茶绝绝子 | 绝绝子吃饭
</details>
<details>
<summary>疯狂星期四</summary>
@@ -959,6 +874,24 @@ print("run[CQ:image,file="+j["img"]+"]")
来份萝莉
```
</details>
<details>
<summary>桑帛云 API</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolimi"`
- [x] 随机妹子
- [x] 随机绕口令
- [x] 颜值鉴定[图片]
- [x] 随机情话
- [x] 发病 嘉然
- [x] 让[嘉然|塔菲|东雪莲|懒羊羊|科比|孙笑川|陈泽|丁真|空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然]说我测尼玛
</details>
<details>
<summary>MagicPrompt-Stable-Diffusion吟唱提示</summary>
@@ -975,7 +908,7 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 钓鱼商店
- [x] 购买xxx [数量]
- [x] 出售xxx [数量]
- [x] 出售[xxx [数量]|所有垃圾]
- [x] 钓鱼背包
- [x] 装备[xx竿|三叉戟|美西螈]
- [x] 附魔[诱钓|海之眷顾]
@@ -1012,10 +945,6 @@ print("run[CQ:image,file="+j["img"]+"]")
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/moegoe"`
- [x] 让[宁宁|爱瑠|芳乃|茉子|丛雨|小春|七海]说(日语)
- [x] 让[수아|미미르|아린|연화|유화|선배]说(韩语)
- [x] 让[派蒙|空|荧|阿贝多|枫原万叶|温迪|八重神子|纳西妲|钟离|诺艾尔|凝光|托马|北斗|莫娜|荒泷一斗|提纳里|芭芭拉|艾尔海森|雷电将军|赛诺|琴|班尼特|五郎|神里绫华|迪希雅|夜兰|辛焱|安柏|宵宫|云堇|妮露|烟绯|鹿野院平藏|凯亚|达达利亚|迪卢克|可莉|早柚|香菱|重云|刻晴|久岐忍|珊瑚宫心海|迪奥娜|戴因斯雷布|魈|神里绫人|丽莎|优菈|凯瑟琳|雷泽|菲谢尔|九条裟罗|甘雨|行秋|胡桃|迪娜泽黛|柯莱|申鹤|砂糖|萍姥姥|奥兹|罗莎莉亚|式大将|哲平|坎蒂丝|托克|留云借风真君|昆钧|塞琉斯|多莉|大肉丸|莱依拉|散兵|拉赫曼|杜拉夫|阿守|玛乔丽|纳比尔|海芭夏|九条镰治|阿娜耶|阿晃|阿扎尔|七七|博士|白术|埃洛伊|大慈树王|女士|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|芽衣|雷之律者|阿波尼亚]说(中文)
</details>
@@ -1080,22 +1009,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- 注:刷新文件夹较慢,请耐心等待刷新完成,会提示“成功”。
</details>
<details>
<summary>抽wife</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativewife"`
- [x] 抽wife[@xxx]
- [x] 添加wife[名字][图片]
- [x] 删除wife[名字]
- [x] [让 | 不让]所有人均可添加wife
- 注:不同群添加后不会重叠
</details>
<details>
<summary>拼音首字母释义工具</summary>
@@ -1114,6 +1027,36 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 搜索日语语法 [xxx]
</details>
<details>
<summary>牛牛大作战</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/niuniu" `
- [x] 打胶
- [x] 使用[道具名称]打胶
- [x] jj[@xxx]
- [x] 使用[道具名称]jj[@xxx]
- [x] 赎牛牛
- [x] 牛牛商店
- [x] 牛牛背包
- [x] 注册牛牛
- [x] 注销牛牛
- [x] 牛子长度排行
- [x] 牛子深度排行
- [x] 查看我的牛牛
</details>
<details>
<summary>小说</summary>
@@ -1138,6 +1081,22 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 当图片属于非 neutral 类别时自动发送评价(默认禁用,启用输入 /启用 nsfwauto)
</details>
<details>
<summary>抽wife</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/nwife"`
- [x] 抽wife[@xxx]
- [x] 添加wife[名字][图片]
- [x] 删除wife[名字]
- [x] [让 | 不让]所有人均可添加wife
- 注:不同群添加后不会重叠
</details>
<details>
<summary>浅草寺求签</summary>
@@ -1148,6 +1107,14 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 解签
</details>
<details>
<summary>抽扑克</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/poker"`
- [x] 抽扑克牌
</details>
<details>
<summary>一群一天一夫一妻制群老婆</summary>
@@ -1180,18 +1147,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 重置花名册
</details>
<details>
<summary>权重查询</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/quan"`
- 来看看大家的账号分吧~据说越高越不容易封号哦
- [x] 权重查询+@xxx
- [x] 权重查询+QQ号(为空时匹配触发者QQ)
</details>
<details>
<summary>qq空间表白墙</summary>
@@ -1226,6 +1181,14 @@ print("run[CQ:image,file="+j["img"]+"]")
- 注:本插件来源于[tgbot](https://github.com/YukariChiba/tgbot/blob/main/modules/Reborn.py)
</details>
<details>
<summary>打劫</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/robbery"`
- [x] 打劫[对方Q号|@对方QQ]
</details>
<details>
<summary>在线代码运行</summary>
@@ -1250,14 +1213,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 设置 saucenao api key [apikey]
</details>
<details>
<summary>叔叔的AI二次元图片放大</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/scale"`
- [x] 放大图片[图片]
</details>
<details>
<summary>签到得分</summary>
@@ -1374,33 +1329,23 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 更新vtb
</details>
<details>
<summary>vtb点歌</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbmusic"`
- [x] vtb点歌
- [x] vtb随机点歌
</details>
<details>
<summary>钱包</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet"`
- [x] 查看我的钱包
- [x] 查看钱包排名
</details>
<details>
<summary>网易云音乐热评</summary>
- [x] 设置硬币名称[ATRI币]
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun"`
- [x] 管理钱包余额[+金额|-金额][@xxx]
- [x] 来份网易云热评
- [x] 查看我的钱包|查看钱包余额[@xxx]
- [x] 钱包转账[金额][@xxx]
- 注:仅超级用户能"管理钱包余额",
</details>
<details>
@@ -1429,20 +1374,6 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 警报
- [x] 每日特惠
</details>
<details>
<summary>天气/拼音查询-名言</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben"`
- [x] xx天气
- [x] xx拼音
- [x] 每日情话/一言/鸡汤
- [x] 绕口令
</details>
<details>
<summary>百度文心AI</summary>
@@ -1517,6 +1448,18 @@ print("run[CQ:image,file="+j["img"]+"]")
- [x] 团队七阶猜单词
</details>
<details>
<summary>鬼东西</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf"`
- [x] 鬼东西列表
- [x] 查询鬼东西[序号][@xxx]
- 注:由于需要科学,默认注释。
</details>
<details>
<summary>一些游戏王插件</summary>
@@ -1558,15 +1501,39 @@ print("run[CQ:image,file="+j["img"]+"]")
</details>
<details>
<summary>鬼东西</summary>
<summary>遇见API</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf"`
- [x] 鬼东西列表
- [x] 查询鬼东西[序号][@xxx]
- 注:由于需要科学,默认注释。
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/yujn"`
- [x] 小姐姐视频
- [x] 小姐姐视频2
- [x] 黑丝视频
- [x] 白丝视频
- [x] 欲梦视频
- [x] 甜妹视频
- [x] 双倍快乐
- [x] 纯情女高
- [x] 萝莉视频
- [x] 玉足视频
- [x] 帅哥视频
- [x] 热舞视频
- [x] 吊带视频
- [x] 汉服视频
- [x] 极品狱卒
- [x] 清纯视频
- [x] 快手变装
- [x] 抖音变装
- [x] 萌娃视频
- [x] 穿搭视频
- [x] 完美身材
- [x] 御姐撒娇
- [x] 绿茶语音
- [x] 怼人语音
- [x] 随机骚话
- [x] 随机污句子
- [x] 随机美句
- [x] 土味情话
- [x] 让[lulu]说我测尼玛
</details>
@@ -1585,11 +1552,11 @@ print("run[CQ:image,file="+j["img"]+"]")
<details>
<summary>人工智能回复</summary>
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/ai_reply"`
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/aireply"`
- [x] @Bot 任意文本(任意一句话回复)
- [x] 设置回复模式[青云客 | 小爱 | ChatGPT]
- [x] 设置文字回复模式[婧枫|沫沫|青云客|小爱|ChatGPT]
- [x] 设置 ChatGPT api key xxx
@@ -1616,8 +1583,7 @@ print("run[CQ:image,file="+j["img"]+"]")
### 1. 使用稳定版/测试版 (推荐)
可以前往[Release](https://github.com/FloatTech/ZeroBot-Plugin/releases)页面下载对应系统版本可执行文件,编译时开启了全部插件。您还可以选择 [gocqzbp](https://github.com/FloatTech/gocqzbp) 的 [Release](https://github.com/FloatTech/gocqzbp/releases) 或 [Package](https://github.com/FloatTech/gocqzbp/pkgs/container/gocqzbp),它是 [Mrs4s/go-cqhttp](https://github.com/Mrs4s/go-cqhttp) 与本插件的合体。
可以前往[Release](https://github.com/FloatTech/ZeroBot-Plugin/releases)页面下载对应系统版本可执行文件,编译时开启了全部插件。
### 2. 本地直接运行
1. 下载安装最新 [Go](https://studygolang.com/dl) 环境

2
data

Submodule data updated: 9b983625ca...f1f8cd107c

25
default.nix Normal file
View File

@@ -0,0 +1,25 @@
{
pkgs ? (
let
inherit (builtins) fetchTree fromJSON readFile;
inherit ((fromJSON (readFile ./flake.lock)).nodes) nixpkgs gomod2nix;
in
import (fetchTree nixpkgs.locked) {
overlays = [
(import "${fetchTree gomod2nix.locked}/overlay.nix")
];
}
),
buildGoApplication ? pkgs.buildGoApplication,
}:
buildGoApplication {
pname = "ZeroBot-Plugin";
version = "1.8.0";
pwd = ./.;
src = ./.;
# spec go version manually bcs
# https://github.com/nix-community/gomod2nix/blob/30e3c3a9ec4ac8453282ca7f67fca9e1da12c3e6/builder/default.nix#L130
# do not work
go = pkgs.go_1_20;
modules = ./gomod2nix.toml;
}

85
flake.lock generated Normal file
View File

@@ -0,0 +1,85 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"gomod2nix": {
"inputs": {
"flake-utils": [
"flake-utils"
],
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1705314449,
"narHash": "sha256-yfQQ67dLejP0FLK76LKHbkzcQqNIrux6MFe32MMFGNQ=",
"owner": "nix-community",
"repo": "gomod2nix",
"rev": "30e3c3a9ec4ac8453282ca7f67fca9e1da12c3e6",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "gomod2nix",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1705856552,
"narHash": "sha256-JXfnuEf5Yd6bhMs/uvM67/joxYKoysyE3M2k6T3eWbg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "612f97239e2cc474c13c9dafa0df378058c5ad8d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"gomod2nix": "gomod2nix",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

53
flake.nix Normal file
View File

@@ -0,0 +1,53 @@
{
description = " ZeroBot OneBot ";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.gomod2nix.url = "github:nix-community/gomod2nix";
inputs.gomod2nix.inputs.nixpkgs.follows = "nixpkgs";
inputs.gomod2nix.inputs.flake-utils.follows = "flake-utils";
outputs = {
self,
nixpkgs,
flake-utils,
gomod2nix,
}: let
allSystems = flake-utils.lib.allSystems;
in (
flake-utils.lib.eachSystem allSystems
(system: let
pkgs = nixpkgs.legacyPackages.${system};
# The current default sdk for macOS fails to compile go projects, so we use a newer one for now.
# This has no effect on other platforms.
callPackage = pkgs.darwin.apple_sdk_11_0.callPackage or pkgs.callPackage;
in {
# doCheck will fail at write files
packages = rec {
ZeroBot-Plugin =
(callPackage ./. {
inherit (gomod2nix.legacyPackages.${system}) buildGoApplication;
})
.overrideAttrs (_: {doCheck = false;});
default = ZeroBot-Plugin;
docker_builder = pkgs.dockerTools.buildLayeredImage {
name = "ZeroBot-Plugin";
tag = "latest";
contents = [
self.packages.${system}.ZeroBot-Plugin
pkgs.cacert
];
};
};
devShells.default = callPackage ./shell.nix {
inherit (gomod2nix.legacyPackages.${system}) mkGoEnv gomod2nix;
};
formatter = pkgs.alejandra;
})
);
}

99
go.mod
View File

@@ -4,99 +4,98 @@ go 1.20
require (
github.com/Baidu-AIP/golang-sdk v1.1.1
github.com/FloatTech/AnimeAPI v1.7.1-0.20231017135344-aefd1d56e900
github.com/FloatTech/floatbox v0.0.0-20231107124407-e38535efa2a2
github.com/FloatTech/gg v1.1.3-0.20230226151425-6ea91286ba08
github.com/FloatTech/AnimeAPI v1.7.1-0.20240826120833-9bf54389aadb
github.com/FloatTech/floatbox v0.0.0-20240505082030-226ec6713e14
github.com/FloatTech/gg v1.1.3
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef
github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9
github.com/FloatTech/rendercard v0.1.1
github.com/FloatTech/sqlite v1.6.3
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b
github.com/FloatTech/zbpctrl v1.6.0
github.com/FloatTech/zbputils v1.7.1-0.20231107124514-083e678fbfe6
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e
github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562
github.com/FloatTech/zbpctrl v1.6.2-0.20240904160347-1317e11a15bb
github.com/FloatTech/zbputils v1.7.2-0.20240822065525-5ea6811ed91c
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5
github.com/antchfx/htmlquery v1.2.5
github.com/antchfx/htmlquery v1.3.1
github.com/corona10/goimagehash v1.1.0
github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3
github.com/disintegration/imaging v1.6.2
github.com/fumiama/ahsai v0.1.0
github.com/fumiama/cron v1.3.0
github.com/fumiama/go-base16384 v1.7.0
github.com/fumiama/go-registry v0.2.6
github.com/fumiama/go-registry v0.2.7
github.com/fumiama/gotracemoe v0.0.3
github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565
github.com/fumiama/unibase2n v0.0.0-20221020155353-02876e777430
github.com/fumiama/slowdo v0.0.0-20241001074058-27c4fe5259a4
github.com/fumiama/terasu v0.0.0-20240507144117-547a591149c0
github.com/fumiama/unibase2n v0.0.0-20240530074540-ec743fd5a6d6
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/jinzhu/gorm v1.9.16
github.com/jozsefsallai/gophersauce v1.0.1
github.com/kanrichan/resvg-go v0.0.2-0.20231001163256-63db194ca9f5
github.com/lithammer/fuzzysearch v1.1.5
github.com/lithammer/fuzzysearch v1.1.8
github.com/liuzl/gocc v0.0.0-20231231122217-0372e1059ca5
github.com/mroth/weightedrand v1.0.0
github.com/notnil/chess v1.9.0
github.com/pkg/errors v0.9.1
github.com/quic-go/quic-go v0.38.1
github.com/shirou/gopsutil/v3 v3.23.1
github.com/shirou/gopsutil/v3 v3.24.4
github.com/sirupsen/logrus v1.9.3
github.com/tidwall/gjson v1.14.4
github.com/wcharczuk/go-chart/v2 v2.1.0
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20231009162356-57f71b9f5258
gitlab.com/gomidi/midi/v2 v2.0.25
golang.org/x/image v0.3.0
golang.org/x/sys v0.8.0
golang.org/x/text v0.9.0
github.com/tidwall/gjson v1.17.3
github.com/wcharczuk/go-chart/v2 v2.1.1
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20240829093431-bea5257d1a2b
gitlab.com/gomidi/midi/v2 v2.1.7
golang.org/x/image v0.16.0
golang.org/x/sys v0.20.0
golang.org/x/text v0.15.0
gopkg.in/yaml.v3 v3.0.1
)
require (
github.com/adamzy/cedar-go v0.0.0-20170805034717-80a9c64b256d // indirect
github.com/ajstarks/svgo v0.0.0-20200320125537-f189e35d30ca // indirect
github.com/antchfx/xpath v1.2.1 // indirect
github.com/antchfx/xpath v1.3.0 // indirect
github.com/blend/go-sdk v1.20220411.3 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 // indirect
github.com/faiface/beep v1.1.0 // indirect
github.com/fumiama/go-simple-protobuf v0.1.0 // indirect
github.com/fumiama/go-simple-protobuf v0.2.0 // indirect
github.com/fumiama/gofastTEA v0.0.10 // indirect
github.com/fumiama/imgsz v0.0.2 // indirect
github.com/fumiama/imgsz v0.0.4 // indirect
github.com/gabriel-vasile/mimetype v1.0.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hajimehoshi/oto v0.7.1 // indirect
github.com/jfreymuth/oggvorbis v1.0.1 // indirect
github.com/jfreymuth/vorbis v1.0.0 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/liuzl/cedar-go v0.0.0-20170805034717-80a9c64b256d // indirect
github.com/liuzl/da v0.0.0-20180704015230-14771aad5b1d // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/onsi/ginkgo/v2 v2.9.5 // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pkumza/numcn v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.3.3 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/tetratelabs/wazero v1.5.0 // indirect
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tklauser/go-sysconf v0.3.11 // indirect
github.com/tklauser/numcpus v0.6.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect
golang.org/x/exp/shiny v0.0.0-20221126150942-6ab00d035af9 // indirect
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f // indirect
golang.org/x/mod v0.10.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/tools v0.9.1 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
modernc.org/libc v1.21.5 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.4.0 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 // indirect
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 // indirect
golang.org/x/net v0.24.0 // indirect
modernc.org/libc v1.49.3 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.8.0 // indirect
modernc.org/sqlite v1.20.0 // indirect
)
replace modernc.org/sqlite => github.com/fumiama/sqlite3 v1.20.0-with-win386
replace modernc.org/sqlite => github.com/fumiama/sqlite3 v1.29.10-simp
replace github.com/remyoudompheng/bigfft => github.com/fumiama/bigfft v0.0.0-20211011143303-6e0bfa3c836b
replace modernc.org/libc => github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5

269
go.sum
View File

@@ -1,40 +1,40 @@
github.com/Baidu-AIP/golang-sdk v1.1.1 h1:RQsAmgDSAkiq22I6n7XJ2t3afgzFeqjY46FGhvrx4cw=
github.com/Baidu-AIP/golang-sdk v1.1.1/go.mod h1:bXnGw7xPeKt8aF7UCELKrV6UZ/46spItONK1RQBQj1Y=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/FloatTech/AnimeAPI v1.7.1-0.20231017135344-aefd1d56e900 h1:UPXoj+lMHFBulp/m+F7uHju0MXslFKQqEplDDz/nOiU=
github.com/FloatTech/AnimeAPI v1.7.1-0.20231017135344-aefd1d56e900/go.mod h1:7Olb5U9q1oeayRZQTNBhXQNMf8QT4T9hccsn38IEt/U=
github.com/FloatTech/floatbox v0.0.0-20231107124407-e38535efa2a2 h1:O4kptIzgYzNwZlBARZFv8EkA40yB6M5LGxxIF7NKLR8=
github.com/FloatTech/floatbox v0.0.0-20231107124407-e38535efa2a2/go.mod h1:TeTlp+hTxpJti4JSdmUqzxGEr4wUBOVct9YWBepilpc=
github.com/FloatTech/gg v1.1.3-0.20230226151425-6ea91286ba08 h1:dPLeoiTVSBlgls+66EB/UJ2e38BaASmBN5nANaycSBU=
github.com/FloatTech/gg v1.1.3-0.20230226151425-6ea91286ba08/go.mod h1:uzPzAeT35egARdRuu+1oyjU3CmTwCceoq3Vvje7LpcI=
github.com/FloatTech/AnimeAPI v1.7.1-0.20240826120833-9bf54389aadb h1:j7m84zwcDWLoMLjgG4MDnvanGQoDNnG8A7/aNCnYMIk=
github.com/FloatTech/AnimeAPI v1.7.1-0.20240826120833-9bf54389aadb/go.mod h1:Ru6q5pZUnfMg1iu0M1Hp73q9N3LNIbDr16kjkzyG6Xk=
github.com/FloatTech/floatbox v0.0.0-20240505082030-226ec6713e14 h1:8O0Iq9MnKsKowltY9txhOqcJdmGTjxHPQ4gEYzbJc9A=
github.com/FloatTech/floatbox v0.0.0-20240505082030-226ec6713e14/go.mod h1:OzGLhvmtz1TKIdGaJDd8pQumvD36UqK+dWsiCISmzQQ=
github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4=
github.com/FloatTech/gg v1.1.3/go.mod h1:/9oLP54CMfq4r+71XL26uaFTJ1uL1boAyX67680/1HE=
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef h1:CJbK/2FRwPuZpeb6M4sWK2d7oXDnBEGhpkQuQrgc91A=
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef/go.mod h1:el5hGpj1C1bDRxcTXYRwEivDCr40zZeJpcrLrB1fajs=
github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9 h1:hffajvmQFfP68U6wUwHemPuuwCUoss+SEFfoLYwbGwE=
github.com/FloatTech/rendercard v0.0.10-0.20230223064326-45d29fa4ede9/go.mod h1:NBFPhWae4hqVMeG8ELBBnUQkKce3nDjkljVn6PdiUNs=
github.com/FloatTech/rendercard v0.1.1 h1:vXz3x92bLavmNexTywdUvhft2/ipUSuo8aPRkqVdGQ8=
github.com/FloatTech/rendercard v0.1.1/go.mod h1:Sbojcy1t3NfFz7/WicZRmR/uKFxNMYkKF8qHx69dxY0=
github.com/FloatTech/sqlite v1.6.3 h1:MQkqBNlkPuCoKQQgoNLuTL/2Ci3tBTFAnVYBdD0Wy4M=
github.com/FloatTech/sqlite v1.6.3/go.mod h1:zFbHzRfB+CJ+VidfjuVbrcin3DAz283F7hF1hIeHzpY=
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b h1:tvciXWq2nuvTbFeJGLDNIdRX3BI546D3O7k7vrVueZw=
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs=
github.com/FloatTech/zbpctrl v1.6.0 h1:BWg9aRR4bUCmNNKj6GPH0TmzFRWYImIi6rQcQTTYRs4=
github.com/FloatTech/zbpctrl v1.6.0/go.mod h1:i3GGM5K4HiDsXzvmXQSYoH1QT3tsSaAHjRzHwKGsHG0=
github.com/FloatTech/zbputils v1.7.1-0.20231107124514-083e678fbfe6 h1:EMdvLnt6i5dSFloLD1klOM8bdoFZqTtILcMCciOpcMo=
github.com/FloatTech/zbputils v1.7.1-0.20231107124514-083e678fbfe6/go.mod h1:4oXgjQ6bGosAF4GbuL/keAhTrGWOV369X5X0ISFebmw=
github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562 h1:snfw7FNFym1eNnLrQ/VCf80LiQo9C7jHgrunZDwiRcY=
github.com/FloatTech/ttl v0.0.0-20240716161252-965925764562/go.mod h1:fHZFWGquNXuHttu9dUYoKuNbm3dzLETnIOnm1muSfDs=
github.com/FloatTech/zbpctrl v1.6.2-0.20240904160347-1317e11a15bb h1:sGqwCiMDyUD/znWEVVRVxbd6Kg1KLgGnnIuq5bCUWaQ=
github.com/FloatTech/zbpctrl v1.6.2-0.20240904160347-1317e11a15bb/go.mod h1:I+MetM++1sJhNPg3zww1aw04BicYsNohvHC4Jh52XSo=
github.com/FloatTech/zbputils v1.7.2-0.20240822065525-5ea6811ed91c h1:hFiqx4uk6+lc2zHAaQ3JkkI2KH59c6O4yHKWKXFzxLs=
github.com/FloatTech/zbputils v1.7.2-0.20240822065525-5ea6811ed91c/go.mod h1:MwTFLPhlP0qMMLcq4x90oiu1IVE1T5dN0ZsxyTGSf6k=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e h1:wR3MXQ3VbUlPKOOUwLOYgh/QaJThBTYtsl673O3lqSA=
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w=
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7 h1:S/ferNiehVjNaBMNNBxUjLtVmP/YWD6Yh79RfPv4ehU=
github.com/RomiChan/syncx v0.0.0-20240418144900-b7402ffdebc7/go.mod h1:vD7Ra3Q9onRtojoY5sMCLQ7JBgjUsrXDnDKyFxqpf9w=
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5 h1:bBmmB7he0iVN4m5mcehfheeRUEer/Avo4ujnxI3uCqs=
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5/go.mod h1:0UcFaCkhp6vZw6l5Dpq0Dp673CoF9GdvA8lTfst0GiU=
github.com/adamzy/cedar-go v0.0.0-20170805034717-80a9c64b256d h1:ir/IFJU5xbja5UaBEQLjcvn7aAU01nqU/NUyOBEU+ew=
github.com/adamzy/cedar-go v0.0.0-20170805034717-80a9c64b256d/go.mod h1:PRWNwWq0yifz6XDPZu48aSld8BWwBfr2JKB2bGWiEd4=
github.com/ajstarks/svgo v0.0.0-20200320125537-f189e35d30ca h1:kWzLcty5V2rzOqJM7Tp/MfSX0RMSI1x4IOLApEefYxA=
github.com/ajstarks/svgo v0.0.0-20200320125537-f189e35d30ca/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/antchfx/htmlquery v1.2.5 h1:1lXnx46/1wtv1E/kzmH8vrfMuUKYgkdDBA9pIdMJnk4=
github.com/antchfx/htmlquery v1.2.5/go.mod h1:2MCVBzYVafPBmKbrmwB9F5xdd+IEgRY61ci2oOsOQVw=
github.com/antchfx/xpath v1.2.1 h1:qhp4EW6aCOVr5XIkT+l6LJ9ck/JsUH/yyauNgTQkBF8=
github.com/antchfx/xpath v1.2.1/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/antchfx/htmlquery v1.3.1 h1:wm0LxjLMsZhRHfQKKZscDf2COyH4vDYA3wyH+qZ+Ylc=
github.com/antchfx/htmlquery v1.3.1/go.mod h1:PTj+f1V2zksPlwNt7uVvZPsxpKNa7mlVliCRxLX6Nx8=
github.com/antchfx/xpath v1.3.0 h1:nTMlzGAK3IJ0bPpME2urTuFL76o4A96iYvoKFHRXJgc=
github.com/antchfx/xpath v1.3.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/blend/go-sdk v1.20220411.3 h1:GFV4/FQX5UzXLPwWV03gP811pj7B8J2sbuq+GJQofXc=
github.com/blend/go-sdk v1.20220411.3/go.mod h1:7lnH8fTi6U4i1fArEXRyOIY2E1X4MALg09qsQqY1+ak=
github.com/corona10/goimagehash v1.1.0 h1:teNMX/1e+Wn/AYSbLHX8mj+mF9r60R1kBeqE9MkoYwI=
github.com/corona10/goimagehash v1.1.0/go.mod h1:VkvE0mLn84L4aF8vCb6mafVajEb6QYMHl2ZJLn0mOGI=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@@ -48,6 +48,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6RO
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4 h1:BBade+JlV/f7JstZ4pitd4tHhpN+w+6I+LyOS7B4fyU=
github.com/ericpauley/go-quantize v0.0.0-20200331213906-ae555eb2afa4/go.mod h1:H7chHJglrhPPzetLdzBleF8d22WYOv7UM/lEKYiwlKM=
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y=
@@ -56,28 +58,32 @@ github.com/faiface/beep v1.1.0 h1:A2gWP6xf5Rh7RG/p9/VAW2jRSDEGQm5sbOb38sf5d4c=
github.com/faiface/beep v1.1.0/go.mod h1:6I8p6kK2q4opL/eWb+kAkk38ehnTunWeToJB+s51sT4=
github.com/fumiama/ahsai v0.1.0 h1:LXD61Kaj6kJHa3AEGsLIfKNzcgaVxg7JB72OR4yNNZ4=
github.com/fumiama/ahsai v0.1.0/go.mod h1:fFeNnqgo44i8FIaguK659aQryuZeFy+4klYLQu/rfdk=
github.com/fumiama/bigfft v0.0.0-20211011143303-6e0bfa3c836b h1:Zt3pFQditAdWTHCOVkiloc9ZauBoWrb37guFV4iIRvE=
github.com/fumiama/bigfft v0.0.0-20211011143303-6e0bfa3c836b/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/fumiama/cron v1.3.0 h1:ZWlwuexF+HQHl3cYytEE5HNwD99q+3vNZF1GrEiXCFo=
github.com/fumiama/cron v1.3.0/go.mod h1:bz5Izvgi/xEUI8tlBN8BI2jr9Moo8N4or0KV8xXuPDY=
github.com/fumiama/go-base16384 v1.7.0 h1:6fep7XPQWxRlh4Hu+KsdH+6+YdUp+w6CwRXtMWSsXCA=
github.com/fumiama/go-base16384 v1.7.0/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
github.com/fumiama/go-registry v0.2.6 h1:+vEeBUwa1+GC87ujW3Km42fi8O/H7QcpVJWu1iuGNh0=
github.com/fumiama/go-registry v0.2.6/go.mod h1:HjYagPZXzR2xCCxaSQerqX7JRzC0yiv2kslDdBiTq/g=
github.com/fumiama/go-simple-protobuf v0.1.0 h1:rLzJgNqB6LHNDVMl81yyNt6ZKziWtVfu+ioF0edlEVw=
github.com/fumiama/go-simple-protobuf v0.1.0/go.mod h1:5yYNapXq1tQMOZg9bOIVhQlZk9pQqpuFIO4DZLbsdy4=
github.com/fumiama/go-registry v0.2.7 h1:tLEqgEpsiybQMqBv0dLHm5leia/z1DhajMupwnOHeNs=
github.com/fumiama/go-registry v0.2.7/go.mod h1:m+wp5fF8dYgVoFkBPZl+vlK90loymaJE0JCtocVQLEs=
github.com/fumiama/go-simple-protobuf v0.2.0 h1:ACyN1MAlu7pDR3EszWgzUeNP+IRsSHwH6V9JCJA5R5o=
github.com/fumiama/go-simple-protobuf v0.2.0/go.mod h1:5yYNapXq1tQMOZg9bOIVhQlZk9pQqpuFIO4DZLbsdy4=
github.com/fumiama/gofastTEA v0.0.10 h1:JJJ+brWD4kie+mmK2TkspDXKzqq0IjXm89aGYfoGhhQ=
github.com/fumiama/gofastTEA v0.0.10/go.mod h1:RIdbYZyB4MbH6ZBlPymRaXn3cD6SedlCu5W/HHfMPBk=
github.com/fumiama/gotracemoe v0.0.3 h1:iI5EbE9A3UUbfukG6+/soYPjp1S31eCNYf4tw7s6/Jc=
github.com/fumiama/gotracemoe v0.0.3/go.mod h1:tyqahdUzHf0bQIAVY/GYmDWvYYe5ik1ZbhnGYh+zl40=
github.com/fumiama/imgsz v0.0.2 h1:fAkC0FnIscdKOXwAxlyw3EUba5NzxZdSxGaq3Uyfxak=
github.com/fumiama/imgsz v0.0.2/go.mod h1:dR71mI3I2O5u6+PCpd47M9TZptzP+39tRBcbdIkoqM4=
github.com/fumiama/imgsz v0.0.4 h1:Lsasu2hdSSFS+vnD+nvR1UkiRMK7hcpyYCC0FzgSMFI=
github.com/fumiama/imgsz v0.0.4/go.mod h1:bISOQVTlw9sRytPwe8ir7tAaEmyz9hSNj9n8mXMBG0E=
github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565 h1:sQuR2+N5HurnvsZhiKdEg+Ig354TaqgCQRxd/0KgIOQ=
github.com/fumiama/jieba v0.0.0-20221203025406-36c17a10b565/go.mod h1:UUEvyLTJ7yoOA/viKG4wEis4ERydM7+Ny6gZUWgkS80=
github.com/fumiama/sqlite3 v1.20.0-with-win386 h1:ZR1AXGBEtkfq9GAXehOVcwn+aaCG8itrkgEsz4ggx5k=
github.com/fumiama/sqlite3 v1.20.0-with-win386/go.mod h1:Os58MHwYCcYZCy2PGChBrQtBAw5/LS1ZZOkfc+C/I7s=
github.com/fumiama/unibase2n v0.0.0-20221020155353-02876e777430 h1:XL4SnagpaVHYybnnj6whQxmt8Ps9/kaG6sCNn4X1GGA=
github.com/fumiama/unibase2n v0.0.0-20221020155353-02876e777430/go.mod h1:lEaZsT4FRSqcjnQ5q8y+mkenkzR/r1D3BJmfdp0vqDg=
github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5 h1:jDxsIupsT84A6WHcs6kWbst+KqrRQ8/o0VyoFMnbBOA=
github.com/fumiama/libc v0.0.0-20240530081950-6f6d8586b5c5/go.mod h1:15P6ublJ9FJR8YQCGy8DeQ2Uwur7iW9Hserr/T3OFZE=
github.com/fumiama/slowdo v0.0.0-20241001074058-27c4fe5259a4 h1:zN9e09TYKXI1mNkuS6YbH+Sn+4k5tBir+ovhZZcRYAs=
github.com/fumiama/slowdo v0.0.0-20241001074058-27c4fe5259a4/go.mod h1:iZf1H/Jcw5gjOOFb4C5nlweJtViWc7uwUxRCe14pbYk=
github.com/fumiama/sqlite3 v1.29.10-simp h1:c5y3uKyU0q9t0/SyfynzYyuslQ5zP+5CD8e0yYY554A=
github.com/fumiama/sqlite3 v1.29.10-simp/go.mod h1:ItX2a1OVGgNsFh6Dv60JQvGfJfTPHPVpV6DF59akYOA=
github.com/fumiama/terasu v0.0.0-20240507144117-547a591149c0 h1:So/3Bg/m2ZcUvqCzzEjjkjHBjcvnV3AN5tCxwsdMwYU=
github.com/fumiama/terasu v0.0.0-20240507144117-547a591149c0/go.mod h1:UVx8YP1jKKL1Cj+uy+OnQRM2Ih6U36Mqy9GSf7jabsI=
github.com/fumiama/unibase2n v0.0.0-20240530074540-ec743fd5a6d6 h1:LtDgr628eji8jRpjPCxsk7ibjcfi97QieZVCTjxLCBw=
github.com/fumiama/unibase2n v0.0.0-20240530074540-ec743fd5a6d6/go.mod h1:lEaZsT4FRSqcjnQ5q8y+mkenkzR/r1D3BJmfdp0vqDg=
github.com/gabriel-vasile/mimetype v1.0.4 h1:uBejfH8l3/2f+5vjl1e4xIaSyNEhRBZ5N/ij7ohpNd8=
github.com/gabriel-vasile/mimetype v1.0.4/go.mod h1:6CDPel/o/3/s4+bp6kIbsWATq8pmgOisOPG40CJa6To=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
@@ -85,36 +91,27 @@ github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebK
github.com/go-audio/audio v1.0.0/go.mod h1:6uAu0+H2lHkwdGsAY+j2wHPNPpPoeg5AaEFh9FlA+Zs=
github.com/go-audio/riff v1.0.0/go.mod h1:l3cQwc85y79NQFCRB7TiPoNiaijp6q8Z0Uv38rVG498=
github.com/go-audio/wav v1.0.0/go.mod h1:3yoReyQOsiARkvPl3ERCi8JFjihzG6WhjYpZCf5zAWE=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hajimehoshi/go-mp3 v0.3.0/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
github.com/hajimehoshi/oto v0.7.1 h1:I7maFPz5MBCwiutOrz++DLdbr4rTzBsbBuV2VpgU9kk=
github.com/hajimehoshi/oto v0.7.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/icza/bitio v1.0.0/go.mod h1:0jGnlLAx8MKMr9VGnn/4YrvZiprkvBelsVIbA9Jjr9A=
github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA=
github.com/jfreymuth/oggvorbis v1.0.1 h1:NT0eXBgE2WHzu6RT/6zcb2H10Kxj6Fm3PccT0LE6bqw=
@@ -131,22 +128,24 @@ github.com/jozsefsallai/gophersauce v1.0.1 h1:BA3ovtQRrAb1qYU9JoRLbDHpxnDunlNcEk
github.com/jozsefsallai/gophersauce v1.0.1/go.mod h1:YVEI7djliMTmZ1Vh01YPF8bUHi+oKhe3yXgKf1T49vg=
github.com/kanrichan/resvg-go v0.0.2-0.20231001163256-63db194ca9f5 h1:BXnB1Gz4y/zwQh+ZFNy7rgd+ZfMOrwRr4uZSHEI+ieY=
github.com/kanrichan/resvg-go v0.0.2-0.20231001163256-63db194ca9f5/go.mod h1:c9+VS9GaommgIOzNWb5ze4lYwfT8BZ2UDyGiuQTT7yc=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4=
github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c=
github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q=
github.com/lithammer/fuzzysearch v1.1.8 h1:/HIuJnjHuXS8bKaiTMeeDlW2/AyIWk2brx1V8LFgLN4=
github.com/lithammer/fuzzysearch v1.1.8/go.mod h1:IdqeyBClc3FFqSzYq/MXESsS4S0FsZ5ajtkr5xPLts4=
github.com/liuzl/cedar-go v0.0.0-20170805034717-80a9c64b256d h1:qSmEGTgjkESUX5kPMSGJ4pcBUtYVDdkNzMrjQyvRvp0=
github.com/liuzl/cedar-go v0.0.0-20170805034717-80a9c64b256d/go.mod h1:x7SghIWwLVcJObXbjK7S2ENsT1cAcdJcPl7dRaSFog0=
github.com/liuzl/da v0.0.0-20180704015230-14771aad5b1d h1:hTRDIpJ1FjS9ULJuEzu69n3qTgc18eI+ztw/pJv47hs=
github.com/liuzl/da v0.0.0-20180704015230-14771aad5b1d/go.mod h1:7xD3p0XnHvJFQ3t/stEJd877CSIMkH/fACVWen5pYnc=
github.com/liuzl/gocc v0.0.0-20231231122217-0372e1059ca5 h1:wnbHIeP1UX8ClYEWKGnw66PfYvReCHu9G5lXSte3Sqc=
github.com/liuzl/gocc v0.0.0-20231231122217-0372e1059ca5/go.mod h1:7KaV9YIR92M1FpbczAcfYQ3UZ5ayT27pNtunDmXvLBo=
github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-sqlite3 v1.14.0 h1:mLyGNKR8+Vv9CAU7PphKa2hkEqxxhn8i32J6FPj1/QA=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
@@ -154,16 +153,14 @@ github.com/mewkiz/flac v1.0.7/go.mod h1:yU74UH277dBUpqxPouHSQIar3G1X/QIclVbFahSd
github.com/mewkiz/pkg v0.0.0-20190919212034-518ade7978e2/go.mod h1:3E2FUC/qYUfM8+r9zAwpeHJzqRVVMIYnpzD/clwWxyA=
github.com/mroth/weightedrand v1.0.0 h1:V8JeHChvl2MP1sAoXq4brElOcza+jxLkRuwvtQu8L3E=
github.com/mroth/weightedrand v1.0.0/go.mod h1:3p2SIcC8al1YMzGhAIoXD+r9olo/g/cdJgAD905gyNE=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/notnil/chess v1.9.0 h1:YMxR5kUVjtwcuFptGU0/3q7eG3MSHQNbg0VUekvRKV0=
github.com/notnil/chess v1.9.0/go.mod h1:cRuJUIBFq9Xki05TWHJxHYkC+fFpq45IWwk94DdlCrA=
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0=
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -173,148 +170,134 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo=
github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A=
github.com/quic-go/qtls-go1-20 v0.3.3 h1:17/glZSLI9P9fDAeyCHBFSWSqJcwx1byhLwP5eUIDCM=
github.com/quic-go/qtls-go1-20 v0.3.3/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58b/fMC9mAL+k=
github.com/quic-go/quic-go v0.38.1 h1:M36YWA5dEhEeT+slOu/SwMEucbYd0YFidxG3KlGPZaE=
github.com/quic-go/quic-go v0.38.1/go.mod h1:ijnZM7JsFIkp4cRyjxJNIzdSfCLmUMg9wdyhGmg+SN4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/shirou/gopsutil/v3 v3.23.1 h1:a9KKO+kGLKEvcPIs4W62v0nu3sciVDOOOPUD0Hz7z/4=
github.com/shirou/gopsutil/v3 v3.23.1/go.mod h1:NN6mnm5/0k8jw4cBfCnJtr5L7ErOTg18tMNpgFkn0hA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/shirou/gopsutil/v3 v3.24.4 h1:dEHgzZXt4LMNm+oYELpzl9YCqV65Yr/6SfrvgRBtXeU=
github.com/shirou/gopsutil/v3 v3.24.4/go.mod h1:lTd2mdiOspcqLgAnr9/nGi71NkeMpWKdmhuxm9GusH8=
github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tetratelabs/wazero v1.5.0 h1:Yz3fZHivfDiZFUXnWMPUoiW7s8tC1sjdBtlJn08qYa0=
github.com/tetratelabs/wazero v1.5.0/go.mod h1:0U0G41+ochRKoPKCJlh0jMg1CHkyfK8kDqiirMmKY8A=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.17.3 h1:bwWLZU7icoKRG+C+0PNwIKC6FCJO/Q3p2pZvuP0jN94=
github.com/tidwall/gjson v1.17.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
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.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI=
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4=
github.com/wcharczuk/go-chart/v2 v2.1.0 h1:tY2slqVQ6bN+yHSnDYwZebLQFkphK4WNrVwnt7CJZ2I=
github.com/wcharczuk/go-chart/v2 v2.1.0/go.mod h1:yx7MvAVNcP/kN9lKXM/NTce4au4DFN99j6i1OwDclNA=
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20231009162356-57f71b9f5258 h1:Q0dKoj9SHrR8WjjlcX+eyYBjQKqBn/x1pdJJO1IIOxQ=
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20231009162356-57f71b9f5258/go.mod h1:y29UIOy0RD3P+0meDNIWRhcJF3jtWPN9xP9hgt/AJAU=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/wcharczuk/go-chart/v2 v2.1.1 h1:2u7na789qiD5WzccZsFz4MJWOJP72G+2kUuJoSNqWnE=
github.com/wcharczuk/go-chart/v2 v2.1.1/go.mod h1:CyCAUt2oqvfhCl6Q5ZvAZwItgpQKZOkCJGb+VGv6l14=
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20240829093431-bea5257d1a2b h1:DGVFcw0yQxLXmqWmVCqt5AfJd3V1Sea6af7hB0ynCfg=
github.com/wdvxdr1123/ZeroBot v1.7.5-0.20240829093431-bea5257d1a2b/go.mod h1:C86nQ0gIdAri4K2vg8IIQIslt08zzrKMcqYt8zhkx1M=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/gomidi/midi/v2 v2.0.25 h1:dkzVBqbaFHjyWwP71MrQNX7IeRUIDonddmHbPpO/Ucg=
gitlab.com/gomidi/midi/v2 v2.0.25/go.mod h1:quTyMKSQ4Klevxu6gY4gy2USbeZra0fV5SalndmPfsY=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
gitlab.com/gomidi/midi/v2 v2.1.7 h1:lIjVXH+bnGG04j/kUVOFILt0BQvBeGz8Kyz0l6aM830=
gitlab.com/gomidi/midi/v2 v2.1.7/go.mod h1:Cj6K9VH5GhYvPgL2JddxHBmZiP3nxKxB5XyTxiXvL9U=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8 h1:idBdZTd9UioThJp8KpM/rTSinK/ChZFBE43/WtIy8zg=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4=
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db h1:D/cFflL63o2KSLJIwjlcIt8PR064j/xsmdEJL/YvY/o=
golang.org/x/exp v0.0.0-20221205204356-47842c84f3db/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/exp/shiny v0.0.0-20221126150942-6ab00d035af9 h1:tLxpBz7qD8qFkRDC159unetNbxKp4zeqsqw2rLwvdxc=
golang.org/x/exp/shiny v0.0.0-20221126150942-6ab00d035af9/go.mod h1:VjAR7z0ngyATZTELrBSkxOOHhhlnVUxDye4mcjx5h/8=
golang.org/x/image v0.0.0-20190220214146-31aff87c08e9/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.3.0 h1:HTDXbdK9bjfSWkPzDJIw89W8CAtfFGduujWs33NLLsg=
golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
golang.org/x/image v0.16.0 h1:9kloLAKhUufZhA12l5fwnx2NZW39/we1UhBesW433jw=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6 h1:vyLBGJPIl9ZYbcQFM2USFmJBK6KI+t+z6jL0lbwjrnc=
golang.org/x/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f h1:kgfVkAEEQXXQ0qc6dH7n6y37NAYmTFmz0YRwrRjgxKw=
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/libc v1.21.5 h1:xBkU9fnHV+hvZuPSRszN0AXDG4M7nwPLwTWwkYcvLCI=
modernc.org/libc v1.21.5/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/cc/v4 v4.21.2 h1:dycHFB/jDc3IyacKipCNSDrjIC0Lm1hyoWOZTRR20Lk=
modernc.org/ccgo/v4 v4.17.8 h1:yyWBf2ipA0Y9GGz/MmCmi3EFpKgeS7ICrAFes+suEbs=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=

269
gomod2nix.toml Normal file
View File

@@ -0,0 +1,269 @@
schema = 3
[mod]
[mod."github.com/Baidu-AIP/golang-sdk"]
version = "v1.1.1"
hash = "sha256-hKshA0K92bKuK92mmtM0osVmqLJcSbeobeWSDpQoRCo="
[mod."github.com/FloatTech/AnimeAPI"]
version = "v1.7.1-0.20240530072450-71c23d2f01f8"
hash = "sha256-NUYNGhjVW5bdpWIeKjBhnVTsjf6OXNqCcqzrRd3c+gE="
[mod."github.com/FloatTech/floatbox"]
version = "v0.0.0-20240505082030-226ec6713e14"
hash = "sha256-v296D9T1QzFmcHQJNxJvx7sMtK+Jd1TUHXWqZtIvvf4="
[mod."github.com/FloatTech/gg"]
version = "v1.1.3"
hash = "sha256-7K/R2mKjUHVnoJ3b1wDObJ5Un2Htj59Y97G1Ja1tuPo="
[mod."github.com/FloatTech/imgfactory"]
version = "v0.2.2-0.20230413152719-e101cc3606ef"
hash = "sha256-2okFyPQSYIxrc8hxICsbjEM9xq25a3I2A4wmDIYFCg8="
[mod."github.com/FloatTech/rendercard"]
version = "v0.1.1"
hash = "sha256-w5GcscWQzgdcfC0Vw4u+7/NipP3PTB2UrVcxki88IPo="
[mod."github.com/FloatTech/sqlite"]
version = "v1.6.3"
hash = "sha256-zWPByEMi89ms67ubPg0fAPIRxfpBC2IRKc0iNVLqkPU="
[mod."github.com/FloatTech/ttl"]
version = "v0.0.0-20240716161252-965925764562"
hash = "sha256-/XjfdVXEzYgeM+OYuyy76tf13lO91vCcwpjWgkRGteU="
[mod."github.com/FloatTech/zbpctrl"]
version = "v1.6.2-0.20240904160347-1317e11a15bb"
hash = "sha256-x0ZR2bnkboEIjjRFMtMAN0T34BP9BPs7r3AwT3BCyzo="
[mod."github.com/FloatTech/zbputils"]
version = "v1.7.2-0.20240822065525-5ea6811ed91c"
hash = "sha256-ouAExps1iPCcD1AmOxyhRXMBGHBDXvUGkplcnQCf3Bg="
[mod."github.com/RomiChan/syncx"]
version = "v0.0.0-20240418144900-b7402ffdebc7"
hash = "sha256-L1j1vgiwqXpF9pjMoRRlrQUHzoULisw/01plaEAwxs4="
[mod."github.com/RomiChan/websocket"]
version = "v1.4.3-0.20220227141055-9b2c6168c9c5"
hash = "sha256-Adx+gvqB+CCoUXx7ebIaBDjVkav+wS5qZPmaqcApBWA="
[mod."github.com/adamzy/cedar-go"]
version = "v0.0.0-20170805034717-80a9c64b256d"
hash = "sha256-N19KTxh70IUBqnchFuWkrJD8uuFOIVqv1iSuN3YFIT0="
[mod."github.com/ajstarks/svgo"]
version = "v0.0.0-20200320125537-f189e35d30ca"
hash = "sha256-ALeRuEJN9jHjGb4wNKJcxC59vVx8Tj7hHikEGkaZZ0s="
[mod."github.com/antchfx/htmlquery"]
version = "v1.3.1"
hash = "sha256-4ZzKk7Z+vH8ytisdtcZz/Y0MbnVVhruiO/7gtUy3ouQ="
[mod."github.com/antchfx/xpath"]
version = "v1.3.0"
hash = "sha256-SU+Tnf5c9vsDCrY1BVKjqYLhB91xt9oHBS5bicbs2cA="
[mod."github.com/blend/go-sdk"]
version = "v1.20220411.3"
hash = "sha256-yxrf24hru8NeTPUmoaJG1PcmHE5pn/U36Sj9Qg+JVqg="
[mod."github.com/corona10/goimagehash"]
version = "v1.1.0"
hash = "sha256-HyS8nc7kUNnDaVBDzJ9Ym4pRs83YB4M2vHSRwfm6mr4="
[mod."github.com/davidscholberg/go-durationfmt"]
version = "v0.0.0-20170122144659-64843a2083d3"
hash = "sha256-0rdbpBf3AAjMpxvVEGFb2ImgB2i7vdEhIwCyqJs1iHE="
[mod."github.com/disintegration/imaging"]
version = "v1.6.2"
hash = "sha256-pSeMTPvSkxlthh65LjNYYhPLvCZDkBgVgAGYWW0Aguo="
[mod."github.com/dustin/go-humanize"]
version = "v1.0.1"
hash = "sha256-yuvxYYngpfVkUg9yAmG99IUVmADTQA0tMbBXe0Fq0Mc="
[mod."github.com/ericpauley/go-quantize"]
version = "v0.0.0-20200331213906-ae555eb2afa4"
hash = "sha256-sMN6D7IlDpDqUWM8ppoE5Sdb7DvLAJaN6qAucBWJ3rs="
[mod."github.com/faiface/beep"]
version = "v1.1.0"
hash = "sha256-66qAbnJjUjhXofxlGCa6G1+vjQcSTyN/POCZvYzHaQo="
[mod."github.com/fumiama/ahsai"]
version = "v0.1.0"
hash = "sha256-lSoos+SFjALcL0ZYPsbOb8wntwn2fcubvSsz0YKgL9c="
[mod."github.com/fumiama/cron"]
version = "v1.3.0"
hash = "sha256-/sN7X8dKXQgv8J+EDzVUB+o+AY9gBC8e1C6sYhaTy1k="
[mod."github.com/fumiama/go-base16384"]
version = "v1.7.0"
hash = "sha256-vTAsBBYe2ISzb2Nba5E96unodZSkhMcqo6hbwR01nz8="
[mod."github.com/fumiama/go-registry"]
version = "v0.2.7"
hash = "sha256-Rjl+z0Hlp2LMi8+pnFe5HrxctyHMi7UPiK33g/OgLdA="
[mod."github.com/fumiama/go-simple-protobuf"]
version = "v0.2.0"
hash = "sha256-2kULBi1sXsFDX2g/KRFmCGkwF60o/UXacNUbIYa/cvw="
[mod."github.com/fumiama/gofastTEA"]
version = "v0.0.10"
hash = "sha256-FOCbkXoS8s/K54yZbhX5pmaN/ouELnCHZoNS8a90VAg="
[mod."github.com/fumiama/gotracemoe"]
version = "v0.0.3"
hash = "sha256-O3cDkVXu5NG1ZtzubxhH+S91zfgu4uH1L+OiSGYSNXQ="
[mod."github.com/fumiama/imgsz"]
version = "v0.0.4"
hash = "sha256-rrGx+v41OEl0ATwL6u5TNcpfkCQbj3jFNnGiQUNu2qs="
[mod."github.com/fumiama/jieba"]
version = "v0.0.0-20221203025406-36c17a10b565"
hash = "sha256-DvDx1pdldkdaSszrbadM/VwqT9TTSmWl6G6a+ysXYEM="
[mod."github.com/fumiama/slowdo"]
version = "v0.0.0-20241001074058-27c4fe5259a4"
hash = "sha256-rsV3MKRCSOBMIgJXFCGbCHRY2aBAb32ftU49hT3GjqY="
[mod."github.com/fumiama/terasu"]
version = "v0.0.0-20240507144117-547a591149c0"
hash = "sha256-ZZG5/Ckq4R0eojmiuli5ZRToDNQt4VeRwdy0jjVCvbg="
[mod."github.com/fumiama/unibase2n"]
version = "v0.0.0-20240530074540-ec743fd5a6d6"
hash = "sha256-I3xNzjrj5y0fy0dfa75V57GanfmHIHmubEn9/y0BBHw="
[mod."github.com/gabriel-vasile/mimetype"]
version = "v1.0.4"
hash = "sha256-5hl9zBo3nkPt8dZfcLoOix8lAKLm3qIkWhopoS4V34E="
[mod."github.com/go-ole/go-ole"]
version = "v1.2.6"
hash = "sha256-+oxitLeJxYF19Z6g+6CgmCHJ1Y5D8raMi2Cb3M6nXCs="
[mod."github.com/golang/freetype"]
version = "v0.0.0-20170609003504-e2365dfdc4a0"
hash = "sha256-AHAFBd20/tqxohkWyQkui2bUef9i1HWYgk9LOIFErvA="
[mod."github.com/golang/groupcache"]
version = "v0.0.0-20210331224755-41bb18bfe9da"
hash = "sha256-7Gs7CS9gEYZkbu5P4hqPGBpeGZWC64VDwraSKFF+VR0="
[mod."github.com/google/uuid"]
version = "v1.6.0"
hash = "sha256-VWl9sqUzdOuhW0KzQlv0gwwUQClYkmZwSydHG2sALYw="
[mod."github.com/hajimehoshi/oto"]
version = "v0.7.1"
hash = "sha256-eRgbEbsziY5F0oI7wAe29FepZG7uGmq2M4deouDHcXI="
[mod."github.com/jfreymuth/oggvorbis"]
version = "v1.0.1"
hash = "sha256-DpkiTLxAA/iCoiylpNRvMzvaDWtK+U4UMJYNnnCmJMU="
[mod."github.com/jfreymuth/vorbis"]
version = "v1.0.0"
hash = "sha256-6kTol+g3NnZ3MazD786fvraw7ydUf0RWNBzHpzgN9Jk="
[mod."github.com/jinzhu/gorm"]
version = "v1.9.16"
hash = "sha256-qKEwgNE8NxcX1uzT20LwC1TKVmve/nIy+oxdAKlxAuc="
[mod."github.com/jinzhu/inflection"]
version = "v1.0.0"
hash = "sha256-3h3pHib5MaCXKyKLIMyQnSptDJ16kPjCOQPoEBoQsZg="
[mod."github.com/jozsefsallai/gophersauce"]
version = "v1.0.1"
hash = "sha256-29DsfnGmK51DPunR/leRBKCcokN/yLoB7S2HxCsqtgY="
[mod."github.com/kanrichan/resvg-go"]
version = "v0.0.2-0.20231001163256-63db194ca9f5"
hash = "sha256-plRZ3yhyCafCXmAD4vnFUoCTRsHmLp7Jn9gFKcEKbds="
[mod."github.com/kr/text"]
version = "v0.2.0"
hash = "sha256-fadcWxZOORv44oak3jTxm6YcITcFxdGt4bpn869HxUE="
[mod."github.com/lithammer/fuzzysearch"]
version = "v1.1.8"
hash = "sha256-aMMRcrlUc9CBiiNkcnWWn4hfNMNyVhrAt67kvP4D4Do="
[mod."github.com/liuzl/cedar-go"]
version = "v0.0.0-20170805034717-80a9c64b256d"
hash = "sha256-N19KTxh70IUBqnchFuWkrJD8uuFOIVqv1iSuN3YFIT0="
[mod."github.com/liuzl/da"]
version = "v0.0.0-20180704015230-14771aad5b1d"
hash = "sha256-J43kwDFmB6LzDhS3Ig/4ddZUTXz1cKztbTA3hILScs8="
[mod."github.com/liuzl/gocc"]
version = "v0.0.0-20231231122217-0372e1059ca5"
hash = "sha256-Dr1xDbO+eR4Y/EpPgQ/S6g6C5etRFKWr8de77skcJR8="
[mod."github.com/lufia/plan9stats"]
version = "v0.0.0-20211012122336-39d0f177ccd0"
hash = "sha256-thb+rkDx5IeWMgw5/5jgu5gZ+6RjJAUXeMgSkJHhRlA="
[mod."github.com/mattn/go-isatty"]
version = "v0.0.20"
hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ="
[mod."github.com/mroth/weightedrand"]
version = "v1.0.0"
hash = "sha256-bP+yIaBUY5+oI455mNM8zh14z/SNPaQg44L3RJ0/v/c="
[mod."github.com/ncruces/go-strftime"]
version = "v0.1.9"
hash = "sha256-T0iw+UEckzueWHT88PkTnZZixyKCEa+DTLzIiiohuWY="
[mod."github.com/nfnt/resize"]
version = "v0.0.0-20180221191011-83c6a9932646"
hash = "sha256-yvPV+HlDOyJsiwAcVHQkmtw8DHSXyw+cXHkigXm8rAA="
[mod."github.com/notnil/chess"]
version = "v1.9.0"
hash = "sha256-2bHp/H5hBE/hPMT1HLOBqMaCZ/DYWJMDri26O9Yzoms="
[mod."github.com/pbnjay/memory"]
version = "v0.0.0-20210728143218-7b4eea64cf58"
hash = "sha256-QI+F1oPLOOtwNp8+m45OOoSfYFs3QVjGzE0rFdpF/IA="
[mod."github.com/pkg/errors"]
version = "v0.9.1"
hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
[mod."github.com/pkumza/numcn"]
version = "v1.0.0"
hash = "sha256-cPxqj5tb10+MurN1Lehkk/v8KjaxXpL08+pVgL4x4Hg="
[mod."github.com/power-devops/perfstat"]
version = "v0.0.0-20210106213030-5aafc221ea8c"
hash = "sha256-ywykDYuqcMt0TvZOz1l9Z6Z2JMTYQw8cP2fT8AtpmX4="
[mod."github.com/remyoudompheng/bigfft"]
version = "v0.0.0-20230129092748-24d4a6f8daec"
hash = "sha256-vYmpyCE37eBYP/navhaLV4oX4/nu0Z/StAocLIFqrmM="
[mod."github.com/rogpeppe/go-internal"]
version = "v1.12.0"
hash = "sha256-qvDNCe3l84/LgrA8X4O15e1FeDcazyX91m9LmXGXX6M="
[mod."github.com/shirou/gopsutil/v3"]
version = "v3.24.4"
hash = "sha256-ubkBxu9X4LRhI1HqkjsIShR4e8rQsuKQs4VNOIIhZCU="
[mod."github.com/shoenig/go-m1cpu"]
version = "v0.1.6"
hash = "sha256-hT+JP30BBllsXosK/lo89HV/uxxPLsUyO3dRaDiLnCg="
[mod."github.com/sirupsen/logrus"]
version = "v1.9.3"
hash = "sha256-EnxsWdEUPYid+aZ9H4/iMTs1XMvCLbXZRDyvj89Ebms="
[mod."github.com/tetratelabs/wazero"]
version = "v1.5.0"
hash = "sha256-fGdJM4LJrZA9jxHuYVo4EUQ3I1k0IVG3QQCBCgZkeZI="
[mod."github.com/tidwall/gjson"]
version = "v1.17.3"
hash = "sha256-zui8S4qlfFXNLartKynJbYqeM/MW3f3eDbojIvh/KS8="
[mod."github.com/tidwall/match"]
version = "v1.1.1"
hash = "sha256-M2klhPId3Q3T3VGkSbOkYl/2nLHnsG+yMbXkPkyrRdg="
[mod."github.com/tidwall/pretty"]
version = "v1.2.0"
hash = "sha256-esRQGsn2Ee/CiySlwyuOICSLdqUkH4P7u8qXszos8Yc="
[mod."github.com/tklauser/go-sysconf"]
version = "v0.3.12"
hash = "sha256-91VBZNb3L2TZkEETF1AE4wnraLoGxKeofUbC5ZiWVHk="
[mod."github.com/tklauser/numcpus"]
version = "v0.6.1"
hash = "sha256-8eFcw4YI0w6+GPhU5xMMQjiio94q/O5PpNO3QsvXve0="
[mod."github.com/wcharczuk/go-chart/v2"]
version = "v2.1.1"
hash = "sha256-emvjt/ze8skM+MBflwV0EgS/svpaEGU/mn27Ie4VTXs="
[mod."github.com/wdvxdr1123/ZeroBot"]
version = "v1.7.5-0.20240829093431-bea5257d1a2b"
hash = "sha256-P8kexm2KOaXIk4Xnex5e02vv1ObTeWKhnWnxnDXrUDE="
[mod."github.com/yusufpapurcu/wmi"]
version = "v1.2.4"
hash = "sha256-N+YDBjOW59YOsZ2lRBVtFsEEi48KhNQRb63/0ZSU3bA="
[mod."gitlab.com/gomidi/midi/v2"]
version = "v2.1.7"
hash = "sha256-fbgxSMCk7PVII3sNEKuGWbN56fy3eM564Xb+lnYTxRQ="
[mod."golang.org/x/exp"]
version = "v0.0.0-20190306152737-a1d7652674e8"
hash = "sha256-VJ0sxFsqnx2O/NmXamL2F5bQeUw5sizVQ7NLusceK5Q="
[mod."golang.org/x/image"]
version = "v0.16.0"
hash = "sha256-+BOLefaFM/c+AV3kmnNvztbhZ+a9GCNwkEya8hZSKYg="
[mod."golang.org/x/mobile"]
version = "v0.0.0-20190415191353-3e0bab5405d6"
hash = "sha256-Ds7JS9muxzDc7WgCncAd0rMSFeBI88/I0dQsk13/56k="
[mod."golang.org/x/net"]
version = "v0.24.0"
hash = "sha256-w1c21ljta5wNIyel9CSIn/crPzwOCRofNKhqmfs4aEQ="
[mod."golang.org/x/sys"]
version = "v0.20.0"
hash = "sha256-mowlaoG2k4n1c1rApWef5EMiXd3I77CsUi8jPh6pTYA="
[mod."golang.org/x/text"]
version = "v0.15.0"
hash = "sha256-pBnj0AEkfkvZf+3bN7h6epCD2kurw59clDP7yWvxKlk="
[mod."gopkg.in/yaml.v3"]
version = "v3.0.1"
hash = "sha256-FqL9TKYJ0XkNwJFnq9j0VvJ5ZUU1RvH/52h/f5bkYAU="
[mod."modernc.org/libc"]
version = "v0.0.0-20240530081950-6f6d8586b5c5"
hash = "sha256-SJYYRaiDUmIbqy9l/IgiT/4VkFsPYsaslqGEowut34w="
replaced = "github.com/fumiama/libc"
[mod."modernc.org/mathutil"]
version = "v1.6.0"
hash = "sha256-lfuEiS1odd2TWrTylnaGihSJ9myqKs3FLdpvd7PqTnE="
[mod."modernc.org/memory"]
version = "v1.8.0"
hash = "sha256-ucvPr73zg8LjvU+bcoIPKTgwgcon3U9VhKrLEMH81xg="
[mod."modernc.org/sqlite"]
version = "v1.29.10-simp"
hash = "sha256-HCUVN6gZDG0g2WIsQ4ksqE1+XR1IjxvnqEBEU2MO1eE="
replaced = "github.com/fumiama/sqlite3"

View File

@@ -3,13 +3,13 @@
package banner
// Version ...
var Version = "v1.7.6"
var Version = "v1.8.4"
// Copyright ...
var Copyright = "© 2020 - 2023 FloatTech"
var Copyright = "© 2020 - 2024 FloatTech"
// Banner ...
var Banner = "* OneBot + ZeroBot + Golang\n" +
"* Version " + Version + " - 2023-11-08 14:13:37 +0900 JST\n" +
"* Version " + Version + " - 2024-10-05 21:11:11 +0900 JST\n" +
"* Copyright " + Copyright + ". All Rights Reserved.\n" +
"* Project: https://github.com/FloatTech/ZeroBot-Plugin"

25
main.go
View File

@@ -34,6 +34,8 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chat" // 基础词库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chatcount" // 聊天时长统计
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/sleepmanage" // 统计睡眠时间
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/atri" // ATRI词库
@@ -62,18 +64,15 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ahsai" // ahsai tts
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aifalse" // 服务器监控
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aipaint" // ai绘图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aiwife" // 随机老婆
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/alipayvoice" // 支付宝到账语音
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/autowithdraw" // 触发者撤回时也自动撤回
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu" // 百度一下
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baiduaudit" // 百度内容审核
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/base16384" // base16384加解密
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/base64gua" // base64卦加解密
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baseamasiro" // base天城文加解密
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/bilibili" // b站相关
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/bookreview" // 哀伤雪刃吧推书记录
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cangtoushi" // 藏头诗
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chess" // 国际象棋
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/choose" // 选择困难症帮手
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/chouxianghua" // 说抽象话
@@ -85,7 +84,6 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dish" // 程序员做饭指南
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drawlots" // 多功能抽签
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress" // 女装
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/driftbottle" // 漂流瓶
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/event" // 好友申请群聊邀请事件处理
@@ -96,18 +94,15 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/gif" // 制图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/github" // 搜索GitHub仓库
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/guessmusic" // 猜歌
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/heisi" // 黑丝
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hitokoto" // 一言
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hs" // 炉石
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/hyaku" // 百人一首
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/imgfinder" // 关键字搜图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/inject" // 注入指令
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jandan" // 煎蛋网无聊图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jiami" // 兽语加密
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/jptingroom" // 日语听力学习材料
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/juejuezi" // 绝绝子生成器
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/kfccrazythursday" // 疯狂星期四
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolicon" // lolicon 随机图片
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/lolimi" // 桑帛云 API
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/magicprompt" // magicprompt吟唱提示
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/mcfish" // 钓鱼模拟器
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/midicreate" // 简易midi音乐制作
@@ -118,18 +113,19 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nativesetu" // 本地涩图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nbnhhsh" // 拼音首字母缩写释义工具
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nihongo" // 日语语法学习
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/niuniu" // 牛牛大作战
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/novel" // 铅笔小说网搜索
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nsfw" // nsfw图片识别
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/nwife" // 本地老婆
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/omikuji" // 浅草寺求签
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/poker" // 抽扑克
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/qqwife" // 一群一天一夫一妻制群老婆
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/quan" // QQ权重查询
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/qzone" // qq空间表白墙
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/realcugan" // realcugan清晰术
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/reborn" // 投胎
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/robbery" // 打劫群友的ATRI币
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/runcode" // 在线运行代码
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/saucenao" // 以图搜图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/scale" // 叔叔的AI二次元图片放大
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/score" // 分数
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/setutime" // 来份涩图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/shadiao" // 沙雕app
@@ -140,19 +136,16 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/tracemoe" // 搜番
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vitsnyaru" // vits猫雷
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbmusic" // vtb点歌
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtbquotation" // vtb语录
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet" // 钱包
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wantquotes" // 据意查句
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" // warframeAPI插件
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinvilg" // 百度文心AI画图
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wife" // 抽老婆
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordcount" // 聊天热词
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/yujn" // 遇见API
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
@@ -176,7 +169,7 @@ import (
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/curse" // 骂人
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ai_reply" // 人工智能回复
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/aireply" // 人工智能回复
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus" // 词典匹配回复
@@ -194,6 +187,7 @@ import (
// //
// //
// -----------------------以下为内置依赖,勿动------------------------ //
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/process"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
@@ -234,6 +228,7 @@ func init() {
rsz := flag.Uint("r", 4096, "Receiving buffer ring size.")
maxpt := flag.Uint("x", 4, "Max process time (min).")
markmsg := flag.Bool("m", false, "Don't mark message as read automatically")
flag.BoolVar(&file.SkipOriginal, "mirror", false, "Use mirrored lazy data at first")
flag.Parse()

View File

@@ -184,7 +184,7 @@ func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string, botrunsta
return
}
data, err = web.GetData("http://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640")
data, err = web.GetData("https://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640")
if err != nil {
return
}

View File

@@ -1,224 +0,0 @@
// Package aipaint ai绘图
package aipaint
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/url"
"os"
"regexp"
"strconv"
"strings"
"time"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
var (
datapath string
predictRe = regexp.MustCompile(`{"steps".+?}`)
// 参考host http://91.217.139.190:5010 http://91.216.169.75:5010
aipaintTxt2ImgURL = "/got_image?token=%v&tags=%v"
aipaintImg2ImgURL = "/got_image2image?token=%v&tags=%v"
cfg = newServerConfig("data/aipaint/config.json")
)
type result struct {
Steps int `json:"steps"`
Sampler string `json:"sampler"`
Seed int `json:"seed"`
Strength float64 `json:"strength"`
Noise float64 `json:"noise"`
Scale float64 `json:"scale"`
Uc string `json:"uc"`
}
func (r *result) String() string {
return fmt.Sprintf("steps: %v\nsampler: %v\nseed: %v\nstrength: %v\nnoise: %v\nscale: %v\nuc: %v\n", r.Steps, r.Sampler, r.Seed, r.Strength, r.Noise, r.Scale, r.Uc)
}
func init() { // 插件主体
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "ai绘图",
Help: "- [ ai绘图 | 生成色图 | 生成涩图 | ai画图 ] xxx\n" +
"- [ ai高级绘图 | 高级生成色图 | 高级生成涩图 | ai高级画图 ] [prompt]\n" +
"- 设置ai绘图配置 [server] [token]\n" +
"- 设置ai绘图撤回时间90s\n" +
"- 查看ai绘图配置\n" +
"Tips: 使用前请先前往 http://91.217.139.190:5010/token 按提示获取token" +
"设置token示例(请确保是主人并且响应): 设置ai绘图配置 http://91.217.139.190:5010 [token] (中括号无需输入)\n" +
"参考服务器 http://91.217.139.190:5010, http://91.216.169.75:5010, http://185.80.202.180:5010\n" +
"[prompt]参数如下\n" +
"tags:tag词条\nntags:ntag词条\nshape:[Portrait|Landscape|Square]\nscale:[6:20]\nseed:种子\nstrength:[0-1] 建议0-0.7\nnoise:[0-1] 建议0-0.15" +
"参数与参数内容用:连接,每个参数之间用回车分割",
PrivateDataFolder: "aipaint",
})
datapath = file.BOTPATH + "/" + engine.DataFolder()
if file.IsNotExist(cfg.file) {
s := serverConfig{}
data, err := json.Marshal(s)
if err != nil {
panic(err)
}
err = os.WriteFile(cfg.file, data, 0666)
if err != nil {
panic(err)
}
}
engine.OnPrefixGroup([]string{`ai绘图`, `生成色图`, `生成涩图`, `ai画图`}).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("少女祈祷中..."))
args := ctx.State["args"].(string)
data, err := web.GetData(cfg.BaseURL + fmt.Sprintf(aipaintTxt2ImgURL, cfg.Token, url.QueryEscape(strings.TrimSpace(strings.ReplaceAll(args, " ", "%20")))))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
sendAiImg(ctx, data, cfg.Interval)
})
engine.OnPrefixGroup([]string{`ai高级绘图`, `高级生成色图`, `高级生成涩图`, `ai高级画图`}).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
tags := make(map[string]string)
args := strings.Split(ctx.State["args"].(string), "\n")
if len(args) < 1 {
ctx.SendChain(message.Text("ERROR: 请输入正确的参数"))
return
}
for _, info := range args {
value := strings.Split(info, ":")
if len(value) > 1 {
if value[0] == "R18" && value[1] == "1" {
value[1] = "0"
ctx.SendChain(message.Text("不准涩涩! 已将R18设置为0. "))
}
tags[value[0]] = strings.Join(value[1:], ":")
}
}
ctx.SendChain(message.Text("少女祈祷中..."))
apiurl := "/got_image?token=" + cfg.Token
if _, ok := tags["tags"]; ok {
apiurl += "&tags=" + url.QueryEscape(strings.ReplaceAll(strings.TrimSpace(tags["tags"]), " ", "%20"))
}
if _, ok := tags["ntags"]; ok {
apiurl += "&ntags=" + url.QueryEscape(strings.ReplaceAll(strings.TrimSpace(tags["ntags"]), " ", "%20"))
}
if _, ok := tags["R18"]; ok {
apiurl += "&R18=" + url.QueryEscape(strings.TrimSpace(tags["R18"]))
}
if _, ok := tags["shape"]; ok {
apiurl += "&shape=" + url.QueryEscape(strings.TrimSpace(tags["shape"]))
}
if _, ok := tags["scale"]; ok {
apiurl += "&scale=" + url.QueryEscape(strings.TrimSpace(tags["scale"]))
}
if _, ok := tags["seed"]; ok {
apiurl += "&seed=" + url.QueryEscape(strings.TrimSpace(tags["seed"]))
}
if _, ok := tags["strength"]; ok {
apiurl += "&strength=" + url.QueryEscape(strings.TrimSpace(tags["strength"]))
}
if _, ok := tags["noise"]; ok {
apiurl += "&noise=" + url.QueryEscape(strings.TrimSpace(tags["noise"]))
}
data, err := web.GetData(cfg.BaseURL + apiurl)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
sendAiImg(ctx, data, cfg.Interval)
})
engine.OnRegex(`^设置ai绘图配置\s(.*[^\s$])\s(.+)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
regexMatched := ctx.State["regex_matched"].([]string)
err := cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = cfg.update(regexMatched[1], regexMatched[2], cfg.Interval)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("成功设置\nbase_url: ", cfg.BaseURL, "\ntoken: ", cfg.Token, "\ninterval: ", cfg.Interval))
})
engine.OnRegex(`^设置ai绘图撤回时间(\d{1,3})s$`, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
regexMatched := ctx.State["regex_matched"].([]string)
interval, err := strconv.Atoi(regexMatched[1])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = cfg.update(cfg.BaseURL, cfg.Token, interval)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("成功设置撤回时间为", cfg.Interval, "s"))
})
engine.OnFullMatch(`查看ai绘图配置`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("base_url: ", cfg.BaseURL, "\ntoken: ", cfg.Token, "\ninterval: ", cfg.Interval))
})
}
func sendAiImg(ctx *zero.Ctx, data []byte, interval int) {
var loadData string
if predictRe.MatchString(binary.BytesToString(data)) {
loadData = predictRe.FindStringSubmatch(binary.BytesToString(data))[0]
}
var r result
if loadData != "" {
err := json.Unmarshal(binary.StringToBytes(loadData), &r)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
r.Uc, err = url.QueryUnescape(r.Uc)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
}
encodeStr := base64.StdEncoding.EncodeToString(data)
m := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Image("base64://"+encodeStr))}
m = append(m, ctxext.FakeSenderForwardNode(ctx, message.Text(r.String())))
if mid := ctx.Send(m); mid.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控或下载图片用时过长,请耐心等待"))
} else if interval > 0 {
go func(i message.MessageID) {
time.Sleep(time.Duration(interval) * time.Second)
ctx.DeleteMessage(i)
}(mid)
}
}

View File

@@ -1,56 +0,0 @@
package aipaint
import (
"encoding/json"
"errors"
"os"
"github.com/FloatTech/floatbox/file"
)
// 配置结构体
type serverConfig struct {
BaseURL string `json:"base_url"`
Token string `json:"token"`
Interval int `json:"interval"`
file string
}
func newServerConfig(file string) *serverConfig {
return &serverConfig{
file: file,
}
}
func (cfg *serverConfig) update(baseURL, token string, interval int) (err error) {
if baseURL != "" {
cfg.BaseURL = baseURL
}
if token != "" {
cfg.Token = token
}
cfg.Interval = interval
reader, err := os.Create(cfg.file)
if err != nil {
return err
}
defer reader.Close()
return json.NewEncoder(reader).Encode(cfg)
}
func (cfg *serverConfig) load() (err error) {
if cfg.BaseURL != "" && cfg.Token != "" && cfg.Interval != 0 {
return
}
if file.IsNotExist(cfg.file) {
err = errors.New("no server config")
return
}
reader, err := os.Open(cfg.file)
if err != nil {
return
}
defer reader.Close()
err = json.NewDecoder(reader).Decode(cfg)
return
}

View File

@@ -1,41 +0,0 @@
package aipaint
import (
"os"
"strconv"
"strings"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/process"
)
type context struct {
usrdir string
headimgsdir []string
}
func newContext(user int64) *context {
c := new(context)
c.usrdir = datapath + "users/" + strconv.FormatInt(user, 10) + `/`
_ = os.MkdirAll(c.usrdir, 0755)
c.headimgsdir = make([]string, 2)
c.headimgsdir[0] = c.usrdir + "0.gif"
c.headimgsdir[1] = c.usrdir + "1.gif"
return c
}
func (cc *context) prepareLogos(s ...string) error {
for i, v := range s {
_, err := strconv.Atoi(v)
if err != nil {
err = file.DownloadTo("https://gchat.qpic.cn/gchatpic_new//--"+strings.ToUpper(v)+"/0", cc.usrdir+strconv.Itoa(i)+".gif")
} else {
err = file.DownloadTo("http://q4.qlogo.cn/g?b=qq&nk="+v+"&s=640", cc.usrdir+strconv.Itoa(i)+".gif")
}
if err != nil {
return err
}
process.SleepAbout1sTo2s()
}
return nil
}

View File

@@ -1,88 +0,0 @@
// Package aipaint ai绘图
package aipaint
import (
"bytes"
"fmt"
"image"
"net/url"
"os"
"strconv"
"strings"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
"github.com/FloatTech/imgfactory"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
func init() { // 插件主体
engine := control.Register("img2img", &ctrl.Options[*zero.Ctx]{
DisableOnDefault: true,
Brief: "以图绘图",
Help: "- [ 以图绘图 | 以图生图 | 以图画图 ] xxx [图片]|@xxx|[qq号]\n" +
"- 官方以图绘图api已失效 需要自建api 其他配置参数同ai绘图",
PrivateDataFolder: "img2img",
})
datapath = file.BOTPATH + "/" + engine.DataFolder()
engine.OnRegex(`^(以图绘图|以图生图|以图画图)[\s\S]*?(\[CQ:(image\,file=([0-9a-zA-Z]{32}).*|at.+?(\d{5,11}))\].*|(\d+))$`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
err := cfg.load()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
c := newContext(ctx.Event.UserID)
list := ctx.State["regex_matched"].([]string)
err = c.prepareLogos(list[4]+list[5]+list[6], strconv.FormatInt(ctx.Event.UserID, 10))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
args := strings.TrimSuffix(strings.TrimPrefix(list[0], list[1]), list[2])
if args == "" {
ctx.SendChain(message.Text("ERROR: 以图绘图必须添加tag"))
return
}
ctx.SendChain(message.Text("少女祈祷中..."))
postURL := cfg.BaseURL + fmt.Sprintf(aipaintImg2ImgURL, cfg.Token, url.QueryEscape(strings.TrimSpace(strings.ReplaceAll(args, " ", "%20"))))
f, err := os.Open(c.headimgsdir[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
imageShape := ""
switch {
case img.Bounds().Dx() > img.Bounds().Dy():
imageShape = "Landscape"
case img.Bounds().Dx() == img.Bounds().Dy():
imageShape = "Square"
default:
imageShape = "Portrait"
}
// 图片转base64
base64Bytes, err := imgfactory.ToBase64(img)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
data, err := web.PostData(postURL+"&shape="+imageShape, "text/plain", bytes.NewReader(base64Bytes))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
sendAiImg(ctx, data, cfg.Interval)
})
}

View File

@@ -11,28 +11,29 @@ import (
"github.com/FloatTech/AnimeAPI/tts"
"github.com/FloatTech/AnimeAPI/tts/baidutts"
"github.com/FloatTech/AnimeAPI/tts/genshin"
"github.com/FloatTech/AnimeAPI/tts/lolimi"
"github.com/FloatTech/AnimeAPI/tts/ttscn"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
)
// 数据结构: [4 bits] [4 bits] [8 bits] [8 bits]
// [ttscn模式] [百度模式] [tts模式] [回复模式]
// 数据结构: [8 bits] [8 bits] [8 bits]
// [具体人物] [tts模式] [回复模式]
// defaultttsindexkey
// 数据结构: [4 bits] [4 bits] [8 bits]
// [ttscn模式] [百度模式] [tts模式]
// 数据结构: [8 bits] [8 bits]
// [具体人物] [tts模式]
// [tts模式]: 0~200 genshin 201 baidu 202 ttscn
// [tts模式]: 0~200 genshin 201 baidu 202 ttscn 203 lolimi
const (
lastgsttsindex = 200 + iota
baiduttsindex
baiduttsindex = 201 + iota
ttscnttsindex
lolimittsindex
)
// extrattsname is the tts other than genshin vits
var extrattsname = []string{"百度", "TTSCN"}
var extrattsname = []string{"百度", "TTSCN", "桑帛云"}
var ttscnspeakers = [...]string{
"晓晓(女 - 年轻人)",
@@ -59,6 +60,7 @@ var (
= newapikeystore("./data/tts/o.txt")
ཆཏ = newapikeystore("./data/tts/c.txt")
= newapikeystore("./data/tts/b.txt")
= newapikeystore("./data/tts/s.txt")
)
type replymode []string
@@ -84,10 +86,11 @@ func (r replymode) setReplyMode(ctx *zero.Ctx, name string) error {
if !ok {
return errors.New("no such plugin")
}
return m.SetData(gid, (m.GetData(index)&^0xff)|(index&0xff))
return m.SetData(gid, (m.GetData(gid)&^0xff)|(index&0xff))
}
func (r replymode) getReplyMode(ctx *zero.Ctx) aireply.AIReply {
k := .k
gid := ctx.Event.GroupID
if gid == 0 {
gid = -ctx.Event.UserID
@@ -96,18 +99,21 @@ func (r replymode) getReplyMode(ctx *zero.Ctx) aireply.AIReply {
if ok {
switch m.GetData(gid) & 0xff {
case 0:
return aireply.NewQYK(aireply.QYKURL, aireply.QYKBotName)
return aireply.NewLolimiAi(aireply.JingfengURL, aireply.JingfengBotName, k, false, 0)
case 1:
return aireply.NewXiaoAi(aireply.XiaoAiURL, aireply.XiaoAiBotName)
return aireply.NewLolimiAi(aireply.MomoURL, aireply.MomoBotName, k, false, 0)
case 2:
k := ཆཏ.k
if k != "" {
return aireply.NewChatGPT(aireply.ChatGPTURL, k)
}
return aireply.NewQYK(aireply.QYKURL, aireply.QYKBotName)
case 3:
return aireply.NewXiaoAi(aireply.XiaoAiURL, aireply.XiaoAiBotName)
case 4:
if ཆཏ.k != "" {
return aireply.NewChatGPT(aireply.ChatGPTURL, ཆཏ.k)
}
return aireply.NewLolimiAi(aireply.JingfengURL, aireply.JingfengBotName, k, false, 0)
}
}
return aireply.NewQYK(aireply.QYKURL, aireply.QYKBotName)
return aireply.NewLolimiAi(aireply.JingfengURL, aireply.JingfengBotName, k, false, 0)
}
var ttsins = func() map[string]tts.TTS {
@@ -119,8 +125,8 @@ var ttsins = func() map[string]tts.TTS {
}()
var ttsModes = func() []string {
s := append(genshin.SoundList[:], make([]string, lastgsttsindex-len(genshin.SoundList))...) // 0-200
s = append(s, extrattsname...) // 201 202 ...
s := append(genshin.SoundList[:], make([]string, baiduttsindex-len(genshin.SoundList))...) // 0-200
s = append(s, extrattsname...) // 201 202 ...
return s
}()
@@ -146,14 +152,14 @@ func newttsmode() *ttsmode {
if ok {
index := m.GetData(defaultttsindexkey)
msk := index & 0xff
if msk >= 0 && (msk < int64(len(genshin.SoundList)) || msk == baiduttsindex || msk == ttscnttsindex) {
if msk >= 0 && (msk < int64(len(ttsModes))) {
(*syncx.Map[int64, int64])(t).Store(defaultttsindexkey, index)
}
}
return t
}
func (t *ttsmode) setSoundMode(ctx *zero.Ctx, name string, baiduper, mockingsynt int) error {
func (t *ttsmode) setSoundMode(ctx *zero.Ctx, name string, character int) error {
gid := ctx.Event.GroupID
if gid == 0 {
gid = -ctx.Event.UserID
@@ -165,7 +171,7 @@ func (t *ttsmode) setSoundMode(ctx *zero.Ctx, name string, baiduper, mockingsynt
var index = int64(-1)
for i, s := range genshin.SoundList {
if s == name {
index = int64(i)
index = int64(i + 1)
break
}
}
@@ -175,13 +181,17 @@ func (t *ttsmode) setSoundMode(ctx *zero.Ctx, name string, baiduper, mockingsynt
index = baiduttsindex
case extrattsname[1]:
index = ttscnttsindex
case extrattsname[2]:
index = lolimittsindex
default:
return errors.New("语音人物" + name + "未注册index")
}
}
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
(*syncx.Map[int64, int64])(t).Store(gid, index)
return m.SetData(gid, (m.GetData(gid)&^0xffff00)|((index<<8)&0xff00)|((int64(baiduper)<<16)&0x0f0000)|((int64(mockingsynt)<<20)&0xf00000))
// 按原来的逻辑map存的是前16位
storeIndex := (m.GetData(gid) &^ 0xffff00) | ((index << 8) & 0xff00) | ((int64(character) << 16) & 0xff0000)
(*syncx.Map[int64, int64])(t).Store(gid, (storeIndex>>8)&0xffff)
return m.SetData(gid, storeIndex)
}
func (t *ttsmode) getSoundMode(ctx *zero.Ctx) (tts.TTS, error) {
@@ -195,8 +205,12 @@ func (t *ttsmode) getSoundMode(ctx *zero.Ctx) (tts.TTS, error) {
i = m.GetData(gid) >> 8
}
m := i & 0xff
if m < 0 || (m >= int64(len(genshin.SoundList)) && m != baiduttsindex && m != ttscnttsindex) {
if m <= 0 || (m >= int64(len(ttsModes))) {
i, _ = (*syncx.Map[int64, int64])(t).Load(defaultttsindexkey)
if i == 0 {
i = ctx.State["manager"].(*ctrl.Control[*zero.Ctx]).GetData(defaultttsindexkey)
(*syncx.Map[int64, int64])(t).Store(defaultttsindexkey, i)
}
m = i & 0xff
}
mode := ttsModes[m]
@@ -205,20 +219,22 @@ func (t *ttsmode) getSoundMode(ctx *zero.Ctx) (tts.TTS, error) {
switch mode {
case extrattsname[0]:
id, sec, _ := strings.Cut(.k, ",")
ins = baidutts.NewBaiduTTS(int(i&0x0f00)>>8, id, sec)
ins = baidutts.NewBaiduTTS(int(i&0xff00)>>8, id, sec)
case extrattsname[1]:
var err error
ins, err = ttscn.NewTTSCN("中文(普通话,简体)", ttscnspeakers[int(i&0xf000)>>12], ttscn.KBRates[0])
ins, err = ttscn.NewTTSCN("中文(普通话,简体)", ttscnspeakers[int(i&0xff00)>>8], ttscn.KBRates[0])
if err != nil {
return nil, err
}
case extrattsname[2]:
ins = lolimi.NewLolimi(int(i&0xff00) >> 8)
default: // 原神
k := .k
if k != "" {
ins = genshin.NewGenshin(int(m), .k)
ins = genshin.NewGenshin(int(m-1), .k)
ttsins[mode] = ins
} else {
return nil, errors.New("no valid speaker")
ins = lolimi.NewLolimi(int(i&0xff00) >> 8)
}
}
}
@@ -231,11 +247,12 @@ func (t *ttsmode) resetSoundMode(ctx *zero.Ctx) error {
gid = -ctx.Event.UserID
}
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
index := m.GetData(defaultttsindexkey)
return m.SetData(gid, (m.GetData(gid)&0xff)|((index&^0xff)<<8)) // 重置数据
// 只保留后面8位
(*syncx.Map[int64, int64])(t).Delete(gid)
return m.SetData(gid, (m.GetData(gid) & 0xff)) // 重置数据
}
func (t *ttsmode) setDefaultSoundMode(name string, baiduper, mockingsynt int) error {
func (t *ttsmode) setDefaultSoundMode(name string, character int) error {
_, ok := ttsins[name]
if !ok {
return errors.New("不支持设置语音人物" + name)
@@ -243,7 +260,7 @@ func (t *ttsmode) setDefaultSoundMode(name string, baiduper, mockingsynt int) er
index := int64(-1)
for i, s := range genshin.SoundList {
if s == name {
index = int64(i)
index = int64(i + 1)
break
}
}
@@ -253,6 +270,8 @@ func (t *ttsmode) setDefaultSoundMode(name string, baiduper, mockingsynt int) er
index = baiduttsindex
case extrattsname[1]:
index = ttscnttsindex
case extrattsname[2]:
index = lolimittsindex
default:
return errors.New("语音人物" + name + "未注册index")
}
@@ -261,6 +280,7 @@ func (t *ttsmode) setDefaultSoundMode(name string, baiduper, mockingsynt int) er
if !ok {
return errors.New("[tts] service not found")
}
(*syncx.Map[int64, int64])(t).Store(defaultttsindexkey, index)
return m.SetData(defaultttsindexkey, (index&0xff)|((int64(baiduper)<<8)&0x0f00)|((int64(mockingsynt)<<12)&0xf000))
storeIndex := (index & 0xff) | ((int64(character) << 8) & 0xff00)
(*syncx.Map[int64, int64])(t).Store(defaultttsindexkey, storeIndex)
return m.SetData(defaultttsindexkey, storeIndex)
}

View File

@@ -5,6 +5,7 @@ import (
"os"
"regexp"
"strconv"
"strings"
"time"
"github.com/FloatTech/AnimeAPI/tts/genshin"
@@ -16,7 +17,7 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
)
var replmd = replymode([]string{"青云客", "小爱", "ChatGPT"})
var replmd = replymode([]string{"婧枫", "沫沫", "青云客", "小爱", "ChatGPT"})
var ttsmd = newttsmode()
@@ -25,9 +26,10 @@ func init() { // 插件主体
DisableOnDefault: true,
Brief: "人工智能语音回复",
Help: "- @Bot 任意文本(任意一句话回复)\n" +
"- 设置语音模式[原神人物/百度/TTSCN] 数字(百度/TTSCN说话人)\n" +
"- 设置默认语音模式[原神人物/百度/TTSCN] 数字(百度/TTSCN说话人)\n" +
"- 设置语音模式[原神人物/百度/TTSCN/桑帛云] 数字(百度/TTSCN说话人/桑帛云)\n" +
"- 设置默认语音模式[原神人物/百度/TTSCN/桑帛云] 数字(百度/TTSCN说话人/桑帛云)\n" +
"- 恢复成默认语音模式\n" +
"- 设置语音回复模式[沫沫|婧枫|青云客|小爱|ChatGPT]\n" +
"- 设置原神语音 api key xxxxxx (key请加开发群获得)\n" +
"- 设置百度语音 api id xxxxxx secret xxxxxx (请自行获得)\n" +
"当前适用的原神人物含有以下: \n" + list(genshin.SoundList[:], 5) +
@@ -35,10 +37,10 @@ func init() { // 插件主体
PrivateDataFolder: "tts",
})
enr := control.Register("aireply", &ctrl.Options[*zero.Ctx]{
enr := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "人工智能回复",
Help: "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客|小爱|ChatGPT]\n- 设置 ChatGPT api key xxx",
Help: "- @Bot 任意文本(任意一句话回复)\n- 设置文字回复模式[婧枫|沫沫|青云客|小爱|ChatGPT]\n- 设置 ChatGPT api key xxx",
PrivateDataFolder: "aireply",
})
@@ -48,15 +50,10 @@ func init() { // 插件主体
reply := message.ParseMessageFromString(aireply.Talk(ctx.Event.UserID, ctx.ExtractPlainText(), zero.BotConfig.NickName[0]))
// 回复
time.Sleep(time.Second * 1)
if zero.OnlyPublic(ctx) {
reply = append(reply, message.Reply(ctx.Event.MessageID))
ctx.Send(reply)
return
}
reply = append(reply, message.Reply(ctx.Event.MessageID))
ctx.Send(reply)
})
enr.OnPrefix("设置回复模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
setReplyMode := func(ctx *zero.Ctx) {
param := ctx.State["args"].(string)
err := replmd.setReplyMode(ctx, param)
if err != nil {
@@ -64,8 +61,16 @@ func init() { // 插件主体
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功"))
}
enr.OnPrefix("设置文字回复模式", zero.AdminPermission).SetBlock(true).Handle(setReplyMode)
enr.OnRegex(`^设置\s*桑帛云\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
err := .set(ctx.State["regex_matched"].([]string)[1])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text("设置成功"))
})
enr.OnRegex(`^设置\s*ChatGPT\s*api\s*key\s*(.*)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
err := ཆཏ.set(ctx.State["regex_matched"].([]string)[1])
if err != nil {
@@ -88,7 +93,20 @@ func init() { // 插件主体
// 获取回复模式
r := replmd.getReplyMode(ctx)
// 获取回复的文本
reply := r.TalkPlain(ctx.Event.UserID, msg, zero.BotConfig.NickName[0])
reply := message.ParseMessageFromString(r.TalkPlain(ctx.Event.UserID, msg, zero.BotConfig.NickName[0]))
// 过滤掉文字消息
filterMsg := make([]message.MessageSegment, 0, len(reply))
sb := strings.Builder{}
for _, v := range reply {
if v.Type != "text" {
filterMsg = append(filterMsg, v)
} else {
sb.WriteString(v.Data["text"])
}
}
// 纯文本
plainReply := sb.String()
plainReply = strings.ReplaceAll(plainReply, "\n", "")
// 获取语音
speaker, err := ttsmd.getSoundMode(ctx)
if err != nil {
@@ -96,22 +114,27 @@ func init() { // 插件主体
return
}
rec, err := speaker.Speak(ctx.Event.UserID, func() string {
if !endpre.MatchString(reply) {
return reply + "。"
if !endpre.MatchString(plainReply) {
return plainReply + "。"
}
return reply
return plainReply
})
// 发送前面的图片
if len(filterMsg) != 0 {
filterMsg = append(filterMsg, message.Reply(ctx.Event.MessageID))
ctx.Send(filterMsg)
}
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply))
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(plainReply))
return
}
// 发送语音
if id := ctx.SendChain(message.Record(rec)); id.ID() == 0 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply))
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(plainReply))
}
})
ent.OnRegex(`^设置语音模式\s*([\S\D]*)\s+(\d*)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
ent.OnPrefix("设置语音回复模式", zero.AdminPermission).SetBlock(true).Handle(setReplyMode)
ent.OnRegex(`^设置语音模式\s*([\S\D]*)\s*(\d*)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
param := ctx.State["regex_matched"].([]string)[1]
num := ctx.State["regex_matched"].([]string)[2]
n := 0
@@ -124,8 +147,8 @@ func init() { // 插件主体
}
}
// 保存设置
logrus.Debugln("[tts] t.setSoundMode( ctx", param, n, n, ")")
err = ttsmd.setSoundMode(ctx, param, n, n)
logrus.Debugln("[tts] t.setSoundMode( ctx", param, n, ")")
err = ttsmd.setSoundMode(ctx, param, n)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
return
@@ -153,7 +176,7 @@ func init() { // 插件主体
return
}
time.Sleep(time.Second * 2)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功"))
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", speaker))
})
ent.OnRegex(`^设置默认语音模式\s*([\S\D]*)\s+(\d*)$`, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
@@ -169,7 +192,7 @@ func init() { // 插件主体
}
}
// 保存设置
err = ttsmd.setDefaultSoundMode(param, n, n)
err = ttsmd.setDefaultSoundMode(param, n)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
return

View File

@@ -53,7 +53,7 @@ func init() { // 插件主体
Brief: "atri人格文本回复",
Help: "本插件基于 ATRI ,为 Golang 移植版\n" +
"- ATRI醒醒\n- ATRI睡吧\n- 萝卜子\n- 喜欢 | 爱你 | 爱 | suki | daisuki | すき | 好き | 贴贴 | 老婆 | 亲一个 | mua\n" +
"- 草你妈 | 操你妈 | 脑瘫 | 废柴 | fw | 废物 | 战斗 | 爬 | 爪巴 | sb | SB | 傻B\n- 早安 | 早哇 | 早上好 | ohayo | 哦哈哟 | お早う | 早好 | 早 | 早早早\n" +
"- 草你妈 | 操你妈 | 脑瘫 | 废柴 | fw | 废物 | 战斗 | 爬 | 爪巴 | sb | SB | 傻B\n- 早哇 | 早上好 | ohayo | 哦哈哟 | お早う | 早好 | 早 | 早早早\n" +
"- 中午好 | 午安 | 午好\n- 晚安 | oyasuminasai | おやすみなさい | 晚好 | 晚上好\n- 高性能 | 太棒了 | すごい | sugoi | 斯国一 | よかった\n" +
"- 没事 | 没关系 | 大丈夫 | 还好 | 不要紧 | 没出大问题 | 没伤到哪\n- 好吗 | 是吗 | 行不行 | 能不能 | 可不可以\n- 啊这\n- 我好了\n- | ? | ¿\n" +
"- 离谱\n- 答应我",
@@ -84,7 +84,7 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
ctx.SendChain(dgtr.randImage("FN.jpg", "WQ.jpg", "WQ1.jpg"))
})
engine.OnFullMatchGroup([]string{"早安", "早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早", "早早早"}).SetBlock(true).
engine.OnFullMatchGroup([]string{"早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早", "早早早"}).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
now := time.Now().Hour()
switch {

View File

@@ -1,60 +0,0 @@
// Package baidu 百度百科
package baidu
import (
"encoding/json"
"fmt"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
duURL = "https://api.a20safe.com/api.php?api=21&key=%s&text=%s" // api地址
wikiURL = "https://api.a20safe.com/api.php?api=23&key=%s&text=%s"
key = "7d06a110e9e20a684e02934549db1d3d"
)
type result struct {
Code int `json:"code"`
Msg string `json:"msg"`
Data []struct {
Content string `json:"content"`
} `json:"data"`
}
func init() { // 主函数
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Help: "百科\n" +
"- 百度/百科/维基/wiki[关键字]",
})
en.OnRegex(`^(百度|维基|百科|wiki)\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
var es []byte
var err error
switch ctx.State["regex_matched"].([]string)[1] {
case "百度", "百科":
es, err = web.GetData(fmt.Sprintf(duURL, key, ctx.State["regex_matched"].([]string)[2])) // 将网站返回结果赋值
case "wiki", "维基":
es, err = web.GetData(fmt.Sprintf(wikiURL, key, ctx.State["regex_matched"].([]string)[2])) // 将网站返回结果赋值
}
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
var r result // r数组
err = json.Unmarshal(es, &r) // 填api返回结果struct地址
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
if r.Code == 0 && len(r.Data) > 0 {
ctx.SendChain(message.Text(r.Data[0].Content)) // 输出提取后的结果
} else {
ctx.SendChain(message.Text("API访问错误"))
}
})
}

View File

@@ -31,8 +31,6 @@ func (bdres *baiduRes) audit(ctx *zero.Ctx, configpath string) {
if bdres.ConclusionType != 2 {
return
}
// 创建消息ID
mid := message.NewMessageIDFromInteger(ctx.Event.MessageID.(int64))
// 获取群配置
group := config.groupof(ctx.Event.GroupID)
// 检测群配置里的不检测类型白名单, 忽略掉不检测的违规类型
@@ -44,7 +42,7 @@ func (bdres *baiduRes) audit(ctx *zero.Ctx, configpath string) {
// 生成回复文本
res := group.reply(bdres)
// 撤回消息
ctx.DeleteMessage(mid)
ctx.DeleteMessage(ctx.Event.MessageID)
// 查看是否启用撤回后禁言
if group.DMBAN {
// 从历史违规记录中获取指定用户

View File

@@ -337,12 +337,12 @@ func init() {
faceH := float64(510)
totalDanmuku := 0
for i := 0; i < len(danmaku.Data.Data); i++ {
totalDanmuku += len(danmaku.Data.Data[i].Danmakus) + 1
for i := 0; i < len(danmaku.Data.Data.Records); i++ {
totalDanmuku += len(danmaku.Data.Data.Records[i].Danmakus) + 1
}
cw := 3000
mcw := float64(2000)
ch := 550 + len(danmaku.Data.Data)*int(faceH) + totalDanmuku*int(danmuH)
ch := 550 + len(danmaku.Data.Data.Records)*int(faceH) + totalDanmuku*int(danmuH)
canvas = gg.NewContext(cw, ch)
canvas.SetColor(color.White)
canvas.Clear()
@@ -372,9 +372,9 @@ func init() {
canvas.DrawString("网页链接: "+fmt.Sprintf(bz.DanmakuURL, u.Mid), startWidth, 422.5)
var channelStart float64
channelStart = float64(550)
for i := 0; i < len(danmaku.Data.Data); i++ {
item := danmaku.Data.Data[i]
facePath = cachePath + strconv.Itoa(int(item.Channel.UID)) + "vupFace" + path.Ext(item.Channel.FaceURL)
for i := 0; i < len(danmaku.Data.Data.Records); i++ {
item := danmaku.Data.Data.Records[i]
facePath = cachePath + strconv.Itoa(item.Channel.UID) + "vupFace" + path.Ext(item.Channel.FaceURL)
if path.Ext(item.Channel.FaceURL) != ".webp" {
err = initFacePic(facePath, item.Channel.FaceURL)
if err != nil {
@@ -393,7 +393,7 @@ func init() {
}
canvas.SetRGB255(24, 144, 255)
canvas.DrawString("标题: "+item.Live.Title, startWidth, channelStart+fontH)
canvas.DrawString("主播: "+item.Channel.Name, startWidth, channelStart+fontH*2)
canvas.DrawString("主播: "+item.Channel.UName, startWidth, channelStart+fontH*2)
canvas.SetColor(color.Black)
canvas.DrawString("开始时间: "+time.UnixMilli(item.Live.StartDate).Format("2006-01-02 15:04:05"), startWidth, channelStart+fontH*3)
if item.Live.IsFinish {
@@ -411,8 +411,8 @@ func init() {
canvas.DrawString("直播时长: "+strconv.FormatFloat(float64(time.Now().UnixMilli()-item.Live.StartDate)/3600000.0, 'f', 1, 64)+"小时", startWidth, channelStart+fontH*5)
}
canvas.DrawString("弹幕数量: "+strconv.Itoa(int(item.Live.DanmakusCount)), startWidth, channelStart+fontH*6)
canvas.DrawString("观看次数: "+strconv.Itoa(int(item.Live.WatchCount)), startWidth, channelStart+fontH*7)
canvas.DrawString("弹幕数量: "+strconv.Itoa(item.Live.DanmakusCount), startWidth, channelStart+fontH*6)
canvas.DrawString("观看次数: "+strconv.Itoa(item.Live.WatchCount), startWidth, channelStart+fontH*7)
t := "收益:"
l, _ := canvas.MeasureString(t)
@@ -434,7 +434,7 @@ func init() {
canvas.DrawString(t, moveW, danmuNow)
moveW += l + dz
t = danItem.Name
t = danItem.UName
l, _ = canvas.MeasureString(t)
canvas.SetRGB255(24, 144, 255)
canvas.DrawString(t, moveW, danmuNow)

View File

@@ -2,10 +2,15 @@
package bilibili
import (
"encoding/json"
"fmt"
"net/http"
"regexp"
"strings"
"time"
bz "github.com/FloatTech/AnimeAPI/bilibili"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
@@ -13,6 +18,11 @@ import (
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
enableHex = 0x10
unableHex = 0x7fffffff_fffffffd
)
var (
limit = ctxext.NewLimiterManager(time.Second*10, 1)
searchVideo = `bilibili.com\\?/video\\?/(?:av(\d+)|([bB][vV][0-9a-zA-Z]+))`
@@ -32,10 +42,11 @@ func init() {
Brief: "b站链接解析",
Help: "例:- t.bilibili.com/642277677329285174\n- bilibili.com/read/cv17134450\n- bilibili.com/video/BV13B4y1x7pS\n- live.bilibili.com/22603245 ",
})
en.OnRegex(`((b23|acg).tv|bili2233.cn)/[0-9a-zA-Z]+`).SetBlock(true).Limit(limit.LimitByGroup).
en.OnRegex(`((b23|acg).tv|bili2233.cn)\\?/[0-9a-zA-Z]+`).SetBlock(true).Limit(limit.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
url := ctx.State["regex_matched"].([]string)[0]
realurl, err := bz.GetRealURL("https://" + url)
u := ctx.State["regex_matched"].([]string)[0]
u = strings.ReplaceAll(u, "\\", "")
realurl, err := bz.GetRealURL("https://" + u)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -55,6 +66,35 @@ func init() {
handleLive(ctx)
}
})
en.OnRegex(`^(开启|打开|启用|关闭|关掉|禁用)视频总结$`, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
if gid <= 0 {
// 个人用户设为负数
gid = -ctx.Event.UserID
}
option := ctx.State["regex_matched"].([]string)[1]
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
if !ok {
ctx.SendChain(message.Text("找不到服务!"))
return
}
data := c.GetData(ctx.Event.GroupID)
switch option {
case "开启", "打开", "启用":
data |= enableHex
case "关闭", "关掉", "禁用":
data &= unableHex
default:
return
}
err := c.SetData(gid, data)
if err != nil {
ctx.SendChain(message.Text("出错啦: ", err))
return
}
ctx.SendChain(message.Text("已", option, "视频总结"))
})
en.OnRegex(searchVideo).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleVideo)
en.OnRegex(searchDynamic).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleDynamic)
en.OnRegex(searchArticle).SetBlock(true).Limit(limit.LimitByGroup).Handle(handleArticle)
@@ -76,12 +116,15 @@ func handleVideo(ctx *zero.Ctx) {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
summaryMsg, err := getVideoSummary(card)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
if ok && c.GetData(ctx.Event.GroupID)&enableHex == enableHex {
summaryMsg, err := getVideoSummary(cfg, card)
if err != nil {
msg = append(msg, message.Text("ERROR: ", err))
} else {
msg = append(msg, summaryMsg...)
}
}
msg = append(msg, summaryMsg...)
ctx.SendChain(msg...)
}
@@ -111,3 +154,38 @@ func handleLive(ctx *zero.Ctx) {
}
ctx.SendChain(liveCard2msg(card)...)
}
// getVideoSummary AI视频总结
func getVideoSummary(cookiecfg *bz.CookieConfig, card bz.Card) (msg []message.MessageSegment, err error) {
var (
data []byte
videoSummary bz.VideoSummary
)
data, err = web.RequestDataWithHeaders(web.NewDefaultClient(), bz.SignURL(fmt.Sprintf(bz.VideoSummaryURL, card.BvID, card.CID, card.Owner.Mid)), "GET", func(req *http.Request) error {
if cookiecfg != nil {
cookie := ""
cookie, err = cookiecfg.Load()
if err != nil {
return err
}
req.Header.Add("cookie", cookie)
}
req.Header.Set("User-Agent", ua)
return nil
}, nil)
if err != nil {
return
}
err = json.Unmarshal(data, &videoSummary)
msg = make([]message.MessageSegment, 0, 16)
msg = append(msg, message.Text("已为你生成视频总结\n\n"))
msg = append(msg, message.Text(videoSummary.Data.ModelResult.Summary, "\n\n"))
for _, v := range videoSummary.Data.ModelResult.Outline {
msg = append(msg, message.Text("● ", v.Title, "\n"))
for _, p := range v.PartOutline {
msg = append(msg, message.Text(fmt.Sprintf("%d:%d %s\n", p.Timestamp/60, p.Timestamp%60, p.Content)))
}
msg = append(msg, message.Text("\n"))
}
return
}

View File

@@ -75,7 +75,7 @@ func updateVup() error {
if err != nil {
return err
}
gjson.Get(binary.BytesToString(data), "@this").ForEach(func(key, value gjson.Result) bool {
gjson.Get(binary.BytesToString(data), "@this").ForEach(func(_, value gjson.Result) bool {
mid := value.Get("mid").Int()
uname := value.Get("uname").String()
roomid := value.Get("roomid").Int()

View File

@@ -24,7 +24,7 @@ import (
const (
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36"
referer = "https://space.bilibili.com/%v"
infoURL = "https://api.bilibili.com/x/space/wbi/acc/info?mid=%v&token=&platform=web&web_location=1550101"
infoURL = "https://api.bilibili.com/x/space/wbi/acc/info?mid=%v"
)
// bdb bilibili推送数据库
@@ -46,8 +46,9 @@ func init() {
"- 取消b站直播订阅[uid|name]\n" +
"- b站推送列表\n" +
"- [开启|关闭]艾特全体\n" +
"Tips: 需要配合job一起使用, 全局只需要设置一个, 无视响应状态推送, 下为例子\n" +
"记录在\"@every 5m\"触发的指令)\n" +
"Tips: 需要先在 bilibili 插件中设置cookie\n" +
"需要配合 job 插件一起使用, 全局只需要设置一个, 无视响应状态推送, 下为例子\n" +
"记录在\"@every 5m\"触发的指令\n" +
"拉取b站推送",
PrivateDataFolder: "bilibilipush",
})
@@ -76,7 +77,7 @@ func init() {
en.OnRegex(`^添加[B|b]站订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
buid, _ := strconv.ParseInt(ctx.State["uid"].(string), 10, 64)
name, err := getName(buid)
name, err := getName(buid, cfg)
if err != nil || name == "" {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -94,7 +95,7 @@ func init() {
en.OnRegex(`^取消[B|b]站订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
buid, _ := strconv.ParseInt(ctx.State["uid"].(string), 10, 64)
name, err := getName(buid)
name, err := getName(buid, cfg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -111,7 +112,7 @@ func init() {
})
en.OnRegex(`^取消[B|b]站动态订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
buid, _ := strconv.ParseInt(ctx.State["uid"].(string), 10, 64)
name, err := getName(buid)
name, err := getName(buid, cfg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -132,7 +133,7 @@ func init() {
if gid == 0 {
gid = -ctx.Event.UserID
}
name, err := getName(buid)
name, err := getName(buid, cfg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -199,10 +200,18 @@ func changeAtAll(gid int64, b int) (err error) {
}
// 取得uid的名字
func getName(buid int64) (name string, err error) {
func getName(buid int64, cookiecfg *bz.CookieConfig) (name string, err error) {
var ok bool
if name, ok = upMap[buid]; !ok {
data, err := web.RequestDataWithHeaders(web.NewDefaultClient(), bz.SignURL(fmt.Sprintf(infoURL, buid)), "GET", func(r *http.Request) error {
if cookiecfg != nil {
cookie := ""
cookie, err = cookiecfg.Load()
if err != nil {
return err
}
r.Header.Add("Cookie", cookie)
}
r.Header.Set("User-Agent", ua)
return nil
}, nil)
@@ -261,8 +270,19 @@ func unsubscribeLive(buid, groupid int64) (err error) {
return bdb.insertOrUpdateLiveAndDynamic(bpMap)
}
func getUserDynamicCard(buid int64) (cardList []gjson.Result, err error) {
data, err := web.RequestDataWith(web.NewDefaultClient(), fmt.Sprintf(bz.SpaceHistoryURL, buid, 0), "GET", referer, ua, nil)
func getUserDynamicCard(buid int64, cookiecfg *bz.CookieConfig) (cardList []gjson.Result, err error) {
data, err := web.RequestDataWithHeaders(web.NewDefaultClient(), fmt.Sprintf(bz.SpaceHistoryURL, buid, 0), "GET", func(req *http.Request) error {
if cookiecfg != nil {
cookie := ""
cookie, err = cookiecfg.Load()
if err != nil {
return err
}
req.Header.Add("Cookie", cookie)
}
req.Header.Add("User-Agent", ua)
return nil
}, nil)
if err != nil {
return
}
@@ -288,7 +308,7 @@ func sendDynamic(ctx *zero.Ctx) error {
uids := bdb.getAllBuidByDynamic()
for _, buid := range uids {
time.Sleep(2 * time.Second)
cardList, err := getUserDynamicCard(buid)
cardList, err := getUserDynamicCard(buid, cfg)
if err != nil {
return err
}

View File

@@ -2,12 +2,10 @@ package bilibili
import (
"encoding/json"
"fmt"
"time"
bz "github.com/FloatTech/AnimeAPI/bilibili"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/web"
"github.com/wdvxdr1123/ZeroBot/message"
)
@@ -326,27 +324,3 @@ func videoCard2msg(card bz.Card) (msg []message.MessageSegment, err error) {
bz.VURL, card.BvID, "\n\n"))
return
}
// getVideoSummary AI视频总结
func getVideoSummary(card bz.Card) (msg []message.MessageSegment, err error) {
var (
data []byte
videoSummary bz.VideoSummary
)
data, err = web.GetData(bz.SignURL(fmt.Sprintf(bz.VideoSummaryURL, card.BvID, card.CID)))
if err != nil {
return
}
err = json.Unmarshal(data, &videoSummary)
msg = make([]message.MessageSegment, 0, 16)
msg = append(msg, message.Text("已为你生成视频总结\n\n"))
msg = append(msg, message.Text(videoSummary.Data.ModelResult.Summary, "\n\n"))
for _, v := range videoSummary.Data.ModelResult.Outline {
msg = append(msg, message.Text("● ", v.Title, "\n"))
for _, p := range v.PartOutline {
msg = append(msg, message.Text(fmt.Sprintf("%d:%d %s\n", p.Timestamp/60, p.Timestamp%60, p.Content)))
}
msg = append(msg, message.Text("\n"))
}
return
}

View File

@@ -46,14 +46,6 @@ func TestVideoInfo(t *testing.T) {
t.Log(videoCard2msg(card))
}
func TestGetVideoSummary(t *testing.T) {
card, err := bz.GetVideoInfo("BV1mF411j7iU")
if err != nil {
t.Fatal(err)
}
t.Log(getVideoSummary(card))
}
func TestLiveRoomInfo(t *testing.T) {
card, err := bz.GetLiveRoomInfo("83171")
if err != nil {

View File

@@ -1,139 +0,0 @@
// Package cangtoushi 藏头诗
package cangtoushi
import (
"fmt"
"io"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/antchfx/htmlquery"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
)
const (
loginURL = "https://www.shicimingju.com/cangtoushi/"
searchURL = "https://www.shicimingju.com/cangtoushi/index.html"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
referer = "https://www.shicimingju.com/cangtoushi/index.html"
)
var (
gCurCookieJar *cookiejar.Jar
csrf string
)
func init() {
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "藏头诗, 藏尾诗",
Help: "- 藏头诗[xxx]\n- 藏尾诗[xxx]",
})
engine.OnRegex(`藏头诗\s?([一-龥]{3,10})$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
kw := ctx.State["regex_matched"].([]string)[1]
err := login()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
data, err := search(kw, "7", "0")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
text, err := dealHTML(helper.BytesToString(data))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(text))
})
engine.OnRegex(`藏尾诗\s?([一-龥]{3,10})$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
kw := ctx.State["regex_matched"].([]string)[1]
err := login()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
data, err := search(kw, "7", "2")
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
text, err := dealHTML(helper.BytesToString(data))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(text))
})
}
func login() error {
gCurCookieJar, _ = cookiejar.New(nil)
client := &http.Client{
Jar: gCurCookieJar,
}
request, err := http.NewRequest("GET", loginURL, nil)
if err != nil {
return err
}
request.Header.Add("User-Agent", ua)
response, err := client.Do(request)
if err != nil {
return err
}
data, err := io.ReadAll(response.Body)
if err != nil {
return err
}
response.Body.Close()
doc, err := htmlquery.Parse(strings.NewReader(helper.BytesToString(data)))
if err != nil {
return err
}
csrf = htmlquery.SelectAttr(htmlquery.FindOne(doc, "//input[@name='_csrf']"), "value")
return nil
}
func search(kw, zishu, position string) (data []byte, err error) {
postStr := fmt.Sprintf("_csrf=%s&kw=%s&zishu=%s&position=%s", url.QueryEscape(csrf), url.QueryEscape(kw), zishu, position)
client := &http.Client{
Jar: gCurCookieJar,
}
request, err := http.NewRequest("POST", searchURL, strings.NewReader(postStr))
if err != nil {
return nil, err
}
request.Header.Add("Referer", referer)
request.Header.Add("User-Agent", ua)
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
response, err := client.Do(request)
if err != nil {
return nil, err
}
data, err = io.ReadAll(response.Body)
if err != nil {
return nil, err
}
response.Body.Close()
return
}
func dealHTML(data string) (text string, err error) {
doc, err := htmlquery.Parse(strings.NewReader(data))
if err != nil {
return "", err
}
text = htmlquery.InnerText(htmlquery.FindOne(doc, "//div[@class='card']/div[@class='card']"))
text = strings.ReplaceAll(text, " ", "")
text = strings.Replace(text, "\n", "", 1)
return text, nil
}

View File

@@ -0,0 +1,64 @@
// Package chatcount 聊天时长统计
package chatcount
import (
"fmt"
"strconv"
"strings"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
)
const (
rankSize = 10
)
func init() {
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "聊天时长统计",
Help: "- 查询水群@xxx\n- 查看水群排名",
PrivateDataFolder: "chatcount",
})
go func() {
ctdb = initialize(engine.DataFolder() + "chatcount.db")
}()
engine.OnMessage(zero.OnlyGroup).SetBlock(false).
Handle(func(ctx *zero.Ctx) {
remindTime, remindFlag := ctdb.updateChatTime(ctx.Event.GroupID, ctx.Event.UserID)
if remindFlag {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text(fmt.Sprintf("BOT提醒你今天已经水群%d分钟了", remindTime)))
}
})
engine.OnPrefix(`查询水群`, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
name := ctx.NickName()
todayTime, todayMessage, totalTime, totalMessage := ctdb.getChatTime(ctx.Event.GroupID, ctx.Event.UserID)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(fmt.Sprintf("%s今天水了%d分%d秒发了%d条消息总计水了%d分%d秒发了%d条消息。", name, todayTime/60, todayTime%60, todayMessage, totalTime/60, totalTime%60, totalMessage)))
})
engine.OnFullMatch("查看水群排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
text := strings.Builder{}
text.WriteString("今日水群排行榜:\n")
chatTimeList := ctdb.getChatRank(ctx.Event.GroupID)
for i := 0; i < len(chatTimeList) && i < rankSize; i++ {
text.WriteString("第")
text.WriteString(strconv.Itoa(i + 1))
text.WriteString("名:")
text.WriteString(ctx.CardOrNickName(chatTimeList[i].UserID))
text.WriteString(" - ")
text.WriteString(strconv.FormatInt(chatTimeList[i].TodayMessage, 10))
text.WriteString("条,共")
text.WriteString(strconv.FormatInt(chatTimeList[i].TodayTime/60, 10))
text.WriteString("分")
text.WriteString(strconv.FormatInt(chatTimeList[i].TodayTime%60, 10))
text.WriteString("秒\n")
}
ctx.SendChain(message.Text(text.String()))
})
}

225
plugin/chatcount/model.go Normal file
View File

@@ -0,0 +1,225 @@
package chatcount
import (
"fmt"
"os"
"sort"
"strconv"
"strings"
"sync"
"time"
"github.com/RomiChan/syncx"
"github.com/jinzhu/gorm"
)
const (
chatInterval = 300
)
var (
// ctdb 聊天时长数据库全局变量
ctdb *chattimedb
// l 水群提醒时间提醒段,单位分钟
l = newLeveler(60, 120, 180, 240, 300)
)
// chattimedb 聊天时长数据库结构体
type chattimedb struct {
// ctdb.userTimestampMap 每个人发言的时间戳 key=groupID_userID
userTimestampMap syncx.Map[string, int64]
// ctdb.userTodayTimeMap 每个人今日水群时间 key=groupID_userID
userTodayTimeMap syncx.Map[string, int64]
// ctdb.userTodayMessageMap 每个人今日水群次数 key=groupID_userID
userTodayMessageMap syncx.Map[string, int64]
// db 数据库
db *gorm.DB
// chatmu 读写添加锁
chatmu sync.Mutex
}
// initialize 初始化
func initialize(dbpath string) *chattimedb {
var err error
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
// 生成文件
f, err := os.Create(dbpath)
if err != nil {
return nil
}
defer f.Close()
}
gdb, err := gorm.Open("sqlite3", dbpath)
if err != nil {
panic(err)
}
gdb.AutoMigrate(&chatTime{})
return &chattimedb{
db: gdb,
}
}
// Close 关闭
func (ctdb *chattimedb) Close() error {
db := ctdb.db
return db.Close()
}
// chatTime 聊天时长,时间的单位都是秒
type chatTime struct {
ID uint `gorm:"primary_key"`
GroupID int64 `gorm:"column:group_id"`
UserID int64 `gorm:"column:user_id"`
TodayTime int64 `gorm:"-"`
TodayMessage int64 `gorm:"-"`
TotalTime int64 `gorm:"column:total_time;default:0"`
TotalMessage int64 `gorm:"column:total_message;default:0"`
}
// TableName 表名
func (chatTime) TableName() string {
return "chat_time"
}
// updateChatTime 更新发言时间,todayTime的单位是分钟
func (ctdb *chattimedb) updateChatTime(gid, uid int64) (remindTime int64, remindFlag bool) {
ctdb.chatmu.Lock()
defer ctdb.chatmu.Unlock()
db := ctdb.db
now := time.Now()
keyword := fmt.Sprintf("%v_%v", gid, uid)
ts, ok := ctdb.userTimestampMap.Load(keyword)
if !ok {
ctdb.userTimestampMap.Store(keyword, now.Unix())
ctdb.userTodayMessageMap.Store(keyword, 1)
return
}
lastTime := time.Unix(ts, 0)
todayTime, _ := ctdb.userTodayTimeMap.Load(keyword)
totayMessage, _ := ctdb.userTodayMessageMap.Load(keyword)
// 这个消息数是必须统计的
ctdb.userTodayMessageMap.Store(keyword, totayMessage+1)
st := chatTime{
GroupID: gid,
UserID: uid,
TotalTime: todayTime,
TotalMessage: totayMessage,
}
// 如果不是同一天把TotalTime,TotalMessage重置
if lastTime.YearDay() != now.YearDay() {
if err := db.Model(&st).Where("group_id = ? and user_id = ?", gid, uid).First(&st).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
db.Model(&st).Create(&st)
}
} else {
db.Model(&st).Where("group_id = ? and user_id = ?", gid, uid).Update(
map[string]any{
"total_time": st.TotalTime + todayTime,
"total_message": st.TotalMessage + totayMessage,
})
}
ctdb.userTimestampMap.Store(keyword, now.Unix())
ctdb.userTodayTimeMap.Delete(keyword)
ctdb.userTodayMessageMap.Delete(keyword)
return
}
userChatTime := int64(now.Sub(lastTime).Seconds())
// 当聊天时间在一定范围内的话,则计入时长
if userChatTime < chatInterval {
ctdb.userTodayTimeMap.Store(keyword, todayTime+userChatTime)
remindTime = (todayTime + userChatTime) / 60
remindFlag = l.level(int((todayTime+userChatTime)/60)) > l.level(int(todayTime/60))
}
ctdb.userTimestampMap.Store(keyword, now.Unix())
return
}
// getChatTime 获得用户聊天时长和消息次数,todayTime,totalTime的单位是秒,todayMessage,totalMessage单位是条数
func (ctdb *chattimedb) getChatTime(gid, uid int64) (todayTime, todayMessage, totalTime, totalMessage int64) {
ctdb.chatmu.Lock()
defer ctdb.chatmu.Unlock()
db := ctdb.db
st := chatTime{}
db.Model(&st).Where("group_id = ? and user_id = ?", gid, uid).First(&st)
keyword := fmt.Sprintf("%v_%v", gid, uid)
todayTime, _ = ctdb.userTodayTimeMap.Load(keyword)
todayMessage, _ = ctdb.userTodayMessageMap.Load(keyword)
totalTime = st.TotalTime
totalMessage = st.TotalMessage
return
}
// getChatRank 获得水群排名,时间单位为秒
func (ctdb *chattimedb) getChatRank(gid int64) (chatTimeList []chatTime) {
ctdb.chatmu.Lock()
defer ctdb.chatmu.Unlock()
chatTimeList = make([]chatTime, 0, 100)
keyList := make([]string, 0, 100)
ctdb.userTimestampMap.Range(func(key string, value int64) bool {
t := time.Unix(value, 0)
if strings.Contains(key, strconv.FormatInt(gid, 10)) && t.YearDay() == time.Now().YearDay() {
keyList = append(keyList, key)
}
return true
})
for _, v := range keyList {
_, a, _ := strings.Cut(v, "_")
uid, _ := strconv.ParseInt(a, 10, 64)
todayTime, _ := ctdb.userTodayTimeMap.Load(v)
todayMessage, _ := ctdb.userTodayMessageMap.Load(v)
chatTimeList = append(chatTimeList, chatTime{
GroupID: gid,
UserID: uid,
TodayTime: todayTime,
TodayMessage: todayMessage,
})
}
sort.Sort(sortChatTime(chatTimeList))
return
}
// leveler 结构体,包含一个 levelArray 字段
type leveler struct {
levelArray []int
}
// newLeveler 构造函数,用于创建 Leveler 实例
func newLeveler(levels ...int) *leveler {
return &leveler{
levelArray: levels,
}
}
// level 方法,封装了 getLevel 函数的逻辑
func (l *leveler) level(t int) int {
for i := len(l.levelArray) - 1; i >= 0; i-- {
if t >= l.levelArray[i] {
return i + 1
}
}
return 0
}
// sortChatTime chatTime排序数组
type sortChatTime []chatTime
// Len 实现 sort.Interface
func (a sortChatTime) Len() int {
return len(a)
}
// Less 实现 sort.Interface按 TodayTime 降序TodayMessage 降序
func (a sortChatTime) Less(i, j int) bool {
if a[i].TodayTime == a[j].TodayTime {
return a[i].TodayMessage > a[j].TodayMessage
}
return a[i].TodayTime > a[j].TodayTime
}
// Swap 实现 sort.Interface
func (a sortChatTime) Swap(i, j int) {
a[i], a[j] = a[j], a[i]
}

View File

@@ -168,7 +168,7 @@ func resign(groupCode, senderUin int64) (msg message.Message, err error) {
}
// play 走棋
func play(senderUin int64, groupCode int64, moveStr string) (msg message.Message, err error) {
func play(groupCode, senderUin int64, moveStr string) (msg message.Message, err error) {
msg = message.Message{message.At(senderUin)}
// 检查对局是否存在
room, ok := chessRoomMap.Load(groupCode)
@@ -343,7 +343,7 @@ func cleanUserRate(senderUin int64) (msg message.Message, err error) {
}
// createGame 创建游戏
func createGame(isBlindfold bool, groupCode int64, senderUin int64, senderName string) (msg message.Message, err error) {
func createGame(isBlindfold bool, groupCode, senderUin int64, senderName string) (msg message.Message, err error) {
room, ok := chessRoomMap.Load(groupCode)
if !ok {
chessRoomMap.Store(groupCode, &chessRoom{

View File

@@ -23,7 +23,7 @@ import (
var (
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36"
coserURL = "http://ovooa.com/API/cosplay/api.php"
coserURL = "https://picture.yinux.workers.dev"
)
func init() {

View File

@@ -24,14 +24,11 @@ func init() {
engine.OnFullMatch(`今日早报`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(api)
if err != nil {
return
}
picURL := gjson.Get(binary.BytesToString(data), "imageUrl").String()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
picURL := gjson.Get(binary.BytesToString(data), "imageUrl").String()
ctx.SendChain(message.Image(picURL))
})
}

View File

@@ -3,6 +3,7 @@ package deepdanbooru
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"image"
"net/url"
@@ -59,8 +60,12 @@ func tagurl(name, u string) (im image.Image, st *sorttags, err error) {
if err != nil {
return
}
if len(data) < 4 {
err = errors.New("data too short")
return
}
tags := make(map[string]float64)
err = json.Unmarshal(data, &tags)
err = json.Unmarshal(data[1:len(data)-1], &tags)
if err != nil {
return
}

View File

@@ -77,7 +77,8 @@ func init() {
}
var d dish
if err := db.Find("dish", &d, fmt.Sprintf("WHERE name like %%%s%%", dishName)); err != nil {
if err := db.Find("dish", &d, fmt.Sprintf("WHERE name like '%%%s%%'", dishName)); err != nil {
ctx.SendChain(message.Text("客官,本店没有" + dishName))
return
}
@@ -86,17 +87,17 @@ func init() {
"原材料:%s\n"+
"步骤:\n"+
"%s",
name, dishName, d.Materials, d.Steps),
name, d.Name, d.Materials, d.Steps),
))
})
en.OnPrefixGroup([]string{"随机菜谱", "随便做点菜"}).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
en.OnFullMatchGroup([]string{"随机菜谱", "随便做点菜"}).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
if !initialized {
ctx.SendChain(message.Text("客官,本店暂未开业"))
return
}
name := ctx.NickName()
name := ctx.CardOrNickName(ctx.Event.UserID)
var d dish
if err := db.Pick("dish", &d); err != nil {
ctx.SendChain(message.Text("小店好像出错了,暂时端不出菜来惹"))

View File

@@ -5,13 +5,15 @@ import (
"bytes"
"errors"
"image"
"image/color"
"image/draw"
"image/gif"
"io"
"math/rand"
"os"
"strconv"
"strings"
fcext "github.com/FloatTech/floatbox/ctxext"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
"github.com/FloatTech/imgfactory"
@@ -89,7 +91,7 @@ func init() {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("file:///"+picPath))
return
}
lotsImg, err := randGif(lotsType + "." + fileInfo.lotsType)
lotsImg, err := randGif(lotsType+"."+fileInfo.lotsType, ctx.Event.UserID)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
@@ -228,27 +230,48 @@ func randFile(path string, indexMax int) (string, error) {
return "", errors.New("图包[" + path + "]不存在签内容!")
}
func randGif(gifName string) (image.Image, error) {
func randGif(gifName string, uid int64) (image.Image, error) {
name := datapath + gifName
file, err := os.Open(name)
if err != nil {
return nil, err
}
im, err := gif.DecodeAll(file)
_ = file.Close()
if err != nil {
return nil, err
}
/*
firstImg, err := imgfactory.Load(name)
if err != nil {
return nil, err
_, err = file.Seek(0, io.SeekStart)
if err != nil {
return nil, err
}
config, err := gif.DecodeConfig(file)
if err != nil {
return nil, err
}
_ = file.Close()
// https://zhuanlan.zhihu.com/p/27718135
rect := image.Rect(0, 0, config.Width, config.Height)
if rect.Min == rect.Max {
var maxP image.Point
for _, frame := range im.Image {
maxF := frame.Bounds().Max
if maxP.X < maxF.X {
maxP.X = maxF.X
}
if maxP.Y < maxF.Y {
maxP.Y = maxF.Y
}
}
v := im.Image[rand.Intn(len(im.Image))]
return imgfactory.Size(firstImg, firstImg.Bounds().Dx(), firstImg.Bounds().Dy()).InsertUpC(v, 0, 0, firstImg.Bounds().Dx()/2, firstImg.Bounds().Dy()/2).Clone().Image(),err
/*/
// 如果gif图片出现信息缺失请使用上面注释掉的代码把下面注释了(上面代码部分图存在bug)
v := im.Image[rand.Intn(len(im.Image))]
return imgfactory.NewFactoryBG(v.Rect.Dx(), v.Rect.Dy(), color.NRGBA{0, 0, 0, 255}).InsertUp(v, 0, 0, 0, 0).Clone().Image(), err
// */
rect.Max = maxP
}
img := image.NewRGBA(rect)
b := fcext.RandSenderPerDayN(uid, len(im.Image)) + 1
a := 0
if b > 8 {
a = b - 8
}
for _, srcimg := range im.Image[a:b] {
draw.Draw(img, srcimg.Bounds(), srcimg, srcimg.Rect.Min, draw.Over)
}
return img, err
}

View File

@@ -1,39 +0,0 @@
package dress
import (
"fmt"
"github.com/FloatTech/floatbox/web"
"github.com/tidwall/gjson"
)
const (
dressURL = "http://www.yoooooooooo.com/gitdress"
male = "dress"
female = "girldress"
dressListURL = dressURL + "/%v/album/list.json"
dressDetailURL = dressURL + "/%v/album/%v/info.json"
dressImageURL = dressURL + "/%v/album/%v/%v-m.webp"
)
func dressList(sex string) (dressList []string, err error) {
data, err := web.GetData(fmt.Sprintf(dressListURL, sex))
if err != nil {
return
}
arr := gjson.ParseBytes(data).Get("@this").Array()
dressList = make([]string, len(arr))
for i, v := range arr {
dressList[i] = v.String()
}
return
}
func detail(sex, name string) (count int, err error) {
data, err := web.GetData(fmt.Sprintf(dressDetailURL, sex, name))
if err != nil {
return
}
count = int(gjson.ParseBytes(data).Get("@this.#").Int())
return
}

View File

@@ -1,113 +0,0 @@
// Package dress 女装
package dress
import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
"github.com/FloatTech/floatbox/binary"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/img/text"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
func init() { // 插件主体
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "女装",
Help: "女装\n" +
"- 女装\n" +
"- 男装\n" +
"- 随机女装\n" +
"- 随机男装",
PrivateDataFolder: "dress",
})
engine.OnFullMatchGroup([]string{"女装", "男装"}).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
matched := ctx.State["matched"].(string)
sex := male
if matched == "男装" {
sex = female
}
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession())
recv, cancel := next.Repeat()
defer cancel()
nameList, err := dressList(sex)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
tex := "请输入" + matched + "序号\n"
for i, v := range nameList {
tex += fmt.Sprintf("%d. %s\n", i, v)
}
base64Str, err := text.RenderToBase64(tex, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Image("base64://" + binary.BytesToString(base64Str)))
for {
select {
case <-time.After(time.Second * 120):
ctx.SendChain(message.Text(matched, "指令过期"))
return
case c := <-recv:
msg := c.Event.Message.ExtractPlainText()
num, err := strconv.Atoi(msg)
if err != nil {
ctx.SendChain(message.Text("请输入数字!"))
continue
}
if num < 0 || num >= len(nameList) {
ctx.SendChain(message.Text("序号非法!"))
continue
}
name := nameList[num]
sendImage(ctx, sex, matched, name)
return
}
}
})
engine.OnFullMatchGroup([]string{"随机女装", "随机男装"}).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
matched := strings.TrimPrefix(ctx.State["matched"].(string), "随机")
sex := male
if matched == "男装" {
sex = female
}
nameList, err := dressList(sex)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
name := nameList[rand.Intn(len(nameList))]
sendImage(ctx, sex, matched, name)
})
}
func sendImage(ctx *zero.Ctx, sex, matched, name string) {
ctx.SendChain(message.Text("请欣赏", matched, ": ", name))
count, err := detail(sex, name)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
imageList := make([]string, count)
for i := range imageList {
imageList[i] = fmt.Sprintf(dressImageURL, sex, name, i+1)
}
m := message.Message{}
for _, v := range imageList {
m = append(m, ctxext.FakeSenderForwardNode(ctx, message.Image(v)))
}
if id := ctx.Send(m).ID(); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控或下载图片用时过长,请耐心等待"))
}
}

View File

@@ -195,55 +195,3 @@ var emojis = map[rune]int64{
127819: 20210521, // 🍋 lemon
127818: 20211115, // 🍊 tangerine orange
}
var qqface = map[int]rune{
0: 128558, // 😮 face exhaling
1: 128556, // 😬 grimacing face
2: 128525, // 😍 smiling face with heart-eyes
4: 128526, // 😎 smiling face with sunglasses
5: 128557, // 😭 loudly crying face
6: 129402, // 🥺 pleading face
7: 129296, // 🤐 zipper-mouth face
8: 128554, // 😪 sleepy face
11: 128545, // 😡 pouting face
12: 128539, // 😛 face with tongue
13: 128513, // 😁 beaming face with smiling eyes
14: 128578, // 🙂 slightly smiling face
15: 128577, // 🙁 slightly frowning face
16: 128526, // 😎 smiling face with sunglasses
19: 129326, // 🤮 face vomiting throw
20: 129325, // 🤭 face with hand over mouth embarrassed
21: 128522, // 😊 smiling face with smiling eyes
23: 128533, // 😕 confused face
24: 128523, // 😋 face savoring food
27: 128531, // 😓 downcast face with sweat
28: 128516, // 😄 grinning face with smiling eyes
31: 129324, // 🤬 face with symbols on mouth
32: 129300, // 🤔 thinking face question hmmm
33: 129323, // 🤫 shushing face quiet whisper
34: 128565, // 😵 face with crossed-out eyes
35: 128547, // 😣 persevering face
37: 128128, // 💀 skull
46: 128055, // 🐷 pig face
53: 127874, // 🎂 birthday cake
59: 128169, // 💩 pile of poo
60: 9749, // ☕ hot beverage coffee cup tea
63: 127801, // 🌹 rose flower
66: 10084, // ❤ mending heart
67: 128148, // 💔 broken heart
69: 127873, // 🎁 wrapped-gift
74: 127774, // 🌞 sun with face
75: 127772, // 🌜 last quarter moon face
96: 128517, // 😅 grinning face with sweat
104: 129393, // 🥱 yawning face
109: 128535, // 😗 kissing face
110: 128562, // 😲 astonished face
111: 129402, // 🥺 pleading face
172: 128539, // 😛 face with tongue
182: 128514, // 😂 face with tears of joy
187: 128123, // 👻 ghost
247: 128567, // 😷 face with medical mask
272: 128579, // 🙃 upside-down face
320: 129395, // 🥳 partying face
325: 128561, // 😱 face screaming in fear
}

View File

@@ -94,7 +94,7 @@ func face2emoji(face message.MessageSegment) rune {
if err != nil {
return 0
}
if r, ok := qqface[id]; ok {
if r, ok := message.Emoji[id]; ok {
return r
}
return 0

View File

@@ -87,13 +87,13 @@ func dlrange(prefix string, end int, wg *sync.WaitGroup, exit func(error)) []str
}
// 新的上下文
func newContext(user int64) *context {
func newContext(user int64, atUser int64) *context {
c := new(context)
c.usrdir = datapath + "users/" + strconv.FormatInt(user, 10) + `/`
c.usrdir = datapath + "users/" + strconv.FormatInt(atUser, 10) + `/`
_ = os.MkdirAll(c.usrdir, 0755)
c.headimgsdir = make([]string, 2)
c.headimgsdir[0] = c.usrdir + "0.gif"
c.headimgsdir[1] = c.usrdir + "1.gif"
c.headimgsdir[0] = datapath + "users/" + strconv.FormatInt(atUser, 10) + ".gif"
c.headimgsdir[1] = datapath + "users/" + strconv.FormatInt(user, 10) + ".gif"
return c
}

View File

@@ -14,9 +14,9 @@ func (cc *context) prepareLogos(s ...string) error {
for i, v := range s {
_, err := strconv.Atoi(v)
if err != nil {
err = file.DownloadTo("https://gchat.qpic.cn/gchatpic_new//--"+strings.ToUpper(v)+"/0", cc.usrdir+strconv.Itoa(i)+".gif")
err = file.DownloadTo("https://gchat.qpic.cn/gchatpic_new//--"+strings.ToUpper(v)+"/0", cc.headimgsdir[i])
} else {
err = file.DownloadTo("http://q4.qlogo.cn/g?b=qq&nk="+v+"&s=640", cc.usrdir+strconv.Itoa(i)+".gif")
err = file.DownloadTo("https://q4.qlogo.cn/g?b=qq&nk="+v+"&s=640", cc.headimgsdir[i])
}
if err != nil {
return err

View File

@@ -150,10 +150,11 @@ func init() { // 插件主体
PrivateDataFolder: "gif",
}).ApplySingle(ctxext.DefaultSingle)
datapath = file.BOTPATH + "/" + en.DataFolder()
en.OnRegex(`^(` + strings.Join(cmd, "|") + `)[\s\S]*?(\[CQ:(image\,file=([0-9a-zA-Z]{32}).*|at.+?(\d{5,11}))\].*|(\d+))$`).
en.OnRegex(`^(` + strings.Join(cmd, "|") + `)[\s\S]*?(\[CQ:(image\,file=([0-9a-zA-Z]{32}).*|at.+?qq=(\d{5,11})).*\].*|(\d+))$`).
SetBlock(true).Handle(func(ctx *zero.Ctx) {
c := newContext(ctx.Event.UserID)
list := ctx.State["regex_matched"].([]string)
atUserID, _ := strconv.ParseInt(list[4]+list[5]+list[6], 10, 64)
c := newContext(ctx.Event.UserID, atUserID)
err := c.prepareLogos(list[4]+list[5]+list[6], strconv.FormatInt(ctx.Event.UserID, 10))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))

View File

@@ -2,15 +2,14 @@
package github
import (
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/fumiama/terasu/http2"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
@@ -26,14 +25,14 @@ func init() { // 插件主体
}).OnRegex(`^>github\s(-.{1,10}? )?(.*)$`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
// 发送请求
header := http.Header{
"User-Agent": []string{"User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36"},
}
api, _ := url.Parse("https://api.github.com/search/repositories")
api.RawQuery = url.Values{
"q": []string{ctx.State["regex_matched"].([]string)[2]},
}.Encode()
body, err := netGet(api.String(), header)
body, err := web.RequestDataWithHeaders(&http2.DefaultClient, api.String(), "GET", func(r *http.Request) error {
r.Header.Set("User-Agent", web.RandUA())
return nil
}, nil)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
}
@@ -96,36 +95,9 @@ func init() { // 插件主体
}
// notnull 如果传入文本为空,则返回默认值
func notnull(text string) string {
if text == "" {
return "None"
}
return text
}
// netGet 返回请求结果
func netGet(dest string, header http.Header) ([]byte, error) {
client := &http.Client{}
req, err := http.NewRequest("GET", dest, nil)
if err != nil {
return nil, err
}
req.Header = header
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if code := resp.StatusCode; code != 200 {
// 如果返回不是200则立刻抛出错误
errmsg := fmt.Sprintf("code %d", code)
return nil, errors.New(errmsg)
}
return body, nil
}

View File

@@ -11,16 +11,28 @@ import (
"sync"
"time"
log "github.com/sirupsen/logrus"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/zbputils/ctxext"
"github.com/pkg/errors"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/liuzl/gocc"
)
var cuttime = [...]string{"00:00:05", "00:00:30", "00:01:00"} // 音乐切割时间点,可自行调节时间(时:分:秒)
var t2s *gocc.OpenCC
func init() {
// 初始化简繁体转换变量
var err1 error
t2s, err1 = gocc.New("t2s")
if err1 != nil {
log.Infof("[guessmusic]:%s", err1)
}
engine.OnRegex(`^(个人|团队)猜歌(-(.*))?$`, zero.OnlyGroup).SetBlock(true).Limit(ctxext.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
mode := ctx.State["regex_matched"].([]string)[3]
@@ -97,6 +109,12 @@ func init() {
ctx.SendChain(message.Text(err))
return
}
// 猜歌环节-提供猜歌选项
files, err := os.ReadDir(pathOfMusic)
if err != nil {
return
}
getMusicSelect(ctx, files, musicName)
// 进行猜歌环节
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + "0.wav"))
var next *zero.FutureEvent
@@ -209,26 +227,8 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
}
return
}
// 进行随机抽取
if playlistID == 0 || !cfg.API {
musicName = getLocalMusic(files, 10)
} else {
switch rand.Intn(3) { // 三分二概率抽取API的
case 1:
musicName = getLocalMusic(files, 10)
default:
if cfg.APIURL == "" {
// 如果没有配置过API地址,尝试连接独角兽
musicName, err = downloadByOvooa(playlistID, pathOfMusic)
} else {
// 从API中抽取歌曲
musicName, err = drawByAPI(playlistID, pathOfMusic)
}
if err != nil {
musicName = getLocalMusic(files, 10)
}
}
}
// 只猜本地已经下好的歌曲
musicName = getLocalMusic(files, 10)
if musicName == "" {
err = errors.New("抽取歌曲轮空了,请重试")
}
@@ -283,10 +283,13 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
// 数据匹配(结果信息,答题次数,提示次数,是否结束游戏)
func gameMatch(c *zero.Ctx, beginner int64, musicInfo []string, answerTimes, tickTimes int) (message.MessageSegment, int, int, bool) {
answer := strings.Replace(c.Event.Message.String(), "-", "", 1)
// 回答内容转小写,比对时再把标准答案转小写
answer = ConvertText(answer)
switch {
case answer == "取消":
if c.Event.UserID == beginner {
return message.Text("游戏已取消,猜歌答案是\n", musicInfo[len(musicInfo)-1], "\n\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
return message.Text("游戏已取消,猜歌答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
}
return message.Text("你无权限取消"), answerTimes, tickTimes, false
case answer == "提示":
@@ -295,11 +298,11 @@ func gameMatch(c *zero.Ctx, beginner int64, musicInfo []string, answerTimes, tic
return message.Text("已经没有提示了哦"), answerTimes, tickTimes, false
}
return message.Text("再听这段音频,要仔细听哦"), answerTimes, tickTimes, false
case strings.Contains(musicInfo[0], answer) || strings.EqualFold(musicInfo[0], answer):
case strings.Contains(ConvertText(musicInfo[0]), answer) || strings.EqualFold(ConvertText(musicInfo[0]), answer):
return message.Text("太棒了,你猜对歌曲名了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
case strings.Contains(musicInfo[1], answer) || strings.EqualFold(musicInfo[1], answer):
case strings.Contains(ConvertText(musicInfo[1]), answer) || strings.EqualFold(ConvertText(musicInfo[1]), answer):
return message.Text("太棒了,你猜对歌手名了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
case len(musicInfo) == 4 && (strings.Contains(musicInfo[2], answer) || strings.EqualFold(musicInfo[2], answer)):
case len(musicInfo) == 4 && (strings.Contains(ConvertText(musicInfo[2]), answer) || strings.EqualFold(ConvertText(musicInfo[2]), answer)):
return message.Text("太棒了,你猜对相关信息了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
default:
answerTimes++
@@ -314,3 +317,51 @@ func gameMatch(c *zero.Ctx, beginner int64, musicInfo []string, answerTimes, tic
}
}
}
// ConvertText 将传入字符串中的英文转为小写,繁体中文转为简体中文
func ConvertText(input string) string {
// 将字符串中的英文转为小写
toLower := strings.ToLower(input)
toLower, err := t2s.Convert(toLower)
if err != nil {
message.Text("简繁转换失败")
return toLower
}
return toLower
}
func getMusicSelect(ctx *zero.Ctx, files []fs.DirEntry, musicName string) {
// 生成音乐选项
var musicInfo []string
musicInfo = append(musicInfo, musicName)
for i := 1; i < 4; i++ {
musicInfo = append(musicInfo, getLocalMusic(files, 10))
for musicInfo[0] == musicInfo[i] {
musicInfo[i] = getLocalMusic(files, 10)
}
}
// 对调正确答案
j := rand.Intn(len(musicInfo))
musicInfo[0], musicInfo[j] = musicInfo[j], musicInfo[0]
musicNameSelect := "请选出正确歌曲:\n"
for i := 0; i < len(musicInfo); i++ {
// 解析歌曲信息
music := strings.Split(musicInfo[i], ".")
// 获取音乐后缀
musicType := music[len(music)-1]
if !strings.Contains(musictypelist, musicType) {
ctx.SendChain(message.Text("抽取到了歌曲:\n",
musicInfo[i], "\n该歌曲不是音乐后缀,请联系bot主人修改"))
}
// 获取音乐信息
musicInfo := strings.Split(strings.ReplaceAll(musicInfo[i], "."+musicType, ""), " - ")
infoNum := len(musicInfo)
if infoNum == 1 {
ctx.SendChain(message.Text("抽取到了歌曲:\n",
musicInfo[i], "\n该歌曲命名不符合命名规则,请联系bot主人修改"))
}
musicNameSelect += musicInfo[0] + " 歌手:" + musicInfo[1] + "\n"
}
ctx.SendChain(message.Text(musicNameSelect))
}

View File

@@ -32,7 +32,7 @@ var (
cfg config
// 插件主体
engine = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
DisableOnDefault: true,
Brief: "猜歌插件",
Help: "------bot主人指令------\n" +
"- 设置猜歌歌库路径 [绝对路径]\n" +

View File

@@ -241,9 +241,9 @@ type listInfoOfAPI struct {
PublishTime int64 `json:"publishTime"`
Tns []string `json:"tns,omitempty"`
} `json:"tracks"`
VideoIds interface{} `json:"videoIds"`
VideoIDs interface{} `json:"videoIds"`
Videos interface{} `json:"videos"`
TrackIds []struct {
TrackIDs []struct {
ID int `json:"id"`
V int `json:"v"`
T int `json:"t"`

View File

@@ -1,119 +0,0 @@
// Package heisi 黑丝
package heisi
import (
"errors"
"math/rand"
"os"
"strconv"
"time"
"unsafe"
"github.com/FloatTech/AnimeAPI/setu"
fbctxext "github.com/FloatTech/floatbox/ctxext"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
var (
heisiPic []item
baisiPic []item
jkPic []item
jurPic []item
zukPic []item
mcnPic []item
fileList = [...]string{"heisi.bin", "baisi.bin", "jk.bin", "jur.bin", "zuk.bin", "mcn.bin"}
)
func init() { // 插件主体
p, err := setu.NewPool(setu.DefaultPoolDir,
func(s string) (string, error) {
if s != "黑丝" && s != "白丝" && s != "jk" && s != "巨乳" && s != "足控" && s != "网红" {
return "", errors.New("invalid call")
}
typ := setu.DefaultPoolDir + "/" + s
if file.IsNotExist(typ) {
err := os.MkdirAll(typ, 0755)
if err != nil {
return "", err
}
}
var pic item
switch s {
case "黑丝":
pic = heisiPic[rand.Intn(len(heisiPic))]
case "白丝":
pic = baisiPic[rand.Intn(len(baisiPic))]
case "jk":
pic = jkPic[rand.Intn(len(jkPic))]
case "巨乳":
pic = jurPic[rand.Intn(len(jurPic))]
case "足控":
pic = zukPic[rand.Intn(len(zukPic))]
case "网红":
pic = mcnPic[rand.Intn(len(mcnPic))]
}
return pic.String(), nil
}, func(s string) ([]byte, error) {
return web.RequestDataWith(web.NewTLS12Client(), s, "GET", "http://hs.heisiwu.com/", web.RandUA(), nil)
}, time.Minute)
if err != nil {
panic(err)
}
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "黑丝",
Help: "- 来点黑丝\n- 来点白丝\n- 来点jk\n- 来点巨乳\n- 来点足控\n- 来点网红",
PublicDataFolder: "Heisi",
})
engine.OnFullMatchGroup([]string{"来点黑丝", "来点白丝", "来点jk", "来点巨乳", "来点足控", "来点网红"}, zero.OnlyGroup, fbctxext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
for i, filePath := range fileList {
data, err := engine.GetLazyData(filePath, true)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
if len(data)%10 != 0 {
ctx.SendChain(message.Text("ERROR: invalid data " + strconv.Itoa(i)))
return false
}
s := (*slice)(unsafe.Pointer(&data))
s.len /= 10
s.cap /= 10
switch i {
case 0:
heisiPic = *(*[]item)(unsafe.Pointer(s))
case 1:
baisiPic = *(*[]item)(unsafe.Pointer(s))
case 2:
jkPic = *(*[]item)(unsafe.Pointer(s))
case 3:
jurPic = *(*[]item)(unsafe.Pointer(s))
case 4:
zukPic = *(*[]item)(unsafe.Pointer(s))
case 5:
mcnPic = *(*[]item)(unsafe.Pointer(s))
}
}
return true
})).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
matched := ctx.State["matched"].(string)
pic, err := p.Roll(matched[3*2:])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
m := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Image("file:///"+file.BOTPATH+"/"+pic))}
if id := ctx.Send(m).ID(); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控或下载图片用时过长,请耐心等待"))
}
})
}

View File

@@ -1,48 +0,0 @@
package heisi
import (
"encoding/binary"
"encoding/hex"
"fmt"
"math/bits"
)
const (
template2021 = "http://hs.heisiwu.com/wp-content/uploads/%4d/%02d/%4d%02d16%06d-611a3%8s.jpg"
templategeneral = "http://hs.heisiwu.com/wp-content/uploads/%4d/%02d/%015x"
)
type item [10]byte
// String item to url
func (it item) String() string {
year, month := int((it[0]>>4)&0x0f), int(it[0]&0x0f)
year += 2021
if year == 2021 {
num := binary.BigEndian.Uint32(it[1:5])
dstr := hex.EncodeToString(it[5:9])
return fmt.Sprintf(template2021, year, month, year, month, num, dstr)
}
d := binary.BigEndian.Uint64(it[1:9])
isscaled := it[9]&0x80 > 0
num := int(it[9] & 0x7f)
trestore := fmt.Sprintf(templategeneral, year, month, d&0x0fffffff_ffffffff)
if num > 0 {
trestore += fmt.Sprintf("-%d", num)
}
if isscaled {
trestore += "-scaled"
}
d = bits.RotateLeft64(d, 4) & 0x0f
switch d {
case 0:
trestore += ".jpg"
case 1:
trestore += ".png"
case 2:
trestore += ".webp"
default:
return "invalid ext"
}
return trestore
}

View File

@@ -1,15 +0,0 @@
package heisi
import "unsafe"
// slice is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
//
// Unlike reflect.SliceHeader, its Data field is sufficient to guarantee the
// data it references will not be garbage collected.
type slice struct {
data unsafe.Pointer
len int
cap int
}

View File

@@ -1,150 +0,0 @@
// Package imagefinder 关键字搜图
package imagefinder
import (
"encoding/json"
"errors"
"math/rand"
"net/http"
"net/url"
"reflect"
"regexp"
"strings"
"github.com/quic-go/quic-go/http3"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/AnimeAPI/pixiv"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/FloatTech/zbputils/img/pool"
)
type resultjson struct {
Error bool `json:"error"`
Message string `json:"message"`
Data struct {
Illusts []struct {
ID int64 `json:"id"`
Title string `json:"title"`
AltTitle string `json:"altTitle"`
Description string `json:"description"`
Type int64 `json:"type"`
CreateDate string `json:"createDate"`
UploadDate string `json:"uploadDate"`
Sanity int64 `json:"sanity"`
Width int64 `json:"width"`
Height int64 `json:"height"`
PageCount int64 `json:"pageCount"`
Tags []struct {
Name string `json:"name"`
Translation string `json:"translation"`
} `json:"tags"`
Statistic struct {
Bookmarks int64 `json:"bookmarks"`
Likes int64 `json:"likes"`
Comments int64 `json:"comments"`
Views int64 `json:"views"`
} `json:"statistic"`
Image string `json:"image"`
} `json:"illusts"`
Scores []float64 `json:"scores"`
HasNext bool `json:"has_next"`
} `json:"data"`
}
var hrefre = regexp.MustCompile(`<a href=".*">`)
func init() {
control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "关键字搜图",
Help: "- 来张 [xxx]",
}).OnRegex(`^来张\s?(.*)$`, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
keyword := ctx.State["regex_matched"].([]string)[1]
soutujson, err := soutuapi(keyword)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
rannum := rand.Intn(len(soutujson.Data.Illusts))
il := soutujson.Data.Illusts[rannum]
illust, err := pixiv.Works(il.ID)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if len(illust.ImageUrls) == 0 {
ctx.SendChain(message.Text("ERROR: nil image url"))
return
}
u := illust.ImageUrls[0]
n := u[strings.LastIndex(u, "/")+1 : len(u)-4]
f := illust.Path(0)
err = pool.SendImageFromPool(n, f, func() error {
// 下载图片
return illust.DownloadToCache(0)
}, ctxext.SendFakeForwardToGroup(ctx,
message.Text(
il.Width, "x", il.Height, "\n",
"标题: ", il.Title, "\n",
"副标题: ", il.AltTitle, "\n",
"ID: ", il.ID, "\n",
"画师: ", illust.UserName, " (", illust.UserID, ")", "\n",
"分级:", il.Sanity, "\n",
hrefre.ReplaceAllString(strings.ReplaceAll(strings.ReplaceAll(il.Description, "<br />", "\n"), "</a>", ""), ""),
printtags(reflect.ValueOf(&il.Tags)),
),
), ctxext.GetFirstMessageInForward(ctx))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
})
}
// soutuapi 请求api
func soutuapi(keyword string) (r resultjson, err error) {
var data []byte
data, err = web.RequestDataWith(&http.Client{Transport: &http3.RoundTripper{}},
"https://api.pixivel.moe/v2/pixiv/illust/search/"+url.QueryEscape(keyword)+"?page=0",
"GET",
"https://pixivel.moe/",
"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",
nil,
)
if err != nil {
return
}
err = json.Unmarshal(data, &r)
if err == nil && r.Error {
err = errors.New(r.Message)
}
return
}
func printtags(r reflect.Value) string {
tags := r.Elem()
s := binary.BytesToString(binary.NewWriterF(func(w *binary.Writer) {
for i := 0; i < tags.Len(); i++ {
_ = w.WriteByte('\n')
tag := tags.Index(i)
_ = w.WriteByte('#')
w.WriteString(tag.Field(0).String())
if !tag.Field(1).IsZero() {
w.WriteString(" (")
w.WriteString(tag.Field(1).String())
w.WriteString(")")
}
}
}))
return s
}

View File

@@ -1,65 +0,0 @@
// Package jiami 兽语加密与解密
package jiami
import (
"encoding/json"
"fmt"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
jiami1 = "http://ovooa.caonm.net/API/sho_u/?msg=%v" // 加密api地址
jiami2 = "http://ovooa.caonm.net/API/sho_u/?format=1&msg=%v" // 解密api地址
)
type nmd struct { // struct解析格式大概是
Data struct {
Message string
} `json:"data"`
}
func init() { // 主函数
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "兽语加解密",
Help: "兽语加解密\n" +
"- 兽语加密xxx\n- 兽语解密xxx",
})
en.OnRegex(`^兽语加密\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
str := ctx.State["regex_matched"].([]string)[1]
es, err := web.GetData(fmt.Sprintf(jiami1, str)) // 将网站返回结果赋值
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
var r nmd // r数组
err = json.Unmarshal(es, &r) // 填api返回结果struct地址
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
ctx.SendChain(message.Text(r.Data.Message)) // 输出提取后的结果
})
en.OnRegex(`^兽语解密\s*(.+)$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
str := ctx.State["regex_matched"].([]string)[1]
es, err := web.GetData(fmt.Sprintf(jiami2, str)) // 将网站返回结果赋值
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
var n nmd // r数组
err = json.Unmarshal(es, &n) // 填api返回结果struct地址
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
ctx.SendChain(message.Text(n.Data.Message)) // 输出提取后的结果
})
}

View File

@@ -1,71 +0,0 @@
// Package juejuezi 绝绝子
package juejuezi
import (
"fmt"
"io"
"net/http"
"strings"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
)
const (
juejueziURL = "https://www.offjuan.com/api/juejuezi/text"
referer = "https://juejuezi.offjuan.com/"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
)
func init() {
control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "绝绝子生成器",
Help: "例: 喝奶茶绝绝子\n绝绝子吃饭",
}).OnRegex("[\u4E00-\u9FA5]{0,10}绝绝子[\u4E00-\u9FA5]{0,10}").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
toDealStr := []rune(strings.ReplaceAll(ctx.ExtractPlainText(), "绝绝子", ""))
switch len(toDealStr) {
case 0, 1:
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("不要只输入绝绝子"))
case 2:
data, err := juejuezi(string(toDealStr[0]), string(toDealStr[1]))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(gjson.Get(helper.BytesToString(data), "text").String()))
default:
params := ctx.GetWordSlices(string(toDealStr)).Get("slices").Array()
data, err := juejuezi(params[0].String(), params[1].String())
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(gjson.Get(helper.BytesToString(data), "text").String()))
}
})
}
func juejuezi(verb, noun string) (data []byte, err error) {
juejueziStr := fmt.Sprintf("{\"verb\":\"%s\",\"noun\":\"%s\"}", verb, noun)
client := &http.Client{}
// 提交请求
request, err := http.NewRequest("POST", juejueziURL, strings.NewReader(juejueziStr))
if err != nil {
return nil, err
}
request.Header.Add("Referer", referer)
request.Header.Add("User-Agent", ua)
response, err := client.Do(request)
if err != nil {
return nil, err
}
data, err = io.ReadAll(response.Body)
response.Body.Close()
return
}

View File

@@ -2,16 +2,16 @@
package kfccrazythursday
import (
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
crazyURL = "https://www.iculture.cc/demo/CrazyThursday/api/kfc.php"
crazyURL = "http://api.jixs.cc/api/wenan-fkxqs/index.php"
)
func init() {
@@ -26,6 +26,6 @@ func init() {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(gjson.ParseBytes(data).Get("@this.0.content").String()))
ctx.SendChain(message.Text(binary.BytesToString(data)))
})
}

View File

@@ -115,5 +115,5 @@ func getimgurl(url string) (string, error) {
if imageurl = json.Get("data.0.urls.original").Str; imageurl == "" {
return "", errors.New("未找到相关内容, 换个tag试试吧")
}
return strings.ReplaceAll(imageurl, "i.pixiv.cat", "i.pixiv.re"), nil
return imageurl, nil
}

112
plugin/lolimi/lolimi.go Normal file
View File

@@ -0,0 +1,112 @@
// Package lolimi 来源于 https://api.lolimi.cn/ 的接口
package lolimi
import (
"fmt"
"net/url"
"strconv"
"strings"
"github.com/FloatTech/AnimeAPI/tts/lolimi"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/tidwall/gjson"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
lolimiURL = "https://api.lolimi.cn"
raoURL = lolimiURL + "/API/rao/api.php"
yanURL = lolimiURL + "/API/yan/?url=%v"
xjjURL = lolimiURL + "/API/tup/xjj.php"
qingURL = lolimiURL + "/API/qing/api.php"
fabingURL = lolimiURL + "/API/fabing/fb.php?name=%v"
)
var (
engine = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "桑帛云 API",
Help: "- 让[嘉然|塔菲|东雪莲|懒羊羊|科比|孙笑川|陈泽|丁真|空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然]说我测尼玛\n- 随机绕口令\n- 颜值鉴定[图片]\n" +
"- 随机妹子\n- 随机情话\n- 发病 嘉然\n\n说明: 颜值鉴定只能鉴定三次元图片",
})
)
func init() {
engine.OnFullMatch("随机妹子").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
ctx.SendChain(message.Image(xjjURL))
})
engine.OnFullMatch("随机绕口令").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(raoURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(gjson.Get(binary.BytesToString(data), "data.Msg").String()))
})
engine.OnFullMatch("随机情话").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(qingURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(binary.BytesToString(data)))
})
engine.OnPrefix(`发病`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
name := ctx.NickName()
data, err := web.GetData(fmt.Sprintf(fabingURL, url.QueryEscape(name)))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(gjson.Get(binary.BytesToString(data), "data").String()))
})
engine.OnKeywordGroup([]string{"颜值鉴定"}, zero.MustProvidePicture).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
list := ctx.State["image_url"].([]string)
if len(list) > 0 {
ctx.SendChain(message.Text("少女祈祷中..."))
data, err := web.GetData(fmt.Sprintf(yanURL, url.QueryEscape(list[0])))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
assessment := gjson.Get(binary.BytesToString(data), "data.text").String()
if assessment == "" {
ctx.SendChain(message.Text("ERROR: 请输入正确的图片"))
return
}
var text strings.Builder // 创建一个strings.Builder实例
text.WriteString("评价: ")
text.WriteString(assessment) // 添加评估信息
for i := 0; i <= 2; i++ {
key := gjson.Get(binary.BytesToString(data), "data.grade.key"+strconv.Itoa(i)).String()
score := gjson.Get(binary.BytesToString(data), "data.grade.score"+strconv.Itoa(i)).String()
if key != "" {
text.WriteString("\n")
text.WriteString(key)
text.WriteString(": ")
text.WriteString(score)
}
}
ctx.SendChain(message.Text(text.String())) // 发送构建好的字符串
}
})
engine.OnRegex("^让(嘉然|塔菲|东雪莲|懒羊羊|科比|孙笑川|陈泽|丁真|空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然)说([\\s\u4e00-\u9fa5\u3040-\u309F\u30A0-\u30FF\\w\\p{P}\u3000-\u303F\uFF00-\uFFEF]+)$").Limit(ctxext.LimitByGroup).Handle(func(ctx *zero.Ctx) {
name := ctx.State["regex_matched"].([]string)[1]
msg := ctx.State["regex_matched"].([]string)[2]
ctx.SendChain(message.Text("少女祈祷中......"))
recordURL, err := lolimi.TTS(name, msg)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Record(recordURL))
})
}

View File

@@ -4,6 +4,7 @@ package manager
import (
"fmt"
"math/rand"
"regexp"
"sort"
"strconv"
"strings"
@@ -35,6 +36,7 @@ const (
"- 修改名片@QQ XXX\n" +
"- 修改头衔@QQ XXX\n" +
"- 申请头衔 XXX\n" +
"- 对信息回复: 撤回\n" +
"- 踢出群聊@QQ\n" +
"- 退出群聊 1234@bot\n" +
"- 群聊转发 1234 XXX\n" +
@@ -47,12 +49,14 @@ const (
"- 取消在\"cron\"的提醒\n" +
"- 列出所有提醒\n" +
"- 翻牌\n" +
"- 赞我\n" +
"- 对信息回复: 回应表情 [表情]\n" +
"- 设置欢迎语XXX 可选添加 [{at}] [{nickname}] [{avatar}] [{uid}] [{gid}] [{groupname}]\n" +
"- 测试欢迎语\n" +
"- 设置告别辞 参数同设置欢迎语\n" +
"- 测试告别辞\n" +
"- [开启 | 关闭]入群验证\n" +
"- 对信息回复:[设置 | 取消]精华\n" +
"- 对信息回复: [设置 | 取消]精华\n" +
"- 取消精华 [信息ID]\n" +
"- /精华列表\n" +
"Tips: {at}可在发送时艾特被欢迎者 {nickname}是被欢迎者名字 {avatar}是被欢迎者头像 {uid}是被欢迎者QQ号 {gid}是当前群群号 {groupname} 是当前群群名"
@@ -259,9 +263,7 @@ func init() { // 插件主体
engine.OnRegex(`^\[CQ:reply,id=(-?\d+)\].*撤回$`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
// 删除需要撤回的消息ID
ctx.DeleteMessage(message.NewMessageIDFromString(ctx.State["regex_matched"].([]string)[1]))
// 删除请求撤回的消息ID
// ctx.DeleteMessage(message.NewMessageIDFromInteger(ctx.Event.MessageID.(int64)))
ctx.DeleteMessage(ctx.State["regex_matched"].([]string)[1])
})
// 群聊转发
engine.OnRegex(`^群聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).
@@ -384,6 +386,57 @@ func init() { // 插件主体
),
)
})
// 给好友点赞
engine.OnFullMatch("赞我").SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
list := ctx.GetFriendList().Array()
flag := false
for _, v := range list {
if ctx.Event.UserID == v.Get("user_id").Int() {
flag = true
break
}
}
if !flag {
// ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("不加好友不给赞!"))
return
}
ctx.SendLike(ctx.Event.UserID, 10)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("给你赞了10下哦记得回我~"))
})
facere := regexp.MustCompile(`\[CQ:face,id=(\d+)\]`)
// 给消息回应表情
engine.OnRegex(`^\[CQ:reply,id=(-?\d+)\].*回应表情\s*(.+)\s*$`, zero.AdminPermission, zero.OnlyGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
msgid := ctx.State["regex_matched"].([]string)[1]
face := ctx.State["regex_matched"].([]string)[2]
if len(face) == 0 {
ctx.SendChain(message.Text("ERROR: 表情长度为 0"))
return
}
ids := facere.FindStringSubmatch(face)
id := rune(0)
if len(ids) == 2 && len(ids[1]) > 0 {
idi, err := strconv.Atoi(ids[1])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
id = rune(idi)
} else {
x := []rune(face)
if len(x) == 0 {
ctx.SendChain(message.Text("ERROR: 解析后表情长度为 0"))
return
}
id = x[0]
}
err := ctx.SetMessageEmojiLike(msgid, id)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
})
// 入群欢迎
engine.OnNotice().SetBlock(false).
Handle(func(ctx *zero.Ctx) {
@@ -443,10 +496,10 @@ func init() { // 插件主体
var w welcome
err := db.Find("farewell", &w, "where gid = "+strconv.FormatInt(ctx.Event.GroupID, 10))
if err == nil {
ctx.SendGroupMessage(ctx.Event.GroupID, message.ParseMessageFromString(welcometocq(ctx, w.Msg)))
collectsend(ctx, message.ParseMessageFromString(welcometocq(ctx, w.Msg))...)
} else {
userid := ctx.Event.UserID
ctx.SendChain(message.Text(ctx.CardOrNickName(userid), "(", userid, ")", "离开了我们..."))
collectsend(ctx, message.Text(ctx.CardOrNickName(userid), "(", userid, ")", "离开了我们..."))
}
}
})
@@ -620,7 +673,7 @@ func init() { // 插件主体
time.Unix(info.Get("operator_time").Int(), 0).Format("2006/01/02 15:04:05"),
))),
)
msgData := ctx.GetMessage(message.NewMessageIDFromInteger(info.Get("message_id").Int())).Elements
msgData := ctx.GetMessage(info.Get("message_id").Int()).Elements
if msgData != nil {
msg = append(msg,
message.CustomNode(info.Get("sender_nick").String(), info.Get("sender_id").Int(), msgData),
@@ -652,12 +705,12 @@ func init() { // 插件主体
// 传入 ctx 和 welcome格式string 返回cq格式string 使用方法:welcometocq(ctx,w.Msg)
func welcometocq(ctx *zero.Ctx, welcome string) string {
uid := strconv.FormatInt(ctx.Event.UserID, 10) // 用户id
nickname := ctx.CardOrNickName(ctx.Event.UserID) // 用户昵称
at := "[CQ:at,qq=" + uid + "]" // at用户
avatar := "[CQ:image,file=" + "http://q4.qlogo.cn/g?b=qq&nk=" + uid + "&s=640]" // 用户头像
gid := strconv.FormatInt(ctx.Event.GroupID, 10) // 群id
groupname := ctx.GetThisGroupInfo(true).Name // 群名
uid := strconv.FormatInt(ctx.Event.UserID, 10) // 用户id
nickname := ctx.CardOrNickName(ctx.Event.UserID) // 用户昵称
at := "[CQ:at,qq=" + uid + "]" // at用户
avatar := "[CQ:image,file=" + "https://q4.qlogo.cn/g?b=qq&nk=" + uid + "&s=640]" // 用户头像
gid := strconv.FormatInt(ctx.Event.GroupID, 10) // 群id
groupname := ctx.GetThisGroupInfo(true).Name // 群名
cqstring := strings.ReplaceAll(welcome, "{at}", at)
cqstring = strings.ReplaceAll(cqstring, "{nickname}", nickname)
cqstring = strings.ReplaceAll(cqstring, "{avatar}", avatar)

42
plugin/manager/slow.go Normal file
View File

@@ -0,0 +1,42 @@
package manager
import (
"time"
"github.com/RomiChan/syncx"
"github.com/fumiama/slowdo"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
var slowsenders = syncx.Map[int64, *syncx.Lazy[*slowdo.Job[*zero.Ctx, message.MessageSegment]]]{}
func collectsend(ctx *zero.Ctx, msgs ...message.MessageSegment) {
id := ctx.Event.GroupID
if id == 0 {
// only support group
return
}
lazy, _ := slowsenders.LoadOrStore(id, &syncx.Lazy[*slowdo.Job[*zero.Ctx, message.MessageSegment]]{
Init: func() *slowdo.Job[*zero.Ctx, message.MessageSegment] {
x, err := slowdo.NewJob(time.Second*5, ctx, func(ctx *zero.Ctx, msg []message.MessageSegment) {
m := make(message.Message, len(msg))
for i, item := range msg {
m[i] = message.CustomNode(
zero.BotConfig.NickName[0],
ctx.Event.SelfID,
message.Message{item})
}
ctx.SendGroupForwardMessage(id, m)
})
if err != nil {
panic(err)
}
return x
},
})
job := lazy.Get()
for _, msg := range msgs {
job.Add(msg)
}
}

View File

@@ -96,12 +96,12 @@ func GetFilledTimer(dateStrs []string, botqq, grp int64, matchDateOnly bool) *Ti
if len(minuteStr) == 3 {
minuteStr = []rune{minuteStr[0], minuteStr[2]} // 去除中间的十
}
min := chineseNum2Int(minuteStr)
if min < -1 || min > 59 { // 分钟非法
minute := chineseNum2Int(minuteStr)
if minute < -1 || minute > 59 { // 分钟非法
t.Alert = "分钟非法!"
return &t
}
t.SetMinute(min)
t.SetMinute(minute)
if !matchDateOnly {
urlStr := dateStrs[5]
if urlStr != "" { // 是图片url

View File

@@ -155,7 +155,7 @@ func (t *Timer) judgeHM() {
if t.SelfID != 0 {
t.sendmsg(t.GrpID, zero.GetBot(t.SelfID))
} else {
zero.RangeBot(func(id int64, ctx *zero.Ctx) (_ bool) {
zero.RangeBot(func(_ int64, ctx *zero.Ctx) (_ bool) {
t.sendmsg(t.GrpID, ctx)
return
})

View File

@@ -44,10 +44,10 @@ func (t *Timer) Hour() (h int) {
}
// Minute 6bits
func (t *Timer) Minute() (min int) {
min = int(t.En1Month4Day5Week3Hour5Min6 & 0x00003f)
if min == 0b111111 {
min = -1
func (t *Timer) Minute() (m int) {
m = int(t.En1Month4Day5Week3Hour5Min6 & 0x00003f)
if m == 0b111111 {
m = -1
}
return
}
@@ -82,6 +82,6 @@ func (t *Timer) SetHour(h int) {
}
// SetMinute ...
func (t *Timer) SetMinute(min int) {
t.En1Month4Day5Week3Hour5Min6 = (int32(min) & 0x00003f) | (t.En1Month4Day5Week3Hour5Min6 & 0xffffc0)
func (t *Timer) SetMinute(m int) {
t.En1Month4Day5Week3Hour5Min6 = (int32(m) & 0x00003f) | (t.En1Month4Day5Week3Hour5Min6 & 0xffffc0)
}

View File

@@ -59,7 +59,7 @@ func init() {
for {
select {
case <-time.After(time.Second * 120):
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消钓鱼")))
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消购买")))
return
case e := <-recv:
nextcmd := e.Event.Message.String()
@@ -69,7 +69,7 @@ func init() {
}
money := wallet.GetWalletOf(uid)
if money < 100 {
ctx.SendChain(message.Text("你钱包当前只有", money, "ATRI币,无法完成支付"))
ctx.SendChain(message.Text("你钱包当前只有", money, wallet.GetWalletName(), ",无法完成支付"))
return
}
err = wallet.InsertWalletOf(uid, -100)
@@ -147,7 +147,7 @@ func init() {
fishNumber = 0
for name, number := range fishNmaes {
fishNumber += number
msg += strconv.Itoa(number) + name + ""
msg += strconv.Itoa(number) + name + " "
}
msg += ")"
fishNumber /= 2

View File

@@ -28,7 +28,7 @@ type fishdb struct {
const FishLimit = 50
// version 规则版本号
const version = "5.4.2"
const version = "5.5.8"
// 各物品信息
type jsonInfo struct {
@@ -101,7 +101,7 @@ type buffInfo struct {
Coupon int `db:"Buff1"` // 优惠卷
SalesPole int `db:"Buff2"` // 卖鱼竿上限
BuyTing int `db:"Buff3"` // 购买上限
Buff4 int `db:"Buff4"` // 暂定
SalesFish int `db:"Buff4"` // 卖鱼次数
Buff5 int `db:"Buff5"` // 暂定
Buff6 int `db:"Buff6"` // 暂定
Buff7 int `db:"Buff7"` // 暂定
@@ -131,7 +131,7 @@ var (
DisableOnDefault: false,
Brief: "钓鱼",
Help: "一款钓鱼模拟器\n----------指令----------\n" +
"- 钓鱼看板/钓鱼商店\n- 购买xxx\n- 购买xxx [数量]\n- 出售xxx\n- 出售xxx [数量]\n" +
"- 钓鱼看板/钓鱼商店\n- 购买xxx\n- 购买xxx [数量]\n- 出售xxx\n- 出售xxx [数量]\n- 出售所有垃圾\n" +
"- 钓鱼背包\n- 装备[xx竿|三叉戟|美西螈]\n- 附魔[诱钓|海之眷顾]\n- 修复鱼竿\n- 合成[xx竿|三叉戟]\n- 消除[绑定|宝藏]诅咒\n- 消除[绑定|宝藏]诅咒 [数量]\n" +
"- 进行钓鱼\n- 进行n次钓鱼\n- 当前装备概率明细\n" +
"规则V" + version + ":\n" +
@@ -146,10 +146,10 @@ var (
"5.鱼类信息:\n-> 鳕鱼 : 均价:10 上钩概率:0.69%\n-> 鲑鱼 : 均价:50 上钩概率:0.2%\n-> 热带鱼 : 均价:100 上钩概率:0.06%\n-> 河豚 : 均价:300 上钩概率:0.03%\n-> 鹦鹉螺 : 均价:500 上钩概率:0.01%\n-> 墨鱼 : 均价:500 上钩概率:0.01%\n" +
"6.垃圾:\n-> 均价:10 上钩概率:30%\n" +
"7.物品BUFF:\n-> 钓鱼佬 : 当背包名字含有'鱼'的物品数量超过100时激活,钓到物品概率提高至90%\n-> 修复大师 : 当背包鱼竿数量超过10时激活,修复物品时耐久百分百继承\n" +
"8.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%,继承附魔等级合/3的等级\n" +
"8.合成:\n-> 铁竿 : 3x木竿\n-> 金竿 : 3x铁竿\n-> 钻石竿 : 3x金竿\n-> 下界合金竿 : 3x钻石竿\n-> 三叉戟 : 3x下界合金竿\n注:合成成功率90%(包括梭哈),合成鱼竿的附魔等级=(附魔等级合/合成鱼竿数量)\n" +
"9.杂项:\n-> 无装备的情况下,每人最多可以购买3次100块钱的鱼竿\n-> 默认状态钓鱼上钩概率为60%(理论值!!!)\n-> 附魔的鱼竿会因附魔变得昂贵,每个附魔最高3级\n-> 三叉戟不算鱼竿,修复时可直接满耐久\n" +
"-> 鱼竿数量大于50的不能买东西;\n 鱼竿数量大于30的不能钓鱼;\n 每购/售10次鱼竿获得1层宝藏诅咒;\n 每购买20次物品将获得3次价格减半福利;\n 每钓鱼75次获得1本净化书;\n" +
" 每天最多只可出售5个鱼竿和购买15次物品;",
" 每天最多只可出售5个鱼竿和购买15次物品;鱼类交易每天最多100条.",
PublicDataFolder: "McFish",
}).ApplySingle(ctxext.DefaultSingle)
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
@@ -208,7 +208,7 @@ func init() {
Min: probableList[2],
Max: probableList[3],
}
min := make(map[string]int, 4)
minMap := make(map[string]int, 4)
for _, info := range articlesInfo.ArticleInfo {
switch {
case info.Type == "pole" || info.Name == "美西螈":
@@ -228,10 +228,10 @@ func init() {
durationList[info.Name] = info.Durable
}
probabilities[info.Name] = probabilityLimit{
Min: min[info.Type],
Max: min[info.Type] + info.Probability,
Min: minMap[info.Type],
Max: minMap[info.Type] + info.Probability,
}
min[info.Type] += info.Probability
minMap[info.Type] += info.Probability
}
// }()
}
@@ -413,9 +413,9 @@ func (sql *fishdb) pickFishFor(uid int64, number int) (fishNames map[string]int,
}
if fishInfo.Number < i {
k++
fishInfo.Number = 0
i -= fishInfo.Number
fishNames[fishInfo.Name] += fishInfo.Number
fishInfo.Number = 0
} else {
fishNames[fishInfo.Name] += i
fishInfo.Number -= i
@@ -530,6 +530,26 @@ func (sql *fishdb) getNumberFor(uid int64, thing string) (number int, err error)
return
}
// 获取用户的某类物品信息
func (sql *fishdb) getUserTypeInfo(uid int64, thingType string) (thingInfos []article, err error) {
name := strconv.FormatInt(uid, 10) + "Pack"
sql.Lock()
defer sql.Unlock()
userInfo := article{}
err = sql.db.Create(name, &userInfo)
if err != nil {
return
}
if !sql.db.CanFind(name, "where Type = '"+thingType+"'") {
return
}
err = sql.db.FindFor(name, &userInfo, "where Type = '"+thingType+"'", func() error {
thingInfos = append(thingInfos, userInfo)
return nil
})
return
}
/*********************************************************/
/************************商店相关函数***********************/
/*********************************************************/
@@ -542,6 +562,10 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
if err != nil {
return false, err
}
err = sql.db.Create("store", &store{})
if err != nil {
return false, err
}
lastTime := storeDiscount{}
_ = sql.db.Find("stroeDiscount", &lastTime, "where Name = 'lastTime'")
refresh := false
@@ -566,6 +590,12 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
Name: name,
Discount: thingDiscount,
}
thingInfo := store{}
_ = sql.db.Find("store", &thingInfo, "where Name = '"+name+"'")
if thingInfo.Number > 150 {
// 通货膨胀
thing.Discount = (1000 - 5*(thingInfo.Number-150)) / 10
}
err = sql.db.Insert("stroeDiscount", &thing)
if err != nil {
return
@@ -591,10 +621,6 @@ func (sql *fishdb) refreshStroeInfo() (ok bool, err error) {
_ = sql.db.Del("stroeDiscount", "where Duration = "+strconv.FormatInt(info.Duration, 10))
}
if refresh {
err = sql.db.Create("store", &store{})
if err != nil {
return
}
// 每天调控1种鱼
fish := fishList[rand.Intn(len(fishList))]
thingInfo := store{
@@ -750,7 +776,7 @@ func (sql *fishdb) useCouponAt(uid int64, times int) (int, error) {
return useTimes, sql.db.Insert("buff", &userInfo)
}
// 检测上限
// 检测卖鱼竿上限
func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
residue := 0
sql.Lock()
@@ -762,6 +788,7 @@ func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
}
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
userInfo.Duration = time.Now().Unix()
userInfo.SalesPole = 0
userInfo.BuyTing = 0
}
@@ -769,8 +796,44 @@ func (sql *fishdb) checkCanSalesFor(uid int64, sales bool) (int, error) {
residue = 5 - userInfo.SalesPole
userInfo.SalesPole++
} else if userInfo.BuyTing < 15 {
residue = 15 - userInfo.SalesPole
userInfo.SalesPole++
residue = 15 - userInfo.BuyTing
userInfo.BuyTing++
}
return residue, sql.db.Insert("buff", &userInfo)
}
// 检测物品是否是鱼
func checkIsFish(thing string) bool {
for _, v := range fishList {
if v == thing {
return true
}
}
return false
}
// 检测买卖鱼上限
func (sql *fishdb) checkCanSalesFishFor(uid int64, sales int) (int, error) {
residue := 0
sql.Lock()
defer sql.Unlock()
userInfo := buffInfo{ID: uid}
err := sql.db.Create("buff", &userInfo)
if err != nil {
return residue, err
}
_ = sql.db.Find("buff", &userInfo, "where ID = "+strconv.FormatInt(uid, 10))
if time.Now().Day() != time.Unix(userInfo.Duration, 0).Day() {
userInfo.Duration = time.Now().Unix()
userInfo.SalesFish = 0
}
maxSales := 100 - userInfo.SalesFish
if maxSales < 0 {
maxSales = 0
}
if sales > maxSales {
sales = maxSales
}
userInfo.SalesFish += sales
return sales, sql.db.Insert("buff", &userInfo)
}

View File

@@ -63,7 +63,10 @@ func init() {
msg = append(msg, message.Text("[", i, "] ", info.Equip, " : 耐", info.Durable, "/修", info.Maintenance,
"/诱", enchantLevel[info.Induce], "/眷顾", enchantLevel[info.Favor], "\n"))
}
msg = append(msg, message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
msg = append(msg, message.Text("————————\n"))
msg = append(msg, message.Text("- 输入对应序号进行装备\n"))
msg = append(msg, message.Text("- 输入“取消”终止本次操作\n"))
msg = append(msg, message.Text("- 鱼竿数量请使用钓鱼背包查看"))
ctx.Send(msg)
// 等待用户下一步选择
recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
@@ -316,13 +319,15 @@ func init() {
case "诱钓":
equipInfo.Induce++
if equipInfo.Induce > 3 {
equipInfo.Induce = 3
ctx.SendChain(message.Text("诱钓等级已达到上限,你浪费了一本附魔书"))
return
}
number = equipInfo.Induce
case "海之眷顾":
equipInfo.Favor++
if equipInfo.Favor > 3 {
equipInfo.Favor = 3
ctx.SendChain(message.Text("海之眷顾等级已达到上限,你浪费了一本附魔书"))
return
}
number = equipInfo.Favor
default:
@@ -356,12 +361,12 @@ func init() {
ctx.SendChain(message.Text("[ERROR at pole.go.10]:", err))
return
}
max := len(articles)
if max < 3 {
maxCount := len(articles)
if maxCount < 3 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("你的合成材料不足"))
return
}
poles := make([]equip, 0, max)
poles := make([]equip, 0, maxCount)
for _, info := range articles {
poleInfo := strings.Split(info.Other, "/")
durable, _ := strconv.Atoi(poleInfo[0])
@@ -386,10 +391,13 @@ func init() {
msg = append(msg, message.Text("[", i, "] ", info.Equip, " : 耐", info.Durable, "/修", info.Maintenance,
"/诱", enchantLevel[info.Induce], "/眷顾", enchantLevel[info.Favor], "\n"))
}
msg = append(msg, message.Text("————————\n输入3个序号进行合成(用空格分割),或回复“取消”取消"))
msg = append(msg, message.Text("————————\n"))
msg = append(msg, message.Text("- 输入3个序号进行合成(用空格分割)\n"))
msg = append(msg, message.Text("- 输入“取消”,终止本次合成\n"))
msg = append(msg, message.Text("- 输入“梭哈“,合成所有鱼竿"))
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...))
// 等待用户下一步选择
recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(取消|\d+ \d+ \d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
recv, cancel := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(梭哈|取消|\d+ \d+ \d+)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
defer cancel()
for {
select {
@@ -410,6 +418,14 @@ func init() {
)
return
}
if nextcmd == "梭哈" {
// len(list)取3的倍数表示能够用于合成鱼竿的最大数量note此处未对article.Number>1的情况做处理
for i := 3; i < (len(articles)/3)*3; i++ {
list = append(list, i)
}
check = true
break
}
chooseList := strings.Split(nextcmd, " ")
first, err := strconv.Atoi(chooseList[0])
if err != nil {
@@ -431,8 +447,8 @@ func init() {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[0]请输入正确的序号\n", list))
continue
}
if first > max || second > max || third > max {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", max, "]请输入正确的序号\n", list))
if first >= maxCount || second >= maxCount || third >= maxCount {
ctx.SendChain(message.At(ctx.Event.UserID), message.Text("[", maxCount, "]请输入正确的序号\n", list))
continue
}
check = true
@@ -442,6 +458,7 @@ func init() {
}
}
}
upgradeNum := len(list)
favorLevel := 0
induceLevel := 0
for _, index := range list {
@@ -463,7 +480,7 @@ func init() {
)
return
}
attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel/3) + "/" + strconv.Itoa(favorLevel/3)
attribute := strconv.Itoa(durationList[thingName]) + "/0/" + strconv.Itoa(induceLevel/upgradeNum) + "/" + strconv.Itoa(favorLevel/upgradeNum)
newthing := article{
Duration: time.Now().Unix(),
Type: "pole",
@@ -471,14 +488,19 @@ func init() {
Number: 1,
Other: attribute,
}
err = dbdata.updateUserThingInfo(uid, newthing)
if err != nil {
ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err))
return
// 代码未对article.Number>1的情况做处理直接生成多个Number=1的鱼竿
for i := 0; i < upgradeNum/3; i++ {
// 使用时间戳作为主键,增加固定值避免主键冲突
newthing.Duration += int64(i * 10)
err = dbdata.updateUserThingInfo(uid, newthing)
if err != nil {
ctx.SendChain(message.Text("[ERROR at pole.go.12]:", err))
return
}
}
ctx.Send(
message.ReplyWithMessage(ctx.Event.MessageID,
message.Text(thingName, "合成成功", list, "\n属性: ", attribute),
message.Text("成功合成:", upgradeNum/3, "", thingName, "\n属性: ", attribute),
),
)
})

View File

@@ -85,6 +85,18 @@ func init() {
if number == 0 || strings.Contains(thingName, "竿") {
number = 1
}
if checkIsFish(thingName) {
residue, err := dbdata.checkCanSalesFishFor(uid, number)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:", err))
return
}
if residue <= 0 {
ctx.SendChain(message.Text("今天你已经超出了鱼交易数量上限,明天再来买鱼吧"))
return
}
number = residue
}
articles, err := dbdata.getUserThingInfo(uid, thingName)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.5]:", err))
@@ -107,7 +119,7 @@ func init() {
"[", i, "]", info.Name, " 数量: ", info.Number, "\n"))
}
}
msg = append(msg, message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
msg = append(msg, message.Text("————————\n输入对应序号进行出售,或回复“取消”取消"))
ctx.Send(msg)
// 等待用户下一步选择
sell := false
@@ -157,7 +169,9 @@ func init() {
maintenance, _ := strconv.Atoi(poleInfo[1])
induceLevel, _ := strconv.Atoi(poleInfo[2])
favorLevel, _ := strconv.Atoi(poleInfo[3])
pice = (priceList[thingName] - (durationList[thingName] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discountList[thingName] / 100
pice = (priceList[thingName] - (durationList[thingName] - durable) - maintenance*2 +
induceLevel*600*discountList["诱钓"]/100 +
favorLevel*1800*discountList["海之眷顾"]/100) * discountList[thingName] / 100
} else {
pice = priceList[thingName] * discountList[thingName] / 100
}
@@ -169,7 +183,7 @@ func init() {
for {
select {
case <-time.After(time.Second * 60):
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消钓鱼")))
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消出售")))
return
case e := <-recv:
nextcmd := e.Event.Message.String()
@@ -306,6 +320,82 @@ func init() {
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("出售成功,你赚到了", pice*number, msg)))
})
engine.OnRegex(`^出售所有垃圾`, getdb, refreshFish).SetBlock(true).Limit(limitSet).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
articles, err := dbdata.getUserTypeInfo(uid, "waste")
if err != nil {
ctx.SendChain(message.Text("[ERROR]:获取背包信息错误", err))
return
}
if len(articles) == 0 {
ctx.SendChain(message.Text("你的背包不存在该物品"))
return
}
if len(articles) > 1 {
msg := make(message.Message, 0, 3+len(articles))
msg = append(msg, message.Reply(ctx.Event.MessageID), message.Text("找到以下物品:\n"))
for i, info := range articles {
msg = append(msg, message.Text(
"[", i, "]", info.Name, " 数量: ", info.Number, "\n"))
}
ctx.Send(msg)
}
pice := 0
for _, info := range articles {
pice += (priceList[info.Name] * discountList[info.Name] / 100) * info.Number * 8 / 10
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("是否接受回收站将以", pice, "收购全部垃圾", "?\n回答\"是\"或\"否\"")))
// 等待用户下一步选择
recv, cancel1 := zero.NewFutureEvent("message", 999, false, zero.RegexRule(`^(是|否)$`), zero.CheckUser(ctx.Event.UserID)).Repeat()
defer cancel1()
buy := false
for {
select {
case <-time.After(time.Second * 60):
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("等待超时,取消出售垃圾")))
return
case e := <-recv:
nextcmd := e.Event.Message.String()
if nextcmd == "否" {
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("已取消出售")))
return
}
buy = true
}
if buy {
break
}
}
msg := ""
curse, err := dbdata.getNumberFor(uid, "宝藏诅咒")
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.9.3]:", err))
return
}
if curse != 0 {
msg = "\n(你身上绑定了" + strconv.Itoa(curse) + "层诅咒)"
pice = pice * (100 - 10*curse) / 100
}
for _, info := range articles {
info.Number = 0
err = dbdata.updateUserThingInfo(uid, info)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.6]:", err))
return
}
}
err = wallet.InsertWalletOf(uid, pice)
if err != nil {
ctx.SendChain(message.Text("[ERROR出售垃圾失败回收站卷款跑路了]:", err))
return
}
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.Text("出售成功,你赚到了", pice, msg)))
})
engine.OnRegex(`^购买(`+strings.Join(thingList, "|")+`)\s*(\d*)$`, getdb, refreshFish).SetBlock(true).Limit(limitSet).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
numberOfPole, err := dbdata.getNumberFor(uid, "竿")
@@ -323,7 +413,7 @@ func init() {
return
}
if buytimes <= 0 {
ctx.SendChain(message.Text("出售次数已达到上限,明天再来购买吧"))
ctx.SendChain(message.Text("购买次数已达到上限,明天再来购买吧"))
return
}
thingName := ctx.State["regex_matched"].([]string)[1]
@@ -331,6 +421,18 @@ func init() {
if number == 0 {
number = 1
}
if checkIsFish(thingName) {
residue, err := dbdata.checkCanSalesFishFor(uid, number)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:", err))
return
}
if residue <= 0 {
ctx.SendChain(message.Text("今天你已经超出了鱼交易数量上限,明天再来买鱼吧"))
return
}
number = residue
}
thingInfos, err := dbdata.getStoreThingInfo(thingName)
if err != nil {
ctx.SendChain(message.Text("[ERROR at store.go.11]:", err))
@@ -372,7 +474,9 @@ func init() {
maintenance, _ := strconv.Atoi(poleInfo[1])
induceLevel, _ := strconv.Atoi(poleInfo[2])
favorLevel, _ := strconv.Atoi(poleInfo[3])
thingPice := (priceList[info.Name] - (durationList[info.Name] - durable) - maintenance*2 + induceLevel*600 + favorLevel*1800) * discountList[info.Name] / 100
thingPice := (priceList[info.Name] - (durationList[info.Name] - durable) - maintenance*2 +
induceLevel*600*discountList["诱钓"]/100 +
favorLevel*1800*discountList["海之眷顾"]/100) * discountList[info.Name] / 100
pice = append(pice, thingPice)
} else {
thingPice := priceList[info.Name] * discountList[info.Name] / 100
@@ -391,7 +495,7 @@ func init() {
"[", i, "]", info.Name, " 数量:", info.Number, " 价格:", pice[i], "\n"))
}
}
msg = append(msg, message.Text("————————\n输入对应序号进行装备,或回复“取消”取消"))
msg = append(msg, message.Text("————————\n输入对应序号进行购买,或回复“取消”取消"))
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, msg...))
// 等待用户下一步选择
sell := false

View File

@@ -18,38 +18,14 @@ import (
"github.com/FloatTech/zbputils/ctxext"
)
const (
jpapi = "https://moegoe.azurewebsites.net/api/speak?text=%s&id=%d"
krapi = "https://moegoe.azurewebsites.net/api/speakkr?text=%s&id=%d"
)
var speakers = map[string]uint{
"宁宁": 0, "爱瑠": 1, "芳乃": 2, "茉子": 3, "丛雨": 4, "小春": 5, "七海": 6,
"Sua": 0, "Mimiru": 1, "Arin": 2, "Yeonhwa": 3, "Yuhwa": 4, "Seonbae": 5,
}
var = newapikeystore("./data/tts/o.txt")
func init() {
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "日韩中 VITS 模型拟声",
Help: "- 让[宁宁|爱瑠|芳乃|茉子|丛雨|小春|七海]说(日语)\n" +
"- 让[Sua|Mimiru|Arin|Yeonhwa|Yuhwa|Seonbae]说(韩语)\n" +
"- 让[空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然|标贝]说(中文)",
Help: "- 让[空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然|标贝]说(中文)",
}).ApplySingle(ctxext.DefaultSingle)
en.OnRegex("^让(宁宁|爱瑠|芳乃|茉子|丛雨|小春|七海)说([A-Za-z\\s\\d\u3005\u3040-\u30ff\u4e00-\u9fff\uff11-\uff19\uff21-\uff3a\uff41-\uff5a\uff66-\uff9d\\pP]+)$").Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
text := ctx.State["regex_matched"].([]string)[2]
id := speakers[ctx.State["regex_matched"].([]string)[1]]
ctx.SendChain(message.Record(fmt.Sprintf(jpapi, url.QueryEscape(text), id)))
})
en.OnRegex("^让(Sua|Mimiru|Arin|Yeonhwa|Yuhwa|Seonbae)说([A-Za-z\\s\\d\u3131-\u3163\uac00-\ud7ff\\pP]+)$").Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
text := ctx.State["regex_matched"].([]string)[2]
id := speakers[ctx.State["regex_matched"].([]string)[1]]
ctx.SendChain(message.Record(fmt.Sprintf(krapi, url.QueryEscape(text), id)))
})
en.OnRegex("^让(空|荧|派蒙|纳西妲|阿贝多|温迪|枫原万叶|钟离|荒泷一斗|八重神子|艾尔海森|提纳里|迪希雅|卡维|宵宫|莱依拉|赛诺|诺艾尔|托马|凝光|莫娜|北斗|神里绫华|雷电将军|芭芭拉|鹿野院平藏|五郎|迪奥娜|凯亚|安柏|班尼特|琴|柯莱|夜兰|妮露|辛焱|珐露珊|魈|香菱|达达利亚|砂糖|早柚|云堇|刻晴|丽莎|迪卢克|烟绯|重云|珊瑚宫心海|胡桃|可莉|流浪者|久岐忍|神里绫人|甘雨|戴因斯雷布|优菈|菲谢尔|行秋|白术|九条裟罗|雷泽|申鹤|迪娜泽黛|凯瑟琳|多莉|坎蒂丝|萍姥姥|罗莎莉亚|留云借风真君|绮良良|瑶瑶|七七|奥兹|米卡|夏洛蒂|埃洛伊|博士|女士|大慈树王|三月七|娜塔莎|希露瓦|虎克|克拉拉|丹恒|希儿|布洛妮娅|瓦尔特|杰帕德|佩拉|姬子|艾丝妲|白露|星|穹|桑博|伦纳德|停云|罗刹|卡芙卡|彦卿|史瓦罗|螺丝咕姆|阿兰|银狼|素裳|丹枢|黑塔|景元|帕姆|可可利亚|半夏|符玄|公输师傅|奥列格|青雀|大毫|青镞|费斯曼|绿芙蓉|镜流|信使|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|真理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|终焉之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|始源之律者|芽衣|雷之律者|苏莎娜|阿波尼亚|陆景和|莫弈|夏彦|左然|标贝)说([\\s\u4e00-\u9fa5\\pP]+)$").Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
if .k == "" {

View File

@@ -23,31 +23,31 @@ func TestSetHoliday(t *testing.T) {
t.Fatal(err)
}
err = SetHoliday("元旦", 1, 2024, 1, 1)
err = SetHoliday("元旦", 1, 2025, 1, 1)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("春节", 7, 2024, 2, 10)
err = SetHoliday("春节", 7, 2025, 1, 29)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("清明节", 1, 2024, 4, 5)
err = SetHoliday("清明节", 1, 2025, 4, 4)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("劳动节", 1, 2024, 5, 1)
err = SetHoliday("劳动节", 1, 2025, 5, 1)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("端午节", 1, 2023, 6, 10)
err = SetHoliday("端午节", 3, 2024, 6, 8)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("中秋节", 2, 2023, 9, 29)
err = SetHoliday("中秋节", 3, 2024, 9, 15)
if err != nil {
t.Fatal(err)
}
err = SetHoliday("国庆节", 6, 2023, 10, 1)
err = SetHoliday("国庆节", 7, 2024, 10, 1)
if err != nil {
t.Fatal(err)
}

View File

@@ -32,7 +32,10 @@ func GetHoliday(name string) *Holiday {
if err != nil {
return NewHoliday(name+err.Error(), 0, 0, 0, 0)
}
fmt.Sscanf(ret, "%d_%d_%d_%d", &dur, &year, &month, &day)
_, err = fmt.Sscanf(ret, "%d_%d_%d_%d", &dur, &year, &month, &day)
if err != nil {
return NewHoliday(name+err.Error(), 0, 0, 0, 0)
}
logrus.Debugln("[moyu]获取节日:", name, dur, year, month, day)
return NewHoliday(name, dur, year, month, day)
}

485
plugin/niuniu/main.go Normal file
View File

@@ -0,0 +1,485 @@
// Package niuniu 牛牛大作战
package niuniu
import (
"fmt"
"math/rand"
"strconv"
"strings"
"time"
"github.com/FloatTech/AnimeAPI/wallet"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/RomiChan/syncx"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/extension/rate"
"github.com/wdvxdr1123/ZeroBot/message"
)
type lastLength struct {
TimeLimit time.Time
Count int
Length float64
}
type propsCount struct {
Count int
TimeLimit time.Time
}
var (
en = control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "牛牛大作战",
Help: "- 打胶\n" +
"- 使用[道具名称]打胶\n" +
"- jj@xxx\n" +
"- 使用[道具名称]jj@xxx\n" +
"- 注册牛牛\n" +
"- 赎牛牛(cd:45分钟)\n" +
"- 牛牛商店\n" +
"- 牛牛背包\n" +
"- 注销牛牛\n" +
"- 查看我的牛牛\n" +
"- 牛子长度排行\n" +
"- 牛子深度排行\n",
PrivateDataFolder: "niuniu",
})
dajiaoLimiter = rate.NewManager[string](time.Second*90, 1)
jjLimiter = rate.NewManager[string](time.Second*150, 1)
jjCount = syncx.Map[string, *lastLength]{}
prop = syncx.Map[string, *propsCount]{}
)
func init() {
en.OnFullMatch("牛牛背包", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
niu, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("你还没有牛牛呢快去注册一个吧!"))
return
}
ctx.SendChain(message.Text("当前牛牛背包如下",
"\n伟哥:", niu.WeiGe,
"\n媚药:", niu.Philter,
"\n击剑神器:", niu.Artifact,
"\n击剑神稽:", niu.ShenJi))
})
en.OnFullMatch("牛牛商店", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
if _, err := db.findNiuNiu(gid, uid); err != nil {
ctx.SendChain(message.Text("你还没有牛牛呢快去注册一个吧!"))
return
}
var messages message.Message
messages = append(messages, ctxext.FakeSenderForwardNode(ctx, message.Text("牛牛商店当前售卖的物品如下")))
messages = append(messages,
ctxext.FakeSenderForwardNode(ctx,
message.Text("商品1\n商品名:伟哥\n商品价格:300ATRI币\n商品描述:可以让你打胶每次都增长有效5次")))
messages = append(messages,
ctxext.FakeSenderForwardNode(ctx,
message.Text("商品2\n商品名:媚药\n商品价格:300ATRI币\n商品描述:可以让你打胶每次都减少有效5次")))
messages = append(messages,
ctxext.FakeSenderForwardNode(ctx,
message.Text("商品3\n商品名:击剑神器\n商品价格:500ATRI币\n商品描述:可以让你每次击剑都立于不败之地有效2次")))
messages = append(messages,
ctxext.FakeSenderForwardNode(ctx,
message.Text("商品4\n商品名:击剑神稽\n商品价格:500ATRI币\n商品描述:可以让你每次击剑都失败有效2次")))
if id := ctx.Send(messages).ID(); id == 0 {
ctx.Send(message.Text("发送商店失败"))
return
}
ctx.SendChain(message.Text("输入对应序号进行购买商品"))
recv, cancel := zero.NewFutureEvent("message", 999, false, zero.CheckUser(uid), zero.CheckGroup(gid), zero.RegexRule(`^(\d+)$`)).Repeat()
defer cancel()
timer := time.NewTimer(120 * time.Second)
answer := ""
defer timer.Stop()
for {
select {
case <-timer.C:
ctx.SendChain(message.At(uid), message.Text(" 超时,已自动取消"))
return
case r := <-recv:
answer = r.Event.Message.String()
n, err := strconv.Atoi(answer)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
info, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
money, err := purchaseItem(n, info)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
if wallet.GetWalletOf(uid) < money {
ctx.SendChain(message.Text("你还没有足够的ATRI币呢,不能购买"))
return
}
if err = wallet.InsertWalletOf(uid, -money); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
if err = db.insertNiuNiu(&info, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text("购买成功!"))
return
}
}
})
en.OnFullMatch("赎牛牛", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
last, ok := jjCount.Load(fmt.Sprintf("%d_%d", gid, uid))
if !ok {
ctx.SendChain(message.Text("你还没有被厥呢"))
return
}
if time.Since(last.TimeLimit) > time.Minute*45 {
ctx.SendChain(message.Text("时间已经过期了,牛牛已被收回!"))
jjCount.Delete(fmt.Sprintf("%d_%d", gid, uid))
return
}
if last.Count < 6 {
ctx.SendChain(message.Text("你还没有被厥够6次呢,不能赎牛牛"))
return
}
money := wallet.GetWalletOf(uid)
if money < 150 {
ctx.SendChain(message.Text("赎牛牛需要150ATRI币快去赚钱吧"))
return
}
if err := wallet.InsertWalletOf(uid, -150); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
niuniu, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
niuniu.Length = last.Length
if err = db.insertNiuNiu(&niuniu, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
jjCount.Delete(fmt.Sprintf("%d_%d", gid, uid))
ctx.SendChain(message.At(uid), message.Text(fmt.Sprintf("恭喜你!成功赎回牛牛,当前长度为:%.2fcm", last.Length)))
})
en.OnFullMatch("牛子长度排行", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
niuniuList, err := db.readAllTable(gid)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
m := niuniuList.positive()
if m == nil {
ctx.SendChain(message.Text("暂时没有男孩子哦"))
return
}
var messages strings.Builder
messages.WriteString("牛子长度排行榜\n")
for i, user := range m.sort(true) {
messages.WriteString(fmt.Sprintf("第%d名 id:%s 长度:%.2fcm\n", i+1,
ctx.CardOrNickName(user.UID), user.Length))
}
msg := ctxext.FakeSenderForwardNode(ctx, message.Text(&messages))
if id := ctx.Send(message.Message{msg}).ID(); id == 0 {
ctx.Send(message.Text("发送排行失败"))
}
})
en.OnFullMatch("牛子深度排行", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
niuniuList, err := db.readAllTable(gid)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
m := niuniuList.negative()
if m == nil {
ctx.SendChain(message.Text("暂时没有女孩子哦"))
return
}
var messages strings.Builder
messages.WriteString("牛牛深度排行榜\n")
for i, user := range m.sort(false) {
messages.WriteString(fmt.Sprintf("第%d名 id:%s 长度:%.2fcm\n", i+1,
ctx.CardOrNickName(user.UID), user.Length))
}
msg := ctxext.FakeSenderForwardNode(ctx, message.Text(&messages))
if id := ctx.Send(message.Message{msg}).ID(); id == 0 {
ctx.Send(message.Text("发送排行失败"))
}
})
en.OnFullMatch("查看我的牛牛", getdb, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
gid := ctx.Event.GroupID
i, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("你还没有牛牛呢不能查看!"))
return
}
niuniu := i.Length
var result strings.Builder
sexLong := "长"
sex := "♂️"
if niuniu < 0 {
sexLong = "深"
sex = "♀️"
}
niuniuList, err := db.readAllTable(gid)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
result.WriteString(fmt.Sprintf("\n📛%s<%s>的牛牛信息\n⭕性别:%s\n⭕%s度:%.2fcm\n⭕排行:%d\n⭕%s ",
ctx.CardOrNickName(uid), strconv.FormatInt(uid, 10),
sex, sexLong, niuniu, niuniuList.ranking(niuniu, uid), generateRandomString(niuniu)))
ctx.SendChain(message.Text(&result))
})
en.OnRegex(`^(?:.*使用(.*))??打胶$`, zero.OnlyGroup,
getdb).SetBlock(true).Limit(func(ctx *zero.Ctx) *rate.Limiter {
lt := dajiaoLimiter.Load(fmt.Sprintf("%d_%d", ctx.Event.GroupID, ctx.Event.UserID))
ctx.State["dajiao_last_touch"] = lt.LastTouch()
return lt
}, func(ctx *zero.Ctx) {
timePass := int(time.Since(time.Unix(ctx.State["dajiao_last_touch"].(int64), 0)).Seconds())
ctx.SendChain(message.Text(randomChoice([]string{
fmt.Sprintf("才过去了%ds时间,你就又要打🦶了,身体受得住吗", timePass),
fmt.Sprintf("不行不行,你的身体会受不了的,歇%ds再来吧", 90-timePass),
fmt.Sprintf("休息一下吧,会炸膛的!%ds后再来吧", 90-timePass),
fmt.Sprintf("打咩哟,你的牛牛会爆炸的,休息%ds再来吧", 90-timePass),
})))
}).Handle(func(ctx *zero.Ctx) {
// 获取群号和用户ID
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
t := fmt.Sprintf("%d_%d", gid, uid)
fiancee := ctx.State["regex_matched"].([]string)
updateMap(t, false)
niuniu, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("请先注册牛牛!"))
dajiaoLimiter.Delete(fmt.Sprintf("%d_%d", gid, uid))
return
}
messages, err := processNiuniuAction(t, &niuniu, fiancee[1])
if err != nil {
ctx.SendChain(message.Text(err))
return
}
if err = db.insertNiuNiu(&niuniu, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.Text(messages))
})
en.OnFullMatch("注册牛牛", zero.OnlyGroup, getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
if _, err := db.findNiuNiu(gid, uid); err == nil {
ctx.SendChain(message.Text("你已经注册过了"))
return
}
// 获取初始长度
length := db.randLength()
u := userInfo{
UID: uid,
Length: length,
}
// 添加数据进入表
if err := db.insertNiuNiu(&u, gid); err != nil {
if err = db.createGIDTable(gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
if err = db.insertNiuNiu(&u, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
}
ctx.SendChain(message.At(uid),
message.Text("注册成功,你的牛牛现在有", u.Length, "cm"))
})
en.OnRegex(`^(?:.*使用(.*))??jj\s?(\[CQ:at,(?:\S*,)?qq=(\d+)(?:,\S*)?\]|(\d+))$`, getdb,
zero.OnlyGroup).SetBlock(true).Limit(func(ctx *zero.Ctx) *rate.Limiter {
lt := jjLimiter.Load(fmt.Sprintf("%d_%d", ctx.Event.GroupID, ctx.Event.UserID))
ctx.State["jj_last_touch"] = lt.LastTouch()
return lt
}, func(ctx *zero.Ctx) {
timePass := int(time.Since(time.Unix(ctx.State["jj_last_touch"].(int64), 0)).Seconds())
ctx.SendChain(message.Text(randomChoice([]string{
fmt.Sprintf("才过去了%ds时间,你就又要击剑了,真是饥渴难耐啊", timePass),
fmt.Sprintf("不行不行,你的身体会受不了的,歇%ds再来吧", 150-timePass),
fmt.Sprintf("你这种男同就应该被送去集中营!等待%ds再来吧", 150-timePass),
fmt.Sprintf("打咩哟!你的牛牛会炸的,休息%ds再来吧", 150-timePass),
})))
},
).Handle(func(ctx *zero.Ctx) {
fiancee := ctx.State["regex_matched"].([]string)
adduser, err := strconv.ParseInt(fiancee[3]+fiancee[4], 10, 64)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
uid := ctx.Event.UserID
gid := ctx.Event.GroupID
t := fmt.Sprintf("%d_%d", gid, uid)
updateMap(t, false)
myniuniu, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("你还没有牛牛快去注册一个吧!"))
jjLimiter.Delete(t)
return
}
adduserniuniu, err := db.findNiuNiu(gid, adduser)
if err != nil {
ctx.SendChain(message.At(uid), message.Text("对方还没有牛牛呢,不能🤺"))
jjLimiter.Delete(t)
return
}
if uid == adduser {
ctx.SendChain(message.Text("你要和谁🤺?你自己吗?"))
jjLimiter.Delete(t)
return
}
fencingResult, f1, err := processJJuAction(&myniuniu, &adduserniuniu, t, fiancee[1])
if err != nil {
ctx.SendChain(message.Text(err))
return
}
if err = db.insertNiuNiu(&myniuniu, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
adduserniuniu.Length = f1
if err = db.insertNiuNiu(&adduserniuniu, gid); err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return
}
ctx.SendChain(message.At(uid), message.Text(" ", fencingResult))
j := fmt.Sprintf("%d_%d", gid, adduser)
count, ok := jjCount.Load(j)
var c lastLength
// 按照第一次jj时的时间计算超过45分钟则重置
if !ok {
c = lastLength{
TimeLimit: time.Now(),
Count: 1,
Length: adduserniuniu.Length,
}
} else {
c = lastLength{
TimeLimit: c.TimeLimit,
Count: count.Count + 1,
Length: count.Length,
}
if time.Since(c.TimeLimit) > time.Minute*45 {
c = lastLength{
TimeLimit: time.Now(),
Count: 1,
Length: adduserniuniu.Length,
}
}
}
jjCount.Store(j, &c)
if c.Count > 5 {
ctx.SendChain(message.Text(randomChoice([]string{fmt.Sprintf("你们太厉害了,对方已经被你们打了%d次了你们可以继续找他🤺", c.Count),
"你们不要再找ta🤺啦"})))
// 保证只发生一次
if c.Count < 7 {
id := ctx.SendPrivateMessage(adduser,
message.Text(fmt.Sprintf("你在%d群里已经被厥冒烟了快去群里赎回你原本的牛牛!\n发送:`赎牛牛`即可!", gid)))
if id == 0 {
ctx.SendChain(message.At(adduser), message.Text("快发送`赎牛牛`来赎回你原本的牛牛!"))
}
}
}
})
en.OnFullMatch("注销牛牛", getdb, zero.OnlyGroup).SetBlock(true).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
gid := ctx.Event.GroupID
_, err := db.findNiuNiu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("你还没有牛牛呢,咋的你想凭空造一个啊"))
return
}
err = db.deleteniuniu(gid, uid)
if err != nil {
ctx.SendChain(message.Text("注销失败"))
return
}
ctx.SendChain(message.Text("注销成功,你已经没有牛牛了"))
})
}
func randomChoice(options []string) string {
return options[rand.Intn(len(options))]
}
func updateMap(t string, d bool) {
value, ok := prop.Load(t)
if value == nil {
return
}
// 检查一次是否已经过期
if !d {
if time.Since(value.TimeLimit) > time.Minute*8 {
prop.Delete(t)
}
return
}
if ok {
prop.Store(t, &propsCount{
Count: value.Count + 1,
TimeLimit: value.TimeLimit,
})
} else {
prop.Store(t, &propsCount{
Count: 1,
TimeLimit: time.Now(),
})
}
if time.Since(value.TimeLimit) > time.Minute*8 {
prop.Delete(t)
}
}

212
plugin/niuniu/model.go Normal file
View File

@@ -0,0 +1,212 @@
// Package niuniu 牛牛大作战
package niuniu
import (
"fmt"
"math"
"math/rand"
"sort"
"strconv"
"sync"
"time"
fcext "github.com/FloatTech/floatbox/ctxext"
sql "github.com/FloatTech/sqlite"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
type model struct {
sql sql.Sqlite
sync.RWMutex
}
type userInfo struct {
UID int64
Length float64
UserCount int
WeiGe int // 伟哥
Philter int // 媚药
Artifact int // 击剑神器
ShenJi int // 击剑神稽
Buff1 int // 暂定
Buff2 int // 暂定
Buff3 int // 暂定
Buff4 int // 暂定
Buff5 int // 暂定
}
type users []*userInfo
var (
db = &model{}
getdb = fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
db.sql.DBPath = en.DataFolder() + "niuniu.db"
err := db.sql.Open(time.Hour * 24)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
return true
})
)
// useWeiGe 使用道具伟哥
func (u *userInfo) useWeiGe() (string, float64) {
niuniu := u.Length
reduce := math.Abs(hitGlue(niuniu))
niuniu += reduce
return randomChoice([]string{
fmt.Sprintf("哈哈,你这一用道具,牛牛就像是被激发了潜能,增加了%.2fcm!看来今天是个大日子呢!", reduce),
fmt.Sprintf("你这是用了什么神奇的道具?牛牛竟然增加了%.2fcm,简直是牛气冲天!", reduce),
fmt.Sprintf("使用道具后,你的牛牛就像是开启了加速模式,一下增加了%.2fcm,这成长速度让人惊叹!", reduce),
}), niuniu
}
// usePhilter 使用道具媚药
func (u *userInfo) usePhilter() (string, float64) {
niuniu := u.Length
reduce := math.Abs(hitGlue(niuniu))
niuniu -= reduce
return randomChoice([]string{
fmt.Sprintf("你使用媚药,咿呀咿呀一下使当前长度发生了一些变化,当前长度%.2f", niuniu),
fmt.Sprintf("看来你追求的是‘微观之美’,故意使用道具让牛牛凹进去了%.2fcm", reduce),
fmt.Sprintf("缩小奇迹’在你身上发生了,牛牛凹进去了%.2fcm,你的选择真是独特!", reduce),
}), niuniu
}
// useArtifact 使用道具击剑神器
func (u *userInfo) useArtifact(adduserniuniu float64) (string, float64, float64) {
myLength := u.Length
difference := myLength - adduserniuniu
var (
change float64
)
if difference > 0 {
change = hitGlue(myLength + adduserniuniu)
} else {
change = hitGlue((myLength + adduserniuniu) / 2)
}
myLength += change
return randomChoice([]string{
fmt.Sprintf("凭借神秘道具的力量,你让对方在你的长度面前俯首称臣!你的长度增加了%.2fcm,当前长度达到了%.2fcm", change, myLength),
fmt.Sprintf("神器在手,天下我有!你使用道具后,长度猛增%.2fcm,现在的总长度是%.2fcm,无人能敌!", change, myLength),
fmt.Sprintf("这就是道具的魔力!你轻松增加了%.2fcm,让对手望尘莫及,当前长度为%.2fcm", change, myLength),
fmt.Sprintf("道具一出,谁与争锋!你的长度因道具而增长%.2fcm,现在的长度是%.2fcm,霸气尽显!", change, myLength),
fmt.Sprintf("使用道具的你,如同获得神助!你的长度增长了%.2fcm,达到%.2fcm的惊人长度,胜利自然到手!", change, myLength),
}), myLength, adduserniuniu - change/1.3
}
// useShenJi 使用道具击剑神稽
func (u *userInfo) useShenJi(adduserniuniu float64) (string, float64, float64) {
myLength := u.Length
difference := myLength - adduserniuniu
var (
change float64
)
if difference > 0 {
change = hitGlue(myLength + adduserniuniu)
} else {
change = hitGlue((myLength + adduserniuniu) / 2)
}
myLength -= change
var r string
if myLength > 0 {
r = randomChoice([]string{
fmt.Sprintf("哦吼!?看来你的牛牛因为使用了神秘道具而缩水了呢🤣🤣🤣!缩小了%.2fcm", change),
fmt.Sprintf("哈哈,看来这个道具有点儿调皮,让你的长度缩水了%.2fcm!现在你的长度是%.2fcm,下次可得小心使用哦!", change, myLength),
fmt.Sprintf("使用道具后,你的牛牛似乎有点儿害羞,缩水了%.2fcm!现在的长度是%.2fcm,希望下次它能挺直腰板!", change, myLength),
fmt.Sprintf("哎呀,这个道具的效果有点儿意外,你的长度减少了%.2fcm,现在只有%.2fcm了!下次选道具可得睁大眼睛!", change, myLength),
})
} else {
r = randomChoice([]string{
fmt.Sprintf("哦哟,小姐姐真是玩得一手好游戏,使用道具后数值又降低了%.2fcm,小巧得更显魅力!", change),
fmt.Sprintf("看来小姐姐喜欢更加精致的风格,使用道具后,数值减少了%.2fcm,更加迷人了!", change),
fmt.Sprintf("小姐姐的每一次变化都让人惊喜,使用道具后,数值减少了%.2fcm,更加优雅动人!", change),
fmt.Sprintf("小姐姐这是在展示什么是真正的精致小巧,使用道具后,数值减少了%.2fcm,美得不可方物!", change),
})
}
return r, myLength, adduserniuniu + 0.7*change
}
func (m users) positive() users {
var m1 []*userInfo
for _, i2 := range m {
if i2.Length > 0 {
m1 = append(m1, i2)
}
}
return m1
}
func (m users) negative() users {
var m1 []*userInfo
for _, i2 := range m {
if i2.Length <= 0 {
m1 = append(m1, i2)
}
}
return m1
}
func (m users) sort(isDesc bool) users {
t := func(i, j int) bool {
return m[i].Length < m[j].Length
}
if isDesc {
t = func(i, j int) bool {
return m[i].Length > m[j].Length
}
}
sort.Slice(m, t)
return m
}
func (m users) ranking(niuniu float64, uid int64) int {
result := niuniu > 0
for i, user := range m.sort(result) {
if user.UID == uid {
return i + 1
}
}
return -1
}
func (db *model) randLength() float64 {
return float64(rand.Intn(9)+1) + (float64(rand.Intn(100)) / 100)
}
func (db *model) createGIDTable(gid int64) error {
db.Lock()
defer db.Unlock()
return db.sql.Create(strconv.FormatInt(gid, 10), &userInfo{})
}
// findNiuNiu 返回一个用户的牛牛信息
func (db *model) findNiuNiu(gid, uid int64) (userInfo, error) {
db.RLock()
defer db.RUnlock()
u := userInfo{}
err := db.sql.Find(strconv.FormatInt(gid, 10), &u, "where UID = "+strconv.FormatInt(uid, 10))
return u, err
}
// insertNiuNiu 更新一个用户的牛牛信息
func (db *model) insertNiuNiu(u *userInfo, gid int64) error {
db.Lock()
defer db.Unlock()
return db.sql.Insert(strconv.FormatInt(gid, 10), u)
}
func (db *model) deleteniuniu(gid, uid int64) error {
db.Lock()
defer db.Unlock()
return db.sql.Del(strconv.FormatInt(gid, 10), "where UID = "+strconv.FormatInt(uid, 10))
}
func (db *model) readAllTable(gid int64) (users, error) {
db.Lock()
defer db.Unlock()
a, err := sql.FindAll[userInfo](&db.sql, strconv.FormatInt(gid, 10), "where UserCount = 0")
return a, err
}

344
plugin/niuniu/utils.go Normal file
View File

@@ -0,0 +1,344 @@
// Package niuniu 牛牛大作战
package niuniu
import (
"errors"
"fmt"
"math"
"math/rand"
"time"
)
func createUserInfoByProps(props string, niuniu *userInfo) error {
var (
err error
)
switch props {
case "伟哥":
if niuniu.WeiGe > 0 {
niuniu.WeiGe--
} else {
err = errors.New("你还没有伟哥呢,不能使用")
}
case "媚药":
if niuniu.Philter > 0 {
niuniu.Philter--
} else {
err = errors.New("你还没有媚药呢,不能使用")
}
case "击剑神器":
if niuniu.Artifact > 0 {
niuniu.Artifact--
} else {
err = errors.New("你还没有击剑神器呢,不能使用")
}
case "击剑神稽":
if niuniu.ShenJi > 0 {
niuniu.ShenJi--
} else {
err = errors.New("你还没有击剑神稽呢,不能使用")
}
default:
err = errors.New("道具不存在")
}
return err
}
// 接收值依次是 自己和被jj用户的信息 一个包含gid和uid的字符串 道具名称
// 返回值依次是 要发生的消息 错误信息
func processJJuAction(myniuniu, adduserniuniu *userInfo, t string, props string) (string, float64, error) {
var (
fencingResult string
f float64
f1 float64
u userInfo
err error
)
v, ok := prop.Load(t)
u = *myniuniu
if props != "" {
if props != "击剑神器" && props != "击剑神稽" {
return "", 0, errors.New("道具不存在")
}
if err = createUserInfoByProps(props, myniuniu); err != nil {
return "", 0, err
}
}
switch {
case ok && v.Count > 1 && time.Since(v.TimeLimit) < time.Minute*8:
fencingResult, f, f1 = fencing(myniuniu.Length, adduserniuniu.Length)
myniuniu.Length = f
errMessage := fmt.Sprintf("你使用道具次数太快了,此次道具不会生效,等待%d再来吧", time.Minute*8-time.Since(v.TimeLimit))
err = errors.New(errMessage)
case myniuniu.ShenJi-u.ShenJi != 0:
fencingResult, f, f1 = myniuniu.useShenJi(adduserniuniu.Length)
myniuniu.Length = f
updateMap(t, true)
case myniuniu.Artifact-u.Artifact != 0:
fencingResult, f, f1 = myniuniu.useArtifact(adduserniuniu.Length)
myniuniu.Length = f
updateMap(t, true)
default:
fencingResult, f, f1 = fencing(myniuniu.Length, adduserniuniu.Length)
myniuniu.Length = f
}
return fencingResult, f1, err
}
func processNiuniuAction(t string, niuniu *userInfo, props string) (string, error) {
var (
messages string
u userInfo
err error
f float64
)
load, ok := prop.Load(t)
u = *niuniu
if props != "" {
if props != "伟哥" && props != "媚药" {
return "", errors.New("道具不存在")
}
if err = createUserInfoByProps(props, niuniu); err != nil {
return "", err
}
}
switch {
case ok && load.Count > 1 && time.Since(load.TimeLimit) < time.Minute*8:
messages, f = generateRandomStingTwo(niuniu.Length)
niuniu.Length = f
errMessage := fmt.Sprintf("你使用道具次数太快了,此次道具不会生效,等待%d再来吧", time.Minute*8-time.Since(load.TimeLimit))
err = errors.New(errMessage)
case niuniu.WeiGe-u.WeiGe != 0:
messages, f = niuniu.useWeiGe()
niuniu.Length = f
updateMap(t, true)
case niuniu.Philter-u.Philter != 0:
messages, f = niuniu.usePhilter()
niuniu.Length = f
updateMap(t, true)
default:
messages, f = generateRandomStingTwo(niuniu.Length)
niuniu.Length = f
}
return messages, err
}
func purchaseItem(n int, info userInfo) (int, error) {
var (
money int
err error
)
switch n {
case 1:
money = 300
info.WeiGe += 5
case 2:
money = 300
info.Philter += 5
case 3:
money = 500
info.Artifact += 2
case 4:
money = 500
info.ShenJi += 2
default:
err = errors.New("无效的选择")
}
return money, err
}
func generateRandomStingTwo(niuniu float64) (string, float64) {
probability := rand.Intn(100 + 1)
reduce := math.Abs(hitGlue(niuniu))
switch {
case probability <= 40:
niuniu += reduce
return randomChoice([]string{
fmt.Sprintf("你嘿咻嘿咻一下,促进了牛牛发育,牛牛增加%.2fcm了呢!", reduce),
fmt.Sprintf("你打了个舒服痛快的🦶呐,牛牛增加了%.2fcm呢!", reduce),
}), niuniu
case probability <= 60:
return randomChoice([]string{
"你打了个🦶,但是什么变化也没有,好奇怪捏~",
"你的牛牛刚开始变长了,可过了一会又回来了,什么变化也没有,好奇怪捏~",
}), niuniu
default:
niuniu -= reduce
if niuniu < 0 {
return randomChoice([]string{
fmt.Sprintf("哦吼!?看来你的牛牛凹进去了%.2fcm呢!", reduce),
fmt.Sprintf("你突发恶疾!你的牛牛凹进去了%.2fcm", reduce),
fmt.Sprintf("笑死,你因为打🦶过度导致牛牛凹进去了%.2fcm!🤣🤣🤣", reduce),
}), niuniu
}
return randomChoice([]string{
fmt.Sprintf("阿哦,你过度打🦶,牛牛缩短%.2fcm了呢!", reduce),
fmt.Sprintf("你的牛牛变长了很多,你很激动地继续打🦶,然后牛牛缩短了%.2fcm呢!", reduce),
fmt.Sprintf("小打怡情,大打伤身,强打灰飞烟灭!你过度打🦶,牛牛缩短了%.2fcm捏!", reduce),
}), niuniu
}
}
func generateRandomString(niuniu float64) string {
switch {
case niuniu <= -100:
return "wtf你已经进化成魅魔了魅魔在击剑时有20%的几率消耗自身长度吞噬对方牛牛呢。"
case niuniu <= -50:
return "嗯....好像已经穿过了身体吧..从另一面来看也可以算是凸出来的吧?"
case niuniu <= -25:
return randomChoice([]string{
"这名女生,你的身体很健康哦!",
"WOW,真的凹进去了好多呢!",
"你已经是我们女孩子的一员啦!",
})
case niuniu <= -10:
return randomChoice([]string{
"你已经是一名女生了呢,",
"从女生的角度来说,你发育良好(,",
"你醒啦?你已经是一名女孩子啦!",
"唔...可以放进去一根手指了都...",
})
case niuniu <= 0:
return randomChoice([]string{
"安了安了,不要伤心嘛,做女生有什么不好的啊。",
"不哭不哭,摸摸头,虽然很难再长出来,但是请不要伤心啦啊!",
"加油加油!我看好你哦!",
"你醒啦?你现在已经是一名女孩子啦!",
})
case niuniu <= 10:
return randomChoice([]string{
"你行不行啊?细狗!",
"虽然短,但是小小的也很可爱呢。",
"像一只蚕宝宝。",
"长大了。",
})
case niuniu <= 25:
return randomChoice([]string{
"唔...没话说",
"已经很长了呢!",
})
case niuniu <= 50:
return randomChoice([]string{
"话说这种真的有可能吗?",
"厚礼谢!",
})
case niuniu <= 100:
return randomChoice([]string{
"已经突破天际了嘛...",
"唔...这玩意应该不会变得比我高吧?",
"你这个长度会死人的...",
"你马上要进化成牛头人了!!",
"你是什么怪物,不要过来啊!!",
})
default:
return "惊世骇俗你已经进化成牛头人了牛头人在击剑时有20%的几率消耗自身长度吞噬对方牛牛呢。"
}
}
// fencing 击剑对决逻辑返回对决结果和myLength的变化值
func fencing(myLength, oppoLength float64) (string, float64, float64) {
devourLimit := 0.27
probability := rand.Intn(100) + 1
switch {
case oppoLength <= -100 && myLength > 0 && 10 < probability && probability <= 20:
change := hitGlue(oppoLength) + rand.Float64()*math.Log2(math.Abs(0.5*(myLength+oppoLength)))
myLength += change
return fmt.Sprintf("对方身为魅魔诱惑了你,你同化成魅魔!当前长度%.2fcm", -myLength), -myLength, oppoLength
case oppoLength >= 100 && myLength > 0 && 10 < probability && probability <= 20:
change := math.Min(math.Abs(devourLimit*myLength), math.Abs(1.5*myLength))
myLength += change
return fmt.Sprintf("对方以牛头人的荣誉摧毁了你的牛牛!当前长度%.2fcm", myLength), myLength, oppoLength
case myLength <= -100 && oppoLength > 0 && 10 < probability && probability <= 20:
change := hitGlue(myLength+oppoLength) + rand.Float64()*math.Log2(math.Abs(0.5*(myLength+oppoLength)))
oppoLength -= change
myLength -= change
return fmt.Sprintf("你身为魅魔诱惑了对方,吞噬了对方部分长度!当前长度%.2fcm", myLength), myLength, oppoLength
case myLength >= 100 && oppoLength > 0 && 10 < probability && probability <= 20:
myLength -= oppoLength
oppoLength = 0.01
return fmt.Sprintf("你以牛头人的荣誉摧毁了对方的牛牛!当前长度%.2fcm", myLength), myLength, oppoLength
default:
return determineResultBySkill(myLength, oppoLength)
}
}
// determineResultBySkill 根据击剑技巧决定结果
func determineResultBySkill(myLength, oppoLength float64) (string, float64, float64) {
probability := rand.Intn(100) + 1
winProbability := calculateWinProbability(myLength, oppoLength) * 100
return applySkill(myLength, oppoLength,
float64(probability) <= winProbability)
}
// calculateWinProbability 计算胜率
func calculateWinProbability(heightA, heightB float64) float64 {
pA := 0.9
heightRatio := math.Max(heightA, heightB) / math.Min(heightA, heightB)
reductionRate := 0.1 * (heightRatio - 1)
reduction := pA * reductionRate
adjustedPA := pA - reduction
return math.Max(adjustedPA, 0.01)
}
// applySkill 应用击剑技巧并生成结果
func applySkill(myLength, oppoLength float64, increaseLength1 bool) (string, float64, float64) {
reduce := fence(oppoLength)
// 兜底操作
if reduce == 0 {
reduce = rand.Float64() + float64(rand.Intn(3))
}
if increaseLength1 {
myLength += reduce
oppoLength -= 0.8 * reduce
if myLength < 0 {
return fmt.Sprintf("哦吼!?你的牛牛在长大欸!长大了%.2fcm", reduce), myLength, oppoLength
}
return fmt.Sprintf("你以绝对的长度让对方屈服了呢!你的长度增加%.2fcm,当前长度%.2fcm", reduce, myLength), myLength, oppoLength
}
myLength -= reduce
oppoLength += 0.8 * reduce
if myLength < 0 {
return fmt.Sprintf("哦吼!?看来你的牛牛因为击剑而凹进去了呢🤣🤣🤣!凹进去了%.2fcm", reduce), myLength, oppoLength
}
return fmt.Sprintf("对方以绝对的长度让你屈服了呢!你的长度减少%.2fcm,当前长度%.2fcm", reduce, myLength), myLength, oppoLength
}
// fence 根据长度计算减少的长度
func fence(rd float64) float64 {
rd = math.Abs(rd)
if rd == 0 {
rd = 1
}
r := hitGlue(rd)*2 + rand.Float64()*math.Log2(rd)
return float64(int(r * rand.Float64()))
}
func hitGlue(l float64) float64 {
if l == 0 {
l = 0.1
}
l = math.Abs(l)
switch {
case l > 1 && l <= 10:
return rand.Float64() * math.Log2(l*2)
case 10 < l && l <= 100:
return rand.Float64() * math.Log2(l*1.5)
case 100 < l && l <= 1000:
return rand.Float64() * (math.Log10(l*1.5) * 2)
case l > 1000:
return rand.Float64() * (math.Log10(l) * 2)
default:
return rand.Float64()
}
}

53
plugin/poker/poker.go Normal file
View File

@@ -0,0 +1,53 @@
// Package poker 抽扑克牌
package poker
import (
"encoding/json"
"math/rand"
fcext "github.com/FloatTech/floatbox/ctxext"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
// 图片来源 https://www.bilibili.com/opus/834601953403076633
var cardImgPathList []string
func init() {
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "抽扑克牌",
Help: "- 抽扑克\n- poker",
PublicDataFolder: "Poker",
}).ApplySingle(ctxext.DefaultSingle)
getImg := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
data, err := engine.GetLazyData("imgdata.json", true)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
err = json.Unmarshal(data, &cardImgPathList)
if err != nil {
ctx.SendChain(message.Text("ERROR:", err))
return false
}
return true
})
engine.OnFullMatchGroup([]string{"抽扑克", "poker"}, getImg).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
randomIndex := rand.Intn(len(cardImgPathList))
randomImgPath := cardImgPathList[randomIndex]
imgData, err := engine.GetLazyData(randomImgPath, true)
if err != nil {
ctx.Send("[poker]读取扑克图片失败")
return
}
ctx.Send(message.ImageBytes(imgData))
})
}

View File

@@ -128,7 +128,7 @@ func init() {
ctx.SendChain(
message.At(uid),
message.Text("\n今天你在", userInfo.Updatetime, "娶了群友"),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(userInfo.Target, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(userInfo.Target, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", userInfo.Targetname, "]",
@@ -140,7 +140,7 @@ func init() {
ctx.SendChain(
message.At(uid),
message.Text("\n今天你在", userInfo.Updatetime, "被群友"),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(userInfo.User, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(userInfo.User, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", userInfo.Username, "]",
@@ -200,7 +200,7 @@ func init() {
ctx.SendChain(
message.At(uid),
message.Text("今天你的群老婆是"),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", ctx.CardOrNickName(fiancee), "]",

View File

@@ -47,7 +47,7 @@ func init() {
)
})
// 礼物系统
engine.OnRegex(`^买礼物给\s?(\[CQ:at,qq=(\d+)\]|(\d+))`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).
engine.OnRegex(`^买礼物给\s?(\[CQ:at,(?:\S*,)?qq=(\d+)(?:,\S*)?\]|(\d+))`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
@@ -117,9 +117,9 @@ func init() {
}
// 输出结果
if mood == 0 {
ctx.SendChain(message.Text("你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很不喜欢,你们的好感度降低至", lastfavor))
ctx.SendChain(message.Text("你花了", moneyToFavor, wallet.GetWalletName(), "买了一件女装送给了ta,ta很不喜欢,你们的好感度降低至", lastfavor))
} else {
ctx.SendChain(message.Text("你花了", moneyToFavor, "ATRI币买了一件女装送给了ta,ta很喜欢,你们的好感度升至", lastfavor))
ctx.SendChain(message.Text("你花了", moneyToFavor, wallet.GetWalletName(), "买了一件女装送给了ta,ta很喜欢,你们的好感度升至", lastfavor))
}
})
engine.OnFullMatch("好感度列表", zero.OnlyGroup, getdb).SetBlock(true).Limit(ctxext.LimitByUser).

View File

@@ -93,7 +93,7 @@ func init() {
ctx.SendChain(message.Text("设置成功"))
})
// 单身技能
engine.OnRegex(`^(娶|嫁)\[CQ:at,qq=(\d+)\]`, zero.OnlyGroup, getdb, checkSingleDog).SetBlock(true).Limit(ctxext.LimitByUser).
engine.OnRegex(`^(娶|嫁)\[CQ:at,(?:\S*,)?qq=(\d+)(?:,\S*)?\]`, zero.OnlyGroup, getdb, checkSingleDog).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
uid := ctx.Event.UserID
@@ -153,7 +153,7 @@ func init() {
message.Text(sendtext[0][rand.Intn(len(sendtext[0]))]),
message.At(uid),
message.Text(choicetext),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", ctx.CardOrNickName(fiancee), "]",
@@ -239,7 +239,7 @@ func init() {
message.Text(sendtext[2][rand.Intn(len(sendtext[2]))]),
message.At(uid),
message.Text("今天你的群"+choicetext+"是"),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(fiancee, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", ctx.CardOrNickName(fiancee), "]",
@@ -303,7 +303,7 @@ func init() {
message.Text("恭喜你成功撮合了一对CP\n\n"),
message.At(gayOne),
message.Text("今天你的群老婆是"),
message.Image("http://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(gayZero, 10)+"&s=640").Add("cache", 0),
message.Image("https://q4.qlogo.cn/g?b=qq&nk="+strconv.FormatInt(gayZero, 10)+"&s=640").Add("cache", 0),
message.Text(
"\n",
"[", ctx.CardOrNickName(gayZero), "]",

View File

@@ -1,60 +0,0 @@
// Package quan qq权重查询
package quan
import (
"encoding/json"
"strconv"
"strings"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
quan = "http://tfapi.top/API/qqqz.php?type=json&qq=" // api
)
type result struct {
Code int `json:"code"`
Msg string `json:"msg"`
Qz string `json:"qz"`
}
func init() { // 主函数
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "QQ权重查询",
Help: "权重查询方式\n" +
"- 权重查询+@xxx" +
"- 权重查询+QQ号(可以不写,默认本人)",
})
en.OnRegex(`^权重查询\s*(\[CQ:at,qq=)?(\d+)?`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
str := ctx.State["regex_matched"].([]string)[2] // 获取uid
if str == "" { // user
str = strconv.FormatInt(ctx.Event.UserID, 10)
}
es, err := web.GetData(quan + str) // 将网站返回结果赋值
if err != nil {
ctx.SendChain(message.Text("出现错误捏: ", err))
return
}
var data result
err = json.Unmarshal(es, &data)
if err != nil {
ctx.SendChain(message.Text("解析json错误: ", err))
return
}
var msg strings.Builder
msg.WriteString("查询账号: ")
msg.WriteString(str)
msg.WriteString("\n")
msg.WriteString("查询状态: ")
msg.WriteString(data.Msg)
msg.WriteString("\n您的权重为: ")
msg.WriteString(data.Qz)
ctx.SendChain(message.Text(msg.String())) // 输出结果
})
}

View File

@@ -31,7 +31,7 @@ const (
agreeStatus
disagreeStatus
loveTag = "表白"
faceURL = "http://q4.qlogo.cn/g?b=qq&nk=%v&s=640"
faceURL = "https://q4.qlogo.cn/g?b=qq&nk=%v&s=640"
anonymousURL = "https://gitcode.net/anto_july/avatar/-/raw/master/%v.png"
)

195
plugin/robbery/robbery.go Normal file
View File

@@ -0,0 +1,195 @@
// Package robbery 打劫群友 基于“qqwife”插件魔改
package robbery
import (
"math/rand"
"strconv"
"sync"
"time"
fcext "github.com/FloatTech/floatbox/ctxext"
sql "github.com/FloatTech/sqlite"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/wdvxdr1123/ZeroBot/extension/single"
"github.com/FloatTech/AnimeAPI/wallet"
"github.com/FloatTech/floatbox/math"
"github.com/FloatTech/zbputils/ctxext"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
type robberyRepo struct {
db *sql.Sqlite
sync.RWMutex
}
type robberyRecord struct {
UserID int64 `db:"user_id"` // 劫匪
VictimID int64 `db:"victim_id"` // 受害者
Time string `db:"time"` // 时间
}
func init() {
police := &robberyRepo{
db: &sql.Sqlite{},
}
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "打劫别人的钱包",
Help: "- 打劫[对方Q号|@对方QQ]\n" +
"1. 受害者钱包少于1000不能被打劫\n" +
"2. 打劫成功率 40%\n" +
"4. 打劫失败罚款1000钱不够钱包归零\n" +
"5. 保险赔付0-80%\n" +
"6. 打劫成功获得对方0-5%+500的财产最高1W\n" +
"7. 每日可打劫或被打劫一次\n" +
"8. 打劫失败不计入次数\n",
PrivateDataFolder: "robbery",
}).ApplySingle(single.New(
single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }),
single.WithPostFn[int64](func(ctx *zero.Ctx) {
ctx.Send(
message.ReplyWithMessage(ctx.Event.MessageID,
message.Text("别着急,警察局门口排长队了!"),
),
)
}),
))
getdb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
police.db.DBPath = engine.DataFolder() + "robbery.db"
err := police.db.Open(time.Hour)
if err == nil {
// 创建CD表
err = police.db.Create("criminal_record", &robberyRecord{})
if err != nil {
ctx.SendChain(message.Text("[ERROR]:", err))
return false
}
return true
}
ctx.SendChain(message.Text("[ERROR]:", err))
return false
})
// 打劫功能
engine.OnRegex(`^打劫\s?(\[CQ:at,(?:\S*,)?qq=(\d+)(?:,\S*)?\]|(\d+))`, getdb).SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
fiancee := ctx.State["regex_matched"].([]string)
victimID, _ := strconv.ParseInt(fiancee[2]+fiancee[3], 10, 64)
if victimID == uid {
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID, message.At(uid), message.Text("不能打劫自己")))
return
}
// 查询记录
ok, err := police.getRecord(victimID, uid)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:", err))
return
}
if ok == 1 {
ctx.SendChain(message.Text("对方今天已经被打劫了,给人家留点后路吧"))
return
}
if ok >= 2 {
ctx.SendChain(message.Text("你今天已经成功打劫过了,贪心没有好果汁吃!"))
return
}
// 穷人保护
victimWallet := wallet.GetWalletOf(victimID)
if victimWallet < 1000 {
ctx.SendChain(message.Text("对方太穷了!打劫失败"))
return
}
// 判断打劫是否成功
if rand.Intn(100) > 60 {
updateMoney := wallet.GetWalletOf(uid)
if updateMoney >= 1000 {
updateMoney = 1000
}
ctx.SendChain(message.Text("打劫失败,罚款1000"))
err := wallet.InsertWalletOf(uid, -updateMoney)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:罚款失败,钱包坏掉力:\n", err))
return
}
return
}
userIncrMoney := math.Min(rand.Intn(victimWallet/20)+500, 10000)
victimDecrMoney := userIncrMoney / (rand.Intn(4) + 1)
// 记录结果
err = wallet.InsertWalletOf(victimID, -victimDecrMoney)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:钱包坏掉力:\n", err))
return
}
err = wallet.InsertWalletOf(uid, +userIncrMoney)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:打劫失败,脏款掉入虚无\n", err))
return
}
// 写入记录
err = police.insertRecord(victimID, uid)
if err != nil {
ctx.SendChain(message.At(uid), message.Text("[ERROR]:犯罪记录写入失败\n", err))
}
ctx.SendChain(message.At(uid), message.Text("打劫成功,钱包增加:", userIncrMoney, wallet.GetWalletName()))
ctx.SendChain(message.At(victimID), message.Text("保险公司对您进行了赔付,您实际损失:", victimDecrMoney, wallet.GetWalletName()))
})
}
// ok==0 可以打劫ok==1 程序错误 or 受害者进入CDok==2 用户进入CD; ok==3 用户和受害者都进入CD
func (sql *robberyRepo) getRecord(victimID, uid int64) (ok int, err error) {
sql.Lock()
defer sql.Unlock()
// 创建群表格
err = sql.db.Create("criminal_record", &robberyRecord{})
if err != nil {
return 1, err
}
// 拼接查询SQL
limitID := "where victim_id is " + strconv.FormatInt(victimID, 10) +
" or user_id is " + strconv.FormatInt(uid, 10)
if !sql.db.CanFind("criminal_record", limitID) {
// 没有记录即不用比较
return 0, nil
}
cdInfo := robberyRecord{}
err = sql.db.FindFor("criminal_record", &cdInfo, limitID, func() error {
if time.Now().Format("2006/01/02") != cdInfo.Time {
// // 如果跨天了就删除
err = sql.db.Del("criminal_record", limitID)
return nil
}
// 俩个if是为了保证重复打劫同一个人ok == 3
if cdInfo.UserID == uid {
ok += 2
}
if cdInfo.VictimID == victimID {
// lint 不允许使用 ok += 1
ok++
}
return nil
})
return ok, err
}
func (sql *robberyRepo) insertRecord(vid int64, uid int64) error {
sql.Lock()
defer sql.Unlock()
return sql.db.Insert("criminal_record", &robberyRecord{
UserID: uid,
VictimID: vid,
Time: time.Now().Format("2006/01/02"),
})
}

View File

@@ -8,6 +8,7 @@ import (
"reflect"
"strconv"
"github.com/fumiama/terasu/http2"
"github.com/sirupsen/logrus"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
@@ -24,6 +25,11 @@ import (
"github.com/FloatTech/zbputils/img/pool"
)
const (
enableHex = 0x10
unableHex = 0x7fffffff_fffffffd
)
var (
saucenaocli *gophersauce.Client
)
@@ -110,10 +116,15 @@ func init() { // 插件主体
Handle(func(ctx *zero.Ctx) {
// 开始搜索图片
pics, ok := ctx.State["image_url"].([]string)
showPic := false
if !ok {
ctx.SendChain(message.Text("ERROR: 未获取到图片链接"))
return
}
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
if ok && c.GetData(ctx.Event.GroupID)&enableHex == enableHex {
showPic = true
}
ctx.SendChain(message.Text("少女祈祷中..."))
for _, pic := range pics {
if saucenaocli != nil {
@@ -134,22 +145,24 @@ func init() { // 插件主体
}
}
})
resp, err := http.Head(result.Header.Thumbnail)
resp, err := http2.Head(result.Header.Thumbnail)
msg := make(message.Message, 0, 3)
if s > 80.0 {
msg = append(msg, message.Text("我有把握是这个!"))
} else {
msg = append(msg, message.Text("也许是这个?"))
}
if err == nil {
_ = resp.Body.Close()
if resp.StatusCode == http.StatusOK {
msg = append(msg, message.Image(result.Header.Thumbnail))
if showPic {
if err == nil {
_ = resp.Body.Close()
if resp.StatusCode == http.StatusOK {
msg = append(msg, message.Image(result.Header.Thumbnail))
} else {
msg = append(msg, message.Image(pic))
}
} else {
msg = append(msg, message.Image(pic))
}
} else {
msg = append(msg, message.Image(pic))
}
msg = append(msg, message.Text("\n图源: ", result.Header.IndexName, binary.BytesToString(b)))
ctx.Send(message.Message{ctxext.FakeSenderForwardNode(ctx, msg...)})
@@ -169,17 +182,19 @@ func init() { // 插件主体
}
msg := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Text("ascii2d搜图结果"))}
for i := 0; i < len(result) && i < 5; i++ {
msg = append(msg, ctxext.FakeSenderForwardNode(ctx,
message.Image(result[i].Thumb),
message.Text(fmt.Sprintf(
"标题: %s\n图源: %s\n画师: %s\n画师链接: %s\n图片链接: %s",
result[i].Name,
result[i].Type,
result[i].AuthNm,
result[i].Author,
result[i].Link,
))),
)
var resultMsgs message.Message
if showPic {
resultMsgs = append(resultMsgs, message.Image(result[i].Thumb))
}
resultMsgs = append(resultMsgs, message.Text(fmt.Sprintf(
"标题: %s\n图源: %s\n画师: %s\n画师链接: %s\n图片链接: %s",
result[i].Name,
result[i].Type,
result[i].AuthNm,
result[i].Author,
result[i].Link,
)))
msg = append(msg, ctxext.FakeSenderForwardNode(ctx, resultMsgs...))
}
if id := ctx.Send(msg).ID(); id == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
@@ -204,4 +219,33 @@ func init() { // 插件主体
}
ctx.SendChain(message.Text("成功!"))
})
engine.OnRegex(`^(开启|打开|启用|关闭|关掉|禁用)搜图显示图片$`, zero.AdminPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
gid := ctx.Event.GroupID
if gid <= 0 {
// 个人用户设为负数
gid = -ctx.Event.UserID
}
option := ctx.State["regex_matched"].([]string)[1]
c, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
if !ok {
ctx.SendChain(message.Text("找不到服务!"))
return
}
data := c.GetData(ctx.Event.GroupID)
switch option {
case "开启", "打开", "启用":
data |= enableHex
case "关闭", "关掉", "禁用":
data &= unableHex
default:
return
}
err := c.SetData(gid, data)
if err != nil {
ctx.SendChain(message.Text("出错啦: ", err))
return
}
ctx.SendChain(message.Text("已", option, "搜图显示图片"))
})
}

View File

@@ -1,152 +0,0 @@
// Package scale 叔叔的AI二次元图片放大
package scale
import (
"bytes"
"image"
"math"
"os"
"strconv"
"time"
_ "image/gif" // import gif decoding
_ "image/jpeg" // import jpg decoding
_ "image/png" // import png decoding
_ "golang.org/x/image/webp" // import webp decoding
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/FloatTech/AnimeAPI/nsfw"
"github.com/FloatTech/AnimeAPI/scale"
"github.com/FloatTech/imgfactory"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
)
func init() {
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "二次元图片放大",
Help: "- 放大图片[图片]",
PrivateDataFolder: "scale",
}).ApplySingle(ctxext.DefaultSingle)
cachedir := engine.DataFolder()
// 上传一张图进行评价
engine.OnKeywordGroup([]string{"放大图片"}, zero.OnlyGroup, zero.MustProvidePicture, getPara).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
url := ctx.State["image_url"].([]string)
if len(url) > 0 {
datachan := make(chan []byte, 1)
var errsub error
go func() {
var d []byte
d, errsub = web.GetData(url[0])
datachan <- d
}()
ctx.SendChain(message.Text("少女祈祷中..."))
p, err := nsfw.Classify(url[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if p.Drawings < 0.1 || p.Neutral > 0.8 {
ctx.SendChain(message.Text("请发送二次元图片!"))
return
}
data := <-datachan
if errsub != nil {
ctx.SendChain(message.Text("ERROR: ", errsub))
return
}
im, _, err := image.Decode(bytes.NewReader(data))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
px := im.Bounds().Size().X * im.Bounds().Size().Y
paras := ctx.State["scale_paras"].([2]int)
if px > 512*512 {
px = int(math.Pow(float64(px), 0.5) + 0.5)
x := im.Bounds().Size().X * 512 / px
y := im.Bounds().Size().Y * 512 / px
ctx.SendChain(message.Text("图片", im.Bounds().Size().X, "x", im.Bounds().Size().Y, "过大,调整图片至", x, "x", y))
im = imgfactory.Size(im, x, y).Image()
w := binary.SelectWriter()
defer binary.PutWriter(w)
_, err = imgfactory.WriteTo(im, w)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
data, err = scale.Post(bytes.NewReader(w.Bytes()), paras[0], paras[1], 2)
} else {
data, err = scale.Get(url[0], paras[0], paras[1], 2)
}
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
n := cachedir + strconv.Itoa(int(ctx.Event.UserID))
f, err := os.Create(n)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
_, _ = f.Write(data)
_ = f.Close()
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + n))
}
})
}
func getPara(ctx *zero.Ctx) bool {
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession())
recv, cancel := next.Repeat()
i := 0
paras := [2]int{}
ctx.SendChain(message.Text("请输入模型序号\n0.", scale.Models[0], "\n1.", scale.Models[1], "\n2.", scale.Models[2], "\n3.", scale.Models[3], "\n4.", scale.Models[4]))
for {
select {
case <-time.After(time.Second * 120):
cancel()
return false
case c := <-recv:
msg := c.Event.Message.ExtractPlainText()
num, err := strconv.Atoi(msg)
if err != nil {
ctx.SendChain(message.Text("请输入数字!"))
continue
}
switch i {
case 0:
if num < 0 || num > 4 {
ctx.SendChain(message.Text("模型序号非法!"))
continue
}
paras[0] = num
ctx.SendChain(message.Text("请输入放大倍数(2-4)"))
case 1:
if num < 2 || num > 4 {
ctx.SendChain(message.Text("放大倍数非法!"))
continue
}
cancel()
paras[1] = num
ctx.State["scale_paras"] = paras
return true
}
i++
}
}
}

View File

@@ -11,6 +11,7 @@ import (
"sync"
"time"
"github.com/FloatTech/AnimeAPI/wallet"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/gg"
"github.com/FloatTech/imgfactory"
@@ -84,8 +85,8 @@ func drawScore16(a *scdata) (image.Image, error) {
return nil, err
}
canvas.DrawStringAnchored(hourWord, 350, 280, 0, 0)
canvas.DrawStringAnchored("ATRI币 + "+strconv.Itoa(a.inc), 350, 350, 0, 0)
canvas.DrawStringAnchored("当前ATRI币"+strconv.Itoa(a.score), 350, 400, 0, 0)
canvas.DrawStringAnchored(wallet.GetWalletName()+" + "+strconv.Itoa(a.inc), 350, 350, 0, 0)
canvas.DrawStringAnchored("当前"+wallet.GetWalletName()+""+strconv.Itoa(a.score), 350, 400, 0, 0)
canvas.DrawStringAnchored("LEVEL: "+strconv.Itoa(getrank(a.level)), 350, 450, 0, 0)
// draw Info(Time,etc.)
getTime := time.Now().Format("2006-01-02 15:04:05")
@@ -161,8 +162,8 @@ func drawScore15(a *scdata) (image.Image, error) {
if err = canvas.LoadFontFace(text.FontFile, float64(back.Bounds().Size().X)*0.04); err != nil {
return nil, err
}
canvas.DrawString(a.nickname+fmt.Sprintf(" ATRI币+%d", a.inc), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.3)
canvas.DrawString("当前ATRI币:"+strconv.FormatInt(int64(a.score), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.4)
canvas.DrawString(a.nickname+fmt.Sprintf(" %s+%d", wallet.GetWalletName(), a.inc), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.3)
canvas.DrawString("当前"+wallet.GetWalletName()+":"+strconv.FormatInt(int64(a.score), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.4)
canvas.DrawString("LEVEL:"+strconv.FormatInt(int64(a.rank), 10), float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.5)
canvas.DrawRectangle(float64(back.Bounds().Size().X)*0.1, float64(back.Bounds().Size().Y)*1.55, float64(back.Bounds().Size().X)*0.6, float64(back.Bounds().Size().Y)*0.1)
canvas.SetRGB255(150, 150, 150)
@@ -247,8 +248,8 @@ func drawScore17(a *scdata) (image.Image, error) {
if err = canvas.ParseFontFace(data, 20); err != nil {
return nil, err
}
canvas.DrawStringAnchored("ATRI币 + "+strconv.Itoa(a.inc), 40, float64(imgDY-90), 0, 0)
canvas.DrawStringAnchored("当前ATRI币"+strconv.Itoa(a.score), 40, float64(imgDY-60), 0, 0)
canvas.DrawStringAnchored(wallet.GetWalletName()+" + "+strconv.Itoa(a.inc), 40, float64(imgDY-90), 0, 0)
canvas.DrawStringAnchored("当前"+wallet.GetWalletName()+""+strconv.Itoa(a.score), 40, float64(imgDY-60), 0, 0)
canvas.DrawStringAnchored("LEVEL: "+strconv.Itoa(getrank(a.level)), 40, float64(imgDY-30), 0, 0)
// Draw Info(Time, etc.)
@@ -477,7 +478,7 @@ func customtext(a *scdata, fontdata []byte, cw, ch, aw float64, textcolor color.
return
}
canvas.DrawStringAnchored("ATRI币 + "+strconv.Itoa(a.inc), ((cw-scw)-(cw/3-scw/2))/8, (ch-sch)/2+sch/4+tempfh, 0, 0.5)
canvas.DrawStringAnchored(wallet.GetWalletName()+" + "+strconv.Itoa(a.inc), ((cw-scw)-(cw/3-scw/2))/8, (ch-sch)/2+sch/4+tempfh, 0, 0.5)
canvas.DrawStringAnchored("EXP + 1", ((cw-scw)-(cw/3-scw/2))/8, (ch-sch)/2+sch/4+tempfh+canvas.FontHeight(), 0, 1)
err = canvas.ParseFontFace(fontdata, (ch-sch)/2/4)
@@ -485,7 +486,7 @@ func customtext(a *scdata, fontdata []byte, cw, ch, aw float64, textcolor color.
return
}
canvas.DrawStringAnchored("你有 "+strconv.Itoa(a.score)+" 枚ATRI币", ((cw-scw)-(cw/3-scw/2))/8, (ch-sch)/2+sch/4*3, 0, 0.5)
canvas.DrawStringAnchored("你有 "+strconv.Itoa(a.score)+" 枚"+wallet.GetWalletName(), ((cw-scw)-(cw/3-scw/2))/8, (ch-sch)/2+sch/4*3, 0, 0.5)
img = canvas.Image()
return

View File

@@ -2,6 +2,8 @@
package score
import (
"encoding/base64"
"io"
"math"
"math/rand"
"os"
@@ -106,7 +108,7 @@ func init() {
// 如果签到时间是今天
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("今天你已经签到过了!"))
if file.IsExist(drawedFile) {
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
trySendImage(drawedFile, ctx)
}
return
case siUpdateTimeStr != today:
@@ -137,13 +139,11 @@ func init() {
// 更新钱包
rank := getrank(level)
add := 1 + rand.Intn(10) + rank*5 // 等级越高获得的钱越高
go func() {
err = wallet.InsertWalletOf(uid, add)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
}()
err = wallet.InsertWalletOf(uid, add)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
alldata := &scdata{
drawedfile: drawedFile,
picfile: picFile,
@@ -176,7 +176,7 @@ func init() {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
trySendImage(drawedFile, ctx)
})
engine.OnPrefix("获得签到背景", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
@@ -193,16 +193,14 @@ func init() {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请先签到!"))
return
}
if id := ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + picFile)); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 消息发送失败, 账号可能被风控"))
}
trySendImage(picFile, ctx)
})
engine.OnFullMatch("查看等级排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
today := time.Now().Format("20060102")
drawedFile := cachePath + today + "scoreRank.png"
if file.IsExist(drawedFile) {
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
trySendImage(drawedFile, ctx)
return
}
st, err := sdb.GetScoreRankByTopN(10)
@@ -267,7 +265,7 @@ func init() {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
trySendImage(drawedFile, ctx)
})
engine.OnRegex(`^设置签到预设\s*(\d+)$`, zero.SuperUserPermission).Limit(ctxext.LimitByUser).SetBlock(true).Handle(func(ctx *zero.Ctx) {
key := ctx.State["regex_matched"].([]string)[1]
@@ -325,7 +323,7 @@ func getrank(count int) int {
func initPic(picFile string, uid int64) (avatar []byte, err error) {
defer process.SleepAbout1sTo2s()
avatar, err = web.GetData("http://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640")
avatar, err = web.GetData("https://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640")
if err != nil {
return
}
@@ -342,3 +340,32 @@ func initPic(picFile string, uid int64) (avatar []byte, err error) {
}
return avatar, os.WriteFile(picFile, data, 0644)
}
// 使用"file:"发送图片失败后改用base64发送
func trySendImage(filePath string, ctx *zero.Ctx) {
filePath = file.BOTPATH + "/" + filePath
if id := ctx.SendChain(message.Image("file:///" + filePath)); id.ID() != 0 {
return
}
imgFile, err := os.Open(filePath)
if err != nil {
ctx.SendChain(message.Text("ERROR: 无法打开文件", err))
return
}
defer imgFile.Close()
// 使用 base64.NewEncoder 将文件内容编码为 base64 字符串
var encodedFileData strings.Builder
encodedFileData.WriteString("base64://")
encoder := base64.NewEncoder(base64.StdEncoding, &encodedFileData)
_, err = io.Copy(encoder, imgFile)
if err != nil {
ctx.SendChain(message.Text("ERROR: 无法编码文件内容", err))
return
}
encoder.Close()
drawedFileBase64 := encodedFileData.String()
if id := ctx.SendChain(message.Image(drawedFileBase64)); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 无法读取图片文件", err))
return
}
}

View File

@@ -57,14 +57,14 @@ func init() {
return
}
// 收集这波用户的streamId然后查当前的状态并建立信息映射表
streamIds := make([]string, len(infos))
streamIDs := make([]string, len(infos))
localPlayerMap := make(map[int64]*player)
for i := 0; i < len(infos); i++ {
streamIds[i] = strconv.FormatInt(infos[i].SteamID, 10)
streamIDs[i] = strconv.FormatInt(infos[i].SteamID, 10)
localPlayerMap[infos[i].SteamID] = infos[i]
}
// 将所有用户状态查一遍
playerStatus, err := getPlayerStatus(streamIds...)
playerStatus, err := getPlayerStatus(streamIDs...)
if err != nil {
// 出错就发消息
ctx.SendPrivateMessage(su, message.Text("[steam] ERROR: ", err))
@@ -117,11 +117,11 @@ func init() {
}
// getPlayerStatus 获取用户状态
func getPlayerStatus(streamIds ...string) ([]*player, error) {
func getPlayerStatus(streamIDs ...string) ([]*player, error) {
players := make([]*player, 0)
// 拼接请求地址
apiKeyMu.Lock()
url := fmt.Sprintf(apiurl+statusurl, apiKey, strings.Join(streamIds, ","))
url := fmt.Sprintf(apiurl+statusurl, apiKey, strings.Join(streamIDs, ","))
apiKeyMu.Unlock()
// 拉取并解析数据
data, err := web.GetData(url)

View File

@@ -178,7 +178,7 @@ func init() {
engine.OnMessage(canmatch(tKAWA), match(chatListK, seg)).
SetBlock(false).
Handle(randreply(sm.K))
engine.OnMessage(canmatch(tALPACA), func(ctx *zero.Ctx) bool {
engine.OnMessage(canmatch(tALPACA), func(_ *zero.Ctx) bool {
return alpacapiurl != "" && alpacatoken != ""
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
msg := ctx.ExtractPlainText()

View File

@@ -1,321 +0,0 @@
// Package vtbmusic vtb点歌
package vtbmusic
import (
"encoding/json"
"fmt"
"math/rand"
"net/http"
"os"
"path"
"strconv"
"strings"
"time"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/img/text"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
getGroupListURL = "https://aqua.chat/v1/GetGroupsList"
getMusicListURL = "https://aqua.chat/v1/GetMusicList"
fileURL = "https://cdn.aqua.chat/"
musicListBody = `{"search":{"condition":"VocalId","keyword":"%v"},"sortField":"CreateTime","sortType":"desc","pageIndex":1,"pageRows":10000}`
)
type groupsList struct {
Total int `json:"Total"`
Data []struct {
ID string `json:"Id"`
CreateTime string `json:"CreateTime"`
Name string `json:"Name"`
GroupImg string `json:"GroupImg"`
VocalList []struct {
ID string `json:"Id"`
CreateTime string `json:"CreateTime"`
ChineseName string `json:"ChineseName"`
OriginName string `json:"OriginName"`
AvatarImg string `json:"AvatarImg"`
} `json:"VocalList"`
} `json:"Data"`
Success bool `json:"Success"`
ErrorCode int `json:"ErrorCode"`
Msg interface{} `json:"Msg"`
}
type musicList struct {
Total int `json:"Total"`
Data []struct {
ID string `json:"Id"`
CreateTime string `json:"CreateTime"`
PublishTime interface{} `json:"PublishTime"`
CreatorID interface{} `json:"CreatorId"`
CreatorRealName interface{} `json:"CreatorRealName"`
Deleted bool `json:"Deleted"`
OriginName string `json:"OriginName"`
VocalID string `json:"VocalId"`
VocalName string `json:"VocalName"`
CoverImg string `json:"CoverImg"`
Music string `json:"Music"`
Lyric interface{} `json:"Lyric"`
CDN string `json:"CDN"`
BiliBili interface{} `json:"BiliBili"`
YouTube interface{} `json:"YouTube"`
Twitter interface{} `json:"Twitter"`
Likes interface{} `json:"Likes"`
Length float64 `json:"Length"`
Label interface{} `json:"Label"`
IsLike bool `json:"isLike"`
Duration float64 `json:"Duration"`
Source interface{} `json:"Source"`
SourceName interface{} `json:"SourceName"`
Statis struct {
PlayCount int `json:"PlayCount"`
CommentCount int `json:"CommentCount"`
LikeCount int `json:"LikeCount"`
ShareCount int `json:"ShareCount"`
} `json:"Statis"`
VocalList []struct {
ID string `json:"Id"`
Cn string `json:"cn"`
Jp string `json:"jp"`
En string `json:"en"`
Originlang string `json:"originlang"`
} `json:"VocalList"`
} `json:"Data"`
Success bool `json:"Success"`
ErrorCode int `json:"ErrorCode"`
Msg interface{} `json:"Msg"`
}
func init() { // 插件主体
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "vtbmusic.com点歌",
Help: "- vtb点歌\n" +
"- vtb随机点歌",
PrivateDataFolder: "vtbmusic",
})
storePath := engine.DataFolder()
// 开启
engine.OnFullMatch(`vtb点歌`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession(), zero.RegexRule(`^\d+$`))
recv, cancel := next.Repeat()
defer cancel()
i := 0
paras := [3]int{}
data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
var (
gl groupsList
ml musicList
num int
imageBytes []byte
)
err = json.Unmarshal(data, &gl)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
tex := "请输入群组序号\n"
for i, v := range gl.Data {
tex += fmt.Sprintf("%d. %s\n", i, v.Name)
}
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
for {
select {
case <-time.After(time.Second * 120):
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb点歌超时"))
return
case c := <-recv:
msg := c.Event.Message.ExtractPlainText()
num, err = strconv.Atoi(msg)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请输入数字!"))
continue
}
switch i {
case 0:
if num < 0 || num >= len(gl.Data) {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
continue
}
if len(gl.Data[num].VocalList) == 0 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败"))
return
}
paras[0] = num
tex = "请输入vtb序号\n"
for i, v := range gl.Data[paras[0]].VocalList {
tex += fmt.Sprintf("%d. %s\n", i, v.OriginName)
}
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
case 1:
if num < 0 || num >= len(gl.Data[paras[0]].VocalList) {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
continue
}
paras[1] = num
data, err := web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = json.Unmarshal(data, &ml)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if len(ml.Data) == 0 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无内容, 点歌失败"))
return
}
tex = "请输入歌曲序号\n"
for i, v := range ml.Data {
tex += fmt.Sprintf("%d. %s\n", i, v.OriginName)
}
imageBytes, err = text.RenderToBase64(tex, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+binary.BytesToString(imageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
case 2:
if num < 0 || num >= len(ml.Data) {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("序号非法!"))
continue
}
paras[2] = num
// 最后播放歌曲
groupName := gl.Data[paras[0]].Name
vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName
musicName := ml.Data[paras[2]].OriginName
recURL := fileURL + ml.Data[paras[2]].Music
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》"))
recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL)
if file.IsExist(recordFile) {
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
err = dlrec(recordFile, recURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
i++
}
}
})
engine.OnFullMatch(`vtb随机点歌`).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
var (
paras = [3]int{}
gl groupsList
ml musicList
)
data, err := web.PostData(getGroupListURL, "application/json", strings.NewReader(`{"PageIndex":1,"PageRows":9999}`))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = json.Unmarshal(data, &gl)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if len(gl.Data) == 0 {
ctx.SendChain(message.Text("ERROR: 数组为空"))
return
}
paras[0] = rand.Intn(len(gl.Data))
for len(gl.Data[paras[0]].VocalList) == 0 {
paras[0] = rand.Intn(len(gl.Data))
}
paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList))
data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = json.Unmarshal(data, &ml)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
for len(ml.Data) == 0 {
paras[1] = rand.Intn(len(gl.Data[paras[0]].VocalList))
data, err = web.PostData(getMusicListURL, "application/json", strings.NewReader(fmt.Sprintf(musicListBody, gl.Data[paras[0]].VocalList[paras[1]].ID)))
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
err = json.Unmarshal(data, &ml)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
}
paras[2] = rand.Intn(len(ml.Data))
// 最后播放歌曲
groupName := gl.Data[paras[0]].Name
vtbName := gl.Data[paras[0]].VocalList[paras[1]].OriginName
musicName := ml.Data[paras[2]].OriginName
recURL := fileURL + ml.Data[paras[2]].Music
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏", groupName, "-", vtbName, "的《", musicName, "》"))
recordFile := storePath + fmt.Sprintf("%d-%d-%d", paras[0], paras[1], paras[2]) + path.Ext(recURL)
if file.IsExist(recordFile) {
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
err = dlrec(recordFile, recURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
})
}
func dlrec(recordFile, recordURL string) error {
if file.IsNotExist(recordFile) {
data, err := web.RequestDataWithHeaders(web.NewTLS12Client(), recordURL, "GET", func(r *http.Request) error {
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
r.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0")
return nil
}, nil)
if err != nil {
return err
}
return os.WriteFile(recordFile, data, 0666)
}
return nil
}

View File

@@ -1,325 +0,0 @@
// Package model vtb数据库操作
package model
import (
"io"
"math/rand"
"net/http"
"os"
"strconv"
"strings"
"github.com/FloatTech/floatbox/web"
"github.com/jinzhu/gorm"
log "github.com/sirupsen/logrus"
"github.com/tidwall/gjson"
)
// VtbDB vtb 数据库
type VtbDB gorm.DB
// Initialize ...
func Initialize(dbpath string) *VtbDB {
var err error
if _, err = os.Stat(dbpath); err != nil || os.IsNotExist(err) {
// 生成文件
f, err := os.Create(dbpath)
if err != nil {
return nil
}
defer f.Close()
}
gdb, err := gorm.Open("sqlite3", dbpath)
if err != nil {
panic(err)
}
gdb.AutoMigrate(FirstCategory{}).AutoMigrate(SecondCategory{}).AutoMigrate(ThirdCategory{})
return (*VtbDB)(gdb)
}
// Open ...
func Open(dbpath string) (*VtbDB, error) {
db, err := gorm.Open("sqlite3", dbpath)
if err != nil {
return nil, err
}
return (*VtbDB)(db), nil
}
// FirstCategory 第一品类
type FirstCategory struct {
gorm.Model
FirstCategoryIndex int64 `gorm:"column:first_category_index"`
FirstCategoryName string `gorm:"column:first_category_name"`
FirstCategoryUID string `gorm:"column:first_category_uid"`
FirstCategoryDescription string `gorm:"column:first_category_description;type:varchar(1024)"`
FirstCategoryIconPath string `gorm:"column:first_category_icon_path"`
}
// TableName ...
func (FirstCategory) TableName() string {
return "first_category"
}
// SecondCategory 第二品类
type SecondCategory struct {
gorm.Model
SecondCategoryIndex int64 `gorm:"column:second_category_index"`
FirstCategoryUID string `gorm:"column:first_category_uid;association_foreignkey:first_category_uid"`
SecondCategoryName string `gorm:"column:second_category_name"`
SecondCategoryAuthor string `gorm:"column:second_category_author"`
SecondCategoryDescription string `gorm:"column:second_category_description"`
}
// TableName ...
func (SecondCategory) TableName() string {
return "second_category"
}
// ThirdCategory 第三品类
type ThirdCategory struct {
gorm.Model
ThirdCategoryIndex int64 `gorm:"column:third_category_index"`
SecondCategoryIndex int64 `gorm:"column:second_category_index"`
FirstCategoryUID string `gorm:"column:first_category_uid"`
ThirdCategoryName string `gorm:"column:third_category_name"`
ThirdCategoryPath string `gorm:"column:third_category_path"`
ThirdCategoryAuthor string `gorm:"column:third_category_author"`
ThirdCategoryDescription string `gorm:"column:third_category_description"`
}
// TableName ...
func (ThirdCategory) TableName() string {
return "third_category"
}
// GetAllFirstCategoryMessage 取出所有vtb
func (vdb *VtbDB) GetAllFirstCategoryMessage() (string, error) {
db := (*gorm.DB)(vdb)
firstStepMessage := "请选择一个vtb并发送序号:\n"
var fcl []FirstCategory
err := db.Model(&FirstCategory{}).Find(&fcl).Error
if err != nil {
return "", err
}
for _, v := range fcl {
firstStepMessage += strconv.FormatInt(v.FirstCategoryIndex, 10) + ". " + v.FirstCategoryName + "\n"
}
return firstStepMessage, nil
}
// GetAllSecondCategoryMessageByFirstIndex 取得同一个vtb所有语录类别
func (vdb *VtbDB) GetAllSecondCategoryMessageByFirstIndex(firstIndex int) (string, error) {
db := (*gorm.DB)(vdb)
secondStepMessage := "请选择一个语录类别并发送序号:\n"
var scl []SecondCategory
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
err := db.Model(&SecondCategory{}).Find(&scl, "first_category_uid = ?", fc.FirstCategoryUID).Error
if err != nil || len(scl) == 0 {
return "", err
}
for _, v := range scl {
secondStepMessage += strconv.FormatInt(v.SecondCategoryIndex, 10) + ". " + v.SecondCategoryName + "\n"
}
return secondStepMessage, nil
}
// GetAllThirdCategoryMessageByFirstIndexAndSecondIndex 取得同一个vtb同个类别的所有语录
func (vdb *VtbDB) GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(firstIndex, secondIndex int) (string, error) {
db := (*gorm.DB)(vdb)
thirdStepMessage := "请选择一个语录并发送序号:\n"
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
var tcl []ThirdCategory
err := db.Model(&ThirdCategory{}).Find(&tcl, "first_category_uid = ? and second_category_index = ?", fc.FirstCategoryUID, secondIndex).Error
if err != nil || len(tcl) == 0 {
return "", err
}
for _, v := range tcl {
thirdStepMessage = thirdStepMessage + strconv.FormatInt(v.ThirdCategoryIndex, 10) + ". " + v.ThirdCategoryName + "\n"
}
return thirdStepMessage, nil
}
// GetThirdCategory ...
func (vdb *VtbDB) GetThirdCategory(firstIndex, secondIndex, thirdIndex int) ThirdCategory {
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Where("first_category_index = ?", firstIndex).First(&fc)
var tc ThirdCategory
db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?", fc.FirstCategoryUID, secondIndex, thirdIndex).Take(&tc)
return tc
}
// RandomVtb ...
func (vdb *VtbDB) RandomVtb() ThirdCategory {
db := (*gorm.DB)(vdb)
var count int
var tc ThirdCategory
db.Model(&ThirdCategory{}).Count(&count).Offset(rand.Intn(count)).Take(&tc)
return tc
}
// GetFirstCategoryByFirstUID ...
func (vdb *VtbDB) GetFirstCategoryByFirstUID(firstUID string) FirstCategory {
db := (*gorm.DB)(vdb)
var fc FirstCategory
db.Model(FirstCategory{}).Take(&fc, "first_category_uid = ?", firstUID)
return fc
}
// Close ...
func (vdb *VtbDB) Close() error {
db := (*gorm.DB)(vdb)
return db.Close()
}
const vtbURL = "https://vtbkeyboard.moe/api/get_vtb_list"
// GetVtbList ...
func (vdb *VtbDB) GetVtbList() (uidList []string, err error) {
db := (*gorm.DB)(vdb)
client := &http.Client{}
req, err := http.NewRequest("GET", vtbURL, nil)
if err != nil {
return
}
// 自定义Header
req.Header.Set("User-Agent", web.RandUA())
resp, err := client.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return
}
vtbListStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`))
if err != nil {
return
}
count := gjson.Get(vtbListStr, "#").Int()
for i := int64(0); i < count; i++ {
item := gjson.Get(vtbListStr, strconv.FormatInt(i, 10))
log.Debugln(item)
fc := FirstCategory{
FirstCategoryIndex: i,
FirstCategoryName: item.Get("name").String(),
FirstCategoryDescription: item.Get("description").String(),
FirstCategoryIconPath: item.Get("icon_path").String(),
FirstCategoryUID: item.Get("uid").String(),
}
log.Debugln(fc)
if err := db.Model(&FirstCategory{}).First(&fc, "first_category_uid = ?", fc.FirstCategoryUID).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
db.Model(&FirstCategory{}).Create(&fc) // newUser not user
}
} else {
db.Model(&FirstCategory{}).Where("first_category_uid = ?", fc.FirstCategoryUID).Update(
map[string]any{
"first_category_index": i,
"first_category_name": item.Get("name").String(),
"first_category_description": item.Get("description").String(),
"first_category_icon_path": item.Get("icon_path").String(),
})
}
uidList = append(uidList, fc.FirstCategoryUID)
}
return
}
// StoreVtb ...
func (vdb *VtbDB) StoreVtb(uid string) (err error) {
db := (*gorm.DB)(vdb)
vtbURL := "https://vtbkeyboard.moe/api/get_vtb_page?uid=" + uid
client := &http.Client{}
req, err := http.NewRequest("GET", vtbURL, nil)
if err != nil {
return
}
// 自定义Header
req.Header.Set("User-Agent", web.RandUA())
resp, err := client.Do(req)
if err != nil {
return
}
defer resp.Body.Close()
bytes, err := io.ReadAll(resp.Body)
if err != nil {
return
}
vtbStr, err := strconv.Unquote(strings.ReplaceAll(strconv.Quote(string(bytes)), `\\u`, `\u`))
if err != nil {
return
}
secondCount := gjson.Get(vtbStr, "data.voices.#").Int()
log.Debugln("二级品类一共有", secondCount)
for secondIndex := int64(0); secondIndex < secondCount; secondIndex++ {
secondItem := gjson.Get(vtbStr, "data.voices."+strconv.FormatInt(secondIndex, 10))
log.Debugln(secondItem)
sc := SecondCategory{
SecondCategoryName: secondItem.Get("categoryName").String(),
SecondCategoryIndex: secondIndex,
SecondCategoryAuthor: secondItem.Get("author").String(),
SecondCategoryDescription: secondItem.Get("categoryDescription.zh-CN").String(),
FirstCategoryUID: uid,
}
if err := db.Model(&SecondCategory{}).First(&sc, "first_category_uid = ? and second_category_index = ?", uid, secondIndex).Error; err != nil {
// error handling...
if gorm.IsRecordNotFoundError(err) {
db.Model(&SecondCategory{}).Create(&sc) // newUser not user
}
} else {
db.Model(&SecondCategory{}).Where("first_category_uid = ? and second_category_index = ?", uid, secondIndex).Update(
map[string]any{
"second_category_name": secondItem.Get("categoryName").String(),
"second_category_author": secondItem.Get("author").String(),
"second_category_description": secondItem.Get("categoryDescription.zh-CN").String(),
})
}
thirdCount := secondItem.Get("voiceList.#").Int()
log.Debugln("三级品类一共有", thirdCount)
for thirdIndex := int64(0); thirdIndex < thirdCount; thirdIndex++ {
thirdItem := secondItem.Get("voiceList." + strconv.FormatInt(thirdIndex, 10))
log.Debugln(thirdItem)
tc := ThirdCategory{
ThirdCategoryName: thirdItem.Get("name").String(),
ThirdCategoryIndex: thirdIndex,
ThirdCategoryDescription: thirdItem.Get("description.zh-CN").String(),
FirstCategoryUID: uid,
SecondCategoryIndex: secondIndex,
ThirdCategoryPath: thirdItem.Get("path").String(),
ThirdCategoryAuthor: thirdItem.Get("author").String(),
}
log.Debugln(tc)
if err := db.Model(&ThirdCategory{}).First(&tc, "first_category_uid = ? and second_category_index = ? and third_category_index = ?",
uid, secondIndex, thirdIndex).Error; err != nil {
if gorm.IsRecordNotFoundError(err) {
db.Model(&ThirdCategory{}).Create(&tc) // newUser not user
}
} else {
db.Model(&ThirdCategory{}).Where("first_category_uid = ? and second_category_index = ? and third_category_index = ?",
uid, secondIndex, thirdIndex).Update(
map[string]any{
"third_category_name": thirdItem.Get("name").String(),
"third_category_description": thirdItem.Get("description.zh-CN").String(),
"third_category_path": thirdItem.Get("path").String(),
"third_category_author": thirdItem.Get("author").String(),
})
}
}
}
return
}

View File

@@ -1,297 +0,0 @@
// Package vtbquotation vtb经典语录
package vtbquotation
import (
"fmt"
"io"
"net/http"
"net/url"
"os"
"path"
"regexp"
"strconv"
"strings"
"time"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
fcext "github.com/FloatTech/floatbox/ctxext"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/img/text"
"github.com/FloatTech/ZeroBot-Plugin/plugin/vtbquotation/model"
)
var reg = regexp.MustCompile(".*/(.*)")
func init() {
engine := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "vtb语录",
Help: "- vtb语录\n- 随机vtb\n- 更新vtb\n来源: vtbkeyboard.moe",
PublicDataFolder: "VtbQuotation",
})
dbfile := engine.DataFolder() + "vtb.db"
storePath := engine.DataFolder() + "store/"
getdb := fcext.DoOnceOnSuccess(func(ctx *zero.Ctx) bool {
err := os.MkdirAll(storePath, 0755)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
_, err = engine.GetLazyData("vtb.db", false)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return false
}
return true
})
engine.OnFullMatch("vtb语录", getdb).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
indexs := [3]int{}
echo, cancel := ctx.FutureEvent("message",
ctx.CheckSession()). // 只复读开启复读模式的人的消息
Repeat() // 不断监听复读
db, err := model.Open(dbfile)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
defer db.Close()
defer cancel()
r, err := db.GetAllFirstCategoryMessage()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
// 步骤012依次选择3个类别
step := 0
// 错误次数
errorCount := 0
for {
select {
case c := <-echo: // 接收到需要复读的消息
// 错误次数达到3次结束命令
if errorCount >= 3 {
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("输入错误太多,请重新发指令"))
return
}
msg := c.Event.Message.ExtractPlainText()
num, err := strconv.Atoi(msg)
if err != nil {
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("请输入正确的序号,三次输入错误,指令可退出重输"))
errorCount++
continue
}
switch step {
case 0:
indexs[0] = num
secondStepMessage, err := db.GetAllSecondCategoryMessageByFirstIndex(indexs[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if secondStepMessage == "" {
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输"))
r, err := db.GetAllFirstCategoryMessage()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
} else {
secondStepMessageBytes, err := text.RenderToBase64(secondStepMessage, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
step++
}
case 1:
indexs[1] = num
thirdStepMessage, err := db.GetAllThirdCategoryMessageByFirstIndexAndSecondIndex(indexs[0], indexs[1])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if thirdStepMessage == "" {
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("你选择的序号没有内容,请重新选择,三次输入错误,指令可退出重输"))
r, err := db.GetAllSecondCategoryMessageByFirstIndex(indexs[0])
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
secondStepMessageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(secondStepMessageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
} else {
thirdStepMessageBytes, err := text.RenderToBase64(thirdStepMessage, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(thirdStepMessageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
step++
}
case 2:
indexs[2] = num
tc := db.GetThirdCategory(indexs[0], indexs[1], indexs[2])
recURL := tc.ThirdCategoryPath
if recURL == "" {
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("没有内容请重新选择,三次输入错误,指令可退出重输"))
r, err := db.GetAllFirstCategoryMessage()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
firstStepImageBytes, err := text.RenderToBase64(r, text.FontFile, 400, 20)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
if id := ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Image("base64://"+helper.BytesToString(firstStepImageBytes))); id.ID() == 0 {
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
}
errorCount++
step = 1
} else {
if reg.MatchString(recURL) {
recURL = strings.ReplaceAll(recURL, reg.FindStringSubmatch(recURL)[1], url.QueryEscape(reg.FindStringSubmatch(recURL)[1]))
recURL = strings.ReplaceAll(recURL, "+", "%20")
}
ctx.SendChain(message.Reply(c.Event.MessageID), message.Text("请欣赏《"+tc.ThirdCategoryName+"》"))
recordFile := storePath + fmt.Sprintf("%d-%d-%d", indexs[0], indexs[1], indexs[2]) + path.Ext(recURL)
if file.IsExist(recordFile) {
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
err = initRecord(recordFile, recURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
default:
return
}
case <-time.After(time.Second * 60):
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("vtb语录指令过期"))
return
}
}
})
engine.OnFullMatch("随机vtb", getdb).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
db, err := model.Open(dbfile)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
defer db.Close()
tc := db.RandomVtb()
fc := db.GetFirstCategoryByFirstUID(tc.FirstCategoryUID)
if (tc != model.ThirdCategory{}) && (fc != model.FirstCategory{}) {
recURL := tc.ThirdCategoryPath
if reg.MatchString(recURL) {
recURL = strings.ReplaceAll(recURL, reg.FindStringSubmatch(recURL)[1], url.QueryEscape(reg.FindStringSubmatch(recURL)[1]))
recURL = strings.ReplaceAll(recURL, "+", "%20")
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("请欣赏"+fc.FirstCategoryName+"的《"+tc.ThirdCategoryName+"》"))
recordFile := storePath + fmt.Sprintf("%d-%d-%d", fc.FirstCategoryIndex, tc.SecondCategoryIndex, tc.ThirdCategoryIndex) + path.Ext(recURL)
if file.IsExist(recordFile) {
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
return
}
err = initRecord(recordFile, recURL)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + recordFile))
}
})
engine.OnFullMatch("更新vtb", zero.SuperUserPermission, getdb).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
ctx.Send("少女祈祷中......")
db := model.Initialize(dbfile)
if db != nil {
vl, err := db.GetVtbList()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
for _, v := range vl {
err = db.StoreVtb(v)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
}
err = db.Close()
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
}
ctx.Send("vtb数据库已更新")
})
}
func initRecord(recordFile, recordURL string) error {
if file.IsNotExist(recordFile) {
client := web.NewTLS12Client()
req, _ := http.NewRequest("GET", recordURL, nil)
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0")
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
data, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
err = os.WriteFile(recordFile, data, 0666)
if err != nil {
return err
}
}
return nil
}

View File

@@ -4,10 +4,13 @@ package wallet
import (
"math"
"os"
"regexp"
"strconv"
"strings"
"time"
"github.com/FloatTech/AnimeAPI/wallet"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/file"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
@@ -21,24 +24,38 @@ import (
func init() {
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "钱包",
Help: "- 查看我的钱包\n- 查看钱包排名",
DisableOnDefault: false,
Brief: "钱包",
Help: "- 查看钱包排名\n" +
"- 设置硬币名称XX\n" +
"- 管理钱包余额[+金额|-金额][@xxx]\n" +
"- 查看我的钱包|查看钱包余额[@xxx]\n" +
"- 钱包转账[金额][@xxx]\n" +
"注:仅超级用户能“管理钱包余额”\n",
PrivateDataFolder: "wallet",
})
cachePath := en.DataFolder() + "cache/"
coinNameFile := en.DataFolder() + "coin_name.txt"
go func() {
_ = os.RemoveAll(cachePath)
err := os.MkdirAll(cachePath, 0755)
if err != nil {
panic(err)
}
// 更改硬币名称
var coinName string
if file.IsExist(coinNameFile) {
content, err := os.ReadFile(coinNameFile)
if err != nil {
panic(err)
}
coinName = binary.BytesToString(content)
} else {
// 旧版本数据
coinName = "ATRI币"
}
wallet.SetWalletName(coinName)
}()
en.OnFullMatch("查看我的钱包").SetBlock(true).Handle(func(ctx *zero.Ctx) {
uid := ctx.Event.UserID
money := wallet.GetWalletOf(uid)
ctx.SendChain(message.At(uid), message.Text("你的钱包当前有", money, "ATRI币"))
})
en.OnFullMatch("查看钱包排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
@@ -62,7 +79,7 @@ func init() {
return
}
if len(st) == 0 {
ctx.SendChain(message.Text("ERROR: 当前没人获取过ATRI币"))
ctx.SendChain(message.Text("ERROR: 当前没人获取过", wallet.GetWalletName()))
return
} else if len(st) > 10 {
st = st[:10]
@@ -98,7 +115,7 @@ func init() {
}
err = chart.BarChart{
Font: font,
Title: "ATRI币排名(1天只刷新1次)",
Title: wallet.GetWalletName() + "排名(1天只刷新1次)",
Background: chart.Style{
Padding: chart.Box{
Top: 40,
@@ -122,4 +139,119 @@ func init() {
}
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
})
en.OnPrefix("设置硬币名称", zero.OnlyToMe, zero.SuperUserPermission).SetBlock(true).
Handle(func(ctx *zero.Ctx) {
coinName := strings.TrimSpace(ctx.State["args"].(string))
err := os.WriteFile(coinNameFile, binary.StringToBytes(coinName), 0644)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
wallet.SetWalletName(coinName)
ctx.SendChain(message.Text("记住啦~"))
})
en.OnPrefix(`管理钱包余额`, zero.SuperUserPermission).SetBlock(true).Limit(ctxext.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
param := strings.TrimSpace(ctx.State["args"].(string))
// 捕获修改的金额
re := regexp.MustCompile(`^[+-]?\d+$`)
amount, err := strconv.Atoi(re.FindString(param))
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("输入的金额异常"))
return
}
// 捕获用户QQ号只支持@事件
var uidStr string
if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" {
uidStr = ctx.Event.Message[1].Data["qq"]
} else {
// 没at就修改自己的钱包
uidStr = strconv.FormatInt(ctx.Event.UserID, 10)
}
uidInt, err := strconv.ParseInt(uidStr, 10, 64)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("QQ号处理失败"))
return
}
if amount+wallet.GetWalletOf(uidInt) < 0 {
ctx.SendChain(message.Text("管理失败:对方钱包余额不足,扣款失败"))
return
}
err = wallet.InsertWalletOf(uidInt, amount)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:管理失败,钱包坏掉了:\n", err))
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("钱包余额修改成功,已修改用户:", uidStr, "的钱包,修改金额为:", amount))
})
// 保留用户习惯,兼容旧语法“查看我的钱包”
en.OnPrefixGroup([]string{`查看钱包余额`, `查看我的钱包`}).SetBlock(true).Limit(ctxext.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
param := ctx.State["args"].(string)
var uidStr string
if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" {
uidStr = ctx.Event.Message[1].Data["qq"]
} else if param == "" {
uidStr = strconv.FormatInt(ctx.Event.UserID, 10)
}
uidInt, err := strconv.ParseInt(uidStr, 10, 64)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("QQ号处理失败"))
return
}
money := wallet.GetWalletOf(uidInt)
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("QQ号", uidStr, ",的钱包有", money, wallet.GetWalletName()))
})
en.OnPrefix(`钱包转账`, zero.OnlyGroup).SetBlock(true).Limit(ctxext.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
param := strings.TrimSpace(ctx.State["args"].(string))
// 捕获修改的金额,amount扣款金额恒正要注意符号
re := regexp.MustCompile(`^[+]?\d+$`)
amount, err := strconv.Atoi(re.FindString(param))
if err != nil || amount <= 0 {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("输入额异常请检查金额或at是否正常"))
return
}
// 捕获用户QQ号只支持@事件
var uidStr string
if len(ctx.Event.Message) > 1 && ctx.Event.Message[1].Type == "at" {
uidStr = ctx.Event.Message[1].Data["qq"]
} else {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("获取被转方信息失败"))
return
}
uidInt, err := strconv.ParseInt(uidStr, 10, 64)
if err != nil {
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("QQ号处理失败"))
return
}
// 开始转账流程
if amount > wallet.GetWalletOf(ctx.Event.UserID) {
ctx.SendChain(message.Text("[ERROR]:钱包余额不足,转账失败"))
return
}
err = wallet.InsertWalletOf(ctx.Event.UserID, -amount)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:转账失败,扣款异常:\n", err))
return
}
err = wallet.InsertWalletOf(uidInt, amount)
if err != nil {
ctx.SendChain(message.Text("[ERROR]:转账失败,转账时银行被打劫:\n", err))
return
}
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("转账成功:成功给"), message.At(uidInt), message.Text(",转账:", amount, wallet.GetWalletName()))
})
}

View File

@@ -1,34 +0,0 @@
// Package wangyiyun 网易云音乐热评
package wangyiyun
import (
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
)
const (
wangyiyunURL = "https://api.gmit.vip/Api/HotComments?format=text"
wangyiyunReferer = "https://api.gmit.vip/"
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
)
func init() {
control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "网易云热评",
Help: "- 来份网易云热评",
}).OnFullMatch("来份网易云热评").SetBlock(true).Limit(ctxext.LimitByUser).
Handle(func(ctx *zero.Ctx) {
data, err := web.RequestDataWith(web.NewDefaultClient(), wangyiyunURL, "GET", wangyiyunReferer, ua, nil)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(message.Text(helper.BytesToString(data)))
})
}

View File

@@ -321,9 +321,9 @@ func init() {
}
ismod := iteminfo.ModMaxRank != 0
max := 5
if len(sells) < max {
max = len(sells)
maxCount := 5
if len(sells) < maxCount {
maxCount = len(sells)
}
sb := strings.Builder{}
if ismod {
@@ -332,13 +332,13 @@ func init() {
} else {
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text("请输入编号选择(30s内)\n输入c直接结束会话")))
}
for i := 0; i < max; i++ {
for i := 0; i < maxCount; i++ {
// msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx,
// message.Text(fmt.Sprintf("[%d] (Rank:%d/%d) %dP - %s\n", i, sells[i].ModRank, iteminfo.ModMaxRank, sells[i].Platinum, sells[i].User.IngameName))))
sb.WriteString(fmt.Sprintf("[%d] (Rank:%d/%d) %dP - %s\n", i, sells[i].ModRank, iteminfo.ModMaxRank, sells[i].Platinum, sells[i].User.IngameName))
}
} else {
for i := 0; i < max; i++ {
for i := 0; i < maxCount; i++ {
// msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx,
// message.Text(fmt.Sprintf("[%d] %dP -%s\n", i, sells[i].Platinum, sells[i].User.IngameName))))
sb.WriteString(fmt.Sprintf("[%d] %dP -%s\n", i, sells[i].Platinum, sells[i].User.IngameName))

View File

@@ -1,113 +0,0 @@
// Package wenben 文本链接
package wenben
import (
"encoding/json"
"fmt"
"strings"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
"github.com/wdvxdr1123/ZeroBot/utils/helper"
)
const (
tianqi = "https://xiaobai.klizi.cn/API/other/weather_1.php?data=&msg=%v" // api地址
pinyin = "http://ovooa.com/API/pinyin/api.php?type=text&msg=%v"
yiyan = "https://v1.hitokoto.cn/?c=a&c=b&c=c&c=d&c=h&c=i" // 动漫 漫画 游戏 文学 影视 诗词
kouling = "http://ovooa.com/API/rao/api.php?type=text" // 口令
tang = "http://api.btstu.cn/yan/api.php?charset=utf-8&encode=text"
qing = "https://xiaobai.klizi.cn/API/other/wtqh.php"
)
type rspData struct {
Hitokoto string `json:"hitokoto"`
From string `json:"from"`
FromWho string `json:"from_who"`
}
func init() { // 主函数
en := control.AutoRegister(&ctrl.Options[*zero.Ctx]{
DisableOnDefault: false,
Brief: "天气/拼音查询",
Help: "文本命令大全\n" +
"- 天气查询xxx天气" +
"- 拼音查询xxx拼音" +
"- 每日一言" +
"- 每日鸡汤" +
"- 每日情话" +
"- 绕口令",
})
en.OnSuffix("天气").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
str := ctx.State["args"].(string)
es, err := web.GetData(fmt.Sprintf(tianqi, str)) // 将网站返回结果赋值
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
ctx.SendChain(message.Text(str, "天气如下:\n", helper.BytesToString(es)))
})
en.OnSuffix("拼音").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
str := ctx.State["args"].(string)
es, err := web.GetData(fmt.Sprintf(pinyin, str)) // 将网站返回结果赋值
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
ctx.SendChain(message.Text(str, "的拼音为:", helper.BytesToString(es)))
})
en.OnFullMatch("每日情话").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(qing)
if err != nil {
ctx.SendChain(message.Text("获取失败惹", err))
return
}
ctx.SendChain(message.Text(helper.BytesToString(data)))
})
en.OnFullMatch("每日鸡汤").SetBlock(true).
Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(tang)
if err != nil {
ctx.SendChain(message.Text("获取失败惹", err))
return
}
ctx.SendChain(message.Text(helper.BytesToString(data)))
})
en.OnFullMatch("绕口令").SetBlock(true).Handle(func(ctx *zero.Ctx) {
data, err := web.GetData(kouling)
if err != nil {
ctx.SendChain(message.Text("获取失败惹", err))
return
}
ctx.SendChain(message.Text(helper.BytesToString(data)))
})
en.OnFullMatch("每日一言").SetBlock(true).Handle(func(ctx *zero.Ctx) { // 每日一言
var rsp rspData
data, err := web.GetData(yiyan)
if err != nil {
ctx.SendChain(message.Text("Err:", err))
return
}
err = json.Unmarshal(data, &rsp)
if err != nil {
ctx.SendChain(message.Text("出现错误捏:", err))
return
}
var msg strings.Builder
msg.WriteString(rsp.Hitokoto)
msg.WriteString("\n出自")
msg.WriteString(rsp.From)
msg.WriteByte('\n')
if len(rsp.FromWho) != 0 {
msg.WriteString("作者:")
msg.WriteString(rsp.FromWho)
}
ctx.SendChain(message.Text(msg.String()))
})
}

Some files were not shown because too many files have changed in this diff Show More