守望客户端观战体验

这次测试,观战范围限定在 OWWC 2018 的八强淘汰赛共八场比赛,每场比赛进行 3-4 张地图的比试,每张地图一个录像。观战使用独立客户端,但实际上就是游戏端添加了录像播放功能。此次测试顺利,未来就会整合进游戏客户端内。

关于功能:

客户端提供了不少有用的功能,包括:

  • 播放与暂停,以及从 0.25 倍减速到 2 倍加速共 6 档变速功能。可以任意拖动进度或跳略播放。
  • 所有选手的第一人称、第三人称视角与全场自由视角,且与速度调节协同。世界冻结只有镜头移动的感觉非常好。
  • 可以开关的圆形实时信息指示器。
  • 可以用快捷键操作。
  • 没有空气墙,自由视角可以任意在地图上移动。

当然也有缺点:

  • 快捷键和游戏本体共享。为了避免冲突,使用了别扭的 F1-F12 来选择玩家视角,使用 Ctrl+I、Ctrl+P 之类组合键切换功能。观战模式与游戏模式本可以各自使用一套快捷键,类似于星际争霸。
  • 没有自定义片段功能,没有赛后杰出卡和全场最佳。也没有保存为视频功能,需要自己录。
  • 没看到有文字聊天消息,我猜应该是包含在录像里的,只是这次选手们没有用上。
  • 没有同步语音。和录像同步的语音,技术上不会有问题。我猜不添加的原因更多的是用户隐私方面的需求。
  • 数据没有本地缓存,每次播放都需要从服务器端传输。

一些数据推算:

这次 OWWC 测试,主要压力在于比赛数据流要实时地从比赛服务器上分发到全球战网用户的电脑上,从结果来看还是很顺利的。

  • 原始数据保存在游戏服务器上,客户端只下载需要的若干秒,在本地重新演算出战斗场景。连续播放则连续下载,跳略播放则跳略下载。
  • 播放时每秒消耗 40KB 流量。每次跳进退重定位会瞬时下载 400 KB 左右缓冲内容。
  • 按一场比赛 16 分钟计算,大约 40MB 总量。加速播放时每秒流量也会相应增大,但总体积不变。

未来这个功能开放给所有玩家,则:

  • 暴雪没有公布过实时在线人数,若比照 Dota 2 的 50 万计算,每 12 人每分钟会生成 2.5 MB 数据,则全球每分钟新增 100GB 录像,一天新增 150TB 数据,三备份则每天 450TB。这个量对于企业而言其实不多,况且还有各种压缩方案可以使用。
  • 流量方面没有额外的成本。录像播放时的数据流量和游戏时是一样的。不难理解,两者的流量实质是一样的,都只是传输玩家的操作信息。当然,录像功能上线增加了玩家在线时间之类,虽然确有可能,但这属于考量范围外的因素。
  • 使用手机流量时,玩游戏延迟会很大,体验不好,但看录像够用,出差的玩家也就能多个选择。一小时 100MB 的流量并不大,刷朋友圈一小时也不止这些。

一些猜测:

  • 不会有 replay 文件下载。
  • 也就不会有第三方 replay 上传下载交流网站,War3 时代的 PLU、Replays.net 不会再出现。OWL 的转播和 VOD 点播都是卖了钱的,暴雪不可能折腾出商业纠纷。
  • 玩家肯定可以看自己的录像,如果朋友同意也可以看他的。通过分享链接给非好友第三方看的,应该也可以。
  • 游戏客户端内卖观战门票,应该会有。但只有少量暴雪授权的大型赛事有权卖票,个人或地方小比赛不能卖,暴雪当然会有分成。
  • 观战模式快捷键会改为独立设定,但会 Coming soon 很久。
  • 理论上,通过抓取网络流量,破解者还是有办法获得『录像文件』的。然后架设私服或者本机服观看录像,实现脱离暴雪,圈外分享录像的目的。但这类破解可以轻易通过版本升级阻止。
  • 外挂实锤变容易了。打完后复盘自己的录像,切视角到疑似外挂者的主视角即可。
  • 恩怨与诬陷者也会变多。剪辑一些高光视频很容易用来指摘别人,就像已经发生的那些。

守望先锋 1.14 版本后更改了底层数据格式

参考老文章: Overwatch Toolchain 解包方式考察,OW 音频小站一直以来使用原始文件 hash 的办法,便每次更新以后,都能区分旧数据和新增数据,使得每次更新的条目数量都在合理范围。但从版本 1.14 开始,暴雪更新了内部数据格式,这个是由蓝帖明确提到的,目的是减少之后的每次客户端更新时的下载。

但这对本小站来说不亚于一次冲击。这意味着,直到 1.13 版为止的条目,和从 1.17 版开始的所有条目,无法从数据角度建立『新』与『旧』的联系。

也就是说,明明从用户角度来说是同一句台词,音频波形也一致,但由于 OW 内部格式的变化,导致 hash 计算的结果变化,使得从数据角度来说,它们变成了两个不同的条目。

比如: D.VaD.Va 一分,坏蛋零分。(1.17 版本) 的 hash 计算结果是 5908654fbc3965232689836abb249c57,而
D.VaD.Va 一分,坏蛋零分。(1.16 或更早版本) 的 hash 计算结果是 1d99c1739f5b0844f57f3a1a5fbb4580。

我做了很多尝试,试图恢复一些信息,把这些本质相同的音频重新联系起来,有些成功了,有些失败了。最后我把匹配成功部分更新到原有条目上,匹配失败的部分按『新增音频』对待,添加到数据库里。

  1. 尝试使用音频分析软件批量比较,如果成功,理论上这是最好的办法。
    • 这是本质的解决办法,如果两个音频文件的波形完全一致,则两个音频当然是一样的。
    • 尝试了 Audacity 和 Similarity,前者缺乏批量功能,后者无法对这种只有一两秒的音频进行比较,均告失败。
  2. 尝试使用新版本拆解工具拆解旧客户端,失败,但得到了启发。
  3. 因为拆解所用的 Toolchain 工具链(简称 TC)本身有自己的文件名系统,而我亦保留了过去所有版本的原始拆解数据,理论上能通过新旧版本文件的相同路径名等信息恢复联系。
  4. 测试以上两条 D.VA 音频的 TC 路径分别为:
    • 旧(1.13):cn\heroes\D.Va\Sound Dump Full\_Base\000300000057\000000020231.wem
    • 新(1.18):cn\HeroVoice\D.Va\00000000059F.078\000000020231.wem
  5. 测试成功。
  6. 进入实操,发现由于旧版本拆解工具的不完全,数据存在错误,依然有许多坑要填:
    • 一,多个不同的 TC 文件名对应同一个 hash,即多个 1.18 新文件条目对应同一个 1.13 旧条目 hash,错误在旧版拆解工具自带的文件名系统有 bug。
      • 解决办法是视为多个条目,并将旧条目的听写内容更新到各个新条目上。
      • 对于网站用户来说,同一个关键词可能会搜索出几条内容,但其中应该至少有一条是对得上的
    • 二,同一个 TC 文件名对应多个一个 hash,即同一个 1.18 新文件条目对应多条旧的 1.13 旧条目,显然错误还是旧版折解工具的不完善
      • 解决办法只能是人工筛选按多条里面正确的那条。
      • 大约一共有 1200 条这种类型的错误,一条一条听完。网站用户肯定会得到正确的结果,因为这部分我都筛完了。

这次更新正常应当在 1.14 新版数据格式更新,1.17 新版拆解软件开发成熟以后更新,但这数据处理是真 TM 麻烦啊,烦死了。

写了个简易的多个网页连续截图脚本

目前适用于 ngacn 论坛帖子,效果图如下:

启动脚本后,会依次询问你 nga 的帖子 id,总页码数量和帖子名称。脚本会自动检查是否之前已经抓取过该帖子并在上次抓取的最后一页开始继续往下抓取。

每个帖子的抓取结果会放在独立的目录,并以”帖子id”-“自定义名称”的形式储存

注意事项:

  1. 脚本会优先检查是否有 $tid-xxx 形式的目录,只要 $tid 一致,脚本就认为本次会在旧的内容基础上往后抓取截图,xxx 的名称可以是任意的,不检查。假如已经存在一个 『12345-上山打老虎』 的目录,而你第二次输入的是 『12345-钻石王老五』,则实际更新的依然是『12345-上山打老虎』 目录。
  2. 目录名称中间的减号必须保留,否则脚本会忽略已存在的目录,按新目录工作执行。目录内的 1.update.sh 文件也必须保留。
  3. 我的运行环境是 Win10 64 位 1703 版本,不保证在其它机器上能正常运行。在 Win10 下脚本文件可以直接双击打开,在Win7 下可能需要右键点击并选择用 Git Bash 打开。
  4. 需要预先安装该脚本所需要的环境才能正常运行,包括 node、bash 等。

 

