WAP游戏,是游戏大家庭中的丑小鸭:近乎为0的美工,仅仅由一些文字符号组成的游戏界面,却可以完成几乎所有大型游戏的功能。目前比较有名的一些WAP游戏比如QQ的西游,新浪的江湖,还有稀饭的学院等。当然,这些都是些MMORPG,为自己网站做个广告,稀饭的游戏比较有特色,是业内公认的,从养成,MMO甚至竞速,这些游戏都是别的网站所没有的。WAP游戏是没有客服端的,仅仅是通过网页页面上的链接,输入框,等等进行游戏,所以实际上,所有的逻辑运行都是在服务器端,举个简单的例子说:比如在地图上移动这一动作,首先地图的所有数据都是保存在服务器上的,无论是数组还是DB,而要表示当前玩家所在的位置在哪,也仅仅是把地名,本地的描述信息,图片,及NPC等有关信息生成一个页面发送给客户端,就这么简单。而玩家要从本地移动到其它地点,也仅仅需要点击一个用POST或GET传递地点ID的链接便可完成,在程序方面,当前程序能够接收到一个合法的地点ID时,便将本ID更新到玩家的记录中去,并生成对应本地的信息生成页面输出即可。挺简单的吧。
详细的,我想应该从三方面介绍一些做WAP游戏所需要注意的:安全,效率,延展。
安全性,应该是一个游戏产品所最需要注重的,试想一个再有想法再好玩的游戏,如果不安全,导致玩家的利益时刻都有可能被盗,或是整个游戏的平衡性被几个受捣乱的玩家通过漏洞弄得乱78糟,这样的游戏,也不会受人欢迎的。我个人也在这些方面吃过些亏,所以把它放在最前面。安全性,一般看来,没有黑客就没有这个问题,对于用PHP这样的服务器端程序来说,安全性的问题基本只来源于我们开发的程序本身,而黑客其实就是那些有意捣乱的用户。简单写一些我所知道的问题和解决办法:

用户输入:这是最基本的,也是最可能被忽视的一点。‘1+(-10000)’,这是什么?这就是‘黑客’最常用的一种方法,它多出现在当你的程序需要用户输入一个数字时,比如,玩家可以把自己钱送给其他玩家,逻辑很简单,看看自己有没有这么多钱(if($my_money>$give_money)()),有的话,给自己扣钱,并给其他玩家加钱。完成。但你试试下面这段程序:
[php]
<?php
$a="1+(-111111)";
$b=2;
if($b>$a)
{echo "xx";}
?>
[/php]
结果如何?你很吃惊嘛?就这样,你的程序有BUG了,还没完,你再试下下面这条SQL:
"update user_money set money=money-".$a." WHERE user_id=155"
结果又如何,你给两个人都加了钱,谁都不亏(听说那个收钱的是送钱的人的小号),你的游戏和你亏了。这样下去,你的游戏货币越来越不值钱,游戏也变得不受欢迎。
怎么解决?过滤!用适当的方法过滤,让他的输入,是一个真实安全的数字,是你真正你需要的。(关于数字的过滤方法,我先卖个关子,因为后面还有和数字有关的更危险可能你觉得更不可思议的事)
类似的问题还有,用户在发言时输入了一个<,结果是你在输入这条发言时,就会有相当一部分显示不了这个页面,你的游戏也受到了怀疑。

数字:过滤数字,你首先想到的是什么方法或函数?intval?嗯,对于“1+(-10000)”这样的输入,这个没有问题,函数返回值是1,这个数字是安全的。注意!这个数字是安全的并不代表就都安全了,你再试试下面这个
[php]
<?php
echo intval(2200000000);
?>
[/php]
看到了嘛,又吓一跳吧,这都是血的教训啊。因为2200000000这个数已经超过了INT的取值范围(强行转化)。相类似的问题还有,在MYSQL5中(目前我不知道能不能设置),如果把字段设成UNSIGNED,那么0-1=42XXXXXXXX。
这里我提供两种解决办法:
1,用abs换掉intval,经初步测试,abs这个函数是可信的,它不会对数字造成什么不良影响。
2,使用高精度函数及相关,如:
bcadd(),bccomp(),ctype_digi()/*注意,这些函数的参数一定得是字符串型!*/

