剪贴簿收集
多数机器人会去打竞技场碰巧给出的那三个对手。这对荣誉没问题,对剪贴簿却毫无用处, 因为那三个名字是游戏挑的,而不是按你缺什么挑的。
Mercy SF 在后台爬取名人堂,记住见过的每个玩家的装备,并把下一次进攻送到全局最 优的、打得过的目标:身上带着最多你的簿子里还没有的物品的那个人。

用 auto_scrapbook 打开它,并把 arena_mode 设为 Scrapbook。
玩家池是怎么运作的
爬虫会按账号在内存里建起一个玩家及其装备的池子。之后每一场战斗都从池子里挑,而不 是从竞技场的推荐列表里挑。
这个池子只活一个会话,不会更久,这是有意为之。把它存下来看着像白得的知识,其 实不是:
- 它会无限增长。有一个被实测的账号涨到了 187,136 名玩家、119 MB,而且还在以每二 十分钟约 20 MB 的速度继续涨;
- 每一次改动都会同步重写整个文件,而且是握着锁写的,那把锁正是机器人挑选战斗所需 的、也是竞技场界面绘制所需的。实测:每 27 秒重写一次 119 MB;
- 写入不是原子的,解析失败会退回到空缓存,所以写到一半崩溃,整趟爬取反正也会被悄 无声息地丢掉;
- 缓存下来的装备只是某人当时穿着什么的一张快照,而玩家换装极其频繁,所以熬过重启 的那些内容大多是错的。
每次运行重新扫描,也正是启发了这套做法的那个参考工具的做法,理由相同。
目标是怎么挑的
池子里的玩家要过好几道关,才值得动手。
| 关卡 | 设置 | 默认 | 含义 |
|---|---|---|---|
| 等级上限 | scrapbook_max_level_diff | 0 | 目标可以比你高多少级。0 表示「绝不比我高」。 |
| 等级下限 | scrapbook_min_level_diff | 0 | 目标可以比你低多少级。0 表示不设下限。 |
| 强度 | scrapbook_max_attribute_pct | 120 | 目标总属性相对你的百分比上限。100 就是「绝不比我强」。 |
| 黑名单 | arena_never_attack | 空 | 无论身上带着什么都绝不攻击的名字。 |
| 存活 | 被服务器以「找不到该玩家」拒绝过的名字会被记住并跳过。 |
两条等级界限都要有,因为它们失手的方向相反。远高于你的,仗会输;远低于你的,赢得 毫不费力,可装备档次低,于是在一本快集齐的簿子上,它们花掉一次免费战斗却什么也带 不回来。
属性对结果的预测力远胜等级,所以真正做决定的旋钮是 scrapbook_max_attribute_pct。默认的 120 允许目标比你强上五分之一,这个强度下输 掉的频率高到你会注意到。如果你宁愿一场都不输,把它降到 100。
黑名单会对每一个来源做核对:竞技场的三个推荐、名人堂,以及爬虫的池子。你已经 说过不的名字,不能从另一扇门绕回来。
搜索带
scrapbook_search_band_enabled 是开启的,它改变的是搜池子的方式,而不是谁有资 格。
在一个经营已久的账号上,池子会达到六位数,而其中得分最高的玩家常常落在等级区间的 最远端,那样的一仗要么打不赢,要么不值钱。所以搜索从你自己等级附近的一条带开始, 只有这条带里搜空了才往外扩。
| 设置 | 默认 | 含义 |
|---|---|---|
scrapbook_search_band_start | 10 | 搜索起始那条带的半宽,单位为等级。 |
scrapbook_search_band_step | 10 | 每搜空一次,带子扩宽多少级。 |
scrapbook_search_band_max | 100 | 带子回到起点之前能扩到的最宽值。 |
回到起点的同时也会清理。既然一路扫到上限、每一级都找过却没找到目标,比起「服务器 是空的」,更可能的解释是记住的那些内容已经过时了。
老化
scrapbook_cache_max_age_hours 默认是 72。缓存的装备是一张快照,而玩家换装从 不停歇,所以一周前爬到的条目,说的更多是某人当时穿什么,而不是现在穿什么。更麻 烦的是,一套你早已集齐的装备,和一套从来就不值钱的装备,看上去毫无分别。设为 0 会彻底关掉老化。
已消失的名字
玩家会改名、被删号、转服。服务器回一句「找不到该玩家」,而如果不记住,池子里一个 过期条目就会把这个错误一路扩散,让整个模块停摆一小时。这些名字按账号记,所以一个 账号上已消失的目标,绝不会替另一个账号挡住一个完全可用的玩家。
这个集合上限是一万个名字。触到上限说明池子的换血程度远超一次真实会话,于是它会被 清空,那几个仍有意义的名字各花一次白费的查询重新学回来。
爬取速率
两个设置,各司其职。
| 设置 | 默认 | 限制什么 |
|---|---|---|
scrapbook_max_hof_lookups | 20 | 机器人每个周期的查询次数。 |
scrapbook_crawl_requests_per_min | 60 | 整个账号每分钟的查询次数。0 表示不限速。 |
每分钟六十次,大致是持续每秒一次:足以让池子不断长大,又不会出现只调高单周期预算 时那种请求扎堆。两个设置存在的理由正在于此。想让爬取跑得更猛,就两个一起调高。
其他设置

| 设置 | 默认 | 作用 |
|---|---|---|
auto_scrapbook | 开 | 模块本身。 |
scrapbook_crawler_enabled | 开 | 持续爬取名人堂,而不是只读竞技场的推荐。 |
scrapbook_after_xp_wins | 开 | 先打完经验优先的战斗,再去猎取剪贴簿目标。 |
scrapbook_scan_arena_opponents | 开 | 顺便记录竞技场给出的三个对手的装备,这是白得的信息。 |
scrapbook_early_game_priority | 开 | 角色等级还低的时候优先打剪贴簿,那是簿子填得最快的阶段。 |
scrapbook_hof_rankup | 开 | 维护一份用于往名人堂上爬的候选名单,而不只是为了物品。 |
scrapbook_notify_at | 0 | 簿子集到这么多件时通知我。0 表示从不通知。 |
buy_scrapbook | 开 | 在游戏出售剪贴簿条目的地方买下它们。 |
判断发生在哪里
如果你在读源码,这一点值得知道:剪贴簿从前是一个独立的机器人模块,而那是个错误。 它和竞技场模块都以为竞技场的冷却归自己管,互相照抄对方的关卡,还在「胜率下限能不 能否决一次免费战斗」这件事上意见不一。
做判断的那一半现在住在战斗模块里。留在「剪贴簿」名下的,是让池子值得从中挑选的那 套机械:爬虫、老化、等级界限,以及冲名次用的候选名单。