安装与准备工作:

  1. 下载并安装 Node for win 使 Windows 获得本截图脚本所需的 node 语言支持: 下载网址: https://nodejs.org/en/download/ ,选择下载 LTS 版本下对应的 32位 或 64  位 Windows Installer。安装一路 next 就行。
  2. 下载并安装 Git for win 使 Windows 也能使用 Bash 脚本。下载网址:https://git-for-windows.github.io/ ,也是一路 next 默认安装就行。
  3. 从开始菜单找到 Git Bash,,点击运行,在黑色窗口内依次输入以下内容:
    效果:
  4. 新建一个目录,起个名,比如叫『nga截图收藏夹』之类的。
  5. 在目录下新建一个文本文件,复制粘贴以下代码:
    随便起个名,并把后缀名改为 .sh。如何修改后缀名请自行百度。

使用:

  1. 双击,依次输入帖子 id,最后一页页码和标题就可以用了。

尾注:

  1. 如果你懂得简单的编程,可以尝试阅读脚本,并自行修改以抓取其它网站的贴子。这个脚本的原理就是利用 nga 帖子很有规律的地址,通过指定帖子 tid、页码 pageid 拼接出需要抓取的指定页面网址,然后反复调用 pageres 去抓取。实际进行抓取的是一个叫 pageres 的 npm 小程序。
  2. 如果你懂得简单的 JS,你可以自行指定 pageres 的抓取参数,甚至包括登录的 cookie 等,以实现『个性化抓取』。
  3. 如果你会完整的 node 开发,希望这个脚本也能为你提供一些参考。

ow.thnuclub.com 更新与计划更新

小站因为忙停更了一段时间,结果被各种催更。值此国庆佳节加之周末免费,趁势也更新一下,再开些空头支票。

  • Done:更新末日铁拳、地平线月球基地及其它英雄新增语音。(1.13 版客户端拆解)
  • 时间有限,只处理了增量更新部分。旧数据的疏漏错误更新后依然存在。他日有空再逐步更新旧数据。

  • Done:去掉了早期开发的赞与踩功能。
  • 在去年小站刚出来时,曾指望让热心用户通过 vote / devote 功能,把『有内容的音频』也就是台词、音乐等条目上浮到前几页,让意义不大的嘈杂环境音下沉。但事实看来结果不好,一来是用户并没有很好地理解该功能。后台数据显示,被踩得最多的是源氏的龙神拔刀,其次是麦爹的午时已到。想必是冤魂太多,多少发泄一下吧╮( ̄▽ ̄”)╭。二来呢,我看到这个数据以后也就懒病发作,没有继续考虑改进该功能了。后来还短暂地改成『倒放音频』,也就是猎奇一番,甚不实用。今日该功能彻底取消,就当是当年那几千投票,终于修正成果了吧。

  • Done:调整了下界面,加了圆角、阴影,js 代码的报错部分也处理了。
  • 主要新增数据会用黄色标签显示在上方。条目按钮加了细微的圆角和渐变阴影,整体会更柔和一些。同时每页条目数从 200 条减少到 100 条,相应的显然页码数量也加了一倍。因为网页背景本身是守望的全屏截图,故整体风格不会有大的变化,没有前后对比,不仔细看的话应该看不出来。修正 JS 报错这事其实也可做可不做,只要不搞死页面,能正常执行功能,jQuery 也就这样了。

  • Done:加了打赏按钮。
  • 这个没啥说的,目前平均也就每周一罐可乐,但听见叮咚声时的好心情很值钱。摊开算收益的话应该现在就把小站关掉,每年能省千儿块服务器钱。

  • Done:更新 36729 条音频的 MP3,音质略有提升。
  • 音频文件的处理路径是游戏客户端→.wem格式→.ogg格式→.mp3格式,理论上每一步都会有损耗。为了能在网页上直接播放必须使用 MP3,但之前在把 OGG 转为 MP3 时我选的是 LameXP 里的质量等级 2(一共 10 级),现在我想通了,把质量等级改成了最高的 0。当然,质量越高,mp3 的体积也越大,从质量 2 到质量 0 体积平均会增大 50%,也就是大概每个文件 20KB 会增加到 30KB。

    这对视频制作者会有所帮助,下载的音频在嵌入视频后的音效会有略微的提升。对 Lame 编码而言,质量 2 到质量 0,新增的数据主要集中在轻微的、高频的或者低频音域。这些音域的补足会让音频的回声、立体感和通透性更好一点点点点,就当是信则有吧。

    缺点是,对于使用手机流量访问的用户流量的消耗会增加。目前统计的平均每条数据大概是 28KB,请量力而行。至于对网页响应速度则是几乎没影响的,你的主要延迟是来自于与 Github.io 这个网站(我拿来存音频源)之间的通讯延迟,至于下载的数据是 20KB 还是 30KB,差的不过是 0.0x 秒而已。

  • Done:当条目文字很长时改用换行式,取代当前的隐藏式。
  • 这个功能和上一条类似,不难,但是会比较烦。换行以后会涉及到每行高度的变化,于是打开编辑面板时的对齐代码就需要调整。同时变化的高度也意味着右侧的齿轮按钮也要相应变化,现在它的高度是写死的。更麻烦的是 Input 框的高度自适应我没做过,可能要换用 contenteditable 的 div,要调整不少代码。好处当然也是显而易见的,长句子台词可以一次看完整了。

    Input 框暂时先不修改了,太麻烦要查资料,一时搞不定。条目本身现在是换行式的了。

  • Done:编辑条目时按 Ctrl+Enter 直接提交当前条目并自动打开下一条的编辑界面并同时播放音频。
  • 我自己,目前还是小站音频条目听写的第一贡献者,我觉得我在编辑条目时遇到的麻烦,你们肯定也遇到了。这个 Ctrl+Enter 的连续编辑提交功能应该会对热心的贡献者比较有帮助。当然伸手党是永远不会遇到这种麻烦的,但谁管你们那么多呢。

    我还没写过根据键盘组合键执行功能的代码,不过想必 Google 一下很容易就能得到答案。这功能不难,但是会比较烦。

 

  • Todo:编辑界面的标签钩选稍微改进一点。
  • 打算把现在的钩选换成和顶部筛选框类似的变色选中,顺便加上和英雄主题色相同的背景色。估计也挺麻烦的,tag 数据都是根据数据库生成的,现在数据库里没有英雄颜色,于是得改后端代码了。

  • Todo:逐步修正音频标签数据。
  • 这个没啥说的,其实主要依靠的是拆解软件的更新。之所以写在这里,是因为现有拆解结果,在数据处理上还能有少许改进,只是要花不少时间。

你看,写完这个,又快天亮了。

4.1 守望先锋平衡性补丁更新

安娜


站姿:

  • 现在安娜站得更直一些了。

摔杯为号(生物手雷被动)

  • 生物手雷技能添加了一个被动效果:摔杯为号。其技能音效可以被大范围的队友听到,并短暂地让队友可以穿墙看到自己。

设计师评论:

  • 安娜一直都是最出色的守望先锋战士之一,但毕竟是老太太了,蹲马步太久实在太累了。
  • 设计师从从削弱生物手雷遭到的巨大争议中获得启发,安娜迫切需要防绕后能力,而最好的办法就是呼叫队友。

 

死神


幽灵形态

  • 幽灵形态添加了新的台词:”死神走了”。

换弹

  • 现在死神扔在地上的枪可以对踩在上面的敌人造成 5 点伤害并轻微地减速敌人一秒。

死亡绽放

  • 死亡绽放现在除原有伤害外同时还会扔下若干把枪,这些枪落地后,同样可以对踩中的敌人造成 5 点伤害并轻微地减速敌人一秒。

设计师评论:

  • 死神的暗影步伴随有台词”死神来了”,使得这个技能的收益伴随风险。我们觉得高风险高收益很 Cool。所以给幽灵形态也添加了台词。
  • 死神特殊的换弹技巧给我们提升死神上场率提供了新的思路。

黑百合


