Compare commits

..
55 Commits
Author SHA1 Message Date
HibiKier 1ce4537605 upadte README.md 2022-10-16 22:54:34 +08:00
HibiKier 701812ed9d upadte README.md 2022-10-16 22:39:57 +08:00
HibiKier 8d9e81827b 修改版本 2022-10-16 22:38:12 +08:00
HibiKier f51a2816b4 修改依赖注入方法 2022-10-16 22:37:58 +08:00
HibiKier 3d4a7950c5 修改依赖注入方法 2022-10-16 22:36:13 +08:00
HibiKier ba6668f144 修改商店道具icon可以为空 2022-10-16 11:46:56 +08:00
HibiKier e1f7a77d15 修正 2022-10-16 00:21:42 +08:00
HibiKier 64e2c512d3 Merge remote-tracking branch 'origin/main' 2022-10-16 00:21:30 +08:00
HibiKier 6082e68a1f Delete Generate.yml 2022-10-16 00:21:00 +08:00
HibiKier f135d48e55 Merge remote-tracking branch 'origin/main' 2022-10-16 00:20:24 +08:00
HibiKier 751fc8fdb4 修复我的道具仅有被动或主动道具时图片显示错误 2022-10-16 00:19:55 +08:00
github-actions[bot] df73e79ee4 Auto generate poetry.lock 2022-10-15 15:10:25 +00:00
HibiKier fa6cfdb609 修正 2022-10-15 23:07:26 +08:00
HibiKier b057a05520 更多的依赖注入 2022-10-15 22:13:41 +08:00
HibiKier cb0938721c 新增用户使用道具,花费金币及用途记录表以及更细致的金币使用依赖注入 2022-10-15 21:21:23 +08:00
HibiKier 4f3f8de734 错误捕获 2022-10-15 20:50:02 +08:00
HibiKier 5ba303aada Merge pull request #1139 from yuzb1beiz/main
色图插件p站反向代理失效
2022-10-15 20:42:49 +08:00
yusean bd42fefe4e Merge branch 'HibiKier:main' into main 2022-10-15 20:15:29 +08:00
sean d24c081973 修复色图插件p站反向代理失效问题 2022-10-15 20:00:06 +08:00
HibiKier 1b9eddd905 Add files via upload 2022-10-15 19:53:11 +08:00
HibiKier 0bfe398dc4 更新至nonebot-rc1 2022-10-15 19:49:53 +08:00
HibiKier e9216a472f Add files via upload 2022-10-13 19:36:54 +08:00
HibiKier 8b93ec0df6 Delete poetry.lock 2022-10-13 19:36:40 +08:00
HibiKier 7497706a0d Merge pull request #1124 from DDS-DS/main
修复碧蓝档案角色获取问题,换源
2022-10-09 19:14:35 +08:00
dingshan 6e41cb0630 修复碧蓝档案角色获取问题,换源 2022-10-09 16:08:55 +08:00
HibiKier 62d99e7e90 Merge remote-tracking branch 'origin/main' 2022-10-07 22:07:51 +08:00
HibiKier 43cddb3580 关闭功能与被动时不再区分大小写 2022-10-07 22:07:36 +08:00
github-actions[bot] c9c1beda75 Auto generate poetry.lock 2022-10-07 13:00:26 +00:00
HibiKier 3ee9ae5fb8 Merge pull request #1119 from SK-415/main
修复 B 站请求返回 -401 错误
2022-10-07 20:57:33 +08:00
github-actions[bot] ea6344fae1 Auto generate poetry.lock 2022-10-02 22:53:37 +00:00
SK 6f54e91f5c ⬆️ Bump bilireq to v0.2.3 2022-10-02 22:50:00 +00:00
HibiKier 27fb3aaa19 Merge pull request #1118 from guohu7777/main
修改重置开箱的使用权限
2022-09-29 18:01:39 +08:00
guohu7777 86d736745d 修改重置开箱的使用权限
禁止普通群员使用重置每日开箱次数指令
2022-09-28 01:23:42 +08:00
HibiKier 821fe21c2b Merge pull request #1117 from yajiwa/main
更新b站转发解析
2022-09-27 19:31:11 +08:00
yajiwa 7f4aa518dc update parse_bilibili 2022-09-27 03:11:57 +08:00
HibiKier 8cf589e433 UPDATE README.md 2022-09-25 21:43:23 +08:00
HibiKier 105a29cd70 Merge pull request #1114 from DDS-DS/main
fix: 重载赛马娘卡池失败
2022-09-24 17:50:52 +08:00
HibiKier cb6a5e81e7 Merge pull request #1112 from yajiwa/main
修复b站订阅
2022-09-24 17:49:57 +08:00
dingshan 9c073383ad fix: 重载赛马娘卡池失败 2022-09-23 18:27:04 +08:00
github-actions[bot] 5e0756825d Auto generate poetry.lock 2022-09-21 19:39:34 +00:00
yajiwa 933523ae6d fix bilibili_sub 2022-09-22 03:35:34 +08:00
HibiKier ed6b05605c Update map.py 2022-09-21 21:59:19 +08:00
HibiKier 71a9c34620 Merge pull request #1108 from yajiwa/main
修复原神资源查询没有图片
2022-09-21 21:57:55 +08:00
HibiKier e29f2cb920 Update query_resource.py 2022-09-21 21:57:25 +08:00
yajiwa d47dd88d6c fix genshin path 2022-09-21 01:13:37 +08:00
github-actions[bot] fb34bbce7a Auto generate poetry.lock 2022-09-20 15:36:00 +00:00
HibiKier 100236da83 修复csgo每日开箱可以多开一次 2022-09-19 22:50:56 +08:00
HibiKier a45a3002d5 Merge pull request #1097 from LambdaYH/main
更换bilibili_sub获取用户昵称用的API&尝试修了一下get_video()
2022-09-19 22:34:01 +08:00
HibiKier 9214a4c978 Merge pull request #1098 from yajiwa/main
update check_zhenxun
2022-09-18 15:07:52 +08:00
HibiKier 70761dc222 Merge pull request #1096 from SK-415/main
修复 bilireq 版本过低导致 B 站视频解析错误
2022-09-18 15:05:29 +08:00
Cinte 32e8136f71 fix get_video()
目前测试了下,至少-401的情况少了很多
2022-09-17 18:26:49 +08:00
yajiwa 8b20d99b2c update check_zhenxun 2022-09-17 13:01:50 +08:00
Cinte 1174b5cc7f x 2022-09-17 11:23:55 +08:00
Cinte ec448cfdfb replace get_user_info with get_user_card 2022-09-17 10:58:58 +08:00
SK f3e44b1baf chore(deps): update bilireq 2022-09-16 23:24:40 +00:00
45 changed files with 2461 additions and 1541 deletions
-38
View File
@@ -1,38 +0,0 @@
name: Generate poetry.lock
on:
push:
branches:
- "main"
paths:
- 'pyproject.toml'
jobs:
poetry_lock:
name: Generate
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python
uses: he0119/setup-python@main
with:
python-version: "3.9"
- name: poetry lock
run: |
rm -f poetry.lock
sed -i.bak "8,11d" pyproject.toml
poetry lock
mv pyproject.toml.bak pyproject.toml
# commit
- name: commit file
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add poetry.lock
git commit -m "Auto generate poetry.lock" -a
# push
- name: push changes
uses: ad-m/github-push-action@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
+64 -478
View File
@@ -13,7 +13,9 @@
如果该项目的图片等等侵犯猫豆腐老师权益请联系我删除! 如果该项目的图片等等侵犯猫豆腐老师权益请联系我删除!
如果希望有个地方讨论绪山真寻Bot,或者有问题或建议,可以发送issues或加入[ <strong>[是真寻酱哒](https://jq.qq.com/?_wv=1027&k=u8PgBkMZ) </strong>] 是新手!希望有个地方讨论绪山真寻Bot,或者有问题或建议,可以发送issues或加入[ <strong>[是真寻酱哒(萌新版)](https://jq.qq.com/?_wv=1027&k=u8PgBkMZ) </strong>]
[//]: # (是老手!讨论插件开发,nonebot2开发,可以加入[ <strong>[真寻酱的技术群]&#40;https://jq.qq.com/?_wv=1027&k=u8PgBkMZ&#41; </strong>])
## 声明 ## 声明
此项目仅用于学习交流,请勿用于非法用途 此项目仅用于学习交流,请勿用于非法用途
@@ -252,6 +254,18 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
### 感谢名单 ### 感谢名单
(可以告诉我你的 __github__ 地址,我偷偷换掉0v|) (可以告诉我你的 __github__ 地址,我偷偷换掉0v|)
[Yui](https://afdian.net/u/870dc10a3cd311ed828852540025c377)
[本喵无敌哒](https://afdian.net/u/dffaa9005bc911ebb69b52540025c377)
[椎名冬羽](https://afdian.net/u/ca1ebd64395e11ed81b452540025c377)
[kaito](https://afdian.net/u/a055e20a498811eab1f052540025c377)
[笑柒XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
[请问一份爱多少钱](https://afdian.net/u/f57ef6602dbd11ed977f52540025c377)
[咸鱼鱼鱼鱼](https://afdian.net/u/8e39b9a400e011ed9f4a52540025c377)
[Kafka](https://afdian.net/u/41d66798ef6911ecbc5952540025c377)
[墨然](https://afdian.net/u/8aa5874a644d11eb8a6752540025c377)
[爱发电用户_T9e4](https://afdian.net/u/2ad1bb82f3a711eca22852540025c377)
[笑柒XIAO_Q7](https://afdian.net/u/4696db5c529111ec84ea52540025c377)
[noahzark](https://afdian.net/a/noahzark)
[腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377) [腊条](https://afdian.net/u/f739c4d69eca11eba94b52540025c377)
[ze roller](https://afdian.net/u/0e599e96257211ed805152540025c377) [ze roller](https://afdian.net/u/0e599e96257211ed805152540025c377)
[爱发电用户_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377) [爱发电用户_4jrf](https://afdian.net/u/6b2cdcc817c611ed949152540025c377)
@@ -263,7 +277,7 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
[爱发电用户_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377) [爱发电用户_eNr9](https://afdian.net/u/05fdb41c0c9a11ed814952540025c377)
[MangataAkihi](https://github.com/Sakuracio) [MangataAkihi](https://github.com/Sakuracio)
[炀](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377) [炀](https://afdian.net/u/69b76e9ec77b11ec874f52540025c377)
[爱发电用户_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377) [爱发电用户_Bc6j](https://afdian.net/u/8546be24f44111eca64052540025c377)
[大魔王](https://github.com/xipesoy) [大魔王](https://github.com/xipesoy)
[CopilotLaLaLa](https://github.com/CopilotLaLaLa) [CopilotLaLaLa](https://github.com/CopilotLaLaLa)
[嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377) [嘿小欧](https://afdian.net/u/daa4bec4f24911ec82e552540025c377)
@@ -279,6 +293,53 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
## 更新 ## 更新
### 2022/10/16 \[v0.1.6.4]
* 修改商店道具icon可以为空
### 2022/10/15
* nonebot2版本更新为rc1
* 我的道具改为图片形式
* 商品添加图标与是否为被动道具(被动道具无法被主动使用)
* 商品添加使用前方法和使用后方法(类似hook),使用方法具体查看文档或签到商品文件中注册的例子
* 新增用户使用道具,花费金币(包括插件)及用途记录
* 更细致的金币使用依赖注入
* 更多的依赖注入(包含图片获取等等..
* 修复我的道具仅有被动或主动道具时图片显示错误
* 色图插件p站反向代理失效 [@pull/1139](https://github.com/HibiKier/zhenxun_bot/pull/1139)
### 2022/10/9
* 修复碧蓝档案角色获取问题,换源 [@pull/1124](https://github.com/HibiKier/zhenxun_bot/pull/1124)
### 2022/10/7
* 修复 B 站请求返回 -401 错误 [@pull/1119](https://github.com/HibiKier/zhenxun_bot/pull/1119)
* 关闭功能与被动时不再区分大小写,同名时仅被动关闭操作生效
### 2022/9/30
* 修改重置开箱的使用权限 [@pull/1118](https://github.com/HibiKier/zhenxun_bot/pull/1118)
### 2022/9/27
* 更新b站转发解析 [@pull/1117](https://github.com/HibiKier/zhenxun_bot/pull/1117)
### 2022/9/24
* 修复b站订阅 [@pull/1112](https://github.com/HibiKier/zhenxun_bot/pull/1112)
* fix: 重载赛马娘卡池失败 [@pull/1114](https://github.com/HibiKier/zhenxun_bot/pull/1114)
### 2022/9/19
* 更换bilibili_sub获取用户昵称用的API&尝试修了一下get_video() [@pull/1097](https://github.com/HibiKier/zhenxun_bot/pull/1097)
* 修复csgo每日开箱可以多开一次
### 2022/9/18
* 修复 bilireq 版本过低导致 B 站视频解析错误 [@pull/1090](https://github.com/HibiKier/zhenxun_bot/pull/1096)
### 2022/9/16 ### 2022/9/16
* fix: bilibili_sub, azur_draw_card [@pull/1090](https://github.com/HibiKier/zhenxun_bot/pull/1090) * fix: bilibili_sub, azur_draw_card [@pull/1090](https://github.com/HibiKier/zhenxun_bot/pull/1090)
@@ -334,7 +395,7 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
* 修复b站转发解析av号无法解析 * 修复b站转发解析av号无法解析
* B站订阅直播订阅支持短号 * B站订阅直播订阅支持短号
* 开箱提供重置开箱命令,重置今日所有开箱数据(重置次数,并不会删除今日已开箱记录) * 开箱提供重置开箱命令,重置今日所有开箱数据(重置次数,并不会删除今日已开箱记录)
* 提供全局字典GDict,通过from utils.manager import GDict导入 * 提供全局字典GDict,通过from utils.utils import GDict导入
* 适配omega 13w张图的数据结构表(建议删表重导) * 适配omega 13w张图的数据结构表(建议删表重导)
* 除首次启动外将配置替换加入单次定时任务,加快启动速度 * 除首次启动外将配置替换加入单次定时任务,加快启动速度
* fix: WordBank.check() [@pull/1008](https://github.com/HibiKier/zhenxun_bot/pull/1008) * fix: WordBank.check() [@pull/1008](https://github.com/HibiKier/zhenxun_bot/pull/1008)
@@ -360,481 +421,6 @@ PS: **ARM平台** 请使用全量版 同时 **如果你的机器 RAM < 1G 可能
* 修复了原神自动签到返回invalid request的问题,新增查看我的cookie命令 [@pull/971](https://github.com/HibiKier/zhenxun_bot/pull/971) * 修复了原神自动签到返回invalid request的问题,新增查看我的cookie命令 [@pull/971](https://github.com/HibiKier/zhenxun_bot/pull/971)
### 2022/7/31
* 对nonebot.beta4中PluginMeta进行解析
* 修改webui元祖类型无法正确转换类型
* 查看订阅以图片形式发送
* 修复pix无图时不会提醒而是出错
### 2022/7/30
* 替换了cos和bt的url [@pull/951](https://github.com/HibiKier/zhenxun_bot/pull/951)
* 发言记录统计添加日消息统计 [@pull/953](https://github.com/HibiKier/zhenxun_bot/pull/953)
### 2022/7/24 \[v0.1.6.2]
* 订阅up动态提供直链
### 2022/7/23
* 优化开箱次数判断
### 2022/7/16
* cos提供连发命令
* 修复B站视频解析中b23解析错误
### 2022/7/13
* B站订阅提供配置项`LIVE_MSG_AT_ALL`,`UP_MSG_AT_ALL`:控制UP动态投稿和直播是否AT全体
* 修改了Omega图库检测的数据库文件名
* game_utils提供了Game类
### 2022/7/7
* 微博热搜选择单条热搜时也会检测时效性 [@pull/891](https://github.com/HibiKier/zhenxun_bot/pull/891)
### 2022/7/4
* 修复商品未设置限购时无法购买
* 修复B站订阅UP动态 [@pull/886](https://github.com/HibiKier/zhenxun_bot/pull/886)
* 修复色图命令带tag时配置项`MAX_ONCE_NUM2FORWARD`无法生效
### 2022/7/3 \[v0.1.6.1]
* BagUser提供方法`check_props`方法,用于判断用户是否含有该道具并是否使用
* 优化商品显示图片,提供限制,限购,折扣提示
* 修复图库内图片无法被连续删除的问题 [@pull/879](https://github.com/HibiKier/zhenxun_bot/pull/879)
* 色图提供配置项`MAX_ONCE_NUM2FORWARD`:群聊中单次发送图片数量达到指定时使用合并转发
* 优化修复了商品修改命令
* B站订阅UP动态改为详情页截图
### 2022/6/28
* 修复色图插件api修改无法搜索图片 [@pull/866](https://github.com/HibiKier/zhenxun_bot/pull/866)
### 2022/6/26
* 替换了bt URL
* PIX当使用pid查询图片时,会发送该pid下所有图片
* 商店提供了每日购买次数限制
### 2022/6/24
* 对WSL虚拟机 代理 添加写法 [@pull/847](https://github.com/HibiKier/zhenxun_bot/pull/847)
### 2022/6/21
* update parse_bilibili [@pull/840](https://github.com/HibiKier/zhenxun_bot/pull/840)
### 2022/6/19 \[v0.1.6.0]
* 暂时使用hook修复webui中plugins2setting修改时会改变plugins2setting.cmd为字符串
* 修复原神树脂重复提醒的bug [@pull/828](https://github.com/HibiKier/zhenxun_bot/pull/828)
* 词条优化问题展示,修改含机器人昵称和@逻辑 [@pull/835](https://github.com/HibiKier/zhenxun_bot/pull/835)
### 2022/6/18
* 修复昵称系统`BLACK_WORD`为空时造成报错
* 修复特殊头像时背景透明化出错
* 修复text2image纯文本时换行时颜色不统一
* 优化webUI,当有插件出错时不会影响其他插件显示
* 优化Config类型注释 [@pull/830](https://github.com/HibiKier/zhenxun_bot/pull/830)
* 优化browser
### 2022/6/17
* 修复wordbank的一些小问题 @pull/820
### 2022/6/14
* AsyncHttpx提供可关闭 ssl 验证参数 [@pull/812](https://github.com/HibiKier/zhenxun_bot/pull/812)
* fix: 自动更新群组 [@pull/810](https://github.com/HibiKier/zhenxun_bot/pull/810)
* fix: 修复添加词条时对answer中图片的处理 [@pull/806](https://github.com/HibiKier/zhenxun_bot/pull/806)
* 修复pix中指定num无法生效
* 替换了bt URL
### 2022/6/13
* Windows 重启适配 [@pull/804](https://github.com/HibiKier/zhenxun_bot/pull/804)
* 色图等提供修改md5方法 [@pull/800](https://github.com/HibiKier/zhenxun_bot/pull/800)
* webui中token.json文件写入补充 [@pull/798](https://github.com/HibiKier/zhenxun_bot/pull/798)
* 修复识图某些图片可能会出错
### 2022/6/11
* pix当只有一个tag时且为数字时可以通过添加'#'防止判定为数量
### 2022/6/9
* 修复b站订阅同群二人以上相同订阅时发送多次信息
* 修复超级用户帮助中缺少了 ‘插件商店’ 相关帮助
* 昵称系统提供了详细帮助
### 2022/6/5 \[v0.1.5.9]
* webui修复plugin2setting中cmd从list转变为str
* 当命令`我的金币`被风控时将以图片形式发送
* fix gold_redbag [@pull/763](https://github.com/HibiKier/zhenxun_bot/pull/763)
* 金币红包功能增加更多封面 [@pull/764](https://github.com/HibiKier/zhenxun_bot/pull/764)
### 2022/6/3
* 插件仓库在已安装插件边上会提示\[已安装]
* 修复ShopRegister kwargs某些字段无效
* 调整了一下查看所有请求中的年龄绘制 [@pull/745](https://github.com/HibiKier/zhenxun_bot/pull/745)
* 修复原神树脂提醒bug [@pull/756](https://github.com/HibiKier/zhenxun_bot/pull/756)
### 2022/5/31
* 修复开启/关闭全部功能时帮助图片未重绘 [@pull/721](https://github.com/HibiKier/zhenxun_bot/pull/721)
* bot_friend_group将group_handle.修改为friend_handle. [@pull/711](https://github.com/HibiKier/zhenxun_bot/pull/711)
* 修复发红包图片背景未透明化;修复原神树脂提醒参数错误 [@pull/712](https://github.com/HibiKier/zhenxun_bot/pull/712)
* 修复抽卡插件:方舟更新UP池信息时,若公告的第一个池子过期会导致无法更新UP池信息 [@pull/707](https://github.com/HibiKier/zhenxun_bot/pull/707)
* 商店插件判断是否有requirements.txt文件 [@pull/705](https://github.com/HibiKier/zhenxun_bot/pull/705)
* 删除原神玩家查询api返回变更的多余键值
* 优化了text2image方法
### 2022/5/29 \[v0.1.5.8]
* 提供了真寻适配仓库的插件 安装/卸载 操作
* 暂时关闭了插件资源清空
* 通过指令安装插件时会在插件目录下生成plugin_info.json记录当前插件信息
### 2022/5/28
* 修复私聊无法添加昵称
* 修复原神玩家查询层岩巨渊地下矿区没开时报错
* 修复 ```休息吧``` 无法阻断戳一戳
* 当图库无图片时,戳一戳将略过发送图片
* 新增搜图提供配置项```ALLOW_GROUP_R18```:允许在群聊中使用r18参数
* 新增自动更新插件```UPDATE_REMIND```:新版本提醒,原配置项```AUTO_UPDATE_ZHENXUN```改为自动更新升级
* black_word新增当群权限为-1时不再检测该群
* 修复非超级用户绑定原神cookie会被black_word阻拦
* 修复微博热搜报错,发红包小bug [@pull/688](https://github.com/HibiKier/zhenxun_bot/pull/688)
* 更多的中文提示
### 2022/5/26
* 修复\[滴滴滴]会被转义成&#91;滴滴滴&#93;导致无法触发的问题
* 将一些错误以中文提示输出
* 更新BT搜索源地址 [@pull/668](https://github.com/HibiKier/zhenxun_bot/pull/668)
* 更新抽卡插件 [@pull/667](https://github.com/HibiKier/zhenxun_bot/pull/667)
### 2022/5/25
* 修复webui中CountLimit字段limit_type类型错误
* 修改nickname插件:一处文案错误,添加敏感词 [@pull/624](https://github.com/HibiKier/zhenxun_bot/pull/624)
* gamedraw的ba卡池搬运了过来并且进行了真寻的适配 [@pull/617](https://github.com/HibiKier/zhenxun_bot/pull/617)
* feat: stream downloading and progress [@pull/607](https://github.com/HibiKier/zhenxun_bot/pull/607)
* 修改翻译插件,添加缺失的冒号 [@pull/602](https://github.com/HibiKier/zhenxun_bot/pull/602)
* 修复碧蓝航线/明日方舟up池解析出错的问题 [@pull/610](https://github.com/HibiKier/zhenxun_bot/pull/602)
### 2022/5/24
* fix: 修正了签到时日期时间的显示不补齐零的bug (符合日期时间表示法 ISO 8601)[@pull/600](https://github.com/HibiKier/zhenxun_bot/pull/600)
* 更新"微博热搜"接口 [@pull/579](https://github.com/HibiKier/zhenxun_bot/pull/579)
* refactor&fix(manager): modify argument [@pull/576](https://github.com/HibiKier/zhenxun_bot/pull/576)
* 修复复读不能复读图片的问题 [@pull/573](https://github.com/HibiKier/zhenxun_bot/pull/573)
* 修复抽卡插件:方舟抽卡的抽取和显示问题 [@pull/581](https://github.com/HibiKier/zhenxun_bot/pull/581)
### 2022/5/23 \[v0.1.5.6]
* 修复"清除已删除插件数据" [@pull/545](https://github.com/HibiKier/zhenxun_bot/pull/545)
* 修复有置顶的up主B站动态获取失败 [@pull/552](https://github.com/HibiKier/zhenxun_bot/pull/552)
* 添加pixiv搜图多关键词支持;修复p站搜图数量参数问题 [@pull/441](https://github.com/HibiKier/zhenxun_bot/pull/441)
* 修复开箱更新价格错误传参
* 修复pix无法正确查询uid
* 新增色图插件添加配置项```ALLOW_GROUP_R18```:允许群聊中使用色图r
* 新增PIX插件添加配置项```ALLOW_GROUP_SETU```:允许非超级用户使用-s参数
* 新增PIX插件添加配置项```ALLOW_GROUP_R18```:允许非超级用户使用-r参数
### 2022/5/22 \[v0.1.5.4]
* 使用action自动更新poetry.lock [@pull/515](https://github.com/HibiKier/zhenxun_bot/pull/515)
* fix(bilibili_sub): card is None and timeout [@pull/516](https://github.com/HibiKier/zhenxun_bot/pull/516)
* 修复了epic有时获取新免费游戏消息时获取不到图片
* 修复好感度满时签到出错(虽然是不可能满的
* 修复原神资源图标下载路径错误
* 修复自动更新群组可能失败
### 2022/5/21
* 修复搜番无结果时报错无正确反馈
* 解锁了windows上无法使用playwright的限制
* 修复p搜对应pid有多张图时出错,改为连续发送图片
* 修复p搜对数字的错误判断
* 修复添加商品折扣无法正确添加
* 修复了bilibili订阅直播间订阅up名称不一致的问题
* 修复原神玩家查询没开地图时报错
* 最低priority修改为 999
* 修复刷屏检测失效
* 修复刷屏检测设置命令无法生效
* 优化刷屏显示设置禁言时长显示,并改为分钟
* 修复了多连开箱无法指定武器箱
* 修复识番链接无法正确获取
* 新增真寻入群时即刻刷新权限
* 提高了微博热搜截图的等待时间
### 2022/5/19
* fix: mihoyo bbs api changed [@pull/357](https://github.com/HibiKier/zhenxun_bot/pull/357)
* Add word_clouds [@pull/265](https://github.com/HibiKier/zhenxun_bot/pull/265)
* Fix wrong live streamer name [@pull/284](https://github.com/HibiKier/zhenxun_bot/pull/284)
### 2022/5/16
* 词条支持图片和@问题 [@pull/160](https://github.com/HibiKier/zhenxun_bot/pull/160)
### 2022/5/15
* 修复了商店商品无法正确添加
* 修复了多张色图无法正确发送
### 2022/5/14
* 修复B站动态生成失败的问题 [@pull/159](https://github.com/HibiKier/zhenxun_bot/pull/159)
### 2022/5/11
* fix: 更改p搜api,解决p搜无法使用的问题 [@pull/155](https://github.com/HibiKier/zhenxun_bot/pull/155)
### 2022/5/9 \[v0.1.5.3]
* 替换了疫情API
* 修复了私聊.ban/.unban出错
### 2022/5/5
* 修改bilibili_sub插件在windows平台下报错 [@pull/153](https://github.com/HibiKier/zhenxun_bot/pull/153)
### 2022/5/3 \[v0.1.5.2]
* 商品使用函数可以添加特定参数,例如:user_id, group_id, ShopParam等以及自己提供的参数
* 添加商品注册装饰器shop_register
* 修复商品函数kwargs无法获取参数值
### 2022/5/1
* 删除了`group_last_chat`插件(该功能可由`chat_history`替代
* 新增敏感词检测(全新反击系统,是时候重拳出击了
### 2022/4/26
* 修复了群白名单无法正确添加
* 优化了管理员帮助图片,背景图层将位于最下层
* 修复了树脂140时不断提醒(未测试
* 新增了消息记录的消息排行
* WebUI新增CPU,内存,磁盘监控
* WebUI新增资源文件夹统计可视化
### 2022/4/12
* 修复b了命令私聊出错
### 2022/4/10 \[v0.1.4.7]
* 新增消息记录模块
* 丰富处理请求操作提示
* web ui新增配置项修改
### 2022/4/9
* fix: 更新问题,戳一戳图片路径问题 [@pull/144](https://github.com/HibiKier/zhenxun_bot/pull/144)
### 2022/4/8
* 修复原神玩家查询
### 2022/4/6
* update search_type [@pull/143](https://github.com/HibiKier/zhenxun_bot/pull/143)
### 2022/4/5 \[v0.1.4.6]
* 修复web修改插件后帮助图片生成错误
### 2022/4/4 \[v0.1.4.5]
* 替换了bt搜索URL
* 优化使用playwright的相关代码
* 原神玩家查询新增层岩巨渊探索
* 修复原神便笺角色头像黑框
* 修复同意群聊请求错误
* 提供webui方面的api
* 新增web-ui(前端简易管理页面插件)插件
### 2022/3/21
* 修复statistics_handle.py乱码
### 2022/3/18 \[v0.1.4.4]
* 修复戳一戳无法功能关闭与ban禁用
* 新增图片搜索 search_image
### 2022/3/7
* 优化增删权限插件
### 2022/3/6
* 修复树脂提醒无法开启
* 修复p搜图片路径错误
### 2022/3/3 \[v0.1.4.3]
* 修复手动同意群聊请求依旧退出
### 2022/3/1 \[v0.1.4.2]
* 0.1.4内容
### 2022/2/27 \[v0.1.4.1]
* 优化抽卡
### 2022/2/25 \[v0.1.4]
* PIX提供配置MAX_ONCE_NUM2FORWARD:当单次发送图片超过指定张数且在群聊时,将转为合并消息
* 修复点歌无法正确发送
* 修复我有一个朋友有时文本会包含CQ码
* 修复群欢消息被动控制文本未删除 [@pull/124](https://github.com/HibiKier/zhenxun_bot/pull/124)
* message_builder.image不再提供参数:abspath
### 2022/2/23
* 插件状态将从已加载插件模块中读取
* 修复b站订阅插件订阅失败问题
* 修复重启命令无法使用
### 2022/2/21 \[v0.1.3.2]
* 群权限为-1时,超级用户发送的命令依旧生效
* 当群权限为-1时,被动技能也将不会发送
* 修复功能开关,b站转发解析,复读 ignore无法使用
* 修复色图下载文件名与路径错误
* 修复被动技能提醒有时无法删除控制文本
### 2022/2/20 \[v0.1.3.1]
* 修复pix下载临时文件目录错误
* 修复AI,天气,发送图片ignore导致无法使用
* 修复纯文本被动技能提醒有时无法删除控制文本
### 2022/2/19 \[v0.1.3] (nonebot beta2!)
* 由于nonebot升级版本,提供更新建议(__该次升级将会导致nonebot.beta1以下的插件无法使用__
* 保证services,utils,configs,plugins,basic_plugins,文件夹均为最新
* 根目录有pyproject.toml与poetry.lock
* 执行命令:
* pip3 install poetry
* poetry install
* poetry shell
* playwright install chromium
* python3 bot.py
* 适配nonebot.beta2
* 删除图片搜索 nonebot_plugin_picsearcher
* 替换cos api
* 原神签到树脂提醒新增绑定群里,在某群绑定uid就会在某群发送提醒信息(有好友则私聊,需要重新绑定uid
* 修改update_info.json
* 修复原神资源查询下载数据失败时导致报错
* 优化BuildImage.circle()锯齿问题 [@pull/109](https://github.com/HibiKier/zhenxun_bot/pull/109)
* epic restful 替换 [@pull/119](https://github.com/HibiKier/zhenxun_bot/pull/119)
* fix: 修复远古时期残留的epic推送问题 [@pull/122](https://github.com/HibiKier/zhenxun_bot/pull/122)
### 2022/2/11
* 修复pix不使用反代无法下载图片
### 2022/2/10 \[v0.1.1]
* 修复购买道具出错
### 2022/2/9 \[v0.1]
* 新增原神自动签到和手动签到
* 新增原神树脂提醒
* 新增手动重载Config.yaml命令以及重载配置定时任务(极少部分帮助或配置可能需要重启
* 修改了发送本地图库的matcher,改为on_message
* register_use可以通过返回值发送消息
* 修复修改商品时限制时间出错
* 修复超时商品依旧可以被购买
### 2022/1/16 \[v0.0.9.0]
* Ai提供文本敏感词过滤器
* 疫情插件适配新版腾讯API
* 修复/t回复带空格切分
* 修复原神玩家查询缺少渊下宫和稻妻家园以及角色不完全
* 修复方法 text2image 中 padding 和 font 无法对纯文本生效
* 修复签到图片中信息并未使用配置文件中的色图概率
* 修改原神大地图合成方式,改为先压缩再合成
* bag_user弃用字段props(该字段会在下次更新删除),使用新字段property
* 数据库中所有belonging_group统一修改为group_id
* 商店将registered_use和register_goods更名为register_use何register_goods
* 商品注册提供了kwargs参数提供:
* bot
* event
* 特殊字段
* “send_success_msg”(发送成功的交互信息->即:使用道具 {name} {num} 次成功)
* “_max_num_limit”(该道具单次使用的最多个数,默认1)
### 2022/1/5 \[v0.0.8.2]
* 提供金币消费hook,可在plugins2settings.yaml中配置该功能需要消费的金币
* 商店插件将作为内置插件移动至basic_plugins
* 商店插件通过export提供了方法,不需要修改商店插件代码添加商品数据和生效方法
* 修改了hook插件顺序,主要以auth_hook为主
* 修改商店图片样式
* 取消每次启动更新城市列表(首次除外),采用定时更新,加快bot启动速度
* 取消每次启动时截取今日素材,采用调用时截取保存,加快bot启动速度
* 更新色图时当图片404时会删除并替换
* 疫情消息回复改为图片
* 修复商店折扣和限时时间无法生效
* 修复原神玩家查询尘歌壶缺少图片
### 2021/12/26
* 修复群词条问题 空格 会被录入导致不断回复
* 修复米游社app替换api导致无法正常查询
### 2021/12/24
* 支持国际疫情数据查询 [@pull/99](https://github.com/HibiKier/zhenxun_bot/pull/99)
### 2021/12/20
* 只有发布小于存储时间的新动态/视频的时候才获取并推送 [@pull/96](https://github.com/HibiKier/zhenxun_bot/pull/96)
### 2021/12/16 \[v0.0.7.0]
* 提供了真寻群聊功能总开关和对应默认配置项,命令:休息吧 醒来
* 新增原神玩家查询,原神便笺查询
* 群功能管理提供全部开启/关闭命令:开启/关闭全部功能
* 提供主要数据自动备份,且提供自定义配置项
* 提供命令:关于,用于介绍Bot之类的
* 新增命令exec,用于执行sql语句
* 签到提供参数 "all",用于签到所有群聊
* Ban提醒提供cd
* 本地图库提供配置项SHOW_ID,用于设置发送图片时是否显示id
* 色图和PIX提供配置项SHOW_INFO,用于设置发送图片时是否显示图片信息
* 所有被动技能提供了进群默认状态配置项
* 修复添加权限第二种添加形式无法正确添加正确的权限
* 修复签到获取好感度卡时金币不会增加
* 修复当红包数量不合法时依旧扣除金币
* 修复金币红包再次使用塞红包时无法正确退回上次未开完的金币
* 修复 滴滴滴- 只包含图片时不会发送至管理员
* 修复添加权限等级错误
* 修复群词条以bot名称为开头时无法正确触发
* 修改了权限插件加载顺序防止小概率优先加载权限插件引起报错
* 本地图库新图库会统一建立在resource/img/image_management文件夹下,如果该文件夹内未找到图库,会从上级目录查找(即:resource/img/)
<br> <br>
__..... 更多更新信息请查看文档__ __..... 更多更新信息请查看文档__
+1 -1
View File
@@ -1 +1 @@
__version__: v0.1.6.3-fix1 __version__: v0.1.6.4
@@ -87,13 +87,13 @@ task_data = None
async def change_group_switch(cmd: str, group_id: int, is_super: bool = False): async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
global task_data
""" """
修改群功能状态 修改群功能状态
:param cmd: 功能名称 :param cmd: 功能名称
:param group_id: 群号 :param group_id: 群号
:param is_super: 是否位超级用户,超级用户用于私聊开关功能状态 :param is_super: 是否位超级用户,超级用户用于私聊开关功能状态
""" """
global task_data
if not task_data: if not task_data:
task_data = group_manager.get_task_data() task_data = group_manager.get_task_data()
group_help_file = DATA_PATH / "group_help" / f"{group_id}.png" group_help_file = DATA_PATH / "group_help" / f"{group_id}.png"
@@ -121,9 +121,9 @@ async def change_group_switch(cmd: str, group_id: int, is_super: bool = False):
if group_help_file.exists(): if group_help_file.exists():
group_help_file.unlink() group_help_file.unlink()
return f"已 {status} 全部功能!" return f"已 {status} 全部功能!"
if cmd in [task_data[x] for x in task_data.keys()]: if cmd.lower() in [task_data[x].lower() for x in task_data.keys()]:
type_ = "task" type_ = "task"
modules = [x for x in task_data.keys() if task_data[x] == cmd] modules = [x for x in task_data.keys() if task_data[x].lower() == cmd.lower()]
for module in modules: for module in modules:
if is_super: if is_super:
module = f"{module}:super" module = f"{module}:super"
+1 -1
View File
@@ -56,10 +56,10 @@ def _create_help_img(
for matcher in _matchers: for matcher in _matchers:
plugin_name = None plugin_name = None
_plugin = matcher.plugin _plugin = matcher.plugin
metadata = _plugin.metadata
if not _plugin: if not _plugin:
logger.warning(f"获取 功能:{matcher.plugin_name} 失败...") logger.warning(f"获取 功能:{matcher.plugin_name} 失败...")
continue continue
metadata = _plugin.metadata
_module = _plugin.module _module = _plugin.module
try: try:
plugin_name = metadata.name if metadata else _module.__getattribute__("__zx_plugin_name__") plugin_name = metadata.name if metadata else _module.__getattribute__("__zx_plugin_name__")
+2
View File
@@ -3,6 +3,7 @@ from nonebot.message import run_preprocessor, run_postprocessor, IgnoredExceptio
from models.friend_user import FriendUser from models.friend_user import FriendUser
from models.group_member_info import GroupInfoUser from models.group_member_info import GroupInfoUser
from models.bag_user import BagUser from models.bag_user import BagUser
from models.user_shop_gold_log import UserShopGoldLog
from utils.manager import ( from utils.manager import (
plugins2settings_manager, plugins2settings_manager,
admin_manager, admin_manager,
@@ -59,6 +60,7 @@ async def _(matcher: Matcher, bot: Bot, event: Event, state: T_State):
if await BagUser.get_gold(event.user_id, event.group_id) < cost_gold: if await BagUser.get_gold(event.user_id, event.group_id) < cost_gold:
await send_msg(f"金币不足..该功能需要{cost_gold}金币..", bot, event) await send_msg(f"金币不足..该功能需要{cost_gold}金币..", bot, event)
raise IgnoredException(f"{module} 金币限制...") raise IgnoredException(f"{module} 金币限制...")
await UserShopGoldLog.add_shop_log(event.user_id, event.group_id, 2, matcher.plugin_name, cost_gold, 1)
# 当插件不阻塞超级用户时,超级用户提前扣除金币 # 当插件不阻塞超级用户时,超级用户提前扣除金币
if ( if (
str(event.user_id) in bot.config.superusers str(event.user_id) in bot.config.superusers
@@ -1,8 +1,8 @@
from pathlib import Path
from ruamel.yaml import YAML from ruamel.yaml import YAML
from utils.manager import plugins_manager from utils.manager import plugins_manager
from utils.utils import get_matchers from utils.utils import get_matchers
import nonebot from services.log import logger
try: try:
import ujson as json import ujson as json
@@ -43,54 +43,57 @@ def init_plugins_data(data_path):
matcher.plugin_name, "version", plugin_data.get("version") matcher.plugin_name, "version", plugin_data.get("version")
) )
else: else:
plugin_version = None try:
if metadata: plugin_version = None
plugin_version = metadata.extra.get("version") if metadata:
if not plugin_version: plugin_version = metadata.extra.get("version")
if not plugin_version:
try:
plugin_version = _module.__getattribute__("__plugin_version__")
except AttributeError:
pass
if metadata:
plugin_name = metadata.name
else:
try:
plugin_name = _module.__getattribute__("__zx_plugin_name__")
except AttributeError:
plugin_name = matcher.plugin_name
plugin_author = None
if metadata:
plugin_author = metadata.extra.get('author')
try: try:
plugin_version = _module.__getattribute__("__plugin_version__") plugin_author = _module.__getattribute__("__plugin_author__")
except AttributeError: except AttributeError:
pass pass
if metadata: if matcher.plugin_name in plugins_manager.keys():
plugin_name = metadata.name plugins_manager.set_module_data(matcher.plugin_name, "error", False)
else: if matcher.plugin_name not in plugins_manager.keys():
try: plugins_manager.add_plugin_data(
plugin_name = _module.__getattribute__("__zx_plugin_name__") matcher.plugin_name,
except AttributeError: plugin_name=plugin_name,
plugin_name = matcher.plugin_name author=plugin_author,
plugin_author = None version=plugin_version,
if metadata: )
plugin_author = metadata.extra.get('author') # metadata不检测version
try: elif isinstance(plugin_version, str) or plugins_manager[matcher.plugin_name]["version"] is None or (
plugin_author = _module.__getattribute__("__plugin_author__") plugin_version is not None
except AttributeError: and plugin_version > float(plugins_manager[matcher.plugin_name]["version"])
pass ):
if matcher.plugin_name in plugins_manager.keys(): plugins_manager.set_module_data(
plugins_manager.set_module_data(matcher.plugin_name, "error", False) matcher.plugin_name, "plugin_name", plugin_name
if matcher.plugin_name not in plugins_manager.keys(): )
plugins_manager.add_plugin_data( plugins_manager.set_module_data(matcher.plugin_name, "author", plugin_author)
matcher.plugin_name, plugins_manager.set_module_data(
plugin_name=plugin_name, matcher.plugin_name, "version", plugin_version
author=plugin_author, )
version=plugin_version, if matcher.plugin_name in _data.keys():
) plugins_manager.set_module_data(
# metadata不检测version matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
elif isinstance(plugin_version, str) or plugins_manager[matcher.plugin_name]["version"] is None or ( )
plugin_version is not None plugins_manager.set_module_data(
and plugin_version > plugins_manager[matcher.plugin_name]["version"] matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
): )
plugins_manager.set_module_data( except Exception as e:
matcher.plugin_name, "plugin_name", plugin_name logger.error(f"插件数据 {matcher.plugin_name} 加载发生错误 {type(e)}:{e}")
)
plugins_manager.set_module_data(matcher.plugin_name, "author", plugin_author)
plugins_manager.set_module_data(
matcher.plugin_name, "version", plugin_version
)
if matcher.plugin_name in _data.keys():
plugins_manager.set_module_data(
matcher.plugin_name, "error", _data[matcher.plugin_name]["error"]
)
plugins_manager.set_module_data(
matcher.plugin_name, "plugin_name", _data[matcher.plugin_name]["plugin_name"]
)
plugins_manager.save() plugins_manager.save()
+1 -1
View File
@@ -15,7 +15,7 @@ from configs.path_config import TEXT_PATH
from asyncio.exceptions import TimeoutError from asyncio.exceptions import TimeoutError
from typing import List from typing import List
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx
from utils.manager import GDict from utils.utils import GDict
from utils.utils import scheduler from utils.utils import scheduler
import nonebot import nonebot
+17 -6
View File
@@ -1,4 +1,6 @@
from nonebot import on_command from nonebot import on_command
from models.user_shop_gold_log import UserShopGoldLog
from services.log import logger from services.log import logger
from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message from nonebot.adapters.onebot.v11 import GroupMessageEvent, Message
from nonebot.params import CommandArg from nonebot.params import CommandArg
@@ -46,10 +48,7 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
for x in await GoodsInfo.get_all_goods() for x in await GoodsInfo.get_all_goods()
if x.goods_limit_time > time.time() or x.goods_limit_time == 0 if x.goods_limit_time > time.time() or x.goods_limit_time == 0
] ]
goods_name_list = [ goods_name_list = [x.goods_name for x in goods_list]
x.goods_name
for x in goods_list
]
msg = arg.extract_plain_text().strip().split() msg = arg.extract_plain_text().strip().split()
num = 1 num = 1
if len(msg) > 1: if len(msg) > 1:
@@ -77,11 +76,15 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
await BagUser.get_gold(event.user_id, event.group_id) await BagUser.get_gold(event.user_id, event.group_id)
) < goods.goods_price * num * goods.goods_discount: ) < goods.goods_price * num * goods.goods_discount:
await buy.finish("您的金币好像不太够哦", at_sender=True) await buy.finish("您的金币好像不太够哦", at_sender=True)
flag, n = await GoodsInfo.check_user_daily_purchase(goods, event.user_id, event.group_id, num) flag, n = await GoodsInfo.check_user_daily_purchase(
goods, event.user_id, event.group_id, num
)
if flag: if flag:
await buy.finish(f"该次购买将超过每日次数限制,目前该道具还可以购买{n}次哦", at_sender=True) await buy.finish(f"该次购买将超过每日次数限制,目前该道具还可以购买{n}次哦", at_sender=True)
if await BagUser.buy_property(event.user_id, event.group_id, goods, num): if await BagUser.buy_property(event.user_id, event.group_id, goods, num):
await GoodsInfo.add_user_daily_purchase(goods, event.user_id, event.group_id, num) await GoodsInfo.add_user_daily_purchase(
goods, event.user_id, event.group_id, num
)
await buy.send( await buy.send(
f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!", f"花费 {goods.goods_price * num * goods.goods_discount} 金币购买 {goods.goods_name} ×{num} 成功!",
at_sender=True, at_sender=True,
@@ -90,6 +93,14 @@ async def _(event: GroupMessageEvent, arg: Message = CommandArg()):
f"USER {event.user_id} GROUP {event.group_id} " f"USER {event.user_id} GROUP {event.group_id} "
f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 成功!" f"花费 {goods.goods_price*num} 金币购买 {goods.goods_name} ×{num} 成功!"
) )
await UserShopGoldLog.add_shop_log(
event.user_id,
event.group_id,
0,
goods.goods_name,
num,
goods.goods_price * num * goods.goods_discount,
)
else: else:
await buy.send(f"{goods.goods_name} 购买失败!", at_sender=True) await buy.send(f"{goods.goods_name} 购买失败!", at_sender=True)
logger.info( logger.info(
@@ -1,4 +1,7 @@
from nonebot import on_command from nonebot import on_command
from utils.message_builder import image
from ._data_source import create_bag_image
from services.log import logger from services.log import logger
from nonebot.adapters.onebot.v11 import GroupMessageEvent from nonebot.adapters.onebot.v11 import GroupMessageEvent
from models.bag_user import BagUser from models.bag_user import BagUser
@@ -32,10 +35,11 @@ my_props = on_command("我的道具", priority=5, block=True, permission=GROUP)
async def _(event: GroupMessageEvent): async def _(event: GroupMessageEvent):
props = await BagUser.get_property(event.user_id, event.group_id) props = await BagUser.get_property(event.user_id, event.group_id)
if props: if props:
rst = "" await my_props.send(image(b64=await create_bag_image(props)))
for i, p in enumerate(props.keys()): # rst = ""
rst += f"{i+1}.{p}\t×{props[p]}\n" # for i, p in enumerate(props.keys()):
await my_props.send("\n" + rst[:-1], at_sender=True) # rst += f"{i+1}.{p}\t×{props[p]}\n"
# await my_props.send("\n" + rst[:-1], at_sender=True)
logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具") logger.info(f"USER {event.user_id} GROUP {event.group_id} 查看我的道具")
else: else:
await my_props.finish("您的背包里没有任何的道具噢~", at_sender=True) await my_props.finish("您的背包里没有任何的道具噢~", at_sender=True)
+121
View File
@@ -0,0 +1,121 @@
from typing import Dict, List, Optional
from models.bag_user import BagUser
from models.goods_info import GoodsInfo
from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH
icon_path = IMAGE_PATH / "shop_icon"
async def create_bag_image(props: Dict[str, int]):
"""
说明:
创建背包道具图片
参数:
:param props: 道具仓库字典
"""
goods_list = await GoodsInfo.get_all_goods()
active_props = await _init_prop(props, [x for x in goods_list if not x.is_passive])
passive_props = await _init_prop(props, [x for x in goods_list if x.is_passive])
active_w = 0
active_h = 0
passive_w = 0
passive_h = 0
if active_props:
img = BuildImage(
active_props.w,
active_props.h + 70,
font="CJGaoDeGuo.otf",
font_size=30,
color="#f9f6f2",
)
await img.apaste(active_props, (0, 70))
await img.atext((0, 30), "主动道具")
active_props = img
active_w = img.w
active_h = img.h
if passive_props:
img = BuildImage(
passive_props.w,
passive_props.h + 70,
font="CJGaoDeGuo.otf",
font_size=30,
color="#f9f6f2",
)
await img.apaste(passive_props, (0, 70))
await img.atext((0, 30), "被动道具")
passive_props = img
passive_w = img.w
passive_h = img.h
A = BuildImage(
active_w + passive_w + 100,
max(active_h, passive_h) + 60,
font="CJGaoDeGuo.otf",
font_size=30,
color="#f9f6f2",
)
curr_w = 50
if active_props:
await A.apaste(active_props, (curr_w, 0))
curr_w += active_props.w + 10
if passive_props:
await A.apaste(passive_props, (curr_w, 0))
if active_props and passive_props:
await A.aline(
(active_props.w + 45, 70, active_props.w + 45, A.h - 20), fill=(0, 0, 0)
)
return A.pic2bs4()
async def _init_prop(
props: Dict[str, int], _props: List[GoodsInfo]
) -> Optional[BuildImage]:
"""
说明:
构造道具列表图片
参数:
:param props: 道具仓库字典
:param _props: 道具列表
"""
active_name = [x.goods_name for x in _props]
name_list = [x for x in props.keys() if x in active_name]
if not name_list:
return None
temp_img = BuildImage(0, 0, font_size=20)
image_list = []
num_list = []
for i, name in enumerate(name_list):
img = BuildImage(
temp_img.getsize(name)[0] + 50,
30,
font="msyh.ttf",
font_size=20,
color="#f9f6f2",
)
await img.atext((30, 5), f"{i + 1}.{name}")
goods = [x for x in _props if x.goods_name == name][0]
if goods.icon and (icon_path / goods.icon).exists():
icon = BuildImage(30, 30, background=icon_path / goods.icon)
await img.apaste(icon, alpha=True)
image_list.append(img)
num_list.append(
BuildImage(
30, 30, font_size=20, font="msyh.ttf", plain_text=f"×{props[name]}"
)
)
max_w = 0
num_max_w = 0
h = 0
for img, num in zip(image_list, num_list):
h += img.h
max_w = max_w if max_w > img.w else img.w
num_max_w = num_max_w if num_max_w > num.w else num.w
A = BuildImage(max_w + num_max_w + 30, h, color="#f9f6f2")
curr_h = 0
for img, num in zip(image_list, num_list):
await A.apaste(img, (0, curr_h))
await A.apaste(num, (max_w + 20, curr_h + 5), True)
curr_h += img.h
return A
@@ -6,7 +6,6 @@ from utils.message_builder import image
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from utils.utils import is_number, scheduler from utils.utils import is_number, scheduler
from nonebot.params import CommandArg from nonebot.params import CommandArg
from nonebot.plugin import export
from services.log import logger from services.log import logger
import os import os
@@ -51,11 +50,6 @@ __plugin_block_limit__ = {
"limit_type": "group" "limit_type": "group"
} }
# 导出方法供其他插件使用
export = export()
export.register_goods = register_goods
export.delete_goods = delete_goods
export.update_goods = update_goods
shop_help = on_command("商店", priority=5, block=True) shop_help = on_command("商店", priority=5, block=True)
+24 -44
View File
@@ -2,49 +2,17 @@ from PIL import Image
from models.goods_info import GoodsInfo from models.goods_info import GoodsInfo
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from models.sign_group_user import SignGroupUser
from utils.utils import is_number from utils.utils import is_number
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from typing import Optional, Union, Tuple from typing import Optional, Union, Tuple
from configs.config import Config from utils.utils import GDict
from nonebot import Driver
from nonebot.plugin import require
from utils.decorator.shop import shop_register
import nonebot
import time import time
driver: Driver = nonebot.get_driver() icon_path = IMAGE_PATH / 'shop_icon'
use = require("use") GDict['run_sql'].append("ALTER TABLE goods_info ADD is_passive boolean DEFAULT False;")
GDict['run_sql'].append("ALTER TABLE goods_info ADD icon VARCHAR(255);")
@driver.on_startup
async def init_default_shop_goods():
"""
导入内置的三个商品
"""
@shop_register(
name=("好感度双倍加持卡Ⅰ", "好感度双倍加持卡Ⅱ", "好感度双倍加持卡Ⅲ"),
price=(30, 150, 250),
des=(
"下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)",
"下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)",
"下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)",
),
load_status=Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"),
daily_limit=(10, 20, 30),
** {"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
)
async def sign_card(user_id: int, group_id: int, prob: float):
user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=prob).apply()
@driver.on_bot_connect
async def _():
await shop_register.load_register()
# 创建商店界面 # 创建商店界面
@@ -63,7 +31,7 @@ async def create_shop_help() -> str:
if goods.goods_limit_time == 0 or time.time() < goods.goods_limit_time: if goods.goods_limit_time == 0 or time.time() < goods.goods_limit_time:
h += len(goods.goods_description.strip().split("\n")) * font_h + 80 h += len(goods.goods_description.strip().split("\n")) * font_h + 80
_list.append(goods) _list.append(goods)
A = BuildImage(1000, h, color="#f9f6f2") A = BuildImage(1100, h, color="#f9f6f2")
current_h = 0 current_h = 0
total_n = 0 total_n = 0
for goods in _list: for goods in _list:
@@ -106,9 +74,12 @@ async def create_shop_help() -> str:
await goods_image.apaste(name_image, (0, 5), True, center_type="by_width") await goods_image.apaste(name_image, (0, 5), True, center_type="by_width")
await goods_image.atext((15, 50), f"简介:{goods.goods_description}") await goods_image.atext((15, 50), f"简介:{goods.goods_description}")
await goods_image.acircle_corner(20) await goods_image.acircle_corner(20)
await bk.apaste(goods_image, alpha=True) if goods.icon and (icon_path / goods.icon).exists():
icon = BuildImage(100, 100, background=icon_path / goods.icon)
await bk.apaste(icon)
await bk.apaste(goods_image, (100, 0), alpha=True)
n = 0 n = 0
_w = 550 _w = 650
# 添加限时图标和时间 # 添加限时图标和时间
if goods.goods_limit_time > 0: if goods.goods_limit_time > 0:
n += 140 n += 140
@@ -162,14 +133,14 @@ async def create_shop_help() -> str:
if total_n < n: if total_n < n:
total_n = n total_n = n
if n: if n:
await bk.aline((550, -1, 550 + n, -1), "#a29ad6", 5) await bk.aline((650, -1, 650 + n, -1), "#a29ad6", 5)
await bk.aline((550, 80, 550 + n, 80), "#a29ad6", 5) await bk.aline((650, 80, 650 + n, 80), "#a29ad6", 5)
# 添加限时图标和时间 # 添加限时图标和时间
idx += 1 idx += 1
await A.apaste(bk, (0, current_h), True) await A.apaste(bk, (0, current_h), True)
current_h += 90 current_h += 90
w = 850 w = 950
if total_n: if total_n:
w += total_n w += total_n
h = A.h + 230 + 100 h = A.h + 230 + 100
@@ -197,6 +168,8 @@ async def register_goods(
discount: Optional[float] = 1, discount: Optional[float] = 1,
limit_time: Optional[int] = 0, limit_time: Optional[int] = 0,
daily_limit: Optional[int] = 0, daily_limit: Optional[int] = 0,
is_passive: Optional[bool] = False,
icon: Optional[str] = None,
) -> bool: ) -> bool:
""" """
添加商品 添加商品
@@ -209,6 +182,8 @@ async def register_goods(
:param discount: 商品折扣 :param discount: 商品折扣
:param limit_time: 商品限时销售时间,单位为小时 :param limit_time: 商品限时销售时间,单位为小时
:param daily_limit: 每日购买次数限制 :param daily_limit: 每日购买次数限制
:param is_passive: 是否为被动
:param icon: 图标
:return: 是否添加成功 :return: 是否添加成功
""" """
if not await GoodsInfo.get_goods_info(name): if not await GoodsInfo.get_goods_info(name):
@@ -220,7 +195,7 @@ async def register_goods(
else 0 else 0
) )
return await GoodsInfo.add_goods( return await GoodsInfo.add_goods(
name, int(price), des, float(discount), limit_time, daily_limit name, int(price), des, float(discount), limit_time, daily_limit, is_passive, icon
) )
return False return False
@@ -272,6 +247,7 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
discount = goods.goods_discount discount = goods.goods_discount
limit_time = goods.goods_limit_time limit_time = goods.goods_limit_time
daily_limit = goods.daily_limit daily_limit = goods.daily_limit
is_passive = goods.is_passive
new_time = 0 new_time = 0
tmp = "" tmp = ""
if kwargs.get("price"): if kwargs.get("price"):
@@ -294,6 +270,9 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
if kwargs.get("daily_limit"): if kwargs.get("daily_limit"):
tmp += f'每日购买限制:{daily_limit} --> {kwargs["daily_limit"]}\n' if daily_limit else "取消了购买限制\n" tmp += f'每日购买限制:{daily_limit} --> {kwargs["daily_limit"]}\n' if daily_limit else "取消了购买限制\n"
daily_limit = int(kwargs["daily_limit"]) daily_limit = int(kwargs["daily_limit"])
if kwargs.get("is_passive"):
tmp += f'被动道具:{is_passive} --> {kwargs["is_passive"]}\n'
des = kwargs["is_passive"]
await GoodsInfo.update_goods( await GoodsInfo.update_goods(
name, name,
int(price), int(price),
@@ -304,7 +283,8 @@ async def update_goods(**kwargs) -> Tuple[bool, str, str]:
if limit_time != 0 and new_time if limit_time != 0 and new_time
else 0 else 0
), ),
daily_limit daily_limit,
is_passive
) )
return True, name, tmp[:-1], return True, name, tmp[:-1],
+28 -20
View File
@@ -1,13 +1,16 @@
from nonebot import on_command from nonebot import on_command
from models.user_shop_gold_log import UserShopGoldLog
from services.log import logger from services.log import logger
from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message from nonebot.adapters.onebot.v11 import Bot, GroupMessageEvent, Message
from nonebot.params import CommandArg from nonebot.params import CommandArg
from utils.decorator.shop import NotMeetUseConditionsException
from utils.utils import is_number from utils.utils import is_number
from models.bag_user import BagUser from models.bag_user import BagUser
from nonebot.adapters.onebot.v11.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from services.db_context import db from services.db_context import db
from nonebot.plugin import export from .data_source import effect, register_use, func_manager, build_params
from .data_source import effect, register_use, func_manager
__zx_plugin_name__ = "商店 - 使用道具" __zx_plugin_name__ = "商店 - 使用道具"
@@ -30,9 +33,6 @@ __plugin_settings__ = {
"cmd": ["商店", "使用道具"], "cmd": ["商店", "使用道具"],
} }
# 导出方法供其他插件使用
export = export()
export.register_use = register_use
use_props = on_command("使用道具", priority=5, block=True, permission=GROUP) use_props = on_command("使用道具", priority=5, block=True, permission=GROUP)
@@ -45,23 +45,29 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
if len(msg_sp) > 1 and is_number(msg_sp[-1]) and int(msg_sp[-1]) > 0: if len(msg_sp) > 1 and is_number(msg_sp[-1]) and int(msg_sp[-1]) > 0:
num = int(msg.split()[-1]) num = int(msg.split()[-1])
msg = " ".join(msg.split()[:-1]) msg = " ".join(msg.split()[:-1])
property_ = await BagUser.get_property(event.user_id, event.group_id) property_ = await BagUser.get_property(event.user_id, event.group_id, True)
if property_: if property_:
async with db.transaction(): name = None
if is_number(msg): if is_number(msg):
if 0 < int(msg) <= len(property_): if 0 < int(msg) <= len(property_):
name = list(property_.keys())[int(msg) - 1] name = list(property_.keys())[int(msg) - 1]
else:
await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
else: else:
if msg not in property_.keys(): await use_props.finish("仔细看看自己的道具仓库有没有这个道具?", at_sender=True)
await use_props.finish("道具名称错误!", at_sender=True) else:
name = msg if msg not in property_.keys():
_user_prop_count = property_[name] await use_props.finish("道具名称错误!", at_sender=True)
if num > _user_prop_count: name = msg
await use_props.finish(f"道具数量不足,无法使用{num}次!") _user_prop_count = property_[name]
if num > (n := func_manager.get_max_num_limit(name)): if num > _user_prop_count:
await use_props.finish(f"该道具单次只能使用 {n} 个!") await use_props.finish(f"道具数量不足,无法使用{num}次!")
if num > (n := func_manager.get_max_num_limit(name)):
await use_props.finish(f"该道具单次只能使用 {n} 个!")
model, kwargs = build_params(bot, event, name, num)
try:
await func_manager.run_handle(type_="before_handle", param=model, **kwargs)
except NotMeetUseConditionsException as e:
await use_props.finish(e.get_info(), at_sender=True)
async with db.transaction():
if await BagUser.delete_property( if await BagUser.delete_property(
event.user_id, event.group_id, name, num event.user_id, event.group_id, name, num
): ):
@@ -72,10 +78,12 @@ async def _(bot: Bot, event: GroupMessageEvent, arg: Message = CommandArg()):
logger.info( logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功" f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次成功"
) )
await UserShopGoldLog.add_shop_log(event.user_id, event.group_id, 1, name, num)
else: else:
await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True) await use_props.send(f"使用道具 {name} {num} 次失败!", at_sender=True)
logger.info( logger.info(
f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败" f"USER {event.user_id} GROUP {event.group_id} 使用道具 {name} {num} 次失败"
) )
await func_manager.run_handle(type_="after_handle", param=model, **kwargs)
else: else:
await use_props.send("您的背包里没有任何的道具噢", at_sender=True) await use_props.send("您的背包里没有任何的道具噢", at_sender=True)
+90 -31
View File
@@ -3,7 +3,7 @@ from services.log import logger
from nonebot.adapters.onebot.v11 import Bot from nonebot.adapters.onebot.v11 import Bot
from pydantic import create_model from pydantic import create_model
from utils.models import ShopParam from utils.models import ShopParam
from typing import Optional, Union from typing import Optional, Union, Callable, List, Tuple, Dict, Any
from types import MappingProxyType from types import MappingProxyType
import inspect import inspect
import asyncio import asyncio
@@ -13,6 +13,30 @@ class GoodsUseFuncManager:
def __init__(self): def __init__(self):
self._data = {} self._data = {}
def register_use_before_handle(self, goods_name: str, fun_list: List[Callable]):
"""
说明:
注册商品使用前函数
参数:
:param goods_name: 商品名称
:param fun_list: 函数列表
"""
if fun_list:
self._data[goods_name]["before_handle"] = fun_list
logger.info(f"register_use_before_handle 成功注册商品:{goods_name} 的{len(fun_list)}个使用前函数")
def register_use_after_handle(self, goods_name: str, fun_list: List[Callable]):
"""
说明:
注册商品使用后函数
参数:
:param goods_name: 商品名称
:param fun_list: 函数列表
"""
if fun_list:
self._data[goods_name]["after_handle"] = fun_list
logger.info(f"register_use_after_handle 成功注册商品:{goods_name} 的{len(fun_list)}个使用后函数")
def register_use(self, goods_name: str, **kwargs): def register_use(self, goods_name: str, **kwargs):
""" """
注册商品使用方法 注册商品使用方法
@@ -26,7 +50,7 @@ class GoodsUseFuncManager:
判断商品使用方法是否被注册 判断商品使用方法是否被注册
:param goods_name: 商品名称 :param goods_name: 商品名称
""" """
return bool(self ._data.get(goods_name)) return bool(self._data.get(goods_name))
def get_max_num_limit(self, goods_name: str) -> int: def get_max_num_limit(self, goods_name: str) -> int:
""" """
@@ -37,6 +61,21 @@ class GoodsUseFuncManager:
return self._data[goods_name]["kwargs"]["max_num_limit"] return self._data[goods_name]["kwargs"]["max_num_limit"]
return 1 return 1
def _parse_args(self, args_: MappingProxyType, param: ShopParam, **kwargs):
param_list_ = []
_bot = param.bot
param.bot = None
param_json = param.dict()
param_json["bot"] = _bot
for par in args_.keys():
if par in ["shop_param"]:
param_list_.append(param)
elif par not in ["args", "kwargs"]:
param_list_.append(param_json.get(par))
if kwargs.get(par) is not None:
del kwargs[par]
return param_list_
async def use( async def use(
self, param: ShopParam, **kwargs self, param: ShopParam, **kwargs
) -> Optional[Union[str, MessageSegment]]: ) -> Optional[Union[str, MessageSegment]]:
@@ -45,31 +84,18 @@ class GoodsUseFuncManager:
:param param: BaseModel :param param: BaseModel
:param kwargs: kwargs :param kwargs: kwargs
""" """
def parse_args(args_: MappingProxyType):
param_list_ = []
_bot = param.bot
param.bot = None
param_json = param.dict()
param_json["bot"] = _bot
for par in args_.keys():
if par in ["shop_param"]:
param_list_.append(param)
elif par not in ["args", "kwargs"]:
param_list_.append(param_json.get(par))
if kwargs.get(par) is not None:
del kwargs[par]
return param_list_
goods_name = param.goods_name goods_name = param.goods_name
if self.exists(goods_name): if self.exists(goods_name):
# 使用方法
args = inspect.signature(self._data[goods_name]["func"]).parameters args = inspect.signature(self._data[goods_name]["func"]).parameters
if args and list(args.keys())[0] != "kwargs": if args and list(args.keys())[0] != "kwargs":
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]): if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
return await self._data[goods_name]["func"]( return await self._data[goods_name]["func"](
*parse_args(args) *self._parse_args(args, param, **kwargs)
) )
else: else:
return self._data[goods_name]["func"]( return self._data[goods_name]["func"](
*parse_args(args) *self._parse_args(args, param, **kwargs)
) )
else: else:
if asyncio.iscoroutinefunction(self._data[goods_name]["func"]): if asyncio.iscoroutinefunction(self._data[goods_name]["func"]):
@@ -81,6 +107,21 @@ class GoodsUseFuncManager:
**kwargs, **kwargs,
) )
async def run_handle(self, goods_name: str, type_: str, param: ShopParam, **kwargs):
if self._data[goods_name].get(type_):
for func in self._data[goods_name].get(type_):
args = inspect.signature(func).parameters
if args and list(args.keys())[0] != "kwargs":
if asyncio.iscoroutinefunction(func):
await func(*self._parse_args(args, param, **kwargs))
else:
func(*self._parse_args(args, param, **kwargs))
else:
if asyncio.iscoroutinefunction(func):
await func(**kwargs)
else:
func(**kwargs)
def check_send_success_message(self, goods_name: str) -> bool: def check_send_success_message(self, goods_name: str) -> bool:
""" """
检查是否发送使用成功信息 检查是否发送使用成功信息
@@ -115,6 +156,34 @@ class GoodsUseFuncManager:
func_manager = GoodsUseFuncManager() func_manager = GoodsUseFuncManager()
def build_params(
bot: Bot, event: GroupMessageEvent, goods_name: str, num: int
) -> Tuple[ShopParam, Dict[str, Any]]:
"""
说明:
构造参数
参数:
:param bot: bot
:param event: event
:param goods_name: 商品名称
:param num: 数量
:return:
"""
_kwargs = func_manager.get_kwargs(goods_name)
return (
func_manager.init_model(goods_name, bot, event, num),
{
**_kwargs,
"_bot": bot,
"event": event,
"group_id": event.group_id,
"user_id": event.user_id,
"num": num,
"goods_name": goods_name,
},
)
async def effect( async def effect(
bot: Bot, event: GroupMessageEvent, goods_name: str, num: int bot: Bot, event: GroupMessageEvent, goods_name: str, num: int
) -> Optional[Union[str, MessageSegment]]: ) -> Optional[Union[str, MessageSegment]]:
@@ -130,24 +199,14 @@ async def effect(
# try: # try:
if func_manager.exists(goods_name): if func_manager.exists(goods_name):
_kwargs = func_manager.get_kwargs(goods_name) _kwargs = func_manager.get_kwargs(goods_name)
return await func_manager.use( model, kwargs = build_params(bot, event, goods_name, num)
func_manager.init_model(goods_name, bot, event, num), return await func_manager.use(model, **kwargs)
**{
**_kwargs,
"_bot": bot,
"event": event,
"group_id": event.group_id,
"user_id": event.user_id,
"num": num,
"goods_name": goods_name,
},
)
# except Exception as e: # except Exception as e:
# logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}") # logger.error(f"use 商品生效函数effect 发生错误 {type(e)}:{e}")
return None return None
def register_use(goods_name: str, func, **kwargs): def register_use(goods_name: str, func: Callable, **kwargs):
""" """
注册商品使用方法 注册商品使用方法
:param goods_name: 商品名称 :param goods_name: 商品名称
+9 -1
View File
@@ -2,6 +2,7 @@ from services.db_context import db
from typing import Dict from typing import Dict
from typing import Optional, List from typing import Optional, List
from services.log import logger from services.log import logger
from .goods_info import GoodsInfo
class BagUser(db.Model): class BagUser(db.Model):
@@ -62,17 +63,24 @@ class BagUser(db.Model):
return 100 return 100
@classmethod @classmethod
async def get_property(cls, user_qq: int, group_id: int) -> Dict[str, int]: async def get_property(cls, user_qq: int, group_id: int, only_active: bool = False) -> Dict[str, int]:
""" """
说明: 说明:
获取当前道具 获取当前道具
参数: 参数:
:param user_qq: qq号 :param user_qq: qq号
:param group_id: 所在群号 :param group_id: 所在群号
:param only_active: 仅仅获取主动使用的道具
""" """
query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id)) query = cls.query.where((cls.user_qq == user_qq) & (cls.group_id == group_id))
user = await query.gino.first() user = await query.gino.first()
if user: if user:
if only_active and user.property:
data = {}
name_list = [x.goods_name for x in await GoodsInfo.get_all_goods() if not x.is_passive]
for key in [x for x in user.property.keys() if x in name_list]:
data[key] = user.property[key]
return data
return user.property return user.property
else: else:
await cls.create( await cls.create(
+16 -2
View File
@@ -16,6 +16,8 @@ class GoodsInfo(db.Model):
daily_purchase_limit = db.Column( daily_purchase_limit = db.Column(
db.JSON(), nullable=False, default={} db.JSON(), nullable=False, default={}
) # 每日购买限制数据存储 ) # 每日购买限制数据存储
is_passive = db.Column(db.Boolean(), nullable=False, default=0) # 是否为被动
icon = db.Column(db.String(), default=0) # 图标
_idx1 = db.Index("goods_group_users_idx1", "goods_name", unique=True) _idx1 = db.Index("goods_group_users_idx1", "goods_name", unique=True)
@@ -28,6 +30,8 @@ class GoodsInfo(db.Model):
goods_discount: float = 1, goods_discount: float = 1,
goods_limit_time: int = 0, goods_limit_time: int = 0,
daily_limit: int = 0, daily_limit: int = 0,
is_passive: bool = False,
icon: Optional[str] = None,
) -> bool: ) -> bool:
""" """
说明: 说明:
@@ -39,6 +43,8 @@ class GoodsInfo(db.Model):
:param goods_discount: 商品折扣 :param goods_discount: 商品折扣
:param goods_limit_time: 商品限时 :param goods_limit_time: 商品限时
:param daily_limit: 每日购买限制 :param daily_limit: 每日购买限制
:param is_passive: 是否为被动道具
:param icon: 图标
""" """
try: try:
if not await cls.get_goods_info(goods_name): if not await cls.get_goods_info(goods_name):
@@ -49,10 +55,12 @@ class GoodsInfo(db.Model):
goods_discount=goods_discount, goods_discount=goods_discount,
goods_limit_time=goods_limit_time, goods_limit_time=goods_limit_time,
daily_limit=daily_limit, daily_limit=daily_limit,
is_passive=is_passive,
icon=icon
) )
return True return True
except Exception as e: except Exception as e:
logger.error(f"GoodsInfo add_goods 发生错误 {type(e)}:{e}") logger.error(f"GoodsInfo add_goods {goods_name} 发生错误 {type(e)}:{e}")
return False return False
@classmethod @classmethod
@@ -81,7 +89,9 @@ class GoodsInfo(db.Model):
goods_description: Optional[str] = None, goods_description: Optional[str] = None,
goods_discount: Optional[float] = None, goods_discount: Optional[float] = None,
goods_limit_time: Optional[int] = None, goods_limit_time: Optional[int] = None,
daily_limit: Optional[int] = None daily_limit: Optional[int] = None,
is_passive: Optional[bool] = None,
icon: Optional[str] = None,
) -> bool: ) -> bool:
""" """
说明: 说明:
@@ -93,6 +103,8 @@ class GoodsInfo(db.Model):
:param goods_discount: 商品折扣 :param goods_discount: 商品折扣
:param goods_limit_time: 商品限时时间 :param goods_limit_time: 商品限时时间
:param daily_limit: 每日次数限制 :param daily_limit: 每日次数限制
:param is_passive: 是否为被动
:param icon: 图标
""" """
try: try:
query = ( query = (
@@ -108,6 +120,8 @@ class GoodsInfo(db.Model):
goods_discount=goods_discount or query.goods_discount, goods_discount=goods_discount or query.goods_discount,
goods_limit_time=goods_limit_time if goods_limit_time is not None else query.goods_limit_time, goods_limit_time=goods_limit_time if goods_limit_time is not None else query.goods_limit_time,
daily_limit=daily_limit if daily_limit is not None else query.daily_limit, daily_limit=daily_limit if daily_limit is not None else query.daily_limit,
is_passive=is_passive if is_passive is not None else query.is_passive,
icon=icon or query.icon
).apply() ).apply()
return True return True
except Exception as e: except Exception as e:
+59
View File
@@ -0,0 +1,59 @@
from datetime import datetime
from services.db_context import db
class UserShopGoldLog(db.Model):
__tablename__ = "user_shop_gold_log"
id = db.Column(db.Integer(), primary_key=True)
user_qq = db.Column(db.BigInteger(), nullable=False)
group_id = db.Column(db.BigInteger(), nullable=False)
type = db.Column(db.Integer(), nullable=False) # 0: 购买,1: 使用,2: 插件
name = db.Column(db.String())
spend_gold = db.Column(db.Integer(), nullable=False)
num = db.Column(db.Integer(), nullable=False)
create_time = db.Column(db.DateTime(timezone=True), nullable=False)
@classmethod
async def add_shop_log(
cls,
user_qq: int,
group_id: int,
type_: int,
name: str,
num: int,
spend_gold: int = 0,
):
"""
说明:
添加商店购买或使用日志
参数:
:param user_qq: qq号
:param group_id: 所在群号
:param type_: 类型
:param name: 商品名称
:param num: 数量
:param spend_gold: 花费金币
"""
await cls.create(
user_qq=user_qq,
group_id=group_id,
type=type_,
name=name,
num=num,
spend_gold=spend_gold,
create_time=datetime.now(),
)
@classmethod
async def get_user_log(cls, user_qq: int, group_id: int) -> "UserShopGoldLog":
"""
说明:
获取用户日志
参数:
:param user_qq: qq号
:param group_id: 所在群号
"""
return await cls.query.where(
(cls.user_qq == user_qq) & (cls.group_qq == group_id)
).first()
+9 -17
View File
@@ -7,11 +7,11 @@ from asyncio.exceptions import TimeoutError
from utils.utils import get_bot from utils.utils import get_bot
from .model import BilibiliSub from .model import BilibiliSub
from bilireq.live import get_room_info_by_id from bilireq.live import get_room_info_by_id
from .utils import get_meta from .utils import get_meta, get_user_card
from utils.message_builder import image from utils.message_builder import image
from bilireq.user import get_user_info from bilireq.user import get_videos
# from .utils import get_videos
from bilireq import dynamic from bilireq import dynamic
from .utils import get_videos
from typing import Optional, Tuple from typing import Optional, Tuple
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from datetime import datetime from datetime import datetime
@@ -83,7 +83,7 @@ async def add_up_sub(uid: int, sub_user: str) -> str:
async with db.transaction(): async with db.transaction():
try: try:
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法""" """bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
user_info = await get_user_info(uid) user_info = await get_user_card(uid)
except ResponseCodeError: except ResponseCodeError:
return f"未找到UpId:{uid} 的信息,请检查Id是否正确" return f"未找到UpId:{uid} 的信息,请检查Id是否正确"
uname = user_info["name"] uname = user_info["name"]
@@ -207,8 +207,8 @@ async def get_sub_status(id_: int, sub_type: str) -> Optional[str]:
return await _get_up_status(id_) return await _get_up_status(id_)
elif sub_type == "season": elif sub_type == "season":
return await _get_season_status(id_) return await _get_season_status(id_)
except ResponseCodeError: except ResponseCodeError as msg:
logger.error(f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试...") logger.info(f"Id:{id_} 获取信息失败...{msg}")
return None return None
# return f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试..." # return f"Id:{id_} 获取信息失败...请检查订阅Id是否存在或稍后再试..."
# except Exception as e: # except Exception as e:
@@ -249,7 +249,7 @@ async def _get_up_status(id_: int) -> Optional[str]:
""" """
_user = await BilibiliSub.get_sub(id_) _user = await BilibiliSub.get_sub(id_)
"""bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法""" """bilibili_api.user库中User类的get_user_info改为bilireq.user库的get_user_info方法"""
user_info = await get_user_info(_user.uid) user_info = await get_user_card(_user.uid)
uname = user_info["name"] uname = user_info["name"]
"""bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法""" """bilibili_api.user库中User类的get_videos改为bilireq.user库的get_videos方法"""
video_info = await get_videos(_user.uid) video_info = await get_videos(_user.uid)
@@ -349,16 +349,8 @@ async def get_user_dynamic(
await page.set_viewport_size( await page.set_viewport_size(
{"width": 2560, "height": 1080, "timeout": 10000 * 20} {"width": 2560, "height": 1080, "timeout": 10000 * 20}
) )
await page.wait_for_selector(".panel-area") await page.wait_for_selector(".bili-dyn-item__main")
await page.evaluate( card = page.locator(".bili-dyn-item__main")
"""
xs = document.getElementById('internationalHeader');
xs.remove();
xs = document.getElementsByClassName('panel-area')
xs[0].remove();
"""
)
card = page.locator(".detail-card")
await card.wait_for() await card.wait_for()
await card.screenshot( await card.screenshot(
path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg", path=dynamic_path / f"{local_user.sub_id}_{dynamic_upload_time}.jpg",
+45 -16
View File
@@ -1,14 +1,15 @@
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from configs.path_config import IMAGE_PATH from configs.path_config import IMAGE_PATH
from utils.http_utils import AsyncHttpx from utils.http_utils import AsyncHttpx, get_user_agent
# from bilibili_api import user # from bilibili_api import user
from bilireq.user import get_user_info from bilireq.user import get_user_info
from httpx import AsyncClient
from io import BytesIO from io import BytesIO
BORDER_PATH = IMAGE_PATH / "border" BORDER_PATH = IMAGE_PATH / "border"
BORDER_PATH.mkdir(parents=True, exist_ok=True) BORDER_PATH.mkdir(parents=True, exist_ok=True)
BASE_URL = "https://api.bilibili.com"
async def get_pic(url: str) -> bytes: async def get_pic(url: str) -> bytes:
""" """
@@ -78,7 +79,6 @@ async def get_meta(media_id: int, auth=None, reqtype="both", **kwargs):
""" """
from bilireq.utils import get from bilireq.utils import get
BASE_URL = "https://api.bilibili.com"
url = f"{BASE_URL}/pgc/review/user" url = f"{BASE_URL}/pgc/review/user"
params = {"media_id": media_id} params = {"media_id": media_id}
raw_json = await get(url, raw=True, params=params, auth=auth, reqtype=reqtype, **kwargs) raw_json = await get(url, raw=True, params=params, auth=auth, reqtype=reqtype, **kwargs)
@@ -86,8 +86,7 @@ async def get_meta(media_id: int, auth=None, reqtype="both", **kwargs):
async def get_videos( async def get_videos(
uid: int, tid: int = 0, pn: int = 1, keyword: str = "", order: str = "pubdate", uid: int, tid: int = 0, pn: int = 1, keyword: str = "", order: str = "pubdate"
*, auth=None, reqtype="both", **kwargs
): ):
""" """
获取用户投该视频信息 获取用户投该视频信息
@@ -100,15 +99,45 @@ async def get_videos(
:param keyword: 搜索关键词 :param keyword: 搜索关键词
:param order: 排序方式,可以为 “pubdate(上传日期从新到旧), stow(收藏从多到少), click(播放量从多到少)” :param order: 排序方式,可以为 “pubdate(上传日期从新到旧), stow(收藏从多到少), click(播放量从多到少)”
""" """
from bilireq.utils import get from bilireq.utils import ResponseCodeError
BASE_URL = "https://api.bilibili.com"
url = f"{BASE_URL}/x/space/arc/search" url = f"{BASE_URL}/x/space/arc/search"
params = { headers = get_user_agent()
"mid": uid, headers["Referer"] = f"https://space.bilibili.com/{uid}/video"
"ps": 30, async with AsyncClient() as client:
"tid": tid, r = await client.head(
"pn": pn, "https://space.bilibili.com",
"keyword": keyword, headers=headers,
"order": order )
} params = {
return await get(url, params=params, auth=auth, reqtype=reqtype, **kwargs) "mid": uid,
"ps": 30,
"tid": tid,
"pn": pn,
"keyword": keyword,
"order": order,
}
raw_json = (
await client.get(url, params=params, headers=headers, cookies=r.cookies)
).json()
if raw_json["code"] != 0:
raise ResponseCodeError(
code=raw_json["code"],
msg=raw_json["message"],
data=raw_json.get("data", None),
)
return raw_json["data"]
async def get_user_card(mid, photo: bool = False, auth=None, reqtype="both", **kwargs):
from bilireq.utils import get
url = f"{BASE_URL}/x/web-interface/card"
return (
await get(
url,
params={"mid": mid, "photo": photo},
auth=auth,
reqtype=reqtype,
**kwargs,
)
)["card"]
+5 -5
View File
@@ -1,4 +1,4 @@
from nonebot.adapters.onebot.v11 import Bot from nonebot.adapters.onebot.v11 import Bot, MessageEvent
from nonebot.permission import SUPERUSER from nonebot.permission import SUPERUSER
from nonebot import on_command from nonebot import on_command
from .data_source import check_update, get_latest_version_data from .data_source import check_update, get_latest_version_data
@@ -50,24 +50,24 @@ restart = on_command(
@update_zhenxun.handle() @update_zhenxun.handle()
async def _(bot: Bot): async def _(bot: Bot, event: MessageEvent):
try: try:
code, error = await check_update(bot) code, error = await check_update(bot)
if error: if error:
logger.error(f"更新真寻未知错误 {error}") logger.error(f"更新真寻未知错误 {error}")
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"更新真寻未知错误 {error}" user_id=event.user_id, message=f"更新真寻未知错误 {error}"
) )
except Exception as e: except Exception as e:
logger.error(f"更新真寻未知错误 {type(e)}:{e}") logger.error(f"更新真寻未知错误 {type(e)}:{e}")
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), user_id=event.user_id,
message=f"更新真寻未知错误 {type(e)}:{e}", message=f"更新真寻未知错误 {type(e)}:{e}",
) )
else: else:
if code == 200: if code == 200:
await bot.send_private_msg( await bot.send_private_msg(
user_id=int(list(bot.config.superusers)[0]), message=f"更新完毕,请重启真寻...." user_id=event.user_id, message=f"更新完毕,请重启真寻...."
) )
+56 -10
View File
@@ -1,4 +1,6 @@
import random import random
import json
from utils.http_utils import AsyncHttpx
from lxml import etree from lxml import etree
from typing import List, Tuple from typing import List, Tuple
from PIL import ImageDraw from PIL import ImageDraw
@@ -107,27 +109,70 @@ class BaHandle(BaseHandle[BaChar]):
else: else:
return 1 return 1
# Bwiki 待恢复
# async def _update_info(self):
# info = {}
# url = "https://wiki.biligame.com/bluearchive/学生筛选"
# result = await self.get_url(url)
# if not result:
# logger.warning(f"更新 {self.game_name_cn} 出错")
# return
# else:
# dom = etree.HTML(result, etree.HTMLParser())
# char_list = dom.xpath("//div[@class='filters']/table[2]/tbody/tr")
# for char in char_list:
# try:
# name = char.xpath("./td[2]/a/div/text()")[0]
# avatar = char.xpath("./td[1]/div/div/a/img/@data-src")[0]
# star_pic = char.xpath("./td[4]/img/@alt")[0]
# except IndexError:
# continue
# member_dict = {
# "头像": unquote(str(avatar)),
# "名称": remove_prohibited_str(name),
# "星级": self.title2star(star_pic),
# }
# info[member_dict["名称"]] = member_dict
# self.dump_data(info)
# logger.info(f"{self.game_name_cn} 更新成功")
# # 下载头像
# for value in info.values():
# await self.download_img(value["头像"], value["名称"])
# # 下载星星
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/e/e0/82nj2x9sxko473g7782r14fztd4zyky.png/15px-Star-1.png",
# "star-1",
# )
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/0/0b/msaff2g0zk6nlyl1rrn7n1ri4yobcqc.png/30px-Star-2.png",
# "star-2",
# )
# await self.download_img(
# "https://patchwiki.biligame.com/images/bluearchive/thumb/8/8a/577yv79x1rwxk8efdccpblo0lozl158.png/46px-Star-3.png",
# "star-3"
# )
# 数据来源:SCHALE DB
async def _update_info(self): async def _update_info(self):
info = {} info = {}
url = "https://wiki.biligame.com/bluearchive/学生筛选" url = "https://lonqie.github.io/SchaleDB/data/cn/students.min.json?v=49"
result = await self.get_url(url) result = await AsyncHttpx.get(url)
if not result: if result.status_code != 200:
logger.warning(f"更新 {self.game_name_cn} 出错") logger.warning(f"更新 {self.game_name_cn} 出错")
return return
else: else:
dom = etree.HTML(result, etree.HTMLParser()) char_list = json.loads(result.text)
char_list = dom.xpath("//div[@class='filters']/table[2]/tbody/tr")
for char in char_list: for char in char_list:
try: try:
name = char.xpath("./td[2]/a/div/text()")[0] name = char.get("Name")
avatar = char.xpath("./td[1]/div/div/a/img/@data-src")[0] avatar = "https://lonqie.github.io/SchaleDB/images/student/icon/"+char.get("CollectionTexture")+".png"
star_pic = char.xpath("./td[4]/img/@alt")[0] star = char.get("StarGrade")
except IndexError: except IndexError:
continue continue
member_dict = { member_dict = {
"头像": unquote(str(avatar)), "头像": unquote(str(avatar)),
"名称": remove_prohibited_str(name), "名称": remove_prohibited_str(name),
"星级": self.title2star(star_pic), "星级": star,
} }
info[member_dict["名称"]] = member_dict info[member_dict["名称"]] = member_dict
self.dump_data(info) self.dump_data(info)
@@ -147,4 +192,5 @@ class BaHandle(BaseHandle[BaChar]):
await self.download_img( await self.download_img(
"https://patchwiki.biligame.com/images/bluearchive/thumb/8/8a/577yv79x1rwxk8efdccpblo0lozl158.png/46px-Star-3.png", "https://patchwiki.biligame.com/images/bluearchive/thumb/8/8a/577yv79x1rwxk8efdccpblo0lozl158.png/46px-Star-3.png",
"star-3" "star-3"
) )
+20 -27
View File
@@ -331,9 +331,7 @@ class PrettyHandle(BaseHandle[PrettyData]):
try: try:
title = announcement.xpath("./@title")[0] title = announcement.xpath("./@title")[0]
url = "https://wiki.biligame.com/" + announcement.xpath("./@href")[0] url = "https://wiki.biligame.com/" + announcement.xpath("./@href")[0]
if re.match(r".*?\d{8}$", title) or re.match( if "卡池" in title:
r"^\d{1,2}月\d{1,2}日.*?", title
):
break break
except IndexError: except IndexError:
continue continue
@@ -353,45 +351,42 @@ class PrettyHandle(BaseHandle[PrettyData]):
up_chars_name = [] up_chars_name = []
up_cards = [] up_cards = []
up_cards_name = [] up_cards_name = []
soup = BeautifulSoup(result, "lxml") dom = etree.HTML(result, etree.HTMLParser())
heads = soup.find_all("span", {"class": "mw-headline"}) content = dom.xpath('//*[@id="mw-content-text"]/div/div/div[1]/div')[0]
heads = content.xpath("./div")
for head in heads: for head in heads:
if "时间" in head.text or "期间" in head.text: if "时间" in head.find("./img").tail or "期间" in head.find("./img").tail:
time = head.find_next("p").text.split("\n")[0] time = content.xpath("./p")[1].text.split("\n")[0]
if "~" in time: if "~" in time:
start, end = time.split("~") start, end = time.split("~")
start_time = dateparser.parse(start) start_time = dateparser.parse(start)
end_time = dateparser.parse(end) end_time = dateparser.parse(end)
elif "赛马娘" in head.text: elif "赛马娘" in head.find("./img").tail:
char_img = head.find_next("center").find("img")[ char_img = content.xpath("./center")[1].find("./a/img").get("src")
"src" lines = content.xpath("./p")[2].xpath("string(.)").split("\n")
]
lines = str(head.find_next("p").text).split("\n")
chars = [ chars = [
line line
for line in lines for line in lines
if "★" in line and "【" in line and "】" in line if "★" in line and "[" in line and "]" in line
] ]
for char in set(chars): # list去重 for char in set(chars): # list去重
star = char.count("★") star = char.count("★")
name = re.split(r"[【】]", char)[-2].strip() name = re.split("[ ]",char)[-1]
up_chars.append( up_chars.append(
UpChar(name=name, star=star, limited=False, zoom=70) UpChar(name=name, star=star, limited=False, zoom=70)
) )
up_chars_name.append(name) up_chars_name.append(name)
elif "支援卡" in head.text: elif "支援卡" in head.find("./img").tail:
card_img = head.find_next("center").find("img")[ card_img = content.xpath("./center")[2].find("./a/img").get("src")
"src" lines = content.xpath("./p")[3].xpath("string(.)").split("\n")
]
lines = str(head.find_next("p").text).split("\n")
cards = [ cards = [
line line
for line in lines for line in lines
if "R" in line and "【" in line and "】" in line if "R" in line and "[" in line and "]" in line
] ]
for card in cards: for card in set(cards):
star = 3 if "SSR" in card else 2 if "SR" in card else 1 star = 3 if "SSR" in card else 2 if "SR" in card else 1
name = re.split(r"[【】]", card)[-2].strip() name = re.split("[ ]",card)[-1]
up_cards.append( up_cards.append(
UpChar(name=name, star=star, limited=False, zoom=70) UpChar(name=name, star=star, limited=False, zoom=70)
) )
@@ -404,7 +399,7 @@ class PrettyHandle(BaseHandle[PrettyData]):
start_time=start_time, start_time=start_time,
end_time=end_time, end_time=end_time,
up_char=up_chars, up_char=up_chars,
up_name=up_chars_name, up_name=",".join(up_chars_name),
) )
self.UP_CARD = UpEvent( self.UP_CARD = UpEvent(
title=title, title=title,
@@ -412,7 +407,7 @@ class PrettyHandle(BaseHandle[PrettyData]):
start_time=start_time, start_time=start_time,
end_time=end_time, end_time=end_time,
up_char=up_cards, up_char=up_cards,
up_name=up_cards_name, up_name=",".join(up_cards_name),
) )
self.dump_up_char() self.dump_up_char()
logger.info(f"成功获取{self.game_name_cn}当前up信息...当前up池: {title}") logger.info(f"成功获取{self.game_name_cn}当前up信息...当前up池: {title}")
@@ -424,10 +419,8 @@ class PrettyHandle(BaseHandle[PrettyData]):
self.load_up_char() self.load_up_char()
if self.UP_CHAR and self.UP_CARD: if self.UP_CHAR and self.UP_CARD:
return Message( return Message(
Message.template("重载成功!\n当前UP池子:{}{:image}\n当前支援卡池子:{}{:image}").format( Message.template("重载成功!\n当前UP池子:{}\n当前支援卡池子:{}").format(
self.UP_CHAR.up_name, self.UP_CHAR.up_name,
self.UP_CHAR.pool_img,
self.UP_CARD.up_name, self.UP_CARD.up_name,
self.UP_CARD.pool_img,
) )
) )
+2 -2
View File
@@ -1,4 +1,4 @@
from configs.path_config import IMAGE_PATH, TEXT_PATH from configs.path_config import IMAGE_PATH, TEXT_PATH, TEMP_PATH
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
from typing import Tuple, List from typing import Tuple, List
from math import sqrt, pow from math import sqrt, pow
@@ -118,7 +118,7 @@ class Map:
self._generate_best_route() self._generate_best_route()
self.map.crop((min_width, min_height, max_width, max_height)) self.map.crop((min_width, min_height, max_width, max_height))
rand = random.randint(1, 10000) rand = random.randint(1, 10000)
self.map.save(f"{TEXT_PATH}/genshin_map_{rand}.png") self.map.save(f"{TEMP_PATH}/genshin_map_{rand}.png")
return rand return rand
# 资源数量 # 资源数量
@@ -1,6 +1,6 @@
from pathlib import Path from pathlib import Path
from typing import Tuple, Optional, List from typing import Tuple, Optional, List
from configs.path_config import IMAGE_PATH, TEXT_PATH from configs.path_config import IMAGE_PATH, TEXT_PATH, TEMP_PATH
from utils.message_builder import image from utils.message_builder import image
from services.log import logger from services.log import logger
from utils.image_utils import BuildImage from utils.image_utils import BuildImage
@@ -57,7 +57,7 @@ async def query_resource(resource_name: str) -> str:
None, map_.generate_resource_icon_in_map None, map_.generate_resource_icon_in_map
) )
return ( return (
f"{image(f'genshin_map_{rand}.png', 'temp')}" f"{image(TEMP_PATH / f'genshin_map_{rand}.png')}"
f"\n\n※ {resource_name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki" f"\n\n※ {resource_name} 一共找到 {count} 个位置点\n※ 数据来源于米游社wiki"
) )
@@ -3,7 +3,6 @@ from nonebot.adapters.onebot.v11 import MessageEvent, GroupMessageEvent
from services.log import logger from services.log import logger
from .data_source import get_user_memo, get_memo from .data_source import get_user_memo, get_memo
from .._models import Genshin from .._models import Genshin
from nonebot.plugin import export
__zx_plugin_name__ = "原神便笺查询" __zx_plugin_name__ = "原神便笺查询"
@@ -28,10 +27,6 @@ __plugin_settings__ = {
__plugin_block_limit__ = {} __plugin_block_limit__ = {}
export = export()
export.get_memo = get_memo
query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True) query_memo_matcher = on_command("原神便签查询", aliases={"原神便笺查询", "yss"}, priority=5, block=True)
@@ -19,7 +19,9 @@ import pytz
driver: Driver = nonebot.get_driver() driver: Driver = nonebot.get_driver()
get_memo = require("query_memo").get_memo require("query_memo")
from ..query_memo import get_memo
global_map = {} global_map = {}
+1 -1
View File
@@ -101,7 +101,7 @@ cases_matcher_group = MatcherGroup(priority=5, permission=GROUP, block=True)
k_open_case = cases_matcher_group.on_command("开箱") k_open_case = cases_matcher_group.on_command("开箱")
reload_count = cases_matcher_group.on_command("重置开箱") reload_count = cases_matcher_group.on_command("重置开箱",permission=SUPERUSER)
@reload_count.handle() @reload_count.handle()
+2 -2
View File
@@ -31,7 +31,7 @@ async def open_case(user_qq: int, group: int, case_name: str = "狂牙大行动"
async with db.transaction(): async with db.transaction():
user = await OpenCasesUser.ensure(user_qq, group, for_update=True) user = await OpenCasesUser.ensure(user_qq, group, for_update=True)
# 一天次数上限 # 一天次数上限
if user.today_open_total > int( if user.today_open_total >= int(
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT") Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
+ int(impression) + int(impression)
/ Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT") / Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
@@ -155,7 +155,7 @@ async def open_shilian_case(user_qq: int, group: int, case_name: str, num: int =
Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT") Config.get_config("open_cases", "INITIAL_OPEN_CASE_COUNT")
+ int(impression) / Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT") + int(impression) / Config.get_config("open_cases", "EACH_IMPRESSION_ADD_COUNT")
) )
if user.today_open_total == max_count: if user.today_open_total >= max_count:
return _handle_is_MAX_COUNT() return _handle_is_MAX_COUNT()
if max_count - user.today_open_total < num: if max_count - user.today_open_total < num:
return ( return (
+7 -2
View File
@@ -1,6 +1,8 @@
from nonebot import on_message from nonebot import on_message
from services.log import logger from services.log import logger
from nonebot.adapters.onebot.v11 import GroupMessageEvent, ActionFailed from nonebot.adapters.onebot.v11 import GroupMessageEvent, ActionFailed
from utils.manager import group_manager
from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text from utils.utils import get_message_json, get_local_proxy, is_number, get_message_text
from nonebot.adapters.onebot.v11.permission import GROUP from nonebot.adapters.onebot.v11.permission import GROUP
from utils.message_builder import image from utils.message_builder import image
@@ -34,7 +36,10 @@ Config.add_plugin_config(
) )
parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False) async def plugin_on_checker(event: GroupMessageEvent) -> bool:
return group_manager.get_plugin_status("parse_bilibili_json", event.group_id)
parse_bilibili_json = on_message(priority=1, permission=GROUP, block=False, rule=plugin_on_checker)
_tmp = {} _tmp = {}
@@ -124,7 +129,7 @@ async def _(event: GroupMessageEvent):
url, url,
timeout=7, timeout=7,
) as response: ) as response:
url = str(response.url).split("?")[0] url = (str(response.url).split("?")[0]).strip("/")
bvid = url.split("/")[-1] bvid = url.split("/")[-1]
vd_info = await video.get_video_base_info(bvid) vd_info = await video.get_video_base_info(bvid)
if vd_info: if vd_info:
+1 -1
View File
@@ -1,5 +1,5 @@
from configs.config import Config from configs.config import Config
from utils.manager import GDict from utils.utils import GDict
import nonebot import nonebot
+5 -1
View File
@@ -12,6 +12,7 @@ from .._model import Setu
import asyncio import asyncio
import os import os
import random import random
import re
try: try:
import ujson as json import ujson as json
@@ -22,6 +23,7 @@ except ModuleNotFoundError:
url = "https://api.lolicon.app/setu/v2" url = "https://api.lolicon.app/setu/v2"
path = "_setu" path = "_setu"
r18_path = "_r18" r18_path = "_r18"
host_pattern = re.compile(r"https?://([^/]+)")
# 获取url # 获取url
@@ -89,7 +91,9 @@ async def search_online_setu(
""" """
ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL") ws_url = Config.get_config("pixiv", "PIXIV_NGINX_URL")
if ws_url: if ws_url:
url_ = url_.replace("i.pximg.net", ws_url).replace("i.pixiv.cat", ws_url) host_match = re.match(host_pattern, url_)
host = host_match.group(1)
url_ = url_.replace(host, ws_url)
index = random.randint(1, 100000) if id_ is None else id_ index = random.randint(1, 100000) if id_ is None else id_
path_ = IMAGE_PATH / path_ if path_ else TEMP_PATH path_ = IMAGE_PATH / path_ if path_ else TEMP_PATH
file_name = f"{index}_temp_setu.jpg" if path_ == TEMP_PATH else f"{index}.jpg" file_name = f"{index}_temp_setu.jpg" if path_ == TEMP_PATH else f"{index}.jpg"
+1
View File
@@ -18,6 +18,7 @@ from configs.path_config import DATA_PATH
from services.log import logger from services.log import logger
from .utils import clear_sign_data_pic from .utils import clear_sign_data_pic
from utils.utils import is_number from utils.utils import is_number
from .goods_register import driver
try: try:
import ujson as json import ujson as json
+60
View File
@@ -0,0 +1,60 @@
from models.sign_group_user import SignGroupUser
from configs.config import Config
from nonebot import Driver
from utils.decorator.shop import shop_register, NotMeetUseConditionsException
import nonebot
driver: Driver = nonebot.get_driver()
@driver.on_startup
async def _():
"""
导入内置的三个商品
"""
@shop_register(
name=("好感度双倍加持卡Ⅰ", "好感度双倍加持卡Ⅱ", "好感度双倍加持卡Ⅲ"),
price=(30, 150, 250),
des=(
"下次签到双倍好感度概率 + 10%(谁才是真命天子?)(同类商品将覆盖)",
"下次签到双倍好感度概率 + 20%(平平庸庸)(同类商品将覆盖)",
"下次签到双倍好感度概率 + 30%(金币才是真命天子!)(同类商品将覆盖)",
),
load_status=Config.get_config("shop", "IMPORT_DEFAULT_SHOP_GOODS"),
icon=("favorability_card_1.png", "favorability_card_2.png", "favorability_card_3.png"),
** {"好感度双倍加持卡Ⅰ_prob": 0.1, "好感度双倍加持卡Ⅱ_prob": 0.2, "好感度双倍加持卡Ⅲ_prob": 0.3},
)
async def sign_card(user_id: int, group_id: int, prob: float):
user = await SignGroupUser.ensure(user_id, group_id)
await user.update(add_probability=prob).apply()
@shop_register(
name="测试道具A",
price=99,
des="随便侧而出",
load_status=False,
icon="sword.png",
)
async def _(user_id: int, group_id: int):
print(user_id, group_id, '使用测试道具')
@shop_register.before_handle(name="测试道具A", load_status=False)
async def _(user_id: int, group_id: int):
print(user_id, group_id, '第一个使用前函数(before handle)')
@shop_register.before_handle(name="测试道具A", load_status=False)
async def _(user_id: int, group_id: int):
print(user_id, group_id, '第二个使用前函数(before handle)222')
raise NotMeetUseConditionsException("太笨了!") # 抛出异常,阻断使用,并返回信息
@shop_register.after_handle(name="测试道具A", load_status=False)
async def _(user_id: int, group_id: int):
print(user_id, group_id, '第一个使用后函数(after handle)')
@driver.on_bot_connect
async def _():
await shop_register.load_register()
Generated
+1541 -700
View File
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -12,18 +12,16 @@ url = "https://mirrors.aliyun.com/pypi/simple/"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.8" python = "^3.8"
nonebot2 = "^2.0.0-beta.4" nonebot2 = "^2.0.0rc1"
nonebot-adapter-onebot = "^2.0.0-beta.1" nonebot-adapter-onebot = "^2.0.0-beta.1"
aiofiles = "^0.8.0" aiofiles = "^0.8.0"
aiohttp = "3.7.4.post0" aiohttp = "3.7.4.post0"
beautifulsoup4 = "4.9.3" beautifulsoup4 = "4.9.3"
feedparser = "^6.0.8" feedparser = "^6.0.8"
gino = "^1.0.1"
httpx = "^0.23.0" httpx = "^0.23.0"
ImageHash = "^4.2.1" ImageHash = "^4.2.1"
jieba = "^0.42.1" jieba = "^0.42.1"
lxml = "4.6.5" lxml = "4.6.5"
nonebot-plugin-apscheduler = "^0.1.2"
opencv-python = "^4.5.5" opencv-python = "^4.5.5"
Pillow = "^9.0.1" Pillow = "^9.0.1"
playwright = "^1.18.2" playwright = "^1.18.2"
@@ -39,10 +37,12 @@ dateparser = "^1.1.0"
cn2an = "^0.5.16" cn2an = "^0.5.16"
python-jose = "^3.3.0" python-jose = "^3.3.0"
python-multipart = "^0.0.5" python-multipart = "^0.0.5"
bilireq = "^0.2.0" bilireq = "^0.2.3.post0"
emoji = "^1.7.0" emoji = "^1.7.0"
wordcloud = "^1.8.1" wordcloud = "^1.8.1"
rich = "^12.4.3" rich = "^12.4.3"
gino = "^1.0.1"
nonebot-plugin-apscheduler = "^0.2.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

+3 -1
View File
@@ -10,6 +10,8 @@
"poetry.lock", "poetry.lock",
"pyproject.toml" "pyproject.toml"
], ],
"add_file": [], "add_file": [
"resources/image/shop_icon"
],
"delete_file": [] "delete_file": []
} }
+97 -47
View File
@@ -1,17 +1,52 @@
from typing import Callable, Union, Tuple from typing import Callable, Union, Tuple, Optional
from nonebot.adapters.onebot.v11 import MessageSegment, Message
from nonebot.plugin import require from nonebot.plugin import require
use = require("use")
shop = require("shop_handle")
class ShopRegister(dict): class ShopRegister(dict):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(ShopRegister, self).__init__(*args, **kwargs) super(ShopRegister, self).__init__(*args, **kwargs)
self._data = {} self._data = {}
self._flag = True self._flag = True
def before_handle(self, name: Union[str, Tuple[str, ...]], load_status: bool = True):
"""
说明:
使用前检查方法
参数:
:param name: 道具名称
:param load_status: 加载状态
"""
def register_before_handle(name_list: Tuple[str, ...], func: Callable):
if load_status:
for name_ in name_list:
if not self._data[name_]:
self._data[name_] = {}
if not self._data[name_].get('before_handle'):
self._data[name_]['before_handle'] = []
self._data[name]['before_handle'].append(func)
_name = (name,) if isinstance(name, str) else name
return lambda func: register_before_handle(_name, func)
def after_handle(self, name: Union[str, Tuple[str, ...]], load_status: bool = True):
"""
说明:
使用后执行方法
参数:
:param name: 道具名称
:param load_status: 加载状态
"""
def register_after_handle(name_list: Tuple[str, ...], func: Callable):
if load_status:
for name_ in name_list:
if not self._data[name_]:
self._data[name_] = {}
if not self._data[name_].get('after_handle'):
self._data[name_]['after_handle'] = []
self._data[name_]['after_handle'].append(func)
_name = (name,) if isinstance(name, str) else name
return lambda func: register_after_handle(_name, func)
def register( def register(
self, self,
name: Tuple[str, ...], name: Tuple[str, ...],
@@ -21,13 +56,15 @@ class ShopRegister(dict):
limit_time: Tuple[int, ...], limit_time: Tuple[int, ...],
load_status: Tuple[bool, ...], load_status: Tuple[bool, ...],
daily_limit: Tuple[int, ...], daily_limit: Tuple[int, ...],
is_passive: Tuple[bool, ...],
icon: Tuple[str, ...],
**kwargs, **kwargs,
): ):
def add_register_item(func: Callable): def add_register_item(func: Callable):
if name in self._data.keys(): if name in self._data.keys():
raise ValueError("该商品已注册,请替换其他名称!") raise ValueError("该商品已注册,请替换其他名称!")
for n, p, d, dd, l, s, dl in zip( for n, p, d, dd, l, s, dl, pa, i in zip(
name, price, des, discount, limit_time, load_status, daily_limit name, price, des, discount, limit_time, load_status, daily_limit, is_passive, icon
): ):
if s: if s:
_temp_kwargs = {} _temp_kwargs = {}
@@ -36,46 +73,60 @@ class ShopRegister(dict):
_temp_kwargs[key.split("_", maxsplit=1)[-1]] = value _temp_kwargs[key.split("_", maxsplit=1)[-1]] = value
else: else:
_temp_kwargs[key] = value _temp_kwargs[key] = value
self._data[n] = { temp = self._data.get(n, {})
temp.update({
"price": p, "price": p,
"des": d, "des": d,
"discount": dd, "discount": dd,
"limit_time": l, "limit_time": l,
"daily_limit": dl, "daily_limit": dl,
"icon": i,
"is_passive": pa,
"func": func, "func": func,
"kwargs": _temp_kwargs, "kwargs": _temp_kwargs,
} })
self._data[n] = temp
return func return func
return lambda func: add_register_item(func) return lambda func: add_register_item(func)
async def load_register(self): async def load_register(self):
require("use")
require("shop_handle")
from basic_plugins.shop.use.data_source import register_use, func_manager
from basic_plugins.shop.shop_handle.data_source import register_goods
# 统一进行注册 # 统一进行注册
if self._flag: if self._flag:
# 只进行一次注册 # 只进行一次注册
self._flag = False self._flag = False
for name in self._data.keys(): for name in self._data.keys():
await shop.register_goods( await register_goods(
name, name,
self._data[name]["price"], self._data[name]["price"],
self._data[name]["des"], self._data[name]["des"],
self._data[name]["discount"], self._data[name]["discount"],
self._data[name]["limit_time"], self._data[name]["limit_time"],
self._data[name]["daily_limit"], self._data[name]["daily_limit"],
self._data[name]["is_passive"],
self._data[name]["icon"],
) )
use.register_use( register_use(
name, self._data[name]["func"], **self._data[name]["kwargs"] name, self._data[name]["func"], **self._data[name]["kwargs"]
) )
func_manager.register_use_before_handle(name, self._data[name].get('before_handle', []))
func_manager.register_use_after_handle(name, self._data[name].get('after_handle', []))
def __call__( def __call__(
self, self,
name: Union[str, Tuple[str, ...]], name: Union[str, Tuple[str, ...]], # 名称
price: Union[float, Tuple[float, ...]], price: Union[float, Tuple[float, ...]], # 价格
des: Union[str, Tuple[str, ...]], des: Union[str, Tuple[str, ...]], # 简介
discount: Union[float, Tuple[float, ...]] = 1, discount: Union[float, Tuple[float, ...]] = 1, # 折扣
limit_time: Union[int, Tuple[int, ...]] = 0, limit_time: Union[int, Tuple[int, ...]] = 0, # 限时
load_status: Union[bool, Tuple[bool, ...]] = True, load_status: Union[bool, Tuple[bool, ...]] = True, # 加载状态
daily_limit: Union[int, Tuple[int, ...]] = 0, daily_limit: Union[int, Tuple[int, ...]] = 0, # 每日限购
is_passive: Union[bool, Tuple[bool, ...]] = False, # 被动道具(无法被'使用道具'命令消耗)
icon: Union[str, Tuple[str, ...]] = False, # 图标
**kwargs, **kwargs,
): ):
_tuple_list = [] _tuple_list = []
@@ -89,35 +140,15 @@ class ShopRegister(dict):
f"注册商品 {name} 中 name,price,des,discount,limit_time,load_status,daily_limit 数量不符!" f"注册商品 {name} 中 name,price,des,discount,limit_time,load_status,daily_limit 数量不符!"
) )
_current_len = _current_len if _current_len > -1 else 1 _current_len = _current_len if _current_len > -1 else 1
_name = name if isinstance(name, tuple) else (name,) _name = self.__get(name, _current_len)
_price = ( _price = self.__get(price, _current_len)
price _discount = self.__get(discount, _current_len)
if isinstance(price, tuple) _limit_time = self.__get(limit_time, _current_len)
else tuple([price for _ in range(_current_len)]) _des = self.__get(des, _current_len)
) _load_status = self.__get(load_status, _current_len)
_discount = ( _daily_limit = self.__get(daily_limit, _current_len)
discount _is_passive = self.__get(is_passive, _current_len)
if isinstance(discount, tuple) _icon = self.__get(icon, _current_len)
else tuple([discount for _ in range(_current_len)])
)
_limit_time = (
limit_time
if isinstance(limit_time, tuple)
else tuple([limit_time for _ in range(_current_len)])
)
_des = (
des if isinstance(des, tuple) else tuple([des for _ in range(_current_len)])
)
_load_status = (
load_status
if isinstance(load_status, tuple)
else tuple([load_status for _ in range(_current_len)])
)
_daily_limit = (
daily_limit
if isinstance(daily_limit, tuple)
else tuple([daily_limit for _ in range(_current_len)])
)
return self.register( return self.register(
_name, _name,
_price, _price,
@@ -126,9 +157,14 @@ class ShopRegister(dict):
_limit_time, _limit_time,
_load_status, _load_status,
_daily_limit, _daily_limit,
_is_passive,
_icon,
**kwargs, **kwargs,
) )
def __get(self, value, _current_len):
return value if isinstance(value, tuple) else tuple([value for _ in range(_current_len)])
def __setitem__(self, key, value): def __setitem__(self, key, value):
self._data[key] = value self._data[key] = value
@@ -151,4 +187,18 @@ class ShopRegister(dict):
return self._data.items() return self._data.items()
class NotMeetUseConditionsException(Exception):
"""
不满足条件异常类
"""
def __init__(self, info: Optional[Union[str, MessageSegment, Message]]):
super().__init__(self)
self._info = info
def get_info(self):
return self._info
shop_register = ShopRegister() shop_register = ShopRegister()
+84
View File
@@ -0,0 +1,84 @@
from typing import List, Callable, Optional
from nonebot.adapters.onebot.v11 import GroupMessageEvent, MessageEvent
from nonebot.internal.matcher import Matcher
from nonebot.internal.params import Depends
from models.user_shop_gold_log import UserShopGoldLog
from models.bag_user import BagUser
from utils.message_builder import at
from utils.utils import get_message_at, get_message_face, get_message_img, get_message_text
def cost_gold(gold: int):
"""
说明:
插件方法调用使用金币
参数:
:param gold: 金币数量
"""
async def dependency(matcher: Matcher, event: GroupMessageEvent):
if (await BagUser.get_gold(event.user_id, event.group_id)) < gold:
await matcher.finish(at(event.user_id) + f"金币不足..该功能需要{gold}金币..")
await BagUser.spend_gold(event.user_id, event.group_id, gold)
await UserShopGoldLog.add_shop_log(event.user_id, event.group_id, 2, matcher.plugin_name, gold, 1)
return Depends(dependency)
async def _match(matcher: Matcher, event: MessageEvent, msg: Optional[str], func: Callable):
_list = func(event.message)
if not _list and msg:
await matcher.finish(msg)
return _list
def ImageList(msg: Optional[str] = None) -> List[str]:
"""
说明:
获取图片列表,含有msg时不能为空,为空时提示并结束事件
参数:
:param msg: 提示文本
"""
async def dependency(matcher: Matcher, event: MessageEvent):
return await _match(matcher, event, msg, get_message_img)
return Depends(dependency)
def AtList(msg: Optional[str] = None) -> List[str]:
"""
说明:
获取at列表,含有msg时不能为空,为空时提示并结束事件
参数:
:param msg: 提示文本
"""
async def dependency(matcher: Matcher, event: MessageEvent):
return await _match(matcher, event, msg, get_message_at)
return Depends(dependency)
def FaceList(msg: Optional[str] = None) -> List[str]:
"""
说明:
获取face列表,含有msg时不能为空,为空时提示并结束事件
参数:
:param msg: 提示文本
"""
async def dependency(matcher: Matcher, event: MessageEvent):
return await _match(matcher, event, msg, get_message_face)
return Depends(dependency)
def PlaintText(msg: Optional[str] = None) -> str:
"""
说明:
获取纯文本且,含有msg时不能为空,为空时提示并结束事件
参数:
:param msg: 提示文本
"""
async def dependency(matcher: Matcher, event: MessageEvent):
return await _match(matcher, event, msg, get_message_text)
return Depends(dependency)
-5
View File
@@ -14,11 +14,6 @@ from .requests_manager import RequestManager
from configs.path_config import DATA_PATH from configs.path_config import DATA_PATH
# 全局字典
GDict = {
"run_sql": [] # 需要启动前运行的sql语句
}
# 群功能开关 | 群被动技能 | 群权限 管理 # 群功能开关 | 群被动技能 | 群权限 管理
group_manager: Optional[GroupManager] = GroupManager( group_manager: Optional[GroupManager] = GroupManager(
DATA_PATH / "manager" / "group_manager.json" DATA_PATH / "manager" / "group_manager.json"
+2 -1
View File
@@ -1,3 +1,4 @@
import io
from pathlib import Path from pathlib import Path
from typing import List, Union from typing import List, Union
@@ -26,7 +27,7 @@ def image(
return MessageSegment.image(file) return MessageSegment.image(file)
logger.warning(f"图片 {file.absolute()}缺失...") logger.warning(f"图片 {file.absolute()}缺失...")
return "" return ""
elif isinstance(file, bytes): elif isinstance(file, (bytes, io.BytesIO)):
return MessageSegment.image(file) return MessageSegment.image(file)
elif b64: elif b64:
return MessageSegment.image(b64 if "base64://" in b64 else "base64://" + b64) return MessageSegment.image(b64 if "base64://" in b64 else "base64://" + b64)
+15 -6
View File
@@ -18,8 +18,17 @@ try:
except ModuleNotFoundError: except ModuleNotFoundError:
import json import json
require("nonebot_plugin_apscheduler")
from nonebot_plugin_apscheduler import scheduler
scheduler = require("nonebot_plugin_apscheduler").scheduler scheduler = scheduler
# 全局字典
GDict = {
"run_sql": [], # 需要启动前运行的sql语句
"_shop_before_handle": {}, # 商品使用前函数
"_shop_after_handle": {}, # 商品使用后函数
}
class CountLimiter: class CountLimiter:
@@ -110,8 +119,8 @@ class BanCheckLimiter:
self.mint[key] = 0 self.mint[key] = 0
return False return False
if ( if (
self.mint[key] >= self.default_count self.mint[key] >= self.default_count
and time.time() - self.mtime[key] < self.default_check_time and time.time() - self.mtime[key] < self.default_check_time
): ):
self.mtime[key] = time.time() self.mtime[key] = time.time()
self.mint[key] = 0 self.mint[key] = 0
@@ -402,7 +411,7 @@ def cn2py(word: str) -> str:
def change_pixiv_image_links( def change_pixiv_image_links(
url: str, size: Optional[str] = None, nginx_url: Optional[str] = None url: str, size: Optional[str] = None, nginx_url: Optional[str] = None
): ):
""" """
说明: 说明:
@@ -422,8 +431,8 @@ def change_pixiv_image_links(
if nginx_url: if nginx_url:
url = ( url = (
url.replace("i.pximg.net", nginx_url) url.replace("i.pximg.net", nginx_url)
.replace("i.pixiv.cat", nginx_url) .replace("i.pixiv.cat", nginx_url)
.replace("_webp", "") .replace("_webp", "")
) )
return url return url