commit 9f9d0a3519b358610bf49225fde34c1c14a69d09 Author: GamerNoTitle Date: Sat Dec 7 20:02:40 2024 +0800 init: initialize the repo diff --git a/.github/workflows/AutoCheckin.yml.disabled b/.github/workflows/AutoCheckin.yml.disabled new file mode 100644 index 0000000..83c5adb --- /dev/null +++ b/.github/workflows/AutoCheckin.yml.disabled @@ -0,0 +1,35 @@ +name: AutoCheckin + +on: + workflow_dispatch: + release: + types: [published] + push: + tags: + - 'v*' + # branches: + # - master + schedule: + - cron: "0 2 * * *" + watch: + types: [started] + +jobs: + build: + runs-on: ubuntu-latest + # if: github.event.repository.owner.id == github.event.sender.id # 自己点的 start + steps: + - name: Checkout + uses: actions/checkout@master + - name: Set up Python #安装python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + - name: Install requirements #安装轮子 + run: | + pip install -r requirements.txt + - name: Run script + env: + MHYY_CONFIG: ${{ secrets.MHYY_SECRET }} + run: | + python3 main.py \ No newline at end of file diff --git a/.github/workflows/KeepActionAlive.yml.disabled b/.github/workflows/KeepActionAlive.yml.disabled new file mode 100644 index 0000000..03d2b8b --- /dev/null +++ b/.github/workflows/KeepActionAlive.yml.disabled @@ -0,0 +1,32 @@ +name: 'KeepActionAlive' + +on: + workflow_dispatch: + schedule: + - cron: '0 0 1 * *' + +jobs: + auto_renew: + runs-on: ubuntu-latest + steps: + - name: 'Checkout codes' + uses: actions/checkout@v2 + + - name: 'Avoid Github Workflow being suspended' + run: echo $(cat /proc/sys/kernel/random/uuid) > UUID.txt + + - name: 'Commit Files' + id: commit + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git diff --quiet && git diff --staged --quiet || git commit -am '是否继续白嫖:[是] —— 继续白嫖成功!' + echo ::set-output name=status::success + + - name: 'GitHub Push' + if: steps.commit.output.status != 'success' + uses: ad-m/github-push-action@v0.6.0 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.ref }} \ No newline at end of file diff --git a/.github/workflows/MirrorSync.yml b/.github/workflows/MirrorSync.yml new file mode 100644 index 0000000..cb002ca --- /dev/null +++ b/.github/workflows/MirrorSync.yml @@ -0,0 +1,20 @@ +name: "SyncMirror" + +on: + workflow_dispatch: + push: + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - name: "Checkout codes" + uses: actions/checkout@v2 + + - name: "Sync" + id: commit + run: | + git fetch --unshallow + git checkout master + git remote add gitea https://${{ secrets.GITEA_USERNAME }}:${{ secrets.GITEA_PASSWORD }}@git.bili33.top/GamerNoTitle/ZZZCloud-AutoCheckin.git + git push gitea master diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/README.md b/README.md new file mode 100644 index 0000000..31d2cd9 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +# ZZZCloud-AutoCheckin + +![ZZZCloud-AutoCheckin](https://socialify.git.ci/GamerNoTitle/ZZZCloud-AutoCheckin/image?forks=1&language=1&name=1&owner=1&stargazers=1&theme=Light) + +云·绝区零自动签到脚本 + +**⚠️请不要进行宣传,谢谢!一旦发现宣传就删库跑路!** + +**要用Action跑请不要点Fork,点Use this template后在自己的号下创建一个仓库来跑,用Fork跑的时间会积累到本仓库,会导致本仓库被封!!!** + +这是一个可以帮助你每天自动进行米忽悠云绝区零签到的脚本,自动获取每日的15分钟(600分钟后无法获取,这是米忽悠定下的规矩,无法突破) + +## 快速开始 + +请参阅[文档](#)进行配置,有问题请在issue中提出。 + +如果本仓库被封了就来这里找https://git.bili33.top/GamerNoTitle/ZZZCloud-AutoCheckin + +**要是真的不会用就别不好意思开issue问啦,我在Sentry的后台看到了一堆不知道怎么形容的Bug** + +## 赞助 +点击下面的Badge其中一个就可以跳转到相应页面,感谢老板的支持! + +前往爱发电赞助 使用微信赞助 使用支付宝赞助 + +## 免责声明 + +一旦你fork了本仓库则代表你同意以下内容: + +- 所有账号被封禁的情况由使用者自行承担 +- 一切由使用本脚本造成的后果由使用者自行承担 + +## Stargazers over time + +[![Stargazers over time](https://starchart.cc/GamerNoTitle/MHYY.svg)](https://starchart.cc/GamerNoTitle/MHYY) \ No newline at end of file diff --git a/config.example.yml b/config.example.yml new file mode 100644 index 0000000..fb3891a --- /dev/null +++ b/config.example.yml @@ -0,0 +1,23 @@ +# 使用前请阅读文档:https://bili33.top/posts/ZZZCloud-AutoCheckin-Manual-Gen2/ +# 有问题请前往Github开启issue:https://github.com/GamerNoTitle/ZZZCloud-AutoCheckin/issues + +######## 以下为账号配置项,可以多账号,详情请参考文档 ######## +accounts: + # 第一个账号 + - token: + # 关于type:如果你在安卓版的云·绝区零里面抓的话type应该是2 + # 此处仅供参考,具体以你抓的为准 + type: + # sysver:安卓版本(鸿蒙不清楚,手上没设备) + sysver: + # deviceid:抓到什么填什么 + deviceid: + # devicename: 手机抓的话就是手机的入网型号,如红米K40为M2012K11AC,红米K50为22021211RC + devicename: + # devicemodel: 手机抓的填抓出来的手机型号,大概为手机厂商+上面的deviceid,如红米K40为Xiaomi M2012K11AC + devicemodel: + # appid: 默认填9000357,如果你的不一样按照你的填 + appid: + # region(可选): 账号所处的地区,国服填cn,国际服填os,不填或非法值按国服处理 + # 目前没用!!!没做外服!!! + region: cn diff --git a/main.py b/main.py new file mode 100644 index 0000000..96a8109 --- /dev/null +++ b/main.py @@ -0,0 +1,210 @@ +import httpx +import json +import os +import re +import sentry_sdk +import random +import time +import yaml +import logging + +if os.environ.get("ZZZCLOUD_LOGLEVEL", "").upper() == "DEBUG": + loglevel = logging.DEBUG +elif os.environ.get("ZZZCLOUD_LOGLEVEL", "").upper() == "WARNING": + loglevel = logging.WARNING +elif os.environ.get("ZZZCLOUD_LOGLEVEL", "").upper() == "ERROR": + loglevel = logging.ERROR +else: + loglevel = logging.INFO + +# 设置日志配置 +logging.basicConfig( + level=loglevel, + format="%(asctime)s [%(levelname)s]: %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", +) + +logger = logging.getLogger() + + +def ReadConf(variable_name, default_value=None): + # Try to get the variable from the environment + env_value = os.environ.get(variable_name) + + if env_value: + config_data = yaml.load(env_value, Loader=yaml.FullLoader) + return config_data + + # If not found in environment, try to read from config.yml + try: + with open("config.yml", "r", encoding="utf-8") as config_file: + config_data = yaml.load(config_file, Loader=yaml.FullLoader) + return config_data + except FileNotFoundError: + return default_value + + +sentry_sdk.init( + "https://379c1d210fc6ea113172c5444297a646@o361988.ingest.us.sentry.io/4508426724966400", + traces_sample_rate=1.0, +) + +conf = ReadConf("ZZZCLOUD_CONFIG")["accounts"] + +if not conf: + logger.error("请正确配置环境变量或者config.yml后再运行本脚本!") + os._exit(0) +logger.info(f"检测到 {len(conf)} 个账号,正在进行任务……") + + +# Options +sct_status = os.environ.get("sct") # https://sct.ftqq.com/ +sct_key = os.environ.get("sct_key") +sct_url = f"https://sctapi.ftqq.com/{sct_key}.send?title=ZZZCloud-AutoCheckin 自动推送" + +sct_msg = "" + + +class RunError(Exception): + pass + + +if __name__ == "__main__": + if not os.environ.get("ZZZCLOUD_DEBUG", False): + wait_time = random.randint(10, 60) # Random Sleep to Avoid Ban + logger.info(f"为了避免同一时间签到人数太多导致被官方怀疑,开始休眠 {wait_time} 秒") + time.sleep(wait_time) + try: + ver_info = httpx.get( + "https://hyp-api.mihoyo.com/hyp/hyp-connect/api/getGameBranches?game_ids[]=x6znKlJ0xK&launcher_id=jGHBHlcOq1", + timeout=60, + verify=False, + ).text + version = json.loads(ver_info)["data"]["game_branches"][0]["main"]["tag"] + logger.info(f"从官方API获取到云·绝区零最新版本号:{version}") + except Exception as e: + version = "1.3.0" + logger.warning(f"获取版本号失败,使用默认版本:{version}") + + for config in conf: + # 各种API的URL + LoginURL = "https://cg-nap-api.mihoyo.com/nap_cn/cg/gamer/api/login" + NotificationURL = "https://cg-nap-api.mihoyo.com/nap_cn/cg/gamer/api/listNotifications?status=NotificationStatusUnread&type=NotificationTypePopup&is_sort=true" + WalletURL = "https://cg-nap-api.mihoyo.com/nap_cn/cg/wallet/wallet/get" + AnnouncementURL = ( + "https://cg-nap-api.mihoyo.com/nap_cn/cg/gamer/api/getAnnouncementInfo" + ) + + if config == "": + # Verify config + raise RunError( + f"请在Settings->Secrets->Actions页面中新建名为config的变量,并将你的配置填入后再运行!" + ) + else: + token = config["token"] + client_type = config["type"] + sysver = config["sysver"] + deviceid = config["deviceid"] + devicename = config["devicename"] + devicemodel = config["devicemodel"] + appid = config["appid"] + headers = { + "x-rpc-combo_token": token, + "x-rpc-client_type": str(client_type), + "x-rpc-app_version": str(version), + "x-rpc-sys_version": str(sysver), + "x-rpc-channel": "oosnsdyu_C", + "x-rpc-device_id": deviceid, + "x-rpc-device_name": devicename, + "x-rpc-device_model": devicemodel, + "x-rpc-vendor_id": "2", + "x-rpc-cg_game_biz": "nap_cn", + "x-rpc-op_biz": "clgm_nap-cn", + "x-rpc-language": "zh-cn", + "Host": "cg-nap-api.mihoyo.com", + "Connection": "Keep-Alive", + "Accept-Encoding": "gzip", + "User-Agent": "okhttp/4.10.0", + } + bbsid = re.findall(r"oi=[0-9]+", token)[0].replace("oi=", "") + + logger.info( + f"正在进行第 {conf.index(config) + 1} 个账号……" + ) + try: + + wallet = httpx.get(WalletURL, headers=headers, timeout=60, verify=False) + logger.debug(wallet.text) + if json.loads(wallet.text) == { + "data": None, + "message": "登录已失效,请重新登录", + "retcode": -100, + }: + logger.error(f"当前登录已过期,请重新登陆!返回为:{wallet.text}") + sct_msg += f"当前登录已过期,请重新登陆!返回为:{wallet.text}" + else: + logger.info( + f"你当前拥有免费时长 {json.loads(wallet.text)['data']['free_time']['free_time']} 分钟,畅玩卡状态为 {json.loads(wallet.text)['data']['play_card']['short_msg']},拥有邦邦点 {json.loads(wallet.text)['data']['coin']['coin_num']} 点({int(json.loads(wallet.text)['data']['coin']['coin_num'])/10}分钟)" + ) + sct_msg += f"你当前拥有免费时长 {json.loads(wallet.text)['data']['free_time']['free_time']} 分钟,畅玩卡状态为 {json.loads(wallet.text)['data']['play_card']['short_msg']},拥有邦邦点 {json.loads(wallet.text)['data']['coin']['coin_num']} 点({int(json.loads(wallet.text)['data']['coin']['coin_num'])/10}分钟)" + announcement = httpx.get( + AnnouncementURL, headers=headers, timeout=60, verify=False + ) + logger.debug(f'获取到公告列表:{json.loads(announcement.text)["data"]}') + res = httpx.get( + NotificationURL, headers=headers, timeout=60, verify=False + ) + success, Signed = False, False + logger.debug(res.text) + try: + if list(json.loads(res.text)["data"]["list"]) == []: + success = True + Signed = True + Over = False + elif ( + json.loads(json.loads(res.text)["data"]["list"][-1]["msg"])[ + "msg" + ] + == "每日登录奖励" + ): + success = True + Signed = False + Over = False + elif ( + json.loads(json.loads(res.text)["data"]["list"][-1]["msg"])[ + "over_num" + ] + > 0 + ): + success = True + Signed = False + Over = True + else: + success = False + except IndexError: + success = False + if success: + if Signed: + logger.info(f"获取签到情况成功!今天是否已经签到过了呢?") + sct_msg += f"获取签到情况成功!今天是否已经签到过了呢?" + logger.debug(f"完整返回体为:{res.text}") + elif not Signed and Over: + logger.info( + f'获取签到情况成功!当前免费时长已经达到上限!签到情况为{json.loads(res.text)["data"]["list"][0]["msg"]}' + ) + sct_msg += f"获取签到情况成功!当前免费时长已经达到上限!签到情况为{json.loads(res.text)['data']['list'][0]['msg']}" + else: + logger.info(f"已经签到过了!") + sct_msg += f"已经签到过了!" + else: + logger.info(f"当前没有签到!请稍后再试!") + sct_msg += f"当前没有签到!请稍后再试!" + if sct_key: + httpx.get(sct_url, params={"desp": sct_msg}) + except Exception as e: + logger.error(f"执行过程中出错:{str(e)}") + sct_msg += f"执行过程中出错:{str(e)}" + if sct_key: + httpx.get(sct_url, params={"desp": sct_msg}) + raise RunError(str(e)) + logger.info("所有任务已经执行完毕!") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..baa5928 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +httpx +sentry-sdk +pyyaml \ No newline at end of file