卧倒

  • 黑百合新增了一个卧倒状态,你可以在设置界面为其绑定额外的按键,或者打开蹲下一秒后自动卧倒的选项。
  • 卧倒时的移动速度极其缓慢,并有专门的匍匐移动动作。
  • 卧倒时的受弹面积大幅减小,但被暴头率因形体原因自然增大到几乎 100%。
  • 卧倒时,黑百合视野会受到一定限制。转身若超过 90 度,继续往该方向的转身速度将有一个上限,不能随鼠标实时地移动到目的方向。
  • 卧倒时黑百合的换弹速度减慢 50%,但开镜及充能速度不变。
  • 卧倒时黑百合还会随机地翘起小腿,此动作不受黑百合玩家控制。

剧毒诡雷(感谢 SamBool 回帖)

  • 为了和动画逻辑一致,剧毒诡雷现在将会造成摔倒效果。

组队

  • 现在黑影、死神无法与黑百合同处一队,以确保黑百合的胜率。已选此二英雄的玩家会自动回到英雄选择界面。

设计师评论:

  • 我们认为玩家对重建帝国组合的抱怨本质上来源于自己的愉悦感不够,因此希望通过让队友及敌人更好地观赏黑百合的屁股获得愉悦,以此减少玩家对重建帝国组合的反感。毕竟半藏已裸左胸,应当会获得一些朋友的亲睐。
  • 考虑到黑爪组织迄今的战绩,我们认为让黑百合单飞,胜率会有所提高,这也能提升队友的愉悦感。

 

源氏


自责

  • 源氏添加了新的被动技能:自责。
  • 每当源氏说出台词:Ahoga 后,机械心脏会在血液内注入微量毒素,5 秒内降低源氏 50% 移动速度并持续造成每秒 10 点伤害。

  • 现在闪无法反弹坦克模式堡垒的攻击和莱因哈特的火箭重锤和烈焰打击,但可以通过闪亮的刀刃反射查莉娅的粒子枪了。但源鬼等刀刃黑色的特定皮肤除外。

影、二段跳

  • 现在源氏使用影、二段跳等技能在空中改变位移状态时,会有明显的喷气声,该音效有助于敌人更好的应对源氏,同时也使源氏的技能更逻辑自洽。

设计师评论:

  • 天使小姐姐多次在战场上被源氏切来切去后,趁着某次维护时给源氏添加了该功能。”既然他师傅没法教他礼貌,那就我来教吧。”天使纯真无邪地微笑着说道。设计师不予更多点评。

 

温斯顿


特斯拉炮

  • 现在特斯拉炮对源氏、半藏、黑百合造成的伤害会被计作治疗量。

屏障发生器

  • 为与动画保持一致,现在屏障发生器会在屏障碎裂或消失后爆炸,对死神造成 50 点伤害,对其它英雄无影响。

原始暴怒

  • 现在温斯顿的眼镜拥有了独立的命中判定,命中眼镜不会对温斯顿造成双倍伤害,但直接触发原始暴怒技能。眼镜不会被范围性攻击技能命中。

设计师评论:

  • 温斯顿的特斯拉炮并非杀伤性武器,他是希望通过科学让世界更美好的守望先锋一员。尽管如此,可不要惹怒它!

 

麦克雷


被动音效

  • 由于长期抽烟,麦克雷现在有很大的喘息声以及不时的咳嗽声,周围 15 码内的友方和敌方均可听到该声音。

战术翻滚

  • 由于长期抽烟,麦克雷现在在战术翻滚后需要双手撑膝大口喘气三秒,期间无法移动和攻击。

午时已到

  • 由于长期抽烟,麦克雷现在喊完午时以到后会咳嗽不止,且无法击中任何目标。

皮肤

  • 现在麦克雷的所有皮肤中的香烟均改成了棒棒糖。

设计师评论:

  • 我们添加该功能是为了保护地球环境和大家的身心健康,正如我们一直以来都规定大家应该怎么玩一样,这很 Cool,不是么。

 

士兵:76


表情

  • 现在士兵:76 在发你好表情时,有机率触发战术目镜,如果战术目镜已经准备就绪则直接激活,如果尚未充能完毕,则损失所有已经积攒的能量。

设计师评论:

  • 现在我们都是 Hello 了。

 

法老之鹰


推进背包

  • 现在法老之鹰在遭受爆炸伤害,例如火箭发射器(法老之鹰)、粒子炮(查莉雅)、坦克模式(堡垒)、螺旋飞弹(士兵:76)等时,会额外削减一部分推进背包能量。
  • 现在法老之鹰在使用推进背包后的上升阶段接触天花板后会遭受少量伤害。

设计师评论:

  • 我们之前忘了漏油这个设计了,现在补上。这对平衡性几乎没有影响,毕竟其它英雄几乎没有对空中目标的爆炸伤害能力,但会让法老之鹰的内战更具戏剧性。

 

堡垒


被动减伤

  • 现在哨卫模式下和坦克模式下的血条添加了一个护盾边框,以明确地表现其减伤特性。

哨卫模式

  • 如果堡垒在户外保持哨卫模式超过 10 秒没有任何动作,妮妮将会从天空飞下来停在堡垒的头或肩上,在堡垒有任何动作或周围有任何敌人发出的声音时飞走。

侦查模式

  • 现在堡垒在原地转身时,仅通过腰部转身,双腿不会再移动了。
  • 在堡垒攻击某个目标时,妮妮会同时不断盘旋在该目标眼前,并啄击该目标,造成 1 点伤害。妮妮不可被击中。

设计师评论:

  • 堡垒没有语言能力,缺乏和其它英雄的互动,因此我们添加了更多和妮妮的互动。

 

莱因哈特


 

冲锋

  • 如果冲锋未能撞到敌人而直接冲撞到墙壁等障碍物,则莱因哈特将获得头晕效果,在玩家的鼠标正常移动基础上,会随机加入若干左右方向的飘移。其效果类似于魔兽世界角色在醉酒时的鼠标效果,但幅度更大。持续 3 秒。
  • 如果被冲锋撞飞的敌人再次碰到墙壁,则会另外受到 30 点伤害并根据方向原地转一圈,操作该敌人的玩家屏幕上也会表现该效果。若击飞的敌人碰到天花板则受到 60 点伤害。

烈焰打击

  • 烈焰打击不能再被源氏反弹。
  • 烈焰打击对小美的冰墙造成 100% 的额外伤害。另外还可以解除队友的被冰冻状态(小美的冰霜冲击枪和暴雪技能效果),但不造成伤害也无法获得充能。

火箭重锤

  • 火箭重锤在撞到墙壁后会立刻结束此次挥动,且不改变下一次挥动的前摇时间。这使得在小巷、通道等狭窄地形中,莱茵哈特可以获得更快的挥锤频率,提高伤害,但同时也限制了范围。

裂地猛击

  • 现在裂地猛击的伤害降低为 30 点,但猛击后的地面会持续对倒地或站立于上面的敌人造成每秒 5 点的伤害,持续 5 秒。对方英雄可以通过跳跃取消该伤害,站立状态的禅雅塔、托比昂不受此效果影响,温斯顿受到该效果双倍伤害。

设计师评论:

  • 莱因哈特现在更重视地形因素对战斗造成的影响,作为终级碾压机器,莱因哈特必需要有相应的优势。另外,通过解冻队友,我们给莱因哈特玩家提供了更多的战斗策略供选择。

 

猎空


闪现

  • 如果猎空的闪现因为地形因素没有完整地移动 7 码距离,即撞到墙、电线杆等地形物,则猎空会短暂地眩晕 0.5 秒。在玩家的鼠标正常移动基础上,会随机加入若干左右方向的飘移。
  • 如果猎空的在眩晕状态下再次闪现撞墙,则眩晕状态会延长 2 秒,该状态可叠加。
  • 猎空使用闪现经过向上斜坡,会使猎空的闪现也变为向上移动,角度与斜坡一致,这使得猎空有机会更丰富地利用地形因素。
  • 猎空在闪现经过敌人时会撞上敌人而非穿过,同时对敌人造成 30 点伤害。

闪回

  • 现在使用闪回会严格地回复到 3 秒前的状态,包括位置、动量、生命值、子弹数量与增减益。但时空稳定器的能量依然会被消耗,因此闪现和闪回不会恢复。

英雄难度评级

  • 现在猎空的英雄难度改为三颗星。

设计师评论:

  • 你上你也晕。

 

D.Va


