-
Notifications
You must be signed in to change notification settings - Fork 0
AUTO CHECKIN
Moonward 支持米游社(国服)/ HoYoLAB(国际服)的每日签到活动奖励领取,覆盖原神、崩坏:星穹铁道、绝区零、崩坏3(各游戏国服 / 国际服,以及 B 服与国服签到活动的映射)。在手动签到之外,还提供按游戏独立开关的自动签到:主程序启动后静默批量处理;通过桌面快捷方式、URL 协议或命令行按指定账号启动游戏时,也会对该账号顺带签到。
说明:自动签到依赖已登录的战绩 Cookie,且仅在对应游戏开启开关后生效。功能默认关闭。触发风控、登录失效等情况时,自动流程会静默跳过或冷却,需用户在界面手动处理。
- 在 米游社工具箱 / HoYoLAB 工具箱 中登录账号,并确保能拉取到对应游戏的游戏角色(
GameRecordRole)。 - 首页能看到当前游戏的签到入口(按游戏显示不同图标)。若该游戏未支持签到、或本地没有可用角色,入口会隐藏。
- Cookie 需保持有效;过期后需重新登录。国服在部分场景下会尝试用
stoken静默刷新 Cookie。
- 在启动页点击签到图标,打开签到卡片。
- 卡片展示:
- 当前角色头像、昵称、区服、UID
- 本月累计签到天数、今日是否已签
- 本月奖励日历(7 列网格;已领取天数有遮罩与对勾)
- 点击 签到 领取今日奖励;补签 会先确认消耗补签货币后再请求。
- 可随时点刷新图标重新拉取状态。
- 在签到卡片底部找到 自动签到 开关(旁有提示图标)。
- 按游戏独立开关:例如原神国服与星铁国服互不影响;切换游戏时开关状态会跟当前游戏走。
- 打开后会提示 「软件下次启动生效」——批量自动签到不会在你刚打开开关的那一刻立刻跑,而是等主界面下次完整启动后执行。
提示文案要点:
- 每个游戏的自动签到相互独立
- 开启后,通过指定登录账号的快捷方式启动游戏时,会单独给该账号签到
| 场景 | 行为 |
|---|---|
| 主程序正常启动并进入主界面 | 约 10 秒后,对所有「已支持签到 + 已开启自动签到」的本地游戏角色静默批量签到(按 Cookie/角色依次请求,请求间随机间隔) |
moonward://startgame/... URL 启动游戏 |
游戏启动成功后,若解析到绑定/指定的登录 UID,且该游戏已开自动签到,则仅对该 UID 静默签一次(不经主界面批量任务) |
命令行 startgame --biz ... 启动 |
同上:启动成功且能解析到登录 UID 时,对该账号静默签一次 |
| 桌面快捷方式 / 启动配置绑定了登录账号 | 本质走 URL 或等价启动路径;解析到 UID 后走「启动时单账号签到」 |
不会在「仅切换当前游戏 Tab」时触发自动签到;批量任务统一挂在主界面启动后。
- 静默:成功 / 已签 / 失败均不弹成功 Toast;细节写在日志中。
- 天然去重:先查服务端「今日是否已签」;已签则跳过,不会重复 POST。
- 失败冷却:某角色签到失败后约 10 分钟内不再对该角色重试,避免 Cookie 失效或风控时疯狂打接口。
- 节奏:批量任务请求之间随机间隔约 3–8 秒,减轻短时间高频请求风险。
- 单次启动只跑一轮批量任务;进程内重复调用会被忽略。
| 手动签到 | 自动签到 | |
|---|---|---|
| 入口 | 签到卡片按钮 | 开关 + 启动后后台任务 / 带账号启动 |
| 范围 | 当前展示的角色 | 批量:所有符合条件的角色;启动路径:解析到的单个 UID |
| 补签 | 支持(需确认) | 不包含补签,仅今日签到 |
| 失败反馈 | Toast / 统一 API 错误反馈,可引导重登或验证账号 | 只打日志;失败进入冷却 |
Q:开了自动签到为什么没立刻签?
A:开关对「下次主程序启动后的批量任务」生效;本次会话不会因打开开关立刻全量签到。若用快捷方式/URL 带账号启动,则走「单账号启动签到」路径。
Q:为什么某个号没签上?
可能原因包括:该游戏未开自动签到、本地没有该角色 Cookie、今日已签、处于失败冷却、Cookie 失效、触发风控需验证。可打开签到卡片手动刷新/签到,并检查工具箱登录状态。
Q:B 服怎么处理?
B 服(*_bilibili)与国服共用签到活动侧配置;开关与角色按映射后的国服 biz(如 hk4e_cn)管理。
Q:触发「需要验证」怎么办?
自动流程不会代打极验。请到米游社 / HoYoLAB 或应用内「验证账号」相关入口处理后再试。
实现严格按 GameRecord 功能分层(与 SignIn 模板一致):
DTO / 活动配置 → JsonContext → Client(CN/OS)
→ GameRecordService → SignInService
→ AutoSignInService → UI(SignInButton) / 启动路径
| 层 | 主要类型 / 路径 | 职责 |
|---|---|---|
| DTO / 配置 |
Starward.Core/GameRecord/SignIn/*、SignInActivityConfig
|
奖励、状态、补签信息、POST body、retcode;按游戏映射 act_id、主机、x-rpc-signgame、可选 Origin |
| JsonContext | GameRecordJsonContext |
源生成序列化注册 |
| Client |
GameRecordClient + HyperionClient / HoyolabClient
|
HTTP、Cookie、平台请求头、DS 签名差异;CommonSendAsync
|
| 门面 | GameRecordService |
选 CN/OS Client、设备指纹、请求恢复(Cookie 刷新等) |
| 业务 | SignInService |
状态聚合、奖励缓存、retcode → 结构化结果、风控判定 |
| 自动任务 | AutoSignInService |
开关读写、启动批量、启动时单账号签到、失败冷却、请求节奏 |
| UI |
SignInButton(挂在 GameLauncherPage) |
日历、手动签到/补签、自动开关、错误展示 |
| 能力开关 | GameFeatureConfig.SupportSignIn |
按 GameBiz 是否展示/允许签到 |
| 设置 / DI |
AppConfig.Get/SetAutoSignInEnabled、ServiceProvider
|
auto_sign_in_enabled_{biz};单例注册 SignInService / AutoSignInService
|
| 文案 | Lang.*.resx |
禁止硬编码用户可见字符串 |
SignInActivityConfig.FromGame(game, isOversea) 统一给出:
-
ActId:活动 ID(随版本可能轮换,改此文件即可) -
SignGame:x-rpc-signgame(如hk4e/hkrpg/zzz/bh3) -
BaseUrl:home/info/sign/resign/resign_info前缀 -
Origin:绝区零专用活动主机需要;其它游戏为 null
接口形态概要:
| 接口 | 方法 | 用途 |
|---|---|---|
home |
GET | 本月奖励列表 |
info |
GET | 已签天数、今日是否已签、服务器日期等 |
resign_info |
GET | 补签次数、货币消耗(部分活动可能无) |
sign |
POST | 今日签到 |
resign |
POST | 补签 |
POST body:act_id + region + uid(SignInPostBody)。
差异只在 Client 子类,不散落到 UI:
国服 HyperionClient
|
国际服 HoyolabClient
|
|
|---|---|---|
| 语言 | 签到语言固定 zh-cn
|
由客户端语言头体系决定 |
| DS 签名 | info/sign/resign 等需 DS(Gen1/LK2) |
签到路径不附加 DS |
| 公共头 | Referer(webstatic)、x-rpc-signgame、设备 id/fp、app version、client type |
Referer(act.hoyolab.com)、x-rpc-signgame、设备信息等 |
| Origin | 绝区零 act-nap-api 等需 Origin |
绝区零 sg-act-nap-api 对称需要 Origin |
| 设备指纹 | 签到前 PrepareSignInClientAsync 会 UpdateDeviceFpAsync
|
不走国服指纹更新 |
GameRecordService 在每次签到 API 前:IsHoyolab 按角色 GameBiz 切换,并走 ExecuteWithRequestRecoveryAsync(登录态恢复等)。
-
GetSignInStatusAsync:info+ 缓存的home奖励 + 可选resign_info(补签失败不影响主流程)。 -
奖励缓存:键
sign_in_reward_{gameBiz}_{yyyyMM};内存IMemoryCache+ SQLiteKVT双层;跨月或月份不一致则回源。 -
ClaimSignInAsync/ClaimReSignInAsync:捕获miHoYoApiException,映射为SignInActionResult:-
Success/AlreadySigned/CookieExpired/RiskControl - 补签相关:
NotEnoughCoin/ResignQuotaUsedUp/NoResignDate/PleaseSignInFirst - 其它 →
Failed
-
-
风控判定(不能只看
gt):success == 1或risk_code != 0或is_risk或gt/challenge非空。
已知 retcode 常量见 SignInReturnCode(如已签 -5003、未登录 -100 等)。
UI 侧通过 MiHoYoApiErrorFeedbackFactory + MiHoYoApiContext.SignIn 展示错误,禁止页面内硬编码 retcode 文案。
Setting 表 Key: auto_sign_in_enabled_{GameBiz}
默认: false
IsEnabled / SetEnabled 委托 AppConfig.Get/SetAutoSignInEnabled。
-
启动批量
- 入口:
MainView首次Loaded→Task.Run(() => AutoSignInService.RunStartupBatchAsync()) -
Interlocked.Exchange保证每个进程生命周期只执行一次 - 先
Delay(10s),再GetAllGameRoles(),过滤SupportSignIn,再按角色循环;循环内实时读IsEnabled(role.GameBiz)(用户中途关掉会跳过后续) - 角色顺序:
ORDER BY Cookie, GameBiz(同账号角色相邻) - 单角色异常只记日志,不中断整批
- 入口:
-
带账号启动游戏
-
UrlProtocolService(moonward://startgame/{biz}?profile=&uid=) -
StartGameStartupHandler(CLIstartgame) - 游戏进程启动成功后:
ResolveLoginUid→TrySignInForLaunchAccountAsync(biz, uid) - B 服映射到
*_cn再查开关与角色;找不到角色则 warning 后返回 - 单次签到不插入批量节奏延时
-
失败冷却中? → 直接 return
pace() → GetSignInInfoAsync
若 IsSign:清冷却标记,return
pace() → ClaimSignInAsync
Success / AlreadySigned:清冷却
其它:写入 last failure ticks(UTC)
失败冷却键:
auto_sign_in_last_failure_ticks_{GameBiz}_{Uid}
存 Setting 表;值为 0 表示无冷却。冷却窗口 10 分钟。
| 参数 | 值 | 作用 |
|---|---|---|
StartupBatchDelay |
10s | 错开启动高峰 |
MinRequestDelaySeconds |
3 | 请求间隔下限 |
MaxRequestDelaySeconds |
8 | 请求间隔上限(含) |
第一个网络请求不延时;之后每个请求前随机 sleep。pace 委托在 info 与 claim 前各调用一次,因此相邻角色之间也会被间隔拉开。
- 挂在启动页;
CurrentGameId变化时:Feature 门控、B 服→国服、同步自动开关、取「上次选中或首个」角色决定是否显示。 - Flyout 懒加载状态(首次打开才
GetSignInStatusAsync)。 - 手动签到/补签走
InAppToast;风控可跳「验证账号」;Cookie 失效走统一恢复动作(重登 / 验证)。 - 打开自动签到开关时立刻 Toast「软件下次启动生效」;不会在切换游戏时触发批量签到。
-
x:Bind属性须在 UI 线程赋值(与全项目约定一致)。
自动「启动时签到」依赖 GameLauncherService.ResolveLoginUid:
- URL/调用方显式
uid - 否则若启动方式为「无」→ 0(不签)
- 否则启动配置
LoginUid/ 默认配置绑定账号
因此:只有「能解析出有效登录 UID」的启动路径才会触发单账号自动签到;纯「无账号绑定」的启动不会走该分支。主界面批量签到不依赖启动配置,只依赖本地已同步的全部 GameRecordRole 与游戏开关。
[用户开自动签到] → Setting: auto_sign_in_enabled_{biz}=true
│
┌─────────────────────┴─────────────────────┐
▼ ▼
MainView.Loaded startgame URL / CLI
RunStartupBatchAsync TrySignInForLaunchAccountAsync
(10s delay, all roles) (single uid)
│ │
└──────────────────┬────────────────────────┘
▼
SignInRoleCoreAsync
│ │
GetSignInInfo ClaimSignIn
│ │
GameRecordService → Hyperion/Hoyolab Client
│
米游社 / HoYoLAB 签到 API
- 自动签到不提交极验;遇到风控只记结果并进入失败冷却。
- 批量节奏与冷却是对服务端限流/风控的软缓解,不能保证永不触发验证。
-
act_id/ 主机随活动轮换;失效时优先改SignInActivityConfig,勿在 UI 层写死 URL。 - Core 层禁止引用 WinUI;异常保留服务端原文,本地化只在 UI / Factory。
| 文件 | 说明 |
|---|---|
Features/GameRecord/SignIn/AutoSignInService.cs |
自动签到调度与冷却 |
Features/GameRecord/SignIn/SignInService.cs |
签到业务与结果映射 |
Features/GameRecord/SignIn/SignInButton.xaml(.cs) |
启动页签到 UI |
Features/ViewHost/MainView.xaml.cs |
启动批量入口 |
Features/UrlProtocol/UrlProtocolService.cs |
URL 启动后单账号签到 |
Features/Startup/StartGameStartupHandler.cs |
CLI 启动后单账号签到 |
Features/GameRecord/GameRecordService.cs |
签到 API 门面 |
Core/GameRecord/GameRecordClient.cs |
签到 HTTP 公共实现 |
Core/GameRecord/HyperionClient.cs / HoyolabClient.cs
|
平台请求头 |
Core/GameRecord/SignIn/SignInActivityConfig.cs |
act_id / 主机映射 |
AppConfig.Setting.cs |
auto_sign_in_enabled_{biz} |
Features/GameFeatureConfig.cs |
SupportSignIn |
每日签到在启动页卡片上完成手动领取与补签;自动签到按游戏独立开关,主程序启动后静默批量为所有已登录角色签到,并在通过快捷方式 / URL / 命令行按指定账号启动游戏时顺带为该账号签到。实现上通过「服务端已签状态 + 失败冷却 + 随机请求间隔」控制幂等与频率,CN/OS 差异收敛在 Client,业务结果与风控在 SignInService 统一建模,UI 与启动路径只消费结构化结果。