259 Commits

Author SHA1 Message Date
d4b8e58946 修复一处异常问题 2024-01-20 17:39:40 +08:00
22416227d8 更新bot测试接口 2024-01-20 10:00:07 +08:00
1705f4d752 Merge remote-tracking branch 'origin/dev_' into dev_ 2024-01-18 16:53:12 +08:00
af18663759 更新B站下载视频接口 2024-01-18 16:53:03 +08:00
e40c19016a Merge branch 'master' into dev_ 2024-01-17 17:23:32 +08:00
4dce74eaf8 提取B站API统一管理 2024-01-17 17:22:21 +08:00
68fd6efdf4 修复空字符串判断错误代码 2024-01-17 15:49:45 +08:00
2000efdd55 补充QQ发出AI内容消息 2024-01-17 15:19:25 +08:00
9ea1450066 新增B站AI总结功能 2024-01-17 15:12:40 +08:00
3437a5386f 修复B站无法登陆问题 2024-01-08 17:31:21 +08:00
177c91c370 update 2024-01-08 10:46:23 +08:00
5af58336ec update gpt 2023-10-26 14:19:18 +08:00
b177561df4 update gpt 2023-10-26 14:08:44 +08:00
126f25af81 update gpt 2023-09-20 22:21:09 +08:00
c48db62d00 update 2023-09-13 15:30:46 +08:00
e595cff31d update 2023-09-13 15:22:56 +08:00
9b70685949 update 2023-09-13 10:47:38 +08:00
a317767ae7 遥遥领先
遥遥领先
2023-09-05 01:33:23 +08:00
5846ef5016 遥遥领先 2023-09-05 01:06:00 +08:00
91a18835c3 遥遥领先 2023-09-05 00:54:07 +08:00
694239eac9 遥遥领先 2023-09-05 00:32:03 +08:00
af3f85618d 遥遥领先 2023-09-04 12:19:37 +08:00
6eedb9786e 更换百合会签到 2023-08-11 09:37:16 +08:00
d56d6edf19 更换摸鱼日历的api 2023-08-08 11:30:01 +08:00
084d8901e9 更换摸鱼日历的api 2023-08-02 09:42:53 +08:00
00816083b9 调整摸鱼图提前下载时间 2023-08-01 14:55:50 +08:00
8da7c2f572 新增QQ启动前检查签名服务器是否运行 2023-07-26 09:42:40 +08:00
e65eb62417 调整百度GPT的User为用户而不是群组 2023-07-25 17:17:42 +08:00
883f5bb820 update pom.xml 2023-07-25 16:56:48 +08:00
a34fafc39c 更新QQ机器人
修复机器人协议问题
2023-07-25 16:04:50 +08:00
9fdf670c26 新增百度文言一心GPT接口模块 2023-07-25 14:48:11 +08:00
00cdf7b96e 修复B站直播签到问题 2023-07-21 01:10:03 +08:00
2c456702d8 调整B站签到出错时输出日志 2023-07-20 13:32:30 +08:00
4aa0a53cc5 更新QQ机器人版本
新增扫码登录
2023-06-25 10:26:13 +08:00
3d3046f1d7 修复B站漫画签到的空指针错误 2023-06-25 08:40:24 +08:00
8df36edd2d 调整摸鱼日历API 2023-06-20 17:48:22 +08:00
808798028f 调整摸鱼日历API 2023-06-20 17:48:04 +08:00
4f5bcc9df3 修复下载摸鱼图片会死循环问题
修复电池签到任务周任务为空问题
2023-06-20 09:40:27 +08:00
43a816066d fix version 2023-04-18 07:48:19 +08:00
9fc377f070 update 更新selenium版本 2023-03-18 13:41:47 +08:00
83e3b5adae remove:MiRouter 2023-03-17 17:43:12 +08:00
b14601ef2c add:FixQQVersion 2023-03-17 17:39:14 +08:00
48501b09ff 修复B站每日签到没有周任务时的异常 2023-03-02 09:57:16 +08:00
a27d6c5a35 新增代理 2023-02-27 20:48:09 +08:00
0819bc58aa 更新 'src/main/java/com/yutou/qqbot/models/Commands/PaoPaoSleepWaring.java' 2023-02-23 22:40:49 +08:00
2e4e072201 update 2023-02-23 17:27:44 +08:00
ff9ae9cc36 更新 'src/main/java/com/yutou/qqbot/models/Commands/PaoPaoSleepWaring.java' 2023-02-23 17:23:08 +08:00
eb4264628d update 2023-02-23 17:21:57 +08:00
211773a230 更新 'src/main/java/com/yutou/qqbot/models/setu/GetSeTu.java'
优化输出中文冒号.
2023-02-14 16:43:21 +08:00
ab941e97e3 更新 'src/main/java/com/yutou/qqbot/models/setu/GetSeTu.java'
优化输出中文冒号
2023-02-14 16:42:15 +08:00
943a2c9334 优化B站直播间每日签到提示文本 2023-01-07 10:22:57 +08:00
3bc4c164e0 修复B站签到未登录时的状态 2023-01-06 01:31:01 +08:00
938d3d532a 新增B站大会员积分签到
修复B站操作前没做登陆校验的问题
2023-01-06 01:23:34 +08:00
5d15f24847 新增B站大会员积分签到
修复B站操作前没做登陆校验的问题
2023-01-05 15:18:53 +08:00
fec901970a 新增B站直播间领电池功能
新增B站APP操作相关API
优化B站登陆根据QQ号分账号存储
修复Redis获取列表时为空报错问题
2023-01-05 14:36:42 +08:00
083218b1cb 新增毛毛提醒,修改泡泡提醒为一小时 2022-11-20 19:08:32 +08:00
ae72956f68 update PaoPaoSleepWaring 2022-11-11 22:55:03 +08:00
1456675446 update PaoPaoSleepWaring 2022-11-11 22:54:15 +08:00
c2fc5c965a add PaoPaoSleepWaring 2022-11-11 22:43:46 +08:00
cf098877c3 update 木鱼音频 2022-11-10 20:36:37 +08:00
c9eceaccf3 update 木鱼音频 2022-11-10 20:29:49 +08:00
ab1facc747 add PaoPaoSleepWaring 2022-11-10 14:18:12 +08:00
5ac0b45540 fix WoodenFish.java 2022-11-07 09:41:45 +08:00
c146eac9c5 add WoodenFish.java 2022-11-04 10:28:58 +08:00
85fbce9f4f add WoodenFish.java 2022-11-04 10:25:17 +08:00
0de499fb57 fix BaiHeHui.java 2022-10-28 09:41:48 +08:00
7623858866 test1 2022-10-22 13:46:55 +08:00
6d9277ced5 update pom.xml 2022-10-17 09:50:42 +08:00
bcafd751e6 fix bili live sign bugs 2022-10-15 11:31:12 +08:00
5d2d41f176 fix bili live sign time sleep 2022-10-15 11:16:31 +08:00
6de3f5d738 fix int.parseInt 2022-10-15 11:10:46 +08:00
28167c7f49 add user info 2022-10-14 21:31:57 +08:00
22add886d5 add user info 2022-10-14 21:30:25 +08:00
47e4039127 add user info 2022-10-14 21:27:24 +08:00
3d730206b9 fix B站添加直播间失败 2022-10-14 21:14:11 +08:00
07361fb616 fix B站添加直播间失败 2022-10-14 21:11:31 +08:00
00985e7fb8 fix bili live sign bugs 2022-10-14 14:12:09 +08:00
960c3e9c56 add bilibili live signIn
add bilibili live room sign
2022-10-14 13:52:59 +08:00
8207498f2c add bilibili live signIn
add bilibili live room sign
2022-10-14 13:49:43 +08:00
fe48b030d9 新增涩图线上观看 2022-10-13 23:51:52 +08:00
de1fe79b09 新增涩图线上观看 2022-10-13 23:50:37 +08:00
1908c905ac 下载器支持代理 2022-10-13 23:28:04 +08:00
f0d61ffbb6 替换BT下载器 2022-10-09 00:03:34 +08:00
f46c09c6ed 移除日历提醒 2022-09-04 11:59:17 +08:00
7885f2bbfb update 2022-09-04 11:04:03 +08:00
f296d4c819 更新layui版本 2022-09-01 21:27:07 +08:00
283deb3e4a tmp 2022-08-22 22:05:06 +08:00
0ffc076a71 Merge remote-tracking branch 'origin/master' into dev_ 2022-08-22 21:41:24 +08:00
6d2b1e9264 tmp 2022-08-22 21:39:56 +08:00
0ee1be5f04 tmp 2022-08-22 21:39:06 +08:00
204da16848 Merge pull request '新增B站视频下载功能' (#7) from dev_ into master
Reviewed-on: test/QQBot#7
Reviewed-by: root <583819556@163.com>
2022-08-15 02:39:56 +08:00
6857a1d5ea fix:#6 版本号未提交问题 2022-08-15 02:29:36 +08:00
e19d1cdeda add:新增B站视频下载接口及页面 2022-08-15 02:24:49 +08:00
39588831d4 Merge pull request '模块图文分离' (#5) from dev_ into master
Reviewed-on: test/QQBot#5
2022-08-05 11:58:22 +08:00
8160d64867 add:优化 #4 涩图模块图文分离 2022-08-05 11:52:45 +08:00
4fabd514a7 update:调整QQBot的返回值 2022-08-05 11:50:56 +08:00
03f8bc07ba Merge pull request 'update version' (#2) from dev_ into master
Reviewed-on: test/QQBot#2
2022-08-05 10:58:31 +08:00
61c9fc60a0 update version 2022-08-05 10:46:29 +08:00
8f8fa41acf update:涩图模块发送回执
fix:修复大头菜模块未关闭浏览器
del:移除未使用import
2022-08-05 10:45:16 +08:00
d737730768 update:优化脚本执行 2022-07-27 09:35:04 +08:00
5209843e86 update:优化脚本执行 2022-07-27 01:22:32 +08:00
21dd8033d1 update:重构脚本执行方式 2022-07-26 22:46:00 +08:00
af54377bb2 update:redis新增对map的支持 2022-07-26 22:45:11 +08:00
788bd24d92 update:redis新增对map的支持 2022-07-26 22:45:00 +08:00
08bbd247a4 fix:修复舰R脚本多调用了一次start 2022-07-25 13:31:24 +08:00
75b43e40e5 fix:修复舰R脚本多调用了一次start 2022-07-25 12:58:22 +08:00
ef8d46aa64 新增舰R脚本 2022-07-25 12:42:55 +08:00
886e3eae6f 新增舰R脚本 2022-07-25 12:39:03 +08:00
30fda14264 新增舰R脚本 2022-07-25 12:35:50 +08:00
c36044e6e4 add:Redis新增列表支持 2022-07-25 12:34:54 +08:00
8661d8f3e7 fix:调整了无头浏览器的流程:需要手动调用关闭浏览器方法
fix:调整了下载文件判断,如果下载结束后文件不存在则抛异常
2022-07-25 08:57:44 +08:00
c10abbe82e update 2022-07-23 10:49:28 +08:00
10675c373a update 2022-07-18 11:48:31 +08:00
67587d208b 更换扫描注解的方式 2022-07-16 15:59:20 +08:00
e085690446 更新QQ依赖 2022-07-16 13:04:09 +08:00
b475e008a2 更新QQ依赖 2022-07-16 12:42:04 +08:00
b2610a02b2 新增HiRes猪猪论坛签到 2022-07-16 12:35:15 +08:00
05e8814b91 改成使用注解来注册模块 2022-07-16 12:34:14 +08:00
d76090af75 更新摸鱼接口 2022-06-27 10:15:24 +08:00
299bc17758 更新依赖
百合会签到改为模拟登陆行为
WebClient导入Cookie修复时间异常问题
2022-06-27 10:02:47 +08:00
8ddfc339dd 更新依赖 2022-06-08 10:29:25 +08:00
7319944441 B站模块:修复字幕顶部过高问题 2022-05-28 17:03:47 +08:00
c1fd29232e B站模块:修复字幕过大的问题
B站模块:修复仅下载前6分钟字幕的问题
2022-05-09 11:55:12 +08:00
a7baf2a236 修复大头菜模块输出异常 2022-05-09 11:52:48 +08:00
af9be86762 调整WebClient代码 2022-05-05 09:31:30 +08:00
84c583ad38 新增B站视频下载功能
新增弹幕转ass功能
优化B站网络请求头代码
2022-05-04 22:30:56 +08:00
edfd663743 update 2022-05-03 16:53:09 +08:00
575df40591 修复大头菜报错问题(FastJSON) 2022-05-03 11:08:15 +08:00
50823587dd update 2022-05-03 10:20:44 +08:00
81929daebd update 2022-05-03 10:19:08 +08:00
bfe7ec77ab update 2022-05-03 10:11:04 +08:00
accead7817 移除调试代码 2022-05-03 09:46:40 +08:00
e0f81620a3 更新FastJSON
调整ChromeDriver参数
2022-05-03 09:40:34 +08:00
4031b07b0b 修复定时器获取bot为空导致异常问题 2022-04-28 09:56:56 +08:00
7943606dc0 修复FastJSON大版本更新后API变动 2022-04-28 09:50:33 +08:00
f1ed4be143 更新依赖
优化签到代码
2022-04-28 09:14:52 +08:00
f116568261 更新路径 2022-04-28 08:37:12 +08:00
694b5fb2ae chromedrive新增代理支持 2022-04-28 08:34:14 +08:00
ec6fce9a8d chromedrive新增代理支持 2022-04-28 08:23:12 +08:00
7ac9d1b188 涩图模块:修复随机色图不被统计的问题 2022-04-26 07:32:13 +08:00
2db6d1fd39 涩图模块:修复每日统计没效果 2022-04-22 00:40:30 +08:00
a90d493975 涩图模块:修复每日统计没效果 2022-04-22 00:37:56 +08:00
e96bdefb67 涩图模块:修复每日统计没效果 2022-04-22 00:35:48 +08:00
61feb23f16 涩图模块:修复每日统计没效果 2022-04-22 00:32:28 +08:00
3dac0288f3 涩图模块:修复每日统计没效果 2022-04-22 00:30:28 +08:00
fd5e32508f 涩图模块:修复每日统计没效果 2022-04-22 00:28:46 +08:00
7e1a0d6b92 涩图模块:修复每日统计没效果 2022-04-22 00:24:03 +08:00
05a892a135 涩图模块:修复每日统计没效果 2022-04-22 00:21:39 +08:00
46322572c7 涩图模块:修复每日统计没效果 2022-04-22 00:18:17 +08:00
938591531d 涩图模块:修复每日统计没效果 2022-04-22 00:16:36 +08:00
4d156ad861 涩图模块:修复每日统计没效果 2022-04-22 00:05:39 +08:00
7776fb3d01 涩图模块:新增每日统计 2022-04-21 00:01:30 +08:00
4f3fea8615 涩图模块:新增每日统计 2022-04-20 21:17:49 +08:00
15b0e14edd 涩图模块:支持多关键词搜索 2022-04-20 20:23:00 +08:00
dfd60919ad 涩图模块:空格替换成|以便支持多关键词搜索 2022-04-20 20:20:42 +08:00
5d4717d7a3 涩图模块:空格替换成|以便支持多关键词搜索 2022-04-20 20:18:49 +08:00
149e64d85f 涩图模块:空格替换成|以便支持多关键词搜索 2022-04-20 20:12:59 +08:00
731d7734d5 摸鱼模块:图片提前下载,后续再发送 2022-04-18 23:13:39 +08:00
b25a146e9a 涩图模块:搜不到图时随机来一张 2022-04-18 23:02:11 +08:00
1f7376c020 涩图模块:新增输出P站id 2022-04-18 22:57:15 +08:00
19a9fb0d1b 涩图模块:搜索不到后会尝试搜索非18、模糊搜索 2022-04-18 22:49:27 +08:00
086d773ac0 涩图模块:新增引用 2022-04-17 22:05:53 +08:00
f908066602 涩图模块:新增引用 2022-04-17 22:05:16 +08:00
d5da784033 涩图模块:匹配正则 2022-04-17 21:57:52 +08:00
5d05f279e8 涩图模块:匹配正则 2022-04-17 21:56:10 +08:00
6c9bd5dc81 涩图模块:匹配正则 2022-04-17 21:53:43 +08:00
c0b394c613 涩图模块:匹配正则 2022-04-17 21:43:09 +08:00
fdc1d7c880 涩图模块:匹配正则 2022-04-17 21:41:54 +08:00
1b593106ab 涩图模块:匹配正则 2022-04-17 21:37:08 +08:00
ccdca908cf 管理员模块:支持this关键词标识本群 2022-04-17 15:55:25 +08:00
9d88fef157 管理员模块:支持this关键词标识本群 2022-04-17 15:51:34 +08:00
a1831163cc 管理员模块:支持this关键词标识本群 2022-04-17 15:49:32 +08:00
4dfbee6d08 涩图模块:图源改成regular,减少图片大小
管理员模块:支持this关键词标识本群
2022-04-17 15:47:12 +08:00
10fd1d6863 涩图模块:区分色图和涩图关键词 2022-04-17 15:25:51 +08:00
4e56d31e43 新增提示 2022-04-17 02:24:26 +08:00
973a51428b 新增错误提示 2022-04-17 02:09:39 +08:00
490ae1b9dc 新增错误提示 2022-04-17 02:03:46 +08:00
e0e7195c57 新增错误提示 2022-04-17 01:54:55 +08:00
479ae1dfba 新增关键词 2022-04-17 01:49:48 +08:00
2558545ffe 新作关键词 2022-04-17 01:20:40 +08:00
f6c9748f48 下载支持代理 2022-04-17 01:06:31 +08:00
2da36d7918 换个二次元图源API试试 2022-04-17 00:58:34 +08:00
a83e92b947 换个二次元图源API试试 2022-04-17 00:14:30 +08:00
f2acbd9dfb update 2022-04-15 04:56:14 +08:00
7405c2a288 update 2022-04-15 04:46:26 +08:00
62ad0a65fd 调整摸鱼时间 2022-04-10 10:11:51 +08:00
409c12b76e 调整摸鱼时间 2022-04-10 09:22:48 +08:00
ac4466c374 调整摸鱼时间 2022-04-10 02:26:22 +08:00
c9a5732721 查询动画新增提示 2022-04-08 18:01:44 +08:00
00ebecb998 查询动画关键词获取到id后转id内容 2022-04-08 18:00:00 +08:00
6bc4ff40d5 查询动画仅限动画模块 2022-04-08 17:49:52 +08:00
6b19fa8f2f 查询动画仅限动画模块 2022-04-08 17:37:46 +08:00
3e709799d2 修复查动画无法保存图片的问题 2022-04-08 17:33:17 +08:00
7fa6c22ef8 修复查动画无法保存图片的问题 2022-04-08 17:11:56 +08:00
bcba637ad5 修复查动画无法保存图片的问题 2022-04-08 17:07:48 +08:00
d56e237b62 新增获取今日动画时提示 2022-04-08 17:03:27 +08:00
606e2e1ef1 允许动画模块在其他群使用 2022-04-08 17:00:07 +08:00
b695e0ff08 移除测试代码 2022-04-08 16:44:00 +08:00
4cbcba6b6e 新增摸鱼模块
测试大头菜
2022-04-08 16:42:08 +08:00
d35b1bdc42 新增模块名字
新番列表模块支持其他群了
定时器支持多个群了
2022-04-08 15:39:59 +08:00
5adb68b2ad 新增漫画购买功能 2022-04-08 13:50:40 +08:00
0ad33b328d 新增漫画购买功能 2022-04-08 13:48:21 +08:00
82c130a506 新增漫画购买功能 2022-04-08 13:46:54 +08:00
fe16be6693 新增漫画购买功能 2022-04-08 13:43:54 +08:00
fab0cdf497 新增漫画购买功能 2022-04-08 13:39:00 +08:00
3fdd2cf5ec 新增漫画购买功能 2022-04-08 13:36:55 +08:00
d9b3e7f558 新增漫画购买功能 2022-04-08 13:33:10 +08:00
9ddd8059dd 新增漫画购买功能 2022-04-08 13:31:54 +08:00
fa2761dbe2 新增漫画购买功能 2022-04-08 13:26:38 +08:00
d4b924f677 新增漫画购买功能 2022-04-08 13:23:49 +08:00
68cecf1e47 新增漫画购买功能 2022-04-08 13:08:12 +08:00
769f106fa3 新增漫画购买功能 2022-04-08 13:06:23 +08:00
2add54f3ad 新增漫画购买功能 2022-04-08 13:03:12 +08:00
159426ed09 新增漫画购买功能 2022-04-08 13:00:34 +08:00
4cc5567568 新增漫画购买功能 2022-04-08 12:59:47 +08:00
c04ada610f 修复B站登陆监测403问题 2022-04-08 02:40:33 +08:00
8145a1c313 update 2022-04-08 02:30:57 +08:00
61e35fb3c5 update 2022-04-08 02:28:41 +08:00
abfe65a534 新增B站漫画签到 2022-04-08 02:26:29 +08:00
d31534311f update 2022-04-07 14:01:49 +08:00
8e13a246ac update 2022-04-07 13:59:21 +08:00
a8b6b34406 update 2022-04-07 13:28:35 +08:00
bdb7d08622 更新pom.xml
新增更新qq和nas服务的指令
2022-04-07 13:08:58 +08:00
f825302b5f 新增临时磁链下载功能 2022-03-17 09:43:07 +08:00
28d98e573d 更新 'src/test/java/com/yutou/qqbot/QqBotApplicationTests.java' 2022-03-16 00:42:13 +08:00
e4ecde0db3 update 2022-03-11 21:07:06 +08:00
4503f2207f 修复忘记取消无头浏览器模式了 2022-02-09 09:22:03 +08:00
b4484f1424 新增NicePT签到
新增https工具
2022-02-08 12:27:07 +08:00
7cb003544b 修复接收文件大小限制 2022-01-28 21:34:56 +08:00
8d6fe31430 fix upload message isEmpty 2022-01-28 20:41:57 +08:00
e2083b1c47 新增文件接口 2022-01-28 20:27:45 +08:00
48651c384f 新增文件接口 2022-01-28 20:26:20 +08:00
bcae613e74 新增文件接口 2022-01-28 20:06:15 +08:00
5fa740c58f 修复QQ接口无法使用的问题 2022-01-16 12:31:39 +08:00
b5076323d7 优化获取小米路由器后台token 2022-01-09 18:55:02 +08:00
8e98929622 新增开门指令 2022-01-09 03:32:30 +08:00
aa935e8662 大头菜调整为本地站点从而提升加载速度
调整无头浏览器参数
升级fastjson版本
2022-01-08 13:23:52 +08:00
7d1128cc1d 大头菜支持群@ 2022-01-05 15:27:05 +08:00
ba7b933bdb 增加大头菜对群的支持
Model新增识别群并@发送人的方法
2022-01-02 10:47:48 +08:00
8f19448239 update 2022-01-02 01:00:24 +08:00
6e4fc0c3d3 修复QQ发图片会资源泄露的问题 2022-01-02 00:59:22 +08:00
6a68e95f45 新增涩图
更新QQ机器人
2022-01-02 00:40:09 +08:00
75f3a68faf 新增涩图 2022-01-02 00:18:48 +08:00
1bf0336b72 新增涩图 2022-01-02 00:16:36 +08:00
5b928afa82 新增涩图 2022-01-02 00:14:27 +08:00
eedd304c43 新增涩图 2022-01-01 23:40:14 +08:00
fb75b5206c 新增涩图 2022-01-01 23:36:12 +08:00
55da787d66 大头菜新增周日满背包价格 2021-12-26 10:25:07 +08:00
33c7f0df56 上次提交忘记加版本号了 2021-12-26 09:10:15 +08:00
66ae1c4e8b 调整天使动漫签到时间
修复大头菜不记录上周趋势的BUG
调整汇报大头菜结果时加入网页地址
2021-12-26 09:08:54 +08:00
e0751972a3 修复路由器扫描问题 2021-12-20 17:52:28 +08:00
59477d518a 完善开门接口 2021-12-20 17:34:23 +08:00
e7719b6cfe update 2021-12-20 01:01:07 +08:00
b430143037 update 2021-12-20 00:59:16 +08:00
edfddd7e17 预备开门页面及接口 2021-12-20 00:47:02 +08:00
a73a5b34e2 update 2021-12-18 17:38:43 +08:00
618f91457f 新增接口重启机器人 2021-12-18 17:33:14 +08:00
e2432b5942 修复通知时间会卡主的问题
修复重复获取路由器状态问题
2021-12-18 17:23:12 +08:00
7b1050b4e3 调整时间通知为每秒
新增wifi设备连入退出判断
为下发开门指令做准备
2021-12-16 23:25:05 +08:00
109 changed files with 75287 additions and 665 deletions

17
KFCFactory.json Normal file
View File

@@ -0,0 +1,17 @@
{
"8.9.63": {
"base_url": "http://192.168.31.88:7400",
"type": "fuqiuluo/unidbg-fetch-qsign",
"key": "114514"
},
"0.1.0": {
"base_url": "http://127.0.0.1:8888",
"type": "kiliokuara/magic-signer-guide",
"server_identity_key": "vivo50",
"authorization_key": "kfc"
},
"8.8.88": {
"base_url": "http://127.0.0.1:80",
"type": "TLV544Provider"
}
}

Binary file not shown.

0
mvnw vendored Normal file → Executable file
View File

108
pom.xml
View File

@@ -35,39 +35,32 @@
<dependency>
<groupId>net.mamoe</groupId>
<artifactId>mirai-core-jvm</artifactId>
<version>2.7.1</version>
<version>2.15.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-jdk8</artifactId>
<version>1.5.2</version>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-coroutines-core-jvm</artifactId>
<version>1.5.2</version>
<version>1.6.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.0-RC1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.4.7</version>
<version>4.3.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.78</version>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.22</version>
</dependency>
<dependency>
@@ -84,17 +77,91 @@
<scope>system</scope>
<systemPath>${project.basedir}/libs/json-jena-1.0.jar</systemPath>
</dependency>
<dependency>
<groupId>com.fix-protocol-version.mirai2</groupId>
<artifactId>mirai2</artifactId>
<version>1.9.9</version>
<scope>system</scope>
<systemPath>${project.basedir}/libs/fix-protocol-version-1.9.9.mirai2.jar</systemPath>
</dependency>
<!-- QQ协议修复的依赖 -->
<dependency>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client</artifactId>
<version>2.12.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<version>4.7.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-chrome-driver</artifactId>
<version>4.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-api -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>4.7.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-remote-driver -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-remote-driver</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-http-jdk-client</artifactId>
<version>4.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.21.12</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java-util</artifactId>
<version>3.21.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.reflections/reflections
-->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.10.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.brotli/dec -->
<dependency>
<groupId>org.brotli</groupId>
<artifactId>dec</artifactId>
<version>0.1.2</version>
</dependency>
</dependencies>
@@ -114,7 +181,9 @@
<configuration>
<tasks>
<echo>复制正式文件</echo>
<copy file="src/main/resources/application.properties.release" tofile="${project.build.outputDirectory}/application.properties" overwrite="true"/>
<copy file="src/main/resources/application.properties.release"
tofile="${project.build.outputDirectory}/application.properties"
overwrite="true"/>
</tasks>
</configuration>
</execution>
@@ -149,6 +218,7 @@
<!--使用-Dloader.path需要在打包的时候增加<layout>ZIP</layou
t>,不指定的话-Dloader.path不生效-->
<layout>ZIP</layout>
<includeSystemScope>true</includeSystemScope>
<!-- 指定该jar包启动时的主类[建议] -->
<mainClass>com.yutou.qqbot.QQBotApplication</mainClass>
</configuration>
@@ -159,12 +229,6 @@
<goal>repackage</goal>
</goals>
<configuration>
<outputDirectory>
X:\servier\qqbot\
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>

View File

@@ -0,0 +1,8 @@
package com.yutou.bilibili;
public class BaseAPI {
public static final String BASE_URL = "https://api.bilibili.com/";
public static final String MCBBS_PNG = "https://www.mcbbs.net/template/mcbbs/image/special_photo_bg.png";
public static final String ACCESS_TOKEN = "https://passport.bilibili.com/login/app/third";
}

View File

@@ -0,0 +1,9 @@
package com.yutou.bilibili.api;
public class LiveAPI {
public static final String LIVE_SEND_DANMU="https://api.live.bilibili.com/msg/send";
public static final String LIVE_ROOM_INFO = "https://api.live.bilibili.com/room/v1/Room/get_info";
public static final String LIVE_TASK_PROGRESS = "https://api.live.bilibili.com/xlive/app-ucenter/v1/userTask/GetUserTaskProgress";
public static final String LIVE_SET_TASK_PROGRESS = "https://api.live.bilibili.com/xlive/app-ucenter/v1/userTask/UserTaskReceiveRewards";
}

View File

@@ -0,0 +1,7 @@
package com.yutou.bilibili.api;
public class LoginAPI {
public static final String LOGIN_QRCODE = "https://passport.bilibili.com/x/passport-login/web/qrcode/generate";
public static final String LOGIN_QRCODE_POLL="https://passport.bilibili.com/x/passport-login/web/qrcode/poll";
}

View File

@@ -0,0 +1,9 @@
package com.yutou.bilibili.api;
public class MangaApi {
public static final String SIGN = "https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn";
public static final String LIST_PRODUCT_DATE = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/ListProduct";
public static final String USER_POINT = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/GetUserPoint";
public static final String PAY_MISSION = "https://manga.bilibili.com/twirp/pointshop.v1.Pointshop/Exchange";
}

View File

@@ -0,0 +1,7 @@
package com.yutou.bilibili.api;
public class SignApi {
public static final String LIVE_SIGN_COIN = "https://api.live.bilibili.com/xlive/revenue/v1/wallet/silver2coin";
public static final String LIVE_SIGN = "https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign";
public static final String VIP_SIGN = "https://api.bilibili.com/pgc/activity/score/task/sign";
}

View File

@@ -0,0 +1,10 @@
package com.yutou.bilibili.api;
public class UserApi {
@Deprecated
public static final String USER_INFO = "https://api.bilibili.com/x/space/acc/info";
public static final String USER_INFO_V2="https://api.bilibili.com/x/space/wbi/acc/info";
public static final String NAV = "https://api.bilibili.com/x/web-interface/nav";
}

View File

@@ -0,0 +1,9 @@
package com.yutou.bilibili.api;
public class VideoApi {
public static final String VIDEO_AI = "https://api.bilibili.com/x/web-interface/view/conclusion/get";
@Deprecated
public static final String VIDEO_PLAY_URL = "https://api.bilibili.com/x/player/playurl";
public static final String VIDEO_PLAY_URL_V2 = "https://api.bilibili.com/x/player/wbi/playurl";
}

View File

@@ -0,0 +1,109 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.message.MessageReceipt;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
@Controller
public class AppController {
@RequestMapping("/restart.do")
@ResponseBody
public String restart() {
AppTools.exec("cd /home/yutou/public/servier/qqbot && ./start.sh", null, true, false);
return "";
}
@ResponseBody
@RequestMapping("/door/set.do")
public String openDoor(String status) {
RedisTools.set("door", status);
return "1";
}
@ResponseBody
@RequestMapping("/door/get.do")
public String getDoor() {
if ("open".equals(RedisTools.get("door"))) {
RedisTools.set("door", "on");
return "1";
}
return "0";
}
@ResponseBody
@RequestMapping("/door/status.do")
public String getStatus() {
String status = RedisTools.get("door");
if ("open".equals(status)) {
return "0";
} else if ("on".equals(status)) {
return "2";
} else if ("over".equals(status)) {
RedisTools.set("door", "ready");
return "1";
}
return "-1";
}
@ResponseBody
@RequestMapping("/qq/send.do")
public String sendQQ(@RequestBody JSONObject json) {
File image = null;
MessageReceipt<?> ret;
if(json.getString("message").isEmpty()){
return "not message";
}
if (json.containsKey("image")) {
image = HttpTools.syncDownload(json.getString("image"), System.currentTimeMillis() + ".png",true);
}
ret = QQBotManager.getInstance().sendMessage(image, json.getLong("qq"), json.getString("message"));
return ret==null?"message send fail":"message send success";
}
@ResponseBody
@RequestMapping("/qq/file.do")
public String sendFile(@RequestParam("image") MultipartFile file) throws Exception {
String path=AppTools.createFile("tmp",file,System.currentTimeMillis()+".png");
if(StringUtils.isEmpty(path)){
return "not file";
}
File _file=new File(path);
QQBotManager.getInstance().sendMessage(_file,583819556L,"time = "+AppTools.getToDayNowTimeToString());
return "ok";
}
@RequestMapping("/test.do")
@ResponseBody
public String test(HttpServletResponse response){
System.out.println("NAS自动关机");
/* try {
response.sendRedirect("http://192.168.31.88:9999/live/index.m3u8");
} catch (IOException e) {
e.printStackTrace();
}*/
// return HttpTools.http_get("http://192.168.31.88:9999/live/index.m3u8",null);
return "1";
}
@RequestMapping("*.ts")
public void test2(HttpServletResponse response, HttpServletRequest request){
try {
response.sendRedirect("http://192.168.31.88:9999/live"+request.getRequestURI());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,30 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.BiliBili.BiliVideo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BiliBiliController {
@RequestMapping("/bilibili/down.do")
@ResponseBody
public JSONObject downloadBili(String data) {
new Thread(() -> {
JSONObject json = JSONObject.parseObject(data);
System.out.println("json = " + json);
String url = json.getString("url");
boolean downDanmu = json.containsKey("danmu") && "on".equals(json.getString("danmu"));
boolean merge = json.containsKey("merge") && "on".equals(json.getString("merge"));
BiliVideo video = new BiliVideo(QQBotManager.defQQ);
video.downVideo(url, downDanmu, merge);
}
).start();
JSONObject json = new JSONObject();
json.put("msg", "ok");
json.put("code", 0);
return json;
}
}

View File

@@ -0,0 +1,240 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.jianr.AndroidDevice;
import com.yutou.qqbot.data.jianr.JianRScriptV2Data;
import com.yutou.qqbot.utlis.JianRTaskManager;
import com.yutou.qqbot.utlis.RedisTools;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
@Controller
public class JianRScriptController {
@RequestMapping("/jianr/run.do")
@ResponseBody
public JSONObject runScript(String task, String device, String modelName) {
JSONObject json = new JSONObject();
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, task);
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, device);
if (data == null || deviceJsonString == null) {
json.put("code", -1);
json.put("msg", "没有找到该方案或设备错误,请配置");
} else {
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
JianRTaskManager manager = JianRTaskManager.getInstance();
if (manager.isRunning()) {
manager.stop();
}
for (int i = 0; i < androidDevice.getDeviceDisplay().size(); i++) {
if (androidDevice.getDeviceDisplay().get(i).getTitle().equals(modelName)) {
manager.setModelId(i);
break;
}
}
manager.setTask(script, androidDevice);
manager.start();
json.put("code", 0);
json.put("msg", "任务创建成功");
}
return json;
}
@RequestMapping("/jianr/stop.do")
@ResponseBody
public JSONObject stop() {
JianRTaskManager.getInstance().stop();
JSONObject json = new JSONObject();
json.put("code", 0);
json.put("msg", "任务已停止");
return json;
}
@RequestMapping("/jianr/status.do")
@ResponseBody
public JSONObject status() {
JSONObject json = new JSONObject();
JSONObject data = new JSONObject();
JianRTaskManager manager = JianRTaskManager.getInstance();
data.put("status", manager.isRunning());
data.put("runIndex", manager.getRunIndex());
data.put("taskName", manager.getTaskName());
data.put("log", manager.getLog());
json.put("code", 0);
json.put("data", data);
return json;
}
@RequestMapping("/jianr/task/list.do")
@ResponseBody
public JSONObject tasks() {
JSONObject json = new JSONObject();
JSONArray array = new JSONArray();
Map<String, String> map = RedisTools.getHashMap(JianRTaskManager.Redis_Script);
array.addAll(map.keySet());
json.put("code", 0);
json.put("data", array);
return json;
}
@RequestMapping("/jianr/task/add.do")
@ResponseBody
public JSONObject addTask(String task) {
JSONObject json = new JSONObject();
JSONObject data = JSON.parseObject(task);
if (data == null) {
json.put("code", -1);
json.put("msg", "JSON格式错误");
} else {
String taskName = data.getString("title");
if (RedisTools.getHashMap(JianRTaskManager.Redis_Script).containsKey(taskName)) {
json.put("code", -1);
json.put("msg", "该任务名称已存在");
} else {
RedisTools.setHashMap(JianRTaskManager.Redis_Script, taskName, task);
json.put("code", 0);
json.put("msg", "任务创建成功");
}
}
return json;
}
@RequestMapping("/jianr/task/get.do")
@ResponseBody
public JSONObject getTask(String task) {
JSONObject json = new JSONObject();
json.put("code", 0);
json.put("data", RedisTools.getHashMap(JianRTaskManager.Redis_Script, task));
return json;
}
@RequestMapping("/jianr/task/remove.do")
@ResponseBody
public JSONObject removeTask(String task) {
RedisTools.removeHashMap(JianRTaskManager.Redis_Script, task);
JSONObject json = new JSONObject();
json.put("code", 0);
json.put("msg", "任务删除成功");
return json;
}
@RequestMapping("/jianr/device/connect.do")
@ResponseBody
public JSONObject connectDevice(String device) {
JSONObject json = new JSONObject();
JianRTaskManager.getInstance().connect(device);
json.put("code", 0);
json.put("msg", "成功");
return json;
}
@RequestMapping("/jianr/device/add.do")
@ResponseBody
public JSONObject addDevice(String device) {
Map<String, String> hashMap = RedisTools.getHashMap(JianRTaskManager.Redis_Device);
JSONObject deviceJson = JSON.parseObject(device);
JSONObject json = new JSONObject();
json.put("code", 0);
if (deviceJson == null) {
json.put("msg", "JSON格式错误");
} else {
if (hashMap.containsKey(device)) {
json.put("msg", "设备已存在");
} else {
json.put("msg", RedisTools.setHashMap(JianRTaskManager.Redis_Device,
deviceJson.getString("title"), device) ?
"设备添加成功" : "设备添加失败");
}
}
return json;
}
@RequestMapping("/jianr/device/edit.do")
@ResponseBody
public JSONObject editDevice(String device, String oldDevice) {
JSONObject deviceJson = JSON.parseObject(device);
JSONObject json = new JSONObject();
json.put("code", 0);
if (deviceJson == null) {
json.put("msg", "JSON格式错误");
} else {
RedisTools.removeHashMap(JianRTaskManager.Redis_Device, oldDevice);
json.put("msg", RedisTools.setHashMap(JianRTaskManager.Redis_Device,
deviceJson.getString("title"), device) ?
"设备修改成功" : "设备修改失败");
}
return json;
}
@RequestMapping("/jianr/device/del.do")
@ResponseBody
public JSONObject delDevice(String device) {
JSONObject deviceJson = JSON.parseObject(device);
JSONObject json = new JSONObject();
json.put("code", 0);
if (deviceJson == null) {
json.put("msg", "JSON格式错误");
} else {
json.put("msg", RedisTools.removeHashMap(JianRTaskManager.Redis_Device) ?
"设备修改成功" : "设备修改失败");
}
return json;
}
@RequestMapping("/jianr/device/list.do")
@ResponseBody
public JSONObject getDeviceList() {
Map<String, String> hashMap = RedisTools.getHashMap(JianRTaskManager.Redis_Device);
JSONObject json = new JSONObject();
JSONArray array = new JSONArray();
json.put("code", 0);
hashMap.keySet().forEach(key -> {
JSONObject device = JSONObject.parseObject(hashMap.get(key));
JSONArray child = new JSONArray();
JSONObject item = new JSONObject();
JSONObject del = new JSONObject();
JSONObject edit = new JSONObject();
JSONObject select = new JSONObject();
JSONObject connect = new JSONObject();
item.put("title", key);
del.put("title", "删除");
del.put("data", "del");
del.put("device", device);
edit.put("title", "编辑");
edit.put("data", "edit");
edit.put("device", device);
select.put("title", "选择");
select.put("data", "select");
select.put("device", device);
connect.put("title", "连接设备");
connect.put("data", "connect");
connect.put("device", device);
child.add(connect);
child.add(select);
child.add(del);
child.add(edit);
item.put("child", child);
array.add(item);
});
json.put("data", array);
return json;
}
public static void main(String[] args) {
Map<String, String> hashMap = RedisTools.getHashMap(JianRTaskManager.Redis_Device);
JSONObject json = new JSONObject();
JSONArray array = new JSONArray();
json.put("code", 0);
hashMap.keySet().forEach(key -> {
JSONObject item = JSONObject.parseObject(hashMap.get(key));
array.add(item);
});
json.put("data", array);
System.out.println(json);
}
}

View File

@@ -0,0 +1,79 @@
package com.yutou.qqbot.Controllers;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.models.XiaoMi.MiRouter;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.XiaoMiRouter;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller
@RequestMapping("/router/")
public class MiRouterDevices {
@RequestMapping("device/add.do")
@ResponseBody
public String addDevice(HttpServletRequest request,String qq) {
String data = RedisTools.get(MiRouter.redis_key);
JSONArray array;
if (data == null) {
array = new JSONArray();
} else {
array = JSON.parseArray(data);
}
for (Object o : array) {
JSONObject item = (JSONObject) o;
if (item.getString("mac").equals(getRemoteAddress(request.getRemoteAddr()))) {
return "已经添加过了";
}
}
JSONObject item=new JSONObject();
item.put("qq",qq);
item.put("mac",getRemoteAddress(request.getRemoteAddr()));
item.put("online",false);
array.add(item);
RedisTools.set(MiRouter.redis_key,array.toString());
return "添加成功,关闭当前页面即可";
}
@ResponseBody
@RequestMapping("device/del.do")
public String delDevice(HttpServletRequest request,String qq){
String data = RedisTools.get(MiRouter.redis_key);
JSONArray array;
if (data == null) {
array = new JSONArray();
} else {
array = JSON.parseArray(data);
}
JSONArray _array= JSON.parseArray(array.toString());
for (Object o : array) {
JSONObject item = (JSONObject) o;
if (item.getString("mac").equals(getRemoteAddress(request.getRemoteAddr()))) {
_array.remove(item);
RedisTools.set(MiRouter.redis_key,_array.toString());
return "已成功删除";
}
}
return "未找到该设备";
}
private String getRemoteAddress(String ip) {
JSONObject data = JSON.parseObject(HttpTools.get(XiaoMiRouter.getDeviceListUrl()));
if (data.getInteger("code") == 0) {
JSONArray array=data.getJSONArray("list");
for (Object o : array) {
JSONObject item= (JSONObject) o;
if(item.getJSONArray("ip").getJSONObject(0).getString("ip").equals(ip)){
return item.getString("mac");
}
}
}
return null;
}
}

View File

@@ -3,7 +3,6 @@ package com.yutou.qqbot.Listeners;
import com.yutou.qqbot.MessageEvent.AdminMessage;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.Log;
import kotlin.coroutines.CoroutineContext;
import net.mamoe.mirai.event.EventHandler;
import net.mamoe.mirai.event.ListeningStatus;

View File

@@ -4,11 +4,15 @@ import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.models.WebSign.BaiHeHui;
import com.yutou.qqbot.models.WebSign.NicePT;
import com.yutou.qqbot.models.WebSign.Tsdm;
import com.yutou.qqbot.models.WebSign.ZhuZhu;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.StringUtils;
import com.yutou.qqbot.utlis.WebClient;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
public class AdminMessage extends Message {
@@ -21,13 +25,16 @@ public class AdminMessage extends Message {
private static final String MODEL_SHOW = "!查看模块";
private static final String MODEL_DEL = "!删除模块";
public static final String SYSTEM_RESTART_QQ="!重启qq";
public static final String SYSTEM_RESTART_TOOLS="!重启服务";
public static final String SYSTEM_RESTART_QQ = "!重启qq";
public static final String SYSTEM_RESTART_TOOLS = "!重启服务";
public static final String SYSTEM_UPDATE_QQ = "!更新qq";
public static final String SYSTEM_UPDATE_NAS = "!更新服务";
private static final String SHOW="!列表";
private static final String HELP="!help";
private static final String SIGN="!签到";
private static final String SHOW = "!列表";
private static final String HELP = "!help";
private static final String SIGN = "!签到";
}
public AdminMessage(Long qq, String msg) {
@@ -35,7 +42,7 @@ public class AdminMessage extends Message {
String[] msgGroup = msg.replace("", "!").split(" ");
switch (msgGroup[0]) {
case QQCommands.HELP -> QQBotManager.getInstance().sendMessage(qq,Model.getCommands(QQCommands.class).toString());
case QQCommands.HELP -> QQBotManager.getInstance().sendMessage(qq, Model.getCommands(QQCommands.class).toString());
case QQCommands.POWER_ADD -> {
if (msgGroup.length == 1) {
StringBuilder builder = Model.getCommands(Model.QQGroupCommands.class);
@@ -78,6 +85,12 @@ public class AdminMessage extends Message {
if (msgGroup.length == 1) {
StringBuilder builder = new StringBuilder();
for (Class<?> aClass : Model.classList) {
try {
Model model = (Model) aClass.getDeclaredConstructor().newInstance();
builder.append("[").append(model.getModelName()).append("]");
} catch (Exception e) {
e.printStackTrace();
}
builder.append(aClass.getName()).append("\n");
}
QQBotManager.getInstance().sendMessage(qq, "使用方法:" + QQCommands.MODEL_ADD + " [qqnumber] 模块" + "\n" + "可设置以下模块,用&分割");
@@ -86,7 +99,11 @@ public class AdminMessage extends Message {
if (msgGroup.length <= 2) {
addModel(msgGroup[1], null);
} else {
addModel(msgGroup[1], msgGroup[2]);
if ("this".equals(msgGroup[1])) {
addModel(sendQQ + "", msgGroup[2]);
} else {
addModel(msgGroup[1], msgGroup[2]);
}
}
}
}
@@ -94,74 +111,132 @@ public class AdminMessage extends Message {
if (msgGroup.length == 1) {
QQBotManager.getInstance().sendMessage(qq, "使用方法:" + QQCommands.MODEL_SHOW + " [qqnumber]");
} else {
List<String> list = QQNumberManager.getManager().getUseModel(Long.parseLong(msgGroup[1]));
String qqGroup = msgGroup[1];
if ("this".equals(qqGroup)) {
qqGroup = sendQQ + "";
}
List<String> list = QQNumberManager.getManager().getUseModel(Long.parseLong(qqGroup));
StringBuilder builder = new StringBuilder();
for (String power : list) {
builder.append(power).append("\n");
}
QQBotManager.getInstance().sendMessage(qq, Long.parseLong(msgGroup[1]) + " 拥有以下模块:" + builder);
QQBotManager.getInstance().sendMessage(qq, Long.parseLong(qqGroup) + " 拥有以下模块:" + builder);
}
}
case QQCommands.MODEL_DEL -> {
if (msgGroup.length == 1) {
QQBotManager.getInstance().sendMessage(qq, "使用方法:" + QQCommands.MODEL_DEL + " [qqnumber] 模块 用&分割");
} else {
String qqGroup = msgGroup[1];
if ("this".equals(qqGroup)) {
qqGroup = sendQQ + "";
}
if (msgGroup.length <= 2) {
delModel(msgGroup[1], null);
delModel(qqGroup, null);
} else {
delModel(msgGroup[1], msgGroup[2]);
delModel(qqGroup, msgGroup[2]);
}
}
}
case QQCommands.SHOW -> {
List<Long> users=QQNumberManager.getManager().getNumber();
StringBuilder builder=new StringBuilder();
List<Long> users = QQNumberManager.getManager().getNumber();
StringBuilder builder = new StringBuilder();
for (Long user : users) {
builder.append(user).append(":\n");
List<String> modelPower=QQNumberManager.getManager().getUseModel(user);
List<String> modelPower = QQNumberManager.getManager().getUseModel(user);
builder.append("模块(").append(modelPower.size()).append("):\n");
for (String model : modelPower) {
builder.append(model).append("\n");
}
List<String> list=QQNumberManager.getManager().getPower(user);
List<String> list = QQNumberManager.getManager().getPower(user);
builder.append("权限(").append(list.size()).append("):\n");
for (String power : list) {
builder.append(power).append("\n");
}
builder.append("\n");
}
QQBotManager.getInstance().sendMessage(qq,builder.toString());
QQBotManager.getInstance().sendMessage(qq, builder.toString());
}
case QQCommands.SYSTEM_RESTART_QQ -> {
QQBotManager.getInstance().sendMessage(qq,"正在重启机器人");
QQBotManager.getInstance().sendMessage(qq, "正在重启机器人");
System.out.println("结束进程");
AppTools.exec("cd /home/yutou/public/servier/qqbot && ./start.sh",null,true,false);
AppTools.exec("cd /home/yutou/public/servier/qqbot && ./start.sh", null, true, false);
}
case QQCommands.SYSTEM_RESTART_TOOLS ->{
QQBotManager.getInstance().sendMessage(qq,"正在重启服务");
case QQCommands.SYSTEM_RESTART_TOOLS -> {
QQBotManager.getInstance().sendMessage(qq, "正在重启服务");
System.out.println("结束进程");
AppTools.exec("cd /home/yutou/public/servier/tools && ./start.sh",null,true,false);
AppTools.exec("cd /home/yutou/public/servier/tools && ./start.sh", null, true, false);
}
case QQCommands.SYSTEM_UPDATE_QQ -> {
QQBotManager.getInstance().sendMessage(qq, "正在更新qq");
System.out.println("结束进程");
AppTools.exec("cd /home/yutou/git/QQBot && ./update.sh", null, true, false);
}
case QQCommands.SYSTEM_UPDATE_NAS -> {
QQBotManager.getInstance().sendMessage(qq, "正在更新NAS服务");
System.out.println("结束进程");
AppTools.exec("cd /home/yutou/git/nas-service && ./update.sh", null, true, false);
}
case QQCommands.SIGN -> {
boolean sign=true;
boolean sign = true;
boolean tsdmSign = false, baiheSign = false, nicePtSign = false, zhuzhuSign=false;
Log.i("开始签到");
try{
new Tsdm().tsdmSign();
}catch (Exception e){
sign=false;
QQBotManager.getInstance().sendMessage(qq,"tsdm签到失败:"+AppTools.getExceptionString(e));
try {
if (new Tsdm().tsdmSign()) {
tsdmSign = true;
}
} catch (Exception e) {
sign = false;
QQBotManager.getInstance().sendMessage(qq, "tsdm签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}
try {
new BaiHeHui().sign();
}catch (Exception e){
sign=false;
QQBotManager.getInstance().sendMessage(qq,"百合会签到失败:"+AppTools.getExceptionString(e));
if (new BaiHeHui().sign()) {
baiheSign = true;
}
} catch (Exception e) {
sign = false;
QQBotManager.getInstance().sendMessage(qq, "百合会签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}
if(sign){
QQBotManager.getInstance().sendMessage(qq,"签到任务完成");
try {
if (new NicePT().sign()) {
nicePtSign = true;
}
} catch (Exception e) {
sign = false;
QQBotManager.getInstance().sendMessage(qq, "NicePT签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}
try {
if (new ZhuZhu().sign()) {
zhuzhuSign = true;
}
} catch (Exception e) {
sign = false;
QQBotManager.getInstance().sendMessage(qq, "HiRes花园签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}
if (sign && tsdmSign && baiheSign && nicePtSign) {
QQBotManager.getInstance().sendMessage(qq, "签到任务完成");
}else{
StringBuilder builder=new StringBuilder();
if(!tsdmSign){
builder.append("天使动漫签到失败\n");
}
if(!baiheSign){
builder.append("百合会签到失败\n");
}
if(!nicePtSign){
builder.append("NicePT签到失败\n");
}
if(!zhuzhuSign){
builder.append("HiRes花园签到失败\n");
}
QQBotManager.getInstance().sendMessage(qq,builder.toString());
}
WebClient.getInstance().quit();
}
}
}
@@ -218,20 +293,22 @@ public class AdminMessage extends Message {
}
private void delModel(String qq, String model) {
boolean flag = false;
try {
if (model == null) {
List<String> list = QQNumberManager.getManager().getUseModel(Long.parseLong(qq));
for (String power : list) {
QQNumberManager.getManager().delUseModel(Long.parseLong(qq), Class.forName(power));
flag = QQNumberManager.getManager().delUseModel(Long.parseLong(qq), Class.forName(power));
}
} else {
for (String power : model.split("&")) {
QQNumberManager.getManager().delUseModel(Long.parseLong(qq), Class.forName(power));
flag = QQNumberManager.getManager().delUseModel(Long.parseLong(qq), Class.forName(power));
}
}
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
QQBotManager.getInstance().sendMessage(sendQQ, flag ? "删除成功" : "删除失败");
}
}

View File

@@ -6,11 +6,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class QQBotApplication {
public static final String version="QQBot v.1.1.2";
public static final String version="QQBot v.1.6.2";
public static void main(String[] args) {
System.out.println("version = " + version);
SpringApplication.run(QQBotApplication.class, args);
RedisTools.initRedisPoolSub();
QQBotManager.getInstance();
//1
}
}

View File

@@ -2,6 +2,7 @@ package com.yutou.qqbot;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.Bot;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -33,4 +34,16 @@ public class QQBotController {
AppTools.sendServer(title, msg);
return "ok";
}
@ResponseBody
@RequestMapping("/bot/test.do")
public String testLogin(){
Bot bot = QQBotManager.getInstance().getBot();
return bot.isOnline()+"";
}
@ResponseBody
@RequestMapping("/bot/login.do")
public String login(){
QQBotManager.getInstance().reLogin();
return "ok";
}
}

View File

@@ -1,48 +1,29 @@
package com.yutou.qqbot;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Listeners.QQMessageListener;
import com.yutou.qqbot.models.Animal.TurnipProphet;
import com.yutou.qqbot.models.Commands.BaiduDown;
import com.yutou.qqbot.models.Commands.Bangumi;
import com.yutou.qqbot.models.Commands.System.*;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.models.WebSign.Tsdm;
import com.yutou.qqbot.models.setu.QQSetu;
import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.BotFactory;
import net.mamoe.mirai.event.GlobalEventChannel;
import net.mamoe.mirai.message.data.Image;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.MessageReceipt;
import net.mamoe.mirai.message.data.*;
import net.mamoe.mirai.utils.BotConfiguration;
import net.mamoe.mirai.utils.ExternalResource;
import xyz.cssxsh.mirai.tool.FixProtocolVersion;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
public class QQBotManager {
public static Long defGroup=891655174L;
public static Long defGroup = 891655174L;
public static Long defQQ = 583819556L;
static {
Model.classList.add(QQSetu.class);
Model.classList.add(Audio.class);
Model.classList.add(BtFlash.class);
Model.classList.add(Cmd.class);
Model.classList.add(Help.class);
Model.classList.add(IP.class);
Model.classList.add(OpenPC.class);
Model.classList.add(Restart.class);
Model.classList.add(ToolsIdea.class);
Model.classList.add(UpdateIP.class);
Model.classList.add(Version.class);
Model.classList.add(Bangumi.class);
Model.classList.add(TurnipProphet.class);
Model.classList.add(Tsdm.class);
Model.classList.add(BaiduDown.class);
}
private static QQBotManager botManager = null;
private Bot bot;
private static final long qqGroup = 891655174L;
@@ -54,19 +35,49 @@ public class QQBotManager {
Object isRun = ConfigTools.load(ConfigTools.CONFIG, "qq_bot");
if (isRun != null && (boolean) isRun) {
isLogin = true;
isInit = true;
init();
}
}
private void init() {
new Thread(new Runnable() {
private void reset() {
try {
Log.i("QQBot", "签名加密服务未启动,1分钟后重试");
Thread.sleep(60 * 1000);
init();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
long qq = ConfigTools.load(ConfigTools.CONFIG,"qq_number",Long.class);
String password = ConfigTools.load(ConfigTools.CONFIG,"qq_password",String.class);
String url=ConfigTools.load(ConfigTools.CONFIG,"sign_url",String.class);
if(StringUtils.isEmpty(url)){
url="http://192.168.31.88:7400/";
}
String test = HttpTools.get(url);
try {
JSONObject json = JSONObject.parseObject(test);
if (json.getInteger("code") != 0) {
reset();
return;
}
} catch (Exception e) {
reset();
return;
}
long qq = ConfigTools.load(ConfigTools.CONFIG, "qq_number", Long.class);
String password = ConfigTools.load(ConfigTools.CONFIG, "qq_password", String.class);
System.out.println("qq = " + qq);
System.out.println("password = " + password);
FixProtocolVersion.load(BotConfiguration.MiraiProtocol.ANDROID_PAD);
bot = BotFactory.INSTANCE.newBot(qq, password, new BotConfiguration() {
{
setProtocol(MiraiProtocol.ANDROID_PAD);
fileBasedDeviceInfo("qq_bot_devices_info.json");
if ("nas".equals(ConfigTools.load(ConfigTools.CONFIG, "model"))) {
@@ -77,7 +88,7 @@ public class QQBotManager {
});
//Events.registerEvents(bot, new MessageListener());
GlobalEventChannel.INSTANCE.registerListenerHost(new QQMessageListener());
// GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, new MessageListener());
// GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, new MessageListener());
bot.login();
new Thread(new Runnable() {
@Override
@@ -87,19 +98,18 @@ public class QQBotManager {
} catch (InterruptedException e) {
e.printStackTrace();
}
String str = sendMessage("姬妻酱上线拉~☆Daze~ 当前版本:"+QQBotApplication.version);
String str = sendMessage("姬妻酱上线拉~☆Daze~ 当前版本:" + QQBotApplication.version);
Log.i(str);
isInit = true;
}
}).start();
bot.join();
}
}).start();
}
public static QQBotManager getInstance() {
public synchronized static QQBotManager getInstance() {
if (botManager == null && !isInit) {
botManager = new QQBotManager();
}
@@ -110,13 +120,24 @@ public class QQBotManager {
return isLogin;
}
private Image getImage(File file,Long qq) {
private Image getImage(File file, Long qq) {
if (file == null) {
return null;
}
if (bot != null) {
if(QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).uploadImage(ExternalResource.create(file));
}else{
return Objects.requireNonNull(bot.getFriend(qq)).uploadImage(ExternalResource.create(file));
ExternalResource resource = ExternalResource.create(file);
Image image;
if (QQNumberManager.getManager().isGroup(qq)) {
image = Objects.requireNonNull(bot.getGroup(qq)).uploadImage(resource);
} else {
image = Objects.requireNonNull(bot.getFriend(qq)).uploadImage(resource);
}
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
return null;
}
@@ -127,7 +148,7 @@ public class QQBotManager {
public String sendMessage(String text) {
if (bot != null&&!StringUtils.isEmpty(text)) {
if (bot != null && !StringUtils.isEmpty(text)) {
try {
return Objects.requireNonNull(bot.getGroup(qqGroup)).sendMessage(text).toString();
} catch (Exception e) {
@@ -137,66 +158,87 @@ public class QQBotManager {
return getNotLoginQQ();
}
public String sendMessage(Long group, String text) {
public MessageReceipt<?> sendMessage(Long group, String text) {
if (bot != null) {
try {
if(QQNumberManager.getManager().isGroup(group)) {
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(text).toString();
}else{
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(text).toString();
if (QQNumberManager.getManager().isGroup(group)) {
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(text);
} else {
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(text);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return getNotLoginQQ();
return null;
}
public void sendMessage(Long group, MessageChainBuilder builder) {
public MessageReceipt<?> sendMessage(Long group, MessageChainBuilder builder) {
if (bot != null) {
if(QQNumberManager.getManager().isGroup(group)) {
Objects.requireNonNull(bot.getGroup(group)).sendMessage(builder.asMessageChain());
}else{
Objects.requireNonNull(bot.getFriend(group)).sendMessage(builder.asMessageChain());
if (QQNumberManager.getManager().isGroup(group)) {
System.out.println("发群");
return Objects.requireNonNull(bot.getGroup(group)).sendMessage(builder.asMessageChain());
} else {
System.out.println("发个人");
return Objects.requireNonNull(bot.getFriend(group)).sendMessage(builder.asMessageChain());
}
}
return null;
}
public String sendMessage(File imageFile,Long qq,String text){
public MessageReceipt<?> sendMessage(File imageFile, Long qq, String text) {
return sendMessage(imageFile, qq, null, text);
}
public MessageReceipt<?> sendMessage(File imageFile, Long qq, MessageChain replyMessage, String text) {
try {
if (bot != null) {
Image image = getImage(imageFile,qq);
Image image = getImage(imageFile, qq);
MessageChainBuilder builder = new MessageChainBuilder();
if (replyMessage != null) {
builder.append(new QuoteReply(replyMessage));
}
if (image != null) {
builder.append(image);
}
List<String> list = PatternTools.getQQ(text);
if (!list.isEmpty()) {
for (String _qq : list) {
String[] tmp = text.split(_qq);
builder.append(tmp[0]);
builder.append(new At(Long.parseLong(_qq.replace("@", ""))));
text = text.replace(tmp[0] + _qq, "");
}
}
builder.append(text);
if(QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).sendMessage(builder.asMessageChain()).toString();
}else{
return Objects.requireNonNull(bot.getFriend(qq)).sendMessage(builder.asMessageChain()).toString();
if (QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).sendMessage(builder.asMessageChain());
} else {
return Objects.requireNonNull(bot.getFriend(qq)).sendMessage(builder.asMessageChain());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return getNotLoginQQ();
}
public String sendMessage(File imageFile, String text) {
return sendMessage(imageFile,qqGroup,text);
return null;
}
public String sendMessage(List<File> imgs,Long qq, String text) {
public MessageReceipt<?> sendMessage(File imageFile, String text) {
return sendMessage(imageFile, qqGroup, text);
}
public String sendMessage(List<File> imgs, Long qq, String text) {
System.out.println("imgs.size() = " + imgs.size());
if (bot != null) {
MessageChainBuilder builder = new MessageChainBuilder();
for (File img : imgs) {
builder.append(Objects.requireNonNull(getImage(img,qq)));
builder.append(Objects.requireNonNull(getImage(img, qq)));
}
builder.append(text);
if(QQNumberManager.getManager().isGroup(qq)) {
if (QQNumberManager.getManager().isGroup(qq)) {
return Objects.requireNonNull(bot.getGroup(qq)).sendMessage(builder.asMessageChain()).toString();
}else{
} else {
return Objects.requireNonNull(bot.getFriend(qq)).sendMessage(builder.asMessageChain()).toString();
}
}
@@ -204,9 +246,14 @@ public class QQBotManager {
}
public static void main(String[] args) {
getInstance();
JSONObject json = new JSONObject();
json.put("t1", 3234567890L);
System.out.println("json = " + json);
String tmp = json.toString();
JSONObject json2 = JSON.parseObject(tmp);
System.out.println("json2 = " + json2);
}
public void sendVersion() {
@@ -218,5 +265,15 @@ public class QQBotManager {
}
public Bot getBot() {
return bot;
}
public void reLogin() {
isInit=false;
if(bot.isOnline()){
bot.close();
}
init();
}
}

View File

@@ -1,7 +1,8 @@
package com.yutou.qqbot;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.RedisTools;
import redis.clients.jedis.Jedis;
@@ -12,56 +13,61 @@ import java.util.Set;
public class QQNumberManager {
private static QQNumberManager manager;
private QQNumberManager(){
private QQNumberManager() {
}
public static QQNumberManager getManager() {
if(manager==null) {
manager=new QQNumberManager();
if (manager == null) {
manager = new QQNumberManager();
}
return manager;
}
public void addNumber(Long qq,boolean isGroup){
if(RedisTools.exists(qq,null)){
public void addNumber(Long qq, boolean isGroup) {
if (RedisTools.exists(qq, null)) {
return;
}
JSONObject json=new JSONObject();
json.put("group",isGroup);
json.put("power",new JSONArray());
json.put("model",new JSONArray());
RedisTools.set(qq,json.toJSONString());
JSONObject json = new JSONObject();
json.put("group", isGroup);
json.put("power", new JSONArray());
json.put("model", new JSONArray());
RedisTools.set(qq, json.toJSONString());
}
public List<Long> getNumber(){
List<Long> list =new ArrayList<>();
Jedis jedis=RedisTools.getRedis();
public List<Long> getNumber() {
List<Long> list = new ArrayList<>();
Jedis jedis = RedisTools.getRedis();
jedis.select(RedisTools.QQBOT_USER);
Set<String> set=jedis.keys("*");
Set<String> set = jedis.keys("*");
for (String s : set) {
try {
list.add(Long.parseLong(s));
}catch (Exception ignored){
list.add(Long.parseLong(s));
} catch (Exception ignored) {
}
}
jedis.close();
return list;
}
public boolean addPower(Long qq, String power){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("power");
public boolean addPower(Long qq, String power) {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("power");
array.add(power);
json.put("power",array);
return RedisTools.set(qq,json.toJSONString());
json.put("power", array);
return RedisTools.set(qq, json.toJSONString());
}
return false;
}
public List<String> getPower(Long qq){
List<String> list=new ArrayList<>();
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("power");
public List<String> getPower(Long qq) {
List<String> list = new ArrayList<>();
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("power");
for (Object power : array) {
list.add((String) power);
}
@@ -69,11 +75,12 @@ public class QQNumberManager {
}
return list;
}
public List<String> getUseModel(long qq) {
List<String> list=new ArrayList<>();
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("model");
List<String> list = new ArrayList<>();
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("model");
for (Object power : array) {
list.add((String) power);
}
@@ -81,42 +88,47 @@ public class QQNumberManager {
}
return list;
}
public boolean delPower(Long qq, String power){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("power");
public boolean delPower(Long qq, String power) {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("power");
array.remove(power);
json.put("power",array);
return RedisTools.set(qq,json.toJSONString());
json.put("power", array);
return RedisTools.set(qq, json.toJSONString());
}
return false;
}
public boolean addUseModel(Long qq,Class<?> modelClass){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("model");
public boolean addUseModel(Long qq, Class<?> modelClass) {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("model");
array.add(modelClass.getName());
json.put("model",array);
return RedisTools.set(qq,json.toJSONString());
json.put("model", array);
return RedisTools.set(qq, json.toJSONString());
}
return false;
}
public boolean delUseModel(Long qq,Class<?> modelClass){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("model");
public boolean delUseModel(Long qq, Class<?> modelClass) {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("model");
array.remove(modelClass.getName());
json.put("model",array);
return RedisTools.set(qq,json.toJSONString());
json.put("model", array);
return RedisTools.set(qq, json.toJSONString());
}
return false;
}
public boolean isExistsPower(Long qq, String... power){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("power");
public boolean isExistsPower(Long qq, String... power) {
//1
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("power");
for (String key : power) {
if(!array.contains(key)){
if (!array.contains(key)) {
return false;
}
}
@@ -124,18 +136,25 @@ public class QQNumberManager {
}
return false;
}
public boolean isGroup(Long qq){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
return json.getBoolean("group");
public boolean isGroup(Long qq) {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
return json.getBooleanValue("group");
}
return false;
}
public boolean isUseModel(Long qq,Class<?> modelClass){
if(RedisTools.exists(qq,null)){
JSONObject json=JSONObject.parseObject(RedisTools.get(qq));
JSONArray array=json.getJSONArray("model");
return array.contains(modelClass.getName());
public boolean isUseModel(Long qq, Class<?> modelClass) {
try {
if (RedisTools.exists(qq, null)) {
JSONObject json = JSON.parseObject(RedisTools.get(qq));
JSONArray array = json.getJSONArray("model");
return array.contains(modelClass.getName());
}
} catch (Exception e) {
e.printStackTrace();
Log.i("isUseModel", qq + " " + modelClass.getName());
}
return false;
}

View File

@@ -0,0 +1,98 @@
package com.yutou.qqbot.bilibili;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class AppUserTask {
private long isSurplus;
private long status;
private long progress;
private long target;
private Wallet wallet;
private List<WeekTask> weekTask = new ArrayList<>();
private long weekTotal;
private long weekGroup;
private DayTask dayTask;
public List<WeekTask> getWeekTask() {
if (weekTask == null) {
weekTask = new ArrayList<>();
}
return weekTask;
}
public static String toMessageFormat(AppUserTask oldTask, AppUserTask newTask) {
StringBuilder sb = new StringBuilder();
sb.append("当前电池数量:").append(String.format("%.2f → %.2f",
(double) oldTask.wallet.gold / 100,
(double) newTask.wallet.gold / 100)
).append("\n");
sb.append("当前银瓜子数量:").append(newTask.wallet.silver).append("\n");
sb.append("每日领取电池:").append(newTask.dayTask.toMessageFormat()).append("\n");
if (newTask.weekTask != null && !newTask.getWeekTask().isEmpty()) {
newTask.weekTask.forEach(task -> sb.append(task.toMessageFormat(newTask.weekTotal)).append("\n"));
}
return sb.toString();
}
public String toMessageFormat() {
StringBuilder sb = new StringBuilder();
sb.append("当前电池数量:").append(String.format("%.2f", (double) wallet.gold / 100)).append("\n");
sb.append("当前银瓜子数量:").append(wallet.silver).append("\n");
sb.append("每日领取电池:").append(dayTask.toMessageFormat()).append("\n");
weekTask.forEach(task -> sb.append(task.toMessageFormat(weekTotal)).append("\n"));
return sb.toString();
}
@Data
public static class DayTask {
private int status;
private long progress;
private long target;
public String toMessageFormat() {
return switch (getStatus()) {
case 0 -> "不可领取,需要发送弹幕数:" + getTarget() + ",进度:" + getProgress();
case 1 -> "进行中,需要发送弹幕数:" + getTarget() + ",进度:" + getProgress();
case 2 -> "可领取";
case 3 -> "已领取";
default -> "未知状态:" + this;
};
}
}
@Data
public static class Wallet {
private long gold;
private long silver;
}
// WeekTask.java
@Data
public static class WeekTask {
private long rewardNum;
private long minimalDay;
private int status;
private int id;
public String toMessageFormat(long totalNum) {
return switch (getStatus()) {
case 0 ->
"任务id:" + id + ",不可领取, 进度天数:" + totalNum + ",需要天数:" + minimalDay + ",任务奖励电池:" + rewardNum;
case 2 -> "任务id:" + id + ":可领取" + ",任务奖励电池:" + rewardNum;
case 3 -> "任务id:" + id + ":已领取" + ",任务奖励电池:" + rewardNum;
default -> "未知状态:" + this;
};
}
}
}

View File

@@ -0,0 +1,170 @@
package com.yutou.qqbot.bilibili;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class AssTools {
private final StringBuilder builder;
private String title;
private int y = 0;
private List<String> filters = new ArrayList<>();
private String alpha="80";
/**
* 弹幕转换ass
* @param title 标题
*/
public AssTools(String title) {
builder = new StringBuilder();
this.title=title;
initAssHeader();
}
/**
* 弹幕过滤器
* @param filter 过滤词
*/
public void addFilter(String... filter) {
filters.addAll(Arrays.asList(filter));
}
/**
* 弹幕透明度
* @param alpha 0 完全不透明 255 完全透明
*/
public void setAlpha(int alpha){
this.alpha=Integer.toHexString(alpha);
}
private void addBuilder(String txt) {
builder.append(txt).append("\n");
}
private void initAssHeader() {
addBuilder("[Script Info]");
addBuilder("Title: " + title);
addBuilder("Original Script: 本字幕由@yutou生成");
addBuilder("ScriptType: v4.00+");
addBuilder("Collisions: Normal");
addBuilder("PlayResX: 1920");
addBuilder("PlayResY: 1080");
addBuilder("Timer: 10.0000");
addBuilder("");
addBuilder("[V4+ Styles]");
addBuilder("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, ");
addBuilder("MarginL, MarginR, MarginV, Encoding");
addBuilder("Style: Fix,Microsoft YaHei UI,45,&H66FFFFFF,&H66FFFFFF,&H66000000,&H66000000,1,0,0,0,100,100,0,0,1,2,0,2,20,20,2,0");
addBuilder("Style: R2L,Microsoft YaHei UI,45,&H00FFFFFF,&H000000FF,&H00161616,&H00000000,0,0,0,0,100,100,0,0,1,2,0,2,20,20,20,1");
addBuilder("");
addBuilder("[Events]");
addBuilder("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text");
}
/**
* 保存弹幕文件
* @param savePath 存储路径
* @return 存储结果
*/
public boolean saveDanmu(String savePath) {
System.out.println("savePath = " + savePath);
File file = new File(savePath+File.separator+title+".ass");
FileWriter writer;
try {
if (file.exists()) {
if (!file.delete()) {
return false;
}
}
boolean mkdirs = file.mkdirs();
boolean delete = file.delete();
if (!mkdirs || !delete) {
return false;
}
if (!file.createNewFile()) {
return false;
}
writer = new FileWriter(file);
writer.write(builder.toString());
writer.flush();
writer.close();
return true;
} catch (IOException e) {
e.printStackTrace();
}finally {
}
return false;
}
/**
* 添加弹幕
* @param list 弹幕
*/
public void addDanmu(List<DanmuData> list) {
list.sort((o1, o2) -> {
if (o1.getTime() == o2.getTime()) {
return 0;
}
return o1.getTime() < o2.getTime() ? -1 : 1;
});
for (DanmuData danmuData : list) {
addDanmu(danmuData);
}
}
/**
* 添加弹幕
* @param danmuData 弹幕
*/
public void addDanmu(DanmuData danmuData) {
if (filters.contains(danmuData.getDanmu())) {
return;
}
addY();
long _time = danmuData.getTime();
long h = TimeUnit.MILLISECONDS.toHours(_time);
long m = TimeUnit.MILLISECONDS.toMinutes(_time) % 60;
long s = TimeUnit.MILLISECONDS.toSeconds(_time) % 60;
String sTime = String.format("%s:%s:%s.0",
new DecimalFormat("00").format(h),
new DecimalFormat("00").format(m),
new DecimalFormat("00").format(s));
if (s >= 52) {
s = (s + 8) - 60;
m++;
} else {
s += 8;
}
String eTime = String.format("%s:%s:%s.0",
new DecimalFormat("00").format(h),
new DecimalFormat("00").format(m),
new DecimalFormat("00").format(s));
float x1, x2;
x1 = 1920 + (danmuData.getDanmu().length() * 12.5f);
x2 = 0 - (danmuData.getDanmu().length() * 12.5f);
String ass = String.format("Dialogue: 0,%s,%s,R2L,,20,20,2,,{\\move(%.1f,%d,%.1f,%d)\\c&%s\\alpha&H%s}%s",
sTime,
eTime,
x1,
y,
x2,
y,
danmuData.getFontColorHex(),
alpha,
danmuData.getDanmu()
);
addBuilder(ass);
}
private void addY() {
y += 40;
if (y >= 1080) {
y = 40;
}
}
}

View File

@@ -0,0 +1,191 @@
package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.BaseAPI;
import com.yutou.bilibili.api.LiveAPI;
import com.yutou.bilibili.api.VideoApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.BiliBili.BiliVideo;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.BiliBiliWbiSign;
import com.yutou.qqbot.utlis.HttpTools;
import javax.net.ssl.HttpsURLConnection;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class BiliBiliAppUtils {
private static final String AppKey = "1d8b6e7d45233436";
private static final String AppSec = "560c52ccd288fed045859ed18bffd973";
private BiliBiliUtils biliUtils;
public BiliBiliAppUtils(Long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
}
public String getAccessToken() {
try {
String tmpUrl = BaseAPI.MCBBS_PNG;
String sign = AppTools.getMD5("api=" + tmpUrl + AppSec);
JSONObject get = biliUtils.http_get(BaseAPI.ACCESS_TOKEN+"?appkey=" + AppKey + "&api=" + tmpUrl + "&sign=" + sign);
assert get != null;
String uri = get.getJSONObject("data").getString("confirm_uri");
HttpsURLConnection connection = biliUtils.getBiliHttpGet(uri, biliUtils.getCookie());
connection.connect();
if (connection.getResponseCode() == 200) {
Map<String, String> params = HttpTools.getUrlParams(connection.getURL().toString());
return params.get("access_key");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Map<String, String> sign(Map<String, String> map) {
map.putAll(getDefaultBody());
map = sort(map);
StringBuilder builder = new StringBuilder();
for (String key : map.keySet()) {
builder.append(key).append("=").append(map.get(key)).append("&");
}
String param = builder.substring(0, builder.length() - 1);
map.put("sign", AppTools.getMD5(param + AppSec));
return map;
}
private Map<String, String> getDefaultBody() {
Map<String, String> map = new TreeMap<>();
map.put("access_key", getAccessToken());
map.put("actionKey", "appkey");
map.put("appkey", AppKey);
map.put("build", "7120200");
map.put("c_locale", "zh_CN");
map.put("channel", "xiaomi_cn_tv.danmaku.bili_20210930");
map.put("device", "android");
map.put("disable_rcmd", "0");
map.put("mobi_app", "android");
map.put("platform", "android");
map.put("s_locale", "zh_CN");
map.put("statistics", URLEncoder.encode("{\"appId\":1,\"platform\":3,\"version\":\"7.12.0\",\"abtest\":\"\"}", Charset.defaultCharset()));
map.put("ts", (System.currentTimeMillis() / 1000) + "");
return map;
}
private LinkedHashMap<String, String> sort(Map<String, String> map) {
return new LinkedHashMap<>(new TreeMap<>(map));
}
private Map<String, String> getHeaderMap() {
String md5_1 = AppTools.getMD5(System.currentTimeMillis() + "");
String md5_2 = AppTools.getMD5(System.currentTimeMillis() + "");
String trace_id = md5_1 + ":" + md5_2.substring(0, 16) + ":0:0";
Map<String, String> map = new TreeMap<>();
map.put("x-bili-mid", "96300");
map.put("x-bili-trace-id", trace_id);
map.put("x-bili-aurora-zone", "");
map.put("x-bili-aurora-eid", "WFICRlE=");
map.put("APP-KEY", "android64");
map.put("bili-http-engine", "cronet");
map.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
map.put("session_id", md5_1.substring(0, 8));
map.put("Host", "api.live.bilibili.com");
map.put("Connection", "keep-alive");
map.put("fp_local", md5_1 + md5_2);
map.put("fp_remote", md5_1 + md5_2);
map.put("env", "prod");
map.put("buvid", "XUF43FCF17D1747514C79C6D3D43B64C8D1B2");
map.put("Accept-Encoding", "gzip, deflate, br");
map.put("User-Agent", "Mozilla/5.0 BiliDroid/7.4.0 (bbcallen@gmail.com) os/android model/22061218C mobi_app/android build/7040300 channel/xiaomi_cn_tv.danmaku.bili_20210930 innerVer/7040310 osVer/12 network/2");
return map;
}
public AppUserTask getTaskProgress() {
JSONObject task = biliUtils.http_get(LiveAPI.LIVE_TASK_PROGRESS);
System.out.println("task = " + task);
assert task != null;
return task.getObject("data", AppUserTask.class);
}
private void setUserTaskProgress(int index) {
Map<String, String> map = new TreeMap<>();
map.put("target_id", "33989");
map.put("reward_index", index + "");
JSONObject httpGet = biliUtils.http(
LiveAPI.LIVE_SET_TASK_PROGRESS,
BiliBiliUtils.HTTP.POST,
HttpTools.toUrlParams(sign(map)),
getHeaderMap(),
BiliBiliUtils.RET_MODEL.JSON
);
System.out.println("任务 " + index + " :" + httpGet);
}
public AppUserTask startAppTask() {
AppUserTask task = getTaskProgress();
if (task.getDayTask().getStatus() == 2) {
setUserTaskProgress(0);
}
List<AppUserTask.WeekTask> taskList = task.getWeekTask();
taskList.forEach(weekTask -> {
if (weekTask.getStatus() == 2) {
setUserTaskProgress(weekTask.getId());
}
});
return task;
}
public static String getVideoAI(String url){
if(url.startsWith("https://b23.tv")){
url=b23ToUrl(url);
}
JSONObject videoInfo = new BiliVideo().getVideoInfo(url);
if(videoInfo==null){
return null;
}
String cid = videoInfo.getJSONObject("data").getString("cid");
TreeMap<String,String> body=new TreeMap<>();
body.put("cid",cid);
body.put("up_mid",videoInfo.getJSONObject("data").getJSONObject("owner").getString("mid"));
body.put("bvid",videoInfo.getJSONObject("data").getString("bvid"));
BiliBiliWbiSign.getWbiSign(body);
JSONObject object = BiliBiliUtils.getInstance(QQBotManager.defQQ)
.http_get(VideoApi.VIDEO_AI +"?"+HttpTools.toUrlParams(body));
if(object.getInteger("code")==0){
if(object.getJSONObject("data").getInteger("code")==0) {
return object.getJSONObject("data").getJSONObject("model_result").getString("summary");
}else{
return "没得省流";
}
}
return null;
}
public static String b23ToUrl(String url){
try {
HttpsURLConnection connection = BiliBiliUtils.getInstance(QQBotManager.defQQ).getBiliHttpGet(url, BiliBiliUtils.getInstance(QQBotManager.defQQ).getCookie());
connection.setInstanceFollowRedirects(false);
connection.connect();
if(connection.getResponseCode()==302){
connection.setConnectTimeout(5000);
return connection.getHeaderField("Location");
}
return connection.getURL().toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
BiliBiliWbiSign.updateRawWbiKey();
String url="https://b23.tv/NtqDorB?share_medium=android&share_source=qq&bbid=XUDCA4BDD60B5853ACDC17794BFAEF91F874A&ts=1705470976484";
// url="https://www.bilibili.com/video/BV1fw411E75p/?buvid=XUDCA4BDD60B5853ACDC17794BFAEF91F874A&from_spmid=tm.recommend.0.0&is_story_h5=false&mid=7G8S%2B4e7nx6XSaU3oMQKXA%3D%3D&p=1&plat_id=116&share_from=ugc&share_medium=android&share_plat=android&share_session_id=ab27db6e-47a5-43b5-b0ec-b027bcfdeccc&share_source=QQ&share_tag=s_i&spmid=main.ugc-video-detail.0.0&timestamp=1705470976&unique_k=NtqDorB&up_id=1156809979";
String ai = getVideoAI(url);
System.out.println("ai = " + ai);
}
}

View File

@@ -0,0 +1,182 @@
package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.MangaApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.utlis.HttpTools;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class BiliBiliManga {
public BiliBiliManga(long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
}
public static JSONObject sign() {
JSONObject body = new JSONObject();
body.put("platform", "android");
return BiliBiliUtils.getInstance(QQBotManager.defQQ).http_post(MangaApi.SIGN, HttpTools.toUrlParams(body));
}
private static JSONObject getListProductDate() {
return BiliBiliUtils.getInstance(QQBotManager.defQQ).http_post(MangaApi.LIST_PRODUCT_DATE, "");
}
private static boolean isPayMission = false;
private static Product missionProduct = new Product();
private static Timer mission = null;
private static BiliBiliUtils biliUtils = null;
private ObjectInterface anInterface = null;
public void addInterface(ObjectInterface objectInterface) {
anInterface = objectInterface;
}
public static boolean isPayMission() {
return isPayMission;
}
public static String getMission() {
return missionProduct + " 兑换数量:" + missionProduct.getPayAmount();
}
public static List<Product> getListProduct() {
List<Product> list = new ArrayList<>();
JSONObject product = getListProductDate();
if (product.getInteger("code") == 0) {
JSONArray array = product.getJSONArray("data");
for (Object o : array) {
JSONObject data = (JSONObject) o;
Product item = new Product();
item.setId(data.getInteger("id"));
item.setTitle(data.getString("title"));
item.setAmount(data.getInteger("amount"));
item.setRemain_amount(data.getInteger("remain_amount"));
item.setReal_cost(data.getInteger("real_cost"));
list.add(item);
}
}
return list;
}
public static int getMyPoint() {
JSONObject user = biliUtils.http_post(MangaApi.USER_POINT, "");
if (user != null && user.getInteger("code") == 0) {
return user.getJSONObject("data").getInteger("point");
}
return 0;
}
public JSONObject startPayMission(int id, int num) {
JSONObject json = new JSONObject();
if (isPayMission) {
json.put("code", 2);
json.put("msg", "任务正在进行:" + getMission());
return json;
}
if (biliUtils == null) {
json.put("code", -1);
json.put("msg", "B站未登录");
return json;
}
int userPoint = getMyPoint();
List<Product> list = getListProduct();
missionProduct = null;
for (Product product : list) {
if (product.getId() == id) {
missionProduct = product;
break;
}
}
if (missionProduct == null) {
json.put("code", -1);
json.put("msg", "未找到商品可能id有误 id:" + id);
return json;
}
if (num == -1) {
num = 99999;
}
int userPointNum = userPoint / missionProduct.getReal_cost();
num = Math.min(num, userPointNum);
if (num < missionProduct.getRemain_amount()) {
num = missionProduct.getRemain_amount();
}
missionProduct.setPayAmount(num);
JSONObject data = new JSONObject();
data.put("product_id", id);
data.put("product_num", num);
data.put("point", num * missionProduct.getReal_cost());
startPayMission(data);
isPayMission = true;
if (num == 0) {
json.put("code", 3);
json.put("msg", "商品无货,正在抢购");
} else {
json.put("code", 0);
json.put("msg", "任务创建成功:" + missionProduct + " 兑换数量:" + num);
}
return json;
}
private void startPayMission(JSONObject data) {
if (mission != null) {
mission.cancel();
}
mission = new Timer();
mission.schedule(new TimerTask() {
@Override
public void run() {
JSONObject post = biliUtils.http_post(MangaApi.PAY_MISSION, HttpTools.toUrlParams(data));
if (post == null) {
anInterface.out("网络请求失败,请查看日志");
cancel();
return;
}
if (post.getInteger("code") == 0) {
anInterface.out("兑换成功,任务已取消");
isPayMission = false;
cancel();
} else {
anInterface.out("[" + post.getInteger("code") + "]" + post.getString("msg"));
}
}
}, 0, 1000);
}
public void stopPayMission() {
if (isPayMission) {
isPayMission = false;
if (mission != null) {
mission.cancel();
}
}
}
public static void main(String[] args) {
// System.out.println(BiliBiliManga.sign());
BiliBiliUtils.getInstance(583819556L).sendLiveDanmu(33989,"学学这个");
}
@Data
public static class Product {
String title;
int id;
int remain_amount;
int real_cost;
int amount;
int payAmount;
@Override
public String toString() {
return "[ " + id + " ] " + title + " (" + remain_amount + "/" + amount + ") $" + real_cost;
}
}
}

View File

@@ -0,0 +1,444 @@
package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.LiveAPI;
import com.yutou.bilibili.api.LoginAPI;
import com.yutou.bilibili.api.SignApi;
import com.yutou.bilibili.api.UserApi;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.utlis.*;
import org.brotli.dec.BrotliInputStream;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
public class BiliBiliUtils {
private long qq;
private long oldBiliBiliHttpTime = 0;
public enum HTTP {
POST, GET
}
public enum RET_MODEL {
BYTE, JSON
}
public BiliBiliUtils(long qq) {
this.qq = qq;
}
public static BiliBiliUtils getInstance(long qq) {
return new BiliBiliUtils(qq);
}
public synchronized JSONObject http_get(String url) {
try {
Log.i("调用url = " + url);
HttpsURLConnection connection = getBiliHttpGet(url, getCookie());
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
String str = outputStream.toString(StandardCharsets.UTF_8);
outputStream.close();
try {
return JSON.parseObject(str);
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("html", str);
return json;
} finally {
stream.close();
connection.disconnect();
}
} catch (IOException e) {
//com.yutou.bilibili.Tools.Log.e(e);
e.printStackTrace();
}
return null;
}
public JSONObject http_login_getSid(String url) {
try {
Log.i("调用url = " + url);
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
setConnection(null, connection);
connection.setRequestMethod("GET");
connection.connect();
BufferedInputStream stream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
List<String> cookie = null;
if (connection.getHeaderFields().containsKey("Set-Cookie")) {
cookie = connection.getHeaderFields().get("Set-Cookie");
}
String str = outputStream.toString(StandardCharsets.UTF_8);
outputStream.close();
try {
JSONObject json = JSON.parseObject(str);
if (cookie != null) {
StringBuilder ck = new StringBuilder();
for (String key : cookie) {
ck.append(";").append(key);
}
json.put("cookie", ck.toString());
}
return json;
} catch (Exception e) {
JSONObject json = new JSONObject();
json.put("html", str);
return json;
} finally {
stream.close();
connection.disconnect();
}
} catch (IOException e) {
//com.yutou.bilibili.Tools.Log.e(e);
e.printStackTrace();
}
return null;
}
public JSONObject http_post(String url, String body) {
return http(url, HTTP.POST, body, RET_MODEL.JSON);
}
public <T> T http(String url, HTTP model, String body, RET_MODEL ret_model) {
return http(url, model, body, null, ret_model);
}
public <T> T http(String url, HTTP model, String body, Map<String, String> headers, RET_MODEL ret_model) {
JSONObject json = null;
BufferedInputStream stream = null;
ByteArrayOutputStream outputStream = null;
OutputStream connectionOutputStream = null;
HttpURLConnection connection = null;
try {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
if (model == HTTP.POST) {
connection = getBiliHttpPost(url, getCookie());
} else {
if (body != null) {
if (url.contains("?")) {
url += "&" + body;
} else {
url += "?" + body;
}
body = null;
}
connection = getBiliHttpGet(url, getCookie());
}
if (headers != null) {
for (String key : headers.keySet()) {
connection.setRequestProperty(key, headers.get(key));
}
} else {
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
}
if (!StringUtils.isEmpty(body)) {
connectionOutputStream = connection.getOutputStream();
connectionOutputStream.write(body.getBytes(StandardCharsets.UTF_8));
connectionOutputStream.flush();
}
connection.connect();
if (connection.getResponseCode() == 400) {
return null;
}
if (connection.getContentEncoding() != null && connection.getContentEncoding().contains("gzip")) {
stream = new BufferedInputStream(new GZIPInputStream(connection.getInputStream()));
} else if (connection.getContentEncoding() != null && connection.getContentEncoding().contains("br")) {
stream = new BufferedInputStream(new BrotliInputStream(connection.getInputStream()));
} else {
stream = new BufferedInputStream(connection.getInputStream());
}
outputStream = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = 0, size;
while ((len = stream.read(bytes)) != -1) {
outputStream.write(bytes, 0, len);
outputStream.flush();
}
if (ret_model == RET_MODEL.BYTE) {
return (T) outputStream.toByteArray();
}
String str = outputStream.toString(StandardCharsets.UTF_8);
try {
json = JSON.parseObject(str);
json.put("cookie", connection.getHeaderField("Set-Cookie"));
return (T) json;
} catch (Exception e) {
json = new JSONObject();
json.put("html", str);
json.put("cookie", connection.getHeaderField("Set-Cookie"));
return (T) json;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stream != null) {
stream.close();
}
if (outputStream != null) {
outputStream.close();
}
if (connectionOutputStream != null) {
connectionOutputStream.close();
}
if (connection != null) {
connection.disconnect();
}
} catch (Exception ignored) {
}
}
return null;
}
public String getCookie() {
if (StringUtils.isEmpty(ConfigTools.readFile(new File(qq + "_bilibili.cookie")))) {
return "";
}
JSONObject json = JSON.parseObject(ConfigTools.readFile(new File(qq + "_bilibili.cookie")));
StringBuilder builder = new StringBuilder();
for (String s : json.keySet()) {
builder.append(s).append("=").append(json.getString(s)).append(";");
}
return builder.toString();
}
public HttpURLConnection getBiliHttpPost(String url, String cookie) throws Exception {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setDoInput(true);
setConnection(cookie, connection);
return connection;
}
public HttpsURLConnection getBiliHttpGet(String url, String cookie) throws IOException {
if (System.currentTimeMillis() - oldBiliBiliHttpTime < 1000) {
try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
oldBiliBiliHttpTime = System.currentTimeMillis();
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
if (cookie != null) {
setConnection(cookie, connection);
}
connection.setReadTimeout(5000);
connection.setConnectTimeout(5000);
return connection;
}
public File download(final String url, final String saveName, boolean isProxy) {
File jar = null;
try {
File savePath = new File(HttpTools.downloadPath + saveName);
Proxy proxy = null;
if (!savePath.exists()) {
savePath.mkdirs();
}
savePath.delete();
Log.i("DOWNLOAD", "下载文件:" + url + " 保存文件:" + saveName);
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
HttpsURLConnection connection;
if (isProxy) {
connection = (HttpsURLConnection) new URL(url).openConnection(proxy);
} else {
connection = (HttpsURLConnection) new URL(url).openConnection();
}
setConnection(getCookie(), connection);
InputStream inputStream = connection.getInputStream();
jar = new File(HttpTools.downloadPath + saveName + "_tmp.tmp");
jar.createNewFile();
Log.i("DOWNLOAD", "临时保存文件:" + jar.getAbsolutePath());
OutputStream outputStream = new FileOutputStream(jar);
byte[] bytes = new byte[1024];
double size = connection.getContentLength();
double downSize = 0;
int len;
while ((len = inputStream.read(bytes)) > 0) {
outputStream.write(bytes, 0, len);
downSize += len;
}
outputStream.close();
inputStream.close();
File oldJar = new File(HttpTools.downloadPath + saveName);
if (oldJar.exists()) {
oldJar.delete();
}
jar.renameTo(oldJar);
Log.i("DOWNLOAD", "实际保存:" + oldJar.getAbsolutePath() + " " + oldJar.getName());
return oldJar;
} catch (Exception e) {
e.printStackTrace();
if (jar != null) {
jar.delete();
}
}
return null;
}
public void download_ffmpeg(final List<String> url, final String saveName) {
new Thread(() -> {
StringBuilder builder = new StringBuilder();
builder.append(ConfigTools.load(ConfigTools.CONFIG, "ffmpeg", String.class)).append(" ");
/* builder.append("-user_agent").append(" ");
builder.append("\"").append("User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Referer:https://live.bilibili.com").append("\"").append(" ");
builder.append("-cookies").append(" ");
builder.append("\"").append(getCookie()).append("\"").append(" ");
builder.append("-headers").append(" ");
builder.append("\"").append("Referer:https://live.bilibili.com").append("\"").append(" ");*/
for (String _url : url) {
builder.append("-i").append(" ");
builder.append("\"").append(_url).append("\"").append(" ");
}
builder.append("-vcodec").append(" ");
builder.append("copy").append(" ");
builder.append("-acodec").append(" ");
builder.append("copy").append(" ");
builder.append("-threads").append(" ");
builder.append("8").append(" ");
// builder.append("-y").append(" ");
builder.append(new File(HttpTools.downloadPath + saveName + ".mp4").getAbsolutePath()).append(" ");
System.out.println(builder);
AppTools.exec(builder.toString(), new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
System.out.println("data = " + data);
}
}, false, false);
}).start();
}
private void setConnection(String cookie, HttpURLConnection connection) {
connection.addRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
connection.addRequestProperty("Accept-Language", "zh-CN,zh;q=0.8");
connection.addRequestProperty("Cache-Control", "max-age=0");
connection.setRequestProperty("Referer", "https://www.bilibili.com");
connection.addRequestProperty("Connection", "keep-alive");
connection.addRequestProperty("Upgrade-Insecure-Requests", "1");
if (!StringUtils.isEmpty(cookie)) {
connection.addRequestProperty("Cookie", cookie);
}
connection.addRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36");
}
public JSONObject getLoginInfo() {
JSONObject jsonObject = http_get(UserApi.NAV);
if (jsonObject == null) {
jsonObject = new JSONObject();
jsonObject.put("code", "-1");
jsonObject.put("data", new JSONObject());
}
return jsonObject;
}
public static void main(String[] args) {
/* String url="https://xy218x85x123x8xy.mcdn.bilivideo.cn:4483/upgcxcode/12/12/17281212/17281212-16-80.flv?e=ig8euxZM2rNcNbNBhbdVhwdlhbUghwdVhoNvNC8BqJIzNbfqXBvEqxTEto8BTrNvN0GvT90W5JZMkX_YN0MvXg8gNEV4NC8xNEV4N03eN0B5tZlqNxTEto8BTrNvNeZVuJ10Kj_g2UB02J0mN0B5tZlqNCNEto8BTrNvNC7MTX502C8f2jmMQJ6mqF2fka1mqx6gqj0eN0B599M=&uipk=5&nbs=1&deadline=1660538573&gen=playurlv2&os=mcdn&oi=2936701972&trid=00006f9623cac1514d8ea18fba3a15a756cau&mid=96300&platform=pc&upsig=25ddd1da610960e8e1d2e80dc97c2361&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,mid,platform&mcdnid=11000101&bvc=vod&nettype=0&orderid=0,2&agrr=1&bw=253116&logo=A0000400&requestFrom=BILIBILI_HELPER_2.5.8";
File file=download(url,"16.mp4",false);
System.out.println("file.getAbsolutePath() = " + file.getAbsolutePath());*/
/* System.out.println(getLiveRoom(42062));
System.out.println("--------------------------------------------");
System.out.println(getUserInfo(730732));*/
JSONObject sign = new BiliBiliUtils(583819556).getUserInfo(96300);
System.out.println("sign = " + sign);
}
public boolean sendLiveDanmu(long roomId, String msg) {
JSONObject body = new JSONObject();
body.put("msg", msg);
body.put("roomid", roomId);
body.put("color", 16777215);
body.put("fontsize", 25);
body.put("rnd", System.currentTimeMillis() / 1000);
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
JSONObject post = http_post(LiveAPI.LIVE_SEND_DANMU, HttpTools.toUrlParams(body));
return post.getInteger("code") == 0;
}
public String liveSignIn() {
//{"code":0,"data":{"coin":1,"gold":19500,"silver":106394,"tid":"Silver2Coin22101413201169763005873"},"message":"兑换成功"}
JSONObject body = new JSONObject();
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
JSONObject toCoin = http_post(SignApi.LIVE_SIGN_COIN, HttpTools.toUrlParams(body));
JSONObject liveSign = http_get(SignApi.LIVE_SIGN);
JSONObject vipSign = http_post(SignApi.VIP_SIGN, null);
return "银瓜子兑换硬币:" + toCoin.getString("message") + "|" + "直播签到:" + liveSign.getString("message") + "|大会员中心签到:" + vipSign.getString("message");
}
public JSONObject getLiveRoom(int roomId) {
JSONObject body = new JSONObject();
body.put("room_id", roomId);
body.put("csrf", BiliLogin.getCookieToken(qq));
body.put("csrf_token", BiliLogin.getCookieToken(qq));
return http_post(LiveAPI.LIVE_ROOM_INFO, HttpTools.toUrlParams(body));
}
public JSONObject getUserInfo(int mid) {
TreeMap<String, String> body = new TreeMap<>();
body.put("mid", mid + "");
BiliBiliWbiSign.getWbiSign(body);
return http_get(UserApi.USER_INFO_V2 + "?" + HttpTools.toUrlParams(body));
}
public boolean checkLiveRoom(int roomId) {
JSONObject post = getLiveRoom(roomId);
return post.getInteger("code") == 0;
}
}

View File

@@ -0,0 +1,110 @@
package com.yutou.qqbot.bilibili;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.LoginAPI;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.utlis.*;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
public class BiliLogin {
BiliBiliUtils biliUtils;
private long qq;
public BiliLogin(Long qq) {
biliUtils = BiliBiliUtils.getInstance(qq);
this.qq = qq;
}
public JSONObject login() {
JSONObject login = JSON.parseObject(HttpTools.get(LoginAPI.LOGIN_QRCODE));
JSONObject json = new JSONObject();
System.out.println("login = " + login);
json.put("code", login.getInteger("code"));
json.put("url", login.getJSONObject("data").getString("url"));
new Thread(() -> waitLogin(login.getJSONObject("data").getString("qrcode_key"))).start();
return json;
}
public void loginAsQQ() {
String url = login().getString("url");
File code = QRCodeUtils.createQRCode("bili_login", url);
QQBotManager.getInstance().sendMessage(code, qq, "B站未登录,请扫码登陆后再试");
}
public void waitLogin(String oauthKey) {
long time = System.currentTimeMillis();
new Timer().schedule(new TimerTask() {
@Override
public void run() {
String bd = "gourl=https%3A%2F%2Fpassport.bilibili.com%2Fajax%2FminiLogin%2Fredirect&oauthKey=" + oauthKey;
if ((System.currentTimeMillis() - time) > 5 * 60 * 1000) {
cancel();
return;
}
JSONObject json = biliUtils.http_login_getSid(LoginAPI.LOGIN_QRCODE_POLL + "?qrcode_key=" + oauthKey);
Log.i("B站登陆", json.toJSONString());
if (json.getInteger("code") == 0 && json.getJSONObject("data").getInteger("code") == 0) {
String[] split = json.getString("cookie").split(";");
JSONObject ck = new JSONObject();
for (String string : split) {
if (!ck.containsKey(string) && !StringUtils.isEmpty(string) && string.contains("=")) {
String key = string.split("=")[0].trim();
String value = string.split("=")[1].trim();
if (key.contains("Expires")) {
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMMM yyyy HH:mm:ss z", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getDefault());
Date date = sdf.parse(value, new ParsePosition(0));
value = String.valueOf(date.getTime() / 1000);
}
ck.put(key, value);
}
}
ck.put("gourl", bd);
ConfigTools.saveFile(new File(qq + "_bilibili.cookie"), ck.toJSONString());
cancel();
}
}
}, 1000, 3000);
}
public boolean testLogin() {
if (biliUtils == null) {
return false;
}
JSONObject jsonObject = biliUtils.getLoginInfo();
return jsonObject.getInteger("code") == 0;
}
public static String getCookieToken(Long qq) {
if (StringUtils.isEmpty(ConfigTools.readFile(new File(qq + "_bilibili.cookie")))) {
return null;
}
JSONObject json = JSON.parseObject(ConfigTools.readFile(new File(qq + "_bilibili.cookie")));
return json.getString("bili_jct");
}
public static void main(String[] args) throws ParseException {
String http = "{\"code\":0,\"message\":\"0\",\"ttl\":1,\"data\":{\"url\":\"https://passport.biligame.com/x/passport-login/web/crossDomain?DedeUserID=96300&DedeUserID__ckMd5=c506a12068157a3a&Expires=1720252437&SESSDATA=c383a8e0,1720252437,9ba5c*11CjCBp3_j-6zYtK27tzUVrmFZNgjyeDW6pcdfmRBJU5cVfz4OhVmujjKCZsGAkXL6ll8SVnplZ2JONlBleHdFOGgzUzNJYUxIbzJwRVhTYVM2LWVuQnJyQVQxQnRWTUFZbUYybV95Y1RELTdGeF9mNlpXV3RDTjdsMVBaYkhxZGZyblRkTUJCMGV3IIEC&bili_jct=e786885293c24eb7198dc0538b56d6d8&gourl=https%3A%2F%2Fwww.bilibili.com\",\"refresh_token\":\"347b83e7c4a1e24f4681f06f28f71b11\",\"timestamp\":1704700437058,\"code\":0,\"message\":\"\"},\"cookie\":\";SESSDATA=c383a8e0%2C1720252437%2C9ba5c%2A11CjCBp3_j-6zYtK27tzUVrmFZNgjyeDW6pcdfmRBJU5cVfz4OhVmujjKCZsGAkXL6ll8SVnplZ2JONlBleHdFOGgzUzNJYUxIbzJwRVhTYVM2LWVuQnJyQVQxQnRWTUFZbUYybV95Y1RELTdGeF9mNlpXV3RDTjdsMVBaYkhxZGZyblRkTUJCMGV3IIEC; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT; HttpOnly; Secure;bili_jct=e786885293c24eb7198dc0538b56d6d8; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;DedeUserID=96300; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;DedeUserID__ckMd5=c506a12068157a3a; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT;sid=ger7871m; Path=/; Domain=bilibili.com; Expires=Sat, 06 Jul 2024 07:53:57 GMT\"}";
JSONObject body = JSON.parseObject(http);
BiliLogin login = new BiliLogin(583819556L);
boolean testLogin = login.testLogin();
System.out.println("testLogin = " + testLogin);
System.out.println(BiliBiliUtils.getInstance(583819556L).getLoginInfo());
//JSONObject json = login.login();
//System.out.println("json = " + json);
// QRCodeUtils.createQRCode("bili_login", json.getString("url"));
}
}

View File

@@ -0,0 +1,26 @@
package com.yutou.qqbot.bilibili;
import lombok.Data;
import java.util.Date;
@Data
public class DanmuData {
private int id;
private int model;//13 滚动弹幕 4 底端弹幕 5 顶端弹幕 6 逆向弹幕 7 精准定位 8 高级弹幕
private int fontSize;
private int fontColor;
private long time;
private String uCode;
private String danmu;
private long uid;
private String uname;
public Date getTimeDate() {
return new Date(time);
}
public String getFontColorHex() {
return Integer.toHexString(fontColor);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
package com.yutou.qqbot.data.baidu;
import lombok.Data;
@Data
public class Message {
private String role = "user";
private String content;
public Message() {
}
public boolean checkIsUser() {
return "user".equals(role);
}
public static Message create(String message) {
return create(message, false);
}
public static Message create(String message, boolean isGTP) {
Message msg = new Message();
msg.content = message;
if (isGTP) {
msg.role = "assistant";
}
return msg;
}
}

View File

@@ -0,0 +1,17 @@
package com.yutou.qqbot.data.baidu;
import lombok.Data;
@Data
public class ResponseMessage {
private String id;
private String object;
private long created;
private String result;
private boolean isTruncated;
private boolean needClearHistory;
private Message usage;
public ResponseMessage() {
}
}

View File

@@ -0,0 +1,50 @@
package com.yutou.qqbot.data.bili;
import lombok.Data;
@Data
public class EPInfo {
private int code;
private String message;
private MediaResult result;
@Data
public static class MediaResult {
private Media media;
// getters and setters
}
@Data
public static class Media {
private String cover;
private String horizontal_picture;
private int media_id;
private NewEp new_ep;
private Rating rating;
private int season_id;
private String share_url;
private String title;
private int type;
private String type_name;
// getters and setters
}
@Data
public static class NewEp {
private int id;
private String index;
private String index_show;
// getters and setters
}
@Data
public static class Rating {
private int count;
private double score;
// getters and setters
}
}

View File

@@ -0,0 +1,49 @@
package com.yutou.qqbot.data.jianr;
import lombok.Data;
import java.util.List;
@Data
public class AndroidDevice {
String title;
String deviceId;
DeviceDisplay androidDevice;
List<GameDisplay> deviceDisplay;
@Data
public static class DeviceDisplay {
int width, height;
}
@Data
public static class GameDisplay {
String title;
double width, height;
Vector2D start, end;
public double getWidth() {
return end.getX() - start.getX();
}
public double getHeight() {
return end.getY() - start.getY();
}
public void setEnabledRandom(boolean enabled) {
if(enabled){
start.setEnableRandomY(true);
start.setEnableRandomX(true);
end.setEnableRandomX(true);
end.setEnableRandomY(true);
}else{
start.setEnableRandomX(false);
start.setEnableRandomY(false);
end.setEnableRandomY(false);
end.setEnableRandomX(false);
}
}
}
}

View File

@@ -0,0 +1,38 @@
package com.yutou.qqbot.data.jianr;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class JianRScriptData {
private String name;
private String device;
private List<Script> run;
public void addRun(Script script) {
if(run==null){
run=new ArrayList<>();
}
run.add(script);
}
@Data
public static class Script {
private String name;
private int nextWaitTime;
private int randomNextWaitTime;
private String model;
private int x;
private int y;
private int rx;
private int ry;
public static class ScriptModel {
public static final String CLICK = "click";
public static final String WAIT = "wait";
}
}
}

View File

@@ -0,0 +1,28 @@
package com.yutou.qqbot.data.jianr;
import lombok.Data;
import java.util.List;
@Data
public class JianRScriptV2Data {
private String title;
private List<Script> script;
@Data
public static class Script {
private String title;
private String activity;
private int nextWaitTime;
private int randomNextWaitTime;
}
public static class ScriptModel {
public static final String MAP = "map";
public static final String attack = "attack";
public static final String formationType = "formationType";
public static final String dialog_go = "dialog_go";
public static final String dialog_back = "dialog_back";
public static final String dialog_assets = "dialog_assets";
public static final String none = "none";
}
}

View File

@@ -0,0 +1,45 @@
package com.yutou.qqbot.data.jianr;
import lombok.Data;
import java.util.Random;
@Data
public class Vector2D {
double x, y;
boolean enableRandomX, enableRandomY;
boolean absRandomX, absRandomY;
int randomNumX, randomNumY;
public double getX() {
if (isEnableRandomX()) {
double tmp = new Random().nextDouble(-randomNumX, randomNumX);
if (isAbsRandomX()) {
return Math.abs(tmp) + x;
} else {
return tmp + x;
}
}
return x;
}
public double getNotRandomY() {
return y;
}
public double getNotRandomX() {
return x;
}
public double getY() {
if(isEnableRandomY()){
double tmp = new Random().nextDouble(-randomNumY, randomNumY);
if (isAbsRandomY()) {
return Math.abs(tmp) + y;
} else {
return tmp + y;
}
}
return y;
}
}

View File

@@ -3,4 +3,5 @@ package com.yutou.qqbot.interfaces;
public interface ModelInterface {
boolean isUserPublic();
String[] getUsePowers();
String getModelName();
}

View File

@@ -1,7 +1,9 @@
package com.yutou.qqbot.models.Animal;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
@@ -15,7 +17,7 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@UseModel
public class TurnipProphet extends Model {
public static class TurnipData {
public static final String MODEL = "趋势:";
@@ -40,7 +42,7 @@ public class TurnipProphet extends Model {
}
static int nowTime=-1;
static int nowTime = -1;
@Override
public boolean isUserPublic() {
@@ -54,32 +56,47 @@ public class TurnipProphet extends Model {
};
}
@Override
public String getModelName() {
return "大头菜";
}
Long user, sendQQ;
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
user = qq;
sendQQ = qq;
if (isGroup) {
return;
if (!event.getMessage().serializeToMiraiCode().contains("[mirai:at:2476945931]")) {
return;
}
user = event.getSource().getFromId();
}
int money = -1;
try {
if (isGroup) {
msg = msg.replace("@2476945931", "").trim();
}
money = Integer.parseInt(msg.trim());
} catch (Exception e) {
if (msg.equals(QQFromCommands.TURNIP_PROPHET)) {
showData(event.getSource().getFromId());
showData();
}
return;
}
setData(money, event.getSource().getFromId());
setData(money);
}
private void showData(long qq) {
String redisKey = qq + "_turnip";
private void showData() {
String redisKey = user + "_turnip";
String data = RedisTools.get(redisKey);
if (StringUtils.isEmpty(data)) {
QQBotManager.getInstance().sendMessage(qq, "没有本周数据,无法预测");
QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有本周数据,无法预测"));
return;
}
JSONObject json = JSONObject.parseObject(data);
JSONObject json = JSON.parseObject(data);
String prices = json.getString("prices");
String pattern = null;
if (json.containsKey("old_pattern")) {
@@ -99,23 +116,26 @@ public class TurnipProphet extends Model {
Map<String, String> map = null;
try {
map = openTurnip(prices, pattern);
sendQQ(map, prices, pattern, qq);
sendQQ(map, prices, pattern);
} catch (Exception e) {
e.printStackTrace();
showData(qq);
showData();
}
}
private void setData(int money, long qq) {
String redisKey = qq + "_turnip";
private void setData(int money) {
String redisKey = user + "_turnip";
String data = RedisTools.get(redisKey);
String pattern = null;
JSONObject json;
JSONArray array;
if (StringUtils.isEmpty(data)||getDay()==0) {
if (StringUtils.isEmpty(data) || getDay() == 0) {
array = new JSONArray();
json = new JSONObject();
if (getDay() == 0 && !StringUtils.isEmpty(data)) {
json = JSON.parseObject(data);
}
array.add(-1);
array.add(-1);
array.add(-1);
@@ -130,11 +150,11 @@ public class TurnipProphet extends Model {
array.add(-1);
array.add(-1);
} else {
json = JSONObject.parseObject(data);
json = JSON.parseObject(data);
array = json.getJSONArray("turnip");
}
if (array.getInteger(0) == -1 && getDay() != 0) {
QQBotManager.getInstance().sendMessage(qq, "没有周日买入信息,本周不收录 :(");
QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有周日买入信息,本周不收录 :("));
return;
}
if (json.containsKey("old_pattern")) {
@@ -145,19 +165,21 @@ public class TurnipProphet extends Model {
}
if (getDay() == 0) {
if (json.containsKey("pattern")) {
json.put("old_pattern", json.getString("pattern"));
pattern = json.getString("pattern");
}
if (money >= 90 && money <= 110) {
array.set(0, money);
}
} else {
if (money >= 9 && money <= 660) {
if (getTime() < 12) {
array.set(getDay() * 2 - 1, money);
if (!json.containsKey("tmp_pattern")) {
json.put("old_pattern", json.getString("pattern"));
pattern = json.getString("pattern");
} else {
array.set(getDay() * 2, money);
pattern = json.getString("old_pattern");
}
json.put("tmp_pattern", json.getString("pattern"));
}
array.set(0, money);
} else {
json.remove("tmp_pattern");
if (getTime() < 12) {
array.set(getDay() * 2 - 1, money);
} else {
array.set(getDay() * 2, money);
}
}
json.put("turnip", array);
@@ -181,13 +203,13 @@ public class TurnipProphet extends Model {
case "小幅上涨(四期型)" -> pattern = "3";
}
}
QQBotManager.getInstance().sendMessage(qq, "已记录,正在预测本周走势...");
QQBotManager.getInstance().sendMessage(sendQQ, getMessage("已记录,正在预测本周走势..."));
Map<String, String> map = openTurnip(prices, pattern);
if(map==null){
map=openTurnip(prices,pattern);
if (map == null) {
map = openTurnip(prices, pattern);
}
String tmp_pattern = sendQQ(map, prices, pattern, qq);
String tmp_pattern = sendQQ(map, prices, pattern);
if (!StringUtils.isEmpty(tmp_pattern)) {
json.put("pattern", tmp_pattern);
}
@@ -195,29 +217,32 @@ public class TurnipProphet extends Model {
} catch (Exception e) {
e.printStackTrace();
setData(money, qq);
setData(money);
}
}
private String sendQQ(Map<String, String> map, String prices, String pattern, long qq) {
private String sendQQ(Map<String, String> map, String prices, String pattern) {
String url = String.format("https://turnipprophet.io?prices=%s%s",
prices,
pattern == null ? "" : "&pattern=" + pattern
);
if (map == null) {
String url = String.format("https://turnipprophet.io?prices=%s%s",
prices,
pattern == null ? "" : "&pattern=" + pattern
);
QQBotManager.getInstance().sendMessage(qq, "没有结果,请检查数据是否有误。 \n网页预览\n" + url);
QQBotManager.getInstance().sendMessage(sendQQ, getMessage("没有结果,请检查数据是否有误。 \n网页预览\n" + url));
return null;
}
JSONObject pr = JSONObject.parseObject(map.get(TurnipData.MODEL));
JSONObject pr = JSON.parseObject(map.get(TurnipData.MODEL));
JSONArray prArray = pr.getJSONArray(TurnipData.MODEL);
StringBuilder out = new StringBuilder();
out.append("预测结果如下:\n");
out.append(TurnipData.MODEL).append(prArray.getJSONObject(0).getString(TurnipData.MODEL)).append("\n");
out.append(TurnipData.PR).append(prArray.getJSONObject(0).getString(TurnipData.PR)).append("\n");
out.append("购入价:").append(prices.split("\\.")[0]).append("\n");
if (getDay() == 0) {
out.append("满背包(4行)购入价:").append(4000 * Integer.parseInt(prices.split("\\.")[0])).append("\n");
}
out.append(TurnipData.MIX).append(map.get(TurnipData.MIX)).append("\n")
.append(TurnipData.MAX).append(map.get(TurnipData.MAX)).append("\n")
.append(TurnipData.DAY).append(map.get(TurnipData.DAY)).append("\n")
@@ -243,21 +268,23 @@ public class TurnipProphet extends Model {
out.append(tmp.getString(TurnipData.MODEL)).append(":").append(tmp.getString(TurnipData.PR)).append("\n");
}
out.append("------------").append("\n");
out.append("网页版:").append("\n").append(url).append("\n");
out.append("祝好运 :)");
Log.i("TurnipProphet", out.toString());
QQBotManager.getInstance().sendMessage(qq, out.toString());
Log.i("TurnipProphet", out.toString()+"\n 发送QQ"+sendQQ);
QQBotManager.getInstance().sendMessage(sendQQ, getMessage(out.toString()));
return prArray.getJSONObject(0).getString(TurnipData.MODEL);
}
@Override
public void onTime(String time) {
super.onTime(time);
public void onTime(Long qq,String time) {
super.onTime(qq,time);
nowTime = Integer.parseInt(time.split(":")[0]);
}
public int getTime(){
if(nowTime==-1){
nowTime=Integer.parseInt(AppTools.getHours());
public int getTime() {
if (nowTime == -1) {
nowTime = Integer.parseInt(AppTools.getHours());
}
return nowTime;
}
@@ -268,19 +295,22 @@ public class TurnipProphet extends Model {
public static void main(String[] args) throws Exception {
TurnipProphet prophet = new TurnipProphet();
prophet.setData(68, 583819556);
String prices="108.93.89.84.79........";
String pattern="0";
Map<String,String >map=prophet.openTurnip(prices,pattern);
prophet.sendQQ(map,prices,pattern);
}
public Map<String, String> openTurnip(String prices, String pattern) throws Exception {
String url = String.format("https://turnipprophet.io?prices=%s%s",
String url = String.format("http://192.168.31.88:7000/?prices=%s%s",
prices,
pattern == null ? "" : "&pattern=" + pattern
);
System.out.println("url = " + url);
LinkedHashMap<String, String> map = new LinkedHashMap<>();
WebDriver driver =WebClient.getInstance().getWebDriver();
WebDriver driver = WebClient.getInstance().getWebDriver();
driver.get(url);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
@@ -292,8 +322,7 @@ public class TurnipProphet extends Model {
JSONObject pr = new JSONObject();
JSONArray array = new JSONArray();
if (list.size() == 0) {
driver.close();
driver.quit();
WebClient.getInstance().quit();
return null;
}
@@ -330,28 +359,27 @@ public class TurnipProphet extends Model {
}
}
}
int maxMoney=0;
String maxDay=null;
int maxMoney = 0;
String maxDay = null;
for (String key : map.keySet()) {
if(map.get(key).contains("~")){
if (map.get(key).contains("~")) {
for (String s : map.get(key).split("~")) {
if(Integer.parseInt(s)>maxMoney){
maxMoney=Integer.parseInt(s);
maxDay=key;
if (Integer.parseInt(s) > maxMoney) {
maxMoney = Integer.parseInt(s);
maxDay = key;
}
}
}else{
if(Integer.parseInt(map.get(key))>maxMoney){
maxMoney=Integer.parseInt(map.get(key));
maxDay=key;
} else {
if (Integer.parseInt(map.get(key)) > maxMoney) {
maxMoney = Integer.parseInt(map.get(key));
maxDay = key;
}
}
}
map.put(TurnipProphet.TurnipData.DAY, maxDay);
pr.put(TurnipProphet.TurnipData.MODEL, array);
map.put(TurnipProphet.TurnipData.MODEL, pr.toJSONString());
driver.close();
driver.quit();
WebClient.getInstance().quit();
return map;
}
}

View File

@@ -0,0 +1,143 @@
package com.yutou.qqbot.models.BiliBili;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.bilibili.AppUserTask;
import com.yutou.qqbot.bilibili.BiliBiliAppUtils;
import com.yutou.qqbot.bilibili.BiliBiliUtils;
import com.yutou.qqbot.bilibili.BiliLogin;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.QRCodeUtils;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
import java.util.Set;
@UseModel
public class BiliBiliLive extends Model {
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[]{
Model.QQGroupCommands.BILI_LIVE_DANMU_LIST,
Model.QQGroupCommands.BILI_LIVE_DANMU_SEND,
QQGroupCommands.BILI_LIVE_DANMU_DEL
};
}
@Override
public String getModelName() {
return "BiliBili Live Sign in";
}
@Override
public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("00:01:00".equals(time)) {
if (!new BiliLogin(QQBotManager.defQQ).testLogin()) {
new BiliLogin(QQBotManager.defQQ).loginAsQQ();
System.out.println(BiliBiliUtils.getInstance(QQBotManager.defQQ).getLoginInfo());
return;
}
signLive(QQBotManager.defQQ, qq);
}
}
private void signLive(long qq, long sendQQ) {
if (!new BiliLogin(qq).testLogin()) {
new BiliLogin(qq).loginAsQQ();
return;
}
BiliBiliUtils biliUtils = BiliBiliUtils.getInstance(qq);
QQBotManager.getInstance().sendMessage(sendQQ, biliUtils.liveSignIn());
Set<String> biliLive = RedisTools.list_get("bili_live");
StringBuilder builder = new StringBuilder();
for (String id : biliLive) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
boolean sign = biliUtils.sendLiveDanmu(Integer.parseInt(id), "打卡");
builder.append("BiliLiveSign").append(id).append(":").append(sign).append("\n");
}
QQBotManager.getInstance().sendMessage(sendQQ, builder.toString());
/* BiliBiliAppUtils appUtils = new BiliBiliAppUtils(QQBotManager.defQQ);
AppUserTask oldTask = appUtils.startAppTask();
AppUserTask newTask = appUtils.getTaskProgress();
builder = new StringBuilder();
builder.append("执行APP任务").append("\n").append(AppUserTask.toMessageFormat(oldTask, newTask));
QQBotManager.getInstance().sendMessage(sendQQ, builder.toString());*/
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_SEND) &&
!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_DEL) &&
!msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_LIST)) {
return;
}
if (msg.equals(QQGroupCommands.BILI_LIVE_DANMU_SEND)) {
signLive(user, qq);
return;
}
BiliBiliUtils biliUtils = BiliBiliUtils.getInstance(isGroup ? event.getSource().getFromId() : qq);
StringBuilder message;
message = new StringBuilder();
try {
boolean isDel = false;
if (msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_DEL)) {
isDel = true;
msg = msg.replace(QQGroupCommands.BILI_LIVE_DANMU_DEL, "").trim();
} else if (msg.startsWith(QQGroupCommands.BILI_LIVE_DANMU_SEND)) {
msg = msg.replace(QQGroupCommands.BILI_LIVE_DANMU_SEND, "").trim();
} else {
msg = "0";
}
Integer roomId = Integer.parseInt(msg);
if (!new BiliLogin(qq).testLogin()) {
new BiliLogin(qq).loginAsQQ();
return;
}
if (biliUtils.checkLiveRoom(roomId) && roomId != 0) {
if (isDel && RedisTools.list_isExist("bili_live", roomId + "")) {
RedisTools.list_remove("bili_live", roomId + "");
message.append("直播签到删除成功").append("\n");
} else if (!RedisTools.list_isExist("bili_live", roomId + "")) {
RedisTools.list_add("bili_live", roomId + "");
message.append("直播签到添加成功").append("\n");
}
} else if (roomId != 0) {
message.append("直播签到操作失败\n");
}
} catch (Exception e) {
message = new StringBuilder("直播签到添加失败\n");
}
message.append("-----直播签到房间号-----\n");
Set<String> biliLive = RedisTools.list_get("bili_live");
for (String id : biliLive) {
message.append(id)
.append(":")
.append(biliUtils.getUserInfo(
biliUtils.getLiveRoom(Integer.parseInt(id))
.getJSONObject("data")
.getInteger("uid"))
.getJSONObject("data")
.getString("name"))
.append("\n");
}
QQBotManager.getInstance().sendMessage(qq, message.toString());
}
public static void main(String[] args) {
new BiliBiliLive().signLive(QQBotManager.defQQ, 0);
}
}

View File

@@ -0,0 +1,429 @@
package com.yutou.qqbot.models.BiliBili;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.bilibili.api.VideoApi;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.bilibili.*;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.QuoteReply;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@UseModel
public class BiliVideo extends Model {
public String downloadPath = "tmp";
List<DanmuData> danmuDatas = new ArrayList<>();
long danmuNextTime = 0;
private BiliBiliUtils biliUtils;
private long qq;
public BiliVideo(long qq) {
this.qq = qq;
biliUtils = BiliBiliUtils.getInstance(qq);
}
public BiliVideo() {
this.qq = QQBotManager.defQQ;
biliUtils = BiliBiliUtils.getInstance(qq);
}
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "B站视频下载";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (event.getMessage().serializeToMiraiCode().contains("mirai:app")) {
int id = event.getSource().getIds()[0];
String json = event.getMessage().get(1).contentToString();
System.out.println("id = " + id);
System.out.println("json = " + json);
RedisTools.set("qq_msg_id_" + id, json, 60 * 60 * 2);
} else if (isAt()) {
if (event.getMessage().get(1) instanceof QuoteReply) {
int id = ((QuoteReply) event.getMessage().get(1)).getSource().getIds()[0];
if (msg.contains("省流") || msg.contains("总结")) {
String value = onAIVideo(id);
if(!StringUtils.isEmpty(value)){
QQBotManager.getInstance().sendMessage(qq,value);
}
}
}
}
}
private String onAIVideo(int id) {
String string = RedisTools.get("qq_msg_id_" + id);
//RedisTools.remove("qq_msg_id_"+id);
String url = null;
if (StringUtils.isEmpty(string)) {
url = ((QuoteReply) event.getMessage().get(1)).getSource().getOriginalMessage().contentToString();
} else {
JSONObject json = JSONObject.parseObject(string);
if (json.containsKey("ver")) {
url = json.getJSONObject("meta").getJSONObject("detail_1").getString("qqdocurl");
}
}
if (StringUtils.isEmpty(url)) {
return "地址不正确";
}
if (url.startsWith("BV")) {
url = "https://www.bilibili.com/video/" + url.trim();
}
if (!url.startsWith("https://www.bilibili.com/video/") && !url.startsWith("https://b23.tv")) {
return "这是B站吗?";
}
String ai = BiliBiliAppUtils.getVideoAI(url.trim());
if (!StringUtils.isEmpty(ai)) {
return ai;
}
return "省流失败";
}
public void downVideo(String url) {
downVideo(url, true, false);
}
public void downVideo(String url, boolean downDanmu, boolean merge) {
if (biliUtils == null || !new BiliLogin(qq).testLogin()) {
System.err.println("未登录");
return;
}
if (!url.contains("?")) {
url += "?";
}
danmuDatas.clear();
JSONObject info = getVideoInfo(url);
if (info.getInteger("code") == 0) {
JSONObject infoData = info.getJSONObject("data");
JSONObject eps = new JSONObject();
if (infoData.containsKey("ugc_season")) {
JSONObject ugc = infoData.getJSONObject("ugc_season");
eps.put("title", ugc.getString("title"));
JSONArray ep = new JSONArray();
for (Object o : ugc.getJSONArray("sections")) {
JSONObject season = (JSONObject) o;
for (Object episodes : season.getJSONArray("episodes")) {
JSONObject _epi = (JSONObject) episodes;
JSONObject _item = new JSONObject();
_item.put("title", season.getString("title") + "-" + _epi.getString("title"));
_item.put("cid", _epi.getLong("cid"));
_item.put("aid", _epi.getLong("aid"));
ep.add(_item);
}
}
eps.put("eps", ep);
} else if (infoData.getInteger("videos") != 1) {
JSONArray pages = infoData.getJSONArray("pages");
JSONArray ep = new JSONArray();
for (Object o : pages) {
JSONObject page = (JSONObject) o;
JSONObject _item = new JSONObject();
_item.put("title", infoData.getString("title") + "-" + page.getString("part"));
_item.put("cid", page.getLong("cid"));
_item.put("aid", infoData.getLong("aid"));
ep.add(_item);
}
eps.put("title", infoData.getString("title"));
eps.put("eps", ep);
} else {
eps.put("title", infoData.getString("title"));
eps.put("cid", infoData.getLong("cid"));
}
JSONObject json = new JSONObject();
json.put("danmu", downDanmu);
json.put("merge", merge);
json.put("avid", infoData.getLong("aid"));
if (eps.containsKey("cid")) {
json.put("cid", eps.getLong("cid"));
json.put("qn", 125);
json.put("fnval", 80);
json.put("fourk", 1);
downVideo(json, eps);
} else {
System.out.println("json = " + json);
System.out.println("eps = " + eps);
List<File> list = new ArrayList<>();
String root = new File("tmp").getAbsolutePath() + File.separator;
for (Object o : eps.getJSONArray("eps")) {
JSONObject item = (JSONObject) o;
json.put("avid", item.getLong("aid"));
json.put("cid", item.getLong("cid"));
json.put("qn", 125);
json.put("fnval", 80);
json.put("fourk", 1);
item.put("title", eps.getString("title") + "$(File.separator)" + item.getString("title"));
list.add(new File(root + StringUtils.toSaveFileName(item.getString("title") + ".mp4")));
downVideo(json, item);
if (downDanmu && merge) {
long tmp = 0;
for (VideoDanMu.DanmakuElem elem : buildDanmuHttp(json.getLong("cid"), json.getLong("avid"), 1)) {
DanmuData danmuData = new DanmuData();
danmuData.setDanmu(elem.getContent());
danmuData.setFontSize(elem.getFontsize());
danmuData.setTime(elem.getProgress() + danmuNextTime);
danmuData.setFontColor(elem.getColor());
danmuData.setModel(elem.getMode());
if (elem.getProgress() > tmp) {
tmp = elem.getProgress();
}
danmuDatas.add(danmuData);
}
danmuNextTime = tmp;
}
}
if (merge) {
merge(root, StringUtils.toSaveFileName(eps.getString("title")), list);
}
}
}
}
private void merge(String root, String name, List<File> files) {
String saveName = root + name;
File fileList = new File(saveName + File.separator + "tmp.txt");
System.out.println("fileList.getAbsolutePath() = " + fileList.getAbsolutePath());
StringBuilder builder = new StringBuilder();
int i = 0;
List<File> tmp = new ArrayList<>();
for (File file : files) {
System.out.println("file.getName() = " + file.getName());
file.renameTo(new File(file.getParentFile(), i + ".mp4"));
tmp.add(new File(file.getParentFile(), i + ".mp4"));
builder.append("file '").append(i++).append(".mp4'");
builder.append("\n");
}
try {
// boolean b = fileList.createNewFile();
// System.out.println("b = " + b);
FileWriter fw = new FileWriter(fileList);
fw.write(builder.toString());
fw.flush();
fw.close();
String exec = String.format("cd \"%s\" && ffmpeg -f concat -i \"%s\" -c copy %s.mp4", saveName, "tmp.txt", name);
System.out.println("exec = " + exec);
AppTools.exec(exec, new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
// System.out.println(data);
System.out.println("over");
fileList.delete();
for (File file : tmp) {
file.delete();
}
AssTools tools = new AssTools(name);
tools.addDanmu(danmuDatas);
boolean saveDanmu = tools.saveDanmu(saveName);
System.out.println("弹幕保存:" + saveDanmu);
}
}, false, false);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void downVideo(JSONObject json, JSONObject eps) {
eps.put("title", StringUtils.toSaveFileName(eps.getString("title")));
File tmp = new File(HttpTools.downloadPath + eps.getString("title") + ".mp4");
if (json.getBooleanValue("danmu") && !json.getBooleanValue("merge")) {
List<VideoDanMu.DanmakuElem> elems = buildDanmuHttp(json.getLong("cid"), json.getLong("avid"), 1);
downDanmu("tmp", eps.getString("title"), elems);
}
if (tmp.exists()) {
return;
}
TreeMap<String,String> body=BiliBiliWbiSign.getWbiSign(json);
JSONObject http = biliUtils.http(VideoApi.VIDEO_PLAY_URL_V2+"?" + HttpTools.toUrlParams(body), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
if (http.getInteger("code") == 0) {
JSONObject data = http.getJSONObject("data");
JSONObject dash = data.getJSONObject("dash");
JSONObject video = dash.getJSONArray("video").getJSONObject(0);
JSONObject audio = dash.getJSONArray("audio").getJSONObject(0);
File videoFile = biliUtils.download(video.getString("baseUrl"), eps.getString("title") + "_video.mp4", false);
if (videoFile == null) {
downVideo(json, eps);
return;
}
File audioFile = biliUtils.download(audio.getString("baseUrl"), eps.getString("title") + "_audio.mp3", false);
if (audioFile == null) {
videoFile.delete();
downVideo(json, eps);
return;
}
save(eps.getString("title"), videoFile, audioFile);
}
}
private void downDanmu(String savePath, String title, List<VideoDanMu.DanmakuElem> danmuList) {
try {
AssTools tools = new AssTools(title);
List<DanmuData> list = new ArrayList<>();
for (VideoDanMu.DanmakuElem elem : danmuList) {
DanmuData danmuData = new DanmuData();
danmuData.setDanmu(elem.getContent());
danmuData.setFontSize(elem.getFontsize());
danmuData.setTime(elem.getProgress());
danmuData.setFontColor(elem.getColor());
danmuData.setModel(elem.getMode());
list.add(danmuData);
}
tools.addDanmu(list);
boolean saveDanmu = tools.saveDanmu(savePath);
System.out.println("弹幕保存:" + saveDanmu);
} catch (Exception e) {
e.printStackTrace();
}
}
private List<VideoDanMu.DanmakuElem> buildDanmuHttp(long cid, long avid, int segment_index) {
List<VideoDanMu.DanmakuElem> tmp, danmuList = new ArrayList<>();
JSONObject json = new JSONObject();
json.put("type", 1);
json.put("oid", cid);
json.put("avid", avid);
json.put("segment_index", segment_index);
while (!(tmp = getDanmu(json)).isEmpty()) {
danmuList.addAll(tmp);
json.put("segment_index", ++segment_index);
}
return danmuList;
}
private List<VideoDanMu.DanmakuElem> getDanmu(JSONObject json) {
try {
byte[] http = biliUtils.http("https://api.bilibili.com/x/v2/dm/web/seg.so?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.BYTE);
VideoDanMu.DmSegMobileReply parse = VideoDanMu.DmSegMobileReply.parseFrom(http);
return parse.getElemsList();
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
private void save(String name, File videoFile, File audioFile) {
List<String> urls = new ArrayList<>();
urls.add(videoFile.getAbsolutePath());
urls.add(audioFile.getAbsolutePath());
StringBuilder builder = new StringBuilder();
builder.append(ConfigTools.load(ConfigTools.CONFIG, "ffmpeg", String.class)).append(" ");
for (String _url : urls) {
builder.append("-i").append(" ");
builder.append("\"").append(_url).append("\"").append(" ");
}
builder.append("-vcodec").append(" ");
builder.append("copy").append(" ");
builder.append("-acodec").append(" ");
builder.append("copy").append(" ");
builder.append("-threads").append(" ");
builder.append("8").append(" ");
// builder.append("-y").append(" ");
builder.append("\"").append(new File(HttpTools.downloadPath + name + ".mp4").getAbsolutePath()).append("\"").append(" ");
System.out.println(builder);
AppTools.exec(builder.toString(), new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
videoFile.delete();
audioFile.delete();
}
}, false, false);
}
public JSONObject getVideoInfo(String url) {
if (!new BiliLogin(qq).testLogin()) {
System.err.println("未登录");
return null;
}
JSONObject json = buildJSON(url);
if (json != null) {
return biliUtils.http("https://api.bilibili.com/x/web-interface/view?" + HttpTools.toUrlParams(json), BiliBiliUtils.HTTP.GET, null, BiliBiliUtils.RET_MODEL.JSON);
}
return null;
}
private JSONObject buildJSON(String url) {
if (!url.contains("?")) {
url += "?";
}
Pattern pattern = Pattern.compile("(?<=video/).*?(?=\\?)");
Matcher matcher = pattern.matcher(url);
String id = null;
if (matcher.find()) {
id = matcher.group();
}
if (id == null) {
return null;
}
if (id.contains("/")) {
id = id.replace("/", "");
}
JSONObject json = new JSONObject();
if (id.startsWith("BV")) {
json.put("bvid", id);
} else {
json.put("avid", id.toLowerCase().replace("av", ""));
}
return json;
}
public static void main(String[] args) {
BiliVideo video = new BiliVideo(QQBotManager.defQQ);
//岚少 480
//video.downVideo("https://www.bilibili.com/video/BV1Ps411m7pt?spm_id_from=333.999.0.0");
//唐诱 合集
//video.downVideo("https://www.bilibili.com/video/BV1Vv4y1K7ox?spm_id_from=444.41.top_right_bar_window_default_collection.content.click");
//邦邦 长视频
video.downVideo("https://www.bilibili.com/video/BV1w5411271A?spm_id_from=444.41.list.card_archive.click");
//LK 超清4k hdr
//video.downVideo("https://www.bilibili.com/video/BV1uZ4y1U7h8/?spm_id_from=333.788.recommend_more_video.-1");
// hdr
// video.downVideo("https://www.bilibili.com/video/BV1rp4y1e745/?spm_id_from=333.788.recommend_more_video.-1");
// 1080+ 60fps
//video.downVideo("https://www.bilibili.com/video/BV1qF411T7Vf?spm_id_from=444.41.list.card_archive.click");
//唐诱正片
//video.downVideo("https://www.bilibili.com/video/BV1L44y147zR?spm_id_from=333.999.0.0");// ep1
//video.downVideo("https://www.bilibili`.com/video/BV1Zu4y1B7DU/?spm_id_from=333.337.search-card.all.click", true, false);// ep5
// video.downVideo("https://www.bilibili.com/video/BV1SL411g7FS/?spm_id_from=333.788.recommend_more_video.0"); //all ig 1\5
// video.downVideo("https://www.bilibili.com/video/BV18L4y1H7rz?spm_id_from=333.999.0.0");
// video.downVideo("https://www.bilibili.com/video/BV1Pe4y1Q7MX?spm_id_from=444.41.top_right_bar_window_history.content.click");
// int a=16|2048;
// System.out.println("a = " + a);
//video.downDanmu(428855000L,976216102L,"【都市_情感】《唐可可的诱惑》第一集",1);
//video.downVideo("https://www.bilibili.com/bangumi/play/ep776259", false, false);// ep5
System.out.println("事件结束");
}
}

View File

@@ -0,0 +1,48 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class BTDownload extends Model {
private static final String DownloadHomePath="/media/yutou/disk_lvm/public/download/";
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[]{
QQFromCommands.BT_DOWNLOAD
};
}
@Override
public String getModelName() {
return "添加BT下载";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(msg.startsWith("magnet:?xt=")){
String builder = "已添加下载磁链" ;
QQBotManager.getInstance().sendMessage(qq, builder);
String exec = String.format("qbittorrent-nox --save-path=%sdownload_tmp/%s \"%s\" "
,DownloadHomePath
, AppTools.getToDayTime()
, msg
);
AppTools.exec(exec, new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
}
},true,false);
}
}
}

View File

@@ -1,5 +1,6 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
@@ -8,7 +9,7 @@ import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
@UseModel
public class BaiduDown extends Model {
@Override
public boolean isUserPublic() {
@@ -22,6 +23,11 @@ public class BaiduDown extends Model {
};
}
@Override
public String getModelName() {
return "同步百度云";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -0,0 +1,45 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.data.baidu.ResponseMessage;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.BaiduGPTManager;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class BaiduGPT extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{
QQGroupCommands.GPT,
QQGroupCommands.GPT_CLEAR
};
}
@Override
public String getModelName() {
return "百度文言一心GPT";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (msg.equals(QQGroupCommands.GPT_CLEAR)) {
BaiduGPTManager.getManager().clear();
QQBotManager.getInstance().sendMessage(qq, "已经失忆捏");
} else if (isAt()) {
if(msg.contains("省流")|| msg.contains("总结")){
return;
}
ResponseMessage message = BaiduGPTManager.getManager().sendMessage(String.valueOf(user), msg.replace("@2476945931", "").trim());
QQBotManager.getInstance().sendMessage(qq, message.getResult());
}
}
}

View File

@@ -1,5 +1,6 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model;
@@ -14,7 +15,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@UseModel
public class Bangumi extends Model {
@@ -22,27 +23,28 @@ public class Bangumi extends Model {
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(!isGroupPower){
return;
}
switch (msg){
switch (msg) {
case QQGroupCommands.QQ_BANGUMI_TODAY -> {
QQBotManager.getInstance().sendMessage(qq, "获取中...");
RedisTools.remove("reportToDayBangumi");
QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportToDayBangumi());
}
case QQGroupCommands.QQ_BANGUMI_LIST -> {
QQBotManager.getInstance().sendMessage(qq,"获取中...");
QQBotManager.getInstance().sendMessage(qq,BangumiTools.reportBangumiList());
}default -> {
if(msg.startsWith(QQGroupCommands.QQ_BANGUMI_SUB)){
subBanGumi(qq,msg);
QQBotManager.getInstance().sendMessage(qq, "获取中...");
QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportBangumiList());
}
default -> {
if (msg.startsWith(QQGroupCommands.QQ_BANGUMI_SUB)) {
subBanGumi(qq, msg);
}
}
}
}
private void subBanGumi(long qq,String msg){
private void subBanGumi(long qq, String msg) {
List<String> infos = null;
QQBotManager.getInstance().sendMessage(qq, "获取中...");
try {
int id = Integer.parseInt(msg.replace(QQGroupCommands.QQ_BANGUMI_SUB, "").trim());
infos = BangumiTools.reportBangumiInfo(id);
@@ -58,9 +60,10 @@ public class Bangumi extends Model {
info = info.replace("<img " + img + " /img>", "");
}
}
sendImagesMsg(imgs,qq, info);
sendImagesMsg(imgs, qq, info, msg.replace(QQGroupCommands.QQ_BANGUMI_SUB, "").trim());
}
}
public static List<String> getImages(String str) {
List<String> list = new ArrayList<>();
String regex = "<img(.*?)/img>";
@@ -73,38 +76,27 @@ public class Bangumi extends Model {
}
return list;
}
private List<File> files;
private int index = 0;
private void sendImagesMsg(List<String> imgs,Long qq, String text) {
private void sendImagesMsg(List<String> imgs, Long qq, String text, String key) {
files = new ArrayList<>();
index = 0;
if (imgs.size() == 0) {
QQBotManager.getInstance().sendMessage(qq,text);
QQBotManager.getInstance().sendMessage(qq, text);
return;
}
for (String img : imgs) {
HttpTools.download(img,null, new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
files.add(file);
send(imgs.size(),qq, text);
}
@Override
public void onError(Exception e) {
super.onError(e);
index++;
send(imgs.size(),qq, text);
}
});
File file = HttpTools.syncDownload(img.replace("http://", "https://"), key + ".jpg",false);
files.add(file);
send(imgs.size(), qq, text);
}
}
private void send(int size,Long qq, String text) {
private void send(int size, Long qq, String text) {
if ((files.size() + index) == size) {
String str = QQBotManager.getInstance().sendMessage(files,qq, text);
String str = QQBotManager.getInstance().sendMessage(files, qq, text);
Log.i("str = " + str);
}
}
@@ -124,10 +116,15 @@ public class Bangumi extends Model {
}
@Override
public void onTime(String time) {
super.onTime(time);
public String getModelName() {
return "新番列表";
}
@Override
public void onTime(Long qq, String time) {
super.onTime(qq, time);
switch (time) {
case "08:00", "20:00" -> QQBotManager.getInstance().sendMessage(QQBotManager.defGroup,BangumiTools.reportToDayBangumi());
case "08:00:00", "20:00:00" -> QQBotManager.getInstance().sendMessage(qq, BangumiTools.reportToDayBangumi());
}
}
}

View File

@@ -0,0 +1,43 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@UseModel
public class MaoMaoWorkWaring extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{QQ_TIMEOUT};
}
@Override
public String getModelName() {
return "毛毛工作提醒";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(Integer.parseInt(AppTools.getHours())>=6 && event.getSource().getFromId() == 526306604
&& "false".equals(RedisTools.get("maomao_work_"+AppTools.getToDayTime(),"false"))){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new QuoteReply(event.getMessage()));
builder.append("别水了,快去打工,没钱氪老婆了");
QQBotManager.getInstance().sendMessage(qq,builder);
RedisTools.set("maomao_work_"+AppTools.getToDayTime(),"true",20*60*60);
}
}
}

View File

@@ -0,0 +1,93 @@
package com.yutou.qqbot.models.Commands;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
@UseModel
public class Moyu extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "摸鱼提醒";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (msg.equals(QQGroupCommands.QQ_MOYU)) {
send(qq);
}
}
@Override
public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("09:50:00".equals(time)) {
downloadImage(false, qq);
}
if ("10:00:00".equals(time)) {
send(qq);
}
}
private void downloadImage(boolean isSend, Long qq) {
Log.i(this, "下载图片");
String ret = HttpTools.get("https://api.vvhan.com/api/moyu?type=json");
JSONObject json = JSON.parseObject(ret);
HttpTools.download(json.getString("url"), AppTools.getToDayTime() + "_moyu.jpg", new DownloadInterface() {
int count = 3;
@Override
public void onDownload(File file) {
super.onDownload(file);
if (isSend) {
send(qq);
}
}
@Override
public void onError(Exception e) {
super.onError(e);
e.printStackTrace();
if (count == 0) {
return;
}
downloadImage(isSend, qq);
count--;
}
});
}
private void send(Long qq) {
File file = new File(HttpTools.downloadPath + AppTools.getToDayTime() + "_moyu.jpg");
Log.i(this, "发送图片 : file.exists = " + file.exists() + " qq = " + qq);
if (file.exists()) {
QQBotManager.getInstance().sendMessage(file, qq, "");
} else {
downloadImage(true, qq);
}
}
public static void main(String[] args) {
}
}

View File

@@ -0,0 +1,50 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_TIMEOUT;
@UseModel
public class PaoPaoSleepWaring extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[]{QQ_TIMEOUT};
}
@Override
public String getModelName() {
return "泡泡提醒";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(Integer.parseInt(AppTools.getHours())>=22 && event.getSource().getFromId() == 914520754
&& "false".equals(RedisTools.get("paopao_sleep_"+AppTools.getToDayTime(),"false"))){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new QuoteReply(event.getMessage()));
builder.append("别水了,该睡了~");
QQBotManager.getInstance().sendMessage(qq,builder);
RedisTools.set("paopao_sleep_"+AppTools.getToDayTime(),"true",1*60*60);
}
/*if(event.getSource().getFromId() == 914520754 && msg.contains("#体力")){
MessageChainBuilder builder=new MessageChainBuilder();
builder.append(new At(369224573L));
builder.append("惠城! 体力! ");
QQBotManager.getInstance().sendMessage(qq,builder);
}*/
}
}

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.models.audio.QQAudio;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class Audio extends Model {
@Override
@@ -20,6 +21,11 @@ public class Audio extends Model {
};
}
@Override
public String getModelName() {
return "音频播放";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,10 +1,11 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class BtFlash extends Model {
@Override
public boolean isUserPublic() {
@@ -18,6 +19,11 @@ public class BtFlash extends Model {
};
}
@Override
public String getModelName() {
return "刷新bt";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class Cmd extends Model {
@Override
public boolean isUserPublic() {
@@ -18,6 +19,11 @@ public class Cmd extends Model {
};
}
@Override
public String getModelName() {
return "cmd指令";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class Help extends Model {
@Override
@@ -16,11 +17,16 @@ public class Help extends Model {
return new String[0];
}
@Override
public String getModelName() {
return "帮助";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(msg.equals(QQGroupCommands.QQ_HELP)){
QQBotManager.getInstance().sendMessage(qq,getCommands(QQGroupCommands.class).toString());
QQBotManager.getInstance().sendMessage(qq,getCommands(QQGroupCommands.class).append(getCommands(QQFromCommands.class)).toString());
}
}
}

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class IP extends Model {
@Override
public boolean isUserPublic() {
@@ -17,6 +18,11 @@ public class IP extends Model {
};
}
@Override
public String getModelName() {
return "获取nas ip";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,12 +1,13 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
@UseModel
public class OpenPC extends Model {
@Override
public boolean isUserPublic() {
@@ -20,6 +21,11 @@ public class OpenPC extends Model {
};
}
@Override
public String getModelName() {
return "远程开机";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,10 +1,11 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.AppTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class Restart extends Model {
@Override
public boolean isUserPublic() {
@@ -18,6 +19,11 @@ public class Restart extends Model {
};
}
@Override
public String getModelName() {
return "重启服务(NAS)";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,12 +1,13 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.IdeaTools;
import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class ToolsIdea extends Model {
@Override
public boolean isUserPublic() {
@@ -22,6 +23,11 @@ public class ToolsIdea extends Model {
};
}
@Override
public String getModelName() {
return "获取idea激活码";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.RedisTools;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class UpdateIP extends Model {
@Override
public boolean isUserPublic() {
@@ -17,6 +18,11 @@ public class UpdateIP extends Model {
};
}
@Override
public String getModelName() {
return "DDNS更新IP";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -1,9 +1,10 @@
package com.yutou.qqbot.models.Commands.System;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.event.events.MessageEvent;
@UseModel
public class Version extends Model {
@Override
public boolean isUserPublic() {
@@ -17,6 +18,11 @@ public class Version extends Model {
};
}
@Override
public String getModelName() {
return "版本信息";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);

View File

@@ -0,0 +1,54 @@
package com.yutou.qqbot.models.Commands;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.contact.AudioSupported;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.Audio;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.OfflineAudio;
import net.mamoe.mirai.utils.ExternalResource;
import java.io.File;
import java.util.Objects;
import static com.yutou.qqbot.models.Model.QQGroupCommands.QQ_WOODEN;
@UseModel
public class WoodenFish extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "电子木鱼";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
File file = null;
if(msg.contains("地狱笑话")){
file=new File("muyu.mp3");
QQBotManager.getInstance().sendMessage(qq,"功德+1");
}else if(msg.contains("遥遥领先")){
file=new File("遥遥领先.silk");
}
if(file!=null){
if(file.exists()) {
OfflineAudio audio = Objects.requireNonNull(event.getBot().getGroup(qq)).uploadAudio(ExternalResource.create(file));
MessageChainBuilder builder = new MessageChainBuilder();
builder.append(audio);
QQBotManager.getInstance().sendMessage(qq,builder);
}
}
}
}

View File

@@ -1,9 +1,14 @@
package com.yutou.qqbot.models;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.interfaces.ModelInterface;
import com.yutou.qqbot.utlis.ConfigTools;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.event.events.GroupMessageEvent;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import java.lang.reflect.Field;
import java.util.ArrayList;
@@ -31,19 +36,40 @@ public abstract class Model implements ModelInterface {
public final static String QQ_TOOLS_IDEA_URL = "!idea_url";
public final static String QQ_BANGUMI_INFO = "!保存动画信息>";
public final static String QQ_MOYU = "!摸鱼";
public final static String BILI_LIVE_DANMU_SEND = "!b站签到";
public final static String BILI_LIVE_DANMU_LIST = "!b站列表";
public final static String BILI_LIVE_DANMU_DEL = "!b站签到删除";
public final static String QQ_WOODEN = "!电子木鱼";
public final static String QQ_TIMEOUT = "!timer";
public final static String GPT="!百度gpt";
public final static String GPT_CLEAR="!百度失忆";
}
public static class QQFromCommands {
public static final String TURNIP_PROPHET = "大头菜";
public static final String TSDM_PAY = "!tsdm";
public static final String TSDM_SIGN = "!tsdm签到";
public static final String BAIDU_DOWN = "!bd";
public static final String ROUTER_ADD = "!添加设备";
public static final String ROUTER_DEL = "!删除设备";
public static final String BT_DOWNLOAD = "下载bt";
public static final String BILI_MANGA_SIGN="!b站漫画签到";
public static final String BILI_MANGA_PAY="!b站漫画积分兑换";
public static final String BILI_MANGA_PAY_STOP="!b站漫画积分兑换取消";
}
public static List<Class<?>> classList = new ArrayList<>();
public static List<Class<?>> classList;
long group;
public MessageEvent event;
static {
classList = new ArrayList<>();
}
public Model() {
if (!classList.contains(getClass())) {
@@ -54,11 +80,16 @@ public abstract class Model implements ModelInterface {
public String msg;
protected boolean isGroupPower = false;
private boolean isGroup;
public Long user;
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
this.event=event;
msg = event.getMessage().contentToString();
msg = msg.replace("", "!");
if(isGroup) {
msg = msg.replace("", "!").trim();
this.isGroup = isGroup;
if (isGroup) {
user = event.getSource().getFromId();
GroupMessageEvent groupEvent = (GroupMessageEvent) event;
group = groupEvent.getGroup().getId();
if (QQNumberManager.getManager().isExistsPower(group, msg.split(" ")[0])) {
@@ -67,7 +98,7 @@ public abstract class Model implements ModelInterface {
}
}
public void onTime(String time) {
public synchronized void onTime(Long qq, String time) {
}
public static StringBuilder getCommands(Class<?> commands) {
@@ -83,4 +114,16 @@ public abstract class Model implements ModelInterface {
return builder;
}
public MessageChainBuilder getMessage(String text) {
MessageChainBuilder chain = new MessageChainBuilder();
if (isGroup) {
chain.add(new At(user));
chain.add("\n");
}
chain.add(text);
return chain;
}
public boolean isAt(){
return msg.contains("@"+ ConfigTools.load(ConfigTools.CONFIG,"qq_number",String.class));
}
}

View File

@@ -1,17 +1,19 @@
package com.yutou.qqbot.models.WebSign;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
import org.openqa.selenium.By;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.io.File;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
@UseModel
public class BaiHeHui extends Model {
@Override
public boolean isUserPublic() {
@@ -24,50 +26,76 @@ public class BaiHeHui extends Model {
}
@Override
public void onTime(String time) {
super.onTime(time);
if ("08:10".equals(time)) {
public String getModelName() {
return "百合会签到";
}
@Override
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("08:10:00".equals(time)) {
Log.i("开始百合会签到");
try {
sign();
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup,"百合会签到成功");
if (sign()) {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "百合会签到成功");
} else {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "百合会签到失败");
}
} catch (Exception e) {
e.printStackTrace();
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup,"百合会签到失败:"+ AppTools.getExceptionString(e));
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "百合会签到失败:" + AppTools.getExceptionString(e));
} finally {
WebClient.getInstance().quit();
}
}
}
public void sign() {
String cookie = ConfigTools.readFile(new File("baihehui.json"));
if (StringUtils.isEmpty(cookie)) {
return;
}
public boolean sign() {
WebDriver driver = WebClient.getInstance().getWebDriver();
JSONArray array = JSONArray.parseArray(cookie);
driver.manage().timeouts().implicitlyWait(10000, TimeUnit.SECONDS);
driver.get("https://bbs.yamibo.com/forum.php");
driver.manage().deleteAllCookies();
for (Cookie _cookie : WebClient.loadCookie(array)) {
driver.manage().addCookie(_cookie);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.navigate().refresh();
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if("打卡签到".equals(element.getText())){
element.click();
break;
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
driver.get("https://bbs.yamibo.com/forum.php");
login(driver);
// driver.manage().deleteAllCookies();
/* Thread.sleep(1000);
for (Cookie _cookie : WebClient.loadCookie(array)) {
System.err.println(_cookie);
driver.manage().addCookie(_cookie);
Thread.sleep(100);
}*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.navigate().refresh();
driver.get("https://bbs.yamibo.com/plugin.php?id=zqlj_sign");
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if ("点击打卡".equals(element.getText())) {
element.click();
break;
}
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
private void login(WebDriver driver) {
driver.get("https://bbs.yamibo.com/member.php?mod=logging&action=login");
driver.findElement(By.name("username")).sendKeys("z583819556");
driver.findElement(By.name("password")).sendKeys("u8fi4Qfr.5D2wZ5");
driver.findElement(By.name("loginsubmit")).submit();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
driver.close();
driver.quit();
}
public static void main(String[] args) {
new BaiHeHui().sign();
}
}

View File

@@ -0,0 +1,135 @@
package com.yutou.qqbot.models.WebSign;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.bilibili.BiliBiliManga;
import com.yutou.qqbot.bilibili.BiliLogin;
import com.yutou.qqbot.interfaces.ObjectInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.QRCodeUtils;
import net.mamoe.mirai.event.events.MessageEvent;
import java.io.File;
@UseModel
public class BiliBiliMangeSign extends Model {
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[]{
QQFromCommands.BILI_MANGA_SIGN,
QQFromCommands.BILI_MANGA_PAY,
QQFromCommands.BILI_MANGA_PAY_STOP
};
}
@Override
public String getModelName() {
return "B站漫画签到and商城兑换";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if(user==null){
return;
}
BiliBiliManga manga = new BiliBiliManga(user);
if (msg.equals(QQFromCommands.BILI_MANGA_SIGN)) {
String msg;
if (new BiliLogin(user).testLogin()) {
if (BiliBiliManga.sign() == null) {
msg = "B站漫画已经签到过了";
} else {
msg = "B站漫画签到完成";
}
QQBotManager.getInstance().sendMessage(qq, msg);
} else {
new BiliLogin(user).loginAsQQ();
}
} else if (msg.equals(QQFromCommands.BILI_MANGA_PAY)) {
StringBuilder builder = new StringBuilder();
builder.append("可用积分:").append(BiliBiliManga.getMyPoint()).append("\n");
builder.append("-------商城列表-------").append("\n");
for (BiliBiliManga.Product product : BiliBiliManga.getListProduct()) {
builder.append(product).append("\n");
}
builder.append("-------------------").append("\n");
builder.append("使用方法:")
.append(QQFromCommands.BILI_MANGA_PAY)
.append(" id 数量[num]")
.append("\n");
builder.append("参数说明:")
.append("\n")
.append("id=物品id")
.append("\n")
.append("num=物品数量,缺省或-1为全部")
.append("\n");
if (BiliBiliManga.isPayMission()) {
builder.append("当前已有执行任务:").append(BiliBiliManga.getMission());
}
QQBotManager.getInstance().sendMessage(qq, builder.toString());
} else if (msg.equals(QQFromCommands.BILI_MANGA_PAY_STOP)) {
manga.stopPayMission();
QQBotManager.getInstance().sendMessage(qq, "当前任务已取消:" + BiliBiliManga.getMission());
} else if (msg.startsWith(QQFromCommands.BILI_MANGA_PAY)) {
msg = msg.replace(QQFromCommands.BILI_MANGA_PAY, "");
String[] message = msg.split(" ");
int num = -1;
int id = 0;
for (String s : message) {
try {
if (id == 0) {
id = Integer.parseInt(s);
} else if (num == -1) {
num = Integer.parseInt(s);
}
} catch (Exception ignored) {
}
}
if (id == 0) {
System.out.println(msg);
for (String s : message) {
System.out.println(s);
}
QQBotManager.getInstance().sendMessage(qq, "商城id错误");
return;
}
manga.addInterface(new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
if (!data.startsWith("[2]") && !data.startsWith("[4]") && !data.startsWith("[1]")) {
QQBotManager.getInstance().sendMessage(qq, "任务异常:" + data);
manga.stopPayMission();
}
}
});
QQBotManager.getInstance().sendMessage(qq, manga.startPayMission(id, num).getString("msg"));
}
}
@Override
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("00:01:00".equals(time)) {
if (new BiliLogin(QQBotManager.defQQ).testLogin()) {
String msg;
if (BiliBiliManga.sign() == null) {
msg = "B站漫画已经签到过了";
} else {
msg = "B站漫画签到完成";
}
QQBotManager.getInstance().sendMessage(msg);
}
}
}
}

View File

@@ -0,0 +1,83 @@
package com.yutou.qqbot.models.WebSign;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import java.io.File;
import java.util.concurrent.TimeUnit;
@UseModel
public class NicePT extends Model {
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "NicePT签到";
}
@Override
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("08:01:00".equals(time)) {
Log.i("开始NicePT签到");
try {
if(sign()) {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "已完成NicePT的签到");
}else{
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "NicePT签到失败");
}
} catch (Exception e) {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "NicePT签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}finally {
WebClient.getInstance().quit();
}
}
}
public boolean sign() {
String url = "https://www.nicept.net/attendance.php";
JSONArray array = JSON.parseArray(ConfigTools.readFile(new File("nicept.json")));
if (array == null) {
System.err.println("array is null");
return false;
}
WebDriver driver = WebClient.getInstance().getWebDriver();
try {
driver.manage().timeouts().implicitlyWait(10000, TimeUnit.SECONDS);
driver.get(url);
driver.navigate().refresh();
for (Cookie _cookie : WebClient.loadCookie(array)) {
driver.manage().addCookie(_cookie);
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.get(url);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}

View File

@@ -1,6 +1,9 @@
package com.yutou.qqbot.models.WebSign;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.*;
@@ -9,7 +12,7 @@ import org.openqa.selenium.*;
import java.io.File;
import java.util.concurrent.TimeUnit;
@UseModel
public class Tsdm extends Model {
@Override
public boolean isUserPublic() {
@@ -23,6 +26,11 @@ public class Tsdm extends Model {
};
}
@Override
public String getModelName() {
return "天使动漫签到";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
@@ -38,59 +46,66 @@ public class Tsdm extends Model {
}
@Override
public void onTime(String time) {
super.onTime(time);
if ("08:00".equals(time)) {
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("08:05:00".equals(time)) {
Log.i("开始天使动漫签到");
try {
tsdmSign();
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "已完成天使动漫的签到");
if (tsdmSign()) {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "已完成天使动漫的签到");
} else {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "天使动漫签到失败");
}
} catch (Exception e) {
QQBotManager.getInstance().sendMessage(QQBotManager.defGroup, "天使动漫签到失败:" + AppTools.getExceptionString(e));
e.printStackTrace();
}finally {
WebClient.getInstance().quit();
}
}
}
public void tsdmSign() {
JSONArray array = JSONArray.parseArray(ConfigTools.readFile(new File("cookie.json")));
public boolean tsdmSign() {
JSONArray array = JSON.parseArray(ConfigTools.readFile(new File("cookie.json")));
if (array == null) {
System.err.println("array is null");
return;
return false;
}
WebDriver driver = WebClient.getInstance().getWebDriver();
driver.get("https://www.tsdm39.net/forum.php");
getTsdm(array, driver);
boolean isSign=false;
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if(element.getText().contains("签到领奖!")){
isSign=true;
break;
try {
driver.get("https://www.tsdm39.net/forum.php");
getTsdm(array, driver);
boolean isSign = false;
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if (element.getText().contains("签到领奖!")) {
isSign = true;
break;
}
}
}
if(!isSign){
driver.close();
driver.quit();
return;
}
try {
((JavascriptExecutor) driver).executeScript("showWindow('dsu_paulsign', 'plugin.php?id=dsu_paulsign:sign&9b5e8da2')");
} catch (Exception ignored) {
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
driver.findElement(By.id("wl")).click();
driver.findElement(By.xpath("//input[@value='3']")).click();
driver.findElement(By.id("qiandao")).submit();
if (!isSign) {
return true;
}
try {
((JavascriptExecutor) driver).executeScript("showWindow('dsu_paulsign', 'plugin.php?id=dsu_paulsign:sign&9b5e8da2')");
} catch (Exception ignored) {
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
driver.findElement(By.id("wl")).click();
driver.findElement(By.xpath("//input[@value='3']")).click();
driver.findElement(By.id("qiandao")).submit();
} catch (Exception e) {
e.printStackTrace();
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
driver.close();
driver.quit();
}
private void getTsdm(JSONArray array, WebDriver driver) {
@@ -113,7 +128,7 @@ public class Tsdm extends Model {
}
public String tsdm(String url) {
JSONArray array = JSONArray.parseArray(ConfigTools.readFile(new File("cookie.json")));
JSONArray array = JSON.parseArray(ConfigTools.readFile(new File("cookie.json")));
if (array == null) {
System.err.println("array is null");
return null;
@@ -137,4 +152,8 @@ public class Tsdm extends Model {
driver.quit();
return body;
}
public static void main(String[] args) {
new Tsdm().tsdmSign();
}
}

View File

@@ -0,0 +1,80 @@
package com.yutou.qqbot.models.WebSign;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.ConfigTools;
import com.yutou.qqbot.utlis.StringUtils;
import com.yutou.qqbot.utlis.WebClient;
import org.openqa.selenium.*;
import java.io.File;
@UseModel
public class ZhuZhu extends Model {
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "HiRes猪猪论坛签到模块";
}
@Override
public synchronized void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("09:01:00".equals(time)) {
if(sign()){
QQBotManager.getInstance().sendMessage("HiRes论坛签到成功");
}else{
QQBotManager.getInstance().sendMessage("HiRes论坛签到失败");
}
WebClient.getInstance().quit();
}
}
public boolean sign() {
String url = "https://magpapa.online/";
String cookie = ConfigTools.readFile(new File("zhuzhu.cookie"));
if (StringUtils.isEmpty(cookie)) {
return false;
}
JSONArray array = JSON.parseArray(cookie);
WebDriver driver = WebClient.getInstance().getWebDriver();
try {
driver.get(url);
driver.manage().deleteAllCookies();
for (Cookie _cookie : WebClient.loadCookie(array)) {
driver.manage().addCookie(_cookie);
Thread.sleep(100);
}
driver.navigate().refresh();
driver.get("https://magpapa.online/plugin.php?id=dc_signin");
for (WebElement element : driver.findElements(By.xpath("//a"))) {
if ("签到".equals(element.getText())) {
element.click();
Thread.sleep(1000);
click(driver);
Thread.sleep(1000);
break;
}
}
} catch (Exception e) {
return false;
}
return true;
}
private void click(WebDriver driver){
driver.findElement(By.className("dcsignin_list")).findElement(By.id("emot_9")).click();
driver.findElement(By.id("fwin_content_sign")).findElement(By.name("signpn")).click();
}
}

View File

@@ -0,0 +1,129 @@
package com.yutou.qqbot.models.XiaoMi;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.XiaoMiRouter;
import net.mamoe.mirai.event.events.MessageEvent;
import java.util.HashSet;
import java.util.Set;
@UseModel
public class MiRouter extends Model {
public static String redis_key = "MiRouterDevices";
@Override
public boolean isUserPublic() {
return false;
}
@Override
public String[] getUsePowers() {
return new String[]{
QQFromCommands.ROUTER_ADD,
QQFromCommands.ROUTER_DEL
};
}
@Override
public String getModelName() {
return "小米路由器";
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
if (msg.equals(QQFromCommands.ROUTER_ADD)) {
String url = "http://192.168.31.88:8002/router/device/add.do?qq=" + qq;
QQBotManager.getInstance().sendMessage(qq, "点击该链接完成设备添加:\n" + url);
} else if (msg.equals(QQFromCommands.ROUTER_DEL)) {
String url = "http://192.168.31.88:8002/router/device/del.do?qq=" + qq;
QQBotManager.getInstance().sendMessage(qq, "点击该删除设备:\n" + url);
}
}
private static boolean isRunTime = true;
@Override
public void onTime(Long qq,String time) {
super.onTime(qq,time);
if (isRunTime) {
return;
}
isRunTime = true;
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
isRunTime = false;
}
private void run()throws Exception{
String url = XiaoMiRouter.getDeviceListUrl();
JSONObject json = JSON.parseObject(HttpTools.get(url));
if (json.getInteger("code") == 0) {
String _tmp = RedisTools.get(redis_key);
if (_tmp == null) {
return;
}
JSONArray devices = JSON.parseArray(_tmp);
JSONArray devs =JSON.parseArray(devices.toString());
JSONArray array = json.getJSONArray("list");
Set<String> links = new HashSet<>();
for (Object o : array) {
JSONObject item = (JSONObject) o;
for (Object device : devices) {
JSONObject _device = (JSONObject) device;
devs.remove(_device);
if (_device.getString("mac").equals(item.getString("mac")) && !_device.getBooleanValue("online")) {
StringBuilder builder = new StringBuilder();
builder.append(item.getString("oname"));
builder.append(" 欢迎回家!").append("\n");
builder.append("点击该链接开门:").append("\n");
builder.append("http://192.168.31.88:802/openDoor.html");
QQBotManager.getInstance().sendMessage(_device.getLong("qq"), builder.toString());
_device.put("online", true);
_device.put("name", item.getString("oname"));
}
if (_device.getString("mac").equals(item.getString("mac")) && _device.getBooleanValue("online")) {
links.add(_device.getString("mac"));
_device.put("linkTime", Long.parseLong(item.getJSONObject("statistics").getString("online")));
}
devs.add(_device);
}
}
devices = JSON.parseArray(devs.toString());
for (Object device : devices) {
JSONObject item = (JSONObject) device;
if (!links.contains(item.getString("mac")) && item.getLong("linkTime") != 0) {
devs.remove(device);
String builder = "你的设备:" +
item.getString("name") +
"已下线" + "\n" +
"在线时长:" + getOnLineTime(item.getString("linkTime")) + "\n";
QQBotManager.getInstance().sendMessage(item.getLong("qq"), builder);
item.put("online", false);
item.put("linkTime", 0);
devs.add(item);
}
}
RedisTools.set(redis_key, devs.toString());
}else {
XiaoMiRouter.setNotToken();
}
}
private String getOnLineTime(String online) {
long time = Long.parseLong(online);
long day = time / 24 / 60 / 60;
long h = time / 60 / 60 % 24;
long m = time / 60 % 60;
long s = time % 60;
return String.format("%02d天%02d时%02d分%02d秒", day, h, m, s);
}
}

View File

@@ -0,0 +1,258 @@
package com.yutou.qqbot.models.setu;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.models.Model;
import com.yutou.qqbot.utlis.HttpTools;
import com.yutou.qqbot.utlis.Log;
import com.yutou.qqbot.utlis.RedisTools;
import com.yutou.qqbot.utlis.StringUtils;
import net.mamoe.mirai.event.events.MessageEvent;
import net.mamoe.mirai.message.MessageReceipt;
import net.mamoe.mirai.message.data.At;
import net.mamoe.mirai.message.data.MessageChainBuilder;
import net.mamoe.mirai.message.data.QuoteReply;
import redis.clients.jedis.Jedis;
import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@UseModel
public class GetSeTu extends Model {
@Override
public boolean isUserPublic() {
return true;
}
@Override
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "随机二次元图";
}
@Override
public void onTime(Long qq, String time) {
super.onTime(qq, time);
if ("00:00:00".equals(time)) {
del();
} else if (RedisTools.get("Setu_time", "23:59:00").equals(time)) {
send(qq);
}
}
private void del() {
Jedis redis = RedisTools.getRedis();
redis.select(RedisTools.QQBOT_USER);
Set<String> keys = redis.keys("Setu_*");
for (String key : keys) {
redis.del(key);
}
redis.close();
}
private void send(Long group) {
Jedis redis = RedisTools.getRedis();
redis.select(RedisTools.QQBOT_USER);
String ret = redis.get("Setu_" + group);
redis.close();
MessageChainBuilder builder = null;
if (!StringUtils.isEmpty(ret)) {
JSONArray array = JSON.parseArray(ret);
builder = new MessageChainBuilder();
builder.append("各位老色胚们晚上好,现在公布本群涩图数据!");
builder.append("\n");
builder.append("本群今日共查询:");
builder.append(String.valueOf(array.size()));
builder.append("次!\n");
builder.append("接下来公布大伙的XP系统:");
builder.append("\n");
Map<Long, List<String>> map = new HashMap<>();
for (Object o : array) {
JSONObject item = (JSONObject) o;
List<String> tags = map.getOrDefault(item.getLong("user"), new ArrayList<>());
tags.add(item.getString("key"));
map.put(item.getLong("user"), tags);
}
Long maxQQ = -1L;
int max = -1;
for (Long qq : map.keySet()) {
builder.append("------------------\n");
List<String> list = map.get(qq);
if (list.size() > max) {
max = list.size();
maxQQ = qq;
}
builder.append(new At(qq))
.append(":\n");
for (String tag : list) {
if (StringUtils.isEmpty(tag)) {
tag = "随机";
}
builder.append(tag).append("\n");
}
builder.append("------------------\n");
}
builder.append("那么今日最色批的就是:");
builder.append(new At(maxQQ));
builder.append("\n");
builder.append("如果炸群了请找他(\n");
builder.append("明天见~");
}
if (builder != null) {
QQBotManager.getInstance().sendMessage(group, builder);
}
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup) {
super.onMessage(qq, event, isGroup);
boolean isRun = false;
boolean isR18 = false;
if (msg.contains("来点") && msg.contains("色图")) {
isRun = true;
} else if (msg.contains("来点") && msg.contains("涩图")) {
isRun = true;
isR18 = true;
msg = msg.replace("涩图", "色图");
}
if (isRun) {
Log.i(event.getSource().getFromId() + " > " + msg);
Pattern pattern = Pattern.compile("来点(.*?)色图");
Matcher matcher = pattern.matcher(msg);
String key = null;
if (matcher.find()) {
key = matcher.group(1);
}
if (!getSeTu("tag", key, isR18, false, qq, event)) {
if (!getSeTu("tag", key, isR18, true, qq, event)) {
if (!getSeTu("keyword", key, isR18, true, qq, event)) {
QQBotManager.getInstance().sendMessage(qq, "找不到喵~ 不如随便来点吧~");
getSeTu("tag", null, false, false, qq, event);
}
}
}
JSONObject data = new JSONObject();
data.put("user", event.getSource().getFromId());
data.put("group", qq);
data.put("key", key);
String redis = RedisTools.get("Setu_" + qq);
JSONArray array = new JSONArray();
if (!StringUtils.isEmpty(redis)) {
array = JSON.parseArray(redis);
}
array.add(data);
RedisTools.set("Setu_" + qq, array.toString());
}
}
private boolean getSeTu(String model, String key, boolean r18, boolean fuzzyR18, Long qq, MessageEvent event) {
return getSeTu(model, key, r18, fuzzyR18, qq, event, 3);
}
private boolean getSeTu(String model, String key, boolean r18, boolean fuzzyR18, Long qq, MessageEvent event, int reset) {
if (reset <= 0) {
QQBotManager.getInstance().sendMessage(qq, "获取失败喵~");
return false;
}
String url = "https://api.lolicon.app/setu/v2?r18=0&size=regular";
if (r18) {
url = "https://api.lolicon.app/setu/v2?r18=1&size=regular";
}
final String tmpKey = key;
if (!StringUtils.isEmpty(key)) {
if ("tag".equals(model)) {
String[] keys = key.split(" ");
StringBuilder keyBuilder = new StringBuilder();
for (String _key : keys) {
keyBuilder.append(URLEncoder.encode(_key, StandardCharsets.UTF_8)).append("&tag=");
}
key = keyBuilder.toString();
key = key.substring(0, key.length() - 5);
} else {
key = URLEncoder.encode(key, StandardCharsets.UTF_8);
}
if (r18) {
url = "https://api.lolicon.app/setu/v2?" + model + "=" + key + "&r18=1&size=regular";
} else {
url = "https://api.lolicon.app/setu/v2?" + model + "=" + key + "&r18=0&size=regular";
}
}
if (fuzzyR18) {
url = url.replace("&r18=0", "&r18=2").replace("&r18=1", "&r18=2");
}
System.out.println("url = " + url);
String ret = HttpTools.http_get(url, null, false);
JSONObject json = JSON.parseObject(ret);
if (json.getJSONArray("data").size() == 0) {
return false;
}
JSONObject item = json.getJSONArray("data").getJSONObject(0);
StringBuilder builder = new StringBuilder();
builder.append(item.getString("title"));
builder.append("\n");
builder.append("P站ID:");
builder.append(item.getInteger("pid"));
builder.append("\n");
builder.append("R18:");
if (item.getBooleanValue("r18")) {
builder.append("YES!");
} else {
builder.append("NO~");
}
builder.append("\n");
builder.append("tags:");
for (Object tags : item.getJSONArray("tags")) {
builder.append(tags).append("");
}
HttpTools.download(item.getJSONObject("urls").getString("regular"),
System.currentTimeMillis() + "_setu.jpg",
true
, new DownloadInterface() {
@Override
public void onDownload(File file) {
super.onDownload(file);
builder.append("\n看不到图?点这里:http://setu.cnmglz.com/setu/").append(file.getName());
QQBotManager.getInstance().sendMessage(file, qq, event.getMessage(), "");
MessageChainBuilder chain = new MessageChainBuilder();
chain.append(new QuoteReply(event.getMessage()));
chain.append(builder.toString());
MessageReceipt<?> message = QQBotManager.getInstance().sendMessage(qq, chain);
Log.i(getModelName(), message);
}
@Override
public void onError(Exception e) {
super.onError(e);
getSeTu(model, tmpKey, r18, fuzzyR18, qq, event, reset - 1);
e.printStackTrace();
}
});
return true;
}
public static void main(String[] args) {
String msg = "来点1色图";
Pattern pattern = Pattern.compile("来点(.*?)色图");
Matcher matcher = pattern.matcher(msg);
String key = null;
if (matcher.find()) {
key = matcher.group(1);
}
System.out.println("key = " + key);
}
}

View File

@@ -1,7 +1,8 @@
package com.yutou.qqbot.models.setu;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
@@ -35,8 +36,8 @@ public class QQSetu extends Model {
Log.i("今日涩图 redisKey = " + redisKey);
String js = RedisTools.get(redisKey, db_print);
if (js != null) {
JSONObject json = JSONObject.parseObject(js);
if(json.containsKey("isPrint")&&json.getBoolean("isPrint")){
JSONObject json = JSON.parseObject(js);
if(json.containsKey("isPrint")&&json.getBooleanValue("isPrint")){
return;
}
Map<String,Float> groupAverage=new HashMap<>();
@@ -128,7 +129,7 @@ public class QQSetu extends Model {
}
private void printSetu(long group) {
JSONObject jt = JSONObject.parseObject(RedisTools.get(group+"setu", db_user));
JSONObject jt = JSON.parseObject(RedisTools.get(group+"setu", db_user));
String id = jt.getString("id");
float average = 0;
float max = 0;
@@ -169,7 +170,7 @@ public class QQSetu extends Model {
if (st == null) {
json = new JSONObject();
} else {
json = JSONObject.parseObject(st);
json = JSON.parseObject(st);
}
if (!json.containsKey(id)) {
JSONObject item;
@@ -190,7 +191,6 @@ public class QQSetu extends Model {
}
@Override
public void onMessage(Long qq, MessageEvent event, boolean isGroup){
System.out.println("qq = " + qq + ", event = " + event.getMessage().contentToString() + ", isGroup = " + isGroup);
if(!isGroup){
return;
}
@@ -220,9 +220,9 @@ public class QQSetu extends Model {
}
@Override
public void onTime(String time) {
super.onTime(time);
if("23:59".equals(time)){
public void onTime(Long qq,String time) {
super.onTime(qq,time);
if("23:59:00".equals(time)){
printTodaySetu();
}
}
@@ -236,4 +236,9 @@ public class QQSetu extends Model {
public String[] getUsePowers() {
return new String[0];
}
@Override
public String getModelName() {
return "涩图评分";
}
}

View File

@@ -1,14 +1,18 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSON;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.DownloadInterface;
import com.yutou.qqbot.interfaces.ObjectInterface;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.lang.annotation.Annotation;
@@ -18,10 +22,12 @@ import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
public class AppTools {
@@ -47,7 +53,7 @@ public class AppTools {
printWriter.close();
return writer.toString();
}
public static void exec(String exec, ObjectInterface objectInterface, boolean isOutQQBot, boolean isInput) {
public static String exec(String exec, ObjectInterface objectInterface, boolean isOutQQBot, boolean isInput) {
try {
Process process;
if (AppTools.isRuntimeSystemOfWindow()) {
@@ -65,39 +71,41 @@ public class AppTools {
}
);
}
String ret;
if (isInput) {
processOut(process.getInputStream(), objectInterface, isOutQQBot);
processOut(process.getErrorStream());
ret=processOut(process.getInputStream(), objectInterface, isOutQQBot);
processOut(process.getErrorStream(),null,isOutQQBot);
} else {
processOut(process.getErrorStream(), objectInterface, isOutQQBot);
processOut(process.getInputStream());
ret=processOut(process.getErrorStream(), objectInterface, isOutQQBot);
processOut(process.getInputStream(),null,isOutQQBot);
}
process.destroy();
return ret;
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static boolean isRuntimeSystemOfWindow() {
return System.getProperty("os.name").contains("Windows");
}
public static List<Class> scanClass(String classPath, Class<? extends Annotation> annotation) {
List<Class> classList = new ArrayList<>();
public static List<Class<?>> scanClass(String classPath, Class<? extends Annotation> annotation) {
List<Class<?>> classList = new ArrayList<>();
if (ObjectUtils.isEmpty(classPath)) {
return classList;
}
ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
TypeFilter includeFilter = (metadataReader, metadataReaderFactory) -> true;
provider.addIncludeFilter(includeFilter);
Set<BeanDefinition> beanDefinitionSet = new HashSet<>();
// 指定扫描的包名
Set<BeanDefinition> candidateComponents = provider.findCandidateComponents(classPath);
beanDefinitionSet.addAll(candidateComponents);
Set<BeanDefinition> beanDefinitionSet = new HashSet<>(candidateComponents);
beanDefinitionSet.forEach(beanDefinition -> {
try {
Class clazz = Class.forName(beanDefinition.getBeanClassName());
Class<?> clazz = Class.forName(beanDefinition.getBeanClassName());
if (!ObjectUtils.isEmpty(annotation)) {
if (!ObjectUtils.isEmpty(AnnotationUtils.getAnnotation(clazz, annotation))) {
@@ -118,7 +126,7 @@ public class AppTools {
public static void processOut(InputStream inputStream) {
processOut(inputStream,null,true);
}
public static void processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot){
public static String processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot){
String tmp;
StringBuilder str = new StringBuilder();
try {
@@ -138,6 +146,7 @@ public class AppTools {
if(isOutQQBot) {
QQBotManager.getInstance().sendMessage(str.toString());
}
return str.toString();
}
public static void sendServer(String title, String msg) {
try {
@@ -181,4 +190,50 @@ public class AppTools {
e.printStackTrace();
}
}
/**
* 保存上传的文件
*
* @param path 路径
* @param file 文件
* @return
* @throws Exception
*/
public static String createFile(String path, MultipartFile file, String newFileName) throws Exception {
String savePath = new File("").getAbsolutePath() + File.separator + "html" + File.separator + path;
File servicePath = new File(savePath);
if (!servicePath.exists()) {
servicePath.mkdirs();
}
String fileName = file.getOriginalFilename();
if (newFileName != null) {
fileName = newFileName;
}
File saveFile = new File(savePath + "/" + fileName);
if (saveFile.exists()) {
if (!saveFile.delete()) {
saveFile = new File(savePath + "/" + fileName.replace(".", "_" + new Date().getTime() + "."));
}
}
file.transferTo(saveFile);
System.out.println("上传文件保存路径:" + saveFile.getAbsolutePath());
return saveFile.getAbsolutePath();
}
public static Date timeToDate(String date,String time){
String form;
if(StringUtils.isEmpty(time)){
form="yyyy-MM-dd";
}else{
form="yyyy-MM-dd HH:mm:ss";
}
try {
return new SimpleDateFormat(form).parse(date+" "+time);
} catch (ParseException e) {
return null;
}
}
public static String getMD5(String str){
return DigestUtils.md5Hex(str);
}
}

View File

@@ -1,6 +1,11 @@
package com.yutou.qqbot.utlis;
import com.yutou.qqbot.Annotations.UseModel;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.QQNumberManager;
import com.yutou.qqbot.models.Model;
import net.mamoe.mirai.Bot;
import net.mamoe.mirai.contact.Group;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@@ -14,28 +19,41 @@ import java.util.TimerTask;
public class ApplicationInit implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
Model.classList.addAll(AppTools.scanClass("com.yutou.qqbot.models", UseModel.class));
new Timer().schedule(new TimerTask() {
private String oldTime = "";
@Override
public void run() {
try {
String time = new SimpleDateFormat("HH:mm").format(new Date());
String time = new SimpleDateFormat("HH:mm:ss").format(new Date());
if (time.equals(oldTime)) {
return;
}
oldTime=time;
BaiduGPTManager.getManager().clear();
oldTime = time;
for (Class<?> model : Model.classList) {
try {
Model useModel= (Model) model.getDeclaredConstructor().newInstance();
useModel.onTime(time);
} catch (Exception e) {
e.printStackTrace();
}
new Thread(() -> {
try {
Bot bot = QQBotManager.getInstance().getBot();
if (bot == null) {
return;
}
Model useModel = (Model) model.getDeclaredConstructor().newInstance();
for (Group group : bot.getGroups()) {
if (QQNumberManager.getManager().isUseModel(group.getId(), model)) {
useModel.onTime(group.getId(), time);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}catch (Exception e){
} catch (Exception e) {
e.printStackTrace();
}
}
},0, 35 * 1000);
}, 0, 300);
}
}

View File

@@ -0,0 +1,88 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.baidu.Message;
import com.yutou.qqbot.data.baidu.ResponseMessage;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BaiduGPTManager {
private static int MAX_MESSAGE = 5;
private static BaiduGPTManager manager;
private static final String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions";
//4.0
//private static final String url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro";
private static final String AppID = "36668599";
private static final String ApiKey = "eyHo6K2ILBm7i378701Az1eT";
private static final String SecretKey = "U4vXt8AOTM9FgB0Omft5IOh6vwhzoDgZ";
private final Map<String, List<Message>> msgMap;
private BaiduGPTManager() {
msgMap = new HashMap<>();
}
public static BaiduGPTManager getManager() {
if (manager == null) {
manager = new BaiduGPTManager();
}
return manager;
}
public int setMaxMessageCount(int count) {
MAX_MESSAGE = count;
return MAX_MESSAGE;
}
public void clear() {
msgMap.clear();
}
private String getToken() {
String _url = String.format("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"
, ApiKey
, SecretKey
);
String get = HttpTools.get(_url);
JSONObject response = JSONObject.parseObject(get);
return response.getString("access_token");
}
public ResponseMessage sendMessage(String user, String message) {
List<Message> messages = msgMap.getOrDefault(user, new ArrayList<>());
if (messages.size() > MAX_MESSAGE * 2) {
messages.remove(0);
messages.remove(1);
}
messages.add(Message.create(message));
JSONObject json = new JSONObject();
json.put("messages", messages);
System.out.println("json = " + json);
Map<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json");
map.put("Content-Length", String.valueOf(json.toJSONString().getBytes(StandardCharsets.UTF_8).length));
String post = HttpTools.http_post(url + "?access_token=" + getToken()
, json.toJSONString().getBytes(StandardCharsets.UTF_8),0,map);
System.out.println("post = " + post);
if (StringUtils.isEmpty(post)) {
clear();
return sendMessage(user, message);
}
ResponseMessage response = JSONObject.parseObject(post, ResponseMessage.class);
messages.add(Message.create(response.getResult(), true));
msgMap.put(user, messages);
System.out.println("\n\n");
return response;
}
public static void main(String[] args) throws Exception {
ResponseMessage message = BaiduGPTManager.getManager().sendMessage("test", "2023年创业什么赚钱?");
System.out.println(message.getResult());
}
}

View File

@@ -1,10 +1,13 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.models.Model;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@@ -12,8 +15,8 @@ import java.util.*;
public class BangumiTools {
private static final String url = "https://api.bgm.tv/";
private static final String toDayBangumi = url + "calendar";
private static final String BangumiInfo = url + "/subject/%s?responseGroup=large";
private static final String SearchBangumi = url + "/search/subject/%s?responseGroup=large";
private static final String BangumiInfo = url + "subject/%s?responseGroup=large";
private static final String SearchBangumi = url + "search/subject/%s?responseGroup=large&type=2";
/**
* 获取番剧列表
@@ -23,7 +26,7 @@ public class BangumiTools {
*/
public static JSONObject getBangumi(int day) {
String str = HttpTools.get(toDayBangumi);
JSONArray main = JSONArray.parseArray(str);
JSONArray main = JSON.parseArray(str);
if (day == -1) {
JSONObject json = new JSONObject();
json.put("bangumi", main);
@@ -58,7 +61,7 @@ public class BangumiTools {
*/
public static JSONObject getBangumiInfo(int id) {
String str = HttpTools.get(String.format(BangumiInfo, id + ""));
return JSONObject.parseObject(str);
return JSON.parseObject(str);
}
public static JSONArray getPeople(int id) {
@@ -114,8 +117,8 @@ public class BangumiTools {
* @return 详细信息
*/
public static JSONObject search(String key) {
String str = HttpTools.get(String.format(SearchBangumi, key));
return JSONObject.parseObject(str);
String str = HttpTools.get(String.format(SearchBangumi, URLEncoder.encode(key, StandardCharsets.UTF_8)));
return JSON.parseObject(str);
}
/**
@@ -314,7 +317,6 @@ public class BangumiTools {
RedisTools.set("toDayBangumi", builder.toString());
return builder.toString();
} else {
System.out.println("error ");
return RedisTools.get("toDayBangumi");
}
}
@@ -329,46 +331,11 @@ public class BangumiTools {
List<String> bangumiList = new ArrayList<>();
JSONObject main = search(key);
if (main.getInteger("results") > 0) {
StringBuilder builder = new StringBuilder();
List<JSONObject> list = main.getJSONArray("list").toJavaList(JSONObject.class);
JSONArray list = main.getJSONArray("list");
Collections.reverse(list);
for (Object items : list) {
JSONObject item = (JSONObject) items;
builder = new StringBuilder();
builder.append("标题:").append(item.getString("name_cn")).append("\n");
builder.append("日文标题:").append(item.getString("name")).append("\n");
String type;
switch (item.getInteger("type")) {
case 1:
type = "书籍";
break;
case 2:
type = "动画";
break;
case 3:
type = "音乐";
break;
case 4:
type = "游戏";
break;
case 6:
type = "真人剧(Real)";
break;
default:
type = item.getInteger("type") + "";
}
builder.append("类型:").append(type).append("\n");
builder.append("id:").append(item.getInteger("id")).append("\n");
if (item.containsKey("rating")) {
builder.append("Bangumi评分:").append(item.getJSONObject("rating").getFloat("score")).append("\n");
}
builder.append("首播时间:").append(item.getString("air_date")).append("\n");
builder.append("每周 ").append(item.getInteger("air_weekday")).append(" 放送").append("\n");
builder.append("放送集数:").append(item.getInteger("eps")).append("\n");
builder.append("Bangumi地址:").append(item.getString("url")).append("\n");
builder.append("介绍:").append(item.getString("summary")).append("\n");
builder.append("\n").append("\n");
bangumiList.add(builder.toString());
for (Object _items : list) {
JSONObject items= (JSONObject) _items;
bangumiList.addAll(reportBangumiInfo(items.getInteger("id")));
}
return bangumiList;
} else {
@@ -377,75 +344,8 @@ public class BangumiTools {
}
}
public static void saveInfoToJellyfin(String name) {
JSONObject json = search(name);
JSONArray array = json.getJSONArray("list");
int id = 0;
StringBuilder bangumiName = new StringBuilder();
for (Object o : array) {
JSONObject _item = (JSONObject) o;
bangumiName.append(_item.getString("name_cn"))
.append(":")
.append(Model.QQGroupCommands.QQ_BANGUMI_INFO)
.append(_item.getString("id"))
.append("\n");
if (_item.getString("name_cn").equals(name)) {
id = _item.getInteger("id");
break;
}
}
if (id == 0) {
QQBotManager.getInstance().sendMessage("没有与《" + name + "》完全匹配的信息,请填写。 \n" + bangumiName.toString());
return;
}
json = getBangumiInfo(id);
}
public static void main(String[] args) {
/* JSONObject json = search("小林家的龙女仆S");
System.out.println(json);
json = getBangumiInfo(274234);
System.err.println("------------");
System.out.println(json);*/
byte[] user=new byte[] {
78, 106, 73, 49, 79, 122, 65, 51, 89, 71,
65, 117, 78, 106, 78, 109, 78, 122, 99, 55,
89, 109, 85, 61 };
byte[] password=new byte[] {
89, 87, 66, 108, 79, 109, 90, 110, 78, 106,
65, 117, 79, 109, 74, 109, 78, 122, 65, 120,
79, 50, 89, 61 };
user=Base64.getDecoder().decode(user);
password=Base64.getDecoder().decode(password);
String showUser=new String(a(user));
String showPassword=new String(a(password));
System.out.println("user = "+showUser);
System.out.println("pass = "+showPassword);
String[] t1=showUser.split("-");
int t11=Integer.parseInt(t1[0],16);
int t12=Integer.parseInt(t1[1],16);
System.out.println("t11 = " + t11);
System.out.println("t12 = " + t12);
System.out.println((t11-t12));
int index=0;
for (int i = 0; i <= 13; i++) {
String t=i+"";
if(t.contains("1")){
index++;
System.err.println(t);
}
}
System.out.println(index);
System.out.println(15);
}
public static byte[] a(byte[] tmp){
byte[] data=tmp.clone();
for (byte i = 0; i < data.length; i++) {
data[i]= (byte) (data[i]^3);
}
return data;
System.out.println(BangumiTools.reportToDayBangumi());
}
}

View File

@@ -0,0 +1,82 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.bilibili.BiliBiliUtils;
import java.nio.charset.StandardCharsets;
import java.util.TreeMap;
public class BiliBiliWbiSign {
private static final byte[] MIXIN_KEY_ENC_TAB = {
46, 47, 18, 2, 53, 8, 23, 32, 15, 50, 10, 31, 58, 3, 45, 35, 27, 43, 5, 49, 33, 9, 42,
19, 29, 28, 14, 39, 12, 38, 41, 13, 37, 48, 7, 16, 24, 55, 40, 61, 26, 17, 0, 1, 60,
51, 30, 4, 22, 25, 54, 21, 56, 59, 6, 63, 57, 62, 11, 36, 20, 34, 44, 52
};
private static String rawWbiKey;
public static TreeMap<String, String> getWbiSign(TreeMap<String, String> body) {
if (rawWbiKey == null) {
updateRawWbiKey();
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return getWbiSign(body);
}
body.put("wts", String.valueOf(System.currentTimeMillis() / 1000));
String params = HttpTools.toUrlParams(body);
System.out.println("params = " + params);
body.put("w_rid", AppTools.getMD5(params + genMixinKey(rawWbiKey)));
return body;
}
public static TreeMap<String, String> getWbiSign(JSONObject json) {
TreeMap<String, String> body=new TreeMap<>();
for (String key : json.keySet()) {
body.put(key, json.getString(key));
}
return getWbiSign(body);
}
private static String genMixinKey(String rawWbiKey) {
byte[] rawBytes = rawWbiKey.getBytes(StandardCharsets.UTF_8);
byte[] mixinKey = new byte[32];
for (int i = 0; i < 32; i++) {
mixinKey[i] = rawBytes[MIXIN_KEY_ENC_TAB[i]];
}
return new String(mixinKey);
}
public static void updateRawWbiKey() {
JSONObject loginInfo = new BiliBiliUtils(QQBotManager.defQQ).getLoginInfo();
if (loginInfo.getInteger("code") == -1) {
rawWbiKey = null;
return;
}
JSONObject wbi = loginInfo.getJSONObject("data").getJSONObject("wbi_img");
String imgKey = wbi.getString("img_url");
String subKey = wbi.getString("sub_url");
imgKey = imgKey.substring(imgKey.lastIndexOf("/") + 1).replace(".png", "");
subKey = subKey.substring(subKey.lastIndexOf("/") + 1).replace(".png", "");
rawWbiKey = imgKey + subKey;
System.out.println(rawWbiKey);
}
public static void main(String[] args) throws Exception {
//System.out.println(genMixinKey("7cd084941338484aae1ad9425b84077c4932caff0ff746eab6f01bf08b70ac45"));
rawWbiKey = "7cd084941338484aae1ad9425b84077c4932caff0ff746eab6f01bf08b70ac45";
TreeMap<String, String> json = new TreeMap<>();
json.put("bvid", "BV1L94y1H7CV");
json.put("cid", "1335073288");
json.put("up_mid", "297242063");
json.put("web_location", "333.788");
//updateRawWbiKey();
TreeMap<String, String> sign = getWbiSign(json);
System.out.println(sign);
//https://api.bilibili.com/x/web-interface/view/conclusion/get?bvid=BV1L94y1H7CV&cid=1335073288&up_mid=297242063&web_location=333.788&w_rid=a5d90f60ac6b6b6fc9d49be3ba3fee53&wts=1705394671
//updateRawWbiKey();
}
}

View File

@@ -1,6 +1,7 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import java.io.*;
@@ -11,6 +12,7 @@ public class ConfigTools {
public static final String CONFIG = "config.json";
public static final String DATA = "data.json";
public static final String SQLITE = "sqlite.json";
public static final String BiliBili = "bilibili.cookie";
static {
try {
@@ -43,9 +45,10 @@ public class ConfigTools {
String src = readFile(file);
if (src != null) {
try {
JSONObject json = JSONObject.parseObject(src);
JSONObject json = JSONObject.parseObject(src,JSONObject.class);
return json.getObject(key, t);
} catch (Exception e) {
e.printStackTrace();
}
}
@@ -79,7 +82,7 @@ public class ConfigTools {
if (src == null) {
src = "{}";
}
JSONObject json = JSONObject.parseObject(src);
JSONObject json = JSON.parseObject(src);
json.put(key, data);
saveFile(file, json.toJSONString());
return false;
@@ -104,7 +107,7 @@ public class ConfigTools {
String tmp;
StringBuilder str = new StringBuilder();
while ((tmp = reader.readLine()) != null) {
str.append(tmp);
str.append(tmp).append("\n");
}
reader.close();
return str.toString();

View File

@@ -0,0 +1,22 @@
package com.yutou.qqbot.utlis;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
//设置允许跨域的路径
registry.addMapping("/**")
//设置允许跨域请求的域名
.allowedOriginPatterns("*")
//是否允许证书 不再默认开启
.allowCredentials(true)
//设置允许的方法
.allowedMethods("*")
//跨域允许时间
.maxAge(3600);
}
}

View File

@@ -0,0 +1,68 @@
package com.yutou.qqbot.utlis;
import net.mamoe.mirai.utils.BotConfiguration;
import java.lang.reflect.Field;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class FixProtocolVersion {
public static void fix(){
try {
Class<?> MiraiProtocolInternal = Class.forName("net.mamoe.mirai.internal.utils.MiraiProtocolInternal");
Field field = MiraiProtocolInternal.getFields()[0];
Object companion = field.get(Object.class);
EnumMap<BotConfiguration.MiraiProtocol, Object> protocols = (EnumMap<BotConfiguration.MiraiProtocol, Object>)companion.getClass().getMethod("getProtocols$mirai_core").invoke(companion);
Object pad = protocols.get(BotConfiguration.MiraiProtocol.ANDROID_PAD);
/*
* apkId: String,
id: Long,
ver: String,
sdkVer: String,
miscBitMap: Int,
subSigMap: Int,
mainSigMap: Int,
sign: String,
buildTime: Long,
ssoVersion: Int,
canDoQRCodeLogin: Boolean = false,
* */
Class<?> padClass = pad.getClass();
Map<String, Object> padData = new HashMap<String, Object>(){{
put("id", 537152242);
put("ver", "8.9.35.10440");
put("sdkVer", "6.0.0.2535");
put("buildTime", 1676531414L);
}};
for (Field f : padClass.getFields()) {
f.setAccessible(true);
if(padData.containsKey(f.getName())){
f.set(pad, padData.get(f.getName()));
}
f.setAccessible(false);
}
Object phone = protocols.get(BotConfiguration.MiraiProtocol.ANDROID_PHONE);
Map<String, Object> phoneData = new HashMap<String, Object>(){{
put("id", 537153294);
put("ver", "8.9.35.10440");
put("sdkVer", "6.0.0.2535");
put("buildTime", 1676531414L);
}};
for (Field f : padClass.getFields()) {
f.setAccessible(true);
if(padData.containsKey(f.getName())){
f.set(phone, phoneData.get(f.getName()));
}
f.setAccessible(false);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

View File

@@ -1,13 +1,14 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.interfaces.DownloadInterface;
import org.jetbrains.annotations.NotNull;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@@ -16,36 +17,22 @@ public class HttpTools {
private static final int HttpRequestIndex = 3;
public static String get(String url) {
return https_get(url, null);
return http_get(url, null, false);
}
public static String post(final String url, final byte[] body) {
return http_post(url, body, 0, null);
}
public static File syncDownload(final String url, final String saveName) {
return new HttpTools().http_syncDownload(url, saveName);
public static File syncDownload(final String url, final String saveName, boolean isProxy) {
return new HttpTools().http_syncDownload(url, saveName, isProxy);
}
public static String https_get(String url, Map<String, String> header) {
try {
URLConnection connection;
connection = new URL(url).openConnection();
connection.setRequestProperty("User-Agent", getExtUa());
if (header != null) {
for (String key : header.keySet()) {
connection.addRequestProperty(key, header.get(key));
}
}
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder str = new StringBuilder();
String tmp;
while ((tmp = reader.readLine()) != null) {
str.append(tmp);
}
reader.close();
return str.toString();
HttpsURLConnection connection;
connection = (HttpsURLConnection) new URL(url).openConnection();
return urlConnection(header, connection);
} catch (Exception e) {
System.err.println("error url = " + url);
e.printStackTrace();
@@ -53,6 +40,47 @@ public class HttpTools {
return null;
}
public static String http_get(String url, Map<String, String> header, boolean isProxy) {
try {
HttpURLConnection connection;
Proxy proxy = null;
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
if (proxy == null) {
connection = (HttpURLConnection) new URL(url).openConnection();
} else {
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
}
return urlConnection(header, connection);
} catch (Exception e) {
System.err.println("error url = " + url);
e.printStackTrace();
}
return null;
}
@NotNull
private static String urlConnection(Map<String, String> header, HttpURLConnection connection) throws IOException {
connection.setRequestProperty("User-Agent", getExtUa());
if (header != null) {
for (String key : header.keySet()) {
connection.addRequestProperty(key, header.get(key));
}
}
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder str = new StringBuilder();
String tmp;
while ((tmp = reader.readLine()) != null) {
str.append(tmp);
str.append("\n");
}
reader.close();
return str.toString();
}
public static String http_post(String url, byte[] body, int index, Map<String, String> headers) {
String tmp;
StringBuilder str = new StringBuilder();
@@ -67,17 +95,19 @@ public class HttpTools {
connection.setDoOutput(true);
connection.setDoInput(true);
connection.addRequestProperty("User-Agent", getExtUa());
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(10 * 1000);
// connection.setConnectTimeout(5 * 1000);
// connection.setReadTimeout(10 * 1000);
//connection.addRequestProperty("Connection", "keep-alive");
//connection.addRequestProperty("User-Agent", getExtUa());
//connection.addRequestProperty("content-type", "application/json");
connection.addRequestProperty("charset", "UTF-8");
OutputStream outputStream = connection.getOutputStream();
//System.out.println(new String(body));
outputStream.write(body);
outputStream.flush();
outputStream.close();
if (body != null) {
OutputStream outputStream = connection.getOutputStream();
//System.out.println(new String(body));
outputStream.write(body);
outputStream.flush();
outputStream.close();
}
connection.connect();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((tmp = reader.readLine()) != null) {
@@ -89,10 +119,10 @@ public class HttpTools {
reader.close();
return finalStr;
} catch (Exception e) {
e.printStackTrace();
if (index < HttpRequestIndex) {
return http_post(url, body, index + 1, headers);
} else {
e.printStackTrace();
return null;
}
}
@@ -102,20 +132,17 @@ public class HttpTools {
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36";
}
private static String getKuKuUA() {
return "/KUKU_APP(Android/#/cn.kuku.sdk/ttsdk17228/29401/A-2.9.4.01.KUSDK/868139039134314/fcddf839c8c135fa/F4:60:E2:AB:25:1A/460019406520644/+8618569400341/#/9/Redmi 6 Pro/xiaomi/1736/76fda4d6-cd6b-485f-987b-8d347b007f24/#/KUKU/Native/92972ea9651fbd2e)";
}
public String toUrlParams(JSONObject json) {
public static String toUrlParams(JSONObject json) {
StringBuilder string = new StringBuilder();
Set<String> keys = json.keySet();
for (String key : keys) {
try {
string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), "UTF-8"));
string.append("&").append(key).append("=").append(URLEncoder.encode(json.getString(key), StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
try {
string.append("&").append(URLEncoder.encode(key, "UTF-8")).append("=");
string.append("&").append(URLEncoder.encode(key, StandardCharsets.UTF_8)).append("=");
// string += "&" + key + "=";
} catch (Exception e1) {
string.append("&").append(key).append("=");
@@ -127,48 +154,74 @@ public class HttpTools {
return string.toString();
}
public static void main(String[] args) {
JSONObject json = new JSONObject();
json.put("pid", "102");
json.put("gid", "100584");
json.put("gameKey", "0gha58u1c9FjZkeAsEmYIzTvp");
json.put("access_token", "659c-S1gV0DwMXdYjPDlSrSLNYOvA8qUoCSvmdFEHvZugKgNX4Z2BCwF18A7W2gRdG7WiWfKsbZgF6YssZHhaozksI9RBn2QQFTXzmAHtbMd4ginEEtwdKmPCM4JbJGg1ollqoNE0PcGENpa4F3e7EdSOa_JFyE6XyUQN1iurJU3F8MZfLlTIcTR9USYoHX15vsAkCht_0mrapZblkeY1_8HFrmK8rlenbZLxccy7PrMz5eZ9uPPDJL5OYiEahyrtLENB8SVmlGofJfQw8wUjN8_XVZSfLMujdwz24");
String url = "http://192.168.1.156:9020/Faxing/reg?" +
"&tpyeCode=dimai" +
"&regParamJson=" + json.toJSONString();
/* ExecutorService service= Executors.newCachedThreadPool();
for (int i = 0; i < 3000; i++) {
service.submit(new Runnable() {
@Override
public void run() {
get(url);
}
});
}*/
Log.i(url);
//String str=get(url);
public static String toUrlParams(Map<String, String> map) {
StringBuilder builder = new StringBuilder();
for (String key : map.keySet()) {
builder.append(key).append("=").append(map.get(key)).append("&");
}
return builder.substring(0, builder.length() - 1);
}
private static String donwloadPath = "tmp" + File.separator;
public static Map<String, String> getUrlParams(String url) {
Map<String, String> map = new HashMap<>();
if (url.contains("?")) {
String param = url.split("\\?")[1];
String[] params = param.split("&");
for (String par : params) {
map.put(par.split("=")[0], par.split("=")[1]);
}
}
return map;
}
public static void main(String[] args) {
File file = syncDownload("https://lain.bgm.tv/pic/cover/l/6c/2a/302128_qQIjG.jpg", "12345.jpg", false);
System.out.println("file.length() = " + file.length());
}
public static String downloadPath = "tmp" + File.separator;
public synchronized static void download(final String url, final String saveName, final DownloadInterface downloadInterface) {
download(url, saveName, false, downloadInterface);
}
public synchronized static void download(final String url, final String saveName, boolean isProxy, final DownloadInterface downloadInterface) {
new Thread(new Runnable() {
@Override
public void run() {
File jar = null;
try {
File savePath = new File(donwloadPath);
File savePath = new File(downloadPath);
Proxy proxy = null;
if (!savePath.exists()) {
savePath.mkdirs();
}
Log.i("DOWNLOAD", "下载文件:" + url + " 保存文件:" + saveName);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.addRequestProperty("User-Agent", getExtUa());
// Log.i(TAG,"获取到网络请求:"+connection.getResponseCode());
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
URLConnection connection;
if (url.startsWith("https:")) {
if (isProxy) {
connection = (HttpsURLConnection) new URL(url).openConnection(proxy);
} else {
connection = (HttpsURLConnection) new URL(url).openConnection();
}
} else {
if (isProxy) {
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
} else {
connection = (HttpURLConnection) new URL(url).openConnection();
}
}
connection.addRequestProperty("User-Agent", getExtUa());
// Log.i("获取到网络请求:"+((HttpsURLConnection)connection).getResponseCode());
InputStream inputStream = connection.getInputStream();
jar = new File(donwloadPath + saveName + "_tmp.tmp");
long fileSize = inputStream.available();
jar = new File(downloadPath + saveName + "_tmp.tmp 文件大小:" + fileSize);
jar.createNewFile();
Log.i("DOWNLOAD", "临时保存文件:" + jar.getAbsolutePath());
OutputStream outputStream = new FileOutputStream(jar);
@@ -185,14 +238,18 @@ public class HttpTools {
}
outputStream.close();
inputStream.close();
File oldJar = new File(donwloadPath + saveName);
File oldJar = new File(downloadPath + saveName);
if (oldJar.exists()) {
oldJar.delete();
}
jar.renameTo(oldJar);
Log.i("DOWNLOAD", "实际保存:" + oldJar.getAbsolutePath() + " " + oldJar.getName());
if (downloadInterface != null) {
downloadInterface.onDownload(oldJar);
if (oldJar.exists()) {
downloadInterface.onDownload(oldJar);
} else {
downloadInterface.onError(new FileNotFoundException("文件下载失败, 网络大小 = " + fileSize + " 本地大小 = " + oldJar.length()));
}
}
@@ -209,29 +266,38 @@ public class HttpTools {
}).start();
}
public synchronized File http_syncDownload(final String url, final String saveName) {
public synchronized File http_syncDownload(final String url, final String saveName, boolean isProxy) {
if (StringUtils.isEmpty(url)) {
return null;
}
File jar = null;
try {
File savePath = new File(donwloadPath);
File savePath = new File(downloadPath);
if (!savePath.exists()) {
savePath.mkdirs();
}
Proxy proxy = null;
if (isProxy) {
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
}
Log.i("DOWNLOAD", "下载文件:" + url + " 保存文件:" + saveName);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
HttpURLConnection connection;
if (proxy == null) {
connection = (HttpURLConnection) new URL(url).openConnection();
} else {
connection = (HttpURLConnection) new URL(url).openConnection(proxy);
}
connection.addRequestProperty("User-Agent", getExtUa());
// Log.i(TAG,"获取到网络请求:"+connection.getResponseCode());
connection.addRequestProperty("Content-type", "image/jpeg");
InputStream inputStream = connection.getInputStream();
jar = new File(donwloadPath + saveName + "_tmp.tmp");
jar = new File(downloadPath + saveName + "_tmp.tmp");
jar.createNewFile();
Log.i("DOWNLOAD", "临时保存文件:" + jar.getAbsolutePath());
OutputStream outputStream = new FileOutputStream(jar);
byte[] bytes = new byte[1024];
double size = connection.getContentLength();
double downSize = 0;
int len;
while ((len = inputStream.read(bytes)) > 0) {
@@ -240,7 +306,7 @@ public class HttpTools {
}
outputStream.close();
inputStream.close();
File oldJar = new File(donwloadPath + saveName);
File oldJar = new File(downloadPath + saveName);
if (oldJar.exists()) {
oldJar.delete();
}
@@ -257,4 +323,25 @@ public class HttpTools {
return null;
}
}
public static String getLocalMacAddress() {
try {
InetAddress address = InetAddress.getLocalHost();
byte[] bytes = NetworkInterface.getByInetAddress(address).getHardwareAddress();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (i != 0) {
builder.append(":");
}
String tmp = Integer.toHexString(bytes[i] & 0xFF);
builder.append(tmp.length() == 1 ? 0 + tmp : tmp);
}
return builder.toString();
} catch (UnknownHostException | java.net.SocketException e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -30,7 +30,7 @@ public class IdeaTools {
}
public static List<String> getIdeaList(String url) {
File file = HttpTools.syncDownload(url, "idea.zip");
File file = HttpTools.syncDownload(url, "idea.zip",false);
List<String> list = new ArrayList<>();
try {
ZipFile zip = new ZipFile(file, Charset.forName("gbk"));

View File

@@ -0,0 +1,441 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.data.jianr.AndroidDevice;
import com.yutou.qqbot.data.jianr.JianRScriptData;
import com.yutou.qqbot.data.jianr.JianRScriptV2Data;
import com.yutou.qqbot.data.jianr.Vector2D;
import com.yutou.qqbot.interfaces.ObjectInterface;
import lombok.SneakyThrows;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;
import java.util.TreeMap;
public class JianRTaskManager {
public static final String Redis_Script = "jianrScript_Script";
public static final String Redis_Device = "jianrScript_Devices";
public static final String Redis_RunIndex = "jianrScript_RunIndex";
private static JianRTaskManager instance;
private JianRScriptV2Data task;
private AndroidDevice device;
private boolean running = false;
private boolean runStatus = false;
private int runIndex = 0;
private String log;
private int modelId;
public static JianRTaskManager getInstance() {
if (instance == null) {
instance = new JianRTaskManager();
}
return instance;
}
private JianRTaskManager() {
}
public void setModelId(int modelId) {
this.modelId = modelId;
}
public void setTask(JianRScriptV2Data data, AndroidDevice device) {
task = data;
this.device = device;
runIndex = 0;
String s = RedisTools.getHashMap(Redis_RunIndex, data.getTitle());
if (s != null) {
runIndex = Integer.parseInt(s);
}
}
public void start() {
if (running || runStatus) {
return;
}
runStatus = true;
running = true;
new Thread(new Runnable() {
@Override
public void run() {
while (running) {
try {
log("已运行: " + runIndex + "");
for (JianRScriptV2Data.Script script : task.getScript()) {
if (!running) {
log("任务已停止");
break;
}
log(script.getTitle());
JianRTaskManager.this.run(device, modelId, script);
/* try {
Thread.sleep((long) getRandom(0, script.getRandomNextWaitTime() * 1000, script.getNextWaitTime() * 1000));
} catch (Exception e) {
throw new RuntimeException(e);
}*/
while (true){
if(waitGame(device,modelId,script)){
System.out.println("next");
break;
}
}
}
runIndex++;
RedisTools.setHashMap(Redis_RunIndex, task.getTitle(), runIndex + "");
log("循环一次任务");
} catch (Exception e) {
running = false;
}
}
runStatus = false;
log("终止任务");
}
}).start();
}
Vector2D nowVector2D = null;
private void run(AndroidDevice device, int modelId, JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP:
nowVector2D = getMapCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.attack:
nowVector2D = getAttackCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.dialog_go:
nowVector2D = getDialogCoords(device, gameDisplay, false);
break;
case JianRScriptV2Data.ScriptModel.dialog_back:
nowVector2D = getDialogCoords(device, gameDisplay, true);
break;
case JianRScriptV2Data.ScriptModel.dialog_assets:
nowVector2D = getDialogAssetsCoords(device, gameDisplay);
break;
case JianRScriptV2Data.ScriptModel.none:
nowVector2D = getNoneCoords(device, gameDisplay);
break;
default:
if (script.getActivity().startsWith(JianRScriptV2Data.ScriptModel.formationType)) {
nowVector2D = getNextFormationCoords(device, gameDisplay, Integer.parseInt(script.getActivity().split("#")[1]));
}
}
if (nowVector2D != null) {
adb(device, nowVector2D);
}
}
private boolean isAttack=false;
private boolean isFormation=false;
private boolean waitGame(AndroidDevice device, int modelId,JianRScriptV2Data.Script script) {
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
String ocr;
switch (script.getActivity()) {
case JianRScriptV2Data.ScriptModel.MAP:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始出征")){
return true;
}
break;
case JianRScriptV2Data.ScriptModel.attack:
ocr=screen(gameDisplay,getAttackCoords(device,gameDisplay));
System.out.println("ocr = " + ocr);
if(ocr.trim().contains("开始战斗")){
isAttack=true;
}
if(isAttack){
run(device, modelId, script);
isFormation= true;
}
if(isFormation){
ocr=screen(gameDisplay,getDialogCoords(device,gameDisplay,true));
String tmp=screen(gameDisplay,getContinueCoords(device,gameDisplay));
if(ocr.contains("放弃")||tmp.contains("继续")){
}
}
break;
case JianRScriptV2Data.ScriptModel.dialog_go:
break;
case JianRScriptV2Data.ScriptModel.dialog_back:
break;
case JianRScriptV2Data.ScriptModel.dialog_assets:
break;
case JianRScriptV2Data.ScriptModel.none:
break;
default:
}
return false;
}
public void stop() {
task = null;
running = false;
}
public int getRunIndex() {
return runIndex;
}
public boolean isRunning() {
return runStatus;
}
/**
* 老版本脚本执行命令
*/
@Deprecated
private void adbTap(String deviceId, JianRScriptData.Script script) {
String exec = String.format("adb -s %s shell input tap %f %f",
deviceId,
getRandom(script.getRx(), script.getX()),
getRandom(script.getRy(), script.getY()));
AppTools.exec(exec
, null, false, false);
}
private void log(String log) {
this.log = String.format("[%s]%s",
AppTools.getToDayNowTimeToString(),
log);
System.out.println(this.log);
}
private float getRandom(int origin, int randomNum, int x) {
Random random = new Random();
return x + random.nextFloat(origin, randomNum);
}
private float getRandom(int randomNum, int x) {
return getRandom(-randomNum, randomNum, x);
}
public String getTaskName() {
if (task != null) {
return task.getTitle();
}
return "没有任务在运行";
}
public String getLog() {
return log;
}
public void connect(String deviceId) {
String exec = String.format("adb connect %s",
deviceId);
System.out.println(exec);
AppTools.exec(exec
, null, false, false);
}
/**
* 获取出击坐标
*
* @param device 设备信息
* @return 坐标
*/
private Vector2D getAttackCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.9161 + gameDisplay.getStart().getY());
return v2d;
}
private Vector2D getContinueCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.8725 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.9 + gameDisplay.getStart().getY());
return v2d;
}
/**
* 获取地图点击坐标
*
* @param device 设备信息
* @return 坐标
*/
private Vector2D getMapCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.5 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.5 + gameDisplay.getStart().getY());
return v2d;
}
/**
* 获取阵型点击坐标
*
* @param device 设备信息
* @param type 阵型。0~4
* @return 坐标
*/
private Vector2D getNextFormationCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay, int type) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.75 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.24835 + gameDisplay.getStart().getY());
for (int i = 0; i < type; i++) {
v2d.setY(v2d.getY() + (gameDisplay.getHeight() * 0.1461));
}
return v2d;
}
public Vector2D getBottomLeft(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getEnd().getY());
return v2d;
}
/**
* 获取出击坐标
*
* @param device 设备信息
* @return 坐标
*/
private Vector2D getDialogCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay, boolean isBack) {
Vector2D v2d = new Vector2D();
v2d.setY(gameDisplay.getHeight() * 0.61722 + gameDisplay.getStart().getY());
if (isBack) {
v2d.setX(gameDisplay.getWidth() * 0.6575 + gameDisplay.getStart().getX());
} else {
v2d.setX(gameDisplay.getWidth() * 0.344642857143 + gameDisplay.getStart().getX());
}
return v2d;
}
/**
* 获取资源对抗确定坐标
*
* @return 坐标
*/
private Vector2D getDialogAssetsCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.5 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.5433 + gameDisplay.getStart().getY());
return v2d;
}
private Vector2D getNoneCoords(AndroidDevice device, AndroidDevice.GameDisplay gameDisplay) {
Vector2D v2d = new Vector2D();
v2d.setX(gameDisplay.getWidth() * 0.1 + gameDisplay.getStart().getX());
v2d.setY(gameDisplay.getHeight() * 0.1 + gameDisplay.getStart().getY());
return v2d;
}
@SneakyThrows
public static void main(String[] args) {
JSONObject json = new JSONObject();
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
if (data == null || deviceJsonString == null) {
json.put("code", -1);
json.put("msg", "没有找到该方案或设备错误,请配置");
} else {
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
JianRTaskManager manager = JianRTaskManager.getInstance();
if (manager.isRunning()) {
manager.stop();
}
for (int i = 0; i < androidDevice.getDeviceDisplay().size(); i++) {
if (androidDevice.getDeviceDisplay().get(i).getTitle().equals("全屏模式")) {
manager.setModelId(i);
break;
}
}
manager.setTask(script, androidDevice);
manager.start();
}
}
public File cut(Vector2D v2d) {
try {
System.out.println("v2d = " + v2d);
int x = (int) v2d.getNotRandomX() - 150;
int y = (int) v2d.getNotRandomY() - 50;
if (y + 150 > device.getAndroidDevice().getHeight()) {
y -= 100;
}
if (y < 0) {
y = 0;
}
if (x + 450 > device.getAndroidDevice().getWidth()) {
x -= 300;
}
if (x < 0) {
x = 0;
}
System.out.println("x = " + x);
System.out.println("y = " + y);
BufferedImage bufImage = ImageIO.read(new File("1.png"));
BufferedImage bufferedImage = bufImage.getSubimage(x, y, 400, 100);
File imgCutFile = new File("tmp.png");
ImageIO.write(bufferedImage, "PNG", imgCutFile);
return imgCutFile;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String ocr(File file) {
String exec = "\"C:\\Program Files\\Tesseract-OCR\\tesseract.exe\" " + file.getAbsolutePath() + " - -l chi_sim --psm 6";
return AppTools.exec(exec, null, false, true).replace("\r", "").replace("\n", "");
}
private String screen(AndroidDevice.GameDisplay gameDisplay, Vector2D v2d) {
AppTools.exec("adb exec-out screencap -p > 1.png", null, false, false);
gameDisplay.setEnabledRandom(false);
File file = cut(v2d);
return ocr(file);
}
public void test() {
String data = RedisTools.getHashMap(JianRTaskManager.Redis_Script, "7-1刷A点");
String deviceJsonString = RedisTools.getHashMap(JianRTaskManager.Redis_Device, "三星平板");
JianRScriptV2Data script = JSON.parseObject(data, JianRScriptV2Data.class);
AndroidDevice androidDevice = JSON.parseObject(deviceJsonString, AndroidDevice.class);
this.device = androidDevice;
this.task = script;
this.modelId = 1;
System.out.println("download image");
AppTools.exec("adb exec-out screencap -p > 1.png", new ObjectInterface() {
@Override
public void out(String data) {
super.out(data);
AndroidDevice dev = device;
AndroidDevice.GameDisplay gameDisplay = device.getDeviceDisplay().get(modelId);
gameDisplay.setEnabledRandom(false);
Vector2D v2d;
v2d = getBottomLeft(device, gameDisplay);
v2d = getNextFormationCoords(device, gameDisplay, 4);
v2d = getAttackCoords(device, gameDisplay);
v2d = getDialogCoords(device, device.getDeviceDisplay().get(modelId), true);
v2d = getContinueCoords(device, gameDisplay);
File file = cut(v2d);
String ocr = ocr(file);
System.out.println(ocr.trim());
}
}, false, true);
}
private void adb(AndroidDevice device, Vector2D v2d) {
String exec = String.format("adb -s %s shell input tap %f %f",
device.getDeviceId(),
v2d.getX(),
v2d.getY());
System.out.println(exec);
AppTools.exec(exec
, null, false, false);
}
}

View File

@@ -6,7 +6,7 @@ public class Log {
}
public static void i(Object log) {
if (ConfigTools.load(ConfigTools.CONFIG, "logout",boolean.class,false)) {
if (ConfigTools.load(ConfigTools.CONFIG, "logout", boolean.class, false)) {
System.out.printf("[%s]%s%n",
AppTools.getToDayNowTimeToString(),
log
@@ -14,11 +14,20 @@ public class Log {
}
}
public static void e(String tag,Exception e){
public static void e(String tag, Exception e) {
System.err.printf("[%s]%s - %s%n",
AppTools.getToDayNowTimeToString(),
tag,
AppTools.getExceptionString(e)
);
);
}
public static void i(Object tag, Object log) {
if (tag instanceof String) {
i("[" + tag + "]" + log);
} else {
i(tag.getClass().getSimpleName(), log);
}
}
}

View File

@@ -0,0 +1,25 @@
package com.yutou.qqbot.utlis;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternTools {
private static List<String> exec(String regex, String input){
List<String> list=new ArrayList<>();
Pattern pattern=Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while(matcher.find()){
list.add(matcher.group());
}
return list;
}
public static List<String> pattern(String text,String start,String end){
return exec(String.format(".(?<=%s).*(?=%s)", start,end), text);
}
public static List<String> getQQ(String text){
return exec("(@[0-9]\\d*)",text);
}
}

View File

@@ -0,0 +1,58 @@
package com.yutou.qqbot.utlis;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class QRCodeUtils {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
public static File createQRCode(String codeName,String value){
try {
String imageType = "jpg";// 图片类型
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
Map<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = multiFormatWriter.encode(value, BarcodeFormat.QR_CODE, 400, 400, hints);
if(!new File("QRCode").exists()){
boolean mkdirs = new File(("QRCode")).mkdirs();
System.out.println("create QRCode dir is = "+mkdirs);
}
File file1 = new File("QRCode"+File.separator+ codeName + "." + imageType);
writeToFile(bitMatrix, imageType, file1);
return file1;
} catch (WriterException | IOException e) {
e.printStackTrace();
}
return null;
}
private static BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
private static void writeToFile(BitMatrix matrix, String format, File file) throws IOException {
BufferedImage image = toBufferedImage(matrix);
if (!ImageIO.write(image, format, file)) {
throw new IOException("Could not write an image of format " + format + " to " + file);
}
}
}

View File

@@ -0,0 +1,136 @@
package com.yutou.qqbot.utlis;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSAUtils {
/**
* 加密算法RSA
*/
public static final String KEY_ALGORITHM = "RSA";
/**
* 签名算法
*/
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
/**
* 获取公钥的key
*/
private static final String PUBLIC_KEY = "RSAPublicKey";
/**
* 获取私钥的key
*/
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* RSA 密钥位数
*/
private static final int KEY_SIZE = 1024;
/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;
/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = MAX_DECRYPT_BLOCK - 11;
private static Map<Integer,String> keyMap=new HashMap<>();
/**
* 随机生成密钥对
* @throws NoSuchAlgorithmException
*/
public static void getKeyPair() throws Exception {
//KeyPairGenerator类用于生成公钥和密钥对基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器密钥大小为96-1024位
keyPairGen.initialize(1024,new SecureRandom());
//生成一个密钥对保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();//得到私钥
PublicKey publicKey = keyPair.getPublic();//得到公钥
//得到公钥字符串
String publicKeyString=new String(Base64.encodeBase64(publicKey.getEncoded()));
//得到私钥字符串
String privateKeyString=new String(Base64.encodeBase64(privateKey.getEncoded()));
//将公钥和私钥保存到Map
keyMap.put(0,publicKeyString);//0表示公钥
keyMap.put(1,privateKeyString);//1表示私钥
}
/**
* <p>
* 公钥加密
* </p>
*
* @param str 源数据
* @param publicKey 公钥(BASE64编码)
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String str, String publicKey) throws Exception {
publicKey=publicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");
byte[] data=Base64.decodeBase64(str);
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
return new String(Base64.encodeBase64(encryptedData));
}
/**
* RSA私钥解密
*
* @param str
* 加密字符串
* @param privateKey
* 私钥
* @return 铭文
* @throws Exception
* 解密过程中的异常信息
*/
public static String decrypt(String str,String privateKey) throws Exception {
//Base64解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes("UTF-8"));
//Base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
PrivateKey priKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE,priKey);
String outStr=new String(cipher.doFinal(inputByte));
return outStr;
}
}

View File

@@ -1,6 +1,7 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.yutou.qqbot.QQBotManager;
import com.yutou.qqbot.interfaces.ObjectInterface;
import redis.clients.jedis.Jedis;
@@ -12,6 +13,8 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -22,7 +25,7 @@ public class RedisTools {
private static String host;
private static int port;
public static int TOKEN_TIMEOUT_DEFAULT = 360;
public final static int DATABASES_ALI_OSS=4;
public final static int DATABASES_ALI_OSS = 4;
private RedisTools() {
@@ -45,7 +48,7 @@ public class RedisTools {
Jedis jedis = getRedis();
jedis.select(dbIndex);
String ret = jedis.set(key, value);
Log.i("Redis set =" + ret,"key = "+key+" value = "+value);
//Log.i("Redis set =" + ret,"key = "+key+" value = "+value);
jedis.close();
} catch (Exception e) {
// TODO: handle exception
@@ -55,13 +58,13 @@ public class RedisTools {
return true;
}
public static boolean set (String key,String value, long timeout,int db){
public static boolean set(String key, String value, long timeout, int db) {
try {
if (isNotInstallRedis) {
return false;
}
Jedis jedis = getRedis();
if(db>-1){
if (db > -1) {
jedis.select(db);
}
if (timeout == -1) {
@@ -79,11 +82,11 @@ public class RedisTools {
}
public static boolean set(Object key, String value) {
return set(QQBOT_USER, key+"", value);
return set(QQBOT_USER, key + "", value);
}
public static boolean set(String key, String value, long timeout) {
return set(key, value, timeout,QQBOT_USER);
return set(key, value, timeout, QQBOT_USER);
}
public static String get(String key, int dbIndex) {
@@ -103,11 +106,19 @@ public class RedisTools {
}
public static String get(Object key) {
return get(key+"", QQBOT_USER);
return get(key + "", QQBOT_USER);
}
public static String get(Object key, String defValue) {
String ret = get(key);
if (StringUtils.isEmpty(ret)) {
return defValue;
}
return ret;
}
public static boolean remove(String key) {
return remove(key,QQBOT_USER);
return remove(key, QQBOT_USER);
}
public static void removeLoginState(String uid) {
@@ -127,27 +138,113 @@ public class RedisTools {
jedis.close();
return tmp;
}
public static boolean exists(Object key,String value){
return exists(QQBOT_USER,key,value);
public static boolean exists(Object key, String value) {
return exists(QQBOT_USER, key, value);
}
public static boolean exists(int db,Object key, String value) {
public static boolean exists(int db, Object key, String value) {
if (isNotInstallRedis) {
return false;
}
Jedis jedis = getRedis();
jedis.select(db);
boolean flag=false;
if(value==null){
flag= jedis.exists(key+"");
}else {
flag = value.equals(jedis.get(key+""));
boolean flag = false;
if (value == null) {
flag = jedis.exists(key + "");
} else {
flag = value.equals(jedis.get(key + ""));
}
jedis.close();
return flag;
}
public static long list_add(String listName, String... value) {
Jedis jedis = getRedis();
jedis.select(QQBOT_USER);
long index = jedis.sadd(listName, value);
jedis.close();
return index;
}
public static Set<String> list_get(String listName) {
Set<String> set;
try {
Jedis jedis = getRedis();
jedis.select(QQBOT_USER);
set = jedis.smembers(listName);
jedis.close();
if (set == null) {
set = new HashSet<>();
}
} catch (Exception e) {
e.printStackTrace();
set = new HashSet<>();
}
return set;
}
public static boolean list_remove(String listName, String... value) {
long index = 0;
try {
Jedis jedis = getRedis();
jedis.select(QQBOT_USER);
index = jedis.srem(listName, value);
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
return index != 0;
}
public static boolean list_isExist(String listName, String value) {
boolean flag = false;
try {
Jedis jedis = getRedis();
flag = jedis.sismember(listName, value);
jedis.close();
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
public static String getHashMap(String hashKey, String key) {
Jedis jedis = getRedis();
return jedis.hget(hashKey, key);
}
public static Map<String, String> getHashMap(String hashKey) {
return getRedis().hgetAll(hashKey);
}
public static boolean setHashMap(String hashKey, String key, String value) {
Jedis jedis = getRedis();
long l = jedis.hset(hashKey, key, value);
jedis.close();
return l == 0;
}
public static boolean removeHashMap(String hashKey, String key) {
Jedis jedis = getRedis();
long l = jedis.hdel(hashKey, key);
jedis.close();
return l > 0;
}
public static boolean removeHashMap(String hashKey) {
Jedis jedis = getRedis();
long del = jedis.del(hashKey);
return del > 0;
}
public static Jedis getRedis() {
return new Jedis(host, port);
Jedis jedis = new Jedis(host, port);
jedis.select(QQBOT_USER);
return jedis;
}
public static boolean remove(String key, int index) {
@@ -156,13 +253,9 @@ public class RedisTools {
}
Jedis jedis = getRedis();
jedis.select(index);
Long i = jedis.del(key);
long i = jedis.del(key);
jedis.close();
if (i > 0) {
return true;
} else {
return false;
}
return i > 0;
}
private static class PropertyUtil {
@@ -190,7 +283,7 @@ public class RedisTools {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxIdle(0);
poolConfig.setMaxWaitMillis(1000);
JedisPool pool = new JedisPool(poolConfig, host);
JedisPool pool = new JedisPool();
return pool.getResource();
}
@@ -243,7 +336,7 @@ public class RedisTools {
system("cmd", message);
break;
case "msg":
AppTools.sendServer("来自服务姬的通知~",message);
AppTools.sendServer("来自服务姬的通知~", message);
break;
}
}
@@ -280,21 +373,22 @@ public class RedisTools {
}
public static void bot(String value) {
switch (value) {
case "getip":
JSONObject json = JSONObject.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
JSONObject json = JSON.parseObject(HttpTools.get("https://api.asilu.com/ip/"));
String ip = json.getString("ip");
QQBotManager.getInstance().sendMessage("服务器IP:\n" + ip);
break;
}
}
}
public static void processOut(InputStream inputStream) {
processOut(inputStream,null,true);
processOut(inputStream, null, true);
}
public static void processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot){
public static void processOut(InputStream inputStream, ObjectInterface objectInterface, boolean isOutQQBot) {
String tmp;
StringBuilder str = new StringBuilder();
try {
@@ -307,14 +401,15 @@ public class RedisTools {
} catch (Exception e) {
e.printStackTrace();
}
if(objectInterface!=null){
if (objectInterface != null) {
objectInterface.out(str.toString());
}
// Log.i("cmd > " + str);
if(isOutQQBot) {
// Log.i("cmd > " + str);
if (isOutQQBot) {
QQBotManager.getInstance().sendMessage(str.toString());
}
}
public static void main(String[] args) {
RedisTools.pullMsg("msg", "abc");
}

View File

@@ -1,7 +1,21 @@
package com.yutou.qqbot.utlis;
import java.io.File;
public class StringUtils {
public static boolean isEmpty(String str){
return str == null || str.trim().length() == 0;
}
public static String toSaveFileName(String str){
return str.replace("\\","_")
.replace("/","_")
.replace(":","_")
.replace("*","_")
.replace("?","_")
.replace("\"","_")
.replace("<","_")
.replace(">","_")
.replace("|","_")
.replace("$(File.separator)", File.separator);
}
}

View File

@@ -1,34 +1,46 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yutou.qqbot.models.Animal.TurnipProphet;
import org.openqa.selenium.*;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import java.io.File;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class WebClient {
private static WebClient client;
private WebDriver driver;
private static WebClient instance;
public static WebClient getInstance() {
if (client == null) {
client = new WebClient();
if (instance == null || instance.driver == null) {
instance = new WebClient();
}
return client;
return instance;
}
public WebDriver getWebDriver() {
return new ChromeDriver(getOptions());
if (driver == null) {
driver = new ChromeDriver(getOptions());
}
return driver;
}
public void quit() {
driver.quit();
driver = null;
}
private WebClient() {
//System.setProperty("webdriver.http.factory", "jdk-http-client");
System.setProperty("webdriver.chrome.driver",
ConfigTools.load(ConfigTools.CONFIG, "chrome", String.class));
// System.setProperty("webdriver.chrome.whitelistedIps", "");
// java.util.logging.Logger.getLogger("org.openqa.selenium").setLevel(Level.OFF);
}
@@ -41,16 +53,23 @@ public class WebClient {
boolean containsDate = json.containsKey("expirationDate");
long t = 0;
if (containsDate) {
t = Long.parseLong(json.getString("expirationDate").replace(".", "")) / 1000;
String _time = json.getString("expirationDate");
if (_time.contains(".")) {
_time = _time.split("\\.")[0];
}
t = Long.parseLong(_time);
} else {
t = (System.currentTimeMillis()) / 1000;
}
t *= 1000;
Cookie cookie = new Cookie(json.getString("name"),
json.getString("value"),
json.getString("domain"),
json.getString("path"),
containsDate ? new Date(t) : new Date(),
json.getBoolean("secure"),
json.getBoolean("httpOnly")
new Date(t),
json.getBooleanValue("secure"),
json.getBooleanValue("httpOnly")
);
list.add(cookie);
@@ -58,16 +77,40 @@ public class WebClient {
return list;
}
public static ChromeOptions getOptions() {
static boolean headless = false;
public void setHeadless(boolean headless) {
WebClient.headless = headless;
}
public ChromeOptions getOptions() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-gpu");
// options.addArguments("blink-settings=imagesEnabled=false");
options.addArguments("--headless");
options.addArguments("--remote-allow-origins=*");
// options.addArguments("--disable-gpu");
// options.addArguments("blink-settings=imagesEnabled=false");
String headless = RedisTools.get("chromedrive_headless");
String proxy = RedisTools.get("chromedrive_proxy");
if ("true".equals(proxy)) {
String url = "http://127.0.0.1:7890";
Proxy _proxy = new Proxy();
_proxy.setHttpProxy(url);
_proxy.setSslProxy(url);
options.setCapability(CapabilityType.PROXY, _proxy);
}
if ("true".equals(headless) || WebClient.headless) {
options.addArguments("--headless");
}
options.addArguments("--no-sandbox");
// options.addArguments("--incognito");
options.addArguments("--disable-plugins");
options.addArguments("--lang=zh-CN");
return options;
}
public static void main(String[] args) {
WebDriver driver1 = getInstance().getWebDriver();
driver1.get("https://www.tsdm39.net/forum.php");
}
}

View File

@@ -0,0 +1,49 @@
package com.yutou.qqbot.utlis;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.codec.digest.DigestUtils;
import java.nio.charset.StandardCharsets;
public class XiaoMiRouter {
private final static String key = "a2ffa5c9be07488bbb04a3a47d3c5f6a";
private static String token = null;
public static void setNotToken() {
token = null;
}
public static String getToken() {
if (token != null) {
return token;
}
String nonce = nonceCreat();
String oldPwd = DigestUtils.sha1Hex(nonce + DigestUtils.sha1Hex("34864394" + key));
JSONObject json = new JSONObject();
json.put("username", "admin");
json.put("password", oldPwd);
json.put("logtype", 2);
json.put("nonce", nonce);
json = JSON.parseObject(HttpTools.http_post("http://192.168.31.1/cgi-bin/luci/api/xqsystem/login", HttpTools.toUrlParams(json).getBytes(StandardCharsets.UTF_8), 1, null));
if (json.getInteger("code") == 0) {
token = json.getString("token");
return token;
}
return null;
}
public static String getDeviceListUrl() {
return "http://192.168.31.1/cgi-bin/luci/;stok=" + getToken() + "/api/misystem/devicelist";
}
private static String nonceCreat() {
return String.format("%s_%s_%s_%s", 0, HttpTools.getLocalMacAddress(), (int) (System.currentTimeMillis() / 1000), (int) (Math.random() * 10000));
}
public static void main(String[] args) {
String url = XiaoMiRouter.getDeviceListUrl();
JSONObject json = JSON.parseObject(HttpTools.get(url));
System.out.println("json = " + json);
}
}

View File

@@ -1 +1,3 @@
server.port=8002
server.port=8002
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB

View File

@@ -1 +1,3 @@
server.port=8002
server.port=8002
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB

View File

@@ -0,0 +1,549 @@
syntax = "proto3";
package com.yutou.qqbot.bilibili;
option java_package= "com.yutou.qqbot.bilibili";
option java_outer_classname="VideoDanMu";
//弹幕
service DM {
// 获取分段弹幕
rpc DmSegMobile (DmSegMobileReq) returns (DmSegMobileReply);
// 客户端弹幕元数据 字幕、分段、防挡蒙版等
rpc DmView (DmViewReq) returns (DmViewReply);
// 修改弹幕配置
rpc DmPlayerConfig (DmPlayerConfigReq) returns (Response);
// ott弹幕列表
rpc DmSegOtt(DmSegOttReq) returns(DmSegOttReply);
// SDK弹幕列表
rpc DmSegSDK(DmSegSDKReq) returns(DmSegSDKReply);
//
rpc DmExpoReport (DmExpoReportReq) returns (DmExpoReportRes);
}
//
message BuzzwordConfig {
//
repeated BuzzwordShowConfig keywords = 1;
}
//
message BuzzwordShowConfig {
//
string name = 1;
//
string schema = 2;
//
int32 source = 3;
//
int64 id = 4;
//
int64 buzzword_id = 5;
//
int32 schema_type = 6;
}
// 互动弹幕条目信息
message CommandDm {
// 弹幕id
int64 id = 1;
// 对象视频cid
int64 oid = 2;
// 发送者mid
string mid = 3;
// 互动弹幕指令
string command = 4;
// 互动弹幕正文
string content = 5;
// 出现时间
int32 progress = 6;
// 创建时间
string ctime = 7;
// 发布时间
string mtime = 8;
// 扩展json数据
string extra = 9;
// 弹幕id str类型
string idStr = 10;
}
// 弹幕属性位值
enum DMAttrBit {
DMAttrBitProtect = 0; // 保护弹幕
DMAttrBitFromLive = 1; // 直播弹幕
DMAttrHighLike = 2; // 高赞弹幕
}
// 弹幕ai云屏蔽列表
message DanmakuAIFlag {
// 弹幕ai云屏蔽条目
repeated DanmakuFlag dm_flags = 1;
}
// 弹幕条目
message DanmakuElem {
// 弹幕dmid
int64 id = 1;
// 弹幕出现位置(单位ms)
int32 progress = 2;
// 弹幕类型
int32 mode = 3;
// 弹幕字号
int32 fontsize = 4;
// 弹幕颜色
uint32 color = 5;
// 发送着mid hash
string midHash = 6;
// 弹幕正文
string content = 7;
// 发送时间
int64 ctime = 8;
// 权重 区间:[1,10]
int32 weight = 9;
// 动作
string action = 10;
// 弹幕池
int32 pool = 11;
// 弹幕dmid str
string idStr = 12;
// 弹幕属性位(bin求AND)
// bit0:保护 bit1:直播 bit2:高赞
int32 attr = 13;
}
// 弹幕ai云屏蔽条目
message DanmakuFlag {
int64 dmid = 1; // 弹幕dmid
uint32 flag = 2; // 评分
}
// 云屏蔽配置信息
message DanmakuFlagConfig {
// 云屏蔽等级
int32 rec_flag = 1;
// 云屏蔽文案
string rec_text = 2;
// 云屏蔽开关
int32 rec_switch = 3;
}
// 弹幕默认配置
message DanmuDefaultPlayerConfig {
bool player_danmaku_use_default_config = 1; // 是否使用推荐弹幕设置
bool player_danmaku_ai_recommended_switch = 4; // 是否开启智能云屏蔽
int32 player_danmaku_ai_recommended_level = 5; // 智能云屏蔽等级
bool player_danmaku_blocktop = 6; // 是否屏蔽顶端弹幕
bool player_danmaku_blockscroll = 7; // 是否屏蔽滚动弹幕
bool player_danmaku_blockbottom = 8; // 是否屏蔽底端弹幕
bool player_danmaku_blockcolorful = 9; // 是否屏蔽彩色弹幕
bool player_danmaku_blockrepeat = 10; // 是否屏蔽重复弹幕
bool player_danmaku_blockspecial = 11; // 是否屏蔽高级弹幕
float player_danmaku_opacity = 12; // 弹幕不透明度
float player_danmaku_scalingfactor = 13; // 弹幕缩放比例
float player_danmaku_domain = 14; // 弹幕显示区域
int32 player_danmaku_speed = 15; // 弹幕速度
bool inline_player_danmaku_switch = 16; // 是否开启弹幕
int32 player_danmaku_senior_mode_switch = 17; //
}
// 弹幕配置
message DanmuPlayerConfig {
bool player_danmaku_switch = 1; // 是否开启弹幕
bool player_danmaku_switch_save = 2; // 是否记录弹幕开关设置
bool player_danmaku_use_default_config = 3; // 是否使用推荐弹幕设置
bool player_danmaku_ai_recommended_switch = 4; // 是否开启智能云屏蔽
int32 player_danmaku_ai_recommended_level = 5; // 智能云屏蔽等级
bool player_danmaku_blocktop = 6; // 是否屏蔽顶端弹幕
bool player_danmaku_blockscroll = 7; // 是否屏蔽滚动弹幕
bool player_danmaku_blockbottom = 8; // 是否屏蔽底端弹幕
bool player_danmaku_blockcolorful = 9; // 是否屏蔽彩色弹幕
bool player_danmaku_blockrepeat = 10; // 是否屏蔽重复弹幕
bool player_danmaku_blockspecial = 11; // 是否屏蔽高级弹幕
float player_danmaku_opacity = 12; // 弹幕不透明度
float player_danmaku_scalingfactor = 13; // 弹幕缩放比例
float player_danmaku_domain = 14; // 弹幕显示区域
int32 player_danmaku_speed = 15; // 弹幕速度
bool player_danmaku_enableblocklist = 16; // 是否开启屏蔽列表
bool inline_player_danmaku_switch = 17; // 是否开启弹幕
int32 inline_player_danmaku_config = 18; //
int32 player_danmaku_ios_switch_save = 19; //
int32 player_danmaku_senior_mode_switch = 20; //
}
// 弹幕显示区域自动配置
message DanmuPlayerDynamicConfig {
// 时间
int32 progress = 1;
// 弹幕显示区域
float player_danmaku_domain = 14;
}
// 弹幕配置信息
message DanmuPlayerViewConfig {
// 弹幕默认配置
DanmuDefaultPlayerConfig danmuku_default_player_config = 1;
// 弹幕用户配置
DanmuPlayerConfig danmuku_player_config = 2;
// 弹幕显示区域自动配置列表
repeated DanmuPlayerDynamicConfig danmuku_player_dynamic_config = 3;
}
// web端用户弹幕配置
message DanmuWebPlayerConfig {
bool dm_switch = 1; // 是否开启弹幕
bool ai_switch = 2; // 是否开启智能云屏蔽
int32 ai_level = 3; // 智能云屏蔽等级
bool blocktop = 4; // 是否屏蔽顶端弹幕
bool blockscroll = 5; // 是否屏蔽滚动弹幕
bool blockbottom = 6; // 是否屏蔽底端弹幕
bool blockcolor = 7; // 是否屏蔽彩色弹幕
bool blockspecial = 8; // 是否屏蔽重复弹幕
bool preventshade = 9; //
bool dmask = 10; //
float opacity = 11; //
int32 dmarea = 12; //
float speedplus = 13; //
float fontsize = 14; // 弹幕字号
bool screensync = 15; //
bool speedsync = 16; //
string fontfamily = 17; //
bool bold = 18; // 是否使用加粗
int32 fontborder = 19; //
string draw_type = 20; // 弹幕渲染类型
int32 senior_mode_switch = 21; //
}
//
message DmExpoReportReq {
//
string session_id = 1;
//
int64 oid = 2;
//
string spmid = 4;
}
//
message DmExpoReportRes {
}
// 修改弹幕配置-请求
message DmPlayerConfigReq {
int64 ts = 1; //
PlayerDanmakuSwitch switch = 2; // 是否开启弹幕
PlayerDanmakuSwitchSave switch_save = 3; // 是否记录弹幕开关设置
PlayerDanmakuUseDefaultConfig use_default_config = 4; // 是否使用推荐弹幕设置
PlayerDanmakuAiRecommendedSwitch ai_recommended_switch = 5; // 是否开启智能云屏蔽
PlayerDanmakuAiRecommendedLevel ai_recommended_level = 6; // 智能云屏蔽等级
PlayerDanmakuBlocktop blocktop = 7; // 是否屏蔽顶端弹幕
PlayerDanmakuBlockscroll blockscroll = 8; // 是否屏蔽滚动弹幕
PlayerDanmakuBlockbottom blockbottom = 9; // 是否屏蔽底端弹幕
PlayerDanmakuBlockcolorful blockcolorful = 10; // 是否屏蔽彩色弹幕
PlayerDanmakuBlockrepeat blockrepeat = 11; // 是否屏蔽重复弹幕
PlayerDanmakuBlockspecial blockspecial = 12; // 是否屏蔽高级弹幕
PlayerDanmakuOpacity opacity = 13; // 弹幕不透明度
PlayerDanmakuScalingfactor scalingfactor = 14; // 弹幕缩放比例
PlayerDanmakuDomain domain = 15; // 弹幕显示区域
PlayerDanmakuSpeed speed = 16; // 弹幕速度
PlayerDanmakuEnableblocklist enableblocklist = 17; // 是否开启屏蔽列表
InlinePlayerDanmakuSwitch inlinePlayerDanmakuSwitch = 18; // 是否开启弹幕
PlayerDanmakuSeniorModeSwitch senior_mode_switch = 19; //
}
//
message DmSegConfig {
//
int64 page_size = 1;
//
int64 total = 2;
}
// 获取弹幕-响应
message DmSegMobileReply {
// 弹幕列表
repeated DanmakuElem elems = 1;
// 是否已关闭弹幕
// 0:未关闭 1:已关闭
int32 state = 2;
// 弹幕云屏蔽ai评分值
DanmakuAIFlag ai_flag = 3;
}
// 获取弹幕-请求
message DmSegMobileReq {
// 稿件avid/漫画epid
int64 pid = 1;
// 视频cid/漫画cid
int64 oid = 2;
// 弹幕类型
// 1:视频 2:漫画
int32 type = 3;
// 分段(6min)
int64 segment_index = 4;
// 是否青少年模式
int32 teenagers_mode = 5;
}
// ott弹幕列表-响应
message DmSegOttReply {
// 是否已关闭弹幕
// 0:未关闭 1:已关闭
bool closed = 1;
// 弹幕列表
repeated DanmakuElem elems = 2;
}
// ott弹幕列表-请求
message DmSegOttReq {
// 稿件avid/漫画epid
int64 pid = 1;
// 视频cid/漫画cid
int64 oid = 2;
// 弹幕类型
// 1:视频 2:漫画
int32 type = 3;
// 分段(6min)
int64 segment_index = 4;
}
// 弹幕SDK-响应
message DmSegSDKReply {
// 是否已关闭弹幕
// 0:未关闭 1:已关闭
bool closed = 1;
// 弹幕列表
repeated DanmakuElem elems = 2;
}
// 弹幕SDK-请求
message DmSegSDKReq {
// 稿件avid/漫画epid
int64 pid = 1;
// 视频cid/漫画cid
int64 oid = 2;
// 弹幕类型
// 1:视频 2:漫画
int32 type = 3;
// 分段(6min)
int64 segment_index = 4;
}
// 客户端弹幕元数据-响应
message DmViewReply {
// 是否已关闭弹幕
// 0:未关闭 1:已关闭
bool closed = 1;
// 智能防挡弹幕蒙版信息
VideoMask mask = 2;
// 视频字幕
VideoSubtitle subtitle = 3;
// 高级弹幕专包url(bfs)
repeated string special_dms = 4;
// 云屏蔽配置信息
DanmakuFlagConfig ai_flag = 5;
// 弹幕配置信息
DanmuPlayerViewConfig player_config = 6;
// 弹幕发送框样式
int32 send_box_style = 7;
// 是否允许
bool allow = 8;
// check box 是否展示
string check_box = 9;
// check box 展示文本
string check_box_show_msg = 10;
// 展示文案
string text_placeholder = 11;
// 弹幕输入框文案
string input_placeholder = 12;
// 用户举报弹幕 cid维度屏蔽的正则规则
repeated string report_filter_content = 13;
//
ExpoReport expo_report = 14;
//
BuzzwordConfig buzzword_config = 15;
//
repeated Expressions expressions = 16;
}
// 客户端弹幕元数据-请求
message DmViewReq {
// 稿件avid/漫画epid
int64 pid = 1;
// 视频cid/漫画cid
int64 oid = 2;
// 弹幕类型
// 1:视频 2:漫画
int32 type = 3;
// 页面spm
string spmid = 4;
// 是否冷启
int32 is_hard_boot = 5;
}
// web端弹幕元数据-响应
message DmWebViewReply {
// 是否已关闭弹幕
// 0:未关闭 1:已关闭
int32 state = 1;
//
string text = 2;
//
string text_side = 3;
// 分段弹幕配置
DmSegConfig dm_sge = 4;
// 云屏蔽配置信息
DanmakuFlagConfig flag = 5;
// 高级弹幕专包url(bfs)
repeated string special_dms = 6;
// check box 是否展示
bool check_box = 7;
// 弹幕数
int64 count = 8;
// 互动弹幕
repeated CommandDm commandDms = 9;
// 用户弹幕配置
DanmuWebPlayerConfig player_config = 10;
// 用户举报弹幕 cid维度屏蔽
repeated string report_filter_content = 11;
//
repeated Expressions expressions = 12;
}
//
message ExpoReport {
//
bool should_report_at_end = 1;
}
//
message Expression {
//
repeated string keyword = 1;
//
string url = 2;
//
repeated Period period = 3;
}
//
message Expressions {
//
repeated Expression data = 1;
}
//
message Period {
//
int64 start = 1;
//
int64 end = 2;
}
// 是否开启弹幕
message InlinePlayerDanmakuSwitch {bool value = 1;}
// 智能云屏蔽等级
message PlayerDanmakuAiRecommendedLevel {bool value = 1;}
// 是否开启智能云屏蔽
message PlayerDanmakuAiRecommendedSwitch {bool value = 1;}
// 是否屏蔽底端弹幕
message PlayerDanmakuBlockbottom {bool value = 1;}
// 是否屏蔽彩色弹幕
message PlayerDanmakuBlockcolorful {bool value = 1;}
// 是否屏蔽重复弹幕
message PlayerDanmakuBlockrepeat {bool value = 1;}
// 是否屏蔽滚动弹幕
message PlayerDanmakuBlockscroll {bool value = 1;}
// 是否屏蔽高级弹幕
message PlayerDanmakuBlockspecial {bool value = 1;}
// 是否屏蔽顶端弹幕
message PlayerDanmakuBlocktop {bool value = 1;}
// 弹幕显示区域
message PlayerDanmakuDomain {float value = 1;}
// 是否开启屏蔽列表
message PlayerDanmakuEnableblocklist {bool value = 1;}
// 弹幕不透明度
message PlayerDanmakuOpacity {float value = 1;}
// 弹幕缩放比例
message PlayerDanmakuScalingfactor {float value = 1;}
//
message PlayerDanmakuSeniorModeSwitch {int32 value = 1;}
// 弹幕速度
message PlayerDanmakuSpeed {int32 value = 1;}
// 是否开启弹幕
message PlayerDanmakuSwitch {bool value = 1;bool canIgnore = 2;}
// 是否记录弹幕开关设置
message PlayerDanmakuSwitchSave {bool value = 1;}
// 是否使用推荐弹幕设置
message PlayerDanmakuUseDefaultConfig {bool value = 1;}
// 修改弹幕配置-响应
message Response {
//
int32 code = 1;
//
string message = 2;
}
// 单个字幕信息
message SubtitleItem {
// 字幕id
int64 id = 1;
// 字幕id str
string id_str = 2;
// 字幕语言代码
string lan = 3;
// 字幕语言
string lan_doc = 4;
// 字幕文件url
string subtitle_url = 5;
// 字幕作者信息
UserInfo author = 6;
// 字幕类型
SubtitleType type = 7;
}
enum SubtitleType {
CC = 0; // CC字幕
AI = 1; // AI生成字幕
}
// 字幕作者信息
message UserInfo {
// 用户mid
int64 mid = 1;
// 用户昵称
string name = 2;
// 用户性别
string sex = 3;
// 用户头像url
string face = 4;
// 用户签名
string sign = 5;
// 用户等级
int32 rank = 6;
}
// 智能防挡弹幕蒙版信息
message VideoMask {
// 视频cid
int64 cid = 1;
// 平台
// 0:web端 1:客户端
int32 plat = 2;
// 帧率
int32 fps = 3;
// 间隔时间
int64 time = 4;
// 蒙版url
string mask_url = 5;
}
// 视频字幕信息
message VideoSubtitle {
// 视频原语言代码
string lan = 1;
// 视频原语言
string lanDoc = 2;
// 视频字幕列表
repeated SubtitleItem subtitles = 3;
}

View File

@@ -8,6 +8,7 @@ class QqBotApplicationTests {
@Test
void contextLoads() {
//1
}
}

81
web/bilibili.html Normal file
View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>BiliBili下载器</title>
<link rel="stylesheet" href="layui/css/layui.css">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
</head>
<body>
<div class="myDiy">
<blockquote class="layui-elem-quote">BiliBili下载器
</blockquote>
<br/><br/><br/>
<div class="layui-bg-gray layui-row layui-col-space15" id="card" style="padding: 30px;">
<form class="layui-form" action="">
<div class="layui-form-item">
<label class="layui-form-label">视频地址</label>
<div class="layui-input-block">
<input type="url" name="url" required lay-verify="required" placeholder="请输入URL" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">复选框</label>
<div class="layui-input-block">
<input type="checkbox" name="danmu" title="下载弹幕" checked>
<input type="checkbox" name="merge" title="合并合集">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
</body>
<script src="layui/layui.js"></script>
<script src="layui/jquery-3.2.1.js"></script>
<script>
layui.use('form', function(){
let form = layui.form;
//监听提交
form.on('submit(formDemo)', function(_data){
//layer.msg(JSON.stringify(data.field));
$.post("/bilibili/down.do",{data:JSON.stringify(_data.field)},function (json) {
layer.msg(json.msg)
})
return false;
});
});
</script>
<style>
.myDiy {
width: 40%;
height: 300px;
margin-top: 10px;
margin-left: 25%;
}
.button {
width: 100px;
height: 100px;
font-size: 1em;
}
</style>
</html>

287
web/jianrTask.html Normal file
View File

@@ -0,0 +1,287 @@
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>舰R脚本管理器</title>
<link rel="stylesheet" href="layui/css/layui.css">
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
</head>
<body>
<div class="myDiy">
<blockquote class="layui-elem-quote">舰R脚本管理器<span id="taskStatus"></span><br/><br/><span id="taskName">当前无任务</span><br/><br/><span id="runIndex"></span><br/><br/><span id="log"></span>
</blockquote>
<button class="layui-btn layui-btn-lg layui-btn-normal" onclick="createTask()">创建任务</button>
<button class="layui-btn layui-btn-lg layui-btn-normal" id="createDevice">选择设备
<i class="layui-icon layui-icon-down layui-font-12"></i>
</button>
<blockquote class="layui-elem-quote">
调用设备:<span id="deviceName"></span><br>
</blockquote>
<br/><br/><br/>
<div class="layui-bg-gray layui-row layui-col-space15" id="card" style="padding: 30px;">
</div>
</div>
</body>
<script src="layui/layui.js"></script>
<script src="layui/jquery-3.2.1.js"></script>
<script>
let homeUrl="";
let device;
let deviceModel=[];
function createTask() {
if(device===undefined){
layer.msg('请选择设备')
return
}
layer.prompt({
formType: 2,
value: '{\n' +
' "title":"",\n' +
' "script":[\n' +
' {\n' +
' "title":"",\n' +
' "activity":"map|attack|formationType#{0-4}|dialog_go|dialog_back|dialog_assets",\n' +
' "nextWaitTime": 0,\n' +
' "randomNextWaitTime": 0\n' +
' }\n' +
' ]\n' +
'}',
title: '创建任务',
maxlength: 99999,
area: ['800px', '350px'] //自定义文本域宽高
}, function (value, index, elem) {
$.post(homeUrl+"/jianr/task/add.do", {task: value}, function (json) {
layer.msg(json.msg)
})
layer.close(index);
});
}
function runTask(name,title) {
if(device===undefined){
layer.msg('请选择设备')
return
}
$.post(homeUrl+"/jianr/run.do", {task: name,device:device.title,modelName:title}, function (json) {
layer.msg(json.msg)
})
}
function stopTask() {
$.post(homeUrl+"/jianr/stop.do", function (json) {
layer.msg(json.msg)
})
}
function removeTask(name) {
$.post(homeUrl+"/jianr/task/remove.do", {task: name}, function (json) {
layer.msg(json.msg)
})
}
function showDevice() {
if(isSelectDevice()){
layer.msg("当前未选择设备")
}else{
layer.prompt({
formType: 2,
value: JSON.stringify(device),
title: '查看设备',
maxlength: 99999,
area: ['800px', '350px'] //自定义文本域宽高
}, function (value, index, elem) {
$.post(homeUrl+"/jianr/device/edit.do", {device: value,oldDevice:device.title}, function (json) {
layer.msg(json.msg)
})
layer.close(index);
});
}
}
function delDevice() {
}
function isSelectDevice() {
return device===undefined;
}
function getStatus() {
$.post(homeUrl+"/jianr/status.do", function (json) {
if(json.data.status){
$('#taskStatus')[0].innerHTML="运行"
$('#taskStatus').css('color','#5C962C')
$('#taskName')[0].innerHTML='执行次数: '+json.data.runIndex;
$('#runIndex')[0].innerHTML='当前正在执行: '+json.data.taskName;
$('#log')[0].innerHTML=json.data.log
}else{
$('#taskStatus')[0].innerHTML="停止"
$('#taskStatus').css('color','#FF5722')
}
setTimeout(function () {
getStatus()
},1000)
})
}
layui.use('dropdown', function(){
let dropdown = layui.dropdown
function createCard(name) {
let html = '<div class="layui-card layui-col-md3 layui-col-lg-offset1"><div class="layui-card-header">' + name
+ '</div><div class="layui-card-body">' +
'<button class="layui-btn layui-btn-radius layui-btn-normal" id="runTask_'+name+'" ><i class="layui-icon">&#xe652;</i>运行 <i class="layui-icon layui-icon-down layui-font-12"></i></button><br/><br/><button class="layui-btn layui-btn-radius layui-btn-warm" onclick="stopTask()"><i class="layui-icon">&#xe651;</i>停止</button><br/><br/><button class="layui-btn layui-btn-radius layui-btn-danger" onclick="removeTask(\'' + name + '\')"><i class="layui-icon">&#xe64d;</i>删除</button></div></div>';
$('#card').append(html)
dropdown.render({
elem: '#runTask_'+name //可绑定在任意元素中,此处以上述按钮为例
,data: deviceModel
,id: 'runTask_'+name
//菜单被点击的事件
,click: function(obj){
console.log(obj);
if(obj.title==='查看'){
$.post(homeUrl+"/jianr/task/get.do",{task:name},function (json) {
layer.prompt({
formType: 2,
value: json.data,
title: '脚本内容',
area: ['800px', '350px'] //自定义文本域宽高
}, function(value, index, elem){
layer.close(index);
});
})
}else{
runTask(name,obj.title)
}
}
});
}
$.get(homeUrl+"/jianr/task/list.do", function (json) {
json.data.forEach(function (item) {
createCard(item)
}
)
})
$.get(homeUrl+"/jianr/device/list.do",function (json) {
let devices=json.data;
devices.push({type:'-'})
devices.push({
title: '添加设备',
name:"addDevice"
,href: '#'
})
dropdown.render({
elem: '#createDevice' //可绑定在任意元素中,此处以上述按钮为例
,data: devices
,id: 'createDevice'
//菜单被点击的事件
,click: function(obj){
if(obj.name==='addDevice'){
layer.prompt({
formType: 2,
value: '{\n' +
' "deviceId":"",\n' +
' "title":"",\n' +
' "androidDevice":{\n' +
' "height":0,\n' +
' "width":0\n' +
' },\n' +
' "deviceDisplay":[\n' +
' {\n' +
' "title":"",\n' +
' "start":{\n' +
' "x":0,\n' +
' "y":0,\n' +
' "enableRandomX":false,\n' +
' "enableRandomY":false,\n' +
' "absRandomX":false,\n' +
' "absRandomY":false,\n' +
' "randomNumX":0,\n' +
' "randomNumY":0\n' +
' },\n' +
' "end":{\n' +
' "x": 0,\n' +
' "y": 0,\n' +
' "enableRandomX": false,\n' +
' "enableRandomY": false,\n' +
' "absRandomX": false,\n' +
' "absRandomY": false,\n' +
' "randomNumX": 0,\n' +
' "randomNumY": 0\n' +
' }\n' +
' }\n' +
' ]\n' +
'}',
title: '添加设备',
maxlength: 99999,
area: ['800px', '350px'] //自定义文本域宽高
}, function (value, index, elem) {
$.post(homeUrl+"/jianr/device/add.do", {device: value}, function (json) {
layer.msg(json.msg)
})
layer.close(index);
});
}else{
console.log(obj)
if(obj.data==='select'){
device=obj.device;
device.deviceDisplay.forEach(function (item){
deviceModel.push({
title:item.title
})
deviceModel.push({type: '-'})
})
deviceModel.push({
title:"查看",
})
$('#deviceName')[0].innerHTML=obj.device.title;
}else if (obj.data==='edit'){
showDevice()
}else if (obj.data==='del'){
delDevice()
}else if (obj.data==='connect'){
$.post(homeUrl+"/jianr/device/connect.do",{device:obj.device.deviceId},function (json) {
layer.msg(json.msg)
})
}
}
}
});
})
});
window.onload = function init() {
getStatus()
}
</script>
<style>
.myDiy {
width: 40%;
height: 300px;
margin-top: 10px;
margin-left: 25%;
}
.button {
width: 100px;
height: 100px;
font-size: 1em;
}
</style>
</html>

1
web/layui/css/layui.css Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-view{display:block;position:relative;margin:10px 0;padding:0;border:1px solid #eee;border-left-width:6px;background-color:#fafafa;color:#333;font-family:Courier New;font-size:13px}.layui-code-title{position:relative;padding:0 10px;height:40px;line-height:40px;border-bottom:1px solid #eee;font-size:12px}.layui-code-title>.layui-code-about{position:absolute;right:10px;top:0;color:#b7b7b7}.layui-code-about>a{padding-left:10px}.layui-code-view>.layui-code-ol,.layui-code-view>.layui-code-ul{position:relative;overflow:auto}.layui-code-view>.layui-code-ol>li{position:relative;margin-left:45px;line-height:20px;padding:0 10px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view>.layui-code-ol>li:first-child,.layui-code-view>.layui-code-ul>li:first-child{padding-top:10px}.layui-code-view>.layui-code-ol>li:last-child,.layui-code-view>.layui-code-ul>li:last-child{padding-bottom:10px}.layui-code-view>.layui-code-ul>li{position:relative;line-height:20px;padding:0 10px;list-style-type:none;*list-style-type:none;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-dark{border:1px solid #0c0c0c;border-left-color:#3f3f3f;background-color:#0c0c0c;color:#c2be9e}.layui-code-dark>.layui-code-title{border-bottom:none}.layui-code-dark>.layui-code-ol>li,.layui-code-dark>.layui-code-ul>li{background-color:#3f3f3f;border-left:none}.layui-code-dark>.layui-code-ul>li{margin-left:6px}.layui-code-demo .layui-code{visibility:visible!important;margin:-15px;border-top:none;border-right:none;border-bottom:none}.layui-code-demo .layui-tab-content{padding:15px;border-top:none}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 701 B

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