近战攻击

  • 现在 Meka 机甲的近战攻击统一造成 50 点伤害,而宋哈娜的近战攻击则造成 10 点伤害。如果对方有黄甲,则额外对哈娜自己造成 10 点伤害。

推进器

  • 现在 Meka 机甲在使用推进器的同时可以使用聚变机炮。

设计师评论:

  • 有感于鱼塘双飞太强,同时为了增加 D.Va 上场率,继让 D.Va 能用右键保被路霸钩走的队友后,我们又给 D.Va 增加了一项新的华而不实的英雄反制设计:D.Va 可以对抗双飞!D.Va 更加万能了,这很 Cool,不是么?

黑影


黑客入侵、电磁脉冲

  • 现在路霸、安娜、死神的所有技能都不会被黑客入侵和电磁脉冲打断制或禁用。尽管如此,视觉上的红色效果依然保留。

黑客入侵

  • 猎空玩家在被黑客入侵后会回到英雄选择界面,猎空直接在你和你所有队友的英雄选择界面上消失。
  • 士兵 76 的战术目镜现在会被黑客入侵打断或禁用,如果被打断时士兵:76正在释放战术目镜,则黑影获得剩余的战术目镜技能与持续时间,此时间内黑影的自动手枪带有自动瞄准功能。
  • 堡垒、禅雅塔被黑客入侵后会开始随机做一系列表情,持续 3 秒,即使你尚未购买该表情。由于 Meka 的一部分功能是通过机械传动的 宋哈娜在机甲里拼命踩脚蹬子 类内燃机结构,因此不会自动做表情,但此时 D.Va 玩不了《失落的维京》飞机游戏。
  • 美被黑客入侵后,其小机器人会开始随机堆雪人,持续 5 秒,其间小美无法释放暴雪技能,但其它技能不受影响。
  • 以下技能将不会再被黑客入侵打断、限制或禁用。尽管如此,视觉上的红色效果依然保留。
    • 狂鼠的捕兽夹和炸弹轮胎。
    • 黑百合的抓钩。
    • 士兵:76 的疾跑。
    • 半藏的竜。
    • 温斯顿的原始暴怒。
    • D.Va 的机甲自毁。
  • 黑客入侵现在可以直接打开部分地图的大门并控制其开关。例如观测站:直布罗陀AB点、多拉多B点、66号公路AB点、国王大道A点车库门等。

电磁脉冲

  • 士兵 76 的战术目镜现在会被电磁脉冲打断或禁用。
  • 堡垒、禅雅塔被电磁脉冲击中后会瘫痪 3 秒,禅雅塔的所有护盾将会消失。由于 Meka 的一部分功能是通过机械传动的 宋哈娜在机甲里拼命踩脚蹬子 类内燃机结构,因此不会瘫痪,但此时 D.Va 玩不了《失落的维京》飞机游戏。
  • 美被被电磁脉冲击中后,无法释放暴雪技能,但其它技能不受影响。
  • 以下技能将不会再被电磁脉冲打断、限制或禁用。尽管如此,视觉上的红色效果依然保留。
    • 狂鼠的捕兽夹和炸弹轮胎。
    • 黑百合的抓钩。
    • 士兵:76 的疾跑。
    • 半藏的竜。
    • 温斯顿的原始暴怒。
    • D.Va 的机甲自毁。

设计师评论:

  • 我们重做了整个黑影,现在她的技能更符合逻辑了,同时也会成为影响双方阵容的重要角色。

Overwatch Toolchain 解包方式考察


理想的英雄语音音频源文件,大概是这样的:

sample

有一个比较标准的文件名(Filename),以英雄名字起头,文件名自己就包含了一些有用的分类信息。
有一个配套的文本文件(Dictionary),里面写好了每个音频对应的台词(Text),我们直接可以查找替换复制粘贴。
有一套分类详尽的标签(Tags)列表,里面详细地给每个音频分好了类,我们可以方便地根据这些标签进行筛选、处理、归档。
这些理论上 Blizzard 应该已经做好了放在客户端里,我们只要解压了就能拿来用。

但事实上并不是这样的,CASC 是 BLZ 私有的加密格式,目前并没有很好的手段可以完美解压,实际解出来的结果大概是这样的:

hashname

这种 32 个数字英文组成的字符串称之为 filehash,可以简单理解为一种特殊的文件名。这种名字没有实际意义,仅仅表示『这个文件和那个文件是不同的』。

所以,比『什么都没有』稍微好点,我们有了『不知道是什么的一堆文件』,稍后我们又通过文件格式识别软件,找出了其中的音频部分,并转换成了可以播放的 mp3。于是我们得到了『不知道是什么的一堆音频』:

untitled-2

情况没有本质变化,但我们有了一大包知道是 mp3 的文件以后,我们就可以 手-动-听-写-打-标-签 了。

于是情况变成了这样:

untitled

这就是 http://ow.thnuclub.com 这个小站现在正在做的事情。全世界想的办法都一样——先解出来能播放的,再人工一个一个挑。幸运的是,吃瓜群众撸袖自己上,一不小心撸出了全世界最好的守望音频网站。


 

昨天 nga 有网友(青龙圣者@ngacn.cc)推荐了 toolchain 系列解压软件。这个软件在小站建站之初是没有的。现在看来,它有优点也有缺点,但前景似乎不错。

toolchain 使用的还是 zezula 的 CASCLib 开源库,但库版本更新了不少。因此比 cascview 能多解出一些信息,具体地来说是有了目录和文件类型,有目录就意味着可以自动完成一部分标签。但缺点是引入了另一套也没啥意义的文件名系统。于是情况变成了这样:

小站的旧数据有 Text 内容,而 toolchain 有相对比较准确的标签分类。但因为两边的文件名对不上,所以不知道哪个对应哪个。

再仔细验证以后,发现 toolchain 解压的文件是可以计算得到 filehash 的,于是又变成了:

tagmatching

这是目前所能获得的最大的成果了。

进一步分析发现,toolchain 解压出的音频总数较少,也就是:

compare

原因可能是 toolchain 的作者的关注重点并不在音频上,因而把原始数据中暂时未分析的部分直接抛弃了。而 CascView 则以解压优先,并未抛弃数据。

 

总结:

  1. toolchain 通过目录结构间接提供了较为准确的英雄分类 tag,可以补充修正现有小站全靠人工听写的标签数据。
  2. toolchain 目前仍然没有解出音频对应的文本,而目前音频文本(Text 数据)依然是最宝贵的劳动成果,也是 ow.thnuclub.com 小站存在的最大价值。暂时还没办法由 toolchain 自动化解决,期待未来某天可以彻底解决。那时小站大概就可以关闭了。
  3. toolchain 引入了另一套文件名,但可以通过计算得到 hash 值与旧数据对应起来。
  4. toolchain 的数据分类更细致,但总量较少,新的文件名系统无甚作用,且构成规则不明。因此也没有必要跟随 toolchain 的命名方式。
  5. toolchain 可解压出 *.mdl、*.dds 等文件,对视频制作者、签名档、头像等很有作用,但对于既有的音频内容,所助仅限于标签分类数据。
  6. 对于一些特殊的标签数据,例如莱因哈特的台词『Many of my comerads fell in battle here, may they rest in peace.(我的许多同伴在此牺牲,愿他们安息)』只会在艾兴瓦尔德这张地图出现,因此较完美的 tag 应当是『莱因哈特,英雄,艾兴瓦尔德,地图,入场』,这个是 toolchain 也无法提供的,只能依靠人工标注。

因此,在现阶段 toolchain 还不成熟的情况下,暂时还没有必要修改小站现有的数据结构和使用方式,只需要把 toolchain 提供的目录结构,转化成较为准确的 tag 数据补充到小站上即可。相比于 toolchain 构成规则不明的文件名系统,可以通过计算得到的 filehash 系统通用性也更好一些。


接下来的工作:

  1. 计算 toolchain 获得的所有音频文件的 hash 值,如果有软件可以直接带子目录列表输出 csv 就好了。
  2. 通过目录路径给 toolchain 所有音频文件打上英雄分类/地图分类 tag。
  3. 合并到现有小站数据上,需要解决英雄标签冲突,并尽可能保留有效信息。
  4. 但合并 tag 也可能导致形如『【天使】I feel unstoppable.』这类音频中的安娜标签丢失。具体处理办法还需要考虑。

更新完成。

盗号开挂被封责任是谁的?