微观操作:同样用送钱的这个例子,你过滤了用户输入,用bccomp比较了用户要送的和他所有的,成功,可以送钱了。别忙,还有一个你可能不太相信但又确实存在的问题。有一句古话:我们不可能两次跨过同一条河。它说的是时间是变化的,所以事物也是变化的。你有没有想如,如果在你验证过了他是不是有这么多钱可送到你用UPDATE语句为他改钱的这一瞬间,另一个人把他的钱取走了?不可能吧?可能,非常可能。至少在我做游戏的这段时间,这种问题不止一次的出现过,要知道,比秒小的,有毫秒,比毫秒小的有微秒,比微秒小的有皮秒....所以一切都可能发生。所以我个人一般在PHP程序验证之后,还会在UPDATE语句之中,再做一次验证,即在WHERE语句中多加一句 AND MONEY>$a,这样的一个条件,基本不会对SQL执行效率产生什么影响,还能保证安全性,加上是很有意义的而语句是否执行成功,才是能否给对方加钱的真正条件。相关的还有一点要说明,在做这样操作时,一定要把对玩家有损失的操作放在前面执行,类似给他加钱这样的能让他HAPPY的操作放在后面,因为在没有引入事务的数据库处理机制之前,程序中止也是可能且可怕的。对于可能出现多人抢同一资源的问题,也应该有很好的先后判断,这点不细说了,但同样重要。

日志:这个东西很重要,要知道,如果程序出了问题,找到是哪里出的问题,问题影响了多少人的多少数据,如何恢复,就全靠它了。日志一般分两种,一种是游戏中需要用户的,比如救济品每人只能领一次,就是通过它来控制(其实是不应该算是程序日志范畴,只提一下)。另一种就是真正的日志,比如谁在什么时候给了谁多少钱他输入的是什么数字,操作前送出方有多少钱,操作后又有多少。如果有了这样的日志记录,我想对钱这类重要数据流向,就很清晰了。在程序没有正常的运行很长时间,经过时间的考验之前,这类日志数据是相当必要的。

总得来说,游戏产品和其他类型产品相比,对精确性的要求更高,所以程序每一步执行都要求是精确且在出错时是可恢复的。另外记住:用户,是绝不能相信的!!!

效率
这点我觉得不用多说什么,作为一个程序开发人员,程序的执行效率是我们的本职工作之一。
个人认为,一个程序的执行效率,很大程度取决于程序的设计(针对某一问题提出想法,并用最合理、高效、低成本的方式解决和实现它,这是我对设计的理解。)所以在进行某系统的开发之前,一定要先把遇到或可能遇到的问题分析清楚,想明白解决方案,并准备好备用的或是在出现问题时的应急方案。(这也是我们头对我们的要求:)具体说基本就是对数据结构和程序逻辑的分析,可能的话,写出一份策划案或是重点问题清单,在实际开发时,只要敲键盘就好了。这样做也能很好的提高程序开发效率。而在程序执行效率上,我不多说了,前人有很多很好的例子,说明我们可以学到,我也就不显丑了(没这个自信)。举一个例子吧,我个人最早是看到DZ论坛的数据结构上这么用的:统计一个论坛下面有多少个主题,可以在本论坛的记录里增加一个用于统计的字段比如stat_threadnum,每次有人发贴删贴时更新这个字段,这样虽然有了一定冗余,但就不用每次都COUNT去了,这是个好办法。别的就不多说了。

延展
其实这个问题,就已经不完全是一个程序开发人员的工作能力上的问题,而是所谓‘职业操守’的问题了。除了不能相信的用户,还有一类人是不能相信的:策划。(这并没有褒贬之意)为什么?因为作为一个策划,他的职责就是求变。所以他们总会想出新的东西来,这也就意味着,你的程序产品,要不断进行修改,再修改,这是必然的。所以把程序写‘活’,也是你必须学会的。(我个人认为,面向对象,其实就是为了解决这一问题。)举一个例子,见过一段这样的程序,它的作用是用玩家的几种道具在一定条件下换取另一种道具。程序的实现方式是用SWITCH。结果是,当每次要添加新的兑换方法(比如加入用两个梨换一个苹果),那就要不断添加新CASE语句。使得这一功能足足用了好几百行来实现。虽然可能换一个数组来写,可能(只是可能)效率上不如SWITCH,但延展性就要好得多(文件也小)。所以能够预测到策划下一步可能会怎么做也算是一个好的开发人员的能力之一。(在下一次改动之时,让自己更轻松一些不也是件好事嘛?)
关于注释和文档。游戏程序的逻辑,相对要更复杂一些,所以,足够且清楚的注释,是当其他同事接手你的工作时,你给它最好的礼物:)当然,如果你能把程序写的清楚些,命名得更准确些,程序本身就是很好的注释。而文档,作为注释的扩展,更是必要的东西。我把它们也算作在程序的延展性之中了。
posted on 2007-07-18 17:46  林宁  阅读(663)  评论(0编辑  收藏  举报