diff --git a/.github/workflows/pylint.yml-off b/.github/workflows/pylint.yml similarity index 100% rename from .github/workflows/pylint.yml-off rename to .github/workflows/pylint.yml diff --git a/.gitignore b/.gitignore index 2bffaaa..63059dd 100644 --- a/.gitignore +++ b/.gitignore @@ -138,4 +138,5 @@ dmypy.json config/*.json # push配置 -config/push.ini \ No newline at end of file +config/push.ini +.DS_Store diff --git a/README.md b/README.md index d0bd5c4..a096b7b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ * 此项目的用途 - 这是一个米游社的辅助签到项目,包含了米游币和原神以及崩坏3 + 这是一个米游社的辅助签到项目,包含了米游币、崩坏2、崩坏3、原神,后续会支持未定事件簿 ## 如何使用程序 @@ -26,12 +26,12 @@ 7. **使用[获取Cookie](#获取米游社Cookie)里面的方法来获取米游社Cookie** - 8. 将复制的Cookie粘贴到`config.json`的`"mihoyobbs_Cookies":" "`中 + 8. 将复制的Cookie粘贴到`config.json`的`"cookie":" "`中(在`account`里面) 例子 > ```json - > "mihoyobbs_Cookies": "你复制的cookie" + > "cookie": "你复制的cookie" > ``` 9. 在命令提示符(cmd)/powershell,输入`python main.py`来进行执行 @@ -46,7 +46,7 @@ 3. 打开`http://bbs.mihoyo.com/ys/`并进行登入操作 -4. 在上一步登入完成后新建标签页,打开`http://user.mihoyo.com/`并进行登入操作 (如果你不需要自动获取米游币可以忽略这个步骤,并把`bbs_Global`改为`false`即可) +4. 在上一步登入完成后新建标签页,打开`http://user.mihoyo.com/`并进行登入操作 (如果你不需要自动获取米游币可以忽略这个步骤,并把`mihoyobbs`的`enable`改为`false`即可) 5. 按下键盘上的`F12`或右键检查,打开开发者工具,点击Console @@ -60,21 +60,24 @@ 7. **此时Cookie已经复制到你的粘贴板上了** - ## 使用Docker运行 Docker的运行脚本基于Linux平台编写,暂未在Win平台测试。 将本项目Clone至本地后,请先按照上述步骤添加或修改配置文件。随后执行 -``` + +```text docker-compose up -d ``` + 启动docker容器。   容器运行成功后可用 -``` + +```text docker-compose logs -f ``` + 命令来查看程序输出。   若需要添加配置文件或修改配置文件,可直接在主机config文件夹中修改,修改的内容将实时同步在容器中。 @@ -83,7 +86,9 @@ docker-compose logs -f ## 使用云函数运行 ->以腾讯云为例 +腾讯云函数服务免费额度近期有变化,为了**避免产生费用**,建议切换到阿里云 函数计算 FC + +* 腾讯云 1. 在本地完整运行一次。 @@ -93,7 +98,7 @@ docker-compose logs -f 4. 提交方法选`本地上传文件夹`,并在下方的函数代码处上传整个项目文件夹。 -5. 执行方法填写 `index.main_handler`. +5. 执行方法填写 `index.main_handler`,多用户请填写`index.main_handler_mulit`. 6. 展开高级配置,将执行超时时间修改为 `300 秒`,其他保持默认。 @@ -101,12 +106,33 @@ docker-compose logs -f 8. 完成,enjoy it! +* 阿里云 + + 1. 在本地完整运行一次。 + 2. 打开并登录[函数计算 FC](https://fcnext.console.aliyun.com/cn-hangzhou/services)。注意左上方显示的地区,可点击切换其他地区。 + 3. 创建服务 (日志功能可能产生费用,建议关闭) + 1. 创建函数 + 2. 从零开始创建 + 1. `请求处理程序类型:处理事件请求` + 2. `请求处理程序:index.main_handler`,多用户请填写`index.main_handler_mulit` + 3. 配置触发器:触发器类型 定时触发器 异步调用。建议触发方式设为`指定时间` + 4. 点击创建 + 3. 进入函数详情 + 1. 打开函数配置 + 2. 修改 `环境信息` - `执行超时时间` 为300秒。 + 4. 测试运行 + 1. 打开 `函数详情` + 2. 点击`测试函数` + 5. 完成 + ## 使用的第三方库 requests: [github](https://github.com/psf/requests) [pypi](https://pypi.org/project/requests/) httpx: [github](https://github.com/encode/httpx) [pypi](https://pypi.org/project/httpx/) +crontab: [github](https://github.com/josiahcarlson/parse-crontab) [pypi](https://pypi.org/project/crontab/) + ## 关于使用 Github Actions 运行 本项目**不支持**也**不推荐**使用`Github Actions`来每日自动执行! @@ -115,6 +141,10 @@ httpx: [github](https://github.com/encode/httpx) [pypi](https://pypi.org/project 推荐使用 阿里云/腾讯云 的云函数来进行每日自动执行脚本。 +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/Womsxd/AutoMihoyoBBS.svg)](https://starchart.cc/Womsxd/AutoMihoyoBBS) + ## License [MIT License](https://github.com/Womsxd/AutoMihoyoBBS/blob/master/LICENSE) diff --git a/account.py b/account.py new file mode 100644 index 0000000..bd0fc57 --- /dev/null +++ b/account.py @@ -0,0 +1,42 @@ +import config +import setting +from request import http +from loghelper import log +from error import CookieError + + +def game_id2name(game_id: str) -> str: + try: + return setting.game_id2name[game_id] + except NameError: + return game_id + + +def stop_module(game_id: str) -> None: + if game_id == "bh2_cn": + config.config["games"]["cn"]["hokai2"]["auto_checkin"] = False + elif game_id == "bh3_cn": + config.config["games"]["cn"]["honkai3rd"]["auto_checkin"] = False + elif game_id == "nxx_cn": + # 未定好像没米游社签到 + pass + elif game_id == "hk4e_cn": + config.config["games"]["cn"]["genshin"]["auto_checkin"] = False + else: + raise NameError + config.save_config() + + +def get_account_list(game_id: str, headers: dict) -> list: + log.info(f"正在获取米哈游账号绑定的{game_id2name(game_id)}账号列表...") + temp_list = [] + req = http.get(setting.account_Info_url + game_id, headers=headers) + data = req.json() + if data["retcode"] != 0: + log.warning(f"获取{game_id2name(game_id)}账号列表失败!") + stop_module(game_id) + raise CookieError("BBS Cookie Error") + for i in data["data"]["list"]: + temp_list.append([i["nickname"], i["game_uid"], i["region"]]) + log.info(f"已获取到{len(temp_list)}个{game_id2name(game_id)}账号信息") + return temp_list diff --git a/config.py b/config.py index 11fd72c..0d1a799 100644 --- a/config.py +++ b/config.py @@ -2,102 +2,142 @@ import os import json from loghelper import log -# 是否启用config -enable_Config = True -# 这里的内容会自动获取 -mihoyobbs_Login_ticket = "" -mihoyobbs_Stuid = "" -mihoyobbs_Stoken = "" -# 这里是米游社的cookie -mihoyobbs_Cookies = "" -# 这个dist里面的内容和米游社有关 -mihoyobbs = { - # 全局开关,关闭之后下面的都不执行 - "bbs_Global": True, - # 讨论区签到 - "bbs_Signin": True, - # 多个讨论区签到 - "bbs_Signin_multi": True, - # 指定签到讨论区 - # 1是崩坏3 2是原神 3是崩坏2 4是未定事件簿 5是大别墅 - # 可以通过设置讨论区的id位置来设置主讨论区,[5,1]就是大别墅为主社区 - # 看帖子 点赞 分享帖子都是使用主社区获取到的列表 - "bbs_Signin_multi_list": [2, 5], - # 浏览3个帖子 - "bbs_Read_posts": True, - # 完成5次点赞 - "bbs_Like_posts": True, - # 完成后取消点赞 - "bbs_Unlike": True, - # 分享帖子 - "bbs_Share": True, +# 这个字段现在还没找好塞什么地方好,就先塞config这里了 +serverless = False + +config = { + 'enable': True, 'version': 5, + 'account': { + 'cookie': '', + 'login_ticket': '', + 'stuid': '', + 'stoken': '' + }, + 'mihoyobbs': { + 'enable': True, 'checkin': True, 'checkin_multi': True, 'checkin_multi_list': [2, 5], + 'read_posts': True, 'like_posts': True, 'un_like': True, 'share_post': True + }, + 'games': { + 'cn': { + 'enable': True, + 'genshin': {'auto_checkin': True, 'black_list': []}, + 'hokai2': {'auto_checkin': False, 'black_list': []}, + 'honkai3rd': {'auto_checkin': False, 'black_list': []}, + 'tears_of_themis': {'auto_checkin': False, 'black_list': []}, + }, + 'os': { + 'enable': False, 'cookie': '', + 'genshin': {'auto_checkin': False, 'black_list': []} + } + } } -# 原神自动签到 -genshin_Auto_sign = True -# 崩坏3自动签到 -honkai3rd_Auto_sign = True + path = os.path.dirname(os.path.realpath(__file__)) + "/config" config_Path = f"{path}/config.json" +def load_v4(data: dict): + global config + # 配置开关 + config["enable"] = data["enable_Config"] + # 账号 cookie + config["account"]["login_ticket"] = data["mihoyobbs_Login_ticket"] + config["account"]["stuid"] = data["mihoyobbs_Stuid"] + config["account"]["stoken"] = data["mihoyobbs_Stoken"] + config["account"]["cookie"] = data["mihoyobbs_Cookies"] + # bbs 相关设置(自己之前造的孽) + config["mihoyobbs"]["enable"] = data["mihoyobbs"]["bbs_Global"] + config["mihoyobbs"]["checkin"] = data["mihoyobbs"]["bbs_Signin"] + config["mihoyobbs"]["checkin_multi"] = data["mihoyobbs"]["bbs_Signin_multi"] + config["mihoyobbs"]["checkin_multi_list"] = data["mihoyobbs"]["bbs_Signin_multi_list"] + config["mihoyobbs"]["read_posts"] = data["mihoyobbs"]["bbs_Read_posts"] + config["mihoyobbs"]["like_posts"] = data["mihoyobbs"]["bbs_Like_posts"] + config["mihoyobbs"]["un_like"] = data["mihoyobbs"]["bbs_Unlike"] + config["mihoyobbs"]["share_post"] = data["mihoyobbs"]["bbs_Share"] + # 游戏相关设置 v4只支持原神和崩坏3,所以其他选项默认关闭 + config["games"]["cn"]["genshin"]["auto_checkin"] = data["genshin_Auto_sign"] + config["games"]["cn"]["honkai3rd"]["auto_checkin"] = data["honkai3rd_Auto_sign"] + + def load_config(): + global config with open(config_Path, "r") as f: data = json.load(f) - global enable_Config - global mihoyobbs_Login_ticket - global mihoyobbs_Stuid - global mihoyobbs_Stoken - global mihoyobbs_Cookies - global mihoyobbs - global genshin_Auto_sign - global honkai3rd_Auto_sign - enable_Config = data["enable_Config"] - mihoyobbs_Login_ticket = data["mihoyobbs_Login_ticket"] - mihoyobbs_Stuid = data["mihoyobbs_Stuid"] - mihoyobbs_Stoken = data["mihoyobbs_Stoken"] - mihoyobbs_Cookies = data["mihoyobbs_Cookies"] - mihoyobbs["bbs_Global"] = data["mihoyobbs"]["bbs_Global"] - mihoyobbs["bbs_Signin"] = data["mihoyobbs"]["bbs_Signin"] - mihoyobbs["bbs_Signin_multi"] = data["mihoyobbs"]["bbs_Signin_multi"] - mihoyobbs["bbs_Signin_multi_list"] = data["mihoyobbs"]["bbs_Signin_multi_list"] - mihoyobbs["bbs_Read_posts"] = data["mihoyobbs"]["bbs_Read_posts"] - mihoyobbs["bbs_Like_posts"] = data["mihoyobbs"]["bbs_Like_posts"] - mihoyobbs["bbs_Unlike"] = data["mihoyobbs"]["bbs_Unlike"] - mihoyobbs["bbs_Share"] = data["mihoyobbs"]["bbs_Share"] - genshin_Auto_sign = data["genshin_Auto_sign"] - honkai3rd_Auto_sign = data["honkai3rd_Auto_sign"] + if data.get('version') == 5: + config = data + try: + config["mihoyobbs"]["like_post"] + except KeyError: + pass + else: + config["mihoyobbs"]["read_posts"] = config["mihoyobbs"]["read_post"] + config["mihoyobbs"]["like_posts"] = config["mihoyobbs"]["like_post"] + del config["mihoyobbs"]["like_post"] + del config["mihoyobbs"]["read_post"] + save_config() + else: + load_v4(data) + log.info("升级v5 config") + # 直接升级到v5 config + save_config() f.close() log.info("Config加载完毕") def save_config(): + global serverless + if serverless: + log.info("云函数执行,无法保存") + return None with open(config_Path, "r+") as f: - data = json.load(f) - data["mihoyobbs_Login_ticket"] = mihoyobbs_Login_ticket - data["mihoyobbs_Stuid"] = mihoyobbs_Stuid - data["mihoyobbs_Stoken"] = mihoyobbs_Stoken - f.seek(0) - f.truncate() - temp_Text = json.dumps(data, sort_keys=False, indent=4, separators=(', ', ': ')) - f.write(temp_Text) - f.flush() + temp_text = json.dumps(config, sort_keys=False, indent=4, separators=(', ', ': ')) + try: + f.seek(0) + f.truncate() + f.write(temp_text) + f.flush() + except OSError: + serverless = True + log.info("Cookie保存失败") + exit(-1) + else: + log.info("Config保存完毕") f.close() - log.info("Config保存完毕") def clear_cookies(): + global config + global serverless + if serverless: + log.info("云函数执行,无法保存") + return None with open(config_Path, "r+") as f: - data = json.load(f) - data["enable_Config"] = False - data["mihoyobbs_Login_ticket"] = "" - data["mihoyobbs_Stuid"] = "" - data["mihoyobbs_Stoken"] = "" - data["mihoyobbs_Cookies"] = "" - f.seek(0) - f.truncate() - temp_Text = json.dumps(data, sort_keys=False, indent=4, separators=(', ', ': ')) - f.write(temp_Text) - f.flush() + config["enable"] = False + config["account"]["login_ticket"] = "" + config["account"]["stuid"] = "" + config["account"]["stoken"] = "" + config["account"]["cookie"] = "CookieError" + temp_text = json.dumps(config, sort_keys=False, indent=4, separators=(', ', ': ')) + try: + f.seek(0) + f.truncate() + f.write(temp_text) + f.flush() + except OSError: + serverless = True + log.info("Cookie删除失败") + else: + log.info("Cookie删除完毕") f.close() - log.info("Cookie删除完毕") + +if __name__ == "__main__": + # 初始化配置文件 + # try: + # account_cookie = config['account']['cookie'] + # config = load_config() + # config['account']['cookie'] = account_cookie + # except OSError: + # pass + # save_config() + pass \ No newline at end of file diff --git a/config/README.md b/config/README.md index 9143b1c..87bb82c 100644 --- a/config/README.md +++ b/config/README.md @@ -13,10 +13,10 @@ >此字段的作用是是否启用这个配置文件,`bool`类型,可设置`true`(默认)和`false` ```json -"config_Version": 3, +"config_Version": 5, ``` ->此字段的作用是表明配置文件版本(不过脚本里面暂时没有用到),`int`类型 +>此字段的作用是表明配置文件版本(4会被转成5),`int`类型 ```json "mihoyobbs_Login_ticket": "", @@ -44,34 +44,34 @@ ```json "mihoyobbs": { - "bbs_Global": true, - "bbs_Signin": true, - "bbs_Signin_multi": true, - "bbs_Signin_multi_list": [2, 5], - "bbs_Read_posts": true, - "bbs_Like_posts": true, - "bbs_Unlike": true, - "bbs_Share": true + "enable": true, + "checkin": true, + "checkin_multi": true, + "checkin_multi_list": [2, 5], + "read_posts": true, + "like_posts": true, + "un_like": true, + "share_post": true }, ``` 此字段的作用是米游币获取相关的设置,`object`类型(**python**里面是`dict`) ->`bbs_Global`的作用是是否启用米游币获取,`bool`类型,可设置`true`(默认)和`false` +>`enable`的作用是是否启用米游币获取,`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Signin`的作用是是否启用讨论区自动签到,`bool`类型,可设置`true`(默认)和`false` +>`checkin`的作用是是否启用讨论区自动签到,`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Signin_multi`的作用是是否启用多个讨论区签到(关闭的话只签到大别墅),`bool`类型,可设置`true`(默认)和`false` +>`checkin_multi`的作用是是否启用多个讨论区签到(关闭的话只签到大别墅),`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Signin_multi_list`的作用设置要签到的讨论区,`array`类型(**python**里面是`list`),可设置内容可以设置`[1,2,3,4,5]`签到全部讨论区,默认是`[2,5]`,可以通过调整id的位置来进行设置阅读/点赞/分享指定讨论区的帖子`[2,1,5]`(签到原神,崩坏3和大别墅)[讨论区的id对应关系](## 讨论区的id对应关系) +>`checkin_multi_list`的作用设置要签到的讨论区,`array`类型(**python**里面是`list`),可设置内容可以设置`[1,2,3,4,5]`签到全部讨论区,默认是`[2,5]`,可以通过调整id的位置来进行设置阅读/点赞/分享指定讨论区的帖子`[2,1,5]`(签到原神,崩坏3和大别墅)[讨论区的id对应关系](## 讨论区的id对应关系) > ->`bbs_Read_posts`的作用是是否启用自动阅读帖子,`bool`类型,可设置`true`(默认)和`false` +>`read_posts`的作用是是否启用自动阅读帖子,`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Like_posts`的作用是是否启用自动点赞帖子,`bool`类型,可设置`true`(默认)和`false` +>`like_posts`的作用是是否启用自动点赞帖子,`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Unlike`的作用是是否启用自动取消帖子点赞(当`bbs_Like_posts`为`false`时本设置无效),`bool`类型,可设置`true`(默认)和`false` +>`un_like`的作用是是否启用自动取消帖子点赞(当`like_posts`为`false`时本设置无效),`bool`类型,可设置`true`(默认)和`false` > ->`bbs_Share`的作用是是否启用自动分享帖子,`bool`类型,可设置`true`(默认)和`false` +>`share_post`的作用是是否启用自动分享帖子,`bool`类型,可设置`true`(默认)和`false` ```json "genshin_Auto_sign": true, @@ -98,3 +98,81 @@ `5`对应大别墅 `6`对应崩坏:星穹铁道 + + +# push.ini配置教程 + +* push_server 可选范围 cqhttp ftqq(sever酱) pushplus telegram dingrobot bark + + +## Wecom +企业微信 + +**wechat_id**填写**企业ID**,见: 我的企业 -> 企业设置 -> 企业ID + +**agentid**填写**AgentId**,见: 应用管理 -> 自建 -> 「你自己的应用」 -> 复制数字 +**secret**填写**Secret**,见: 应用管理 -> 自建 -> 「你自己的应用」-> 点查看链接 + +**touser**填写**接收人**,默认 @all 通知企业内所有人,指定接收人时使用大驼峰拼音,多个可用|隔开 + +填写示例 + +```ini +[setting] +enable=true +push_server=wecom + +[wecom] +#企业微信的corpid +wechat_id= +#企业微信的应用配置 +agentid= +secret= +touser=@all +``` + +## dingrobot +钉钉群机器人 + +**webhook**填写**Webhook**地址 + +**secret**填写**安全设置**中**加签**的密钥,此选项为可选项 + +填写示例 + +```ini +[setting] +enable=true +push_server=dingrobot + +[dingrobot] +webhook=https://oapi.dingtalk.com/robot/send?access_token=XXX +secret= +``` + + + +## bark + +一款开源的消息推送工具 https://github.com/Finb/Bark + +手机安装bark客户端获得托管在api.day.app的Token,也可以自己搭建私有服务端。 + +**api_url**一般不用改,自己搭建私有服务端的需要改掉 + +**token**填写**APP**内**URL**中的密钥,此选项必填 + +> `https://api.day.app/` `token部分` `/Title/NotificationContent` + +填写示例 + +```ini +[setting] +enable=true +push_server=bark + +[bark] +api_url=https://api.day.app +token=XXX +``` + diff --git a/config/config.json.example b/config/config.json.example index f847b83..aec32bc 100644 --- a/config/config.json.example +++ b/config/config.json.example @@ -1,20 +1,49 @@ { - "enable_Config": true, - "config_Version": 4, - "mihoyobbs_Login_ticket": "", - "mihoyobbs_Stuid": "", - "mihoyobbs_Stoken": "", - "mihoyobbs_Cookies": "", - "mihoyobbs": { - "bbs_Global": true, - "bbs_Signin": true, - "bbs_Signin_multi": true, - "bbs_Signin_multi_list": [2, 5], - "bbs_Read_posts": true, - "bbs_Like_posts": true, - "bbs_Unlike": true, - "bbs_Share": true - }, - "genshin_Auto_sign": true, - "honkai3rd_Auto_sign": false + "enable": true, + "version": 5, + "account": { + "cookie": "", + "login_ticket": "", + "stuid": "", + "stoken": "" + }, + "mihoyobbs": { + "enable": true, + "checkin": true, + "checkin_multi": true, + "checkin_multi_list": [2, 5], + "read_posts": true, + "like_posts": true, + "un_like": true, + "share_post": true + }, + "games": { + "cn": { + "enable": true, + "hokai2": { + "auto_checkin": false, + "black_list": [] + }, + "honkai3rd": { + "auto_checkin": false, + "black_list": [] + }, + "tears_of_themis": { + "auto_checkin": false, + "black_list": [] + }, + "genshin": { + "auto_checkin": false, + "black_list": [] + } + }, + "os": { + "enable": false, + "cookie": "", + "genshin": { + "auto_checkin": false, + "black_list": [] + } + } + } } \ No newline at end of file diff --git a/config/push.ini.example b/config/push.ini.example index f5cc758..466eba4 100644 --- a/config/push.ini.example +++ b/config/push.ini.example @@ -1,8 +1,8 @@ [setting] enable=false -#共有 cqhttp ftqq(sever酱) pushplus telegram +#共有 cqhttp ftqq(sever酱) pushplus telegram wecom dingrobot bark push_server=cqhttp -#server酱和pushplus的推送token +#server酱 pushplus dingrobot 的推送token push_token=123456 [cqhttp] @@ -14,4 +14,24 @@ cqhttp_qq=10001 [telegram] api_url=api.telegram.org bot_token=123465:abcdefg -chat_id=123456 \ No newline at end of file +chat_id=123456 + +[wecom] +#企业微信的corpid +wechat_id= +#企业微信的应用配置 +agentid= +secret= +touser=@all + +[pushdeer] +api_url=https://api2.pushdeer.com +token= + +[dingrobot] +webhook=https://oapi.dingtalk.com/robot/send?access_token=XXX +secret= + +[bark] +api_url=https://api.day.app +token=ssXXX diff --git a/docker.py b/docker.py index 28b2ea1..30d4b4c 100644 --- a/docker.py +++ b/docker.py @@ -1,21 +1,14 @@ -import datetime import os -import logging -import signal import time -#from settings import * +import signal +import datetime +from loghelper import log from crontab import CronTab time_format = "%Y-%m-%d %H:%M:%S" -logging.basicConfig( - level=logging.INFO, - format='%(asctime)s %(levelname)s %(message)s', - datefmt='%Y-%m-%dT%H:%M:%S') -log = logging - def stop_me(_signo, _stack): log.info("Docker container has stoped....") exit(-1) diff --git a/genshin.py b/genshin.py index 21afe58..11c5c75 100644 --- a/genshin.py +++ b/genshin.py @@ -6,48 +6,25 @@ import setting from request import http from loghelper import log from error import CookieError +from account import get_account_list class Genshin: def __init__(self) -> None: - self.headers = { - 'Accept': 'application/json, text/plain, */*', - 'DS': tools.get_ds(web=True, web_old=True), - 'Origin': 'https://webstatic.mihoyo.com', - 'x-rpc-app_version': setting.mihoyobbs_Version_old, - 'User-Agent': 'Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.3.0', - 'x-rpc-client_type': setting.mihoyobbs_Client_type_web, - 'Referer': 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true&act_id=e202009291139501&utm_source=bbs&utm_medium=mys&utm_campaign=icon', - 'Accept-Encoding': 'gzip, deflate', - 'Accept-Language': 'zh-CN,en-US;q=0.8', - 'X-Requested-With': 'com.mihoyo.hyperion', - "Cookie": config.mihoyobbs_Cookies, - 'x-rpc-device_id': tools.get_device_id() - } - self.acc_List = self.get_account_list() - if len(self.acc_List) != 0: - self.sign_Give = self.get_signgive() - - # 获取绑定的账号列表 - def get_account_list(self) -> list: - log.info("正在获取米哈游账号绑定原神账号列表...") - temp_list = [] - req = http.get(setting.genshin_Account_info_url, headers=self.headers) - data = req.json() - if data["retcode"] != 0: - log.warning("获取账号列表失败!") - config.genshin_Auto_sign = False - config.save_config() - raise CookieError("BBS Cookie Errror") - for i in data["data"]["list"]: - temp_list.append([i["nickname"], i["game_uid"], i["region"]]) - log.info(f"已获取到{len(temp_list)}个原神账号信息") - return temp_list + self.headers = setting.headers + self.headers['DS'] = tools.get_ds(web=True, web_old=True) + self.headers['Referer'] = 'https://webstatic.mihoyo.com/bbs/event/signin-ys/index.html?bbs_auth_required=true'\ + f'&act_id={setting.genshin_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon' + self.headers['Cookie'] = config.config["account"]["cookie"] + self.headers['x-rpc-device_id'] = tools.get_device_id() + self.account_list = get_account_list("hk4e_cn", self.headers) + if len(self.account_list) != 0: + self.checkin_rewards = self.get_checkin_rewards() # 获取已经签到奖励列表 - def get_signgive(self) -> list: + def get_checkin_rewards(self) -> list: log.info("正在获取签到奖励列表...") - req = http.get(setting.genshin_Signlisturl.format(setting.genshin_Act_id), headers=self.headers) + req = http.get(setting.genshin_checkin_rewards, headers=self.headers) data = req.json() if data["retcode"] != 0: log.warning("获取签到奖励列表失败") @@ -55,22 +32,24 @@ class Genshin: return data["data"]["awards"] # 判断签到 - def is_sign(self, region: str, uid: str): + def is_sign(self, region: str, uid: str) -> dict: req = http.get(setting.genshin_Is_signurl.format(setting.genshin_Act_id, region, uid), headers=self.headers) data = req.json() if data["retcode"] != 0: log.warning("获取账号签到信息失败!") print(req.text) - config.genshin_Auto_sign = False + config.config["games"]["cn"]["genshin"]["auto_checkin"] = False config.save_config() raise CookieError("BBS Cookie Errror") return data["data"] # 签到 - def sign_account(self): - return_data = "原神:" - if len(self.acc_List) != 0: - for i in self.acc_List: + def sign_account(self) -> str: + return_data = "原神: " + if len(self.account_list) != 0: + for i in self.account_list: + if i[1] in config.config["games"]["cn"]["genshin"]["black_list"]: + continue log.info(f"正在为旅行者{i[0]}进行签到...") time.sleep(random.randint(2, 8)) is_data = self.is_sign(region=i[2], uid=i[1]) @@ -80,23 +59,24 @@ class Genshin: sign_days = is_data["total_sign_day"] - 1 ok = True if is_data["is_sign"]: - log.info(f"旅行者{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.sign_Give[sign_days])}") + log.info(f"旅行者{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days])}") + sign_days += 1 else: time.sleep(random.randint(2, 8)) req = http.post(url=setting.genshin_Signurl, headers=self.headers, json={'act_id': setting.genshin_Act_id, 'region': i[2], 'uid': i[1]}) data = req.json() if data["retcode"] == 0: - log.info(f"旅行者{i[0]}签到成功~\r\n今天获得的奖励是{tools.get_item(self.sign_Give[0 if sign_days == 0 else sign_days + 1])}") - sign_days += 1 + log.info(f"旅行者{i[0]}签到成功~\r\n今天获得的奖励是" + f"{tools.get_item(self.checkin_rewards[0 if sign_days == 0 else sign_days + 1])}") + sign_days += 2 elif data["retcode"] == -5003: - log.info(f"旅行者{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.sign_Give[sign_days])}") + log.info(f"旅行者{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days])}") else: log.warning("账号签到失败!") - print(req.text) ok = False if ok: - return_data += f"\n{i[0]}已连续签到{sign_days}天\n今天获得的奖励是{tools.get_item(self.sign_Give[sign_days])}" + return_data += f"\n{i[0]}已连续签到{sign_days}天\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days - 1])}" else: return_data += f"\n{i[0]},本次签到失败" else: diff --git a/honkai2.py b/honkai2.py new file mode 100644 index 0000000..74b0ff4 --- /dev/null +++ b/honkai2.py @@ -0,0 +1,87 @@ +import time +import tools +import config +import random +import setting +from request import http +from loghelper import log +from error import CookieError +from account import get_account_list + + +class Honkai2: + def __init__(self) -> None: + self.headers = setting.headers + self.headers['DS'] = tools.get_ds(web=True, web_old=True) + self.headers['Referer'] = 'https://webstatic.mihoyo.com/bbs/event/signin/bh2/index.html?bbs_auth_required' \ + f'=true&act_id={setting.honkai2_Act_id}&bbs_presentation_style=fullscreen' \ + '&utm_source=bbs&utm_medium=mys&utm_campaign=icon' + self.headers['Cookie'] = config.config["account"]["cookie"] + self.headers['x-rpc-device_id'] = tools.get_device_id() + self.account_list = get_account_list("bh2_cn", self.headers) + self.sign_day = 0 + if len(self.account_list) != 0: + self.checkin_rewards = self.get_checkin_rewards() + + def get_checkin_rewards(self) -> list: + log.info("正在获取签到奖励列表...") + req = http.get(setting.honkai2_checkin_rewards, headers=self.headers) + data = req.json() + if data["retcode"] != 0: + log.warning("获取签到奖励列表失败") + print(req.text) + return data["data"]["awards"] + + # 判断签到 + def is_sign(self, region: str, uid: str) -> dict: + req = http.get(setting.honkai2_Is_signurl.format(setting.honkai2_Act_id, region, uid), headers=self.headers) + data = req.json() + if data["retcode"] != 0: + log.warning("获取账号签到信息失败!") + print(req.text) + config.config["games"]["cn"]["hokai2"]["auto_checkin"] = False + config.save_config() + raise CookieError("BBS Cookie Errror") + return data["data"] + + # 签到 + def sign_account(self) -> str: + return_data = "崩坏学园2: " + if len(self.account_list) != 0: + for i in self.account_list: + if i[1] in config.config["games"]["cn"]["hokai2"]["black_list"]: + continue + log.info(f"正在为崩坏2玩家: {i[0]}进行签到...") + time.sleep(random.randint(2, 8)) + is_data = self.is_sign(region=i[2], uid=i[1]) + # if not is_data["is_sub"]: # 这个字段不知道干啥的,就先塞这里了 + if False: # 算了先改成false + log.warning(f"旅行者{i[0]}是第一次绑定米游社,请先手动签到一次") + else: + sign_days = is_data["total_sign_day"] - 1 + ok = True + if is_data["is_sign"]: + log.info(f"崩坏2玩家:{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days])}") + sign_days += 1 + else: + time.sleep(random.randint(2, 8)) + req = http.post(url=setting.honkai2_Sign_url, headers=self.headers, + json={'act_id': setting.honkai2_Act_id, 'region': i[2], 'uid': i[1]}) + data = req.json() + if data["retcode"] == 0: + log.info(f"崩坏2玩家:{i[0]}签到成功~\r\n今天获得的奖励是" + f"{tools.get_item(self.checkin_rewards[0 if sign_days == 0 else sign_days + 1])}") + sign_days += 2 + elif data["retcode"] == -5003: + log.info(f"崩坏2玩家:{i[0]}今天已经签到过了~\r\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days])}") + else: + log.warning("账号签到失败!") + ok = False + if ok: + return_data += f"\n{i[0]}已连续签到{sign_days}天\n今天获得的奖励是{tools.get_item(self.checkin_rewards[sign_days - 1])}" + else: + return_data += f"\n{i[0]},本次签到失败" + else: + log.warning("账号没有绑定任何崩坏学园2账号!") + return_data += "\n并没有绑定任何崩坏学园2账号" + return return_data diff --git a/honkai3rd.py b/honkai3rd.py index 3c75c9b..c5407d3 100644 --- a/honkai3rd.py +++ b/honkai3rd.py @@ -5,47 +5,21 @@ import random import setting from request import http from loghelper import log -from error import CookieError +from account import get_account_list class Honkai3rd: def __init__(self) -> None: - self.headers = { - 'Accept': 'application/json, text/plain, */*', - 'DS': tools.get_ds(web=True, web_old=True), - 'Origin': 'https://webstatic.mihoyo.com', - 'x-rpc-app_version': setting.mihoyobbs_Version_old, - 'User-Agent': 'Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) ' - 'Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.3.0', - 'x-rpc-client_type': setting.mihoyobbs_Client_type_web, - 'Referer': f'https://webstatic.mihoyo.com/bh3/event/euthenia/index.html?bbs_presentation_style=fullscreen' - f'&bbs_game_role_required=bh3_cn&bbs_auth_required=t' - f'rue&act_id={setting.honkai3rd_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon', - 'Accept-Encoding': 'gzip, deflate', - 'Accept-Language': 'zh-CN,en-US;q=0.8', - 'X-Requested-With': 'com.mihoyo.hyperion', - "Cookie": config.mihoyobbs_Cookies, - 'x-rpc-device_id': tools.get_device_id() - } - self.acc_List = self.get_account_list() + self.headers = setting.headers + self.headers['DS'] = tools.get_ds(web=True, web_old=True) + self.headers['Referer'] = 'https://webstatic.mihoyo.com/bh3/event/euthenia/index.html?bbs_presentation_style' \ + '=fullscreen&bbs_game_role_required=bh3_cn&bbs_auth_required=true&act_id=' \ + f'{setting.honkai3rd_Act_id}&utm_source=bbs&utm_medium=mys&utm_campaign=icon' + self.headers['Cookie'] = config.config["account"]["cookie"] + self.headers['x-rpc-device_id'] = tools.get_device_id() + self.account_list = get_account_list("bh3_cn", self.headers) self.sign_day = 0 - # 获取绑定的账号列表 - def get_account_list(self) -> list: - log.info("正在获取米哈游账号绑定的崩坏3账号列表...") - temp_list = [] - req = http.get(setting.honkai3rd_Account_info_url, headers=self.headers) - data = req.json() - if data["retcode"] != 0: - log.warning("获取账号列表失败!") - config.honkai3rd_Auto_sign = False - config.save_config() - raise CookieError("BBS Cookie Error") - for i in data["data"]["list"]: - temp_list.append([i["nickname"], i["game_uid"], i["region"]]) - log.info(f"已获取到{len(temp_list)}个崩坏3账号信息") - return temp_list - # 获取今天已经签到了的dict def get_today_item(self, raw_data: list): # 用range进行循环,当status等于0的时候上一个就是今天签到的dict @@ -60,15 +34,18 @@ class Honkai3rd: return raw_data[i] # 签到 - def sign_account(self): - return_data = "崩坏3:" - if len(self.acc_List) == 0: + def sign_account(self) -> str: + return_data = "崩坏3: " + if len(self.account_list) == 0: log.warning("账号没有绑定任何崩坏3账号!") return_data += "\n并没有绑定任何崩坏3账号" else: - for i in self.acc_List: + for i in self.account_list: + if i[1] in config.config["games"]["cn"]["honkai3rd"]["black_list"]: + continue log.info(f"正在为舰长 {i[0]} 进行签到...") - req = http.get(setting.honkai3rd_Is_signurl.format(setting.honkai3rd_Act_id, i[2], i[1]), headers=self.headers) + req = http.get(setting.honkai3rd_Is_signurl.format(setting.honkai3rd_Act_id, i[2], i[1]), + headers=self.headers) data = req.json() re_message = "" if data["retcode"] != 0: @@ -79,7 +56,7 @@ class Honkai3rd: today_item = self.get_today_item(data["data"]["sign"]["list"]) # 判断是否已经签到 if today_item["status"] == 0: - re_message = f"舰长 {i[0]} 今天已经签到过了~\t已连续签到{self.sign_day}天\t今天获得的奖励是{tools.get_item(today_item)}" + re_message = f"舰长 {i[0]} 今天已经签到过了~\t已连续签到{self.sign_day + 1}天\t今天获得的奖励是{tools.get_item(today_item)}" log.info(re_message) else: time.sleep(random.randint(2, 8)) @@ -88,14 +65,14 @@ class Honkai3rd: data = req.json() if data["retcode"] == 0: today_item = self.get_today_item(data["data"]["list"]) - re_message = f"舰长 {i[0]} 签到成功~\t已连续签到{self.sign_day}天\t今天获得的奖励是{tools.get_item(today_item)}" + re_message = f"舰长 {i[0]} 签到成功~\t已连续签到{self.sign_day + 2}天\t今天获得的奖励是{tools.get_item(today_item)}" log.info(re_message) elif data["retcode"] == -5003: - re_message = f"舰长 {i[0]} 今天已经签到过了~\t已连续签到{self.sign_day}天\t今天获得的奖励是{tools.get_item(today_item)}" + re_message = f"舰长 {i[0]} 今天已经签到过了~\t已连续签到{self.sign_day + 1}天\t今天获得的奖励是{tools.get_item(today_item)}" log.info(re_message) else: re_message = f"舰长 {i[0]} 本次签到失败!" log.warning(re_message) print(req.text) - return_data += re_message + return_data += "\r\n" + re_message return return_data diff --git a/index.py b/index.py index 65c202b..972af5c 100644 --- a/index.py +++ b/index.py @@ -1,10 +1,12 @@ import main import push +import config import main_multi from error import CookieError def main_handler(event: dict, context: dict): + config.serverless = True try: status_code, push_message = main.main() except CookieError: @@ -15,6 +17,7 @@ def main_handler(event: dict, context: dict): def main_handler_mulit(event: dict, context: dict): + config.serverless = True # 多用户需要传递True表示自动执行,不需要手动进行确认 main_multi.main_multi(True) print("云函数多用户测试支持!") diff --git a/login.py b/login.py index fa0955f..fb1e2f5 100644 --- a/login.py +++ b/login.py @@ -1,28 +1,29 @@ import config -import request import setting +from request import http from loghelper import log from error import CookieError def login(): - if config.mihoyobbs_Cookies == '': + if config.config["account"]["cookie"] == '': log.error("请填入Cookies!") config.clear_cookies() raise CookieError('No cookie') # 判断Cookie里面是否有login_ticket 没有的话直接退了 - if "login_ticket" in config.mihoyobbs_Cookies: - temp_Cookies = config.mihoyobbs_Cookies.split(";") - for i in temp_Cookies: + if "login_ticket" in config.config["account"]["cookie"]: + temp_cookies = config.config["account"]["cookie"].split(";") + for i in temp_cookies: if i.split("=")[0] == " login_ticket": - config.mihoyobbs_Login_ticket = i.split("=")[1] + config.config["account"]["login_ticket"] = i.split("=")[1] break # 这里获取Stuid,但是实际是可以直接拿cookie里面的Uid - data = request.get(url=setting.bbs_Cookieurl.format(config.mihoyobbs_Login_ticket)) + data = http.get(url=setting.bbs_Cookie_url.format(config.config["account"]["login_ticket"])).json() if "成功" in data["data"]["msg"]: - config.mihoyobbs_Stuid = str(data["data"]["cookie_info"]["account_id"]) - data = request.get(url=setting.bbs_Cookieurl2.format(config.mihoyobbs_Login_ticket, config.mihoyobbs_Stuid)) - config.mihoyobbs_Stoken = data["data"]["list"][0]["token"] + config.config["account"]["stuid"] = str(data["data"]["cookie_info"]["account_id"]) + data = http.get(url=setting.bbs_Cookie_url2.format( + config.config["account"]["login_ticket"], config.config["account"]["stuid"])).json() + config.config["account"]["stoken"] = data["data"]["list"][0]["token"] log.info("登录成功!") log.info("正在保存Config!") config.save_config() diff --git a/main.py b/main.py index 68d2dbc..1477be5 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,7 @@ import push import login import config import random +import honkai2 import genshin import setting import mihoyobbs @@ -13,19 +14,20 @@ from error import CookieError def main(): # 初始化,加载配置 - return_data = "\n米游社:" + return_data = "\n米游社: " config.load_config() - if config.enable_Config: + if config.config["enable"]: # 检测参数是否齐全,如果缺少就进行登入操作 - if config.mihoyobbs_Login_ticket == "" or config.mihoyobbs_Stuid == "" or config.mihoyobbs_Stoken == "": + if config.config["account"]["login_ticket"] == "" or config.config["account"]["stuid"] == "" or \ + config.config["account"]["stoken"] == "": # 登入,如果没开启bbs全局没打开就无需进行登入操作 - if config.mihoyobbs["bbs_Global"]: + if config.config["mihoyobbs"]["enable"]: login.login() time.sleep(random.randint(2, 8)) # 获取要使用的BBS列表,#判断是否开启bbs_Signin_multi - if config.mihoyobbs["bbs_Signin_multi"]: + if config.config["mihoyobbs"]["checkin_multi"]: # 用这里的方案可以实现当让id在第一个的时候为主社区 - for i in config.mihoyobbs["bbs_Signin_multi_list"]: + for i in config.config["mihoyobbs"]["checkin_multi_list"]: for i2 in setting.mihoyobbs_List: if i == int(i2["id"]): setting.mihoyobbs_List_Use.append(i2) @@ -35,47 +37,56 @@ def main(): if int(i["id"]) == 5: setting.mihoyobbs_List_Use.append(i) # 米游社签到 - if config.mihoyobbs["bbs_Global"]: - bbs = mihoyobbs.mihoyobbs() + if config.config["mihoyobbs"]["enable"]: + bbs = mihoyobbs.Mihoyobbs() if bbs.Task_do["bbs_Sign"] and bbs.Task_do["bbs_Read_posts"] and bbs.Task_do["bbs_Like_posts"] and \ bbs.Task_do["bbs_Share"]: - return_data += "\n" + f"今天已经全部完成了!\n"\ - f"一共获得{mihoyobbs.Today_have_getcoins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币" - log.info(f"今天已经全部完成了!一共获得{mihoyobbs.Today_have_getcoins}个米游币,目前有{mihoyobbs.Have_coins}个米游币") + return_data += "\n" + f"今天已经全部完成了!\n" \ + f"一共获得{mihoyobbs.today_have_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币" + log.info(f"今天已经全部完成了!一共获得{mihoyobbs.today_have_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币") else: - if config.mihoyobbs["bbs_Signin"]: - bbs.signing() - if config.mihoyobbs["bbs_Read_posts"]: - bbs.read_posts() - if config.mihoyobbs["bbs_Like_posts"]: - bbs.Likeposts() - if config.mihoyobbs["bbs_Share"]: - bbs.share_post() - bbs.Get_taskslist() - return_data += "\n" + f"今天已经获得{mihoyobbs.Today_have_getcoins}个米游币\n"\ - f"还能获得{mihoyobbs.Today_getcoins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币" - log.info(f"今天已经获得{mihoyobbs.Today_have_getcoins}个米游币," - f"还能获得{mihoyobbs.Today_getcoins}个米游币,目前有{mihoyobbs.Have_coins}个米游币") + i = 0 + while mihoyobbs.today_get_coins != 0 and i < 3: + if i > 0: + bbs.refresh_list() + if config.config["mihoyobbs"]["checkin"]: + bbs.signing() + if config.config["mihoyobbs"]["read_posts"]: + bbs.read_posts() + if config.config["mihoyobbs"]["like_posts"]: + bbs.like_posts() + if config.config["mihoyobbs"]["share_post"]: + bbs.share_post() + bbs.get_tasks_list() + i += 1 + return_data += "\n" + f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币\n" \ + f"还能获得{mihoyobbs.today_get_coins}个米游币\n目前有{mihoyobbs.Have_coins}个米游币" + log.info(f"今天已经获得{mihoyobbs.today_have_get_coins}个米游币," + f"还能获得{mihoyobbs.today_get_coins}个米游币,目前有{mihoyobbs.Have_coins}个米游币") time.sleep(random.randint(2, 8)) else: return_data += "\n" + "米游社功能未启用!" log.info("米游社功能未启用!") + # 崩坏2签到 config这里少了个n,下回config v6的时候再修复吧 + if config.config["games"]["cn"]["hokai2"]["auto_checkin"]: + log.info("正在进行崩坏2签到") + honkai2_help = honkai2.Honkai2() + return_data += "\n\n" + honkai2_help.sign_account() + time.sleep(random.randint(2, 8)) + # 崩坏3签到 + if config.config["games"]["cn"]["honkai3rd"]["auto_checkin"]: + log.info("正在进行崩坏3签到") + honkai3rd_help = honkai3rd.Honkai3rd() + return_data += "\n\n" + honkai3rd_help.sign_account() # 原神签到 - if config.genshin_Auto_sign: + if config.config["games"]["cn"]["genshin"]["auto_checkin"]: log.info("正在进行原神签到") genshin_help = genshin.Genshin() return_data += "\n\n" + genshin_help.sign_account() time.sleep(random.randint(2, 8)) - else: - log.info("原神签到功能未启用!") - # 崩坏3签到 - if config.honkai3rd_Auto_sign: - log.info("正在进行崩坏3签到") - honkai3rd_help = honkai3rd.Honkai3rd() - return_data += "\n\n" + honkai3rd_help.sign_account() - else: - log.info("崩坏3签到功能未启用!") return 0, return_data + elif config.config["account"]["cookie"] == "CookieError": + raise CookieError('Cookie expires') else: log.warning("Config未启用!") return 1, "Config未启用!" diff --git a/main_multi.py b/main_multi.py index 6cbde62..5a09d0f 100644 --- a/main_multi.py +++ b/main_multi.py @@ -32,7 +32,7 @@ def main_multi(autorun: bool): log.info(f"已搜索到{len(config_list)}个配置文件,请确认是否无多余文件!\r\n{config_list}") try: input("请输入回车继续,需要重新搜索配置文件请Ctrl+C退出脚本") - except: + except KeyboardInterrupt: exit(0) results = {"ok": [], "close": [], "error": []} for i in iter(config_list): @@ -51,10 +51,16 @@ def main_multi(autorun: bool): log.info(f"{i}执行完毕") time.sleep(random.randint(3, 10)) print("") - push_message = f'脚本执行完毕,共执行{len(config_list)}个配置文件,成功{len(results["ok"])}个,没执行{len(results["close"])}个,失败{len(results["error"])}个'\ + push_message = f'脚本执行完毕,共执行{len(config_list)}个配置文件,成功{len(results["ok"])}个,' \ + f'没执行{len(results["close"])}个,失败{len(results["error"])}个' \ f'\r\n没执行的配置文件: {results["close"]}\r\n执行失败的配置文件: {results["error"]}' log.info(push_message) - push.push(0, push_message) + status = 0 + if len(results["error"]) == len(config_list): + status = 1 + elif len(results["error"]) != 0: + status = 2 + push.push(status, push_message) if __name__ == "__main__": diff --git a/mihoyobbs.py b/mihoyobbs.py index 5e31eed..51b69ff 100644 --- a/mihoyobbs.py +++ b/mihoyobbs.py @@ -7,17 +7,16 @@ from request import http from loghelper import log from error import CookieError - -Today_getcoins = 0 -Today_have_getcoins = 0 # 这个变量以后可能会用上,先留着了 +today_get_coins = 0 +today_have_get_coins = 0 # 这个变量以后可能会用上,先留着了 Have_coins = 0 -class mihoyobbs: +class Mihoyobbs: def __init__(self): self.headers = { "DS": tools.get_ds(web=False, web_old=False), - "cookie": f"stuid={config.mihoyobbs_Stuid};stoken={config.mihoyobbs_Stoken}", + "cookie": f'stuid={config.config["account"]["stuid"]};stoken={config.config["account"]["stoken"]}', "x-rpc-client_type": setting.mihoyobbs_Client_type, "x-rpc-app_version": setting.mihoyobbs_Version, "x-rpc-sys_version": "6.0.1", @@ -37,31 +36,34 @@ class mihoyobbs: "bbs_Like_posts_num": 5, "bbs_Share": False } - self.Get_taskslist() + self.get_tasks_list() # 如果这三个任务都做了就没必要获取帖子了 if self.Task_do["bbs_Read_posts"] and self.Task_do["bbs_Like_posts"] and self.Task_do["bbs_Share"]: pass else: self.postsList = self.get_list() + def refresh_list(self) -> None: + self.postsList = self.get_list() + # 获取任务列表,用来判断做了哪些任务 - def Get_taskslist(self): - global Today_getcoins - global Today_have_getcoins + def get_tasks_list(self): + global today_get_coins + global today_have_get_coins global Have_coins log.info("正在获取任务列表") - req = http.get(url=setting.bbs_Taskslist, headers=self.headers) + req = http.get(url=setting.bbs_Tasks_list, headers=self.headers) data = req.json() if "err" in data["message"] or data["retcode"] == -100: log.error("获取任务列表失败,你的cookie可能已过期,请重新设置cookie。") config.clear_cookies() raise CookieError('Cookie expires') else: - Today_getcoins = data["data"]["can_get_points"] - Today_have_getcoins = data["data"]["already_received_points"] + today_get_coins = data["data"]["can_get_points"] + today_have_get_coins = data["data"]["already_received_points"] Have_coins = data["data"]["total_points"] # 如果当日可获取米游币数量为0直接判断全部任务都完成了 - if Today_getcoins == 0: + if today_get_coins == 0: self.Task_do["bbs_Sign"] = True self.Task_do["bbs_Read_posts"] = True self.Task_do["bbs_Like_posts"] = True @@ -69,10 +71,10 @@ class mihoyobbs: else: # 如果第0个大于或等于62则直接判定任务没做 if data["data"]["states"][0]["mission_id"] >= 62: - log.info(f"新的一天,今天可以获得{Today_getcoins}个米游币") + log.info(f"新的一天,今天可以获得{today_get_coins}个米游币") pass else: - log.info(f"似乎还有任务没完成,今天还能获得{Today_getcoins}") + log.info(f"似乎还有任务没完成,今天还能获得{today_get_coins}") for i in data["data"]["states"]: # 58是讨论区签到 if i["mission_id"] == 58: @@ -101,10 +103,16 @@ class mihoyobbs: def get_list(self) -> list: temp_list = [] log.info("正在获取帖子列表......") - req = http.get(url=setting.bbs_Listurl.format(setting.mihoyobbs_List_Use[0]["forumId"]), headers=self.headers) - data = req.json() + req = http.get(url=setting.bbs_List_url.format(setting.mihoyobbs_List_Use[0]["forumId"]), + headers=self.headers) + data = req.json()["data"]["list"] for n in range(5): - temp_list.append([data["data"]["list"][n]["post"]["post_id"], data["data"]["list"][n]["post"]["subject"]]) + r_l = random.choice(data) + while r_l["post"]["subject"] in str(temp_list): + r_l = random.choice(data) + temp_list.append([r_l["post"]["post_id"], r_l["post"]["subject"]]) + # temp_list.append([data["data"]["list"][n]["post"]["post_id"], data["data"]["list"][n]["post"]["subject"]]) + log.info("已获取{}个帖子".format(len(temp_list))) return temp_list @@ -115,7 +123,7 @@ class mihoyobbs: else: log.info("正在签到......") for i in setting.mihoyobbs_List_Use: - req = http.post(url=setting.bbs_Signurl.format(i["id"]), data={}, headers=self.headers) + req = http.post(url=setting.bbs_Sign_url.format(i["id"]), data={}, headers=self.headers) data = req.json() if "err" not in data["message"]: log.info(str(i["name"] + data["message"])) @@ -132,28 +140,28 @@ class mihoyobbs: else: log.info("正在看帖......") for i in range(self.Task_do["bbs_Read_posts_num"]): - req = http.get(url=setting.bbs_Detailurl.format(self.postsList[i][0]), headers=self.headers) + req = http.get(url=setting.bbs_Detail_url.format(self.postsList[i][0]), headers=self.headers) data = req.json() if data["message"] == "OK": log.debug("看帖:{} 成功".format(self.postsList[i][1])) time.sleep(random.randint(2, 8)) # 点赞 - def Likeposts(self): + def like_posts(self): if self.Task_do["bbs_Like_posts"]: log.info("点赞任务已经完成过了~") else: log.info("正在点赞......") for i in range(self.Task_do["bbs_Like_posts_num"]): - req = http.post(url=setting.bbs_Likeurl, headers=self.headers, + req = http.post(url=setting.bbs_Like_url, headers=self.headers, json={"post_id": self.postsList[i][0], "is_cancel": False}) data = req.json() if data["message"] == "OK": log.debug("点赞:{} 成功".format(self.postsList[i][1])) # 判断取消点赞是否打开 - if config.mihoyobbs["bbs_Unlike"]: + if config.config["mihoyobbs"]["un_like"] : time.sleep(random.randint(2, 8)) - req = http.post(url=setting.bbs_Likeurl, headers=self.headers, + req = http.post(url=setting.bbs_Like_url, headers=self.headers, json={"post_id": self.postsList[i][0], "is_cancel": True}) data = req.json() if data["message"] == "OK": @@ -168,13 +176,13 @@ class mihoyobbs: else: log.info("正在执行分享任务......") for i in range(3): - req = http.get(url=setting.bbs_Shareurl.format(self.postsList[0][0]), headers=self.headers) + req = http.get(url=setting.bbs_Share_url.format(self.postsList[0][0]), headers=self.headers) data = req.json() if data["message"] == "OK": log.debug("分享:{} 成功".format(self.postsList[0][1])) log.info("分享任务执行成功......") break else: - log.debug(f"分享任务执行失败,正在执行第{i+2}次,共3次") + log.debug(f"分享任务执行失败,正在执行第{i + 2}次,共3次") time.sleep(random.randint(2, 8)) time.sleep(random.randint(2, 8)) diff --git a/push.py b/push.py index 70ff873..25b831a 100644 --- a/push.py +++ b/push.py @@ -1,4 +1,9 @@ import os +import time +import base64 +import hashlib +import urllib +import hmac from request import http from loghelper import log from configparser import ConfigParser @@ -18,10 +23,13 @@ def load_config(): def title(status): if status == 0: return "「米游社脚本」执行成功!" - else: + elif status == 1: return "「米游社脚本」执行失败!" + elif status == 2: + return "「米游社脚本」部分账号执行失败!" +# telegram的推送 def telegram(status, push_message): http.post( url="https://{}/bot{}/sendMessage".format(cfg.get('telegram', 'api_url'), cfg.get('telegram', 'bot_token')), @@ -32,6 +40,7 @@ def telegram(status, push_message): ) +# server酱 def ftqq(status, push_message): http.post( url="https://sctapi.ftqq.com/{}.send".format(cfg.get('setting', 'push_token')), @@ -42,9 +51,10 @@ def ftqq(status, push_message): ) +# pushplus def pushplus(status, push_message): http.post( - url="http://www.pushplus.plus/send", + url="https://www.pushplus.plus/send", data={ "token": cfg.get('setting', 'push_token'), "title": title(status), @@ -53,7 +63,8 @@ def pushplus(status, push_message): ) -def cq_http(status, push_message): +# cq http协议的推送 +def cqhttp(status, push_message): http.post( url=cfg.get('cqhttp', 'cqhttp_url'), json={ @@ -63,20 +74,98 @@ def cq_http(status, push_message): ) +# 企业微信 感谢linjie5492@github +def wecom(status, push_message): + secret = cfg.get('wecom', 'secret') + corpid = cfg.get('wecom', 'wechat_id') + try: + touser = cfg.get('wecom', 'touser') + except: + # 没有配置时赋默认值 + touser = '@all' + + push_token = http.post( + url=f'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={corpid}&corpsecret={secret}', + data="" + ).json()['access_token'] + push_data = { + "agentid": cfg.get('wecom', 'agentid'), + "msgtype": "text", + "touser": touser, + "text": { + "content": title(status) + "\r\n" + push_message + }, + "safe": 0 + } + http.post(f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={push_token}', json=push_data) + + +# pushdeer +def pushdeer(status, push_message): + http.get( + url=f'{cfg.get("pushdeer", "api_url")}/message/push', + params={ + "pushkey": cfg.get("pushdeer", "token"), + "text": title(status), + "desp": str(push_message).replace("\r\n", "\r\n\r\n"), + "type": "markdown" + } + ) + +# 钉钉群机器人 +def dingrobot(status, push_message): + api_url = cfg.get('dingrobot', 'webhook') # https://oapi.dingtalk.com/robot/send?access_token=XXX + secret = cfg.get('dingrobot', 'secret') # 安全设置 -> 加签 -> 密钥 -> SEC* + + if secret: + timestamp = str(round(time.time() * 1000)) + sign_string = f"{timestamp}\n{secret}" + hmac_code = hmac.new( + key=secret.encode("utf-8"), + msg=sign_string.encode("utf-8"), + digestmod=hashlib.sha256 + ).digest() + sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) + api_url = f"{api_url}×tamp={timestamp}&sign={sign}" + + rep = http.post( + url=api_url, + headers={"Content-Type": "application/json; charset=utf-8"}, + json={ + "msgtype": "text", "text": { "content": title(status) + "\r\n" + push_message } + } + ).json() + log.info(f"推送结果:{rep.get('errmsg')}") + +# Bark +def bark(status, push_message): + rep = http.get( + url=f'{cfg.get("bark", "api_url")}/{cfg.get("bark", "token")}/{title(status)}/{push_message}' + ).json() + log.info(f"推送结果:{rep.get('message')}") + def push(status, push_message): if not load_config(): return 0 if cfg.getboolean('setting', 'enable'): - push_server = cfg.get('setting', 'push_server').lower() log.info("正在执行推送......") - log.debug(f"推送所用的服务为:{push_server}") - if push_server == "cqhttp": - cq_http(status, push_message) - elif push_server == "ftqq": - ftqq(status, push_message) - elif push_server == "pushplus": - pushplus(status, push_message) - elif push_server == "telegram": - telegram(status, push_message) - log.info("推送完毕......") - return 0 + func_name = cfg.get('setting', 'push_server').lower() + func = globals().get(func_name) + # print(func) + if not func: + log.warning("推送服务名称错误:请检查config/push.ini -> [setting] -> push_server") + return 0 + log.debug(f"推送所用的服务为:{func_name}") + try: + # eval(push_server[:10] + "(status, push_message)") + # 与面代码等效 20220508 + func(status, push_message) + except Exception as r: + log.warning(f"推送执行错误:{str(r)}") + return 0 + else: + log.info("推送完毕......") + return 1 + +if __name__ == "__main__": + push(0, f'推送验证{int(time.time())}') diff --git a/push_main-pushplus.py b/push_main-pushplus.py deleted file mode 100644 index 8e13297..0000000 --- a/push_main-pushplus.py +++ /dev/null @@ -1,40 +0,0 @@ -import sys -import time -import random -import subprocess -from request import http - -SendKey = "" -send_Url = "http://www.pushplus.plus/send" - -python_Path = sys.executable - -run_ShellCommand = python_Path + " main_multi.py autorun" - -for i in range(2): - opt_id, opt_info = subprocess.getstatusoutput(run_ShellCommand) - if opt_id == 0: - break - time.sleep(random.randint(30, 70)) - -if opt_id != 0: - print("Error!") - http.post( - url=send_Url, - data={ - "token": SendKey, - "title": "「米游社-签到」Error!", - "content": opt_info.split()[-1] + "\nHello!推送相关的设置已修改,请注意更新!\n这里是运行相关日志:\r\n" + opt_info, - } - ) -else: - print("OK!") - http.post( - url=send_Url, - data={ - "token": SendKey, - "title": "「米游社-签到」OK!", - "content": opt_info.split()[-1] + "\nHello!推送相关的设置已修改,请注意更新!\n这里是运行相关日志:\r\n" + opt_info, - } - ) -exit(0) diff --git a/push_main-server.py b/push_main-server.py deleted file mode 100644 index 9ad95a2..0000000 --- a/push_main-server.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys -import time -import random -import subprocess -from request import http - -SendKey = "" -send_Url = f"https://sctapi.ftqq.com/{SendKey}.send" - -python_Path = sys.executable - -run_ShellCommand = python_Path + " main_multi.py autorun" - -for i in range(2): - opt_id, opt_info = subprocess.getstatusoutput(run_ShellCommand) - if opt_id == 0: - break - time.sleep(random.randint(30, 70)) - -if opt_id != 0: - print("Error!") - http.post( - url=send_Url, - data={ - "title": "米游社脚本执行出错!", - "desp": "\nHello!推送相关的设置已修改,请注意更新!\n这里是运行相关日志:\r\n" + opt_info - } - ) -else: - http.post( - url=send_Url, - data={ - "title": "米游社脚本执行成功", - "desp": "\nHello!推送相关的设置已修改,请注意更新!\n这里是运行相关日志:\r\n" + opt_info - } - ) - print("OK!") -exit(0) diff --git a/request.py b/request.py index 8b090a1..c8fdd1d 100644 --- a/request.py +++ b/request.py @@ -5,39 +5,13 @@ try: http = httpx.Client(timeout=10, transport=httpx.HTTPTransport(retries=5)) # 当openssl版本小于1.0.2的时候直接进行一个空请求让httpx报错 import tools + if tools.get_openssl_version() <= 102: httpx.get() -except: +except (TypeError, ModuleNotFoundError): import requests from requests.adapters import HTTPAdapter + http = requests.Session() http.mount('http://', HTTPAdapter(max_retries=5)) http.mount('https://', HTTPAdapter(max_retries=5)) - - -# 这里实际上应该加个"-> dict"但是考虑到请求可能失败的关系,所以直接不声明返回变量 -def get(url: str, **headers: dict): - try: - req = http.get(url, headers=headers) - return req.json() - except: - print("请求失败,网络错误!") - return "" - - -def post(url: str, data: dict, **headers: dict): - try: - req = http.post(url, data=data, headers=headers) - return req.json() - except: - print("请求失败,网络错误!") - return "" - - -def post_json(url: str, json, **headers: dict): - try: - req = http.post(url, json=json, headers=headers) - return req.json() - except: - print("请求失败,网络错误!") - return "" diff --git a/setting.py b/setting.py index f2c438e..7497d00 100644 --- a/setting.py +++ b/setting.py @@ -39,30 +39,67 @@ mihoyobbs_List = [{ "forumId": "52", "name": "崩坏:星穹铁道", "url": "https://bbs.mihoyo.com/sr/" +}, { + "id": "8", + "forumId": "57", + "name": "绝区零", + "url": "https://bbs.mihoyo.com/zzz/" }] +game_id2name = { + "bh2_cn": "崩坏2", + "bh3_cn": "崩坏3", + "nxx_cn": "未定事件簿", + "hk4e_cn": "原神", +} # Config Load之后run里面进行列表的选择 mihoyobbs_List_Use = [] -# 米游社的API列表 -bbs_Cookieurl = "https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket?login_ticket={}" -bbs_Cookieurl2 = "https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}" -bbs_Taskslist = "https://bbs-api.mihoyo.com/apihub/sapi/getUserMissionsState" # 获取任务列表 -bbs_Signurl = "https://bbs-api.mihoyo.com/apihub/sapi/signIn?gids={}" # post -bbs_Listurl = "https://bbs-api.mihoyo.com/post/api/getForumPostList?forum_id={}&is_good=false&is_hot=false&page_size=20&sort_type=1" -bbs_Detailurl = "https://bbs-api.mihoyo.com/post/api/getPostFull?post_id={}" -bbs_Shareurl = "https://bbs-api.mihoyo.com/apihub/api/getShareConf?entity_id={}&entity_type=1" -bbs_Likeurl = "https://bbs-api.mihoyo.com/apihub/sapi/upvotePost" # post json +# 游戏签到的请求头 +headers = { + 'Accept': 'application/json, text/plain, */*', + 'DS': "", + 'Origin': 'https://webstatic.mihoyo.com', + 'x-rpc-app_version': mihoyobbs_Version_old, + 'User-Agent': 'Mozilla/5.0 (Linux; Android 9; Unspecified Device) AppleWebKit/537.36 (KHTML, like Gecko) ' + 'Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 miHoYoBBS/2.3.0', + 'x-rpc-client_type': mihoyobbs_Client_type_web, + 'Referer': '', + 'Accept-Encoding': 'gzip, deflate', + 'Accept-Language': 'zh-CN,en-US;q=0.8', + 'X-Requested-With': 'com.mihoyo.hyperion', + "Cookie": "", + 'x-rpc-device_id': "" +} -# 原神自动签到相关的设置 -genshin_Act_id = "e202009291139501" -genshin_Account_info_url = "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn" -genshin_Signlisturl = "https://api-takumi.mihoyo.com/event/bbs_sign_reward/home?act_id={}" -genshin_Is_signurl = "https://api-takumi.mihoyo.com/event/bbs_sign_reward/info?act_id={}®ion={}&uid={}" -genshin_Signurl = "https://api-takumi.mihoyo.com/event/bbs_sign_reward/sign" +# 通用设置 +bbs_Api = "https://bbs-api.mihoyo.com" +web_Api = "https://api-takumi.mihoyo.com" +account_Info_url = web_Api + "/binding/api/getUserGameRolesByCookie?game_biz=" + +# 米游社的API列表 +bbs_Cookie_url = "https://webapi.account.mihoyo.com/Api/cookie_accountinfo_by_loginticket?login_ticket={}" +bbs_Cookie_url2 = web_Api + "/auth/api/getMultiTokenByLoginTicket?login_ticket={}&token_types=3&uid={}" +bbs_Tasks_list = bbs_Api + "/apihub/sapi/getUserMissionsState" # 获取任务列表 +bbs_Sign_url = bbs_Api + "/apihub/sapi/signIn?gids={}" # post +bbs_List_url = bbs_Api + "/post/api/getForumPostList?forum_id={}&is_good=false&is_hot=false&page_size=20&sort_type=1" +bbs_Detail_url = bbs_Api + "/post/api/getPostFull?post_id={}" +bbs_Share_url = bbs_Api + "/apihub/api/getShareConf?entity_id={}&entity_type=1" +bbs_Like_url = bbs_Api + "/apihub/sapi/upvotePost" # post json + +# 崩坏2自动签到相关的相关设置 +honkai2_Act_id = "e202203291431091" +honkai2_checkin_rewards = f'{web_Api}/event/luna/home?lang=zh-cn&act_id={honkai2_Act_id}' +honkai2_Is_signurl = web_Api + "/event/luna/info?lang=zh-cn&act_id={}®ion={}&uid={}" +honkai2_Sign_url = web_Api + "/event/luna/sign" # 崩坏3自动签到相关的设置 honkai3rd_Act_id = "ea20211026151532" -honkai3rd_Account_info_url = "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=bh3_cn" -honkai3rd_Is_signurl = "https://api-takumi.mihoyo.com/common/eutheniav2/index?act_id={}®ion={}&uid={}" -honkai3rd_SignUrl = "https://api-takumi.mihoyo.com/common/eutheniav2/sign" +honkai3rd_Is_signurl = web_Api + "/common/eutheniav2/index?act_id={}®ion={}&uid={}" +honkai3rd_SignUrl = web_Api + "/common/eutheniav2/sign" + +# 原神自动签到相关的设置 +genshin_Act_id = "e202009291139501" +genshin_checkin_rewards = f'{web_Api}/event/bbs_sign_reward/home?act_id={genshin_Act_id}' +genshin_Is_signurl = web_Api + "/event/bbs_sign_reward/info?act_id={}®ion={}&uid={}" +genshin_Signurl = web_Api + "/event/bbs_sign_reward/sign" diff --git a/tools.py b/tools.py index c8e5f03..4709089 100644 --- a/tools.py +++ b/tools.py @@ -41,7 +41,7 @@ def get_ds(web: bool, web_old: bool) -> str: # 生成一个device id def get_device_id() -> str: - return str(uuid.uuid3(uuid.NAMESPACE_URL, config.mihoyobbs_Cookies)).replace( + return str(uuid.uuid3(uuid.NAMESPACE_URL, config.config["account"]["cookie"])).replace( '-', '').upper() @@ -53,10 +53,10 @@ def get_item(raw_data: dict) -> str: # 获取明天早晨0点的时间戳 -def nextday() -> int: +def next_day() -> int: now_time = int(time.time()) - nextday_time = now_time - now_time % 86400 + time.timezone + 86400 - return nextday_time + next_day_time = now_time - now_time % 86400 + time.timezone + 86400 + return next_day_time # 获取Openssl版本