最近一段时间守望外挂封号频率变快,吃瓜群众们顺带就发现了另一乐趣:『看演员』。即是围观被封号的人员是如何花样百出地去论坛控诉他们是『被误封』的。我也去了。可不是嘛,挺开心的。

绝大部分的申冤理由最后都集中到了『被盗号开挂』上,毕竟这大概确实属于最能彻底撇清责任的理由。帐号被盗并非拥有者意愿,而被盗期间主人对帐号失去了控制权,造成的影响也应当与主人无关,既然两个环节都并非号主意愿,那么号主自然不应当承受处罚。我觉得这个申诉理由确实有点意思,就记一笔理一下这里的逻辑好了。

 

『帐号被盗开挂被封』,仔细想想这八个字背后的逻辑其实挺复杂的。为了说明问题逻辑,不妨先来看一下另一个例子:

你买了一辆汽车,一切手续完备资格有效,各种费用包括保险费交通费全部交清——这完完全全是你的东西,别人找不到一丝茬。然后你某天下车没有关好门,一个无业混混一拉车把,门就开了。他坐进去打算开一把过瘾,然后就撞死了个老太太,要赔 30 万。

你忘了关车门,混混偷了你的车撞死了人。好嘛,这事怎么了结?

一般来说,首先是分配责任。混混偷车还撞死人当然是主责,但你确实也忘了关门,次要责任肯定得担一些。至于比例多少基本就是法官定度了,就假设是二八开吧。于是理论上你承担 6 万,混混承担 24 万。在结案以后,汽车会还给你。至于洗车费做法事香火钱,那得你自己出。

这个例子可以有诸般变化,比如你能证明你没有疏忽,已经尽到了保管责任,有监控录像证明你确实停在车库并且锁了门,混混是自己撬门开的。那你很幸运的不用承担责任,理论上还可以找混混要求赔偿修车钱。又比如混混还未成年,你停车的地方又是学校附近,可以预见到这里未成年人多。那你忘关车门甚至可能成为主责。再比如混混出车祸一块死了。那你就安心赔上 30 万给老太太家属,说不定还得另赔 30 万给混混家属。

但就算是一堆废铁了,车还是会还给你。如果你还要,记得付拖车费。

 

所以照这么说,帐号=车,应该还你罗?

这里的最大区别,其实恰恰就在于帐号不等于车。

你对某辆车拥有『所有权』,意味着对这车拥有一切处置、支配的权力,改了拆了砸了埋了卖了,都行。除非法律明确禁止,比如做成汽车炸弹。但退一万步说,法律也只是禁止你危害公共安全,并不禁止你对汽车进行改装,哪怕是改造成炸弹。

实物商品的复制需要和原型等量多的材料,还需要同等的加工和运输,凝聚了诸多人类劳动,因而我们可以将每一辆车看作独立物品,并单独分配所有权。但软件不同,软件存在一个实物没有的特点,『零成本复制』。无论是代码也好,小说也好,本质上都只是一段特定的排列顺序。软件作者,小说也好,所做的工作本质是排出这段序列而已。排列是困难的,排出来了,接触到的人想要照着再排一次,却毫不费力。

为了对抗这种情况,人们发明了版权。一旦某个序列排好,作者就可以宣称对这样一段序列有所有权。全世界任何一个地方,只要出现相同的序列,作者就拥有所有权,这就是版权的本质。实物的『复制』有成本,所以所有权可以分配到物。序列的复制无成本,则所有权索性不可分割,全部属于创造者。

而客人购买的,是『接触、阅读或者使用这段序列』的权利。说人话,就是买了软件的使用权,或者书本的阅读权。对于书籍而言,作者把『一段排列好的文字』通过卖实体 / 电子书的渠道,展现在你面前。展现的期限通常都是永久的,但也存在『租书』这种有时限的情况。软件同理,你购买的是限时或者永久使用这段代码的权利。

因为所有权永远是作者的,所以『复制』作为对原型的一种处置,自然也只有作者拥有这一权利。这样就从法理上,确定了未经作者许可的『复制』(也就是盗版)是侵犯作者权力的。同时,尽管在绝大多数情况下使用时长是永久的,但购买使用权本身更像是一种『租赁』。你花钱在某网吧办了『牛逼会员』,终身免费上网,也终归只是一种特殊的包时上网,并非就拥有网吧了。

 

回到守望这事上。你花 198/328 购买的,首先并不是软件的『所有权』。如果你对守望有了『所有权』,则暴雪网易反过来需要向你交纳使用费了,这显然不成立。没有所有权,就排除了『任意处置』的权利。顾客购买的并非所有权,则如何使用,需要根据买卖双方的约定执行。

你把钱交给暴雪,暴雪允许你复制它的客户端,连上它架的服务器,获得愉悦。所以你购买的是『使用名为守望的这段代码获得娱乐』的权利。时长名义上是『永久』,实际上是暴雪公司的寿命。服务器本质上也只是另一段代码,客户端和服务端代码一起,才能整个正常运行起来。

讲到这里,就涉及到核心问题了:盗号开挂该不该封?

暴雪拥有守望的『所有权』,并分割出了很多份不同的『使用权』,一个客人通常会购买一份使用权,但真想要购买多份也可以(小号)。每一份使用权都在顾客和暴雪达成约定后获得,约定内容包括:

  • 支付一定的金钱(就是花钱买)。
  • 为客人准备一份使用权,并准备相应的服务资源。(例如每卖出一千份多开一组服务器)。
  • 约定这份使用权的帐号密码,包括密保等,通常由客人自行完成(注册帐号)。
  • 若干条使用权的限制(也就是用户协议),通常包括不可共享、反编译等,当然也包括不可开挂。

在这一逻辑下,帐号密码只是链接暴雪和玩家的一个环节。它本身并不是出售的使用权的一部分,而仅仅是用来和玩家约定,谁可以使用这份『使用权』而已。也就是说:

  • 对于玩家,主观感觉可能是:花了 198 / 328,买了一个游戏的使用权,只有我能用,别人用不算。
  • 对于暴雪,客观的逻辑则是:某一份特定的『使用权』已经售出。自己准备好了相应的服务资源,并和客人约定了使用这份资源的口令。当然,口令可以由双方约定得很复杂(安全令/异地IP限制),并且暴雪也建议约定得足够复杂(绑安全令送 WOW 宠物)。但用户依然可以约定得很简单。

对于暴雪而言,确认身份的唯一方法就是口令,只有拥有口令才能获得『使用权』,只要拥有口令就能拥有『使用权』。而惩罚也是针对『使用权』在行使过程中的不当行为作出的,根据情节轻重,会暂停提供使用权,几天到永久不等。也就是说,对于暴雪而言,只是针对每一份『使用权』的不当行为,削减该份『使用权』的时长罢了。

由于事先约定了口令,自然拥有该口令的连接,必须可以访问该份『使用权』。盗号者当然犯了冒用他人身份的罪,然而之所以说“冒用”,正是因为只有当事人才知道是假的,而对于善意的第三方而言,这个身份是正确有效的。

一个有效『使用权』做出了不当行为,于是削减该份『使用权』的时间。

一个有效『使用权』开了外挂,于是削减该份『使用权』所有剩余时间(即封禁)。

由冒用身份而对事主造成的损失,由冒用身份的人负责。假若在核对口令检查身份时服务方有疏忽,则服务方也有责任。也就是说,如果你不但可以证明是有人盗用你的帐号开的挂,并且还能证明暴雪在验证帐号密码上有疏忽(比如明明开了将军令没却没验证 / 错误的用户名密码也可以登录),那么确实有理由解封。但假若在验证帐号密码上没有疏忽,则你的损失应当向冒用身份的人去追索,而与服务方无关。

 

以上只是逻辑上而言的,但在现实中其实还有更强大的约束存在——购买时的事前约定,也就是用户协议。当用户协议与法律不冲突时,该协议无论从人伦视角来看多么过份,依然是受法律保护的有效协议。因为这是最顶层的“事前约定”。至于怎么看用户协议,就不用多说了。

 

新地图艾兴瓦尔德

更新完音频小站上线体验了一把新地图。

艾兴瓦尔德,德国小镇,智械危机中莱因哈特所在的十字军死守的小镇。十字军在此一役中几乎全军覆没,但为后方大部队的集结争取了时间,人类从而获得了反攻的机会并最终赢得了胜利。(大概是这样的剧情吧)《最后的堡垒》短片里有一段回忆也和这场战役有关。莱因哈特在这地图上也有特殊相关台词。

