- 不要硬编码,常量尽量做成配置文件
-
很多文章和书籍都对通用的面向对象设计实践给出了很好的建议,但我印象中很少有针对游戏编程实践的。游戏程序员与典型的应用程序员有些不同。由于游戏程序员总是工作在最前沿的,要把人类和使件的限制推到极限,因而他们往往更愿意改变其至打破传统的程序设计原则。不幸的是,这种倾向常常会由于对共本OOP原则理解或实现的不当而产生负面效应,产生不可维护的代码。
-
Façade设计模式:
↓
- 模板元编程允许在编译期进行计算,从而减少运行时的开销。例如,编译期的常量表达式计算和类型推导可以显著提升程序的运行效率。
- 报文篡改:大多数针对协议的黑客攻击都是偶发的:他们尝试更改报文的字节看看会发生什么。针对此类攻击的第一线防御是一个简单的校验和checksum)。校验和是通过组合报文中每个字节得到的-个短数字。发送者计算报文的校验和并且将之与报文一起发送给接收者。接收者根据收到的报文重新计算校验和:如果计算得到的校验和与发送者的校验和不匹配,则报文被破坏并且应该被丢弃。校验和的计算范围必须包含包括包头在内的整个报文,以使接收者可以像检测有效负荷一样检 测包头的有效性。一个完美的校验和算法能对任意修改过的报文计算出不同的值。当然如果这个完美的校验和算法太长则会变得根本不实用。哈希(hash)函数具有相同的设计日标并可以构造极好的校验和。特别是实用的单向哈希函数,它可以将输入不规则地映射到一个很宽的范围,以致通过哈希值来重新构造输入的任意一个部分在实际中不可能办得到。MD5算法就是一个经过广泛测试,可以公开使用的单向哈希函数,并且对于游戏它的速度也足够快。公开领域的实现可以在网上找到IPlumb93]。
- 报文重放:在报文重放攻击中,恶意用户从客户端捕获报文(通常通过报文监听)然后多次发送。通常使用报文重放以超过游戏允许的速度来执行命令,即使客户端有时间检测。例如客户端可以使用一个计时器每秒向服务器发送一个特定命令,不管玩家以何等频率执行此命令。使用报文重放,一个单独用户可以每秒发送相同的命令儿百次。 系统设计者可以通过在服务器端也设置一个类似的每秒一次的计时器来阻止这种攻击。但因为可变的网络延迟,这种防范措施实际上是不可行的。虽然它能检测大部分报文重放攻击,但变化的网络延迟可能导致报文同时抵达服务器端,导致合法的命令列被拒绝。我们当然不希望我们的安全机制将合法玩家当成欺骗者。要预防报文重放,每个报文需要包含一些状态信息,因此即使相同的有效负荷也要有不同的位模式(bit pattem)。一个随着每个报文发送而累加的计数器之类的方法就可以做到,尽管这种策略使攻击者能够很容易的预期。一个较好的方法是使用一个状态机为连续的报文生成连续的识别号。一个快速并且足够复杂的计算方法是常用于系统库中的线性叠加随机数生成器。
- 客户端包括完整的加密算法,总是可以进行逆向工程;这是最难解决的问题,也是任何阻止协议篡改的机制的根本弱点。你可以采用以下的一些步骤增大逆向工程的难度:
- 当公开发布时删除所有代码中的符号和调试信息。
- 不要将缓冲区加密和解密放在一个独立的函数中:而要将之与其他网络代码合并到一起。这是一个值得以可维护性换取安全性的地方。
- 运行时计算“魔术数”(例如初始化随机数种子),而不是将其值直接保存在可执行文件中。
- 在每个版本的客户端中包含一个好的加密机制,甚至包括早期测试版。如果任意一个客户端版本缺乏加密,用户就可以记录从该客户端发出的未加密报文流,并可以使用其知识攻击后续版本的加密机制。
- 牢记你的目标是让作弊的成本最大化,而非完全禁止作弊。