这篇文章好早就写了, 一直放在草稿箱, 今天整理的时候发现了, 于是修改了一下就发布了出来 !


前段时间我们的游戏公测了下, 在安全这方面遇到了不少问题, 和大家分享一下.

1. 道具负数卖出

卖出道具是多数游戏都有的一个功能, 那么如果卖出一个负数量的道具呢? 卖出道具的逻辑可能是这样的:

1
2
3
function sell(_id, _count)
item_data[_id].count = item_data[_id].count - _count
end

可以看到, 如果不做任何保护的话, 一旦 _count 是负数, 实际会变成加法. 我们遇到的第一个问题就是这个, 玩家通过八门神器或烧饼助手修改出售数量为负数, 这样就会变成增加道具. 一般情况下, 游戏后端会拦截住, 返回卖出失败的结果, 但是不巧, 他们也没有做类似的判断.

解决方案:

对于前端来说, 可以粗暴的断言一下, 因为正常肯定不会出现这个情况, 也可以温和的 Alert 一个提示. 如下:

1
2
3
4
5
6
7
function sell(_id, _count)
if _count < 1 then
Alert.new("卖出道具数量不能小于1")
return
end
item_data[_id].count = item_data[_id].count - _count
end

但这种限制肯定是服务端做的, 毕竟客户端这里只是第一道防线, 中间还有太多的手脚可做 !

2. 游戏加速

烧饼助手有一个游戏加速的功能, 类似于变速齿轮. 可以将游戏加速到十倍甚至百倍的速度, 一般对于网游来说, 真实的时间是服务端来计算的, 客户端的计时只是一个表现. 但是由于我们的战斗模块基本上是离线的, 所以这里在加速的情况下出了问题.

我们战斗有一个特色就是主公技, 是一系列非常强大的技能. 因此在战斗中会严格控制释放次数, 通过消耗能量冷却时间来实现. 正常情况下, 战斗中加速的话整个战斗的节奏就会加快, 因此不会有问题.

但是不知为何, 我们的人物动作加速到一定倍数后就会停止, 而主公技的能量回复和冷却速度却会无限增大, 因此表现出来的就是主公技可以无限释放, 玩家可以轻松挑战数倍强于自己的敌人!

发现这个问题后, 我和小伙伴们都惊呆了, 原来还可以这样搞!!!

解决方案:

现在我们的解决方案是将主公技的能量回复速度与人物动作联系起来, 这样不至于太变态. 同时加入了战斗的时间限制, 如果加速到10倍以上的, 时间很快会耗尽, 战斗失败!

但是我想到了一个更好的办法, 能从源头解决这个问题, 就是对比系统的时间流逝与游戏内的时间流逝速度. 一般, 变速齿轮只会改你当前游戏的时间, 没法改动系统的时间. 只要我么通过 native 的函数获取原生系统的时间, 一对比就可以发现有木有使用加速了.

但是目前还没有去实现这个想法, 有机会吧!

2. socket 抓包/发包

当看到群里有玩家讨论抓包的时候, 我们都目瞪口呆, 这年头作弊都需要高科技了! 玩家通过截取客户端发送的数据包, 重复发送, 这样可以轻松避开客户端的各种限制, 从而达到作弊的目的.

解决方案:

最终的解决方案还是得靠服务端严谨的逻辑来避免, 各种检查参数, 检查返回值! 也可以通过设计来避免, 比如每次发送数据包都附加一个 id 属性, 这个 id 会以某种规则增长, 服务端哪里也有一个 id , 对比之后就可以判断是否玩家作弊了 !


哈哈, 综上所述, 一个有经验的游戏服务端是多麽的重要.