体验了几把,包括使用自定义跑图,感觉是对进攻方非常不友好的地图。大概是随着游戏被越来越多的玩家深入理解掌握,各地图进攻方的优势和胜率越来越大,逼得暴雪通过地图加强防御方了。

但从全局看,这图怕是更难做到攻防平衡。

A 点路口

在所有的占点推车混合图里,这图是唯一一个 A 点只有一条直路可供大部分英雄通过的了,对于同类型的努巴尼,A 点有四条路线,任何一条路线都可以集体进攻。国王大道也有右侧二楼的集体路线。即使是好莱坞也有一个侧门,虽然对于鱼塘局作用不大但也偶有奇效,况且好莱坞大门处防守方掩体不足,很难死守大门,完全阻止进攻方突进英雄从左侧绕后。

但这个新图真的差不多准心瞄准桥头就行了。桥左破房子翻过去也只能骚扰,很可能在没有技能时直接面对对面两三个英雄,右侧只有法拉 D.VA 能飞,并且也要耗费完主力技能(飞行)才能通过。占点圈也比其它地图小,并暴露在三处高点下。

进攻方大部队我想不出什么其它策略,只能正面强冲。顶多就是利用温斯顿、法拉天使双飞、源氏、猎空之类的从桥上翻跃,勉强算是半个绕后。但温斯顿单重装强冲往往瞬死,如果想再加上查莉娅盾、禅雅塔谐,那么查莉娅和禅雅塔还是得从桥下经过,落单反而更容易死。对于水平相当的对战,很难想通过源氏、法拉等个人超水平发挥来牵制两名以上防守方英雄足够长的时间,让剩下 5 名队友获得足够长时间的人数优势从而压制并控制桥洞。

A – B (城门)运载路线

运车路线全程都很狭窄,并且左右优势高地众多。进攻方由于必须推车,并没有很好的分支路线选择,顶多就是源氏法拉略微脱离人群打开视野,而防守方却有多个选择,甚至可以集体绕后或居高临下强冲。尤其是 A B 点之间那段路,对进攻方简直是恶梦。前半段几十米路有三个弯曲,暴露在至少五六处不同高地的火力覆盖范围内,防守方登上城墙以后不用绕直接就可以突袭进攻方后方辅助位。同时路线狭窄,查莉娅大招、小美大招甚至温斯顿大招都可以分割整条道路。这前半段是少有的防守方可以在任何位置都可以主动寻求开团的地图版块了,比好莱坞 A B 段还强硬,至少好莱坞两个房顶只能占一个。

后半段则是奈何桥,这桥防守方重生路线比进攻方略短,交换人头会积累微弱的优势,同时左侧的城墙高点还能发挥作用,进攻方要上城墙需要从左边绕一大圈,而防守方只是顺路。进攻方需要尽量避免在桥上长时间作战,被迫作战也要尽量以攻城锤为掩体,否则全场最佳大概就会变成法拉的了。对鱼塘局而言,有大门遮挡视野,防守方重生英雄很难中途被截,必然可以赶到战场,而进攻方重生英雄则要面临整条路线上的任何可能位置的埋伏。

这段路线尽管非常短,差不多是所有地图中最短的一条,但同时也是最易守难攻的一段了。

B – 运载终点

这段防守方的优势没有前面的大了但依然存在,一是拐弯左侧小道利于防守方,二是依然狭窄的道路对于防守续命英雄(温斯顿、美、D.VA 等)也都是利好。但其实在我看来,这段路线对进攻方的最大压力已经不在于地形,而在于经过前两段路以后,捉襟见肘的剩余时间了。

总结

主路小,几个关键关卡点没有分路,繁多的支线和立体地形,使得防守方的优势极其巨大。由于鱼塘局和高端局在攻防配合上的天然差距,这图会成为鱼塘进攻方的恶梦,同时对于高端局而言,也因为存在过大的不确定性,导致 Banpick 中被选出的可能性较小。

源氏、法拉等立体机动性英雄和狂鼠等封路英雄优势较大,而猎空却受限明显,黑百合在 A 点桥门和 B 点奈何桥的争夺中可以当奇兵一用(狙掉两个,强冲一波)。

由于制作地图工程量巨大,后期也很难修改,所以猜测暴雪会在日后加快推车速度以平衡一下鱼塘进攻方的劣势,不会修改地图本身。但由于高端局和比赛是『一次团战胜利推一段』的模式,较短的路线和加快的车速又会变成进攻方的优势。就是说,这个地图放大了配合推进的重要性,导致鱼塘和比赛的攻防胜率更加割裂。不知道暴雪之后会怎么处理,会不会出现加快 AB 段车速减慢 BC 段车速的奇葩情况。拭目以待。

ow.thnuclub.com 条目编辑规范

1006 update: 添加 Ctrl+Enter 功能:提交当前条目,并自动跳到下一条编辑面板,方便连续编辑。
0522 update: 在提交编辑文本内容时,会再播放一遍该音频,方便检查。
12.11 update: 试图添加『下载时自动根据文本内容重命名』功能 失败了。原因是浏览器限制,跨域 a 连接中的 download 属性会被忽略。请勿再提类似需求。
11.20 update: 请勿随意改动英雄标签,目前数据已经是通过客户端导入的正确数据了,除非你有非常确实的理由。比如为对话语音添加对话另一方是可以的,但猜测就不必了。
=====================================

感谢您的热心贡献。

如果确信某个条目有错误或需要补充,请直接在页面上修改。

由于音频资源是托管在国外的免费空间上的,因此 移动宽带 国内部分品牌宽带 可能 无法访问 ,请自行准备梯子。

这篇规则说明并规范守望先锋在线音频小站 http://ow.thnuclub.com 条目编辑时的格式。这份规则不是强制的,但相同的格式有助于更好地回馈大家的贡献。

基本格式:

【黑百合】(对猎空)哦呵呵,似乎我们这次要合作了。
【地图】【好莱坞】【导演】还要多久?真希望这玩艺还有轮胎。
【源氏】竜神の剣を喰らえ(尝我龙神剑)(技能演示语音)

细则:

1. 发出语音的英雄名、地图名、特有元素名称,使用黑色方括号【】括起,放在条目开头。如果有多个元素则从大类到小类排列。

2. 并未在语音内出现,但有助于说明场景的,比如对话另一方,触发条件等,使用圆括号()括起,放在正文文本

3.  并未在语音内出现,但有助于解释语义的,比如解释台词梗等,使用圆括号()括起,放在正文文本最后

4. 非中、英文语音(岛田兄弟日文、查莉娅俄文、D.Va 韩文、堡垒蜂鸣器文等),有能力可以使用该语言原文,并使用括号配以中文翻译,放在紧邻正文文本。无法写出原文的,用中文或(中文)。英语文本可以不配中译。

5. 使用规范的英雄、地图、元素名称:莱因哈特 大锤 、查莉娅 毛妹 、路霸  ,尽管小站有少量繁体与海外访客,但考虑到最大用户群和称呼一致性,还是以简体中文客户端的英雄名称为准。

简体中文版英雄名称:堡垒,D.VA,源氏,半藏,狂鼠,卢西奥,麦克雷,美,天使,法老之鹰,死神,莱因哈特,路霸,士兵:76,秩序之光,托比昂,猎空,黑白合,温斯顿,查莉雅,禅雅塔,安娜,黑影,奥丽莎,莫伊拉。

6. 优先贡献尚未有内容的条目,越往后翻新条目越多。尽量保证听译的准确,不确定的使用三个问号『???/???』标记。

7. 即使如此,您只要愿意贡献,依然可以无视以上规则。『黑百合 – (法语听不出来)』同样可以接受,留待别人去改进。

标签:

“标签”功能已经上线,齿轮面板是编辑音频标签,顶部面板是筛选标签。请留言建议,改进标签分类。

无标题

编辑语音标签

根据标签筛选

根据标签筛选

 

尽管已经导入了一部分标签数据,但目前数据依然较少,需要您的鼎力相助。关于标签的编辑细则:

1. 不确定的内容尽量都勾选。例如听出是女声,但不确定是猎空、D.Va 或者美的声音,则三位都勾选上,以增大曝光机率,更快地修正结果。此条部分废弃,现在涉及英雄的语音已通过拆解客户端导入了正确数据,不必猜测是哪位英雄了。尽管如此,技能音效、环境音效等依然需要通过猜测解决。
此条已废弃。

