mirror of
https://github.com/FloatTech/ZeroBot-Plugin.git
synced 2026-02-07 07:40:21 +00:00
Compare commits
96 Commits
v1.6.0-bet
...
v1.6.2-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
20821827b3 | ||
|
|
3dd10169e3 | ||
|
|
8cd60a84d5 | ||
|
|
03a2f4c331 | ||
|
|
cfc9b55fce | ||
|
|
fc99eb3e22 | ||
|
|
93625f9c4f | ||
|
|
b6ce9f7b2e | ||
|
|
20642b3776 | ||
|
|
16ab7c08f6 | ||
|
|
7bce7f28dc | ||
|
|
8c695c96d7 | ||
|
|
d4a057e21a | ||
|
|
f18c809355 | ||
|
|
0d9c8d9a43 | ||
|
|
76e7f81a6c | ||
|
|
faf00dfea7 | ||
|
|
39af90e63d | ||
|
|
36b09b8e94 | ||
|
|
7ec2b46d75 | ||
|
|
7cc5771a9a | ||
|
|
f96b5f8965 | ||
|
|
07e6f33b04 | ||
|
|
f1a33a1845 | ||
|
|
0a72566378 | ||
|
|
a029add486 | ||
|
|
778b8749ea | ||
|
|
7d5944fccf | ||
|
|
3e16a24ab5 | ||
|
|
ff682da3fe | ||
|
|
a0120485de | ||
|
|
0c8e9198ee | ||
|
|
40da2481cc | ||
|
|
a7ae56481b | ||
|
|
f550d58ad7 | ||
|
|
f488b75ac6 | ||
|
|
4308e386b4 | ||
|
|
df1c207d77 | ||
|
|
8ca71967b6 | ||
|
|
c99d09ea63 | ||
|
|
9ce65de698 | ||
|
|
cc7953c486 | ||
|
|
d50f330ccf | ||
|
|
36f2a23aa1 | ||
|
|
14b98d4006 | ||
|
|
d401136966 | ||
|
|
d0610b152f | ||
|
|
fa8428ae8b | ||
|
|
7d1a4b4005 | ||
|
|
19e3688499 | ||
|
|
b8da6f8cfd | ||
|
|
58631c5b19 | ||
|
|
e994768318 | ||
|
|
c304d72d77 | ||
|
|
a1f1016fb9 | ||
|
|
913f01d69f | ||
|
|
f56929c852 | ||
|
|
e9e0498b34 | ||
|
|
b6026ee76a | ||
|
|
8fdc358cc5 | ||
|
|
fef0ac6049 | ||
|
|
e144db9205 | ||
|
|
825a5a0d43 | ||
|
|
6dccfc862c | ||
|
|
771f93f9af | ||
|
|
7893fc9ebe | ||
|
|
9b4363dda8 | ||
|
|
257263bfa2 | ||
|
|
8f009bb4ee | ||
|
|
34a3cf82e7 | ||
|
|
cd927ec2c4 | ||
|
|
1266b2378a | ||
|
|
575d158d5a | ||
|
|
a008faf805 | ||
|
|
9a2081de0a | ||
|
|
9550b817c5 | ||
|
|
ee895e7dc4 | ||
|
|
7aa2996540 | ||
|
|
725aa5b180 | ||
|
|
f96f14052e | ||
|
|
adfa9f9e0f | ||
|
|
d8bc336006 | ||
|
|
b69bd3d640 | ||
|
|
5d9ac50106 | ||
|
|
df83ffc8b0 | ||
|
|
e49b568d6d | ||
|
|
8399e49072 | ||
|
|
d76a65ec07 | ||
|
|
ed7cef7566 | ||
|
|
3349ec7694 | ||
|
|
11f358bcbf | ||
|
|
82608d01bb | ||
|
|
a93f4f68b4 | ||
|
|
6f8c576a44 | ||
|
|
e75fc83412 | ||
|
|
2e538e3905 |
BIN
.github/hua_nobg_512.gif
vendored
Normal file
BIN
.github/hua_nobg_512.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
14
.github/workflows/push.yml
vendored
14
.github/workflows/push.yml
vendored
@@ -17,3 +17,17 @@ jobs:
|
||||
uses: golangci/golangci-lint-action@master
|
||||
with:
|
||||
version: latest
|
||||
|
||||
- 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 "🎨 改进代码样式"
|
||||
|
||||
- name: Create Pull Request
|
||||
if: ${{ !github.head_ref }}
|
||||
continue-on-error: true
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
|
||||
BIN
.github/黒金.jpg
vendored
BIN
.github/黒金.jpg
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 191 KiB |
@@ -18,7 +18,6 @@ linters:
|
||||
fast: false
|
||||
enable:
|
||||
- bodyclose
|
||||
- deadcode
|
||||
- depguard
|
||||
- dogsled
|
||||
- errcheck
|
||||
@@ -39,13 +38,11 @@ linters:
|
||||
- nolintlint
|
||||
- rowserrcheck
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- stylecheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
- prealloc
|
||||
- predeclared
|
||||
@@ -76,4 +73,5 @@ issues:
|
||||
fix: true
|
||||
exclude-use-default: false
|
||||
exclude:
|
||||
- "Error return value of .((os.)?std(out|err)..*|.*Close|.*Seek|.*Flush|os.Remove(All)?|.*print(f|ln)?|os.(Un)?Setenv). is not check"
|
||||
- "Error return value of .((os.)?std(out|err)..*|.*Close|.*Seek|.*Flush|os.Remove(All)?|.*print(f|ln)?|os.(Un)?Setenv). is not check"
|
||||
- 'identifier ".*" contain non-ASCII character: U\+.*'
|
||||
|
||||
116
README.md
116
README.md
@@ -1,9 +1,12 @@
|
||||
<div align="center">
|
||||
<a href="https://crypko.ai/crypko/5k8HyUVTq5421/">
|
||||
<img src=".github/黒金.jpg" alt="看板娘" width = "400">
|
||||
<img src=".github/hua_nobg_512.gif" alt="椛" width = "400">
|
||||
</a><br>
|
||||
|
||||
<h1>ZeroBot-Plugin</h1>
|
||||
|
||||
“椛椛是[真寻](https://github.com/HibiKier/zhenxun_bot)的好朋友!”
|
||||
|
||||
ZeroBot-Plugin 是 ZeroBot 的 实用插件合集<br><br>
|
||||
|
||||
|
||||
@@ -15,7 +18,7 @@
|
||||
|
||||
[](https://goreportcard.com/badge/github.com/FloatTech/ZeroBot-Plugin)
|
||||
[](https://t.me/zerobotplugin)
|
||||
[](https://github.com/wdvxdr1123/ZeroBot)
|
||||
[](https://github.com/wdvxdr1123/ZeroBot)
|
||||
[](https://raw.githubusercontent.com/FloatTech/ZeroBot-Plugin/master/LICENSE)
|
||||
[](https://jq.qq.com/?_wv=1027&k=QMb7x1mM)
|
||||
[](https://t.me/zerobotplugin)
|
||||
@@ -23,9 +26,9 @@
|
||||
本项目符合 [OneBot](https://github.com/howmanybots/onebot) 标准,可基于以下项目与机器人框架/平台进行交互
|
||||
| 项目地址 | 平台 | 核心作者 |
|
||||
| --- | --- | --- |
|
||||
| [Mrs4s/go-cqhttp](https://github.com/Mrs4s/go-cqhttp) | [MiraiGo](https://github.com/Mrs4s/MiraiGo) | Mrs4s |
|
||||
| [yyuueexxiinngg/cqhttp-mirai](https://github.com/yyuueexxiinngg/cqhttp-mirai) | [Mirai](https://github.com/mamoe/mirai) | yyuueexxiinngg |
|
||||
| [takayama-lily/onebot](https://github.com/takayama-lily/onebot) | [OICQ](https://github.com/takayama-lily/oicq) | takayama |
|
||||
| [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 |
|
||||
|
||||
[](https://seladb.github.io/StarTrack-js/#/preload?r=FloatTech,ZeroBot-Plugin)
|
||||
|
||||
@@ -49,7 +52,7 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
|
||||
- **-c config.json**: 从`config.json`加载`bot`配置
|
||||
- **-s config.json**: 保存现在`bot`配置到`config.json`
|
||||
- **-l latency**: 全局处理延时 (ms)
|
||||
- **-r ringlen**: 接收消息环缓冲区大小
|
||||
- **-r ringlen**: 接收消息环缓冲区大小,`0`为不设缓冲,并发处理
|
||||
- **-x max process time**: 最大处理时间 (min)
|
||||
- **qqs**: superusers 的 qq 号
|
||||
- **&**: 驻留在后台,必须放在最后,仅`Linux`下有效
|
||||
@@ -76,7 +79,8 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
|
||||
"Url": "ws://127.0.0.1:6700",
|
||||
"AccessToken": ""
|
||||
}
|
||||
]
|
||||
],
|
||||
"wss": null
|
||||
}
|
||||
```
|
||||
|
||||
@@ -100,6 +104,10 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
|
||||
|
||||
- [x] /禁用 xxx (在发送的群/用户禁用xxx)
|
||||
|
||||
- [x] /此处启用所有插件
|
||||
|
||||
- [x] /此处禁用所有插件
|
||||
|
||||
- [x] /全局启用 xxx
|
||||
|
||||
- [x] /全局禁用 xxx
|
||||
@@ -237,7 +245,7 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
|
||||
|
||||
- [ ] 同意好友请求
|
||||
|
||||
- [ ] 撤回[@xxx] [xxx]
|
||||
- [x] 对信息回复: 撤回
|
||||
|
||||
- [ ] 警告[@xxx]
|
||||
|
||||
@@ -245,15 +253,6 @@ zerobot [-h] [-n nickname] [-t token] [-u url] [-p prefix] [-d|w] [-c|s config.j
|
||||
|
||||
- 设置欢迎语可选添加参数说明:{at}可在发送时艾特被欢迎者 {nickname}是被欢迎者名字 {avatar}是被欢迎者头像 {uid}是被欢迎者QQ号 {gid}是当前群群号 {groupname} 是当前群群名
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>词典匹配回复</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus"`
|
||||
|
||||
- [x] 切换[kimo|傲娇|可爱]词库
|
||||
- [x] 设置词库触发概率0.x (0<x<9)
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>定时指令触发器</summary>
|
||||
@@ -402,6 +401,14 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 支付宝到账 1
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>触发者撤回时也自动撤回</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/autowithdraw"`
|
||||
|
||||
- [x] 撤回一条消息
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>base16384加解密</summary>
|
||||
@@ -633,6 +640,20 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 教你一篇小作文[作文]
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>女装</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress"`
|
||||
|
||||
- [x] 女装
|
||||
|
||||
- [x] 男装
|
||||
|
||||
- [x] 随机女装
|
||||
|
||||
- [x] 随机男装
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>漂流瓶</summary>
|
||||
@@ -651,14 +672,6 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] [emoji][emoji]
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>城市疫情查询</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic"`
|
||||
|
||||
- [x] xxx疫情
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>好友申请及群聊邀请事件处理</summary>
|
||||
@@ -686,7 +699,7 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 运势 | 抽签
|
||||
|
||||
- [x] 设置底图[车万 DC4 爱因斯坦 星空列车 樱云之恋 富婆妹 李清歌 公主连结 原神 明日方舟 碧蓝航线 碧蓝幻想 战双 阴阳师 赛马娘 东方归言录 奇异恩典 夏日口袋 ASoul]
|
||||
- [x] 设置底图[车万 DC4 爱因斯坦 星空列车 樱云之恋 富婆妹 李清歌 公主连结 原神 明日方舟 碧蓝航线 碧蓝幻想 战双 阴阳师 赛马娘 东方归言录 奇异恩典 夏日口袋 ASoul Hololive]
|
||||
|
||||
</details>
|
||||
<details>
|
||||
@@ -917,6 +930,8 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 让[수아|미미르|아린|연화|유화|선배]说(韩语)
|
||||
|
||||
- [x] 让[派蒙|空|荧|阿贝多|枫原万叶|温迪|八重神子|纳西妲|钟离|诺艾尔|凝光|托马|北斗|莫娜|荒泷一斗|提纳里|芭芭拉|艾尔海森|雷电将军|赛诺|琴|班尼特|五郎|神里绫华|迪希雅|夜兰|辛焱|安柏|宵宫|云堇|妮露|烟绯|鹿野院平藏|凯亚|达达利亚|迪卢克|可莉|早柚|香菱|重云|刻晴|久岐忍|珊瑚宫心海|迪奥娜|戴因斯雷布|魈|神里绫人|丽莎|优菈|凯瑟琳|雷泽|菲谢尔|九条裟罗|甘雨|行秋|胡桃|迪娜泽黛|柯莱|申鹤|砂糖|萍姥姥|奥兹|罗莎莉亚|式大将|哲平|坎蒂丝|托克|留云借风真君|昆钧|塞琉斯|多莉|大肉丸|莱依拉|散兵|拉赫曼|杜拉夫|阿守|玛乔丽|纳比尔|海芭夏|九条镰治|阿娜耶|阿晃|阿扎尔|七七|博士|白术|埃洛伊|大慈树王|女士|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|芽衣|雷之律者|阿波尼亚]说(中文)
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>摸鱼</summary>
|
||||
@@ -1021,6 +1036,12 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 小说[xxx]
|
||||
|
||||
- 设置小说配置 zerobot 123456
|
||||
|
||||
- 下载小说30298
|
||||
|
||||
- 注: 建议去https://www.23qb.com/ 注册一个账号, 小说下载有积分限制
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>nsfw图片识别</summary>
|
||||
@@ -1250,6 +1271,16 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 更新vtb
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>钱包</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet"`
|
||||
|
||||
- [x] 查看我的钱包
|
||||
|
||||
- [x] 查看钱包排名
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>网易云音乐热评</summary>
|
||||
@@ -1258,6 +1289,23 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
- [x] 来份网易云热评
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>星际战甲</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi"`
|
||||
|
||||
- [x] wf时间同步
|
||||
|
||||
- [x] [金星|地球|火卫二]平原状态
|
||||
|
||||
- [x] .wm [物品名称]
|
||||
|
||||
- [x] 仲裁
|
||||
|
||||
- [x] 警报
|
||||
|
||||
- [x] 每日特惠
|
||||
</details>
|
||||
<details>
|
||||
<summary>天气/拼音查询-名言</summary>
|
||||
@@ -1372,11 +1420,22 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
|
||||
###### `"github.com/FloatTech/ZeroBot-Plugin/plugin/ygo/ygotrade.go"`
|
||||
- [x] 查卡价 [卡名]
|
||||
- [x] 查卡价 [卡名] [稀有度 稀有度 ...]
|
||||
- [x] 查卡价 [卡名] -r [稀有度 稀有度 ...]
|
||||
- [x] 查卡店 [卡名]
|
||||
- [x] 查卡店 [卡名] [稀有度]
|
||||
- [x] 查卡店 [卡名] -r [稀有度]
|
||||
- 注:卡店只支持单个稀有度查询
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>词典匹配回复</summary>
|
||||
|
||||
`import _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus"`
|
||||
|
||||
- [x] 切换[kimo|傲娇|可爱]词库
|
||||
- [x] 设置词库触发概率0.x (0<x<9)
|
||||
|
||||
- 注:由于占用资源较大,默认注释。
|
||||
|
||||
</details>
|
||||
<details>
|
||||
<summary>鬼东西</summary>
|
||||
@@ -1411,6 +1470,7 @@ print("run[CQ:image,file="+j["img"]+"]")
|
||||
- [x] @Bot 任意文本(任意一句话回复)
|
||||
|
||||
- [x] 设置回复模式[青云客 | 小爱]
|
||||
|
||||
</details>
|
||||
|
||||
## 三种使用方法,推荐第一种
|
||||
|
||||
2
data
2
data
Submodule data updated: 485fc2618e...5e0fa81c3b
54
go.mod
54
go.mod
@@ -4,53 +4,56 @@ go 1.19
|
||||
|
||||
require (
|
||||
github.com/Baidu-AIP/golang-sdk v1.1.1
|
||||
github.com/Coloured-glaze/gg v1.3.4
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20221203040820-0dda47e61cd8
|
||||
github.com/FloatTech/floatbox v0.0.0-20221203040505-d7352e564906
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7
|
||||
github.com/FloatTech/floatbox v0.0.0-20230205065512-4039f6dd0a68
|
||||
github.com/FloatTech/gg v1.1.0
|
||||
github.com/FloatTech/rendercard v0.0.9-0.20230206125820-929cee91387c
|
||||
github.com/FloatTech/sqlite v1.5.7
|
||||
github.com/FloatTech/ttl v0.0.0-20220715042055-15612be72f5b
|
||||
github.com/FloatTech/zbpctrl v1.5.3-0.20221203040611-11f118e1d5ec
|
||||
github.com/FloatTech/zbputils v1.6.1-0.20221203040741-3bc28d5e3cd1
|
||||
github.com/FloatTech/zbpctrl v1.5.3-0.20230130095145-714ad318cd52
|
||||
github.com/FloatTech/zbputils v1.6.2-0.20230206130001-6b404926bf66
|
||||
github.com/RomiChan/syncx v0.0.0-20221202055724-5f842c53020e
|
||||
github.com/RomiChan/websocket v1.4.3-0.20220227141055-9b2c6168c9c5
|
||||
github.com/antchfx/htmlquery v1.2.5
|
||||
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.6.1
|
||||
github.com/fumiama/go-registry v0.2.5-0.20221121111817-44b0846bdce6
|
||||
github.com/fumiama/go-base16384 v1.6.4
|
||||
github.com/fumiama/go-registry v0.2.5
|
||||
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/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
|
||||
github.com/jinzhu/gorm v1.9.16
|
||||
github.com/jozsefsallai/gophersauce v1.0.1
|
||||
github.com/lucas-clemente/quic-go v0.31.0
|
||||
github.com/lithammer/fuzzysearch v1.1.5
|
||||
github.com/mroth/weightedrand v1.0.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkumza/numcn v1.0.0
|
||||
github.com/shirou/gopsutil/v3 v3.22.11
|
||||
github.com/quic-go/quic-go v0.32.0
|
||||
github.com/shirou/gopsutil/v3 v3.23.1
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/wcharczuk/go-chart/v2 v2.1.0
|
||||
github.com/wdvxdr1123/ZeroBot v1.6.5
|
||||
github.com/wdvxdr1123/ZeroBot v1.6.8
|
||||
gitlab.com/gomidi/midi/v2 v2.0.25
|
||||
golang.org/x/image v0.1.0
|
||||
golang.org/x/image v0.3.0
|
||||
golang.org/x/text v0.6.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/FloatTech/rendercard v0.0.2-0.20221128165614-a41216d2422e // indirect
|
||||
github.com/antchfx/xpath v1.2.1 // indirect
|
||||
github.com/disintegration/imaging v1.6.2 // 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/gofastTEA v0.0.10 // indirect
|
||||
github.com/fumiama/imgsz v0.0.2 // 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-20210107165309-348f09dbbbc0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // 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
|
||||
@@ -60,28 +63,29 @@ require (
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/marten-seemann/qpack v0.3.0 // indirect
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 // indirect
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.2.0 // 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-18 v0.2.0 // indirect
|
||||
github.com/quic-go/qtls-go1-19 v0.2.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.1.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // 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.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // 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.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect
|
||||
golang.org/x/sys v0.2.0 // indirect
|
||||
golang.org/x/text v0.4.0 // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/mod v0.6.0 // indirect
|
||||
golang.org/x/net v0.4.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
modernc.org/libc v1.21.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
|
||||
94
go.sum
94
go.sum
@@ -1,23 +1,23 @@
|
||||
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/Coloured-glaze/gg v1.3.4 h1:l31zIF/HaVwkzjrj+A56RGQoSKyKuR1IWtIrqXGFStI=
|
||||
github.com/Coloured-glaze/gg v1.3.4/go.mod h1:Ih5NLNNDHOy3RJbB0EPqGTreIzq/H02TGThIagh8HJg=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20221203040820-0dda47e61cd8 h1:HlJDqBlEuS1337zBhjjyutf+GESQJ6wMIk9zBoOVgBI=
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20221203040820-0dda47e61cd8/go.mod h1:9d56SRgNBXZrs2mnndEMBuctdFHhxoTwGBvOK3jIVi0=
|
||||
github.com/FloatTech/floatbox v0.0.0-20221203040505-d7352e564906 h1:Rxc/7zh/dR96prmq/mOjmtam261CSRwZPFXi/+oU7d8=
|
||||
github.com/FloatTech/floatbox v0.0.0-20221203040505-d7352e564906/go.mod h1:i8k21EWZVoSz7/0PB2reDQXnGR6eEL9VytEev2XuqLc=
|
||||
github.com/FloatTech/rendercard v0.0.2-0.20221128165614-a41216d2422e h1:7bF01RHsYS99Zp+OWfob1W/Cymho6fcggoRSpiuiYB8=
|
||||
github.com/FloatTech/rendercard v0.0.2-0.20221128165614-a41216d2422e/go.mod h1:e2M5OWspdblwq182zbVgRefiOc+gXtB1XzTW/2z86/I=
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7 h1:4FCjcjcsjUSJzmuUi8u570SUnmYasZ98ugSRg2SIl18=
|
||||
github.com/FloatTech/AnimeAPI v1.6.1-0.20230130095520-be357484e5a7/go.mod h1:LmHu358Oovtxhc/7xz+IfffUAMCX2bijpEvWatacEYQ=
|
||||
github.com/FloatTech/floatbox v0.0.0-20230205065512-4039f6dd0a68 h1:K03MRdjGBtoZ7QOnyeKf8dmxsRoNF7dN0udNrR5t138=
|
||||
github.com/FloatTech/floatbox v0.0.0-20230205065512-4039f6dd0a68/go.mod h1:OoZE4Ra7olpFaJSrlD6mcyT4chPLg9QBRE1pzTC8R84=
|
||||
github.com/FloatTech/gg v1.1.0 h1:4qmsleYqRZ/gv48izGgkyJgvP1RmybA5xJJnzkhK/OU=
|
||||
github.com/FloatTech/gg v1.1.0/go.mod h1:uzPzAeT35egARdRuu+1oyjU3CmTwCceoq3Vvje7LpcI=
|
||||
github.com/FloatTech/rendercard v0.0.9-0.20230206125820-929cee91387c h1:nE1X4Z3BAyYydlo0QKVU/nUtEyF5ek/cN6S5sZsyio4=
|
||||
github.com/FloatTech/rendercard v0.0.9-0.20230206125820-929cee91387c/go.mod h1:0LVxMhsw6LayHM78pJ58/TCkx0/CIVuYc19fCHpM/5g=
|
||||
github.com/FloatTech/sqlite v1.5.7 h1:Bvo4LSojcZ6dVtbHrkqvt6z4v8e+sj0G5PSUIvdawsk=
|
||||
github.com/FloatTech/sqlite v1.5.7/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.5.3-0.20221203040611-11f118e1d5ec h1:7v8vUn83DTD8mKRNmBFS4tp7OczWikrZPxEolrpMUWI=
|
||||
github.com/FloatTech/zbpctrl v1.5.3-0.20221203040611-11f118e1d5ec/go.mod h1:9K0wS8sj6H8goHniT0zpaqd2rCrVbSbbCIDLrQKvCns=
|
||||
github.com/FloatTech/zbputils v1.6.1-0.20221203040741-3bc28d5e3cd1 h1:b/DKfa17Q0FnNe01LyyPLHK80kIUK4ZZ0DNDwZ0PoVc=
|
||||
github.com/FloatTech/zbputils v1.6.1-0.20221203040741-3bc28d5e3cd1/go.mod h1:0ds7lVGqlctA6u6S7vbLRr4w7SQIaVJCdIGKFXS0u2g=
|
||||
github.com/FloatTech/zbpctrl v1.5.3-0.20230130095145-714ad318cd52 h1:BrStRXeosWh8L0iA/EjPd8w6xNexDkqki39ITZko/9Q=
|
||||
github.com/FloatTech/zbpctrl v1.5.3-0.20230130095145-714ad318cd52/go.mod h1:qqMLUwR7tKpqnAqsgI7aZbn0hbs2FEVF4ylMXqIpBdY=
|
||||
github.com/FloatTech/zbputils v1.6.2-0.20230206130001-6b404926bf66 h1:Flhj6lBRDQQnAkRML2pIJEwqSu1NjfS2Tzh0HncaC2Q=
|
||||
github.com/FloatTech/zbputils v1.6.2-0.20230206130001-6b404926bf66/go.mod h1:cJiEzrjnkGlnw1oyL4wXmF64njoDN/jNV1Qm+Hu3B2o=
|
||||
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=
|
||||
@@ -38,6 +38,8 @@ github.com/d4l3k/messagediff v1.2.2-0.20190829033028-7e0a312ae40b/go.mod h1:Oozb
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3 h1:qshMBFxVjYjzI+kwvWvgoByF3uMCvnJiaK8KslWAbr8=
|
||||
github.com/davidscholberg/go-durationfmt v0.0.0-20170122144659-64843a2083d3/go.mod h1:M9fx6rAdHSYLKxXPgUXGgblb586CA7ceNrpu4DEc2No=
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM=
|
||||
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=
|
||||
@@ -54,16 +56,18 @@ github.com/fumiama/bigfft v0.0.0-20211011143303-6e0bfa3c836b h1:Zt3pFQditAdWTHCO
|
||||
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.6.1 h1:4yb4JgmBJDnQtq3XGXXdLrVwEnRpjhMUt4eAcsNeA30=
|
||||
github.com/fumiama/go-base16384 v1.6.1/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
|
||||
github.com/fumiama/go-registry v0.2.5-0.20221121111817-44b0846bdce6 h1:rCvtE5Qcj6HVJICbDC7SOmIl4QnkAKSNt5/wJ/AO4wo=
|
||||
github.com/fumiama/go-registry v0.2.5-0.20221121111817-44b0846bdce6/go.mod h1:GP45kejHuDLFxcWdksrt75r5rHBqYwtfeUl3JzGWxfQ=
|
||||
github.com/fumiama/go-base16384 v1.6.4 h1:rYDRwD/th2cG4U7QLokpzmST1cCxZGXtHmolOUePt5o=
|
||||
github.com/fumiama/go-base16384 v1.6.4/go.mod h1:OEn+947GV5gsbTAnyuUW/SrfxJYUdYupSIQXOuGOcXM=
|
||||
github.com/fumiama/go-registry v0.2.5 h1:Y6tnHnTThQPv7E4JPM2vBprU+4EQw/LEDO33HCmxgI4=
|
||||
github.com/fumiama/go-registry v0.2.5/go.mod h1:GP45kejHuDLFxcWdksrt75r5rHBqYwtfeUl3JzGWxfQ=
|
||||
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/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/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=
|
||||
@@ -88,8 +92,9 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZ
|
||||
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 h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY=
|
||||
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.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
@@ -125,17 +130,11 @@ 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/lucas-clemente/quic-go v0.31.0 h1:MfNp3fk0wjWRajw6quMFA3ap1AVtlU+2mtwmbVogB2M=
|
||||
github.com/lucas-clemente/quic-go v0.31.0/go.mod h1:0wFbizLgYzqHqtlyxyCaJKlE7bYgE6JQ+54TLd/Dq2g=
|
||||
github.com/lithammer/fuzzysearch v1.1.5 h1:Ag7aKU08wp0R9QCfF4GoGST9HbmAIeLP7xwMrOBEp1c=
|
||||
github.com/lithammer/fuzzysearch v1.1.5/go.mod h1:1R1LRNk7yKid1BaQkmuLQaHruxcC4HmAH30Dh61Ih1Q=
|
||||
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/marten-seemann/qpack v0.3.0 h1:UiWstOgT8+znlkDPOg2+3rIuYXJ2CnGDkGUXN6ki6hE=
|
||||
github.com/marten-seemann/qpack v0.3.0/go.mod h1:cGfKPBiP4a9EQdxCwEwI/GEeWAsjSekBvx/X8mh58+g=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3 h1:R4H2Ks8P6pAtUagjFty2p7BVHn3XiwDAl7TTQf5h7TI=
|
||||
github.com/marten-seemann/qtls-go1-18 v0.1.3/go.mod h1:mJttiymBAByA49mhlNZZGrH5u1uXYZJ+RW28Py7f4m4=
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1 h1:mnbxeq3oEyQxQXwI4ReCgW9DPoPR94sNlqWoDZnjRIE=
|
||||
github.com/marten-seemann/qtls-go1-19 v0.1.1/go.mod h1:5HTDWtVudo/WFsHKRNuOhWlbdjrfs5JHrYb0wIJqGpI=
|
||||
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-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
@@ -160,10 +159,20 @@ 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-18 v0.2.0 h1:5ViXqBZ90wpUcZS0ge79rf029yx0dYB0McyPJwqqj7U=
|
||||
github.com/quic-go/qtls-go1-18 v0.2.0/go.mod h1:moGulGHK7o6O8lSPSZNoOwcLvJKJ85vVNc7oJFD65bc=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.0 h1:Cvn2WdhyViFUHoOqK52i51k4nDX8EwIh5VJiVM4nttk=
|
||||
github.com/quic-go/qtls-go1-19 v0.2.0/go.mod h1:ySOI96ew8lnoKPtSqx2BlI5wCpUVPT05RMAlajtnyOI=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.0 h1:d1PK3ErFy9t7zxKsG3NXBJXZjp/kMLoIb3y/kV54oAI=
|
||||
github.com/quic-go/qtls-go1-20 v0.1.0/go.mod h1:JKtK6mjbAVcUTN/9jZpvLbGxvdWIKS8uT7EiStoU1SM=
|
||||
github.com/quic-go/quic-go v0.32.0 h1:lY02md31s1JgPiiyfqJijpu/UX/Iun304FI3yUqX7tA=
|
||||
github.com/quic-go/quic-go v0.32.0/go.mod h1:/fCsKANhQIeD5l76c2JFU+07gVE3KaA0FP+0zMWwfwo=
|
||||
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.22.11 h1:kxsPKS+Eeo+VnEQ2XCaGJepeP6KY53QoRTETx3+1ndM=
|
||||
github.com/shirou/gopsutil/v3 v3.22.11/go.mod h1:xl0EeL4vXJ+hQMAGN8B9VFpxukEMA0XdevQOe5MZ1oY=
|
||||
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/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -187,8 +196,8 @@ github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYm
|
||||
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.6.5 h1:w2dwDnMqYpwVAO3DPESznavAJ5T2jrqgU46owd3PFi4=
|
||||
github.com/wdvxdr1123/ZeroBot v1.6.5/go.mod h1:T5kD5vLi/YxL/fyDOCOaawi96LRBdJjcXh2CIjDyFfg=
|
||||
github.com/wdvxdr1123/ZeroBot v1.6.8 h1:jdFhd6Bk0JBIKPpKhHnkACtjnIf4co6Hdw3U16e4Gi0=
|
||||
github.com/wdvxdr1123/ZeroBot v1.6.8/go.mod h1:T5kD5vLi/YxL/fyDOCOaawi96LRBdJjcXh2CIjDyFfg=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg=
|
||||
@@ -200,12 +209,13 @@ golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACk
|
||||
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 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
|
||||
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/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-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
|
||||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA=
|
||||
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=
|
||||
@@ -213,8 +223,8 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
|
||||
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.1.0 h1:r8Oj8ZA2Xy12/b5KZYj3tuv7NG/fBz3TwQVvpJ9l8Rk=
|
||||
golang.org/x/image v0.1.0/go.mod h1:iyPr49SD/G/TBxYVB/9RRtGUT5eNbo2u4NamWeQcD5c=
|
||||
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/mobile v0.0.0-20190415191353-3e0bab5405d6/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mobile v0.0.0-20201217150744-e6ae53a27f4f h1:kgfVkAEEQXXQ0qc6dH7n6y37NAYmTFmz0YRwrRjgxKw=
|
||||
@@ -223,8 +233,9 @@ 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 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
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=
|
||||
@@ -235,8 +246,9 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
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 h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
|
||||
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
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=
|
||||
@@ -257,22 +269,24 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
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 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/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.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
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 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
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=
|
||||
|
||||
@@ -1,42 +1,10 @@
|
||||
package kanban
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
// Version ...
|
||||
var Version = "v1.6.2-beta2"
|
||||
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/fumiama/go-registry"
|
||||
)
|
||||
|
||||
var (
|
||||
// Banner ...
|
||||
Banner = "* OneBot + ZeroBot + Golang\n" +
|
||||
"* Version 1.6.0-beta2 - 2022-12-03 12:1755 +0800 CST\n" +
|
||||
"* Copyright © 2020 - 2022 FloatTech. All Rights Reserved.\n" +
|
||||
"* Project: https://github.com/FloatTech/ZeroBot-Plugin"
|
||||
reg = registry.NewRegReader("reilia.fumiama.top:32664", control.Md5File, "fumiama")
|
||||
)
|
||||
|
||||
// PrintBanner ...
|
||||
func PrintBanner() {
|
||||
fmt.Print(
|
||||
"\n======================[ZeroBot-Plugin]======================",
|
||||
"\n", Banner, "\n",
|
||||
"----------------------[ZeroBot-公告栏]----------------------",
|
||||
"\n", Kanban(), "\n",
|
||||
"============================================================\n\n",
|
||||
)
|
||||
}
|
||||
|
||||
// Kanban ...
|
||||
func Kanban() string {
|
||||
err := reg.Connect()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
defer reg.Close()
|
||||
text, err := reg.Get("ZeroBot-Plugin/kanban")
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return text
|
||||
}
|
||||
// Banner ...
|
||||
var Banner = "* OneBot + ZeroBot + Golang\n" +
|
||||
"* Version " + Version + " - 2023-02-06 21:46:22 +0800 CST\n" +
|
||||
"* Copyright © 2020 - 2023 FloatTech. All Rights Reserved.\n" +
|
||||
"* Project: https://github.com/FloatTech/ZeroBot-Plugin"
|
||||
|
||||
46
kanban/gen/banner.go
Normal file
46
kanban/gen/banner.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Package main generates banner.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const banner = `package kanban
|
||||
|
||||
// Version ...
|
||||
var Version = "%s"
|
||||
|
||||
// Banner ...
|
||||
var Banner = "* OneBot + ZeroBot + Golang\n" +
|
||||
"* Version " + Version + " - %s\n" +
|
||||
"* Copyright © 2020 - %d FloatTech. All Rights Reserved.\n" +
|
||||
"* Project: https://github.com/FloatTech/ZeroBot-Plugin"
|
||||
`
|
||||
|
||||
const timeformat = `2006-01-02 15:04:05 +0800 CST`
|
||||
|
||||
func main() {
|
||||
f, err := os.Create("banner.go")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer f.Close()
|
||||
vartag := bytes.NewBuffer(nil)
|
||||
vartagcmd := exec.Command("git", "tag", "--sort=committerdate")
|
||||
vartagcmd.Stdout = vartag
|
||||
err = vartagcmd.Run()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
s := strings.Split(vartag.String(), "\n")
|
||||
now := time.Now()
|
||||
_, err = fmt.Fprintf(f, banner, s[len(s)-2], now.Format(timeformat), now.Year())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,44 @@
|
||||
package kanban
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/fumiama/go-registry"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/FloatTech/ZeroBot-Plugin/kanban/gen
|
||||
|
||||
var once sync.Once
|
||||
|
||||
func init() {
|
||||
once.Do(PrintBanner)
|
||||
}
|
||||
|
||||
var reg = registry.NewRegReader("reilia.fumiama.top:32664", control.Md5File, "fumiama")
|
||||
|
||||
// PrintBanner ...
|
||||
func PrintBanner() {
|
||||
fmt.Print(
|
||||
"\n======================[ZeroBot-Plugin]======================",
|
||||
"\n", Banner, "\n",
|
||||
"----------------------[ZeroBot-公告栏]----------------------",
|
||||
"\n", Kanban(), "\n",
|
||||
"============================================================\n\n",
|
||||
)
|
||||
}
|
||||
|
||||
// Kanban ...
|
||||
func Kanban() string {
|
||||
err := reg.Connect()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
defer reg.Close()
|
||||
text, err := reg.Get("ZeroBot-Plugin/kanban")
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
19
main.go
19
main.go
@@ -36,8 +36,6 @@ import (
|
||||
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/manager" // 群管
|
||||
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus" // 词典匹配回复
|
||||
|
||||
_ "github.com/FloatTech/zbputils/job" // 定时指令触发器
|
||||
|
||||
// ^^^^ //
|
||||
@@ -63,6 +61,7 @@ import (
|
||||
_ "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/b14" // base16384加解密
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baidu" // 百度一下
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/baiduaudit" // 百度内容审核
|
||||
@@ -78,9 +77,9 @@ import (
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/cpstory" // cp短打
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/danbooru" // DeepDanbooru二次元图标签识别
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/diana" // 嘉心糖发病
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/dress" // 女装
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/drift_bottle" // 漂流瓶
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/emojimix" // 合成emoji
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/epidemic" // 城市疫情查询
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/event" // 好友申请群聊邀请事件处理
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/font" // 渲染任意文字到图片
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/fortune" // 运势
|
||||
@@ -131,15 +130,18 @@ import (
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/translation" // 翻译
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vitsnyaru" // vits猫雷
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/vtb_quotation" // vtb语录
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wallet" // 钱包
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wangyiyun" // 网易云音乐热评
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/warframeapi" // warframeAPI插件
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenben" // 文本指令大全
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wenxinAI" // 百度文心AI画图
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/word_count" // 聊天热词
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/wordle" // 猜单词
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ygo" // 游戏王相关插件
|
||||
_ "github.com/FloatTech/ZeroBot-Plugin/plugin/ymgal" // 月幕galgame
|
||||
|
||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/thesaurus" // 词典匹配回复
|
||||
// _ "github.com/FloatTech/ZeroBot-Plugin/plugin/wtf" // 鬼东西
|
||||
|
||||
// ^^^^ //
|
||||
// ^^^^^^^^^^^^^^ //
|
||||
@@ -188,6 +190,7 @@ import (
|
||||
type zbpcfg struct {
|
||||
Z zero.Config `json:"zero"`
|
||||
W []*driver.WSClient `json:"ws"`
|
||||
S []*driver.WSServer `json:"wss"`
|
||||
}
|
||||
|
||||
var config zbpcfg
|
||||
@@ -249,14 +252,16 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
config.Z.Driver = make([]zero.Driver, len(config.W))
|
||||
config.Z.Driver = make([]zero.Driver, len(config.W)+len(config.S))
|
||||
for i, w := range config.W {
|
||||
config.Z.Driver[i] = w
|
||||
}
|
||||
for i, s := range config.S {
|
||||
config.Z.Driver[i+len(config.W)] = s
|
||||
}
|
||||
logrus.Infoln("[main] 从", *runcfg, "读取配置文件")
|
||||
return
|
||||
}
|
||||
|
||||
config.W = []*driver.WSClient{driver.NewWebSocketClient(*url, *token)}
|
||||
config.Z = zero.Config{
|
||||
NickName: append([]string{*adana}, "ATRI", "atri", "亚托莉", "アトリ"),
|
||||
|
||||
@@ -30,7 +30,7 @@ func init() {
|
||||
engine := control.Register("ahsai", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "フリーテキスト音声合成",
|
||||
Help: "- 使[伊織弓鶴|紲星あかり|結月ゆかり|京町セイカ|東北きりたん|東北イタコ|ついなちゃん標準語|ついなちゃん関西弁|音街ウナ|琴葉茜|吉田くん|民安ともえ|桜乃そら|月読アイ|琴葉葵|東北ずん子|月読ショウタ|水奈瀬コウ]说(日语)\n",
|
||||
Help: "- 使[伊織弓鶴|紲星あかり|結月ゆかり|京町セイカ|東北きりたん|東北イタコ|ついなちゃん標準語|ついなちゃん関西弁|音街ウナ|琴葉茜|吉田くん|民安ともえ|桜乃そら|月読アイ|琴葉葵|東北ずん子|月読ショウタ|水奈瀬コウ]说(日语)",
|
||||
PrivateDataFolder: "ahsai",
|
||||
})
|
||||
cachePath := engine.DataFolder() + "cache/"
|
||||
|
||||
@@ -2,23 +2,49 @@
|
||||
package aifalse
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"bytes"
|
||||
"errors"
|
||||
"image"
|
||||
"math"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/bilibili"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/rendercard"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/shirou/gopsutil/v3/cpu"
|
||||
"github.com/shirou/gopsutil/v3/disk"
|
||||
"github.com/shirou/gopsutil/v3/host"
|
||||
"github.com/shirou/gopsutil/v3/mem"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
"github.com/FloatTech/ZeroBot-Plugin/kanban"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
const (
|
||||
backgroundURL = "https://iw233.cn/api.php?sort=mp"
|
||||
referer = "https://weibo.com/"
|
||||
)
|
||||
|
||||
var boottime = time.Now()
|
||||
|
||||
func init() { // 插件主体
|
||||
engine := control.Register("aifalse", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
@@ -39,12 +65,16 @@ func init() { // 插件主体
|
||||
}
|
||||
engine.OnFullMatchGroup([]string{"检查身体", "自检", "启动自检", "系统状态"}, zero.AdminPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text(
|
||||
"* CPU占用: ", cpuPercent(), "%\n",
|
||||
"* RAM占用: ", memPercent(), "%\n",
|
||||
"* 硬盘使用: ", diskPercent(),
|
||||
),
|
||||
)
|
||||
img, err := drawstatus(ctx.State["manager"].(*ctrl.Control[*zero.Ctx]), ctx.Event.SelfID, zero.BotConfig.NickName[0])
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
sendimg, cl := writer.ToBytes(img)
|
||||
if id := ctx.SendChain(message.ImageBytes(sendimg)); id.ID() == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
cl()
|
||||
})
|
||||
engine.OnRegex(`^设置默认限速为每\s*(\d+)\s*(分钟|秒)\s*(\d+)\s*次触发$`, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
@@ -84,38 +114,479 @@ func init() { // 插件主体
|
||||
})
|
||||
}
|
||||
|
||||
func cpuPercent() float64 {
|
||||
func drawstatus(m *ctrl.Control[*zero.Ctx], uid int64, botname string) (sendimg image.Image, err error) {
|
||||
diskstate, err := diskstate()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
diskcardh := 40 + (20+50)*len(diskstate) + 40 - 20
|
||||
|
||||
moreinfo, err := moreinfo(m)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
moreinfocardh := 30 + (20+32*72/96)*len(moreinfo) + 30 - 20
|
||||
|
||||
basicstate, err := basicstate()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
url, err := bilibili.GetRealURL(backgroundURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), url, "", referer, "", nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
back, _, err := image.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
data, err = web.GetData("http://q4.qlogo.cn/g?b=qq&nk=" + strconv.FormatInt(uid, 10) + "&s=640")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
avatar, _, err := image.Decode(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
avatarf := img.Size(avatar, 200, 200)
|
||||
|
||||
fontbyte, err := file.GetLazyData(text.GlowSansFontFile, control.Md5File, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
canvas := gg.NewContext(1280, 70+250+40+380+diskcardh+40+moreinfocardh+40+70)
|
||||
|
||||
bh, bw, ch, cw := float64(back.Bounds().Dy()), float64(back.Bounds().Dx()), float64(canvas.H()), float64(canvas.W())
|
||||
|
||||
if bh/bw < ch/cw {
|
||||
back = img.Size(back, int(bw*ch/bh), int(bh*ch/bh)).Im
|
||||
canvas.DrawImageAnchored(back, canvas.W()/2, canvas.H()/2, 0.5, 0.5)
|
||||
} else {
|
||||
back = img.Size(back, int(bw*cw/bw), int(bh*cw/bw)).Im
|
||||
canvas.DrawImage(back, 0, 0)
|
||||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(5)
|
||||
|
||||
cardw := canvas.W() - 70 - 70
|
||||
|
||||
titlecardh := 250
|
||||
basiccardh := 380
|
||||
|
||||
var titleimg, basicimg, diskimg, moreinfoimg, shadowimg image.Image
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
titlecard := gg.NewContext(cardw, titlecardh)
|
||||
|
||||
titlecard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70)
|
||||
|
||||
titlecard.DrawRoundedRectangle(1, 1, float64(titlecard.W()-1*2), float64(titlecardh-1*2), 16)
|
||||
titlecard.SetLineWidth(3)
|
||||
titlecard.SetRGBA255(255, 255, 255, 100)
|
||||
titlecard.StrokePreserve()
|
||||
titlecard.SetRGBA255(255, 255, 255, 140)
|
||||
titlecard.Fill()
|
||||
|
||||
titlecard.DrawImage(avatarf.Circle(0).Im, (titlecardh-avatarf.H)/2, (titlecardh-avatarf.H)/2)
|
||||
|
||||
err = titlecard.ParseFontFace(fontbyte, 72)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fw, _ := titlecard.MeasureString(botname)
|
||||
|
||||
titlecard.SetRGBA255(30, 30, 30, 255)
|
||||
|
||||
titlecard.DrawStringAnchored(botname, float64(titlecardh)+fw/2, float64(titlecardh)*0.5/2, 0.5, 0.5)
|
||||
|
||||
err = titlecard.ParseFontFace(fontbyte, 24)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
titlecard.SetRGBA255(30, 30, 30, 180)
|
||||
|
||||
titlecard.NewSubPath()
|
||||
titlecard.MoveTo(float64(titlecardh), float64(titlecardh)/2)
|
||||
titlecard.LineTo(float64(titlecard.W()-titlecardh), float64(titlecardh)/2)
|
||||
titlecard.Stroke()
|
||||
|
||||
brt, err := botruntime()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fw, _ = titlecard.MeasureString(brt)
|
||||
|
||||
titlecard.DrawStringAnchored(brt, float64(titlecardh)+fw/2, float64(titlecardh)*(0.5+0.25/2), 0.5, 0.5)
|
||||
|
||||
bs, err := botstatus()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
fw, _ = titlecard.MeasureString(bs)
|
||||
|
||||
titlecard.DrawStringAnchored(bs, float64(titlecardh)+fw/2, float64(titlecardh)*(0.5+0.5/2), 0.5, 0.5)
|
||||
titleimg = rendercard.Fillet(titlecard.Image(), 16)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
basiccard := gg.NewContext(cardw, basiccardh)
|
||||
|
||||
basiccard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40)
|
||||
|
||||
basiccard.DrawRoundedRectangle(1, 1, float64(basiccard.W()-1*2), float64(basiccardh-1*2), 16)
|
||||
basiccard.SetLineWidth(3)
|
||||
basiccard.SetRGBA255(255, 255, 255, 100)
|
||||
basiccard.StrokePreserve()
|
||||
basiccard.SetRGBA255(255, 255, 255, 140)
|
||||
basiccard.Fill()
|
||||
|
||||
bslen := len(basicstate)
|
||||
for i, v := range basicstate {
|
||||
offset := float64(i) * ((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1) + 200)
|
||||
|
||||
basiccard.SetRGBA255(235, 235, 235, 255)
|
||||
basiccard.DrawCircle((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 100)
|
||||
basiccard.Fill()
|
||||
|
||||
switch {
|
||||
case v.precent > 90:
|
||||
basiccard.SetRGBA255(255, 70, 0, 255)
|
||||
case v.precent > 70:
|
||||
basiccard.SetRGBA255(255, 165, 0, 255)
|
||||
default:
|
||||
basiccard.SetRGBA255(145, 240, 145, 255)
|
||||
}
|
||||
|
||||
basiccard.NewSubPath()
|
||||
basiccard.MoveTo((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2)
|
||||
basiccard.DrawEllipticalArc((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 100, 100, -0.5*math.Pi, -0.5*math.Pi+2*v.precent*0.01*math.Pi)
|
||||
basiccard.Fill()
|
||||
|
||||
basiccard.SetRGBA255(255, 255, 255, 255)
|
||||
basiccard.DrawCircle((float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 80)
|
||||
basiccard.Fill()
|
||||
|
||||
err = basiccard.ParseFontFace(fontbyte, 42)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
basiccard.SetRGBA255(213, 213, 213, 255)
|
||||
basiccard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200/2, 0.5, 0.5)
|
||||
|
||||
basiccard.SetRGBA255(30, 30, 30, 255)
|
||||
_, fw := basiccard.MeasureString(v.name)
|
||||
basiccard.DrawStringAnchored(v.name, (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200+15+basiccard.FontHeight()/2, 0.5, 0.5)
|
||||
|
||||
err = basiccard.ParseFontFace(fontbyte, 20)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
basiccard.SetRGBA255(30, 30, 30, 180)
|
||||
|
||||
textoffsety := basiccard.FontHeight() + 10
|
||||
for k, s := range v.text {
|
||||
basiccard.DrawStringAnchored(s, (float64(basiccard.W())-200*float64(bslen))/float64(bslen+1)+200/2+offset, 20+200+15+fw+15+basiccard.FontHeight()/2+float64(k)*textoffsety, 0.5, 0.5)
|
||||
}
|
||||
}
|
||||
basicimg = rendercard.Fillet(basiccard.Image(), 16)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
diskcard := gg.NewContext(cardw, diskcardh)
|
||||
diskcard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40)
|
||||
|
||||
diskcard.DrawRoundedRectangle(1, 1, float64(diskcard.W()-1*2), float64(diskcardh-1*2), 16)
|
||||
diskcard.SetLineWidth(3)
|
||||
diskcard.SetRGBA255(255, 255, 255, 100)
|
||||
diskcard.StrokePreserve()
|
||||
diskcard.SetRGBA255(255, 255, 255, 140)
|
||||
diskcard.Fill()
|
||||
|
||||
err = diskcard.ParseFontFace(fontbyte, 32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dslen := len(diskstate)
|
||||
if dslen == 1 {
|
||||
diskcard.SetRGBA255(192, 192, 192, 255)
|
||||
diskcard.DrawRoundedRectangle(40, 40, float64(diskcard.W())-40-100, 50, 12)
|
||||
diskcard.Fill()
|
||||
|
||||
switch {
|
||||
case diskstate[0].precent > 90:
|
||||
diskcard.SetRGBA255(255, 70, 0, 255)
|
||||
case diskstate[0].precent > 70:
|
||||
diskcard.SetRGBA255(255, 165, 0, 255)
|
||||
default:
|
||||
diskcard.SetRGBA255(145, 240, 145, 255)
|
||||
}
|
||||
|
||||
diskcard.DrawRoundedRectangle(40, 40, (float64(diskcard.W())-40-100)*diskstate[0].precent*0.01, 50, 12)
|
||||
diskcard.Fill()
|
||||
|
||||
diskcard.SetRGBA255(30, 30, 30, 255)
|
||||
|
||||
fw, _ := diskcard.MeasureString(diskstate[0].name)
|
||||
fw1, _ := diskcard.MeasureString(diskstate[0].text[0])
|
||||
|
||||
diskcard.DrawStringAnchored(diskstate[0].name, 40+10+fw/2, 40+50/2, 0.5, 0.5)
|
||||
diskcard.DrawStringAnchored(diskstate[0].text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+50/2, 0.5, 0.5)
|
||||
diskcard.DrawStringAnchored(strconv.FormatFloat(diskstate[0].precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+50/2, 0.5, 0.5)
|
||||
} else {
|
||||
for i, v := range diskstate {
|
||||
offset := float64(i)*(50+20) - 20
|
||||
|
||||
diskcard.SetRGBA255(192, 192, 192, 255)
|
||||
diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, float64(diskcard.W())-40-100, 50, 12)
|
||||
diskcard.Fill()
|
||||
|
||||
switch {
|
||||
case v.precent > 90:
|
||||
diskcard.SetRGBA255(255, 70, 0, 255)
|
||||
case v.precent > 70:
|
||||
diskcard.SetRGBA255(255, 165, 0, 255)
|
||||
default:
|
||||
diskcard.SetRGBA255(145, 240, 145, 255)
|
||||
}
|
||||
|
||||
diskcard.DrawRoundedRectangle(40, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+offset, (float64(diskcard.W())-40-100)*v.precent*0.01, 50, 12)
|
||||
diskcard.Fill()
|
||||
|
||||
diskcard.SetRGBA255(30, 30, 30, 255)
|
||||
|
||||
fw, _ := diskcard.MeasureString(v.name)
|
||||
fw1, _ := diskcard.MeasureString(v.text[0])
|
||||
|
||||
diskcard.DrawStringAnchored(v.name, 40+10+fw/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5)
|
||||
diskcard.DrawStringAnchored(v.text[0], (float64(diskcard.W())-100-10)-fw1/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5)
|
||||
diskcard.DrawStringAnchored(strconv.FormatFloat(v.precent, 'f', 0, 64)+"%", float64(diskcard.W())-100/2, 40+(float64(diskcardh-40*2)-50*float64(dslen))/float64(dslen-1)+50/2+offset, 0.5, 0.5)
|
||||
}
|
||||
}
|
||||
diskimg = rendercard.Fillet(diskcard.Image(), 16)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
moreinfocard := gg.NewContext(cardw, moreinfocardh)
|
||||
|
||||
moreinfocard.DrawImage(imaging.Blur(canvas.Image(), 8), -70, -70-titlecardh-40-basiccardh-40-diskcardh-40)
|
||||
|
||||
moreinfocard.DrawRoundedRectangle(1, 1, float64(moreinfocard.W()-1*2), float64(moreinfocard.H()-1*2), 16)
|
||||
moreinfocard.SetLineWidth(3)
|
||||
moreinfocard.SetRGBA255(255, 255, 255, 100)
|
||||
moreinfocard.StrokePreserve()
|
||||
moreinfocard.SetRGBA255(255, 255, 255, 140)
|
||||
moreinfocard.Fill()
|
||||
|
||||
err = moreinfocard.ParseFontFace(fontbyte, 32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
milen := len(moreinfo)
|
||||
for i, v := range moreinfo {
|
||||
offset := float64(i)*(20+moreinfocard.FontHeight()) - 20
|
||||
|
||||
moreinfocard.SetRGBA255(30, 30, 30, 255)
|
||||
|
||||
fw, _ := moreinfocard.MeasureString(v.name)
|
||||
fw1, _ := moreinfocard.MeasureString(v.text[0])
|
||||
|
||||
moreinfocard.DrawStringAnchored(v.name, 20+fw/2, 30+(float64(moreinfocardh-30*2)-moreinfocard.FontHeight()*float64(milen))/float64(milen-1)+moreinfocard.FontHeight()/2+offset, 0.5, 0.5)
|
||||
moreinfocard.DrawStringAnchored(v.text[0], float64(moreinfocard.W())-20-fw1/2, 30+(float64(moreinfocardh-30*2)-moreinfocard.FontHeight()*float64(milen))/float64(milen-1)+moreinfocard.FontHeight()/2+offset, 0.5, 0.5)
|
||||
}
|
||||
moreinfoimg = rendercard.Fillet(moreinfocard.Image(), 16)
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
shadow := gg.NewContext(canvas.W(), canvas.H())
|
||||
shadow.SetRGBA255(0, 0, 0, 100)
|
||||
shadow.SetLineWidth(12)
|
||||
shadow.DrawRoundedRectangle(70, 70, float64(cardw), float64(titlecardh), 16)
|
||||
shadow.Stroke()
|
||||
shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40), float64(cardw), float64(basiccardh), 16)
|
||||
shadow.Stroke()
|
||||
shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40), float64(cardw), float64(basiccardh), 16)
|
||||
shadow.Stroke()
|
||||
shadow.DrawRoundedRectangle(70, float64(70+titlecardh+40+basiccardh+40+diskcardh+40), float64(cardw), float64(moreinfocardh), 16)
|
||||
shadow.Stroke()
|
||||
shadowimg = imaging.Blur(shadow.Image(), 24)
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
if shadowimg == nil || titleimg == nil || basicimg == nil || diskimg == nil || moreinfoimg == nil {
|
||||
err = errors.New("图片渲染失败")
|
||||
return
|
||||
}
|
||||
canvas.DrawImage(shadowimg, 0, 0)
|
||||
canvas.DrawImage(titleimg, 70, 70)
|
||||
canvas.DrawImage(basicimg, 70, 70+titlecardh+40)
|
||||
canvas.DrawImage(diskimg, 70, 70+titlecardh+40+basiccardh+40)
|
||||
canvas.DrawImage(moreinfoimg, 70, 70+titlecardh+40+basiccardh+40+diskcardh+40)
|
||||
|
||||
err = canvas.ParseFontFace(fontbyte, 28)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
canvas.SetRGBA255(0, 0, 0, 255)
|
||||
canvas.DrawStringAnchored("Created By ZeroBot-Plugin "+kanban.Version, float64(canvas.W())/2+3, float64(canvas.H())-70/2+3, 0.5, 0.5)
|
||||
canvas.SetRGBA255(255, 255, 255, 255)
|
||||
canvas.DrawStringAnchored("Created By ZeroBot-Plugin "+kanban.Version, float64(canvas.W())/2, float64(canvas.H())-70/2, 0.5, 0.5)
|
||||
|
||||
sendimg = canvas.Image()
|
||||
return
|
||||
}
|
||||
|
||||
func botruntime() (string, error) {
|
||||
hostinfo, err := host.Info()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
t := &strings.Builder{}
|
||||
t.WriteString("ZeroBot-Plugin 已运行 ")
|
||||
t.WriteString(strconv.FormatInt((time.Now().Unix()-boottime.Unix())/86400, 10))
|
||||
t.WriteString(" 天 ")
|
||||
t.WriteString(time.Unix(time.Now().Unix()-boottime.Unix(), 0).UTC().Format("15:04:05"))
|
||||
t.WriteString(" | 系统运行 ")
|
||||
t.WriteString(strconv.FormatInt(int64(hostinfo.Uptime)/86400, 10))
|
||||
t.WriteString(" 天 ")
|
||||
t.WriteString(time.Unix(int64(hostinfo.Uptime), 0).UTC().Format("15:04:05"))
|
||||
return t.String(), nil
|
||||
}
|
||||
|
||||
func botstatus() (string, error) {
|
||||
hostinfo, err := host.Info()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
t := &strings.Builder{}
|
||||
t.WriteString(time.Now().Format("2006-01-02 15:04:05"))
|
||||
t.WriteString(" | Compiled by ")
|
||||
t.WriteString(runtime.Version())
|
||||
t.WriteString(" | ")
|
||||
t.WriteString(cases.Title(language.English).String(hostinfo.OS))
|
||||
return t.String(), nil
|
||||
}
|
||||
|
||||
type status struct {
|
||||
precent float64
|
||||
name string
|
||||
text []string
|
||||
}
|
||||
|
||||
func basicstate() (stateinfo [3]*status, err error) {
|
||||
percent, err := cpu.Percent(time.Second, false)
|
||||
if err != nil {
|
||||
return -1
|
||||
return
|
||||
}
|
||||
return math.Round(percent[0])
|
||||
cpuinfo, err := cpu.Info()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cores := strconv.Itoa(int(cpuinfo[0].Cores)) + " Core"
|
||||
times := "最大 " + strconv.FormatFloat(cpuinfo[0].Mhz/1000, 'f', 1, 64) + "Ghz"
|
||||
|
||||
stateinfo[0] = &status{
|
||||
precent: math.Round(percent[0]),
|
||||
name: "CPU",
|
||||
text: []string{cores, times},
|
||||
}
|
||||
|
||||
raminfo, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
total := "总共 " + storagefmt(float64(raminfo.Total))
|
||||
used := "已用 " + storagefmt(float64(raminfo.Used))
|
||||
free := "剩余 " + storagefmt(float64(raminfo.Free))
|
||||
|
||||
stateinfo[1] = &status{
|
||||
precent: math.Round(raminfo.UsedPercent),
|
||||
name: "RAM",
|
||||
text: []string{total, used, free},
|
||||
}
|
||||
|
||||
swapinfo, err := mem.SwapMemory()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
total = "总共 " + storagefmt(float64(swapinfo.Total))
|
||||
used = "已用 " + storagefmt(float64(swapinfo.Used))
|
||||
free = "剩余 " + storagefmt(float64(swapinfo.Free))
|
||||
|
||||
stateinfo[2] = &status{
|
||||
precent: math.Round(swapinfo.UsedPercent),
|
||||
name: "SWAP",
|
||||
text: []string{total, used, free},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func memPercent() float64 {
|
||||
memInfo, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
return -1
|
||||
func storagefmt(num float64) string {
|
||||
if num /= 1024; num < 1 {
|
||||
return strconv.FormatFloat(num*1024, 'f', 2, 64) + "B"
|
||||
}
|
||||
return math.Round(memInfo.UsedPercent)
|
||||
if num /= 1024; num < 1 {
|
||||
return strconv.FormatFloat(num*1024, 'f', 2, 64) + "KB"
|
||||
}
|
||||
if num /= 1024; num < 1 {
|
||||
return strconv.FormatFloat(num*1024, 'f', 2, 64) + "MB"
|
||||
}
|
||||
if num /= 1024; num < 1 {
|
||||
return strconv.FormatFloat(num*1024, 'f', 2, 64) + "GB"
|
||||
}
|
||||
return strconv.FormatFloat(num, 'f', 2, 64) + "TB"
|
||||
}
|
||||
|
||||
func diskPercent() string {
|
||||
parts, err := disk.Partitions(true)
|
||||
func diskstate() (stateinfo []*status, err error) {
|
||||
parts, err := disk.Partitions(false)
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
return
|
||||
}
|
||||
msg := ""
|
||||
for _, p := range parts {
|
||||
diskInfo, err := disk.Usage(p.Mountpoint)
|
||||
stateinfo = make([]*status, len(parts))
|
||||
for i, v := range parts {
|
||||
mp := v.Mountpoint
|
||||
diskusage, err := disk.Usage(mp)
|
||||
usage := ""
|
||||
precent := 0.0
|
||||
if err != nil {
|
||||
msg += "\n - " + err.Error()
|
||||
continue
|
||||
usage = err.Error()
|
||||
} else {
|
||||
usage = storagefmt(float64(diskusage.Used)) + " / " + storagefmt(float64(diskusage.Total))
|
||||
precent = math.Round(diskusage.UsedPercent)
|
||||
}
|
||||
pc := uint(math.Round(diskInfo.UsedPercent))
|
||||
if pc > 0 {
|
||||
msg += fmt.Sprintf("\n - %s(%dM) %d%%", p.Mountpoint, diskInfo.Total/1024/1024, pc)
|
||||
stateinfo[i] = &status{
|
||||
precent: precent,
|
||||
name: mp,
|
||||
text: []string{usage},
|
||||
}
|
||||
}
|
||||
return msg
|
||||
return stateinfo, nil
|
||||
}
|
||||
|
||||
func moreinfo(m *ctrl.Control[*zero.Ctx]) (stateinfo []*status, err error) {
|
||||
hostinfo, err := host.Info()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cpuinfo, err := cpu.Info()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
count := len(m.Manager.M)
|
||||
stateinfo = []*status{
|
||||
{name: "OS", text: []string{hostinfo.Platform}},
|
||||
{name: "CPU", text: []string{cpuinfo[0].ModelName}},
|
||||
{name: "Version", text: []string{hostinfo.PlatformVersion}},
|
||||
{name: "Plugin", text: []string{"共 " + strconv.Itoa(count) + " 个"}},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,92 +2,42 @@ package aireply
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"regexp"
|
||||
"sync"
|
||||
"net/url"
|
||||
|
||||
"github.com/RomiChan/syncx"
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/aireply"
|
||||
"github.com/FloatTech/AnimeAPI/tts"
|
||||
"github.com/FloatTech/AnimeAPI/tts/baidutts"
|
||||
"github.com/FloatTech/AnimeAPI/tts/genshin"
|
||||
"github.com/FloatTech/AnimeAPI/tts/mockingbird"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
)
|
||||
|
||||
// 数据结构: [4 bits] [4 bits] [8 bits] [8 bits]
|
||||
// [拟声鸟模式] [百度模式] [tts模式] [回复模式]
|
||||
|
||||
// defaultttsindexkey
|
||||
// 数据结构: [4 bits] [4 bits] [8 bits]
|
||||
// [拟声鸟模式] [百度模式] [tts模式]
|
||||
|
||||
// [tts模式]: 0~63 genshin 64 baidu 65 mockingbird
|
||||
|
||||
const (
|
||||
cnapi = "https://genshin.azurewebsites.net/api/speak?format=mp3&id=%d&text=%s"
|
||||
lastgsttsindex = 63 + iota
|
||||
baiduttsindex
|
||||
mockingbirdttsindex
|
||||
)
|
||||
|
||||
// 每个角色的测试文案
|
||||
var testRecord = map[string]string{
|
||||
"派蒙": "哎,又是看不懂的东西。我完全不知道这些奇怪的问题和实验,能得到什么结果…",
|
||||
"凯亚": "真是个急性子啊你。",
|
||||
"安柏": "最初的鸟儿是不会飞翔的,飞翔是它们勇敢跃入峡谷的奖励。",
|
||||
"丽莎": "嗨,小可爱,你是新来的助理吗?",
|
||||
"琴": "蒲公英骑士,琴,申请入队。",
|
||||
"香菱": "我是来自璃月的厨师香菱,最擅长的是做各种捞…捞,料理…哎呀,练了那么多次,还是会紧张,嘿。",
|
||||
"枫原万叶": "飘摇风雨中,带刀归来赤脚行。",
|
||||
"迪卢克": "在黎明来临之前,总要有人照亮黑暗。",
|
||||
"温迪": "若你困于无风之地,我将为你奏响高天之歌。",
|
||||
"可莉": "西风骑士团,火花骑士,可莉,前来报到!…呃—后面该说什么词来着?可莉背不下来啦...",
|
||||
"早柚": "终末番,早柚,参上。 呼——",
|
||||
"托马": "初次见面,异乡的旅人,你的名字我可是早就听说了。只要你不嫌弃,我托马,从今天起就是你的朋友了。",
|
||||
"芭芭拉": "芭芭拉,闪耀登场~治疗就交给我吧,不会让你失望的!",
|
||||
"优菈": "沉沦是很容易的一件事,但我仍想冻住这股潮流。",
|
||||
"云堇": "曲高未必人不识,自有知音和清词。",
|
||||
"钟离": "人间归离复归离,借一浮生逃浮生。",
|
||||
"魈": "三眼五显仙人,魈,听召,前来守护",
|
||||
"凝光": "就算古玩价值连城,给人的快乐,也只有刚拥有的一瞬",
|
||||
"雷电将军": "浮世千百年来风景依旧,人之在世却如白露与泡影。",
|
||||
"北斗": "不知道如何向前的话,总之先迈出第一步,后面的道路就会自然而然地展开了。",
|
||||
"甘雨": "这项工作,该划掉了。",
|
||||
"七七": "椰羊的奶,好喝!比一般的羊奶,好喝!",
|
||||
"刻晴": "劳逸结合是不错,但也别放松过头。",
|
||||
"神里绫华": "若知是梦何须醒,不比真如一相会。",
|
||||
"雷泽": "你是朋友。我和你一起狩猎。",
|
||||
"神里绫人": "此前听绫华屡次提起阁下,不料公务繁忙,直至今日才有机会相见。",
|
||||
"罗莎莉亚": "哪怕如今你已经走上截然不同的道路,也不要否认从前的自己,从前的每一个你都是你脚下的基石,不要害怕过去,不要畏惧与它抗衡。",
|
||||
"阿贝多": "用自己的双脚丈量土地,将未知变为知识。",
|
||||
"八重神子": "我的神明,就托付给你了。",
|
||||
"宵宫": "即使只是片刻的火花,也能在仰望黑夜的人心中留下久久不灭的美丽光芒。",
|
||||
"荒泷一斗": "更好地活下去,绝不该靠牺牲同类换取,应该是,一起更好地活着,才对。",
|
||||
"九条裟罗": "想要留住雪花。但在手心里,它只会融化的更快。",
|
||||
"夜兰": "线人来信了,嗯,看来又出现了新的变数。",
|
||||
"珊瑚宫心海": "成为了现任人神巫女之后,我也慢慢习惯了这样的生活,更重要的是我也因此和你相遇了,不是吗?",
|
||||
"五郎": "海祇岛反抗军大将,五郎,前来助阵!",
|
||||
"达达利亚": "许下的诺言就好好遵守,做错了事情就承担责任,这才是家人应有的样子吧。",
|
||||
"莫娜": "正是因为无法更改,无可违逆,只能接受,命运才会被称之为命运。",
|
||||
"班尼特": "只要有大家在,伤口就不会痛!",
|
||||
"申鹤": "不知道你是喜欢人间的灯火,还是山林的月光?",
|
||||
"行秋": "有时明月无人夜,独向昭潭制恶龙。",
|
||||
"烟绯": "律法即是约束,也是工具。",
|
||||
"久岐忍": "有麻烦事要处理的话,直接告诉我就好,我来摆平。",
|
||||
"辛焱": "马上就要演出了,你也一起来嗨吗?",
|
||||
"砂糖": "我是砂糖,炼金术的…研究员。",
|
||||
"胡桃": "阴阳有序,命运无常,死亡难以预测,却也有它的规矩。",
|
||||
"重云": "我名重云,家族久居璃月,世代以驱邪除魔为业。",
|
||||
"菲谢尔": "我即断罪之皇女,真名为菲谢尔。应命运的召唤降临在此间——哎?你也是,异世界的旅人吗…?",
|
||||
"诺艾尔": "我是诺艾尔,西风骑士团的女仆,从今天起会陪你一起去冒险。",
|
||||
"迪奥娜": "猫尾酒馆的招牌调酒师,迪奥娜,我的出场费可是很贵的。",
|
||||
"鹿野院平藏": "我叫鹿野院平藏,是天领奉行里破案最多最快的侦探……",
|
||||
}
|
||||
|
||||
var (
|
||||
re = regexp.MustCompile(`(\-|\+)?\d+(\.\d+)?`)
|
||||
soundList = [...]string{
|
||||
"派蒙", "凯亚", "安柏", "丽莎", "琴",
|
||||
"香菱", "枫原万叶", "迪卢克", "温迪", "可莉",
|
||||
"早柚", "托马", "芭芭拉", "优菈", "云堇",
|
||||
"钟离", "魈", "凝光", "雷电将军", "北斗",
|
||||
"甘雨", "七七", "刻晴", "神里绫华", "雷泽",
|
||||
"神里绫人", "罗莎莉亚", "阿贝多", "八重神子", "宵宫",
|
||||
"荒泷一斗", "九条裟罗", "夜兰", "珊瑚宫心海", "五郎",
|
||||
"达达利亚", "莫娜", "班尼特", "申鹤", "行秋",
|
||||
"烟绯", "久岐忍", "辛焱", "砂糖", "胡桃",
|
||||
"重云", "菲谢尔", "诺艾尔", "迪奥娜", "鹿野院平藏",
|
||||
}
|
||||
const (
|
||||
defaultttsindexkey = -2905
|
||||
)
|
||||
|
||||
/*************************************************************
|
||||
*******************************AIreply************************
|
||||
*************************************************************/
|
||||
var replyModes = [...]string{"青云客", "小爱"}
|
||||
|
||||
func setReplyMode(ctx *zero.Ctx, name string) error {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
@@ -109,30 +59,41 @@ func setReplyMode(ctx *zero.Ctx, name string) error {
|
||||
if !ok {
|
||||
return errors.New("no such plugin")
|
||||
}
|
||||
return m.SetData(gid, index)
|
||||
return m.SetData(gid, (m.GetData(index)&^0xff)|(index&0xff))
|
||||
}
|
||||
|
||||
func getReplyMode(ctx *zero.Ctx) (name string) {
|
||||
func getReplyMode(ctx *zero.Ctx) aireply.AIReply {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
m, ok := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
if ok {
|
||||
index := m.GetData(gid)
|
||||
if int(index) < len(replyModes) {
|
||||
return replyModes[index]
|
||||
if m.GetData(gid)&0xff == 1 {
|
||||
return aireply.NewXiaoAi(aireply.XiaoAiURL, aireply.XiaoAiBotName)
|
||||
}
|
||||
return aireply.NewQYK(aireply.QYKURL, aireply.QYKBotName)
|
||||
}
|
||||
return "青云客"
|
||||
return aireply.NewQYK(aireply.QYKURL, aireply.QYKBotName)
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
***********************tts************************************
|
||||
*************************************************************/
|
||||
var ttsins = func() map[string]tts.TTS {
|
||||
m := make(map[string]tts.TTS, 128)
|
||||
for _, mode := range append(genshin.SoundList[:], "百度", "拟声鸟") {
|
||||
m[mode] = nil
|
||||
}
|
||||
return m
|
||||
}()
|
||||
|
||||
var ttsModes = func() []string {
|
||||
s := append(genshin.SoundList[:], make([]string, 64-len(genshin.SoundList))...) // 0-63
|
||||
s = append(s, "百度", "拟声鸟") // 64 65
|
||||
return s
|
||||
}()
|
||||
|
||||
type ttsmode struct {
|
||||
sync.RWMutex
|
||||
mode map[int64]int64
|
||||
APIKey string // APIKey is for genshin vits
|
||||
mode syncx.Map[int64, int64] `json:"-"` // mode grp index
|
||||
}
|
||||
|
||||
func list(list []string, num int) string {
|
||||
@@ -149,90 +110,142 @@ func list(list []string, num int) string {
|
||||
}
|
||||
|
||||
func newttsmode() *ttsmode {
|
||||
tts := &ttsmode{}
|
||||
tts.Lock()
|
||||
defer tts.Unlock()
|
||||
t := &ttsmode{}
|
||||
m, ok := control.Lookup("tts")
|
||||
tts.mode = make(map[int64]int64, 2*len(soundList))
|
||||
tts.mode[-2905] = 1
|
||||
t.mode = syncx.Map[int64, int64]{}
|
||||
t.mode.Store(defaultttsindexkey, 0)
|
||||
if ok {
|
||||
index := m.GetData(-2905)
|
||||
if index > 0 && index < int64(len(soundList)) {
|
||||
tts.mode[-2905] = index
|
||||
index := m.GetData(defaultttsindexkey)
|
||||
msk := index & 0xff
|
||||
if msk >= 0 && (msk < int64(len(genshin.SoundList)) || msk == baiduttsindex || msk == mockingbirdttsindex) {
|
||||
t.mode.Store(defaultttsindexkey, index)
|
||||
}
|
||||
}
|
||||
return tts
|
||||
return t
|
||||
}
|
||||
|
||||
func (tts *ttsmode) setSoundMode(ctx *zero.Ctx, name string) error {
|
||||
func (t *ttsmode) getAPIKey(ctx *zero.Ctx) string {
|
||||
if t.APIKey == "" {
|
||||
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
_ = m.Manager.GetExtra(-1, &t)
|
||||
logrus.Debugln("[tts] get api key:", t.APIKey)
|
||||
}
|
||||
return url.QueryEscape(t.APIKey)
|
||||
}
|
||||
|
||||
func (t *ttsmode) setAPIKey(m *ctrl.Control[*zero.Ctx], key string) error {
|
||||
t.APIKey = key
|
||||
_ = m.Manager.Response(-1)
|
||||
return m.Manager.SetExtra(-1, t)
|
||||
}
|
||||
|
||||
func (t *ttsmode) setSoundMode(ctx *zero.Ctx, name string, baiduper, mockingsynt int) error {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
var index int64
|
||||
for i, s := range soundList {
|
||||
_, ok := ttsins[name]
|
||||
if !ok {
|
||||
return errors.New("不支持设置语音人物" + name)
|
||||
}
|
||||
var index = int64(-1)
|
||||
for i, s := range genshin.SoundList {
|
||||
if s == name {
|
||||
index = int64(i + 1)
|
||||
index = int64(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if index == 0 {
|
||||
return errors.New("不支持设置语音人物" + name)
|
||||
if index == -1 {
|
||||
switch name {
|
||||
case "百度":
|
||||
index = baiduttsindex
|
||||
case "拟声鸟":
|
||||
index = mockingbirdttsindex
|
||||
default:
|
||||
return errors.New("语音人物" + name + "未注册index")
|
||||
}
|
||||
}
|
||||
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
tts.Lock()
|
||||
defer tts.Unlock()
|
||||
tts.mode[gid] = index
|
||||
return m.SetData(gid, index)
|
||||
t.mode.Store(gid, index)
|
||||
return m.SetData(gid, (m.GetData(gid)&^0xffff00)|((index<<8)&0xff00)|((int64(baiduper)<<16)&0x0f0000)|((int64(mockingsynt)<<20)&0xf00000))
|
||||
}
|
||||
|
||||
func (tts *ttsmode) getSoundMode(ctx *zero.Ctx) int64 {
|
||||
func (t *ttsmode) getSoundMode(ctx *zero.Ctx) (tts.TTS, error) {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
tts.Lock()
|
||||
defer tts.Unlock()
|
||||
i, ok := tts.mode[gid]
|
||||
i, ok := t.mode.Load(gid)
|
||||
if !ok {
|
||||
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
i = m.GetData(gid)
|
||||
i = m.GetData(gid) >> 8
|
||||
}
|
||||
if i <= 0 || i >= int64(len(soundList)) {
|
||||
i = tts.mode[-2905]
|
||||
m := i & 0xff
|
||||
if m < 0 || (m >= int64(len(genshin.SoundList)) && m != baiduttsindex && m != mockingbirdttsindex) {
|
||||
i, _ = t.mode.Load(defaultttsindexkey)
|
||||
m = i & 0xff
|
||||
}
|
||||
return i - 1
|
||||
mode := ttsModes[m]
|
||||
ins, ok := ttsins[mode]
|
||||
if !ok || ins == nil {
|
||||
switch mode {
|
||||
case "百度":
|
||||
ins = baidutts.NewBaiduTTS(int(i&0x0f00) >> 8)
|
||||
case "拟声鸟":
|
||||
var err error
|
||||
ins, err = mockingbird.NewMockingBirdTTS(int(i&0xf000) >> 12)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default: // 原神
|
||||
k := t.getAPIKey(ctx)
|
||||
if k != "" {
|
||||
ins = genshin.NewGenshin(int(m), t.getAPIKey(ctx))
|
||||
ttsins[mode] = ins
|
||||
} else {
|
||||
return nil, errors.New("no valid speaker")
|
||||
}
|
||||
}
|
||||
}
|
||||
return ins, nil
|
||||
}
|
||||
|
||||
func (tts *ttsmode) resetSoundMode(ctx *zero.Ctx) error {
|
||||
func (t *ttsmode) resetSoundMode(ctx *zero.Ctx) error {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
tts.Lock()
|
||||
defer tts.Unlock()
|
||||
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
tts.mode[gid] = 0
|
||||
return m.SetData(gid, 0) // 重置数据
|
||||
index := m.GetData(defaultttsindexkey)
|
||||
return m.SetData(gid, (m.GetData(gid)&0xff)|((index&^0xff)<<8)) // 重置数据
|
||||
}
|
||||
|
||||
func (tts *ttsmode) setDefaultSoundMode(name string) error {
|
||||
var index int64
|
||||
for i, s := range soundList {
|
||||
func (t *ttsmode) setDefaultSoundMode(name string, baiduper, mockingsynt int) error {
|
||||
_, ok := ttsins[name]
|
||||
if !ok {
|
||||
return errors.New("不支持设置语音人物" + name)
|
||||
}
|
||||
index := int64(-1)
|
||||
for i, s := range genshin.SoundList {
|
||||
if s == name {
|
||||
index = int64(i + 1)
|
||||
index = int64(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if index == 0 {
|
||||
return errors.New("不支持设置语音人物" + name)
|
||||
if index == -1 {
|
||||
switch name {
|
||||
case "百度":
|
||||
index = baiduttsindex
|
||||
case "拟声鸟":
|
||||
index = mockingbirdttsindex
|
||||
default:
|
||||
return errors.New("语音人物" + name + "未注册index")
|
||||
}
|
||||
}
|
||||
tts.Lock()
|
||||
defer tts.Unlock()
|
||||
m, ok := control.Lookup("tts")
|
||||
if !ok {
|
||||
return errors.New("[tts] service not found")
|
||||
}
|
||||
tts.mode[-2905] = index
|
||||
return m.SetData(-2905, index)
|
||||
t.mode.Store(defaultttsindexkey, index)
|
||||
return m.SetData(defaultttsindexkey, (index&0xff)|((int64(baiduper)<<8)&0x0f00)|((int64(mockingsynt)<<12)&0xf000))
|
||||
}
|
||||
|
||||
@@ -2,46 +2,44 @@
|
||||
package aireply
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/aireply"
|
||||
"github.com/FloatTech/AnimeAPI/tts/genshin"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/pkumza/numcn"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
var replyModes = [...]string{"青云客", "小爱"}
|
||||
var t = newttsmode()
|
||||
|
||||
func init() { // 插件主体
|
||||
enOftts := control.Register("tts", &ctrl.Options[*zero.Ctx]{
|
||||
ent := control.Register("tts", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: true,
|
||||
Brief: "人工智能语音回复",
|
||||
Help: "- @Bot 任意文本(任意一句话回复)\n" +
|
||||
"- 设置语音模式[原神人物]\n" +
|
||||
"- 设置默认语音模式[原神人物]\n" +
|
||||
"- 设置语音模式[原神人物/百度/拟声鸟] 数字(百度/拟声鸟模式)\n" +
|
||||
"- 设置默认语音模式[原神人物/百度/拟声鸟] 数字(百度/拟声鸟模式)\n" +
|
||||
"- 恢复成默认语音模式\n" +
|
||||
"当前适用的原神人物含有以下:\n" + list(soundList[:], 5),
|
||||
"- 设置原神语音 api key xxxxxx (key请加开发群获得)\n" +
|
||||
"当前适用的原神人物含有以下:\n" + list(genshin.SoundList[:], 5),
|
||||
})
|
||||
tts := newttsmode()
|
||||
enOfreply := control.Register("aireply", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "人工智能回复",
|
||||
Help: "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客|小爱]",
|
||||
|
||||
enr := control.Register("aireply", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "人工智能回复",
|
||||
Help: "- @Bot 任意文本(任意一句话回复)\n- 设置回复模式[青云客|小爱]",
|
||||
PrivateDataFolder: "aireply",
|
||||
})
|
||||
/*************************************************************
|
||||
*******************************AIreply************************
|
||||
*************************************************************/
|
||||
enOfreply.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
|
||||
enr.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
aireply := aireply.NewAIReply(getReplyMode(ctx))
|
||||
reply := message.ParseMessageFromString(aireply.Talk(ctx.ExtractPlainText(), zero.BotConfig.NickName[0]))
|
||||
aireply := getReplyMode(ctx)
|
||||
reply := message.ParseMessageFromString(aireply.Talk(ctx.Event.UserID, ctx.ExtractPlainText(), zero.BotConfig.NickName[0]))
|
||||
// 回复
|
||||
time.Sleep(time.Second * 1)
|
||||
if zero.OnlyPublic(ctx) {
|
||||
@@ -51,7 +49,8 @@ func init() { // 插件主体
|
||||
}
|
||||
ctx.Send(reply)
|
||||
})
|
||||
enOfreply.OnPrefix("设置回复模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
|
||||
enr.OnPrefix("设置回复模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
param := ctx.State["args"].(string)
|
||||
err := setReplyMode(ctx, param)
|
||||
if err != nil {
|
||||
@@ -60,86 +59,122 @@ func init() { // 插件主体
|
||||
}
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功"))
|
||||
})
|
||||
/*************************************************************
|
||||
***********************tts************************************
|
||||
*************************************************************/
|
||||
enOftts.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
|
||||
endpre := regexp.MustCompile(`\pP$`)
|
||||
ent.OnMessage(zero.OnlyToMe).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
msg := ctx.ExtractPlainText()
|
||||
// 获取回复模式
|
||||
r := aireply.NewAIReply(getReplyMode(ctx))
|
||||
r := getReplyMode(ctx)
|
||||
// 获取回复的文本
|
||||
reply := r.TalkPlain(msg, zero.BotConfig.NickName[0])
|
||||
reply := r.TalkPlain(ctx.Event.UserID, msg, zero.BotConfig.NickName[0])
|
||||
// 获取语音
|
||||
index := tts.getSoundMode(ctx)
|
||||
record := message.Record(fmt.Sprintf(cnapi, index, url.QueryEscape(
|
||||
// 将数字转文字
|
||||
re.ReplaceAllStringFunc(reply, func(s string) string {
|
||||
f, err := strconv.ParseFloat(s, 64)
|
||||
if err != nil {
|
||||
log.Errorln("[tts]:", err)
|
||||
return s
|
||||
}
|
||||
return numcn.EncodeFromFloat64(f)
|
||||
}),
|
||||
))).Add("cache", 0)
|
||||
speaker, err := t.getSoundMode(ctx)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
rec, err := speaker.Speak(ctx.Event.UserID, func() string {
|
||||
if !endpre.MatchString(reply) {
|
||||
return reply + "。"
|
||||
}
|
||||
return reply
|
||||
})
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply))
|
||||
return
|
||||
}
|
||||
// 发送语音
|
||||
if ID := ctx.SendChain(record); ID.ID() == 0 {
|
||||
if id := ctx.SendChain(message.Record(rec)); id.ID() == 0 {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(reply))
|
||||
}
|
||||
})
|
||||
enOftts.OnRegex(`^设置语音模式(.*)$`, zero.AdminPermission, func(ctx *zero.Ctx) bool {
|
||||
|
||||
ent.OnRegex(`^设置语音模式\s*([\S\D]*)\s*(\d*)$`, zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
param := ctx.State["regex_matched"].([]string)[1]
|
||||
if _, ok := testRecord[param]; !ok {
|
||||
return false
|
||||
num := ctx.State["regex_matched"].([]string)[2]
|
||||
n := 0
|
||||
var err error
|
||||
if num != "" {
|
||||
n, err = strconv.Atoi(num)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
return true
|
||||
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
param := ctx.State["regex_matched"].([]string)[1]
|
||||
// 保存设置
|
||||
err := tts.setSoundMode(ctx, param)
|
||||
logrus.Debugln("[tts] t.setSoundMode( ctx", param, n, n, ")")
|
||||
err = t.setSoundMode(ctx, param, n, n)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
|
||||
return
|
||||
}
|
||||
// 设置验证
|
||||
i := tts.getSoundMode(ctx)
|
||||
if _, ok := testRecord[soundList[i]]; !ok {
|
||||
ctx.SendChain(message.Text("配置的语音人物数据丢失!请重新设置语音人物。"))
|
||||
return
|
||||
if banner, ok := genshin.TestRecord[param]; ok {
|
||||
logrus.Debugln("[tts] banner:", banner, "get sound mode...")
|
||||
// 设置验证
|
||||
speaker, err := t.getSoundMode(ctx)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
logrus.Debugln("[tts] got sound mode, speaking...")
|
||||
rec, err := speaker.Speak(ctx.Event.UserID, func() string { return banner })
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无法发送测试语音,请重试。"))
|
||||
return
|
||||
}
|
||||
logrus.Debugln("[tts] sending...")
|
||||
if id := ctx.SendChain(message.Record(rec).Add("cache", 0)); id.ID() == 0 {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("无法发送测试语音,请重试。"))
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Second * 2)
|
||||
}
|
||||
record := message.Record(fmt.Sprintf(cnapi, i, url.QueryEscape(testRecord[soundList[i]]))).Add("cache", 0)
|
||||
if ID := ctx.SendChain(record); ID.ID() == 0 {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置失败!无法发送测试语音,请重试。"))
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Second * 2)
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功"))
|
||||
})
|
||||
enOftts.OnRegex(`^设置默认语音模式(.*)$`, zero.SuperUserPermission, func(ctx *zero.Ctx) bool {
|
||||
|
||||
ent.OnRegex(`^设置默认语音模式\s*([\S\D]*)\s*(\d*)$`, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
param := ctx.State["regex_matched"].([]string)[1]
|
||||
if _, ok := testRecord[param]; !ok {
|
||||
return false
|
||||
num := ctx.State["regex_matched"].([]string)[2]
|
||||
n := 0
|
||||
var err error
|
||||
if num != "" {
|
||||
n, err = strconv.Atoi(num)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
return true
|
||||
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
param := ctx.State["regex_matched"].([]string)[1]
|
||||
// 保存设置
|
||||
err := tts.setDefaultSoundMode(param)
|
||||
err = t.setDefaultSoundMode(param, n, n)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功"))
|
||||
})
|
||||
enOftts.OnFullMatch("恢复成默认语音模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
err := tts.resetSoundMode(ctx)
|
||||
|
||||
ent.OnFullMatch("恢复成默认语音模式", zero.AdminPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
err := t.resetSoundMode(ctx)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text(err))
|
||||
return
|
||||
}
|
||||
// 设置验证
|
||||
index := tts.getSoundMode(ctx)
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", soundList[index]))
|
||||
speaker, err := t.getSoundMode(ctx)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("设置成功,当前为", speaker))
|
||||
})
|
||||
|
||||
ent.OnRegex(`^设置原神语音\s*api\s*key\s*([0-9a-zA-Z-_]{54}==)$`, zero.OnlyPrivate, zero.SuperUserPermission).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
err := t.setAPIKey(ctx.State["manager"].(*ctrl.Control[*zero.Ctx]), ctx.State["regex_matched"].([]string)[1])
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("设置成功"))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ func init() { // 插件主体
|
||||
"- 设置ai绘图配置 [server] [token]\n" +
|
||||
"- 设置ai绘图撤回时间90s\n" +
|
||||
"- 查看ai绘图配置\n" +
|
||||
"例: 设置ai绘图配置 http://91.217.139.190:5010 abc\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" +
|
||||
"通过 http://91.217.139.190:5010/token 获取token\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" +
|
||||
"参数与参数内容用:连接,每个参数之间用回车分割",
|
||||
@@ -146,7 +146,7 @@ func init() { // 插件主体
|
||||
}
|
||||
sendAiImg(ctx, data, cfg.Interval)
|
||||
})
|
||||
engine.OnRegex(`^设置ai绘图配置\s(.*[^\s$])\s(.+)$`, zero.SuperUserPermission).SetBlock(true).
|
||||
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()
|
||||
@@ -159,8 +159,7 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf("成功设置\nbase_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval)
|
||||
ctx.SendChain(message.Text(text))
|
||||
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) {
|
||||
@@ -180,18 +179,16 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
text := fmt.Sprintf("成功设置\nbase_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval)
|
||||
ctx.SendChain(message.Text(text))
|
||||
ctx.SendChain(message.Text("成功设置撤回时间为", cfg.Interval, "s"))
|
||||
})
|
||||
engine.OnFullMatch(`查看ai绘图配置`, zero.SuperUserPermission).SetBlock(true).
|
||||
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
|
||||
}
|
||||
text := fmt.Sprintf("base_url: %v\ntoken: %v\ninterval: %v\n", cfg.BaseURL, cfg.Token, cfg.Interval)
|
||||
ctx.SendChain(message.Text(text))
|
||||
ctx.SendChain(message.Text("base_url: ", cfg.BaseURL, "\ntoken: ", cfg.Token, "\ninterval: ", cfg.Interval))
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
)
|
||||
|
||||
type context struct {
|
||||
@@ -27,13 +28,14 @@ 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", true)
|
||||
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", true)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -6,18 +6,46 @@ Package atri 本文件基于 https://github.com/Kyomotoi/ATRI
|
||||
package atri
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
)
|
||||
|
||||
const res = "https://gitcode.net/u011570312/zbpdata/-/raw/main/Atri/"
|
||||
type datagetter func(string, bool) ([]byte, error)
|
||||
|
||||
func (dgtr datagetter) randImage(file ...string) message.MessageSegment {
|
||||
data, err := dgtr(file[rand.Intn(len(file))], true)
|
||||
if err != nil {
|
||||
return message.Text("ERROR: ", err)
|
||||
}
|
||||
return message.ImageBytes(data)
|
||||
}
|
||||
|
||||
func (dgtr datagetter) randRecord(file ...string) message.MessageSegment {
|
||||
data, err := dgtr(file[rand.Intn(len(file))], true)
|
||||
if err != nil {
|
||||
return message.Text("ERROR: ", err)
|
||||
}
|
||||
return message.Record("base64://" + base64.StdEncoding.EncodeToString(data))
|
||||
}
|
||||
|
||||
func randText(text ...string) message.MessageSegment {
|
||||
return message.Text(text[rand.Intn(len(text))])
|
||||
}
|
||||
|
||||
// isAtriSleeping 凌晨0点到6点,ATRI 在睡觉,不回应任何请求
|
||||
func isAtriSleeping(ctx *zero.Ctx) bool {
|
||||
if now := time.Now().Hour(); now >= 1 && now < 6 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func init() { // 插件主体
|
||||
engine := control.Register("atri", &ctrl.Options[*zero.Ctx]{
|
||||
@@ -29,39 +57,36 @@ func init() { // 插件主体
|
||||
"- 中午好 | 午安 | 午好\n- 晚安 | oyasuminasai | おやすみなさい | 晚好 | 晚上好\n- 高性能 | 太棒了 | すごい | sugoi | 斯国一 | よかった\n" +
|
||||
"- 没事 | 没关系 | 大丈夫 | 还好 | 不要紧 | 没出大问题 | 没伤到哪\n- 好吗 | 是吗 | 行不行 | 能不能 | 可不可以\n- 啊这\n- 我好了\n- ? | ? | ¿\n" +
|
||||
"- 离谱\n- 答应我",
|
||||
PublicDataFolder: "Atri",
|
||||
OnEnable: func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Text("嗯呜呜……夏生先生……?"))
|
||||
},
|
||||
OnDisable: func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Text("Zzz……Zzz……"))
|
||||
},
|
||||
})
|
||||
engine.OnFullMatch("萝卜子", isAtriSleeping).SetBlock(true).
|
||||
engine.UsePreHandler(isAtriSleeping)
|
||||
var dgtr datagetter = engine.GetLazyData
|
||||
engine.OnFullMatch("萝卜子").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
switch rand.Intn(2) {
|
||||
case 0:
|
||||
ctx.SendChain(randText("萝卜子是对机器人的蔑称!", "是亚托莉......萝卜子可是对机器人的蔑称"))
|
||||
case 1:
|
||||
ctx.SendChain(randRecord("RocketPunch.amr"))
|
||||
ctx.SendChain(dgtr.randRecord("RocketPunch.amr"))
|
||||
}
|
||||
})
|
||||
engine.OnFullMatchGroup([]string{"喜欢", "爱你", "爱", "suki", "daisuki", "すき", "好き", "贴贴", "老婆", "亲一个", "mua"}, isAtriSleeping, zero.OnlyToMe).SetBlock(true).
|
||||
engine.OnFullMatchGroup([]string{"喜欢", "爱你", "爱", "suki", "daisuki", "すき", "好き", "贴贴", "老婆", "亲一个", "mua"}, zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(randImage("SUKI.jpg", "SUKI1.jpg", "SUKI2.png"))
|
||||
ctx.SendChain(dgtr.randImage("SUKI.jpg", "SUKI1.jpg", "SUKI2.png"))
|
||||
})
|
||||
engine.OnKeywordGroup([]string{"草你妈", "操你妈", "脑瘫", "废柴", "fw", "five", "废物", "战斗", "爬", "爪巴", "sb", "SB", "傻B"}, isAtriSleeping, zero.OnlyToMe).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"草你妈", "操你妈", "脑瘫", "废柴", "fw", "five", "废物", "战斗", "爬", "爪巴", "sb", "SB", "傻B"}, zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(randImage("FN.jpg", "WQ.jpg", "WQ1.jpg"))
|
||||
ctx.SendChain(dgtr.randImage("FN.jpg", "WQ.jpg", "WQ1.jpg"))
|
||||
})
|
||||
engine.OnFullMatchGroup([]string{"早安", "早哇", "早上好", "ohayo", "哦哈哟", "お早う", "早好", "早", "早早早"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
now := time.Now().Hour()
|
||||
process.SleepAbout1sTo2s()
|
||||
switch {
|
||||
case now < 6: // 凌晨
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
|
||||
@@ -102,7 +127,6 @@ func init() { // 插件主体
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
now := time.Now().Hour()
|
||||
if now > 11 && now < 15 { // 中午
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
|
||||
"午安w",
|
||||
"午觉要好好睡哦,ATRI会陪伴在你身旁的w",
|
||||
@@ -114,7 +138,6 @@ func init() { // 插件主体
|
||||
engine.OnFullMatchGroup([]string{"晚安", "oyasuminasai", "おやすみなさい", "晚好", "晚上好"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
now := time.Now().Hour()
|
||||
process.SleepAbout1sTo2s()
|
||||
switch {
|
||||
case now < 6: // 凌晨
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText(
|
||||
@@ -154,9 +177,8 @@ func init() { // 插件主体
|
||||
))
|
||||
}
|
||||
})
|
||||
engine.OnKeywordGroup([]string{"高性能", "太棒了", "すごい", "sugoi", "斯国一", "よかった"}, isAtriSleeping, zero.OnlyToMe).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"高性能", "太棒了", "すごい", "sugoi", "斯国一", "よかった"}, zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(randText(
|
||||
"当然,我是高性能的嘛~!",
|
||||
"小事一桩,我是高性能的嘛",
|
||||
@@ -175,9 +197,8 @@ func init() { // 插件主体
|
||||
"呣......我的高性能,毫无遗憾地施展出来了......",
|
||||
))
|
||||
})
|
||||
engine.OnKeywordGroup([]string{"没事", "没关系", "大丈夫", "还好", "不要紧", "没出大问题", "没伤到哪"}, isAtriSleeping, zero.OnlyToMe).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"没事", "没关系", "大丈夫", "还好", "不要紧", "没出大问题", "没伤到哪"}, zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(randText(
|
||||
"当然,我是高性能的嘛~!",
|
||||
"没事没事,因为我是高性能的嘛!嗯哼!",
|
||||
@@ -190,67 +211,42 @@ func init() { // 插件主体
|
||||
))
|
||||
})
|
||||
|
||||
engine.OnKeywordGroup([]string{"好吗", "是吗", "行不行", "能不能", "可不可以"}, isAtriSleeping).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"好吗", "是吗", "行不行", "能不能", "可不可以"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
if rand.Intn(2) == 0 {
|
||||
ctx.SendChain(randImage("YES.png", "NO.jpg"))
|
||||
ctx.SendChain(dgtr.randImage("YES.png", "NO.jpg"))
|
||||
}
|
||||
})
|
||||
engine.OnKeywordGroup([]string{"啊这"}, isAtriSleeping).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"啊这"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
if rand.Intn(2) == 0 {
|
||||
ctx.SendChain(randImage("AZ.jpg", "AZ1.jpg"))
|
||||
ctx.SendChain(dgtr.randImage("AZ.jpg", "AZ1.jpg"))
|
||||
}
|
||||
})
|
||||
engine.OnKeywordGroup([]string{"我好了"}, isAtriSleeping).SetBlock(true).
|
||||
engine.OnKeywordGroup([]string{"我好了"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), randText("不许好!", "憋回去!"))
|
||||
})
|
||||
engine.OnFullMatchGroup([]string{"?", "?", "¿"}, isAtriSleeping).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
switch rand.Intn(5) {
|
||||
case 0:
|
||||
ctx.SendChain(randText("?", "?", "嗯?", "(。´・ω・)ん?", "ん?"))
|
||||
case 1, 2:
|
||||
ctx.SendChain(randImage("WH.jpg", "WH1.jpg", "WH2.jpg", "WH3.jpg"))
|
||||
}
|
||||
})
|
||||
engine.OnKeyword("离谱", isAtriSleeping).SetBlock(true).
|
||||
engine.OnFullMatchGroup([]string{"?", "?", "¿"}).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
switch rand.Intn(5) {
|
||||
case 0:
|
||||
ctx.SendChain(randText("?", "?", "嗯?", "(。´・ω・)ん?", "ん?"))
|
||||
case 1, 2:
|
||||
ctx.SendChain(randImage("WH.jpg"))
|
||||
ctx.SendChain(dgtr.randImage("WH.jpg", "WH1.jpg", "WH2.jpg", "WH3.jpg"))
|
||||
}
|
||||
})
|
||||
engine.OnKeyword("答应我", isAtriSleeping, zero.OnlyToMe).SetBlock(true).
|
||||
engine.OnKeyword("离谱").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
switch rand.Intn(5) {
|
||||
case 0:
|
||||
ctx.SendChain(randText("?", "?", "嗯?", "(。´・ω・)ん?", "ん?"))
|
||||
case 1, 2:
|
||||
ctx.SendChain(dgtr.randImage("WH.jpg"))
|
||||
}
|
||||
})
|
||||
engine.OnKeyword("答应我", zero.OnlyToMe).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(randText("我无法回应你的请求"))
|
||||
})
|
||||
}
|
||||
|
||||
func randText(text ...string) message.MessageSegment {
|
||||
return message.Text(text[rand.Intn(len(text))])
|
||||
}
|
||||
|
||||
func randImage(file ...string) message.MessageSegment {
|
||||
return message.Image(res + file[rand.Intn(len(file))])
|
||||
}
|
||||
|
||||
func randRecord(file ...string) message.MessageSegment {
|
||||
return message.Record(res + file[rand.Intn(len(file))])
|
||||
}
|
||||
|
||||
// isAtriSleeping 凌晨0点到6点,ATRI 在睡觉,不回应任何请求
|
||||
func isAtriSleeping(ctx *zero.Ctx) bool {
|
||||
if now := time.Now().Hour(); now >= 1 && now < 6 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
29
plugin/autowithdraw/main.go
Normal file
29
plugin/autowithdraw/main.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Package autowithdraw 触发者撤回时也自动撤回
|
||||
package autowithdraw
|
||||
|
||||
import (
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
func init() {
|
||||
control.Register("autowithdraw", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "触发者撤回时也自动撤回",
|
||||
Help: "- 撤回一条消息\n",
|
||||
}).OnNotice(func(ctx *zero.Ctx) bool {
|
||||
return ctx.Event.NoticeType == "group_recall" || ctx.Event.NoticeType == "friend_recall"
|
||||
}).SetBlock(false).Handle(func(ctx *zero.Ctx) {
|
||||
id, ok := ctx.Event.MessageID.(int64)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, msg := range zero.GetTriggeredMessages(message.NewMessageIDFromInteger(id)) {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.DeleteMessage(msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -157,7 +157,6 @@ func init() {
|
||||
if !find {
|
||||
msgs += "无"
|
||||
}
|
||||
|
||||
} else {
|
||||
// 生成配置文本
|
||||
msgs = fmt.Sprintf("本群配置:\n"+
|
||||
@@ -187,9 +186,9 @@ func init() {
|
||||
group := getGroup(ctx.Event.GroupID)
|
||||
inputType, _ := strconv.Atoi(k2)
|
||||
if k1 == "不" {
|
||||
group.WhiteListType[inputType] = true //不检测:则进入类型白名单
|
||||
group.WhiteListType[inputType] = true // 不检测:则进入类型白名单
|
||||
} else {
|
||||
group.WhiteListType[inputType] = false //检测:则退出白名单
|
||||
group.WhiteListType[inputType] = false // 检测:则退出白名单
|
||||
}
|
||||
config.Groups[ctx.Event.GroupID] = group
|
||||
ctx.SendChain(message.At(ctx.Event.UserID), message.Text(fmt.Sprintf("本群将%s检测%s类型内容", k1, typetext[inputType])))
|
||||
@@ -324,7 +323,6 @@ func init() {
|
||||
}
|
||||
group := getGroup(ctx.Event.GroupID)
|
||||
ctx.SendChain(buildResp(bdres, group)...)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -367,10 +365,10 @@ func banCheck(ctx *zero.Ctx, bdres baiduRes) {
|
||||
} else {
|
||||
bantime = group.BANTime * 60
|
||||
}
|
||||
//执行禁言
|
||||
// 执行禁言
|
||||
ctx.SetGroupBan(ctx.Event.GroupID, ctx.Event.UserID, bantime)
|
||||
}
|
||||
//查看是否开启撤回提示
|
||||
// 查看是否开启撤回提示
|
||||
if group.DMRemind {
|
||||
res = append(res, message.At(ctx.Event.Sender.ID))
|
||||
ctx.SendChain(res...)
|
||||
|
||||
@@ -16,12 +16,12 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
bz "github.com/FloatTech/AnimeAPI/bilibili"
|
||||
fcext "github.com/FloatTech/floatbox/ctxext"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
"github.com/FloatTech/gg"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
@@ -291,7 +291,7 @@ func init() {
|
||||
}
|
||||
|
||||
client := &http.Client{Transport: tr}
|
||||
data, err := web.RequestDataWith(client, fmt.Sprintf(bz.DanmakuAPI, id, pagenum), "GET", "", web.RandUA())
|
||||
data, err := web.RequestDataWith(client, fmt.Sprintf(bz.DanmakuAPI, id, pagenum), "GET", "", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
@@ -35,7 +35,7 @@ func init() {
|
||||
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)
|
||||
realurl, err := bz.GetRealURL("https://" + url)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
@@ -56,7 +56,7 @@ func init() {
|
||||
dbfile := dbpath + "push.db"
|
||||
bdb = initializePush(dbfile)
|
||||
|
||||
en.OnRegex(`^添加b站订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -73,7 +73,7 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Text("已添加" + name + "的订阅"))
|
||||
})
|
||||
en.OnRegex(`^取消b站订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -90,7 +90,7 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Text("已取消" + name + "的订阅"))
|
||||
})
|
||||
en.OnRegex(`^取消b站动态订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
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)
|
||||
if err != nil {
|
||||
@@ -107,7 +107,7 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Text("已取消" + name + "的动态订阅"))
|
||||
})
|
||||
en.OnRegex(`^取消b站直播订阅\s?(.{1,25})$`, zero.UserOrGrpAdmin, getPara).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
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)
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
@@ -124,13 +124,13 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Text("已取消" + name + "的直播订阅"))
|
||||
})
|
||||
en.OnFullMatch("b站推送列表", zero.UserOrGrpAdmin).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
en.OnRegex(`^[B|b]站推送列表$`, zero.UserOrGrpAdmin).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
gid := ctx.Event.GroupID
|
||||
if gid == 0 {
|
||||
gid = -ctx.Event.UserID
|
||||
}
|
||||
bpl := bdb.getAllPushByGroup(gid)
|
||||
msg := "--------b站推送列表--------"
|
||||
msg := "--------B站推送列表--------"
|
||||
for _, v := range bpl {
|
||||
if _, ok := upMap[v.BilibiliUID]; !ok {
|
||||
bdb.updateAllUp()
|
||||
@@ -158,7 +158,7 @@ func init() {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
})
|
||||
en.OnFullMatch("拉取b站推送").SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
en.OnRegex(`拉取[B|b]站推送$`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
err := sendDynamic(ctx)
|
||||
if err != nil {
|
||||
ctx.SendPrivateMessage(ctx.Event.UserID, message.Text("Error: bilibilipush,", err))
|
||||
@@ -175,7 +175,7 @@ func getName(buid int64) (name string, err error) {
|
||||
var ok bool
|
||||
if name, ok = upMap[buid]; !ok {
|
||||
var data []byte
|
||||
data, err = web.RequestDataWith(web.NewDefaultClient(), fmt.Sprintf(infoURL, buid), "GET", referer, ua)
|
||||
data, err = web.RequestDataWith(web.NewDefaultClient(), fmt.Sprintf(infoURL, buid), "GET", referer, ua, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -232,7 +232,7 @@ func unsubscribeLive(buid, groupid int64) (err error) {
|
||||
}
|
||||
|
||||
func getUserDynamicCard(buid int64) (cardList []gjson.Result, err error) {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), fmt.Sprintf(bz.SpaceHistoryURL, buid, 0), "GET", referer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), fmt.Sprintf(bz.SpaceHistoryURL, buid, 0), "GET", referer, ua, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
package coser
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"errors"
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
@@ -10,6 +13,8 @@ import (
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
"github.com/wdvxdr1123/ZeroBot/utils/helper"
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/setu"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
@@ -19,35 +24,44 @@ 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"
|
||||
datestr = regexp.MustCompile(`/\d{4}-\d{2}-\d{2}/`)
|
||||
)
|
||||
|
||||
func init() {
|
||||
p, err := setu.NewPool(setu.DefaultPoolDir,
|
||||
func(s string) (string, error) {
|
||||
if s != "coser" {
|
||||
return "", errors.New("invalid call")
|
||||
}
|
||||
typ := setu.DefaultPoolDir + "/" + "coser"
|
||||
if file.IsNotExist(typ) {
|
||||
err := os.MkdirAll(typ, 0755)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), coserURL, "GET", "", ua, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
arr := gjson.Get(helper.BytesToString(data), "data.data").Array()
|
||||
pic := arr[rand.Intn(len(arr))]
|
||||
return pic.String(), nil
|
||||
}, web.GetData, time.Minute)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
control.Register("coser", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "三次元coser",
|
||||
Help: "- coser",
|
||||
}).ApplySingle(ctxext.DefaultSingle).OnFullMatch("coser").SetBlock(true).Limit(ctxext.LimitByGroup).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text("少女祈祷中......"))
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), coserURL, "GET", "", ua)
|
||||
pic, err := p.Roll("coser")
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
text := gjson.Get(helper.BytesToString(data), "data.Title").String()
|
||||
m := message.Message{ctxext.FakeSenderForwardNode(ctx, message.Text(text))}
|
||||
ds := ""
|
||||
gjson.Get(helper.BytesToString(data), "data.data").ForEach(func(_, value gjson.Result) bool {
|
||||
if ds == "" {
|
||||
ds = datestr.FindString(value.String())
|
||||
} else if ds != datestr.FindString(value.String()) {
|
||||
return false
|
||||
}
|
||||
m = append(m, ctxext.FakeSenderForwardNode(ctx, message.Image(value.String())))
|
||||
return true
|
||||
})
|
||||
if id := ctx.Send(m).ID(); id == 0 {
|
||||
if id := ctx.Send(message.Message{ctxext.FakeSenderForwardNode(ctx, message.Image("file:///"+file.BOTPATH+"/"+pic))}).ID(); id == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控或下载图片用时过长,请耐心等待"))
|
||||
}
|
||||
})
|
||||
|
||||
@@ -53,7 +53,7 @@ func init() {
|
||||
text := strings.ReplaceAll(cs.Story, "<攻>", gong)
|
||||
text = strings.ReplaceAll(text, "<受>", shou)
|
||||
text = strings.ReplaceAll(text, cs.Gong, gong)
|
||||
text = strings.ReplaceAll(text, cs.Shou, gong)
|
||||
text = strings.ReplaceAll(text, cs.Shou, shou)
|
||||
ctx.SendChain(message.Text(text))
|
||||
})
|
||||
engine.OnPrefix("磕cp", getdb).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"net/url"
|
||||
"sort"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
imgutils "github.com/FloatTech/zbputils/img"
|
||||
"github.com/FloatTech/zbputils/img/text" // jpg png gif
|
||||
|
||||
39
plugin/dress/api.go
Normal file
39
plugin/dress/api.go
Normal file
@@ -0,0 +1,39 @@
|
||||
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
|
||||
}
|
||||
113
plugin/dress/dress.go
Normal file
113
plugin/dress/dress.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// 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.Register("dress", &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: 可能被风控或下载图片用时过长,请耐心等待"))
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
// Package epidemic 城市疫情查询
|
||||
package epidemic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
)
|
||||
|
||||
const txurl = "https://api.inews.qq.com/newsqa/v1/query/inner/publish/modules/list?modules=statisGradeCityDetail,diseaseh5Shelf"
|
||||
|
||||
// result 疫情查询结果
|
||||
type result struct {
|
||||
Data struct {
|
||||
Epidemic epidemic `json:"diseaseh5Shelf"`
|
||||
} `json:"data"`
|
||||
}
|
||||
|
||||
// epidemic 疫情数据
|
||||
type epidemic struct {
|
||||
LastUpdateTime string `json:"lastUpdateTime"`
|
||||
AreaTree []*area `json:"areaTree"`
|
||||
}
|
||||
|
||||
// area 城市疫情数据
|
||||
type area struct {
|
||||
Name string `json:"name"`
|
||||
Today struct {
|
||||
Confirm int `json:"confirm"`
|
||||
Wzzadd any `json:"wzz_add"`
|
||||
} `json:"today"`
|
||||
Total struct {
|
||||
NowConfirm int `json:"nowConfirm"`
|
||||
Confirm int `json:"confirm"`
|
||||
Dead int `json:"dead"`
|
||||
Heal int `json:"heal"`
|
||||
Grade string `json:"grade"`
|
||||
Wzz int `json:"wzz"`
|
||||
} `json:"total"`
|
||||
Children []*area `json:"children"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
engine := control.Register("epidemic", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "城市疫情查询",
|
||||
Help: "- xxx疫情\n",
|
||||
})
|
||||
engine.OnSuffix("疫情").SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
city := ctx.State["args"].(string)
|
||||
if city == "" {
|
||||
ctx.SendChain(message.Text("你还没有输入城市名字呢!"))
|
||||
return
|
||||
}
|
||||
data, time, err := queryEpidemic(city)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if data == nil {
|
||||
ctx.SendChain(message.Text("没有找到【", city, "】城市的疫情数据."))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(
|
||||
message.Text(
|
||||
"【", data.Name, "】疫情数据\n",
|
||||
"新增人数:", data.Today.Confirm, "\n",
|
||||
"现有确诊:", data.Total.NowConfirm, "\n",
|
||||
"累计确诊:", data.Total.Confirm, "\n",
|
||||
"治愈人数:", data.Total.Heal, "\n",
|
||||
"死亡人数:", data.Total.Dead, "\n",
|
||||
"无症状人数:", data.Total.Wzz, "\n",
|
||||
"新增无症状:", data.Today.Wzzadd, "\n",
|
||||
"更新时间:\n『", time, "』",
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
// rcity 查找城市
|
||||
func rcity(a *area, cityName string) *area {
|
||||
if a == nil {
|
||||
return nil
|
||||
}
|
||||
if a.Name == cityName {
|
||||
return a
|
||||
}
|
||||
for _, v := range a.Children {
|
||||
if v.Name == cityName {
|
||||
return v
|
||||
}
|
||||
c := rcity(v, cityName)
|
||||
if c != nil {
|
||||
return c
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// queryEpidemic 查询城市疫情
|
||||
func queryEpidemic(findCityName string) (citydata *area, times string, err error) {
|
||||
data, err := web.GetData(txurl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
var r result
|
||||
err = json.Unmarshal(data, &r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
citydata = rcity(r.Data.Epidemic.AreaTree[0], findCityName)
|
||||
return citydata, r.Data.Epidemic.LastUpdateTime, nil
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/Coloured-glaze/gg" // 注册了 jpg png gif
|
||||
"github.com/FloatTech/gg" // 注册了 jpg png gif
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
@@ -40,7 +40,7 @@ const (
|
||||
|
||||
var (
|
||||
// 底图类型列表
|
||||
table = [...]string{"车万", "DC4", "爱因斯坦", "星空列车", "樱云之恋", "富婆妹", "李清歌", "公主连结", "原神", "明日方舟", "碧蓝航线", "碧蓝幻想", "战双", "阴阳师", "赛马娘", "东方归言录", "奇异恩典", "夏日口袋", "ASoul"}
|
||||
table = [...]string{"车万", "DC4", "爱因斯坦", "星空列车", "樱云之恋", "富婆妹", "李清歌", "公主连结", "原神", "明日方舟", "碧蓝航线", "碧蓝幻想", "战双", "阴阳师", "赛马娘", "东方归言录", "奇异恩典", "夏日口袋", "ASoul", "Hololive"}
|
||||
// 映射底图与 index
|
||||
index = make(map[string]uint8)
|
||||
// 签文
|
||||
@@ -53,7 +53,7 @@ func init() {
|
||||
DisableOnDefault: false,
|
||||
Brief: "每日运势",
|
||||
Help: "- 运势 | 抽签\n" +
|
||||
"- 设置底图[车万 | DC4 | 爱因斯坦 | 星空列车 | 樱云之恋 | 富婆妹 | 李清歌 | 公主连结 | 原神 | 明日方舟 | 碧蓝航线 | 碧蓝幻想 | 战双 | 阴阳师 | 赛马娘 | 东方归言录 | 奇异恩典 | 夏日口袋 | ASoul]",
|
||||
"- 设置底图[车万 | DC4 | 爱因斯坦 | 星空列车 | 樱云之恋 | 富婆妹 | 李清歌 | 公主连结 | 原神 | 明日方舟 | 碧蓝航线 | 碧蓝幻想 | 战双 | 阴阳师 | 赛马娘 | 东方归言录 | 奇异恩典 | 夏日口袋 | ASoul | Hololive]",
|
||||
PublicDataFolder: "Fortune",
|
||||
})
|
||||
_ = os.RemoveAll(cache)
|
||||
|
||||
@@ -20,7 +20,7 @@ func dlchan(name string, s *string, wg *sync.WaitGroup, exit func(error)) {
|
||||
defer wg.Done()
|
||||
target := datapath + `materials/` + name
|
||||
if file.IsNotExist(target) {
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), `https://gitcode.net/m0_60838134/imagematerials/-/raw/main/`+name, "GET", "gitcode.net", web.RandUA())
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), `https://gitcode.net/m0_60838134/imagematerials/-/raw/main/`+name, "GET", "gitcode.net", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
_ = os.Remove(target)
|
||||
exit(err)
|
||||
@@ -48,7 +48,7 @@ func dlchan(name string, s *string, wg *sync.WaitGroup, exit func(error)) {
|
||||
func dlblock(name string) (string, error) {
|
||||
target := datapath + `materials/` + name
|
||||
if file.IsNotExist(target) {
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), `https://gitcode.net/m0_60838134/imagematerials/-/raw/main/`+name, "GET", "gitcode.net", web.RandUA())
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), `https://gitcode.net/m0_60838134/imagematerials/-/raw/main/`+name, "GET", "gitcode.net", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
_ = os.Remove(target)
|
||||
return "", err
|
||||
|
||||
@@ -6,9 +6,9 @@ import (
|
||||
"image/color"
|
||||
"sync"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
)
|
||||
|
||||
@@ -13,13 +14,14 @@ 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", true)
|
||||
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", true)
|
||||
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
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/img"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
|
||||
@@ -129,21 +129,22 @@ func init() { // 插件主体
|
||||
en := control.Register("gif", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "制图",
|
||||
Help: "下为制图命令: " +
|
||||
"- 搓|-冲|-摸|-拍|-丢|-吃|-敲|-啃|-蹭|-爬|-撕|-灰度|-上翻|-下翻\n" +
|
||||
"- 左翻|-右翻|-反色|-浮雕|- 打码|- 负片|- 旋转|- 变形|- 亲\n" +
|
||||
"- 结婚申请|结婚登记|- 阿尼亚喜欢XXX|- 像只|- 我永远喜欢XXX\n" +
|
||||
"- 像样的亲亲|- 国旗|- 不要靠近|- 万能表情|-空白表情|- 采访\n" +
|
||||
"- 需要|-你可能需要|- 这像画吗|- 小画家|- 完美|- 玩游戏|- 出警\n" +
|
||||
"- 警察|- 舔|舔屏|prpr|- 安全感|- 精神支柱|- 想什么|- 墙纸\n" +
|
||||
"- 为什么at我|- 交个朋友|- 打工人|-继续干活|- 兑换券|- 炖\n" +
|
||||
"- 垃圾桶|- 垃圾|- 捶|- 啾啾|- 2敲|- 听音乐|- 永远爱你|- 2拍\n" +
|
||||
"- 顶|- 捣|- 打拳|- 滚|- 吸|- 嗦|- 扔|- 锤|- 紧贴|紧紧贴着|- 转\n" +
|
||||
"- 抬棺|- 远离|- 我老婆|- 小天使XXX|- 你的XXX|- 不要看\n" +
|
||||
"- 玩一下XXX|- 给我变|- 揍|- 吞|- 膜拜|- 诶嘿|- 2蹭|- 你犯法了\n" +
|
||||
"- 砰|- 注意力涣散|- 蒙蔽|- 踩|- 好玩|- 2转|- 踢球|- 2舔|\n" +
|
||||
"- 可莉吃|- 胡桃啃|- 怀|- 一直(支持动图)\n" +
|
||||
"例: 制图命令XXX[@用户|QQ号|图片]" +
|
||||
Help: "下为制图命令:\n" +
|
||||
"- 搓|- 冲|- 摸|-拍|- 丢|- 吃|- 敲|- 啃|- 蹭|- 爬|- 撕\n" +
|
||||
"- 吸|- 嗦|- 扔|- 锤|- 紧贴|紧紧贴着|- 转|- 抬棺|- 远离\n" +
|
||||
"- 揍|- 吞|- 膜拜|- 诶嘿|- 2蹭|- 你犯法了|- 砰|- 注意力涣散\n" +
|
||||
"- 2敲|- 听音乐|- 永远爱你|- 2拍|- 顶|- 捣|- 打拳|- 滚\n" +
|
||||
"- 灰度|- 上翻|- 下翻|- 左翻|- 右翻|- 反色|- 浮雕|- 打码\n" +
|
||||
"- 负片|- 旋转|- 变形|- 亲|- 结婚申请|结婚登记|- 阿尼亚喜欢XXX\n" +
|
||||
"- 像只|- 我永远喜欢XXX|- 像样的亲亲|- 国旗|- 不要靠近\n" +
|
||||
"- 蒙蔽|- 踩|- 好玩|- 2转|- 踢球|- 2舔|- 可莉吃|- 胡桃啃|- 怀\n" +
|
||||
"- 小画家|- 完美|- 玩游戏|- 出警|- 警察|- 舔|舔屏|prpr\n" +
|
||||
"- 安全感|- 精神支柱|- 想什么|- 墙纸|- 为什么at我|- 交个朋友\n" +
|
||||
"- 打工人|- 继续干活|- 兑换券|- 炖|- 垃圾桶|- 垃圾|- 捶|- 啾啾\n" +
|
||||
"- 我老婆|- 小天使XXX|- 你的XXX|- 不要看|- 玩一下XXX|- 给我变\n" +
|
||||
"- 万能表情|- 空白表情|- 采访|- 需要|- 你可能需要|- 这像画吗\n" +
|
||||
"- 一直(支持动图)\n" +
|
||||
"例: 制图命令XXX[@用户|QQ号|图片]\n" +
|
||||
"Tips: XXX可以为限制长度的任何文字\n" +
|
||||
"对Bot使用为 @Bot制图命令[XXX]@Bot",
|
||||
PrivateDataFolder: "gif",
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
@@ -84,11 +85,11 @@ func init() {
|
||||
return
|
||||
}
|
||||
answerString := "歌名:" + musicInfo[0] + "\n歌手:" + musicInfo[1]
|
||||
musicAlia := ""
|
||||
if infoNum > 2 {
|
||||
musicAlia = musicInfo[2]
|
||||
answerString += "\n其他信息:\n" + strings.ReplaceAll(musicAlia, "&", "\n")
|
||||
musicInfo[2] = strings.ReplaceAll(musicInfo[2], "&", "\n")
|
||||
answerString += "\n其他信息:\n" + musicInfo[2]
|
||||
}
|
||||
musicInfo = append(musicInfo, answerString)
|
||||
// 切割音频,生成3个10秒的音频
|
||||
outputPath := cachePath + strconv.FormatInt(gid, 10) + "/"
|
||||
err = cutMusic(musicName, pathOfMusic, outputPath)
|
||||
@@ -104,13 +105,18 @@ func init() {
|
||||
} else {
|
||||
next = zero.NewFutureEvent("message", 999, false, zero.OnlyGroup, zero.RegexRule(`^-\S{1,}`), zero.CheckGroup(ctx.Event.GroupID))
|
||||
}
|
||||
var musicCount = 0 // 音频数量
|
||||
var answerCount = 0 // 问答次数
|
||||
recv, cancel := next.Repeat()
|
||||
defer cancel()
|
||||
wait := time.NewTimer(40 * time.Second)
|
||||
tick := time.NewTimer(105 * time.Second)
|
||||
after := time.NewTimer(120 * time.Second)
|
||||
wg := sync.WaitGroup{}
|
||||
var (
|
||||
messageStr message.MessageSegment // 文本信息
|
||||
tickCount = 0 // 音频数量
|
||||
answerCount = 0 // 问答次数
|
||||
win bool // 是否赢得游戏
|
||||
)
|
||||
for {
|
||||
select {
|
||||
case <-tick.C:
|
||||
@@ -121,107 +127,41 @@ func init() {
|
||||
return
|
||||
case <-wait.C:
|
||||
wait.Reset(40 * time.Second)
|
||||
musicCount++
|
||||
if musicCount > 2 {
|
||||
tickCount++
|
||||
if tickCount > 2 {
|
||||
wait.Stop()
|
||||
continue
|
||||
}
|
||||
ctx.SendChain(
|
||||
message.Text("好像有些难度呢,再听这段音频,要仔细听哦"),
|
||||
)
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(tickCount) + ".wav"))
|
||||
case c := <-recv:
|
||||
wait.Reset(40 * time.Second)
|
||||
tick.Reset(105 * time.Second)
|
||||
after.Reset(120 * time.Second)
|
||||
answer := strings.Replace(c.Event.Message.String(), "-", "", 1)
|
||||
switch {
|
||||
case answer == "取消":
|
||||
if c.Event.UserID == ctx.Event.UserID {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
messageStr, answerCount, tickCount, win = gameMatch(c, ctx.Event.UserID, musicInfo, answerCount, tickCount)
|
||||
if win { // 游戏结束的话
|
||||
wait.Stop()
|
||||
tick.Stop()
|
||||
after.Stop()
|
||||
ctx.Send(message.ReplyWithMessage(ctx.Event.MessageID,
|
||||
message.Text("游戏已取消,猜歌答案是\n", answerString, "\n\n\n下面欣赏猜歌的歌曲")))
|
||||
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
|
||||
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
|
||||
return
|
||||
}
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("你无权限取消"),
|
||||
),
|
||||
)
|
||||
case answer == "提示":
|
||||
musicCount++
|
||||
if musicCount > 2 {
|
||||
wait.Stop()
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("已经没有提示了哦"),
|
||||
),
|
||||
)
|
||||
continue
|
||||
}
|
||||
wait.Reset(40 * time.Second)
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("再听这段音频,要仔细听哦"),
|
||||
),
|
||||
)
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
|
||||
case strings.Contains(musicInfo[0], answer) || strings.EqualFold(musicInfo[0], answer):
|
||||
wait.Stop()
|
||||
tick.Stop()
|
||||
after.Stop()
|
||||
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("太棒了,你猜对歌曲名了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
|
||||
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
|
||||
return
|
||||
case strings.Contains(musicInfo[1], answer) || strings.EqualFold(musicInfo[1], answer):
|
||||
wait.Stop()
|
||||
tick.Stop()
|
||||
after.Stop()
|
||||
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("太棒了,你猜对歌手名了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
|
||||
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
|
||||
return
|
||||
case strings.Contains(musicAlia, answer) || strings.EqualFold(musicAlia, answer):
|
||||
wait.Stop()
|
||||
tick.Stop()
|
||||
after.Stop()
|
||||
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("太棒了,你猜对出处了!答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
|
||||
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
|
||||
return
|
||||
default:
|
||||
musicCount++
|
||||
switch {
|
||||
case musicCount > 2 && answerCount < 6:
|
||||
wait.Stop()
|
||||
answerCount++
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("答案不对哦,加油啊~"),
|
||||
),
|
||||
)
|
||||
case musicCount > 2:
|
||||
wait.Stop()
|
||||
tick.Stop()
|
||||
after.Stop()
|
||||
ctx.Send(message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("次数到了,没能猜出来。答案是\n", answerString, "\n\n下面欣赏猜歌的歌曲")))
|
||||
ctx.SendChain(message.Record("file:///" + pathOfMusic + musicName))
|
||||
return
|
||||
default:
|
||||
} else {
|
||||
wait.Reset(40 * time.Second)
|
||||
answerCount++
|
||||
ctx.Send(
|
||||
message.ReplyWithMessage(c.Event.MessageID,
|
||||
message.Text("答案不对,再听这段音频,要仔细听哦"),
|
||||
),
|
||||
)
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(musicCount) + ".wav"))
|
||||
tick.Reset(105 * time.Second)
|
||||
after.Reset(120 * time.Second)
|
||||
if tickCount > 2 || messageStr.Data["text"] == "你无权限取消" {
|
||||
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
|
||||
} else {
|
||||
ctx.SendChain(message.Reply(c.Event.MessageID), messageStr)
|
||||
ctx.SendChain(message.Record("file:///" + file.BOTPATH + "/" + outputPath + strconv.Itoa(tickCount) + ".wav"))
|
||||
}
|
||||
}
|
||||
wg.Done()
|
||||
}()
|
||||
wg.Wait()
|
||||
if win {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +173,7 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
|
||||
// 读取歌单文件
|
||||
pathOfMusic = musicPath + listName + "/"
|
||||
if file.IsNotExist(pathOfMusic) {
|
||||
err = errors.New("指定的歌单不存在")
|
||||
err = errors.New("指定的歌单不存在,可发送“歌单列表”查看歌单列表")
|
||||
return
|
||||
}
|
||||
files, err := os.ReadDir(pathOfMusic)
|
||||
@@ -271,11 +211,11 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
|
||||
}
|
||||
// 进行随机抽取
|
||||
if playlistID == 0 || !cfg.API {
|
||||
musicName = getLocalMusic(files)
|
||||
musicName = getLocalMusic(files, 10)
|
||||
} else {
|
||||
switch rand.Intn(3) { // 三分二概率抽取API的
|
||||
case 1:
|
||||
musicName = getLocalMusic(files)
|
||||
musicName = getLocalMusic(files, 10)
|
||||
default:
|
||||
if cfg.APIURL == "" {
|
||||
// 如果没有配置过API地址,尝试连接独角兽
|
||||
@@ -285,22 +225,27 @@ func musicLottery(musicPath, listName string) (pathOfMusic, musicName string, er
|
||||
musicName, err = drawByAPI(playlistID, pathOfMusic)
|
||||
}
|
||||
if err != nil {
|
||||
musicName = getLocalMusic(files)
|
||||
err = nil
|
||||
return
|
||||
musicName = getLocalMusic(files, 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
if musicName == "" {
|
||||
err = errors.New("抽取歌曲轮空了,请重试")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 从本地列表中随机抽取一首
|
||||
func getLocalMusic(files []fs.DirEntry) (musicName string) {
|
||||
// 从本地列表中随机抽取一首( indexMax : 最大递归次数 )
|
||||
func getLocalMusic(files []fs.DirEntry, indexMax int) (musicName string) {
|
||||
if len(files) > 1 {
|
||||
music := files[rand.Intn(len(files))]
|
||||
// 如果是文件夹就递归
|
||||
if music.IsDir() {
|
||||
musicName = getLocalMusic(files)
|
||||
indexMax--
|
||||
if indexMax <= 0 {
|
||||
return
|
||||
}
|
||||
musicName = getLocalMusic(files, indexMax)
|
||||
} else {
|
||||
musicName = music.Name()
|
||||
}
|
||||
@@ -334,3 +279,38 @@ func cutMusic(musicName, pathOfMusic, outputPath string) (err error) {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 数据匹配(结果信息,答题次数,提示次数,是否结束游戏)
|
||||
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)
|
||||
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("你无权限取消"), answerTimes, tickTimes, false
|
||||
case answer == "提示":
|
||||
tickTimes++
|
||||
if tickTimes > 2 {
|
||||
return message.Text("已经没有提示了哦"), answerTimes, tickTimes, false
|
||||
}
|
||||
return message.Text("再听这段音频,要仔细听哦"), answerTimes, tickTimes, false
|
||||
case strings.Contains(musicInfo[0], answer) || strings.EqualFold(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):
|
||||
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)):
|
||||
return message.Text("太棒了,你猜对相关信息了!答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
|
||||
default:
|
||||
answerTimes++
|
||||
tickTimes++
|
||||
switch {
|
||||
case tickTimes > 2 && answerTimes < 6:
|
||||
return message.Text("答案不对哦,还有", 6-answerTimes, "次答题,加油啊~"), answerTimes, tickTimes, false
|
||||
case tickTimes > 2:
|
||||
return message.Text("次数到了,没能猜出来。答案是\n", musicInfo[len(musicInfo)-1], "\n\n下面欣赏猜歌的歌曲"), answerTimes, tickTimes, true
|
||||
default:
|
||||
return message.Text("答案不对,再听这段音频,要仔细听哦"), answerTimes, tickTimes, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@ import (
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
// 图片输出
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
)
|
||||
|
||||
@@ -380,8 +381,9 @@ func init() {
|
||||
break
|
||||
}
|
||||
}
|
||||
err = file.DownloadTo(fileURL, cfg.MusicPath+listName+"/"+fileSearchName, true)
|
||||
err = file.DownloadTo(fileURL, cfg.MusicPath+listName+"/"+fileSearchName)
|
||||
if err == nil {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Text("成功!"))
|
||||
} else {
|
||||
ctx.SendChain(message.Text(serviceErr, err))
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
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"
|
||||
@@ -25,6 +31,41 @@ var (
|
||||
)
|
||||
|
||||
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.Register("heisi", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "黑丝",
|
||||
@@ -65,22 +106,12 @@ func init() { // 插件主体
|
||||
})).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
matched := ctx.State["matched"].(string)
|
||||
var pic item
|
||||
switch matched {
|
||||
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))]
|
||||
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(pic.String()))}
|
||||
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: 可能被风控或下载图片用时过长,请耐心等待"))
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ func init() {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(),
|
||||
`https://res.fbigame.com/hs/v13/`+cid+`.png?auth_key=`+
|
||||
gjson.Get(g, `list.`+strconv.Itoa(i)+`.auth_key`).String(),
|
||||
reqconf[0], reqconf[1], reqconf[2])
|
||||
reqconf[0], reqconf[1], reqconf[2], nil)
|
||||
if err == nil {
|
||||
err = os.WriteFile(cachefile, data, 0644)
|
||||
}
|
||||
@@ -95,10 +95,10 @@ func init() {
|
||||
}
|
||||
|
||||
func sh(s string) string {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), "https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2])
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), "https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2], nil)
|
||||
if err == nil {
|
||||
url := hs + para + "&hash=" + strings.SplitN(strings.SplitN(helper.BytesToString(data), `var hash = "`, 2)[1], `"`, 2)[0] + "&search=" + s
|
||||
r, err := web.RequestDataWith(web.NewDefaultClient(), url, reqconf[0], reqconf[1], reqconf[2])
|
||||
r, err := web.RequestDataWith(web.NewDefaultClient(), url, reqconf[0], reqconf[1], reqconf[2], nil)
|
||||
if err == nil {
|
||||
return helper.BytesToString(r)
|
||||
}
|
||||
@@ -107,10 +107,10 @@ func sh(s string) string {
|
||||
}
|
||||
|
||||
func kz(s string) string {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), "https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2])
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), "https://hs.fbigame.com", reqconf[0], reqconf[1], reqconf[2], nil)
|
||||
if err == nil {
|
||||
url := hs + para + "mod=general_deck_image&deck_code=" + s + "&deck_text=&hash=" + strings.SplitN(strings.SplitN(helper.BytesToString(data), `var hash = "`, 2)[1], `"`, 2)[0] + "&search=" + s
|
||||
r, err := web.RequestDataWith(web.NewDefaultClient(), url, reqconf[0], reqconf[1], reqconf[2])
|
||||
r, err := web.RequestDataWith(web.NewDefaultClient(), url, reqconf[0], reqconf[1], reqconf[2], nil)
|
||||
if err == nil {
|
||||
return "base64://" + gjson.Get(helper.BytesToString(r), "img").String()
|
||||
}
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
package hyaku
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
@@ -12,8 +12,6 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"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"
|
||||
@@ -23,7 +21,6 @@ import (
|
||||
|
||||
const bed = "https://gitcode.net/u011570312/OguraHyakuninIsshu/-/raw/master/"
|
||||
|
||||
// nolint: asciicheck
|
||||
type line struct {
|
||||
番号, 歌人, 上の句, 下の句, 上の句ひらがな, 下の句ひらがな string
|
||||
}
|
||||
@@ -61,56 +58,36 @@ func init() {
|
||||
"- 百人一首之n",
|
||||
PrivateDataFolder: "hyaku",
|
||||
})
|
||||
csvfile := engine.DataFolder() + "hyaku.csv"
|
||||
err := os.MkdirAll(engine.DataFolder()+"img", 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
go func() {
|
||||
var f *os.File
|
||||
if file.IsNotExist(csvfile) {
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), bed+"小倉百人一首.csv", "GET", "gitcode.net", web.RandUA())
|
||||
if err != nil {
|
||||
_ = os.Remove(csvfile)
|
||||
panic(err)
|
||||
}
|
||||
f, err = os.Create(csvfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_, _ = f.Write(data)
|
||||
_, _ = f.Seek(0, io.SeekStart)
|
||||
} else {
|
||||
var err error
|
||||
f, err = os.Open(csvfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data, err := engine.GetCustomLazyData(bed, "小倉百人一首.csv")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
records, err := csv.NewReader(bytes.NewReader(data)).ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
records = records[1:] // skip title
|
||||
if len(records) != 100 {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
for j, r := range records {
|
||||
if len(r) != 6 {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
records, err := csv.NewReader(f).ReadAll()
|
||||
i, err := strconv.Atoi(r[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
_ = f.Close()
|
||||
records = records[1:] // skip title
|
||||
if len(records) != 100 {
|
||||
i--
|
||||
if j != i {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
for j, r := range records {
|
||||
if len(r) != 6 {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
i, err := strconv.Atoi(r[0])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
i--
|
||||
if j != i {
|
||||
panic("invalid csvfile")
|
||||
}
|
||||
lines[i] = (*line)(*(*unsafe.Pointer)(unsafe.Pointer(&r)))
|
||||
}
|
||||
}()
|
||||
lines[i] = (*line)(*(*unsafe.Pointer)(unsafe.Pointer(&r)))
|
||||
}
|
||||
engine.OnFullMatch("百人一首").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
i := rand.Intn(100)
|
||||
img0, err := engine.GetCustomLazyData(bed, fmt.Sprintf("img/%03d.jpg", i+1))
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/lucas-clemente/quic-go/http3"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
@@ -81,6 +81,10 @@ func init() {
|
||||
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)
|
||||
@@ -94,7 +98,7 @@ func init() {
|
||||
"标题: ", il.Title, "\n",
|
||||
"副标题: ", il.AltTitle, "\n",
|
||||
"ID: ", il.ID, "\n",
|
||||
"画师: ", illust.UserName, " (", illust.UserId, ")", "\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)),
|
||||
@@ -115,6 +119,7 @@ func soutuapi(keyword string) (r resultjson, err error) {
|
||||
"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
|
||||
|
||||
@@ -222,7 +222,7 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("那我就不手下留情了~"))
|
||||
})
|
||||
// 修改名片
|
||||
engine.OnRegex(`^修改名片.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
|
||||
engine.OnRegex(`^修改名片.*?(\d+).+?\s*(.*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if len(ctx.State["regex_matched"].([]string)[2]) > 60 {
|
||||
ctx.SendChain(message.Text("名字太长啦!"))
|
||||
@@ -236,33 +236,51 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("嗯!已经修改了"))
|
||||
})
|
||||
// 修改头衔
|
||||
engine.OnRegex(`^修改头衔.*?(\d+).*?\s(.*)`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
|
||||
engine.OnRegex(`^修改头衔.*?(\d+).+?\s*(.*)$`, zero.OnlyGroup, zero.AdminPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if len(ctx.State["regex_matched"].([]string)[1]) > 18 {
|
||||
sptitle := ctx.State["regex_matched"].([]string)[2]
|
||||
if sptitle == "" {
|
||||
ctx.SendChain(message.Text("头衔不能为空!"))
|
||||
return
|
||||
} else if len(sptitle) > 18 {
|
||||
ctx.SendChain(message.Text("头衔太长啦!"))
|
||||
return
|
||||
}
|
||||
ctx.SetGroupSpecialTitle(
|
||||
ctx.Event.GroupID,
|
||||
math.Str2Int64(ctx.State["regex_matched"].([]string)[1]), // 被修改群头衔的人
|
||||
ctx.State["regex_matched"].([]string)[2], // 修改成的群头衔
|
||||
sptitle, // 修改成的群头衔
|
||||
)
|
||||
ctx.SendChain(message.Text("嗯!已经修改了"))
|
||||
})
|
||||
// 申请头衔
|
||||
engine.OnRegex(`^申请头衔(.*)`, zero.OnlyGroup).SetBlock(true).
|
||||
engine.OnRegex(`^申请头衔\s*(.*)$`, zero.OnlyGroup).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if len(ctx.State["regex_matched"].([]string)[1]) > 18 {
|
||||
sptitle := ctx.State["regex_matched"].([]string)[1]
|
||||
if sptitle == "" {
|
||||
ctx.SendChain(message.Text("头衔不能为空!"))
|
||||
return
|
||||
} else if len(sptitle) > 18 {
|
||||
ctx.SendChain(message.Text("头衔太长啦!"))
|
||||
return
|
||||
}
|
||||
ctx.SetGroupSpecialTitle(
|
||||
ctx.Event.GroupID,
|
||||
ctx.Event.UserID, // 被修改群头衔的人
|
||||
ctx.State["regex_matched"].([]string)[1], // 修改成的群头衔
|
||||
ctx.Event.UserID, // 被修改群头衔的人
|
||||
sptitle, // 修改成的群头衔
|
||||
)
|
||||
ctx.SendChain(message.Text("嗯!不错的头衔呢~"))
|
||||
})
|
||||
// 撤回
|
||||
// 群聊中直接回复消息结尾带上撤回
|
||||
// 权限够的话,可以把请求撤回的消息也一并撤回
|
||||
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)))
|
||||
})
|
||||
// 群聊转发
|
||||
engine.OnRegex(`^群聊转发.*?(\d+)\s(.*)`, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
|
||||
@@ -16,13 +16,12 @@ import (
|
||||
const (
|
||||
jpapi = "https://moegoe.azurewebsites.net/api/speak?text=%s&id=%d"
|
||||
krapi = "https://moegoe.azurewebsites.net/api/speakkr?text=%s&id=%d"
|
||||
cnapi = "https://genshin.azurewebsites.net/api/speak?format=mp3&text=%s&id=%d"
|
||||
cnapi = "http://267978.proxy.nscc-gz.cn:8888?text=%s&speaker=%s"
|
||||
)
|
||||
|
||||
var speakers = map[string]uint{
|
||||
"宁宁": 0, "爱瑠": 1, "芳乃": 2, "茉子": 3, "丛雨": 4, "小春": 5, "七海": 6,
|
||||
"Sua": 0, "Mimiru": 1, "Arin": 2, "Yeonhwa": 3, "Yuhwa": 4, "Seonbae": 5,
|
||||
"派蒙": 0, "凯亚": 1, "安柏": 2, "丽莎": 3, "琴": 4, "香菱": 5, "枫原万叶": 6, "迪卢克": 7, "温迪": 8, "可莉": 9, "早柚": 10, "托马": 11, "芭芭拉": 12, "优菈": 13, "云堇": 14, "钟离": 15, "魈": 16, "凝光": 17, "雷电将军": 18, "北斗": 19, "甘雨": 20, "七七": 21, "刻晴": 22, "神里绫华": 23, "戴因斯雷布": 24, "雷泽": 25, "神里绫人": 26, "罗莎莉亚": 27, "阿贝多": 28, "八重神子": 29, "宵宫": 30, "荒泷一斗": 31, "九条裟罗": 32, "夜兰": 33, "珊瑚宫心海": 34, "五郎": 35, "散兵": 36, "女士": 37, "达达利亚": 38, "莫娜": 39, "班尼特": 40, "申鹤": 41, "行秋": 42, "烟绯": 43, "久岐忍": 44, "辛焱": 45, "砂糖": 46, "胡桃": 47, "重云": 48, "菲谢尔": 49, "诺艾尔": 50, "迪奥娜": 51, "鹿野院平藏": 52,
|
||||
}
|
||||
|
||||
func init() {
|
||||
@@ -31,7 +30,7 @@ func init() {
|
||||
Brief: "日韩中 VITS 模型拟声",
|
||||
Help: "- 让[宁宁|爱瑠|芳乃|茉子|丛雨|小春|七海]说(日语)\n" +
|
||||
"- 让[Sua|Mimiru|Arin|Yeonhwa|Yuhwa|Seonbae]说(韩语)\n" +
|
||||
"- 让[派蒙|凯亚|安柏|丽莎|琴|香菱|枫原万叶|迪卢克|温迪|可莉|早柚|托马|芭芭拉|优菈|云堇|钟离|魈|凝光|雷电将军|北斗|甘雨|七七|刻晴|神里绫华|雷泽|神里绫人|罗莎莉亚|阿贝多|八重神子|宵宫|荒泷一斗|九条裟罗|夜兰|珊瑚宫心海|五郎|达达利亚|莫娜|班尼特|申鹤|行秋|烟绯|久岐忍|辛焱|砂糖|胡桃|重云|菲谢尔|诺艾尔|迪奥娜|鹿野院平藏]说(中文)",
|
||||
"- 让[派蒙|空|荧|阿贝多|枫原万叶|温迪|八重神子|纳西妲|钟离|诺艾尔|凝光|托马|北斗|莫娜|荒泷一斗|提纳里|芭芭拉|艾尔海森|雷电将军|赛诺|琴|班尼特|五郎|神里绫华|迪希雅|夜兰|辛焱|安柏|宵宫|云堇|妮露|烟绯|鹿野院平藏|凯亚|达达利亚|迪卢克|可莉|早柚|香菱|重云|刻晴|久岐忍|珊瑚宫心海|迪奥娜|戴因斯雷布|魈|神里绫人|丽莎|优菈|凯瑟琳|雷泽|菲谢尔|九条裟罗|甘雨|行秋|胡桃|迪娜泽黛|柯莱|申鹤|砂糖|萍姥姥|奥兹|罗莎莉亚|式大将|哲平|坎蒂丝|托克|留云借风真君|昆钧|塞琉斯|多莉|大肉丸|莱依拉|散兵|拉赫曼|杜拉夫|阿守|玛乔丽|纳比尔|海芭夏|九条镰治|阿娜耶|阿晃|阿扎尔|七七|博士|白术|埃洛伊|大慈树王|女士|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|芽衣|雷之律者|阿波尼亚]说(中文)",
|
||||
}).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) {
|
||||
@@ -45,10 +44,10 @@ func init() {
|
||||
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).
|
||||
en.OnRegex("^让(派蒙|空|荧|阿贝多|枫原万叶|温迪|八重神子|纳西妲|钟离|诺艾尔|凝光|托马|北斗|莫娜|荒泷一斗|提纳里|芭芭拉|艾尔海森|雷电将军|赛诺|琴|班尼特|五郎|神里绫华|迪希雅|夜兰|辛焱|安柏|宵宫|云堇|妮露|烟绯|鹿野院平藏|凯亚|达达利亚|迪卢克|可莉|早柚|香菱|重云|刻晴|久岐忍|珊瑚宫心海|迪奥娜|戴因斯雷布|魈|神里绫人|丽莎|优菈|凯瑟琳|雷泽|菲谢尔|九条裟罗|甘雨|行秋|胡桃|迪娜泽黛|柯莱|申鹤|砂糖|萍姥姥|奥兹|罗莎莉亚|式大将|哲平|坎蒂丝|托克|留云借风真君|昆钧|塞琉斯|多莉|大肉丸|莱依拉|散兵|拉赫曼|杜拉夫|阿守|玛乔丽|纳比尔|海芭夏|九条镰治|阿娜耶|阿晃|阿扎尔|七七|博士|白术|埃洛伊|大慈树王|女士|丽塔|失落迷迭|缭乱星棘|伊甸|伏特加女孩|狂热蓝调|莉莉娅|萝莎莉娅|八重樱|八重霞|卡莲|第六夜想曲|卡萝尔|姬子|极地战刃|布洛妮娅|次生银翼|理之律者|迷城骇兔|希儿|魇夜星渊|黑希儿|帕朵菲莉丝|天元骑英|幽兰黛尔|德丽莎|月下初拥|朔夜观星|暮光骑士|明日香|李素裳|格蕾修|梅比乌斯|渡鸦|人之律者|爱莉希雅|爱衣|天穹游侠|琪亚娜|空之律者|薪炎之律者|云墨丹心|符华|识之律者|维尔薇|芽衣|雷之律者|阿波尼亚)说([\\s\u4e00-\u9fa5\\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(cnapi, url.QueryEscape(text), id)))
|
||||
speaker := ctx.State["regex_matched"].([]string)[1]
|
||||
ctx.SendChain(message.Record(fmt.Sprintf(cnapi, url.QueryEscape(text), speaker)))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Package music QQ音乐、网易云、酷狗、酷我 点歌
|
||||
// Package music QQ音乐、网易云、酷狗、酷我、咪咕 点歌
|
||||
package music
|
||||
|
||||
import (
|
||||
@@ -28,11 +28,14 @@ func init() {
|
||||
Help: "- 点歌[xxx]\n" +
|
||||
"- 网易点歌[xxx]\n" +
|
||||
"- 酷我点歌[xxx]\n" +
|
||||
"- 酷狗点歌[xxx]",
|
||||
"- 酷狗点歌[xxx]\n" +
|
||||
"- 咪咕点歌[xxx]",
|
||||
}).OnRegex(`^(.{0,2})点歌\s?(.{1,25})$`).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
// switch 平台
|
||||
switch ctx.State["regex_matched"].([]string)[1] {
|
||||
case "咪咕":
|
||||
ctx.SendChain(migu(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "酷我":
|
||||
ctx.SendChain(kuwo(ctx.State["regex_matched"].([]string)[2]))
|
||||
case "酷狗":
|
||||
@@ -45,6 +48,32 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// migu 返回咪咕音乐卡片
|
||||
func migu(keyword string) message.MessageSegment {
|
||||
headers := http.Header{
|
||||
"Cookie": []string{"audioplayer_exist=1; audioplayer_open=0; migu_cn_cookie_id=3ad476db-f021-4bda-ab91-c485ac3d56a0; Hm_lvt_ec5a5474d9d871cb3d82b846d861979d=1671119573; Hm_lpvt_ec5a5474d9d871cb3d82b846d861979d=1671119573; WT_FPC=id=279ef92eaf314cbb8d01671116477485:lv=1671119583092:ss=1671116477485"},
|
||||
"csrf": []string{"LWKACV45JSQ"},
|
||||
"User-Agent": []string{"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36"},
|
||||
"Referer": []string{"http://m.music.migu.cn"},
|
||||
"proxy": []string{"false"},
|
||||
}
|
||||
// 搜索音乐信息 第一首歌
|
||||
search, _ := url.Parse("http://m.music.migu.cn/migu/remoting/scr_search_tag")
|
||||
search.RawQuery = url.Values{
|
||||
"keyword": []string{keyword},
|
||||
"type": []string{"2"},
|
||||
"pgc": []string{"1"},
|
||||
"rows": []string{"10"},
|
||||
}.Encode()
|
||||
info := gjson.ParseBytes(netGet(search.String(), headers)).Get("musics.0")
|
||||
// 返回音乐卡片
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://music.migu.cn/v3/music/song/%s", info.Get("copyrightId").String()),
|
||||
info.Get("mp3").String(),
|
||||
info.Get("songName").String(),
|
||||
).Add("content", info.Get("artist").Str).Add("image", info.Get("cover").Str).Add("subtype", "migu")
|
||||
}
|
||||
|
||||
// kuwo 返回酷我音乐卡片
|
||||
func kuwo(keyword string) message.MessageSegment {
|
||||
headers := http.Header{
|
||||
@@ -63,23 +92,20 @@ func kuwo(keyword string) message.MessageSegment {
|
||||
}.Encode()
|
||||
info := gjson.ParseBytes(netGet(search.String(), headers)).Get("data.list.0")
|
||||
// 获得音乐直链
|
||||
music, _ := url.Parse("http://www.kuwo.cn/url")
|
||||
music, _ := url.Parse("http://www.kuwo.cn/api/v1/www/music/playUrl")
|
||||
music.RawQuery = url.Values{
|
||||
"format": []string{"mp3"},
|
||||
"rid": []string{fmt.Sprintf("%d", info.Get("rid").Int())},
|
||||
"response": []string{"url"},
|
||||
"mid": []string{fmt.Sprintf("%d", info.Get("rid").Int())},
|
||||
"type": []string{"convert_url3"},
|
||||
"br": []string{"128kmp3"},
|
||||
"from": []string{"web"},
|
||||
"br": []string{"320kmp3"},
|
||||
"httpsStatus": []string{"1"},
|
||||
}.Encode()
|
||||
audio := gjson.ParseBytes(netGet(music.String(), headers))
|
||||
// 返回音乐卡片
|
||||
return message.CustomMusic(
|
||||
fmt.Sprintf("https://www.kuwo.cn/play_detail/%d", info.Get("rid").Int()),
|
||||
audio.Get("url").Str,
|
||||
audio.Get("data.url").Str,
|
||||
info.Get("name").Str,
|
||||
).Add("content", info.Get("artist").Str).Add("image", info.Get("pic").Str)
|
||||
).Add("content", info.Get("artist").Str).Add("image", info.Get("pic").Str).Add("subtype", "kuwo")
|
||||
}
|
||||
|
||||
// kugou 返回酷狗音乐卡片
|
||||
@@ -133,7 +159,7 @@ func kugou(keyword string) message.MessageSegment {
|
||||
"https://www.kugou.com/song/#hash="+audio.Get("hash").Str+"&album_id="+audio.Get("album_id").Str,
|
||||
strings.ReplaceAll(audio.Get("play_backup_url").Str, "\\/", "/"),
|
||||
audio.Get("audio_name").Str,
|
||||
).Add("content", audio.Get("author_name").Str).Add("image", audio.Get("img").Str)
|
||||
).Add("content", audio.Get("author_name").Str).Add("image", audio.Get("img").Str).Add("subtype", "kugou")
|
||||
}
|
||||
|
||||
// cloud163 返回网易云音乐卡片
|
||||
@@ -151,7 +177,7 @@ func cloud163(keyword string) (msg message.MessageSegment) {
|
||||
// qqmusic 返回QQ音乐卡片
|
||||
func qqmusic(keyword string) (msg message.MessageSegment) {
|
||||
requestURL := "https://c.y.qq.com/splcloud/fcgi-bin/smartbox_new.fcg?platform=yqq.json&key=" + url.QueryEscape(keyword)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), requestURL, "GET", "", web.RandUA())
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), requestURL, "GET", "", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
msg = message.Text("ERROR: ", err)
|
||||
return
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/wdvxdr1123/ZeroBot/utils/helper"
|
||||
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
)
|
||||
@@ -78,8 +79,9 @@ func init() {
|
||||
return
|
||||
}
|
||||
}
|
||||
err := file.DownloadTo(url, grpfolder+"/"+name, true)
|
||||
err := file.DownloadTo(url, grpfolder+"/"+name)
|
||||
if err == nil {
|
||||
process.SleepAbout1sTo2s()
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("成功!"))
|
||||
} else {
|
||||
ctx.SendChain(message.Reply(ctx.Event.MessageID), message.Text("错误:", err.Error()))
|
||||
|
||||
@@ -3,19 +3,21 @@ package novel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/antchfx/htmlquery"
|
||||
"github.com/sirupsen/logrus"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
"github.com/wdvxdr1123/ZeroBot/utils/helper"
|
||||
|
||||
ub "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"
|
||||
@@ -32,26 +34,47 @@ const (
|
||||
ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
|
||||
loginURL = websiteURL + "/login.php?do=submit&jumpurl=https%3A%2F%2Fwww.23qb.com%2F"
|
||||
searchURL = websiteURL + "/saerch.php"
|
||||
downloadURL = websiteURL + "/modules/article/txtarticle.php?id=%v"
|
||||
detailURL = websiteURL + "/book/%v/"
|
||||
idReg = `/(\d+)/`
|
||||
)
|
||||
|
||||
var gCurCookieJar *cookiejar.Jar
|
||||
var (
|
||||
cachePath string
|
||||
// apikey 由账号和密码拼接而成, 例: zerobot,123456
|
||||
apikey string
|
||||
)
|
||||
|
||||
func init() {
|
||||
control.Register("novel", &ctrl.Options[*zero.Ctx]{
|
||||
engine := control.Register("novel", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "铅笔小说网搜索",
|
||||
Help: "- 小说[xxx]",
|
||||
}).OnRegex("^小说([\u4E00-\u9FA5A-Za-z0-9]{1,25})$").SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Help: "- 小说[xxx]\n" +
|
||||
"- 设置小说配置 zerobot 123456\n" +
|
||||
"- 下载小说30298\n" +
|
||||
"建议去https://www.23qb.com/ 注册一个账号, 小说下载有积分限制",
|
||||
PrivateDataFolder: "novel",
|
||||
})
|
||||
cachePath = engine.DataFolder() + "cache/"
|
||||
_ = os.MkdirAll(cachePath, 0755)
|
||||
engine.OnRegex("^小说([\u4E00-\u9FA5A-Za-z0-9]{1,25})$").SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text("少女祈祷中......"))
|
||||
err := login(username, password)
|
||||
key := getAPIKey(ctx)
|
||||
u, p, _ := strings.Cut(key, ",")
|
||||
if u == "" {
|
||||
u = username
|
||||
}
|
||||
if p == "" {
|
||||
p = password
|
||||
}
|
||||
cookie, err := login(u, p)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
searchKey := ctx.State["regex_matched"].([]string)[1]
|
||||
searchHTML, err := search(searchKey)
|
||||
searchHTML, err := search(searchKey, cookie)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
@@ -93,7 +116,7 @@ func init() {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if id := ctx.SendChain(message.Image("base64://" + helper.BytesToString(data))); id.ID() == 0 {
|
||||
if id := ctx.SendChain(message.Image("base64://" + ub.BytesToString(data))); id.ID() == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 可能被风控了"))
|
||||
}
|
||||
} else {
|
||||
@@ -124,23 +147,76 @@ func init() {
|
||||
ctx.SendChain(message.Text(text))
|
||||
}
|
||||
})
|
||||
engine.OnRegex(`^设置小说配置\s(.*[^\s$])\s(.+)$`, zero.SuperUserPermission).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
regexMatched := ctx.State["regex_matched"].([]string)
|
||||
err := setAPIKey(ctx.State["manager"].(*ctrl.Control[*zero.Ctx]), regexMatched[1]+","+regexMatched[2])
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text("成功设置小说配置\nusername: ", regexMatched[1], "\npassword: ", regexMatched[2]))
|
||||
})
|
||||
engine.OnRegex("^下载小说([0-9]{1,25})$").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
regexMatched := ctx.State["regex_matched"].([]string)
|
||||
id := regexMatched[1]
|
||||
ctx.SendChain(message.Text("少女祈祷中......"))
|
||||
key := getAPIKey(ctx)
|
||||
u, p, _ := strings.Cut(key, ",")
|
||||
if u == "" {
|
||||
u = username
|
||||
}
|
||||
if p == "" {
|
||||
p = password
|
||||
}
|
||||
cookie, err := login(u, p)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
detailHTML, err := detail(id, cookie)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
doc, err := htmlquery.Parse(strings.NewReader(detailHTML))
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
title := htmlquery.InnerText(htmlquery.FindOne(doc, "//*[@id='bookinfo']/div[@class='bookright']/div[@class='d_title']/h1"))
|
||||
fileName := filepath.Join(cachePath, title+".txt")
|
||||
if file.IsExist(fileName) {
|
||||
ctx.UploadThisGroupFile(filepath.Join(file.BOTPATH, fileName), filepath.Base(fileName), "")
|
||||
return
|
||||
}
|
||||
data, err := download(id, cookie)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
err = os.WriteFile(fileName, ub.StringToBytes(data), 0666)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.UploadThisGroupFile(filepath.Join(file.BOTPATH, fileName), filepath.Base(fileName), "")
|
||||
})
|
||||
}
|
||||
|
||||
func login(username, password string) (err error) {
|
||||
gCurCookieJar, _ = cookiejar.New(nil)
|
||||
client := &http.Client{
|
||||
Jar: gCurCookieJar,
|
||||
}
|
||||
usernameData, err := ub.UTF82GBK(helper.StringToBytes(username))
|
||||
func login(username, password string) (cookie string, err error) {
|
||||
client := &http.Client{}
|
||||
usernameData, err := ub.UTF82GBK(ub.StringToBytes(username))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
usernameGbk := helper.BytesToString(usernameData)
|
||||
passwordData, err := ub.UTF82GBK(helper.StringToBytes(password))
|
||||
usernameGbk := ub.BytesToString(usernameData)
|
||||
passwordData, err := ub.UTF82GBK(ub.StringToBytes(password))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
passwordGbk := helper.BytesToString(passwordData)
|
||||
passwordGbk := ub.BytesToString(passwordData)
|
||||
loginReq, err := http.NewRequest("POST", loginURL, strings.NewReader(fmt.Sprintf("username=%s&password=%s&usecookie=315360000&action=login&submit=%s", url.QueryEscape(usernameGbk), url.QueryEscape(passwordGbk), submit)))
|
||||
if err != nil {
|
||||
return
|
||||
@@ -151,38 +227,79 @@ func login(username, password string) (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_ = loginResp.Body.Close()
|
||||
defer loginResp.Body.Close()
|
||||
for _, v := range loginResp.Cookies() {
|
||||
cookie += v.Name + "=" + v.Value + ";"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func search(searchKey string) (searchHTML string, err error) {
|
||||
searchKeyData, err := ub.UTF82GBK(helper.StringToBytes(searchKey))
|
||||
func search(searchKey string, cookie string) (searchHTML string, err error) {
|
||||
searchKeyData, err := ub.UTF82GBK(ub.StringToBytes(searchKey))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
searchKeyGbk := helper.BytesToString(searchKeyData)
|
||||
client := &http.Client{
|
||||
Jar: gCurCookieJar,
|
||||
}
|
||||
searchReq, err := http.NewRequest("POST", searchURL, strings.NewReader(fmt.Sprintf("searchkey=%s&searchtype=all", url.QueryEscape(searchKeyGbk))))
|
||||
searchKeyGbk := ub.BytesToString(searchKeyData)
|
||||
data, err := web.RequestDataWithHeaders(web.NewDefaultClient(), searchURL, "POST", func(r *http.Request) error {
|
||||
r.Header.Set("Cookie", cookie)
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
r.Header.Set("User-Agent", ua)
|
||||
return nil
|
||||
}, strings.NewReader(fmt.Sprintf("searchkey=%s&searchtype=all", url.QueryEscape(searchKeyGbk))))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
searchReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
searchReq.Header.Set("User-Agent", ua)
|
||||
searchResp, err := client.Do(searchReq)
|
||||
searchData, err := ub.GBK2UTF8(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
searchData, err := io.ReadAll(searchResp.Body)
|
||||
_ = searchResp.Body.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
searchData, err = ub.GBK2UTF8(searchData)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
searchHTML = helper.BytesToString(searchData)
|
||||
return searchHTML, nil
|
||||
searchHTML = ub.BytesToString(searchData)
|
||||
return
|
||||
}
|
||||
|
||||
func detail(id string, cookie string) (detailHTML string, err error) {
|
||||
data, err := web.RequestDataWithHeaders(web.NewDefaultClient(), fmt.Sprintf(detailURL, id), "GET", func(r *http.Request) error {
|
||||
r.Header.Set("Cookie", cookie)
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
r.Header.Set("User-Agent", ua)
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
detailData, err := ub.GBK2UTF8(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
detailHTML = ub.BytesToString(detailData)
|
||||
return
|
||||
}
|
||||
|
||||
func download(id string, cookie string) (downloadHTML string, err error) {
|
||||
data, err := web.RequestDataWithHeaders(web.NewDefaultClient(), fmt.Sprintf(downloadURL, id), "GET", func(r *http.Request) error {
|
||||
r.Header.Set("Cookie", cookie)
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
r.Header.Set("User-Agent", ua)
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
downloadHTML = ub.BytesToString(data)
|
||||
return
|
||||
}
|
||||
|
||||
func getAPIKey(ctx *zero.Ctx) string {
|
||||
if apikey == "" {
|
||||
m := ctx.State["manager"].(*ctrl.Control[*zero.Ctx])
|
||||
_ = m.Manager.GetExtra(-1, &apikey)
|
||||
logrus.Debugln("[novel] get api key:", apikey)
|
||||
}
|
||||
return apikey
|
||||
}
|
||||
|
||||
func setAPIKey(m *ctrl.Control[*zero.Ctx], key string) error {
|
||||
apikey = key
|
||||
_ = m.Manager.Response(-1)
|
||||
return m.Manager.SetExtra(-1, apikey)
|
||||
}
|
||||
|
||||
@@ -21,16 +21,13 @@ import (
|
||||
// 数据库
|
||||
sql "github.com/FloatTech/sqlite"
|
||||
// 画图
|
||||
"github.com/Coloured-glaze/gg"
|
||||
fcext "github.com/FloatTech/floatbox/ctxext"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
// 货币系统
|
||||
)
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
type 婚姻登记 struct {
|
||||
db *sql.Sqlite
|
||||
sync.RWMutex
|
||||
@@ -56,15 +53,13 @@ type userinfo struct {
|
||||
}
|
||||
|
||||
var (
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
民政局 = &婚姻登记{
|
||||
db: &sql.Sqlite{},
|
||||
}
|
||||
engine = control.Register("qqwife", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "一群一天一夫一妻制群老婆",
|
||||
Help: "- 娶群友\n- 群老婆列表\n- [允许|禁止]自由恋爱\n- [允许|禁止]牛头人\n- 设置CD为xx小时 →(默认12小时)\n- 重置花名册\n- 重置所有花名册(用于清除所有群数据及其设置)\n- 查好感度[对方Q号|@对方QQ]\n- 好感度列表\n" +
|
||||
Help: "- 娶群友\n- 群老婆列表\n- [允许|禁止]自由恋爱\n- [允许|禁止]牛头人\n- 设置CD为xx小时 →(默认12小时)\n- 重置花名册\n- 重置所有花名册(用于清除所有群数据及其设置)\n- 查好感度[对方Q号|@对方QQ]\n- 好感度列表\n- 好感度数据整理 (当好感度列表出现重复名字时使用)\n" +
|
||||
"--------------------------------\n以下指令存在CD,不跨天刷新,前两个受指令开关\n--------------------------------\n" +
|
||||
"- (娶|嫁)@对方QQ\n自由选择对象, 自由恋爱(好感度越高成功率越高,保底30%概率)\n" +
|
||||
"- 当[对方Q号|@对方QQ]的小三\n我和你才是真爱, 为了你我愿意付出一切(好感度越高成功率越高,保底10%概率)\n" +
|
||||
@@ -73,7 +68,7 @@ var (
|
||||
"- 做媒 @攻方QQ @受方QQ\n身为管理, 群友的xing福是要搭把手的(攻受双方好感度越高成功率越高,保底30%概率)\n" +
|
||||
"--------------------------------\n好感度规则\n--------------------------------\n" +
|
||||
"\"娶群友\"指令好感度随机增加1~5。\n\"A牛B的C\"会导致C恨A, 好感度-5;\nB为了报复A, 好感度+5(什么柜子play)\nA为BC做媒,成功B、C对A好感度+1反之-1\n做媒成功BC好感度+1" +
|
||||
"Tips: 群老婆列表过0点刷新",
|
||||
"\nTips: 群老婆列表过0点刷新",
|
||||
PrivateDataFolder: "qqwife",
|
||||
}).ApplySingle(single.New(
|
||||
single.WithKeyFn(func(ctx *zero.Ctx) int64 { return ctx.Event.GroupID }),
|
||||
@@ -286,7 +281,7 @@ func init() {
|
||||
err = 民政局.清理花名册("group" + strconv.FormatInt(ctx.Event.GroupID, 10))
|
||||
default:
|
||||
cmd := ctx.State["regex_matched"].([]string)[1]
|
||||
gid, _ := strconv.ParseInt(cmd, 10, 64) //判断是否为群号
|
||||
gid, _ := strconv.ParseInt(cmd, 10, 64) // 判断是否为群号
|
||||
if gid == 0 {
|
||||
ctx.SendChain(message.Text("请输入正确的群号"))
|
||||
return
|
||||
@@ -301,8 +296,6 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 查看设置(gid int64) (dbinfo updateinfo, err error) {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -324,16 +317,12 @@ func (sql *婚姻登记) 查看设置(gid int64) (dbinfo updateinfo, err error)
|
||||
return
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 更新设置(dbinfo updateinfo) error {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
return sql.db.Insert("updateinfo", &dbinfo)
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 开门时间(gid int64) error {
|
||||
grouInfo, err := sql.查看设置(gid)
|
||||
if err != nil {
|
||||
@@ -354,8 +343,6 @@ func (sql *婚姻登记) 开门时间(gid int64) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, err error) {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -373,8 +360,6 @@ func (sql *婚姻登记) 查户口(gid, uid int64) (info userinfo, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
// 民政局登记数据
|
||||
func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname string) error {
|
||||
sql.Lock()
|
||||
@@ -390,8 +375,6 @@ func (sql *婚姻登记) 登记(gid, uid, target int64, username, targetname str
|
||||
return sql.db.Insert(gidstr, &uidinfo)
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 花名册(gid int64) (list [][4]string, err error) {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -437,8 +420,6 @@ func slicename(name string, canvas *gg.Context) (resultname string) {
|
||||
return
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 清理花名册(gid ...string) error {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -449,7 +430,6 @@ func (sql *婚姻登记) 清理花名册(gid ...string) error {
|
||||
for _, listName := range grouplist {
|
||||
if listName == "favorability" {
|
||||
continue
|
||||
|
||||
}
|
||||
err = sql.db.Drop(listName)
|
||||
}
|
||||
|
||||
@@ -12,10 +12,11 @@ import (
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
// 画图
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/gg"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
|
||||
// 货币系统
|
||||
@@ -83,16 +84,18 @@ func init() {
|
||||
ctx.SendChain(message.Text("你钱包没钱啦!"))
|
||||
return
|
||||
}
|
||||
moneyToFavor := rand.Intn(math.Min(walletinfo, 100))
|
||||
moneyToFavor := rand.Intn(math.Min(walletinfo, 100)) + 1
|
||||
// 计算钱对应的好感值
|
||||
newFavor := 1
|
||||
moodMax := 2
|
||||
if favor > 50 {
|
||||
newFavor = moneyToFavor % 10 // 礼物厌倦
|
||||
} else {
|
||||
moodMax = 5
|
||||
newFavor += rand.Intn(moneyToFavor)
|
||||
}
|
||||
// 随机对方心情
|
||||
mood := rand.Intn(2)
|
||||
mood := rand.Intn(moodMax)
|
||||
if mood == 0 {
|
||||
newFavor = -newFavor
|
||||
}
|
||||
@@ -190,10 +193,73 @@ func init() {
|
||||
ctx.SendChain(message.ImageBytes(data))
|
||||
cl()
|
||||
})
|
||||
|
||||
engine.OnFullMatch("好感度数据整理", zero.SuperUserPermission, getdb).SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
ctx.SendChain(message.Text("开始整理力,请稍等"))
|
||||
民政局.Lock()
|
||||
defer 民政局.Unlock()
|
||||
count, err := 民政局.db.Count("favorability")
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("[ERROR]: ", err))
|
||||
return
|
||||
}
|
||||
if count == 0 {
|
||||
ctx.SendChain(message.Text("[ERROR]: 不存在好感度数据."))
|
||||
return
|
||||
}
|
||||
favor := favorability{}
|
||||
delInfo := make([]string, 0, count*2)
|
||||
favorInfo := make(map[string]int, count*2)
|
||||
_ = 民政局.db.FindFor("favorability", &favor, "group by Userinfo", func() error {
|
||||
delInfo = append(delInfo, favor.Userinfo)
|
||||
// 解析旧数据
|
||||
userList := strings.Split(favor.Userinfo, "+")
|
||||
maxQQ, _ := strconv.ParseInt(userList[0], 10, 64)
|
||||
minQQ, _ := strconv.ParseInt(userList[1], 10, 64)
|
||||
if maxQQ > minQQ {
|
||||
favor.Userinfo = userList[0] + "+" + userList[1]
|
||||
} else {
|
||||
favor.Userinfo = userList[1] + "+" + userList[0]
|
||||
}
|
||||
// 判断是否是重复的
|
||||
score, ok := favorInfo[favor.Userinfo]
|
||||
if ok {
|
||||
if score < favor.Favor {
|
||||
favorInfo[favor.Userinfo] = favor.Favor
|
||||
}
|
||||
} else {
|
||||
favorInfo[favor.Userinfo] = favor.Favor
|
||||
}
|
||||
return nil
|
||||
})
|
||||
for _, updateinfo := range delInfo {
|
||||
// 删除旧数据
|
||||
err = 民政局.db.Del("favorability", "where Userinfo = '"+updateinfo+"'")
|
||||
if err != nil {
|
||||
userList := strings.Split(favor.Userinfo, "+")
|
||||
uid1, _ := strconv.ParseInt(userList[0], 10, 64)
|
||||
uid2, _ := strconv.ParseInt(userList[1], 10, 64)
|
||||
ctx.SendChain(message.Text("[ERROR]: 删除", ctx.CardOrNickName(uid1), "和", ctx.CardOrNickName(uid2), "的好感度时发生了错误。\n错误信息:", err))
|
||||
}
|
||||
}
|
||||
for userInfo, favor := range favorInfo {
|
||||
favorInfo := favorability{
|
||||
Userinfo: userInfo,
|
||||
Favor: favor,
|
||||
}
|
||||
err = 民政局.db.Insert("favorability", &favorInfo)
|
||||
if err != nil {
|
||||
userList := strings.Split(userInfo, "+")
|
||||
uid1, _ := strconv.ParseInt(userList[0], 10, 64)
|
||||
uid2, _ := strconv.ParseInt(userList[1], 10, 64)
|
||||
ctx.SendChain(message.Text("[ERROR]: 更新", ctx.CardOrNickName(uid1), "和", ctx.CardOrNickName(uid2), "的好感度时发生了错误。\n错误信息:", err))
|
||||
}
|
||||
}
|
||||
ctx.SendChain(message.Text("清理好了哦"))
|
||||
})
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
func (sql *婚姻登记) 查好感度(uid, target int64) (int, error) {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -202,9 +268,19 @@ func (sql *婚姻登记) 查好感度(uid, target int64) (int, error) {
|
||||
return 0, err
|
||||
}
|
||||
info := favorability{}
|
||||
uidstr := strconv.FormatInt(uid, 10)
|
||||
targstr := strconv.FormatInt(target, 10)
|
||||
_ = sql.db.Find("favorability", &info, "where Userinfo glob '*"+uidstr+"+"+targstr+"*'")
|
||||
if uid > target {
|
||||
userinfo := strconv.FormatInt(uid, 10) + "+" + strconv.FormatInt(target, 10)
|
||||
err = sql.db.Find("favorability", &info, "where Userinfo is '"+userinfo+"'")
|
||||
if err != nil {
|
||||
_ = sql.db.Find("favorability", &info, "where Userinfo glob '*"+userinfo+"*'")
|
||||
}
|
||||
} else {
|
||||
userinfo := strconv.FormatInt(target, 10) + "+" + strconv.FormatInt(uid, 10)
|
||||
err = sql.db.Find("favorability", &info, "where Userinfo is '"+userinfo+"'")
|
||||
if err != nil {
|
||||
_ = sql.db.Find("favorability", &info, "where Userinfo glob '*"+userinfo+"*'")
|
||||
}
|
||||
}
|
||||
return info.Favor, nil
|
||||
}
|
||||
|
||||
@@ -246,8 +322,6 @@ func (sql *婚姻登记) getGroupFavorability(uid int64) (list favorList, err er
|
||||
return
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
//nolint: asciicheck
|
||||
// 设置好感度 正增负减
|
||||
func (sql *婚姻登记) 更新好感度(uid, target int64, score int) (favor int, err error) {
|
||||
sql.Lock()
|
||||
@@ -259,8 +333,19 @@ func (sql *婚姻登记) 更新好感度(uid, target int64, score int) (favor in
|
||||
info := favorability{}
|
||||
uidstr := strconv.FormatInt(uid, 10)
|
||||
targstr := strconv.FormatInt(target, 10)
|
||||
_ = sql.db.Find("favorability", &info, "where Userinfo glob '*"+uidstr+"+"+targstr+"*'")
|
||||
info.Userinfo = uidstr + "+" + targstr + "+" + uidstr
|
||||
if uid > target {
|
||||
info.Userinfo = uidstr + "+" + targstr
|
||||
err = sql.db.Find("favorability", &info, "where Userinfo is '"+info.Userinfo+"'")
|
||||
} else {
|
||||
info.Userinfo = targstr + "+" + uidstr
|
||||
err = sql.db.Find("favorability", &info, "where Userinfo is '"+info.Userinfo+"'")
|
||||
}
|
||||
if err != nil {
|
||||
err = sql.db.Find("favorability", &info, "where Userinfo glob '*"+targstr+"+"+uidstr+"*'")
|
||||
if err == nil { // 如果旧数据存在就删除旧数据
|
||||
err = 民政局.db.Del("favorability", "where Userinfo = '"+info.Userinfo+"'")
|
||||
}
|
||||
}
|
||||
info.Favor += score
|
||||
if info.Favor > 100 {
|
||||
info.Favor = 100
|
||||
|
||||
@@ -193,7 +193,7 @@ func init() {
|
||||
var choicetext string
|
||||
var ntrID = uid
|
||||
var targetID = fiancee
|
||||
var greenID int64 //被牛的
|
||||
var greenID int64 // 被牛的
|
||||
fianceeInfo, err := 民政局.查户口(gid, fiancee)
|
||||
switch {
|
||||
case err != nil:
|
||||
@@ -359,8 +359,6 @@ func init() {
|
||||
})
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
// nolint: asciicheck
|
||||
func (sql *婚姻登记) 判断CD(gid, uid int64, model string, cdtime float64) (ok bool, err error) {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -386,8 +384,6 @@ func (sql *婚姻登记) 判断CD(gid, uid int64, model string, cdtime float64)
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
// nolint: asciicheck
|
||||
func (sql *婚姻登记) 记录CD(gid, uid int64, mode string) error {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -399,8 +395,6 @@ func (sql *婚姻登记) 记录CD(gid, uid int64, mode string) error {
|
||||
})
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
// nolint: asciicheck
|
||||
func (sql *婚姻登记) 离婚休妻(gid, wife int64) error {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
@@ -409,8 +403,6 @@ func (sql *婚姻登记) 离婚休妻(gid, wife int64) error {
|
||||
return sql.db.Del(gidstr, "where target = "+wifestr)
|
||||
}
|
||||
|
||||
// nolint: asciicheck
|
||||
// nolint: asciicheck
|
||||
func (sql *婚姻登记) 离婚休夫(gid, husband int64) error {
|
||||
sql.Lock()
|
||||
defer sql.Unlock()
|
||||
|
||||
@@ -3,13 +3,15 @@ package quan
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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"
|
||||
"github.com/wdvxdr1123/ZeroBot/utils/helper"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -25,8 +27,8 @@ func init() { // 主函数
|
||||
"- 权重查询+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 := ctx.State["regex_matched"].([]string)[2] // 获取uid
|
||||
if str == "" { // user
|
||||
str = strconv.FormatInt(ctx.Event.UserID, 10)
|
||||
}
|
||||
es, err := web.GetData(fmt.Sprintf(quan, str)) // 将网站返回结果赋值
|
||||
@@ -34,7 +36,23 @@ func init() { // 主函数
|
||||
ctx.SendChain(message.Text("出现错误捏:", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text(str, helper.BytesToString(es))) // 输出结果
|
||||
if len(helper.BytesToString(es)) <= 24 {
|
||||
ctx.SendChain(message.Text("网站维护中")) // 输出结果
|
||||
return
|
||||
}
|
||||
f := helper.BytesToString(es)[24:]
|
||||
_, err = strconv.Atoi(f)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("网站维护中")) // 输出结果
|
||||
return
|
||||
}
|
||||
var msg strings.Builder
|
||||
msg.WriteString("查询账号:")
|
||||
msg.WriteString(str)
|
||||
msg.WriteString("\n")
|
||||
msg.WriteString("查询状态:成功\n")
|
||||
msg.WriteString("您的权重为:")
|
||||
msg.WriteString(f)
|
||||
ctx.SendChain(message.Text(msg.String())) // 输出结果
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -12,11 +12,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/AnimeAPI/qzone"
|
||||
"github.com/FloatTech/floatbox/binary"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
"github.com/FloatTech/gg"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
@@ -311,12 +311,11 @@ func renderForwardMsg(qq int64, raw string) (base64Bytes []byte, err error) {
|
||||
imgdata []byte
|
||||
msgImg image.Image
|
||||
faceImg image.Image
|
||||
t text.Text
|
||||
)
|
||||
if qq != 0 {
|
||||
face, err = web.GetData(fmt.Sprintf(faceURL, qq))
|
||||
} else {
|
||||
face, err = web.RequestDataWith(web.NewTLS12Client(), fmt.Sprintf(anonymousURL, rand.Intn(4)+1), "GET", "gitcode.net", web.RandUA())
|
||||
face, err = web.RequestDataWith(web.NewTLS12Client(), fmt.Sprintf(anonymousURL, rand.Intn(4)+1), "GET", "gitcode.net", web.RandUA(), nil)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
@@ -332,11 +331,10 @@ func renderForwardMsg(qq int64, raw string) (base64Bytes []byte, err error) {
|
||||
for _, v := range m {
|
||||
switch {
|
||||
case v.Type == "text" && strings.TrimSpace(v.Data["text"]) != "":
|
||||
t, err = text.Render(strings.TrimSuffix(v.Data["text"], "\r\n"), text.FontFile, 400, 40)
|
||||
msgImg, err = text.Render(strings.TrimSuffix(v.Data["text"], "\r\n"), text.FontFile, 400, 40)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
msgImg = t.Image()
|
||||
case v.Type == "image" && v.Data["url"] != "":
|
||||
imgdata, err = web.GetData(v.Data["url"])
|
||||
if err != nil {
|
||||
|
||||
@@ -91,7 +91,7 @@ func init() { // 插件主体
|
||||
"标题: ", illust.Title, "\n",
|
||||
"插画ID: ", illust.Pid, "\n",
|
||||
"画师: ", illust.UserName, "\n",
|
||||
"画师ID: ", illust.UserId, "\n",
|
||||
"画师ID: ", illust.UserID, "\n",
|
||||
"直链: ", "https://pixivel.moe/detail?id=", illust.Pid,
|
||||
)
|
||||
if imgs != nil {
|
||||
@@ -157,7 +157,7 @@ func init() { // 插件主体
|
||||
ctx.SendChain(message.Text("请私聊发送 设置 saucenao api key [apikey] 以启用 saucenao 搜图 (方括号不需要输入), key 请前往 https://saucenao.com/user.php?page=search-api 获取"))
|
||||
}
|
||||
// ascii2d 搜索
|
||||
if result, err := ascii2d.Ascii2d(pic); err != nil {
|
||||
if result, err := ascii2d.ASCII2d(pic); err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
continue
|
||||
} else {
|
||||
|
||||
@@ -9,9 +9,13 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/AnimeAPI/bilibili"
|
||||
"github.com/FloatTech/AnimeAPI/wallet"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/floatbox/process"
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
"github.com/FloatTech/gg"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
@@ -22,13 +26,11 @@ import (
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
|
||||
// 货币系统
|
||||
"github.com/FloatTech/AnimeAPI/wallet"
|
||||
)
|
||||
|
||||
const (
|
||||
backgroundURL = "https://img.moehu.org/pic.php?id=pc"
|
||||
backgroundURL = "https://iw233.cn/api.php?sort=pc"
|
||||
referer = "https://weibo.com/"
|
||||
signinMax = 1
|
||||
// SCOREMAX 分数上限定为1200
|
||||
SCOREMAX = 1200
|
||||
@@ -54,11 +56,6 @@ func init() {
|
||||
}
|
||||
sdb = initialize(engine.DataFolder() + "score.db")
|
||||
}()
|
||||
zero.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币"))
|
||||
})
|
||||
engine.OnFullMatch("签到").Limit(ctxext.LimitByUser).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
uid := ctx.Event.UserID
|
||||
@@ -275,88 +272,6 @@ func init() {
|
||||
}
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
})
|
||||
engine.OnFullMatch("查看钱包排名", zero.OnlyGroup).Limit(ctxext.LimitByGroup).SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
gid := strconv.FormatInt(ctx.Event.GroupID, 10)
|
||||
today := time.Now().Format("20060102")
|
||||
drawedFile := cachePath + gid + today + "walletRank.png"
|
||||
if file.IsExist(drawedFile) {
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
return
|
||||
}
|
||||
// 无缓存获取群员列表
|
||||
temp := ctx.GetThisGroupMemberListNoCache().Array()
|
||||
var usergroup []int64
|
||||
for _, info := range temp {
|
||||
usergroup = append(usergroup, info.Get("user_id").Int())
|
||||
}
|
||||
// 获取钱包信息
|
||||
st, err := wallet.GetGroupWalletOf(usergroup, true)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if len(st) == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 当前没人获取过ATRI币"))
|
||||
return
|
||||
} else if len(st) > 10 {
|
||||
st = st[:10]
|
||||
}
|
||||
_, err = file.GetLazyData(text.FontFile, control.Md5File, true)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
b, err := os.ReadFile(text.FontFile)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
font, err := freetype.ParseFont(b)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
f, err := os.Create(drawedFile)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
var bars []chart.Value
|
||||
for _, v := range st {
|
||||
if v.Money != 0 {
|
||||
bars = append(bars, chart.Value{
|
||||
Label: ctx.CardOrNickName(v.UID),
|
||||
Value: float64(v.Money),
|
||||
})
|
||||
}
|
||||
}
|
||||
err = chart.BarChart{
|
||||
Font: font,
|
||||
Title: "ATRI币排名(1天只刷新1次)",
|
||||
Background: chart.Style{
|
||||
Padding: chart.Box{
|
||||
Top: 40,
|
||||
},
|
||||
},
|
||||
YAxis: chart.YAxis{
|
||||
Range: &chart.ContinuousRange{
|
||||
Min: 0,
|
||||
Max: math.Ceil(bars[0].Value/10) * 10,
|
||||
},
|
||||
},
|
||||
Height: 500,
|
||||
BarWidth: 50,
|
||||
Bars: bars,
|
||||
}.Render(chart.PNG, f)
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
_ = os.Remove(drawedFile)
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
})
|
||||
}
|
||||
|
||||
func getHourWord(t time.Time) string {
|
||||
@@ -392,5 +307,14 @@ func initPic(picFile string) error {
|
||||
if file.IsExist(picFile) {
|
||||
return nil
|
||||
}
|
||||
return file.DownloadTo(backgroundURL, picFile, true)
|
||||
defer process.SleepAbout1sTo2s()
|
||||
url, err := bilibili.GetRealURL(backgroundURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), url, "", referer, "", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(picFile, data, 0644)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package setutime
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -154,6 +155,9 @@ func (p *imgpool) size(imgtype string) int {
|
||||
}
|
||||
|
||||
func (p *imgpool) push(ctx *zero.Ctx, imgtype string, illust *pixiv.Illust) {
|
||||
if len(illust.ImageUrls) == 0 {
|
||||
return
|
||||
}
|
||||
u := illust.ImageUrls[0]
|
||||
n := u[strings.LastIndex(u, "/")+1 : len(u)-4]
|
||||
m, err := imagepool.GetImage(n)
|
||||
@@ -222,6 +226,9 @@ func (p *imgpool) add(ctx *zero.Ctx, imgtype string, id int64) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(illust.ImageUrls) == 0 {
|
||||
return errors.New("nil image url")
|
||||
}
|
||||
err = imagepool.SendImageFromPool(strconv.FormatInt(illust.Pid, 10)+"_p0", illust.Path(0), func() error {
|
||||
return illust.DownloadToCache(0)
|
||||
}, ctxext.Send(ctx), ctxext.GetMessage(ctx))
|
||||
|
||||
@@ -38,7 +38,7 @@ var (
|
||||
func init() {
|
||||
engine.OnFullMatchGroup([]string{"哄我", "来碗毒鸡汤", "发个朋友圈"}).SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
requestURL := sdMap[ctx.State["matched"].(string)]
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), requestURL, "GET", sdReferer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), requestURL, "GET", sdReferer, ua, nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
func init() {
|
||||
engine.OnFullMatch("来碗绿茶").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), chayiURL, "GET", loveliveReferer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), chayiURL, "GET", loveliveReferer, ua, nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
@@ -22,7 +22,7 @@ func init() {
|
||||
})
|
||||
|
||||
engine.OnFullMatch("渣我").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), ganhaiURL, "GET", loveliveReferer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), ganhaiURL, "GET", loveliveReferer, ua, nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
func init() {
|
||||
engine.OnFullMatch("讲个段子").SetBlock(true).Limit(ctxext.LimitByUser).Handle(func(ctx *zero.Ctx) {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), yduanziURL, "POST", yduanziReferer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), yduanziURL, "POST", yduanziReferer, ua, nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
@@ -122,10 +122,6 @@ func init() {
|
||||
ctx.SendChain(message.Text("ERROR: 张数必须为正"))
|
||||
return
|
||||
}
|
||||
if n > 1 && !zero.OnlyGroup(ctx) {
|
||||
ctx.SendChain(message.Text("ERROR: 抽取多张仅支持群聊"))
|
||||
return
|
||||
}
|
||||
if n > 20 {
|
||||
ctx.SendChain(message.Text("ERROR: 抽取张数过多"))
|
||||
return
|
||||
@@ -153,7 +149,7 @@ func init() {
|
||||
}
|
||||
imgpath := cache + "/" + imgname + ".png"
|
||||
err := pool.SendImageFromPool("pool"+imgname, imgpath, func() error {
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), imgurl, "GET", "gitcode.net", web.RandUA())
|
||||
data, err := web.RequestDataWith(web.NewTLS12Client(), imgurl, "GET", "gitcode.net", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -336,7 +332,7 @@ func poolimg(ctx *zero.Ctx, imgurl, imgname, cache string) (msg message.MessageS
|
||||
}
|
||||
if file.IsNotExist(aimgfile) {
|
||||
var data []byte
|
||||
data, err = web.RequestDataWith(web.NewTLS12Client(), imgurl, "GET", "gitcode.net", web.RandUA())
|
||||
data, err = web.RequestDataWith(web.NewTLS12Client(), imgurl, "GET", "gitcode.net", web.RandUA(), nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
package thesaurus
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/fs"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
@@ -82,7 +81,7 @@ func init() {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
seg, err := jieba.LoadDictionary(&mockfile{data: data})
|
||||
seg, err := jieba.LoadDictionary(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@@ -120,13 +119,13 @@ func init() {
|
||||
}
|
||||
logrus.Infoln("[thesaurus]加载", len(chatListD), "条傲娇词库", len(chatListK), "条可爱词库")
|
||||
|
||||
engine.OnMessage(canmatch(tKIMO), match(chatList, seg, getmsg)).
|
||||
engine.OnMessage(canmatch(tKIMO), match(chatList, seg)).
|
||||
SetBlock(false).
|
||||
Handle(randreply(kimomap))
|
||||
engine.OnMessage(canmatch(tDERE), match(chatListD, seg, getmsg)).
|
||||
engine.OnMessage(canmatch(tDERE), match(chatListD, seg)).
|
||||
SetBlock(false).
|
||||
Handle(randreply(sm.D))
|
||||
engine.OnMessage(canmatch(tKAWA), match(chatListK, seg, getmsg)).
|
||||
engine.OnMessage(canmatch(tKAWA), match(chatListK, seg)).
|
||||
SetBlock(false).
|
||||
Handle(randreply(sm.K))
|
||||
}()
|
||||
@@ -139,42 +138,20 @@ type simai struct {
|
||||
K map[string][]string `yaml:"可爱"`
|
||||
}
|
||||
|
||||
type mockfile struct {
|
||||
p uintptr
|
||||
data []byte
|
||||
}
|
||||
|
||||
func (*mockfile) Stat() (fs.FileInfo, error) {
|
||||
return nil, nil
|
||||
}
|
||||
func (f *mockfile) Read(buf []byte) (int, error) {
|
||||
if int(f.p) >= len(f.data) {
|
||||
return 0, io.EOF
|
||||
}
|
||||
n := copy(buf, f.data[f.p:])
|
||||
f.p += uintptr(n)
|
||||
return n, nil
|
||||
}
|
||||
func (f *mockfile) Close() error {
|
||||
if f.data == nil {
|
||||
return fs.ErrClosed
|
||||
}
|
||||
f.data = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
tKIMO = iota
|
||||
tDERE
|
||||
tKAWA
|
||||
)
|
||||
|
||||
func match(l []string, seg *jieba.Segmenter, getmsg func(*zero.Ctx) string) zero.Rule {
|
||||
func match(l []string, seg *jieba.Segmenter) zero.Rule {
|
||||
return func(ctx *zero.Ctx) bool {
|
||||
if zero.KeywordRule(l...)(ctx) {
|
||||
if zero.FullMatchRule(l...)(ctx) {
|
||||
return true
|
||||
}
|
||||
return ctxext.JiebaFullMatch(seg, getmsg, l...)(ctx)
|
||||
return ctxext.JiebaFullMatch(seg, func(ctx *zero.Ctx) string {
|
||||
return ctx.ExtractPlainText()
|
||||
}, l...)(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,10 +173,6 @@ func canmatch(typ int64) zero.Rule {
|
||||
}
|
||||
}
|
||||
|
||||
func getmsg(ctx *zero.Ctx) string {
|
||||
return ctx.MessageString()
|
||||
}
|
||||
|
||||
func randreply(m map[string][]string) zero.Handler {
|
||||
return func(ctx *zero.Ctx) {
|
||||
key := ctx.State["matched"].(string)
|
||||
|
||||
125
plugin/wallet/wallet.go
Normal file
125
plugin/wallet/wallet.go
Normal file
@@ -0,0 +1,125 @@
|
||||
// Package wallet 钱包
|
||||
package wallet
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/wallet"
|
||||
"github.com/FloatTech/floatbox/file"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/FloatTech/zbputils/img/text"
|
||||
"github.com/golang/freetype"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
func init() {
|
||||
en := control.Register("wallet", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "钱包",
|
||||
Help: "- 查看我的钱包\n- 查看钱包排名",
|
||||
PrivateDataFolder: "wallet",
|
||||
})
|
||||
cachePath := en.DataFolder() + "cache/"
|
||||
go func() {
|
||||
_ = os.RemoveAll(cachePath)
|
||||
err := os.MkdirAll(cachePath, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
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) {
|
||||
gid := strconv.FormatInt(ctx.Event.GroupID, 10)
|
||||
today := time.Now().Format("20060102")
|
||||
drawedFile := cachePath + gid + today + "walletRank.png"
|
||||
if file.IsExist(drawedFile) {
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
return
|
||||
}
|
||||
// 无缓存获取群员列表
|
||||
temp := ctx.GetThisGroupMemberListNoCache().Array()
|
||||
usergroup := make([]int64, len(temp))
|
||||
for i, info := range temp {
|
||||
usergroup[i] = info.Get("user_id").Int()
|
||||
}
|
||||
// 获取钱包信息
|
||||
st, err := wallet.GetGroupWalletOf(true, usergroup...)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if len(st) == 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 当前没人获取过ATRI币"))
|
||||
return
|
||||
} else if len(st) > 10 {
|
||||
st = st[:10]
|
||||
}
|
||||
_, err = file.GetLazyData(text.FontFile, control.Md5File, true)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
b, err := os.ReadFile(text.FontFile)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
font, err := freetype.ParseFont(b)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
f, err := os.Create(drawedFile)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
var bars []chart.Value
|
||||
for _, v := range st {
|
||||
if v.Money != 0 {
|
||||
bars = append(bars, chart.Value{
|
||||
Label: ctx.CardOrNickName(v.UID),
|
||||
Value: float64(v.Money),
|
||||
})
|
||||
}
|
||||
}
|
||||
err = chart.BarChart{
|
||||
Font: font,
|
||||
Title: "ATRI币排名(1天只刷新1次)",
|
||||
Background: chart.Style{
|
||||
Padding: chart.Box{
|
||||
Top: 40,
|
||||
},
|
||||
},
|
||||
YAxis: chart.YAxis{
|
||||
Range: &chart.ContinuousRange{
|
||||
Min: 0,
|
||||
Max: math.Ceil(bars[0].Value/10) * 10,
|
||||
},
|
||||
},
|
||||
Height: 500,
|
||||
BarWidth: 50,
|
||||
Bars: bars,
|
||||
}.Render(chart.PNG, f)
|
||||
_ = f.Close()
|
||||
if err != nil {
|
||||
_ = os.Remove(drawedFile)
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Image("file:///" + file.BOTPATH + "/" + drawedFile))
|
||||
})
|
||||
}
|
||||
@@ -24,7 +24,7 @@ func init() {
|
||||
Help: "- 来份网易云热评",
|
||||
}).OnFullMatch("来份网易云热评").SetBlock(true).Limit(ctxext.LimitByUser).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), wangyiyunURL, "GET", wangyiyunReferer, ua)
|
||||
data, err := web.RequestDataWith(web.NewDefaultClient(), wangyiyunURL, "GET", wangyiyunReferer, ua, nil)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
|
||||
94
plugin/warframeapi/api.go
Normal file
94
plugin/warframeapi/api.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package warframeapi
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
"github.com/FloatTech/floatbox/web"
|
||||
)
|
||||
|
||||
const wfapiurl = "https://api.warframestat.us/pc" // 星际战甲API
|
||||
const wfitemurl = "https://api.warframe.market/v1/items" // 星际战甲游戏品信息列表URL
|
||||
|
||||
// 从WFapi获取数据
|
||||
func newwfapi() (w wfapi, err error) {
|
||||
var data []byte
|
||||
data, err = web.GetData(wfapiurl)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &w)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取Warframe市场的售价表,并进行排序,cn_name为物品中文名称,onlyMaxRank表示只取最高等级的物品,返回物品售价表,物品信息,物品英文
|
||||
func getitemsorder(cnName string, onlyMaxRank bool) (od orders, it *itemsInSet, n string, err error) {
|
||||
var wfapiio wfAPIItemsOrders
|
||||
data, err := web.RequestDataWithHeaders(&http.Client{}, fmt.Sprintf("https://api.warframe.market/v1/items/%s/orders?include=item", cnName), "GET", func(request *http.Request) error {
|
||||
request.Header.Add("Accept", "application/json")
|
||||
request.Header.Add("Platform", "pc")
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = json.Unmarshal(data, &wfapiio)
|
||||
if len(wfapiio.Payload.Orders) == 0 {
|
||||
err = errors.New("no such name")
|
||||
}
|
||||
od = make(orders, 0, len(wfapiio.Payload.Orders))
|
||||
// 遍历市场物品列表
|
||||
for _, v := range wfapiio.Payload.Orders {
|
||||
// 取其中类型为售卖,且去掉不在线的玩家
|
||||
if v.OrderType == "sell" && v.User.Status != "offline" {
|
||||
if !onlyMaxRank {
|
||||
od = append(od, v)
|
||||
continue
|
||||
}
|
||||
if v.ModRank == wfapiio.Include.Item.ItemsInSet[0].ModMaxRank {
|
||||
od = append(od, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 对报价表进行排序,由低到高
|
||||
sort.Sort(od)
|
||||
// 获取物品信息
|
||||
for i, v := range wfapiio.Include.Item.ItemsInSet {
|
||||
if v.URLName == cnName {
|
||||
it = &wfapiio.Include.Item.ItemsInSet[i]
|
||||
n = v.En.ItemName
|
||||
return
|
||||
}
|
||||
}
|
||||
it = &wfapiio.Include.Item.ItemsInSet[0]
|
||||
n = wfapiio.Include.Item.ItemsInSet[0].En.ItemName
|
||||
return
|
||||
}
|
||||
|
||||
func newwm() (wmitems map[string]items, itemNames []string) {
|
||||
var itemapi wfAPIItem // WarFrame市场的数据实例
|
||||
|
||||
data, err := web.RequestDataWithHeaders(&http.Client{}, wfitemurl, "GET", func(request *http.Request) error {
|
||||
request.Header.Add("Accept", "application/json")
|
||||
request.Header.Add("Language", "zh-hans")
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = json.Unmarshal(data, &itemapi)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
wmitems = make(map[string]items, len(itemapi.Payload.Items)*4)
|
||||
itemNames = make([]string, len(itemapi.Payload.Items))
|
||||
for i, v := range itemapi.Payload.Items {
|
||||
wmitems[v.ItemName] = v
|
||||
itemNames[i] = v.ItemName
|
||||
}
|
||||
return
|
||||
}
|
||||
404
plugin/warframeapi/main.go
Normal file
404
plugin/warframeapi/main.go
Normal file
@@ -0,0 +1,404 @@
|
||||
// Package warframeapi 星际战甲
|
||||
package warframeapi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
"github.com/lithammer/fuzzysearch/fuzzy"
|
||||
zero "github.com/wdvxdr1123/ZeroBot"
|
||||
"github.com/wdvxdr1123/ZeroBot/message"
|
||||
)
|
||||
|
||||
var wmitems, itemNames = newwm()
|
||||
|
||||
func init() {
|
||||
eng := control.Register("warframeapi", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "星际战甲",
|
||||
Help: "- wf时间同步\n" +
|
||||
"- [金星|地球|火卫二]平原时间\n" +
|
||||
"- .wm [物品名称]\n" +
|
||||
"- wf仲裁\n" +
|
||||
"- wf警报\n" +
|
||||
"- wf每日特惠",
|
||||
PrivateDataFolder: "warframeapi",
|
||||
})
|
||||
|
||||
// 获取具体的平原时间, 在触发后, 会启动持续时间按5分钟的时间更新模拟, 以此处理短时间内请求时, 时间不会变化的问题
|
||||
eng.OnSuffix("平原时间").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
if !gameWorld.hasSync() { // 没有进行同步,就拉取一次服务器状态
|
||||
wfapi, err := newwfapi()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: 获取服务器时间失败"))
|
||||
}
|
||||
gameWorld.refresh(&wfapi)
|
||||
}
|
||||
var msg any
|
||||
switch ctx.State["args"].(string) {
|
||||
case "地球", "夜灵":
|
||||
msg = gameWorld.w[0]
|
||||
case "金星", "奥布山谷":
|
||||
msg = gameWorld.w[1]
|
||||
case "魔胎之境", "火卫二", "火卫":
|
||||
msg = gameWorld.w[2]
|
||||
default:
|
||||
msg = "ERROR: 平原不存在"
|
||||
}
|
||||
ctx.SendChain(message.Text(msg))
|
||||
// 是否正在进行同步,没有就开启同步,有就不开启
|
||||
if !gameWorld.hasSync() {
|
||||
if gameWorld.setsync() {
|
||||
go func() {
|
||||
// 30*10=300=5分钟
|
||||
for i := 0; i < 30; i++ {
|
||||
time.Sleep(10 * time.Second)
|
||||
gameWorld.update() // 5分钟内每隔10秒更新一下时间
|
||||
}
|
||||
// 5分钟时间同步结束
|
||||
_ = gameWorld.resetsync()
|
||||
}()
|
||||
}
|
||||
}
|
||||
})
|
||||
eng.OnFullMatch("wf警报").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
wfapi, err := newwfapi()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
// 如果返回的wfapi中, 警报数量>0
|
||||
if len(wfapi.Alerts) > 0 {
|
||||
msgs := make(message.Message, len(wfapi.Alerts))
|
||||
// 遍历警报数据, 打印警报信息
|
||||
for i, v := range wfapi.Alerts {
|
||||
msgs[i] = ctxext.FakeSenderForwardNode(ctx, message.Text(
|
||||
"激活: ", v.Active,
|
||||
"\n节点: ", v.Mission.Node,
|
||||
"\n类型: ", v.Mission.Type,
|
||||
"\n敌人等级: ", v.Mission.MinEnemyLevel, "~", v.Mission.MaxEnemyLevel,
|
||||
"\n奖励: ", v.Mission.Reward.AsString,
|
||||
"\n剩余时间:", v.Eta))
|
||||
}
|
||||
ctx.SendChain(msgs...)
|
||||
}
|
||||
})
|
||||
//TODO:订阅功能-等待重做
|
||||
// eng.OnRegex(`^(订阅|取消订阅)(.*)平原(.*)$`).SetBlock(true).
|
||||
// Handle(func(ctx *zero.Ctx) {
|
||||
// args := ctx.State["regex_matched"].([]string)
|
||||
// var isEnable bool
|
||||
// if args[1] == "订阅" {
|
||||
// isEnable = true
|
||||
// }
|
||||
// updateWFAPI()
|
||||
// status := false
|
||||
// switch args[3] {
|
||||
// case "fass", "白天", "温暖":
|
||||
// status = true
|
||||
// }
|
||||
// switch args[2] {
|
||||
// case "金星", "奥布山谷":
|
||||
// //sublist = append(sublist, subList{ctx.Event.GroupID, ctx.Event.UserID, 1, status, false})
|
||||
// if isEnable {
|
||||
// addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1, status)
|
||||
// } else {
|
||||
// removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 1)
|
||||
// }
|
||||
// ctx.SendChain(
|
||||
// message.At(ctx.Event.UserID),
|
||||
// message.Text("已成功", args[1]),
|
||||
// message.Text(gameTimes[1].Name),
|
||||
// message.Text(status),
|
||||
// )
|
||||
// case "地球", "夜灵":
|
||||
// if isEnable {
|
||||
// addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0, status)
|
||||
// } else {
|
||||
// removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 0)
|
||||
// }
|
||||
// ctx.SendChain(
|
||||
// message.At(ctx.Event.UserID),
|
||||
// message.Text("已成功", args[1]),
|
||||
// message.Text(gameTimes[0].Name),
|
||||
// message.Text(status),
|
||||
// )
|
||||
// case "魔胎之境", "火卫", "火卫二":
|
||||
// if isEnable {
|
||||
// addUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2, status)
|
||||
// } else {
|
||||
// removeUseSub(ctx.Event.UserID, ctx.Event.GroupID, 2)
|
||||
// }
|
||||
// ctx.SendChain(
|
||||
// message.At(ctx.Event.UserID),
|
||||
// message.Text("已成功", args[1]),
|
||||
// message.Text(gameTimes[2].Name),
|
||||
// message.Text(status),
|
||||
// )
|
||||
// default:
|
||||
// ctx.SendChain(message.Text("ERROR: 平原不存在"))
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
// eng.OnFullMatch(`wf订阅检测`).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
// rwm.Lock()
|
||||
// var msg []message.MessageSegment
|
||||
// for i, v := range gameTimes {
|
||||
// nt := time.Until(v.NextTime).Seconds()
|
||||
// switch {
|
||||
// case nt < 0:
|
||||
// if v.Status {
|
||||
// v.NextTime = v.NextTime.Add(time.Duration(v.NightTime) * time.Second)
|
||||
// } else {
|
||||
// v.NextTime = v.NextTime.Add(time.Duration(v.DayTime) * time.Second)
|
||||
// }
|
||||
// v.Status = !v.Status
|
||||
//
|
||||
// msg = callUser(i, v.Status, 0)
|
||||
// case nt < float64(5)*60:
|
||||
// msg = callUser(i, !v.Status, 5)
|
||||
// case nt < float64(15)*60:
|
||||
// if i == 2 && !v.Status {
|
||||
// return
|
||||
// }
|
||||
// msg = callUser(i, !v.Status, 15)
|
||||
// }
|
||||
// }
|
||||
// rwm.Unlock()
|
||||
// if msg != nil && len(msg) > 0 {
|
||||
// ctx.SendChain(msg...)
|
||||
// }
|
||||
// })
|
||||
eng.OnFullMatch("wf仲裁").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
// 通过wfapi获取仲裁信息
|
||||
wfapi, err := newwfapi()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
ctx.SendChain(message.Text(
|
||||
"节点: ", wfapi.Arbitration.Node,
|
||||
"\n类型: ", wfapi.Arbitration.Type,
|
||||
"\n阵营: ", wfapi.Arbitration.Enemy,
|
||||
"\n剩余时间: ", int(wfapi.Arbitration.Expiry.Sub(time.Now().UTC()).Minutes()), "m",
|
||||
))
|
||||
})
|
||||
eng.OnFullMatch("wf每日特惠").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
wfapi, err := newwfapi()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
if len(wfapi.DailyDeals) > 0 {
|
||||
msgs := make(message.Message, len(wfapi.DailyDeals))
|
||||
for i, dd := range wfapi.DailyDeals {
|
||||
msgs[i] = ctxext.FakeSenderForwardNode(ctx, message.Text(
|
||||
"物品: ", dd.Item,
|
||||
"\n价格: ", dd.OriginalPrice, "→", dd.SalePrice,
|
||||
"\n数量: (", dd.Total, "/", dd.Sold, ")",
|
||||
"\n时间: ", dd.Eta,
|
||||
))
|
||||
}
|
||||
ctx.SendChain(msgs...)
|
||||
}
|
||||
})
|
||||
// eng.OnRegex(`^入侵$`).SetBlock(true).
|
||||
// Handle(func(ctx *zero.Ctx) {
|
||||
// updateWFAPI(ctx)
|
||||
// for _, dd := range wfapi.dailyDeals {
|
||||
// imagebuild.DrawTextSend([]string{
|
||||
// "节点:" + wfapi.arbitration.Node,
|
||||
// "类型:" + wfapi.arbitration.Type,
|
||||
// "阵营:" + wfapi.arbitration.Enemy,
|
||||
// "剩余时间:" + fmt.Sprint(int(wfapi.arbitration.Expiry.Sub(time.Now().UTC()).Minutes())) + "m",
|
||||
// }, ctx)
|
||||
// }
|
||||
// })
|
||||
eng.OnFullMatch("wf时间同步").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
wfapi, err := newwfapi()
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
return
|
||||
}
|
||||
gameWorld.refresh(&wfapi)
|
||||
ctx.SendChain(message.Text("已拉取服务器时间并同步到本地模拟"))
|
||||
})
|
||||
// 根据名称从Warframe市场查询物品售价
|
||||
eng.OnPrefix(".wm ").SetBlock(true).
|
||||
Handle(func(ctx *zero.Ctx) {
|
||||
// 根据输入的名称, 从游戏物品名称列表中进行模糊搜索
|
||||
sol := fuzzy.FindNormalizedFold(ctx.State["args"].(string), itemNames)
|
||||
// 物品名称
|
||||
var name string
|
||||
|
||||
// 根据搜搜结果, 打印找到的物品
|
||||
switch len(sol) {
|
||||
case 0: // 没有搜索到任何东西
|
||||
ctx.SendChain(message.Text("无法查询到该物品"))
|
||||
return
|
||||
case 1: // 如果只搜索到了一个
|
||||
name = sol[0]
|
||||
default: // 如果搜搜到了多个
|
||||
sb := strings.Builder{}
|
||||
if len(sol) > 25 {
|
||||
sb.WriteString("数量过多, 只显示前25\n")
|
||||
sol = sol[:25]
|
||||
}
|
||||
sb.WriteString("[0] ")
|
||||
sb.WriteString(sol[0])
|
||||
for i, v := range sol[1:] {
|
||||
sb.WriteString("\n[")
|
||||
sb.WriteString(strconv.Itoa(i + 1))
|
||||
sb.WriteString("] ")
|
||||
sb.WriteString(v)
|
||||
}
|
||||
ctx.SendChain(
|
||||
ctxext.FakeSenderForwardNode(ctx, message.Text("包含多个结果, 请输入编号查看(30s内),输入c直接结束会话")),
|
||||
ctxext.FakeSenderForwardNode(ctx, message.Text(&sb)),
|
||||
)
|
||||
itemIndex := getitemnameindex(ctx)
|
||||
if itemIndex < 0 {
|
||||
return
|
||||
}
|
||||
if itemIndex >= len(sol) || itemIndex < 0 {
|
||||
ctx.SendChain(message.Text("ERROR: 编号超出范围"))
|
||||
return
|
||||
}
|
||||
name = sol[itemIndex]
|
||||
}
|
||||
onlymaxrank := false
|
||||
msgs := message.Message{}
|
||||
GETWM:
|
||||
if onlymaxrank {
|
||||
msgs = msgs[:0]
|
||||
}
|
||||
sells, iteminfo, txt, err := getitemsorder(wmitems[name].URLName, onlymaxrank)
|
||||
if !onlymaxrank {
|
||||
if iteminfo.ZhHans.WikiLink == "" {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx,
|
||||
message.Image("https://warframe.market/static/assets/"+wmitems[name].Thumb),
|
||||
message.Text("\n", wmitems[name].ItemName)))
|
||||
} else {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx,
|
||||
message.Image("https://warframe.market/static/assets/"+wmitems[name].Thumb),
|
||||
message.Text("\n", wmitems[name].ItemName, "\nwiki: ", iteminfo.ZhHans.WikiLink)))
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text("ERROR: ", err)))
|
||||
ctx.SendChain(msgs...)
|
||||
return
|
||||
}
|
||||
if sells == nil {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text("无可购买对象")))
|
||||
ctx.SendChain(msgs...)
|
||||
return
|
||||
}
|
||||
|
||||
ismod := iteminfo.ModMaxRank != 0
|
||||
max := 5
|
||||
if len(sells) < max {
|
||||
max = len(sells)
|
||||
}
|
||||
sb := strings.Builder{}
|
||||
if ismod {
|
||||
if !onlymaxrank {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text("请输入编号选择, 或输入r获取满级报价(30s内)\n输入c直接结束会话")))
|
||||
} else {
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text("请输入编号选择(30s内)\n输入c直接结束会话")))
|
||||
}
|
||||
for i := 0; i < max; 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++ {
|
||||
// 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))
|
||||
}
|
||||
}
|
||||
msgs = append(msgs, ctxext.FakeSenderForwardNode(ctx, message.Text(&sb)))
|
||||
ctx.SendChain(msgs...)
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
next := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Next()
|
||||
select {
|
||||
case <-time.After(time.Second * 30):
|
||||
ctx.SendChain(message.Text("会话已结束!"))
|
||||
return
|
||||
case e := <-next:
|
||||
msg := e.Event.Message.ExtractPlainText()
|
||||
// 重新获取报价
|
||||
if msg == "r" {
|
||||
onlymaxrank = true
|
||||
goto GETWM
|
||||
}
|
||||
// 主动结束会话
|
||||
if msg == "c" {
|
||||
ctx.SendChain(message.Text("会话已结束!"))
|
||||
return
|
||||
}
|
||||
i, err := strconv.Atoi(msg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("请输入数字! (输入c结束会话)"))
|
||||
continue
|
||||
}
|
||||
if ismod {
|
||||
ctx.SendChain(message.Text("/w ", sells[i].User.IngameName, " Hi! I want to buy: ", txt, "(Rank:", sells[i].ModRank, ") for ", sells[i].Platinum, " platinum. (warframe.market)"))
|
||||
} else {
|
||||
ctx.SendChain(message.Text("/w ", sells[i].User.IngameName, " Hi! I want to buy: ", txt, " for ", sells[i].Platinum, " platinum. (warframe.market)"))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取搜索结果中的物品具体名称index的FutureEvent
|
||||
//
|
||||
// 传入ctx和一个递归次数上限,返回一个int
|
||||
// 如果为返回内容为负, 说明
|
||||
// -1 会话超时
|
||||
// -2 主动结束
|
||||
// -3 连续3次错误
|
||||
func getitemnameindex(ctx *zero.Ctx) int {
|
||||
recv, cancel := zero.NewFutureEvent("message", 999, false, ctx.CheckSession()).Repeat()
|
||||
defer cancel()
|
||||
for i := 0; i < 3; i++ {
|
||||
select {
|
||||
case <-time.After(time.Second * 30):
|
||||
// 超时15秒处理
|
||||
ctx.SendChain(message.Text("会话已超时!"))
|
||||
return -1
|
||||
case e := <-recv:
|
||||
msg := e.Event.Message.ExtractPlainText()
|
||||
// 输入c主动结束的处理
|
||||
if msg == "c" {
|
||||
ctx.SendChain(message.Text("会话已结束!"))
|
||||
return -2
|
||||
}
|
||||
// 尝试对输入进行数字转换
|
||||
num, err := strconv.Atoi(msg)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("请输入数字! (输入c结束会话)"))
|
||||
continue
|
||||
}
|
||||
return num
|
||||
}
|
||||
}
|
||||
ctx.SendChain(message.Text("连续输入错误, 会话已结束!"))
|
||||
return -3
|
||||
}
|
||||
630
plugin/warframeapi/types.go
Normal file
630
plugin/warframeapi/types.go
Normal file
@@ -0,0 +1,630 @@
|
||||
package warframeapi
|
||||
|
||||
import "time"
|
||||
|
||||
type wfapi struct {
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
News []news `json:"news"`
|
||||
Events []events `json:"events"`
|
||||
Alerts []alerts `json:"alerts"`
|
||||
Sortie sortie `json:"sortie"`
|
||||
SyndicateMissions []syndicateMissions `json:"syndicateMissions"`
|
||||
Fissures []fissures `json:"fissures"`
|
||||
GlobalUpgrades []interface{} `json:"globalUpgrades"`
|
||||
FlashSales []flashSales `json:"flashSales"`
|
||||
Invasions []invasions `json:"invasions"`
|
||||
DarkSectors []interface{} `json:"darkSectors"`
|
||||
VoidTrader voidTrader `json:"voidTrader"`
|
||||
DailyDeals []dailyDeals `json:"dailyDeals"`
|
||||
Simaris simaris `json:"simaris"`
|
||||
ConclaveChallenges []conclaveChallenges `json:"conclaveChallenges"`
|
||||
PersistentEnemies []interface{} `json:"persistentEnemies"`
|
||||
EarthCycle earthCycle `json:"earthCycle"`
|
||||
CetusCycle cetusCycle `json:"cetusCycle"`
|
||||
CambionCycle cambionCycle `json:"cambionCycle"`
|
||||
ZarimanCycle zarimanCycle `json:"zarimanCycle"`
|
||||
WeeklyChallenges []interface{} `json:"weeklyChallenges"`
|
||||
ConstructionProgress constructionProgress `json:"constructionProgress"`
|
||||
VallisCycle vallisCycle `json:"vallisCycle"`
|
||||
Nightwave nightwave `json:"nightwave"`
|
||||
Kuva []interface{} `json:"kuva"`
|
||||
Arbitration arbitration `json:"arbitration"`
|
||||
SentientOutposts sentientOutposts `json:"sentientOutposts"`
|
||||
SteelPath steelPath `json:"steelPath"`
|
||||
VaultTrader vaultTrader `json:"vaultTrader"`
|
||||
}
|
||||
type translations struct {
|
||||
En string `json:"en"`
|
||||
Fr string `json:"fr"`
|
||||
It string `json:"it"`
|
||||
De string `json:"de"`
|
||||
Es string `json:"es"`
|
||||
Pt string `json:"pt"`
|
||||
Ru string `json:"ru"`
|
||||
Pl string `json:"pl"`
|
||||
Uk string `json:"uk"`
|
||||
Tr string `json:"tr"`
|
||||
Ja string `json:"ja"`
|
||||
Zh string `json:"zh"`
|
||||
Ko string `json:"ko"`
|
||||
Tc string `json:"tc"`
|
||||
}
|
||||
type news struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Link string `json:"link"`
|
||||
ImageLink string `json:"imageLink"`
|
||||
Priority bool `json:"priority"`
|
||||
Date time.Time `json:"date"`
|
||||
Eta string `json:"eta"`
|
||||
Update bool `json:"update"`
|
||||
PrimeAccess bool `json:"primeAccess"`
|
||||
Stream bool `json:"stream"`
|
||||
Translations translations `json:"translations"`
|
||||
AsString string `json:"asString"`
|
||||
}
|
||||
type metadata struct {
|
||||
}
|
||||
type nextAlt struct {
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
}
|
||||
type events struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
MaximumScore int `json:"maximumScore"`
|
||||
CurrentScore int `json:"currentScore"`
|
||||
SmallInterval interface{} `json:"smallInterval"`
|
||||
LargeInterval interface{} `json:"largeInterval"`
|
||||
Faction string `json:"faction"`
|
||||
Description string `json:"description"`
|
||||
Tooltip string `json:"tooltip"`
|
||||
Node string `json:"node"`
|
||||
ConcurrentNodes []interface{} `json:"concurrentNodes"`
|
||||
Rewards []interface{} `json:"rewards"`
|
||||
Expired bool `json:"expired"`
|
||||
InterimSteps []interface{} `json:"interimSteps"`
|
||||
ProgressSteps []interface{} `json:"progressSteps"`
|
||||
IsPersonal bool `json:"isPersonal"`
|
||||
RegionDrops []interface{} `json:"regionDrops"`
|
||||
ArchwingDrops []interface{} `json:"archwingDrops"`
|
||||
AsString string `json:"asString"`
|
||||
Metadata metadata `json:"metadata"`
|
||||
CompletionBonuses []interface{} `json:"completionBonuses"`
|
||||
AltExpiry time.Time `json:"altExpiry"`
|
||||
AltActivation time.Time `json:"altActivation"`
|
||||
NextAlt nextAlt `json:"nextAlt"`
|
||||
}
|
||||
type variants struct {
|
||||
MissionType string `json:"missionType"`
|
||||
Modifier string `json:"modifier"`
|
||||
ModifierDescription string `json:"modifierDescription"`
|
||||
Node string `json:"node"`
|
||||
}
|
||||
type sortie struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
RewardPool string `json:"rewardPool"`
|
||||
Variants []variants `json:"variants"`
|
||||
Boss string `json:"boss"`
|
||||
Faction string `json:"faction"`
|
||||
Expired bool `json:"expired"`
|
||||
Eta string `json:"eta"`
|
||||
}
|
||||
type jobs struct {
|
||||
ID string `json:"id"`
|
||||
RewardPool []string `json:"rewardPool"`
|
||||
Type string `json:"type"`
|
||||
EnemyLevels []int `json:"enemyLevels"`
|
||||
StandingStages []int `json:"standingStages"`
|
||||
MinMR int `json:"minMR"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
TimeBound string `json:"timeBound,omitempty"`
|
||||
}
|
||||
type syndicateMissions struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Syndicate string `json:"syndicate"`
|
||||
SyndicateKey string `json:"syndicateKey"`
|
||||
Nodes []interface{} `json:"nodes"`
|
||||
Jobs []jobs `json:"jobs"`
|
||||
Eta string `json:"eta"`
|
||||
}
|
||||
type fissures struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Node string `json:"node"`
|
||||
MissionType string `json:"missionType"`
|
||||
MissionKey string `json:"missionKey"`
|
||||
Enemy string `json:"enemy"`
|
||||
EnemyKey string `json:"enemyKey"`
|
||||
NodeKey string `json:"nodeKey"`
|
||||
Tier string `json:"tier"`
|
||||
TierNum int `json:"tierNum"`
|
||||
Expired bool `json:"expired"`
|
||||
Eta string `json:"eta"`
|
||||
IsStorm bool `json:"isStorm"`
|
||||
}
|
||||
type flashSales struct {
|
||||
Item string `json:"item"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Discount int `json:"discount"`
|
||||
RegularOverride int `json:"regularOverride"`
|
||||
PremiumOverride int `json:"premiumOverride"`
|
||||
IsShownInMarket bool `json:"isShownInMarket"`
|
||||
IsFeatured bool `json:"isFeatured"`
|
||||
IsPopular bool `json:"isPopular"`
|
||||
ID string `json:"id"`
|
||||
Expired bool `json:"expired"`
|
||||
Eta string `json:"eta"`
|
||||
}
|
||||
type countedItems struct {
|
||||
Count int `json:"count"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
type attackerReward struct {
|
||||
Items []interface{} `json:"items"`
|
||||
CountedItems []countedItems `json:"countedItems"`
|
||||
Credits int `json:"credits"`
|
||||
AsString string `json:"asString"`
|
||||
ItemString string `json:"itemString"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Color int `json:"color"`
|
||||
}
|
||||
type reward struct {
|
||||
Items []interface{} `json:"items"`
|
||||
CountedItems []countedItems `json:"countedItems"`
|
||||
Credits int `json:"credits"`
|
||||
AsString string `json:"asString"`
|
||||
ItemString string `json:"itemString"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Color int `json:"color"`
|
||||
}
|
||||
type attacker struct {
|
||||
Reward reward `json:"reward"`
|
||||
Faction string `json:"faction"`
|
||||
FactionKey string `json:"factionKey"`
|
||||
}
|
||||
type defenderReward struct {
|
||||
Items []interface{} `json:"items"`
|
||||
CountedItems []countedItems `json:"countedItems"`
|
||||
Credits int `json:"credits"`
|
||||
AsString string `json:"asString"`
|
||||
ItemString string `json:"itemString"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Color int `json:"color"`
|
||||
}
|
||||
type defender struct {
|
||||
Reward reward `json:"reward"`
|
||||
Faction string `json:"faction"`
|
||||
FactionKey string `json:"factionKey"`
|
||||
}
|
||||
type invasions struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Node string `json:"node"`
|
||||
NodeKey string `json:"nodeKey"`
|
||||
Desc string `json:"desc"`
|
||||
AttackerReward attackerReward `json:"attackerReward"`
|
||||
AttackingFaction string `json:"attackingFaction"`
|
||||
Attacker attacker `json:"attacker"`
|
||||
DefenderReward defenderReward `json:"defenderReward"`
|
||||
DefendingFaction string `json:"defendingFaction"`
|
||||
Defender defender `json:"defender"`
|
||||
VsInfestation bool `json:"vsInfestation"`
|
||||
Count int `json:"count"`
|
||||
RequiredRuns int `json:"requiredRuns"`
|
||||
Completion float64 `json:"completion"`
|
||||
Completed bool `json:"completed"`
|
||||
Eta string `json:"eta"`
|
||||
RewardTypes []string `json:"rewardTypes"`
|
||||
}
|
||||
type voidTrader struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Character string `json:"character"`
|
||||
Location string `json:"location"`
|
||||
Inventory []interface{} `json:"inventory"`
|
||||
PsID string `json:"psId"`
|
||||
EndString string `json:"endString"`
|
||||
InitialStart time.Time `json:"initialStart"`
|
||||
Schedule []interface{} `json:"schedule"`
|
||||
}
|
||||
type dailyDeals struct {
|
||||
Item string `json:"item"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
OriginalPrice int `json:"originalPrice"`
|
||||
SalePrice int `json:"salePrice"`
|
||||
Total int `json:"total"`
|
||||
Sold int `json:"sold"`
|
||||
ID string `json:"id"`
|
||||
Eta string `json:"eta"`
|
||||
Discount int `json:"discount"`
|
||||
}
|
||||
type simaris struct {
|
||||
Target string `json:"target"`
|
||||
IsTargetActive bool `json:"isTargetActive"`
|
||||
AsString string `json:"asString"`
|
||||
}
|
||||
type conclaveChallenges struct {
|
||||
ID string `json:"id"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Amount int `json:"amount"`
|
||||
Mode string `json:"mode"`
|
||||
Category string `json:"category"`
|
||||
Eta string `json:"eta"`
|
||||
Expired bool `json:"expired"`
|
||||
Daily bool `json:"daily"`
|
||||
RootChallenge bool `json:"rootChallenge"`
|
||||
EndString string `json:"endString"`
|
||||
Description string `json:"description"`
|
||||
Title string `json:"title"`
|
||||
Standing int `json:"standing"`
|
||||
AsString string `json:"asString"`
|
||||
}
|
||||
type earthCycle struct {
|
||||
ID string `json:"id"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
IsDay bool `json:"isDay"`
|
||||
State string `json:"state"`
|
||||
TimeLeft string `json:"timeLeft"`
|
||||
}
|
||||
type cetusCycle struct {
|
||||
ID string `json:"id"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
IsDay bool `json:"isDay"`
|
||||
State string `json:"state"`
|
||||
TimeLeft string `json:"timeLeft"`
|
||||
IsCetus bool `json:"isCetus"`
|
||||
ShortString string `json:"shortString"`
|
||||
}
|
||||
type cambionCycle struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
TimeLeft string `json:"timeLeft"`
|
||||
Active string `json:"active"`
|
||||
}
|
||||
type zarimanCycle struct {
|
||||
ID string `json:"id"`
|
||||
BountiesEndDate time.Time `json:"bountiesEndDate"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Activation time.Time `json:"activation"`
|
||||
IsCorpus bool `json:"isCorpus"`
|
||||
State string `json:"state"`
|
||||
TimeLeft string `json:"timeLeft"`
|
||||
ShortString string `json:"shortString"`
|
||||
}
|
||||
type constructionProgress struct {
|
||||
ID string `json:"id"`
|
||||
FomorianProgress string `json:"fomorianProgress"`
|
||||
RazorbackProgress string `json:"razorbackProgress"`
|
||||
UnknownProgress string `json:"unknownProgress"`
|
||||
}
|
||||
type vallisCycle struct {
|
||||
ID string `json:"id"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
IsWarm bool `json:"isWarm"`
|
||||
State string `json:"state"`
|
||||
Activation time.Time `json:"activation"`
|
||||
TimeLeft string `json:"timeLeft"`
|
||||
ShortString string `json:"shortString"`
|
||||
}
|
||||
type params struct {
|
||||
}
|
||||
type activeChallenges struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
IsDaily bool `json:"isDaily,omitempty"`
|
||||
IsElite bool `json:"isElite"`
|
||||
Desc string `json:"desc"`
|
||||
Title string `json:"title"`
|
||||
Reputation int `json:"reputation"`
|
||||
}
|
||||
type nightwave struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Season int `json:"season"`
|
||||
Tag string `json:"tag"`
|
||||
Phase int `json:"phase"`
|
||||
Params params `json:"params"`
|
||||
PossibleChallenges []interface{} `json:"possibleChallenges"`
|
||||
ActiveChallenges []activeChallenges `json:"activeChallenges"`
|
||||
RewardTypes []string `json:"rewardTypes"`
|
||||
}
|
||||
type arbitration struct {
|
||||
Activation time.Time `json:"activation"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Enemy string `json:"enemy"`
|
||||
Type string `json:"type"`
|
||||
Archwing bool `json:"archwing"`
|
||||
Sharkwing bool `json:"sharkwing"`
|
||||
Node string `json:"node"`
|
||||
NodeKey string `json:"nodeKey"`
|
||||
TypeKey string `json:"typeKey"`
|
||||
ID string `json:"id"`
|
||||
Expired bool `json:"expired"`
|
||||
}
|
||||
type mission struct {
|
||||
Node string `json:"node"`
|
||||
Faction string `json:"faction"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
type sentientOutposts struct {
|
||||
Mission mission `json:"mission"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
type currentReward struct {
|
||||
Name string `json:"name"`
|
||||
Cost int `json:"cost"`
|
||||
}
|
||||
type rotation struct {
|
||||
Name string `json:"name"`
|
||||
Cost int `json:"cost"`
|
||||
}
|
||||
type evergreens struct {
|
||||
Name string `json:"name"`
|
||||
Cost int `json:"cost"`
|
||||
}
|
||||
type incursions struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
}
|
||||
type steelPath struct {
|
||||
CurrentReward currentReward `json:"currentReward"`
|
||||
Activation time.Time `json:"activation"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Remaining string `json:"remaining"`
|
||||
Rotation []rotation `json:"rotation"`
|
||||
Evergreens []evergreens `json:"evergreens"`
|
||||
Incursions incursions `json:"incursions"`
|
||||
}
|
||||
type inventory struct {
|
||||
Item string `json:"item"`
|
||||
Ducats int `json:"ducats"`
|
||||
Credits interface{} `json:"credits"`
|
||||
}
|
||||
type schedule struct {
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Item string `json:"item"`
|
||||
}
|
||||
type vaultTrader struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Character string `json:"character"`
|
||||
Location string `json:"location"`
|
||||
Inventory []inventory `json:"inventory"`
|
||||
PsID string `json:"psId"`
|
||||
EndString string `json:"endString"`
|
||||
InitialStart time.Time `json:"initialStart"`
|
||||
Completed bool `json:"completed"`
|
||||
Schedule []schedule `json:"schedule"`
|
||||
}
|
||||
type alerts struct {
|
||||
ID string `json:"id"`
|
||||
Activation time.Time `json:"activation"`
|
||||
StartString string `json:"startString"`
|
||||
Expiry time.Time `json:"expiry"`
|
||||
Active bool `json:"active"`
|
||||
Mission struct {
|
||||
Description string `json:"description"`
|
||||
Node string `json:"node"`
|
||||
NodeKey string `json:"nodeKey"`
|
||||
Type string `json:"type"`
|
||||
TypeKey string `json:"typeKey"`
|
||||
Faction string `json:"faction"`
|
||||
Reward struct {
|
||||
Items []interface{} `json:"items"`
|
||||
CountedItems []struct {
|
||||
Count int `json:"count"`
|
||||
Type string `json:"type"`
|
||||
Key string `json:"key"`
|
||||
} `json:"countedItems"`
|
||||
Credits int `json:"credits"`
|
||||
AsString string `json:"asString"`
|
||||
ItemString string `json:"itemString"`
|
||||
Thumbnail string `json:"thumbnail"`
|
||||
Color int `json:"color"`
|
||||
} `json:"reward"`
|
||||
MinEnemyLevel int `json:"minEnemyLevel"`
|
||||
MaxEnemyLevel int `json:"maxEnemyLevel"`
|
||||
MaxWaveNum int `json:"maxWaveNum"`
|
||||
Nightmare bool `json:"nightmare"`
|
||||
ArchwingRequired bool `json:"archwingRequired"`
|
||||
IsSharkwing bool `json:"isSharkwing"`
|
||||
LevelOverride string `json:"levelOverride"`
|
||||
EnemySpec string `json:"enemySpec"`
|
||||
AdvancedSpawners []interface{} `json:"advancedSpawners"`
|
||||
RequiredItems []interface{} `json:"requiredItems"`
|
||||
LevelAuras []interface{} `json:"levelAuras"`
|
||||
} `json:"mission"`
|
||||
Eta string `json:"eta"`
|
||||
RewardTypes []string `json:"rewardTypes"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
type wfAPIItem struct {
|
||||
Payload payload `json:"payload"`
|
||||
}
|
||||
type items struct {
|
||||
URLName string `json:"url_name"`
|
||||
Thumb string `json:"thumb"`
|
||||
ItemName string `json:"item_name"`
|
||||
ID string `json:"id"`
|
||||
Vaulted bool `json:"vaulted,omitempty"`
|
||||
}
|
||||
type payload struct {
|
||||
Items []items `json:"items"`
|
||||
Orders orders `json:"orders"`
|
||||
}
|
||||
|
||||
type wfAPIItemsOrders struct {
|
||||
Payload payload `json:"payload"`
|
||||
Include include `json:"include"`
|
||||
}
|
||||
type user struct {
|
||||
IngameName string `json:"ingame_name"`
|
||||
LastSeen time.Time `json:"last_seen"`
|
||||
Reputation int `json:"reputation"`
|
||||
Region string `json:"region"`
|
||||
ID string `json:"id"`
|
||||
Avatar interface{} `json:"avatar"`
|
||||
Status string `json:"status"`
|
||||
}
|
||||
type orders []struct {
|
||||
OrderType string `json:"order_type"`
|
||||
LastUpdate time.Time `json:"last_update"`
|
||||
Region string `json:"region"`
|
||||
Quantity int `json:"quantity"`
|
||||
Visible bool `json:"visible"`
|
||||
CreationDate time.Time `json:"creation_date"`
|
||||
Platinum int `json:"platinum"`
|
||||
Platform string `json:"platform"`
|
||||
User user `json:"user"`
|
||||
ID string `json:"id"`
|
||||
ModRank int `json:"mod_rank"`
|
||||
}
|
||||
|
||||
func (a orders) Len() int { // 重写 Len() 方法
|
||||
return len(a)
|
||||
}
|
||||
func (a orders) Swap(i, j int) { // 重写 Swap() 方法
|
||||
a[i], a[j] = a[j], a[i]
|
||||
}
|
||||
func (a orders) Less(i, j int) bool { // 重写 Less() 方法, 从大到小排序
|
||||
return a[i].Platinum < a[j].Platinum
|
||||
}
|
||||
|
||||
type en struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type ru struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type ko struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type fr struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type sv struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type de struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type zhHant struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type zhHans struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type pt struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type es struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type pl struct {
|
||||
ItemName string `json:"item_name"`
|
||||
Description string `json:"description"`
|
||||
WikiLink string `json:"wiki_link"`
|
||||
Drop []interface{} `json:"drop"`
|
||||
}
|
||||
type itemsInSet struct {
|
||||
Icon string `json:"icon"`
|
||||
URLName string `json:"url_name"`
|
||||
SubIcon string `json:"sub_icon"`
|
||||
ModMaxRank int `json:"mod_max_rank"`
|
||||
Thumb string `json:"thumb"`
|
||||
SetRoot bool `json:"set_root"`
|
||||
QuantityForSet int `json:"quantity_for_set,omitempty"`
|
||||
ID string `json:"id"`
|
||||
TradingTax int `json:"trading_tax"`
|
||||
Tags []string `json:"tags"`
|
||||
MasteryLevel int `json:"mastery_level"`
|
||||
Ducats int `json:"ducats"`
|
||||
IconFormat string `json:"icon_format"`
|
||||
En en `json:"en"`
|
||||
Ru ru `json:"ru"`
|
||||
Ko ko `json:"ko"`
|
||||
Fr fr `json:"fr"`
|
||||
Sv sv `json:"sv"`
|
||||
De de `json:"de"`
|
||||
ZhHant zhHant `json:"zh-hant"`
|
||||
ZhHans zhHans `json:"zh-hans"`
|
||||
Pt pt `json:"pt"`
|
||||
Es es `json:"es"`
|
||||
Pl pl `json:"pl"`
|
||||
}
|
||||
type item struct {
|
||||
ID string `json:"id"`
|
||||
ItemsInSet []itemsInSet `json:"items_in_set"`
|
||||
}
|
||||
type include struct {
|
||||
Item item `json:"item"`
|
||||
}
|
||||
108
plugin/warframeapi/world.go
Normal file
108
plugin/warframeapi/world.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package warframeapi
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/davidscholberg/go-durationfmt"
|
||||
)
|
||||
|
||||
// 游戏时间模拟
|
||||
type timezone struct {
|
||||
sync.RWMutex `json:"-"`
|
||||
Name string `json:"name"` // 时间名称
|
||||
NextTime time.Time `json:"time"` // 下次更新时间
|
||||
IsDay bool `json:"status"` // 状态
|
||||
DayDesc string `json:"true_des"` // 状态说明
|
||||
NightDesc string `json:"false_des"` // 状态说明
|
||||
DayLen int `json:"day"` // 白天时长
|
||||
NightLen int `json:"night"` // 夜间时长
|
||||
}
|
||||
|
||||
type world struct {
|
||||
w [3]*timezone
|
||||
hassync uintptr
|
||||
}
|
||||
|
||||
var gameWorld = newworld()
|
||||
|
||||
// String 根据传入的世界编号,获取对应的游戏时间文本
|
||||
func (t *timezone) String() string {
|
||||
t.RLock()
|
||||
defer t.RUnlock()
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("平原时间: ")
|
||||
if t.IsDay {
|
||||
sb.WriteString(t.DayDesc)
|
||||
} else {
|
||||
sb.WriteString(t.NightDesc)
|
||||
}
|
||||
sb.WriteString(", ")
|
||||
sb.WriteString("下次更新: ")
|
||||
d := time.Until(t.NextTime)
|
||||
durStr, _ := durationfmt.Format(d, "%m分%s秒后")
|
||||
sb.WriteString(durStr)
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
func newworld() (w world) {
|
||||
w.w = [3]*timezone{
|
||||
{Name: "地球平原", DayDesc: "白天", NightDesc: "夜晚", DayLen: 100 * 60, NightLen: 50 * 60},
|
||||
{Name: "金星平原", DayDesc: "温暖", NightDesc: "寒冷", DayLen: 400, NightLen: 20 * 60},
|
||||
{Name: "火卫二平原", DayDesc: "fass", NightDesc: "vome", DayLen: 100 * 60, NightLen: 50 * 60},
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (w *world) hasSync() bool {
|
||||
return atomic.LoadUintptr(&w.hassync) != 0
|
||||
}
|
||||
|
||||
func (w *world) setsync() bool {
|
||||
return atomic.CompareAndSwapUintptr(&w.hassync, 0, 1)
|
||||
}
|
||||
|
||||
func (w *world) resetsync() bool {
|
||||
return atomic.CompareAndSwapUintptr(&w.hassync, 1, 0)
|
||||
}
|
||||
|
||||
// 根据API返回内容修正游戏时间
|
||||
func (w *world) refresh(api *wfapi) {
|
||||
for _, t := range w.w {
|
||||
t.Lock()
|
||||
}
|
||||
w.w[0].NextTime = api.CetusCycle.Expiry.Local()
|
||||
w.w[0].IsDay = api.CetusCycle.IsDay
|
||||
|
||||
w.w[1].NextTime = api.VallisCycle.Expiry.Local()
|
||||
w.w[1].IsDay = api.VallisCycle.IsWarm
|
||||
|
||||
w.w[2].NextTime = api.CambionCycle.Expiry.Local()
|
||||
w.w[2].IsDay = api.CambionCycle.Active == "fass"
|
||||
}
|
||||
|
||||
// 游戏时间更新
|
||||
func (w *world) update() {
|
||||
if !w.hasSync() {
|
||||
return
|
||||
}
|
||||
for _, t := range w.w {
|
||||
t.Lock()
|
||||
// 当前时间对比下一次游戏状态更新时间,看看还剩多少秒
|
||||
nt := time.Until(t.NextTime).Seconds()
|
||||
// 已经过了游戏时间状态更新时间
|
||||
if nt < 0 {
|
||||
// 更新游戏状态,如果是白天就切换到晚上,反之亦然
|
||||
if t.IsDay {
|
||||
// 计算下次的晚上更新时间
|
||||
t.NextTime = t.NextTime.Add(time.Duration(t.NightLen) * time.Second)
|
||||
} else {
|
||||
// 计算下次的白天更新时间
|
||||
t.NextTime = t.NextTime.Add(time.Duration(t.DayLen) * time.Second)
|
||||
}
|
||||
}
|
||||
t.Unlock()
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,21 @@ 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"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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" //口令
|
||||
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"
|
||||
)
|
||||
@@ -86,7 +87,7 @@ func init() { // 主函数
|
||||
}
|
||||
ctx.SendChain(message.Text(helper.BytesToString(data)))
|
||||
})
|
||||
en.OnFullMatch("每日一言").SetBlock(true).Handle(func(ctx *zero.Ctx) { //每日一言
|
||||
en.OnFullMatch("每日一言").SetBlock(true).Handle(func(ctx *zero.Ctx) { // 每日一言
|
||||
var rsp rspData
|
||||
data, err := web.GetData(yiyan)
|
||||
if err != nil {
|
||||
|
||||
@@ -14,10 +14,10 @@ import (
|
||||
|
||||
"github.com/FloatTech/AnimeAPI/tl"
|
||||
|
||||
"github.com/Coloured-glaze/gg"
|
||||
"github.com/FloatTech/floatbox/binary"
|
||||
fcext "github.com/FloatTech/floatbox/ctxext"
|
||||
"github.com/FloatTech/floatbox/img/writer"
|
||||
"github.com/FloatTech/gg"
|
||||
ctrl "github.com/FloatTech/zbpctrl"
|
||||
"github.com/FloatTech/zbputils/control"
|
||||
"github.com/FloatTech/zbputils/ctxext"
|
||||
|
||||
@@ -41,7 +41,7 @@ type searchResult struct {
|
||||
func init() {
|
||||
en := control.Register("ygocdb", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "游戏王百鸽API",// 本插件基于游戏王百鸽API"https://www.ygo-sem.cn/"
|
||||
Brief: "游戏王百鸽API", // 本插件基于游戏王百鸽API"https://www.ygo-sem.cn/"
|
||||
Help: "- /ydp [xxx]\n" +
|
||||
"- /yds [xxx]\n" +
|
||||
"- /ydb [xxx]\n" +
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Package ygo 一些关于ygo的插件
|
||||
package ygo
|
||||
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -49,14 +48,14 @@ type tradeInfo struct {
|
||||
func init() {
|
||||
engine := control.Register("ygotrade", &ctrl.Options[*zero.Ctx]{
|
||||
DisableOnDefault: false,
|
||||
Brief: "游戏王卡价查询",// 本插件基于集换社API
|
||||
Help: "- 查卡价 [卡名]\n- 查卡价 [卡名] [稀有度 稀有度 ...]\n- 查卡店 [卡名]\n- 查卡店 [卡名] [稀有度]",
|
||||
Brief: "游戏王卡价查询", // 本插件基于集换社API
|
||||
Help: "- 查卡价 [卡名]\n- 查卡价 [卡名] -r [稀有度 稀有度 ...]\n- 查卡店 [卡名]\n- 查卡店 [卡名] -r [稀有度]",
|
||||
}).ApplySingle(ctxext.DefaultSingle)
|
||||
engine.OnPrefix("查卡价", func(ctx *zero.Ctx) bool {
|
||||
ctx.State["args"] = strings.TrimSpace(ctx.State["args"].(string))
|
||||
return ctx.State["args"].(string) != ""
|
||||
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " ")
|
||||
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " -r ")
|
||||
listOfTrace, err := getRarityTrade(cardName, rarity)
|
||||
if err != nil {
|
||||
ctx.SendChain(message.Text("ERROR: ", err))
|
||||
@@ -80,7 +79,7 @@ func init() {
|
||||
ctx.State["args"] = strings.TrimSpace(ctx.State["args"].(string))
|
||||
return ctx.State["args"].(string) != ""
|
||||
}).SetBlock(true).Handle(func(ctx *zero.Ctx) {
|
||||
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " ")
|
||||
cardName, rarity, _ := strings.Cut(ctx.State["args"].(string), " -r ")
|
||||
if strings.Count(rarity, " ") > 0 {
|
||||
ctx.SendChain(message.Text("ERROR: ", "卡店查询不支持查找多个罕贵度"))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user