离线经验、多端升级与防作弊 v0.8.1#
2026-09-13 · 设计态。目标是让离线努力可恢复、多端不重复领奖,并让公开竞榜具有更强证据。SQLite保存账号、进度和成绩权威;Redis仅用于每日榜单缓存及官方录像TTL存储;个人录像仍仅本机。
1. 经验是一份账本,等级是计算结果#
玩家体验:断网仍能看到成长和升级;联网后明确看到哪些成果已同步。不要要求玩家因为服务器暂时不可用而停止普通单人游戏。
三个数值分开:confirmed_xp_units 为服务器已入账经验;pending_xp_units 为本机待确认事实推算的净奖励;display_xp_units = confirmed_xp_units + pending_xp_units(遵守现有容量)。这里的 confirmed 仅表示入账,不等于反作弊认证。每条奖励另带 client_reported / server_validated / legacy_import / server_adjustment 来源。
服务器不接收 set_total_xp、add_xp、set_level。客户端上传稳定对局身份、规则版本、终局事实和必要的续局状态;服务端按该局规则计算奖励,用 reward_ledger 记录实际增量。个人录像/录制事件不随这些事实上传。
经验用整数百分之一单位保存,100 units = 1 XP。沿用 core/progression.js 当前20档门槛,不新增成长曲线:
XP门槛 = [0,600,1600,3000,5000,8000,12000,18000,26000,36000,
50000,70000,96000,130000,170000,220000,280000,360000,460000,600000]
level(XP) = 1 + max{i | XP >= XP门槛[i]},i从0开始本机按预计经验立即显示“预计军衔,待同步”;云端升级按入账总额重新推导。等级不独立同步、不取两台设备等级最大值。当前游戏开局时冻结生命值:军衔1–2为1格、3–7为2格、8起3格;同步升级不在局中加血或复活。下次普通本地开局可用本机预计军衔,正式每日开局只读取服务端已入账军衔。
2. 多端离线的确定性合并#
| 输入情形 | 合并规则 | 纸面结果 |
|---|---|---|
| 云端1000 XP,A独立完成初级+50,B独立完成中级+200 | 不同run,两条事实都入账 | 1250 XP;不能用max得到1200,也不能把两端总额相加得到2250 |
| 云端1500 XP,A+50,B+200 | 两事件各结算一次 | 1750 XP,跨过1600门槛升到第3档,下次开局2格生命 |
| A/B复制同一存档,各自完成 | 保留原run_id/origin_id,终局只结算一次 | 同内容返回重复;不同内容返回冲突,两份存档保留供选择,不创造第二份奖励 |
| 两台设备都完成同日同档每日 | (user_id,date,tier)串行补差,首通权益只一次 | 初级首通总权益144 XP;不会得288 |
| 已领每日失败进度6 XP,之后首通144 XP | 只补差 | 本次+138;另一设备再首通+0 |
| 网络重试、重装后旧队列重发 | op_id去重+run/origin业务去重 | 已入账事件不再加经验,即使请求ID改变 |
| 旧版本只有两份总经验,无法识别共同来源 | 迁移预览采用保守max并拆分可证明的每日权益 | 不把可能重叠的旧基线相加;能确认独立的新事件另计 |
普通初/中/高基础奖励50/200/600 XP;每日初/中/高首通基础144/540/1320 XP来自当前规则(不含另行封顶的分数奖励)。这些是现有值,不是本次新设经济参数。首次结算以服务器事务顺序为准,不根据设备自行填写的时间抢“先完成”。
日奖励本地预测也要去重:同一设备离线连续失败和首通,按日期权益当前预计已领额度计算净增量,不能把每次失败目标与完整首通额累加。服务器已从另一设备发过权益后,本机未确认首通的预计净增量变为0。
3. 联网恢复协议#
- 每次本地结算,在同一 IndexedDB 事务保存结果和 outbox。新局生成一次随机 run_id;续局/复制分支/导出导入都保留 origin_id,不能为同一局换身份。同步账号切换时不把旧账号队列发送给新账号。
- 恢复网络先核对账号、规则版本与服务器时间,再 bootstrap/pull。同步状态同时包含 summary版本、日权益、已结算run标识;新基线到达但本地操作尚未获得回执时,暂列“同步确认中”,不能把可能已含在基线中的奖励重复叠加。
- 上传事实。服务端事务内先查 op 回执和 run/origin,再插入唯一终局、奖励账本、日权益、summary、增量日志和回执;全部提交才ACK。耗时校验在事务外,事务内复核版本与归属。
- 客户端用
summary.version应用较新基线;用op_id/run_id/award_key确认待发事实,并按更新后的每日权益重算剩余预测。同一效果出现在push回执和pull中只应用一次。不得执行“设置新总额后,再加回执中的delta”。 - 单次push不是pull游标,不能跳过另一设备的变更。游标过期先重建快照,待发操作保留并逐条查询/重投取得业务回执。
可验证不变量:对同一组有效且独立的新对局,A先同步或B先同步,总经验相同;重复上报不会改变总经验;同一日权益不超过规则上限。互相矛盾的同一run终局以首个已提交合法终局为准并显示冲突,不能宣称这种矛盾集合也与顺序无关。
离线可产生多个本地升级动画;云端若发现重复每日、非法事实或旧规则不支持,展示具体“已在另一设备领取/待更新验证/结果冲突”。仅删除无效预测、不静默删玩家存档。若服务器已有非法奖励被复核撤销,以新的补偿账目记录原因,不能改写历史账本。
4. 每日离线与经验的关系#
- 今天的题由服务器统一生成、验证并在线裁决;未下载或服务器没有合格题时,客户端不能自己补一道“今天的每日”。经典、自定义、已安装关卡可离线。
- 已结束日期的题可从服务器下载历史练习包,缓存后离线玩,按原日期记录私人进度。首次完成的原每日权益仍可按现有补差规则同步,重复不重领;历史练习永不补排名、永不形成今天的观看资格。
- 今天的在线每日断线后停操作,服务端计时不暂停;原连接/epoch恢复后从权威状态继续。不能离线操作一段再补回正式比赛。若已跨日,旧局只能继续普通通关,无法入榜。
- 服务器确认的每日结果用稳定桥接run写同一日奖励账本;与历史离线结果共享同一个
(user,date,tier)权益。榜单/录像本身不额外加经验。
5. 分层防作弊与不能保证的事情#
| 攻击或风险 | 机制 | 实际保证及局限 |
|---|---|---|
| 改客户端总经验/军衔 | 拒绝数值写入;服务器按规则重算并记账 | 能拒绝直接改总额;不能证明无录像的离线过程真实发生 |
| 重复提交、复制存档刷同一奖励 | op/run/origin唯一键,日权益补差,事务原子性 | 可阻止相同身份重领;恶意不断伪造全新run_id仍需风控,不能声称已消除 |
| 改本机日期、计时器、暂停加速 | 正式局由服务器单调时钟计时,UTC日期由服务器判定;历史局不入榜 | 本机时间不影响正式成绩;网络RTT会影响实时操作体验,需实测并展示网络状态 |
| 偷读雷阵、客户端发明题目 | 当日私有地图/种子只存服务端;公开目录和投影白名单;不因失败揭全图 | 减少直接读内存答案;固定题反复练习、其他账号探图仍能记忆题目 |
| 伪造低用时骗入榜 | 成绩引用本人已结算服务器attempt,先比较,证据重演后再次比较 | 未核验候选不占名额;客户自己填的total_ms不可信 |
| 伪造/裁剪/拼接录像 | 官方压缩记录绑定date/tier/map/rules/attempt;逐事件重演并校验服务器记录的哈希链与终局 | 验证过程与在线确认一致;合法输入序列也可能由机器人产生 |
| 两设备并行控制同一正式局 | 一个账号一个活动正式局,device/epoch/seq检查,接管显式确认 | 阻止旧控制流继续写;不能可靠识别一人多号 |
| 看当天答案后刷新纪录 | 当前日三档通关门槛+明确观看提示+服务端曝光屏障/日期锁 | 防官方接口绕过;无法阻止他人屏幕、小号转述、场外录屏 |
| 压缩炸弹/超大录像/上传耗尽资源 | 仅候选签发归属绑定的上传授权;压缩/展开字节、事件数、CPU、并发配额全受限 | 拒绝资源滥用;参数需要真实录像与负载测试 |
| 自动求解/脚本/代打 | 异常用时与行为模式、相似输入序列、批量账号关联作为复核信号 | 概率风控,不能凭“太快”、同IP、规则化键盘输入直接封号 |
SHA-256用于完整性;若没有服务器已保存的哈希链/秘密签名,攻击者可连数据带hash一起重算。客户端内嵌密钥、代码混淆、本地时间签名都不能把普通Web变成可信执行环境。
两种信任域:私人离线成长允许 client_reported;公开成绩只接受服务器裁决并有完整候选录像验证的正式过程。已入账离线经验即使影响正式开局血量,Top10仍要求全程零踩雷/零失血,不能靠额外生命把有伤段改成无伤;重复练习优势依然存在。未来若加入交易、货币价值或竞技成长,需重新设计专用在线验证成长,不能直接复用私人XP。
复核只凭足够证据处置,保留原因和申诉渠道。当日有效榜可按已验证候补重算;日切后只能给原名次加“成绩取消/录像移除”注记,不能改时长、调顺序或递补。平台停机、网络慢和玩家作弊必须区分。
6. 失败标准与待测参数#
任何重复入账、账号串档、未核验入榜、截止后补榜、历史观看错误锁住今日,均属发布阻断问题。私人录像在任何cloud snapshot/export/log中出现同样阻断发布。
本地检查点5秒、前台私人同步30秒为沿用初值 [待测试],用于控制丢进度窗口与请求量,结算必须即时写本地事务。压缩/负载/在线挑战参数见多人API。本文件的合并示例是纸面推演;需要真实同步服务的乱序、并发、崩溃、账号切换测试,不能用DDL检查替代。
7. 变更记录#
| 版本 | 日期 | 变化 |
|---|---|---|
| 0.8.1 | 2026-09-13 | 收紧录像大小/事件上限;双hash上传前去重;补流式拒收、配额、慢连接及验证资源保护 |
| 0.8.0 | 2026-09-13 | Redis限每日榜单缓存与官方录像TTL存储;录像正文移出SQLite,不设录像到期清理job;补跨库故障与持久化边界 |
| 0.7.0 | 2026-09-13 | 移除直播入口/协议/三张专用表;观看仅限每日公榜录像,保留四榜与私人同步;整理审阅范围 |
| 0.6.0 | 2026-09-13 | 初中高与综合四榜独立;单项1段/综合3段,录像共享、统一冻结、跨端分段提交;48项DDL检查通过 |
| 0.5.0 | 2026-09-13 | 明确多端离线经验/升级/预测对账、日权益补差、双信任域与防作弊局限 |