2. 对话的双方英雄都勾选上。由客户端拆解只能得到发出语音的英雄名,与其对话的另一名英雄,需要手动钩选。

3. 语言数据来自于客户端本身(中英),尽管如此,对于源氏、半藏、小美等英雄,可以按实际情况添加标签,但请勿改动旧标签。

4. 没有数据时,不会得到筛选结果,所以请勿询问为何搜索结果比标签筛选结果多。

5. 堡垒的语音是不分语言的,中英完全相同。

 

===============================================

由于音频内容增多,单个包的体积已经超出 github 限制,故不得不拆分为 256 个包了。

打包下载地址,随版本更新,请使用批量下载工具:

https://codeload.github.com/k6i/00/zip/gh-pages
https://codeload.github.com/k6i/10/zip/gh-pages
https://codeload.github.com/k6i/20/zip/gh-pages
https://codeload.github.com/k6i/30/zip/gh-pages
https://codeload.github.com/k6i/40/zip/gh-pages
https://codeload.github.com/k6i/50/zip/gh-pages
https://codeload.github.com/k6i/60/zip/gh-pages
https://codeload.github.com/k6i/70/zip/gh-pages
https://codeload.github.com/k6i/80/zip/gh-pages
https://codeload.github.com/k6i/90/zip/gh-pages
https://codeload.github.com/k6i/a0/zip/gh-pages
https://codeload.github.com/k6i/b0/zip/gh-pages
https://codeload.github.com/k6i/c0/zip/gh-pages
https://codeload.github.com/k6i/d0/zip/gh-pages
https://codeload.github.com/k6i/e0/zip/gh-pages
https://codeload.github.com/k6i/f0/zip/gh-pages
https://codeload.github.com/k6i/01/zip/gh-pages
https://codeload.github.com/k6i/11/zip/gh-pages
https://codeload.github.com/k6i/21/zip/gh-pages
https://codeload.github.com/k6i/31/zip/gh-pages
https://codeload.github.com/k6i/41/zip/gh-pages
https://codeload.github.com/k6i/51/zip/gh-pages
https://codeload.github.com/k6i/61/zip/gh-pages
https://codeload.github.com/k6i/71/zip/gh-pages
https://codeload.github.com/k6i/81/zip/gh-pages
https://codeload.github.com/k6i/91/zip/gh-pages
https://codeload.github.com/k6i/a1/zip/gh-pages
https://codeload.github.com/k6i/b1/zip/gh-pages
https://codeload.github.com/k6i/c1/zip/gh-pages
https://codeload.github.com/k6i/d1/zip/gh-pages
https://codeload.github.com/k6i/e1/zip/gh-pages
https://codeload.github.com/k6i/f1/zip/gh-pages
https://codeload.github.com/k6i/02/zip/gh-pages
https://codeload.github.com/k6i/12/zip/gh-pages
https://codeload.github.com/k6i/22/zip/gh-pages
https://codeload.github.com/k6i/32/zip/gh-pages
https://codeload.github.com/k6i/42/zip/gh-pages
https://codeload.github.com/k6i/52/zip/gh-pages
https://codeload.github.com/k6i/62/zip/gh-pages
https://codeload.github.com/k6i/72/zip/gh-pages
https://codeload.github.com/k6i/82/zip/gh-pages
https://codeload.github.com/k6i/92/zip/gh-pages
https://codeload.github.com/k6i/a2/zip/gh-pages
https://codeload.github.com/k6i/b2/zip/gh-pages
https://codeload.github.com/k6i/c2/zip/gh-pages
https://codeload.github.com/k6i/d2/zip/gh-pages
https://codeload.github.com/k6i/e2/zip/gh-pages
https://codeload.github.com/k6i/f2/zip/gh-pages
https://codeload.github.com/k6i/03/zip/gh-pages
https://codeload.github.com/k6i/13/zip/gh-pages
https://codeload.github.com/k6i/23/zip/gh-pages
https://codeload.github.com/k6i/33/zip/gh-pages
https://codeload.github.com/k6i/43/zip/gh-pages
https://codeload.github.com/k6i/53/zip/gh-pages
https://codeload.github.com/k6i/63/zip/gh-pages
https://codeload.github.com/k6i/73/zip/gh-pages
https://codeload.github.com/k6i/83/zip/gh-pages
https://codeload.github.com/k6i/93/zip/gh-pages
https://codeload.github.com/k6i/a3/zip/gh-pages
https://codeload.github.com/k6i/b3/zip/gh-pages
https://codeload.github.com/k6i/c3/zip/gh-pages
https://codeload.github.com/k6i/d3/zip/gh-pages
https://codeload.github.com/k6i/e3/zip/gh-pages
https://codeload.github.com/k6i/f3/zip/gh-pages
https://codeload.github.com/k6i/04/zip/gh-pages
https://codeload.github.com/k6i/14/zip/gh-pages
https://codeload.github.com/k6i/24/zip/gh-pages
https://codeload.github.com/k6i/34/zip/gh-pages
https://codeload.github.com/k6i/44/zip/gh-pages
https://codeload.github.com/k6i/54/zip/gh-pages
https://codeload.github.com/k6i/64/zip/gh-pages
https://codeload.github.com/k6i/74/zip/gh-pages
https://codeload.github.com/k6i/84/zip/gh-pages
https://codeload.github.com/k6i/94/zip/gh-pages
https://codeload.github.com/k6i/a4/zip/gh-pages
https://codeload.github.com/k6i/b4/zip/gh-pages
https://codeload.github.com/k6i/c4/zip/gh-pages
https://codeload.github.com/k6i/d4/zip/gh-pages
https://codeload.github.com/k6i/e4/zip/gh-pages
https://codeload.github.com/k6i/f4/zip/gh-pages
https://codeload.github.com/k6i/05/zip/gh-pages
https://codeload.github.com/k6i/15/zip/gh-pages
https://codeload.github.com/k6i/25/zip/gh-pages
https://codeload.github.com/k6i/35/zip/gh-pages
https://codeload.github.com/k6i/45/zip/gh-pages
https://codeload.github.com/k6i/55/zip/gh-pages
https://codeload.github.com/k6i/65/zip/gh-pages
https://codeload.github.com/k6i/75/zip/gh-pages
https://codeload.github.com/k6i/85/zip/gh-pages
https://codeload.github.com/k6i/95/zip/gh-pages
https://codeload.github.com/k6i/a5/zip/gh-pages
https://codeload.github.com/k6i/b5/zip/gh-pages
https://codeload.github.com/k6i/c5/zip/gh-pages
https://codeload.github.com/k6i/d5/zip/gh-pages
https://codeload.github.com/k6i/e5/zip/gh-pages
https://codeload.github.com/k6i/f5/zip/gh-pages
https://codeload.github.com/k6i/06/zip/gh-pages
https://codeload.github.com/k6i/16/zip/gh-pages
https://codeload.github.com/k6i/26/zip/gh-pages
https://codeload.github.com/k6i/36/zip/gh-pages
https://codeload.github.com/k6i/46/zip/gh-pages
https://codeload.github.com/k6i/56/zip/gh-pages
https://codeload.github.com/k6i/66/zip/gh-pages
https://codeload.github.com/k6i/76/zip/gh-pages
https://codeload.github.com/k6i/86/zip/gh-pages
https://codeload.github.com/k6i/96/zip/gh-pages
https://codeload.github.com/k6i/a6/zip/gh-pages
https://codeload.github.com/k6i/b6/zip/gh-pages
https://codeload.github.com/k6i/c6/zip/gh-pages
https://codeload.github.com/k6i/d6/zip/gh-pages
https://codeload.github.com/k6i/e6/zip/gh-pages
https://codeload.github.com/k6i/f6/zip/gh-pages
https://codeload.github.com/k6i/07/zip/gh-pages
https://codeload.github.com/k6i/17/zip/gh-pages
https://codeload.github.com/k6i/27/zip/gh-pages
https://codeload.github.com/k6i/37/zip/gh-pages
https://codeload.github.com/k6i/47/zip/gh-pages
https://codeload.github.com/k6i/57/zip/gh-pages
https://codeload.github.com/k6i/67/zip/gh-pages
https://codeload.github.com/k6i/77/zip/gh-pages
https://codeload.github.com/k6i/87/zip/gh-pages
https://codeload.github.com/k6i/97/zip/gh-pages
https://codeload.github.com/k6i/a7/zip/gh-pages
https://codeload.github.com/k6i/b7/zip/gh-pages
https://codeload.github.com/k6i/c7/zip/gh-pages
https://codeload.github.com/k6i/d7/zip/gh-pages
https://codeload.github.com/k6i/e7/zip/gh-pages
https://codeload.github.com/k6i/f7/zip/gh-pages
https://codeload.github.com/k6i/08/zip/gh-pages
https://codeload.github.com/k6i/18/zip/gh-pages
https://codeload.github.com/k6i/28/zip/gh-pages
https://codeload.github.com/k6i/38/zip/gh-pages
https://codeload.github.com/k6i/48/zip/gh-pages
https://codeload.github.com/k6i/58/zip/gh-pages
https://codeload.github.com/k6i/68/zip/gh-pages
https://codeload.github.com/k6i/78/zip/gh-pages
https://codeload.github.com/k6i/88/zip/gh-pages
https://codeload.github.com/k6i/98/zip/gh-pages
https://codeload.github.com/k6i/a8/zip/gh-pages
https://codeload.github.com/k6i/b8/zip/gh-pages
https://codeload.github.com/k6i/c8/zip/gh-pages
https://codeload.github.com/k6i/d8/zip/gh-pages
https://codeload.github.com/k6i/e8/zip/gh-pages
https://codeload.github.com/k6i/f8/zip/gh-pages
https://codeload.github.com/k6i/09/zip/gh-pages
https://codeload.github.com/k6i/19/zip/gh-pages
https://codeload.github.com/k6i/29/zip/gh-pages
https://codeload.github.com/k6i/39/zip/gh-pages
https://codeload.github.com/k6i/49/zip/gh-pages
https://codeload.github.com/k6i/59/zip/gh-pages
https://codeload.github.com/k6i/69/zip/gh-pages
https://codeload.github.com/k6i/79/zip/gh-pages
https://codeload.github.com/k6i/89/zip/gh-pages
https://codeload.github.com/k6i/99/zip/gh-pages
https://codeload.github.com/k6i/a9/zip/gh-pages
https://codeload.github.com/k6i/b9/zip/gh-pages
https://codeload.github.com/k6i/c9/zip/gh-pages
https://codeload.github.com/k6i/d9/zip/gh-pages
https://codeload.github.com/k6i/e9/zip/gh-pages
https://codeload.github.com/k6i/f9/zip/gh-pages
https://codeload.github.com/k6i/0a/zip/gh-pages
https://codeload.github.com/k6i/1a/zip/gh-pages
https://codeload.github.com/k6i/2a/zip/gh-pages
https://codeload.github.com/k6i/3a/zip/gh-pages
https://codeload.github.com/k6i/4a/zip/gh-pages
https://codeload.github.com/k6i/5a/zip/gh-pages
https://codeload.github.com/k6i/6a/zip/gh-pages
https://codeload.github.com/k6i/7a/zip/gh-pages
https://codeload.github.com/k6i/8a/zip/gh-pages
https://codeload.github.com/k6i/9a/zip/gh-pages
https://codeload.github.com/k6i/aa/zip/gh-pages
https://codeload.github.com/k6i/ba/zip/gh-pages
https://codeload.github.com/k6i/ca/zip/gh-pages
https://codeload.github.com/k6i/da/zip/gh-pages
https://codeload.github.com/k6i/ea/zip/gh-pages
https://codeload.github.com/k6i/fa/zip/gh-pages
https://codeload.github.com/k6i/0b/zip/gh-pages
https://codeload.github.com/k6i/1b/zip/gh-pages
https://codeload.github.com/k6i/2b/zip/gh-pages
https://codeload.github.com/k6i/3b/zip/gh-pages
https://codeload.github.com/k6i/4b/zip/gh-pages
https://codeload.github.com/k6i/5b/zip/gh-pages
https://codeload.github.com/k6i/6b/zip/gh-pages
https://codeload.github.com/k6i/7b/zip/gh-pages
https://codeload.github.com/k6i/8b/zip/gh-pages
https://codeload.github.com/k6i/9b/zip/gh-pages
https://codeload.github.com/k6i/ab/zip/gh-pages
https://codeload.github.com/k6i/bb/zip/gh-pages
https://codeload.github.com/k6i/cb/zip/gh-pages
https://codeload.github.com/k6i/db/zip/gh-pages
https://codeload.github.com/k6i/eb/zip/gh-pages
https://codeload.github.com/k6i/fb/zip/gh-pages
https://codeload.github.com/k6i/0c/zip/gh-pages
https://codeload.github.com/k6i/1c/zip/gh-pages
https://codeload.github.com/k6i/2c/zip/gh-pages
https://codeload.github.com/k6i/3c/zip/gh-pages
https://codeload.github.com/k6i/4c/zip/gh-pages
https://codeload.github.com/k6i/5c/zip/gh-pages
https://codeload.github.com/k6i/6c/zip/gh-pages
https://codeload.github.com/k6i/7c/zip/gh-pages
https://codeload.github.com/k6i/8c/zip/gh-pages
https://codeload.github.com/k6i/9c/zip/gh-pages
https://codeload.github.com/k6i/ac/zip/gh-pages
https://codeload.github.com/k6i/bc/zip/gh-pages
https://codeload.github.com/k6i/cc/zip/gh-pages
https://codeload.github.com/k6i/dc/zip/gh-pages
https://codeload.github.com/k6i/ec/zip/gh-pages
https://codeload.github.com/k6i/fc/zip/gh-pages
https://codeload.github.com/k6i/0d/zip/gh-pages
https://codeload.github.com/k6i/1d/zip/gh-pages
https://codeload.github.com/k6i/2d/zip/gh-pages
https://codeload.github.com/k6i/3d/zip/gh-pages
https://codeload.github.com/k6i/4d/zip/gh-pages
https://codeload.github.com/k6i/5d/zip/gh-pages
https://codeload.github.com/k6i/6d/zip/gh-pages
https://codeload.github.com/k6i/7d/zip/gh-pages
https://codeload.github.com/k6i/8d/zip/gh-pages
https://codeload.github.com/k6i/9d/zip/gh-pages
https://codeload.github.com/k6i/ad/zip/gh-pages
https://codeload.github.com/k6i/bd/zip/gh-pages
https://codeload.github.com/k6i/cd/zip/gh-pages
https://codeload.github.com/k6i/dd/zip/gh-pages
https://codeload.github.com/k6i/ed/zip/gh-pages
https://codeload.github.com/k6i/fd/zip/gh-pages
https://codeload.github.com/k6i/0e/zip/gh-pages
https://codeload.github.com/k6i/1e/zip/gh-pages
https://codeload.github.com/k6i/2e/zip/gh-pages
https://codeload.github.com/k6i/3e/zip/gh-pages
https://codeload.github.com/k6i/4e/zip/gh-pages
https://codeload.github.com/k6i/5e/zip/gh-pages
https://codeload.github.com/k6i/6e/zip/gh-pages
https://codeload.github.com/k6i/7e/zip/gh-pages
https://codeload.github.com/k6i/8e/zip/gh-pages
https://codeload.github.com/k6i/9e/zip/gh-pages
https://codeload.github.com/k6i/ae/zip/gh-pages
https://codeload.github.com/k6i/be/zip/gh-pages
https://codeload.github.com/k6i/ce/zip/gh-pages
https://codeload.github.com/k6i/de/zip/gh-pages
https://codeload.github.com/k6i/ee/zip/gh-pages
https://codeload.github.com/k6i/fe/zip/gh-pages
https://codeload.github.com/k6i/0f/zip/gh-pages
https://codeload.github.com/k6i/1f/zip/gh-pages
https://codeload.github.com/k6i/2f/zip/gh-pages
https://codeload.github.com/k6i/3f/zip/gh-pages
https://codeload.github.com/k6i/4f/zip/gh-pages
https://codeload.github.com/k6i/5f/zip/gh-pages
https://codeload.github.com/k6i/6f/zip/gh-pages
https://codeload.github.com/k6i/7f/zip/gh-pages
https://codeload.github.com/k6i/8f/zip/gh-pages
https://codeload.github.com/k6i/9f/zip/gh-pages
https://codeload.github.com/k6i/af/zip/gh-pages
https://codeload.github.com/k6i/bf/zip/gh-pages
https://codeload.github.com/k6i/cf/zip/gh-pages
https://codeload.github.com/k6i/df/zip/gh-pages
https://codeload.github.com/k6i/ef/zip/gh-pages
https://codeload.github.com/k6i/ff/zip/gh-pages