Initial import of HEROLL source and design documents

This commit is contained in:
toshiocn
2026-10-26 16:05:39 +08:00
commit fdb55672c1
1846 changed files with 290692 additions and 0 deletions
@@ -0,0 +1,196 @@
# HEROLL 2.0.1 掉落规则逆向报告
> 样本:`com.percent.aos.rollinghero`,versionName `2.0.1`,versionCode `113296145`
> 原始 XAPK SHA-256:`439D532704AFCCDBEBA8C01AF7869552387CDE31651963D0A45541F252B94E2F`
> 结论等级:**确认**=配置或 Native 正文直接证明;**高置信推导**=多项独立证据闭合;**未知**=不得用于原作还原。
## 1. 核心结论
HEROLL 的局内装备生成不是一次抽完,而是至少拆成四步:
1. 从 `WeaponDrop` 的 40 条局内装备中随机选装备身份。
2. 以六档相对权重生成品质,并叠加 Joker/局内效果及圈数相关修正。
3. 另行生成 `loopGrade` 与随机属性。
4. 检查封印等后处理,生成装备槽;槽满时先进入回收路径。
基础品质权重为:
`NORMAL : RARE : EPIC : LEGEND : MYTH : ARCANE = 210 : 60 : 28 : 4 : 1 : 4`
这些数值是**相对权重,不是百分比**。未激活任何动态修正时,总权重为 307,基线概率如下:
| 品质 | 权重 | 基线概率 |
|---|---:|---:|
| NORMAL | 210 | 68.4039% |
| RARE | 60 | 19.5440% |
| EPIC | 28 | 9.1205% |
| LEGEND | 4 | 1.3029% |
| MYTH | 1 | 0.3257% |
| ARCANE | 4 | 1.3029% |
`ARCANE` 的基础权重确实高于 `MYTH`;这是样本原值,不能为了“看起来合理”而改写。
## 2. Native 生成链
### 2.1 装备身份
`BattleController.GetMonoWeaponData`(VA `0x55BDCC0`)读取 `WeaponDrop` 表的总行数,以随机整数索引取一条,再写入 `weaponStringId`。
`weapondrop.csv` 正好有 40 条数据:
| 槽位类型 | 数量 | 基础身份概率 |
|---|---:|---:|
| Ingame_Weapon | 10 | 25%(单件 2.5%) |
| Ingame_Ring | 10 | 25%(单件 2.5%) |
| Ingame_Gauntlet | 10 | 25%(单件 2.5%) |
| Ingame_Boots | 10 | 25%(单件 2.5%) |
该等概率结论仅适用于走基础 `GetMonoWeaponData` 随机重载的奖励。`SpawnFixWeapon`、`SpawnTypeWeapon` 及其他带筛选参数的入口可以固定身份或限制类型,不能套用 2.5%。
### 2.2 品质
`BattleController.GetEWeaponGrade`(VA `0x55BDE8C`)执行以下流程:
```text
weights = [210, 60, 28, 4, 1, 4]
for gradeIndex in 0..5:
weights[gradeIndex] *= JokerEffectController.GetWeaponProbMultiplier(gradeIndex)
apply_loop_or_grade_related_modifiers(weights)
if excludeNormal:
weights[0] = 0
gradeIndex = Utils.GetRatioPercent(weights)
```
`Utils.GetRatioPercent` 是加权选择器,因此最终概率为 `修正后本档权重 / 修正后总权重`。
当调用入口设置 `excludeNormal=true` 且没有其他修正时,归一化结果为:RARE 61.8557%、EPIC 28.8660%、LEGEND 4.1237%、MYTH 1.0309%、ARCANE 4.1237%。这不是普通掉落率,只是该特殊分支的数学基线。
### 2.3 `loopGrade`、属性与后处理
`BattleController.GetWeaponLoop`(VA `0x55BE240`)另建一个三项权重列表,经 `Utils.GetRatioPercent` 抽取并叠加圈数/品质相关值。它不是六档品质抽取。
随后 `GetMonoWeaponData` 继续生成状态值、检查封印并写入 `MonoWeaponData`。随机装备协程的已闭合调用链为:
```text
CheckFullSlotRecycleFirstExtra
-> GetMonoWeaponData
-> MonoWeaponSlot.Spawn
-> AddWeaponRewardForEventLog
-> HandleJokerWeaponSpawnPostProcess
```
因此以下行为已确认:
- 满槽会在生成前进入回收处理。
- Joker 不只修正品质权重,装备生成后还有独立后处理。
- `GetWeaponDropDestroyChance` 表明某些 Joker 效果可令掉落销毁;具体活动值取决于当前效果状态。
## 3. 掉落“出现机会”与“掉落品质”必须分开
`ingameWeaponDropRatio` 只证明**已经进入装备生成时的品质分布**,不等于“每只敌人有多少概率掉装备”。
当前静态证据能确认多个系统会调用随机、固定或类型限定装备生成接口,包括战斗相关奖励、宝箱/事件、碎片交互、小游戏和特殊祝福效果。但 APK 中没有发现一个可直接解释为“所有普通敌人的统一装备掉率”的全局配置。
两个启用的祝福配置会改变装备出现机会:
| ID | StringId | 关键配置 | 可确认内容 | 尚未确认内容 |
|---:|---|---|---|---|
| 124 | KillInTimeGetGear | `timeValue=2.5` | 祝福启用,名称指向限时击杀装备奖励 | 2.5 的精确单位、触发对象及是否必掉 |
| 132 | KillForHeroGear | `Value=10` | 祝福启用,名称指向击杀换高品质装备 | “10”的计数/概率语义及品质下限 |
仅凭 StringId 不足以把这两项写成确定公式;需要继续闭合祝福消费者 Native 正文或做指定种子的动态采样。
## 4. 局内非装备奖励表
`ingamereward.csv` 配置了以下节点:
| 时机 | 奖励 | 配置 |
|---|---|---|
| `killStrong` | 钻石(item 101) | 数量 0、概率 0,等同关闭 |
| `loopClear` | 钻石(item 101) | 数量 1、概率 80 |
| `loopEndTileMove` | 金币(item 100) | 基数 10、概率 100、随目标关卡乘 `stageMult` |
| `loopClear` | 金币(item 100) | 基数 330、概率 100、随目标关卡乘 `stageMult` |
| `loopClear` | 四槽卷轴(119–122) | 各数量 1、配置概率数组均为 20 |
| `loopClear` | 四槽强化材料(126–129) | 各数量 1、配置概率数组均为 20 |
| `gameEnd` | 鱼饼(item 111) | 数量 1、概率 100 |
金币 `stageMult`:
| 目标关卡索引 | stageMult |
|---|---:|
| -1–16 | 0.30 |
| 17–21 | 0.29 |
| 22–25 | 0.28 |
| 26–30 | 0.27 |
| 31–33 | 0.26 |
| 34–37 | 0.25 |
| 38–44 | 0.24 |
| 45–99 | 0.23 |
表中 `itemCount × stageMult` 的小数取整规则尚未由消费者正文证明,不应自行选择 floor、round 或 ceil。四项 `20` 是配置事实,但“各自独立判定”还是“先选一项再判空”也需 Native 消费者闭合。
## 5. 抓娃娃掉落配置
`clawcraneminigame.csv` 说明场内出现 20 个胶囊,配置项包括:
| 奖励 | 普通 Prob | goodProb |
|---|---:|---:|
| 空 | 40 | 0 |
| 点数 | 70 | 0 |
| 药水 | 14 | 0 |
| NORMAL 装备 | 40 | 0 |
| RARE 装备 | 0 | 0 |
| EPIC 装备 | 0 | 0 |
| LEGEND 装备 | 0 | 1 |
| 祝福 | 0 | 0 |
| 药水祝福 | 0 | 0 |
这些是胶囊生成器的输入权重/概率字段,不应直接归一化为单次抓取概率;胶囊层级、20 个场内对象、好胶囊分支和物理抓取成功率都会影响最终获得率。
## 6. 保底与重复保护
结论:**未发现局内 `BattleController` 装备品质抽取的保底计数器或重复品排除逻辑。**
搜索到的保底实现属于其他系统:
- `gachaceildata.csv`:局外抽卡保底。
- `IdleDungeonController.RollGuaranteedIdleDungeonEquipmentGrade`:挂机地牢装备保底。
- `DestinyStatPage.RollGuaranteedHighGrade`:命运属性重掷保底。
它们不能迁移为普通局内装备掉落规则。公开社区所说的“20 抽保底”和 S 级装备抽取率也属于 Mimic Hunt/局外抽取,不是局内棋盘掉落。
## 7. 仍然未知的精确项
以下项目不应冒充已经还原:
1. 普通敌人自然产生一次装备奖励的基础触发率。
2. `GetEWeaponGrade` 中圈数对 EPIC/LEGEND/MYTH/ARCANE 的完整倍率公式。
3. 当前运行中各 Joker 的实际倍率、掉落销毁率及远程配置覆盖值。
4. `GetWeaponLoop` 三项权重的语义名称及最终 `loopGrade` 分布。
5. 卷轴/强化材料概率数组的精确判定顺序。
6. 小数奖励数量的取整方式。
要闭合 1–4,最小动态采样方案是固定 seed,分别在无祝福、获取 ID 124、获取 ID 132、不同圈数及指定 Joker 状态下,Hook `GetEWeaponGrade` 的入参、六项修正后权重和返回值,并记录每个 `SpawnRandomWeapon` 的调用栈。互联网资料无法替代这一步。
## 8. 证据索引
| 证据 | SHA-256 | 用途 |
|---|---|---|
| `gameconfig.csv` | `A57510DEDE13DAF1A597DE1EE73E47B0ABD830D96719DAD24B2CA7370E8DFE3D` | 六档基础权重 |
| `weapondrop.csv` | `AF8C97D022A83C1FF898D33FC541F157CAD1DC6C5732FF57D61A502E82914809` | 40 条局内装备身份 |
| `ingamereward.csv` | `BCD0E607C0F31A378960F3CD3BA25518A3F3D72D377EEDE11064A276849A9A74` | 圈结算与关卡结束奖励 |
| `augment.csv` | `E0B14AF4709E3F0D548973E124F679EF091589D7C99B0E35DE78C628A73D032A` | 装备掉落相关祝福 |
| `clawcraneminigame.csv` | `AE52FA502303678DE55D910BF07CD222C29A6995D0A4D96A785E84C660035015` | 抓娃娃胶囊配置 |
| `assembly-csharp.json` | `BA6D3F4BD91B0D3977EB1229AB46FE563118CC55793346796F93816BA7FEF526` | IL2CPP 类型、字段、方法映射 |
| `libil2cpp.runtime-decrypted.so` | `AC357FBA5BF8A68BA02829593020F29DA220EAC8D5ECA91212C1A6744B0100DA` | Native 规则正文 |
| `battlecontroller-drop-code.bin` | `DC28F8583A8AA60C2C3ED7CED8E5B9A60EDBF4A10E82370B32F2C169424FC0ED` | 原 SO 的只读函数区切片,便于 ARM64 复核 |
## 9. 互联网交叉检索结论
- [Heroll Wiki 的 Equipment 页面](https://heroll.fandom.com/wiki/Equipment)描述的是局外装备、Mimic Hunt、合成与升级,没有公开局内 `EMonoWeaponGrade` 的生成算法。
- [Heroll 社区的 S Legendary 讨论](https://www.reddit.com/r/heroll/comments/1mtb15a/the_thing_about_s_legendary_equipment/)出现了玩家声称的 0.5964% 以及评论中的“20 抽保底”,上下文明确是局外抽取/合成,不可用于本报告的局内掉落率。
因此,互联网没有补上 Native 中尚缺的圈数倍率;本报告以 APK 2.0.1 本地证据为准。