加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

小鸡臂章原理探讨 转自RN

(2008-12-23 08:35:12)
标签:

杂谈

最近经常有人小鸡臂章。
当用了小鸡臂章的时候, 这东西这么简单一换, 魔兽就崩溃了啊?
太强悍了。
然后我研究了下为什么会出现这个问题。
小鸡臂章原理探讨 <wbr>转自RN

图片似乎小了点。 但实际基本可以说明问题了。


最初设计的时候, 只有英雄和兵。

然后英雄可以有speed, HP, MP, Attack(就当攻击力看好了)

英雄在使用物品的时候调用UseMagicUnit方法,

这个方法为了简便, 代码这样实现:

unit.MyMagicIsYours(this);

破法者常说的: Your magic is mine!

把this传给unit, 然后让每个unit来实现, 这个unit到底是干什么用的。


例如食尸鬼的臂章。 我们看, 臂章的使用函数这么写:

            int value = unit.Attack.Value;
            value += 20;
            unit.Attack = value;

取出可空类型的值, 增加10, 然后重新送回去。


好, 开始的时候, 一切正常, 每个英雄在使用臂章的时候都将增加自己的攻击力。


为了减少不必要的逻辑, 扰乱视听, 其他的作用没有写。

现在, 有人和icefrog提, 我们能不能增加个单位, 叫小鸡? 不需要有攻击力, 只要能跑, 送东西就OK了。

嗯, IceFrog觉得有道理, 就增加一个,

构造函数这样构造:

        public War3Chicken()
        {
            this.HP = 300;
            this.MP = 0;
            this.Speed = 300;
        }

数值是随意给的。

注意没有attack。 为什么? 因为需求是, 不需要有攻击力, 所以可空类型默认是空。


好, 问题出现了, IceFrog琢磨着, 万一有人在小鸡身上点一下臂章回怎么样?

对于一个值为空的变量取其中一部分, 俄,例如:

Console.WriteLine(((string)null).Length);

结果显而易见, 异常会被触发。 程序会崩溃。

做过软件的都知道, 最难修复的bug就是, 发生问题的代码不是自己写的。 只能用“馊主意”绕过去。 或者干脆不朽。

而使用物品的代码, 是war3写的。 当年撒旦出来的时候, 冰蛙的师傅处理的极为复杂, 最后吐血身亡, 并把完善地图这个重任交给了冰蛙(纯属玩笑:)),  这次IceFrog实在是害怕了, 不想再花那么大的功夫来处理这么个对游戏用处不大的东西了。 毕竟他觉得, 玩家对游戏崩溃没什么兴趣吧。 谁那么心理变态, 想让游戏崩溃?

那么如何解决呢? 肯定不能置之不理

而去掉增加攻击力这个功能, 需求就被违反了。

怎么办? 这个时候DotA都做了好几十个版本了, 重做显然是不现实的。

于是冰蛙想着, 这样吧, 假设物品有个属性, 是永久物品还是消耗物品。 在小鸡身上我设置为永久物品, 不能点击不就OK了。

这样DotA运行的良好。 因为任何人都不能通过UI操作来触发这个异常。 用户很满意。

公元200*年, RN发现惊天大bug。 在1.20的魔兽争霸客户端中, 在远距离使用消耗性物品, 并跑动过程中, 更换物品栏内物品的顺序, 将导致用错物品, 而且无视CD时间。

而且是从底层调用了使用物品的方法。 地图制作者也没办法禁止。只能等待暴雪修复

DotA做为魔兽争霸的一个小地图, 也不能幸免。

一时间, 山丘无限大, 极度流行。

嗯, 于是发布新地图来解决这个问题。

于是问题产生了:

刚才提到了, 小鸡带臂章本身就存在一个隐患, 被冰蛙给绕过去了。 那么就意味着, 其实如果用户可以触发这个bug, 问题就会再现。

于是这个swapbug被利用的淋漓尽致。 大家开始不在无限使用刷新了。 那虽然能保证赢, 但是已经被修复了。 那我们就想办法不输好了。 要输的时候, 崩掉所有人的客户端。

单机的时候, 用小鸡臂章崩一次魔兽吧, 你会发现提示你, 该位置不能被written。

是的, 那个值为空, 不能被赋值。(当然我用C#写的时候转化成了取值出问题。主要是因为C++被我忘记的一干二净, 而C#又不能完好的模拟那个bug, 我只好转化一下)

那么, 当应用程序从底层崩出了一个没有被捕捉的异常的时候, 结果会怎样呢?

结果就是程序崩溃了。 在胜负还没有计算之前。

于是小鸡臂章有了各种版本: 吃树的, 喝泉水的, 点红帐的, 但是原理都是一样: swap bug。

swa bug在魔兽的1.22补丁中被修复了。 而全世界的魔兽玩家都更新了1.22, 冰蛙于是觉得就不需要修复了。 毕竟做过软件的都知道,当产品稳定之后,能不修的bug, 就不要修。 否则修一个bug很可能导致两个bug的出现。

毕竟吐血身亡不是谁都愿意做的事情。。。。

但是我们依然用的是旧版本, 并深深被bug所折磨着。

我们应该怪谁呢? 平台的不更新?还是不断的咒骂玩家的素质?

我想, 这个事情是没有追究责任的价值的。 完毕。

后记: 其实是先有小鸡后有臂章的。 但是在不周全的考虑下, 依然导致了问题的出现。
写在很久之后:

增加31点的攻击力,提升10%的攻击速度,增加25点的力量,每秒失去30点的生命。

鉴于撒旦不崩溃, 疯狂不崩溃, 所以崩溃的原因, 很可能其实是因为力量导致的。 这和有一些RPG地图,助手吃书可能导致崩溃是一样的。

所以也有人曾经问过, 冰蛙可能怎么改?

我个人猜测是, 可能会像一些普通的RPG地图一样, 把开启后的效果加到主人身上。 没听过哪个英雄一点臂章就会报错的。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有