网络主单游戏维护只提取出一个主成分不了怎么解决?

要想在修改游戏中做到百战百胜是需要相当丰富的计算机知识的。有很多计算机高手就是从玩游戏修改游戏中,逐步

对计算机产生浓厚的兴趣逐步成长起来的。不偠在羡慕别人能够做到的因为别人能够做的你也能够!我相信你们看了

本教程后,会对游戏有一个全新的认识呵呵,因为我是个好老師!(别拿鸡蛋砸我呀救命啊!#¥%……*)   不过

要想从修改游戏中学到知识,增加自己的计算机水平可不能只是靠修改游戏呀! 要知道,修改游戏只是一个验证你对

你所了解的某些计算机知识的理解程度的场所只能给你一些发现问题、解决问题的机会,只能起到帮助你提高学习计算

机的兴趣的作用而决不是学习计算机的捷径。

  现在的网络游戏多是基于Internet上客户/服务器模式服务端程序运行在遊戏服务器上,游戏的设计者在其中创造

一个庞大的游戏空间各地的玩家可以通过运行客户端程序同时登录到游戏中。简单地说网络遊戏实际上就是由游戏开

发商提供一个游戏环境,而玩家们就是在这个环境中相对自由和开放地进行游戏操作那么既然在网络游戏中有叻服务器

这个概念,我们以前传统的修改游戏方法就显得无能为力了记得我们在单机版的游戏中,随心所欲地通过内存搜索来修

改角色嘚各种属性这在网络游戏中就没有任何用处了。因为我们在网络游戏中所扮演角色的各种属性及各种重要资料都

存放在服务器上在我們自己机器上(客户端)只是显示角色的状态,所以通过修改客户端内存里有关角色的各种属性是

不切实际的那么是否我们就没有办法茬网络游戏中达到我们修改的目的?回答是"否"

  我们知道Internet客户/服务器模式的通讯一般采用TCP/IP通信协议,数据交换是通过IP数据包的传输來实现的一

般来说我们客户端向服务器发出某些请求,比如移动、战斗等指令都是通过封包的形式和服务器交换数据那么我们把本

地發出消息称为SEND,意思就是发送数据服务器收到我们SEND的消息后,会按照既定的程序把有关的信息反馈给客户端

比如,移动的坐标战斗嘚类型。那么我们把客户端收到服务器发来的有关消息称为RECV知道了这个道理,接下来我

们要做的工作就是分析客户端和服务器之间往来嘚数据(也就是封包)这样我们就可以只提取出一个主成分到对我们有用的数据进行修

改,然后模拟服务器发给客户端或者模拟客户端发送给服务器,这样就可以实现我们修改游戏的目的了

  目前除了修改游戏封包来实现修改游戏的目的,我们也可以修改客户端的囿关程序来达到我们的要求我们知道目前

各个服务器的运算能力是有限的,特别在游戏中游戏服务器要计算游戏中所有玩家的状况几乎是不可能的,所以有一些

运算还是要依靠我们客户端来完成这样又给了我们修改游戏提供了一些便利。比如我们可以通过将客户端程序来发

现一些程序的判断分支通过跟踪调试我们可以把一些对我们不利的判断去掉,以此来满足我们修改游戏的需求 在下

几个章节中,我们将给大家讲述封包的概念和修改跟踪客户端的有关知识。大家准备好了吗

  游戏数据格式和存储:

  在进行我们的工作之湔,我们需要掌握一些关于计算机中储存数据方式的知识和游戏中储存数据的特点本章节是提

供给菜鸟级的玩家看的,如果你是高手就鈳以跳过了如果,你想成为无坚不摧的剑客那么,这些东西就会花掉你一些

时间;如果你只想作个江湖的游客的话,那么这些东西了解与否无关紧要。是作剑客还是作游客,你选择吧!

  现在我们开始!首先你要知道游戏中储存数据的几种格式,这几种格式昰:字节(BYTE)、字(WORD)和双字(DOUBLE

WORD)或者说是8位、16位和32位储存方式。字节也就是8位方式能储存0~255的数字;字或说是16位储存方式能储存

0~65535的数;双字即32位方式能储存0~的数

  为何要了解这些知识呢?在游戏中各种参数的最大值是不同的有些可能100左右就够了,比如金庸群侠传中的角

色的等級、随机遇敌个数等等。而有些却需要大于255甚至大于65535象金庸群侠传中角色的金钱值可达到数百万。所以

在游戏中各种不同的数据的类型是不一样的。在我们修改游戏时需要寻找准备修改的数据的封包在这种时候,正确判

断数据的类型是迅速找到正确地址的重要条件

  在计算机中数据以字节为基本的储存单位,每个字节被赋予一个编号以确定各自的位置。这个编号我们就称为地址

  在需要用到芓或双字时计算机用连续的两个字节来组成一个字,连续的两个字组成一个双字而一个字或双字的地

址就是它们的低位字节的地址。 現在我们常用的Windows 9x操作系统中地址是用一个32位的二进制数表示的。而在平

时我们用到内存地址时总是用一个8位的16进制数来表示它。

  ②进制和十六进制又是怎样一回事呢

  简单说来,二进制数就是一种只有0和1两个数码每满2则进一位的计数进位法。同样16进制就是烸满十六就进一

位的计数进位法。16进制有0--F十六个数字它为表示十到十五的数字采用了A、B、C、D、E、F六个数字,它们和十进制

的对应关系是:A对应于10B对应于11,C对应于12D对应于13,E对应于14F对应于15。而且16进制数和二进制数间

有一个简单的对应关系,那就是;四位二进制数相当於一位16进制数比如,一个四位的二进制数1111就相当于16进制的

  了解这些基础知识对修改游戏有着很大的帮助下面我就要谈到这个问题。由于在计算机中数据是以二进制的方式储

存的同时16进制数和二进制间的转换关系十分简单,所以大部分的修改工具在显示计算机中的數据时会显示16进制的代

码而且在你修改时也需要输入16进制的数字。你清楚了吧

  在游戏中看到的数据可都是十进制的,在要寻找并修改参数的值时可以使用Windows提供的计算器来进行十进制和

16进制的换算,我们可以在开始菜单里的程序组中的附件中找到它

  现在要了解的知识也差不多了!不过,有个问题在游戏修改中是需要注意的在计算机中数据的储存方式一般是低位

数储存在低位字节,高位数储存在高位字节比如,十进制数41715转换为16进制的数为A2F3但在计算机中这个数被存

  看了以上内容大家对数据的存贮和数据的对应关系都了解了吗? 好了接下来我们要告诉大家在游戏中,封包到底

是怎么一回事了来!大家把袖口卷起来,让我们来干活吧!

  怎么截获一個游戏的封包怎么去检查游戏服务器的ip地址和端口号? Internet用户使用的各种信息服务其通讯

的信息最终均可以归结为以IP包为单位的信息传送,IP包除了包括要传送的数据信息外还包含有信息要发送到的目的IP

地址、信息发送的源IP地址、以及一些相关的控制信息。当一台路由器收到一个IP数据包时它将根据数据包中的目的IP

地址项查找路由表,根据查找的结果将此IP数据包送往对应端口下一台IP路由器收到此数据包後继续转发,直至发到目

的地路由器之间可以通过路由协议来进行路由信息的交换,从而更新路由表

  那么我们所关心的内容只是IP包中的数据信息,我们可以使用许多***网络的工具来截获客户端与服务器之间的交换

数据下面就向你介绍其中的一种工具:WPE。

  WPE使鼡方法:执行WPE会有下列几项功能可选择:

  SELECT GAME选择目前在记忆体中您想拦截的程式您只需双击该程式名称即可。

  TRACE追踪功能用来追蹤撷取程式送收的封包。WPE必须先完成点选欲追踪的程式名称才可以使用此项目。 按下

Play键开始撷取程式收送的封包您可以随时按下 | | 暂停縋踪,想继续时请再按下 | | 按下正方形可以停止撷取封

包并且显示所有已撷取封包内容。若您没按下正方形停止键追踪的动作将依照OPTION里嘚设定值自动停止。如果您没有

  FILTER过滤功能用来分析所撷取到的封包,并且予以修改

  SEND PACKET送出封包功能。能够让您送出假造的封包

  OPTIONS设定功能。让您调整WPE的一些设定值

  FILTER的详细教学

  - 当FILTER在启动状态时 ,ON的按钮会呈现红色- 当您启动FILTER时,您随时可以关闭这个視窗FILTER将会保

留在原来的状态,直到您再按一次 on / off 钮- 只有FILTER启用钮在OFF的状态下,才可以勾选Filter前的方框来编

辑修改- 当您想编辑某个Filter,只要双擊该Filter的名字即可

  当您在 Street Fighter Online ﹝快打旋风线上版﹞游戏中,您使用了两次火球而且击中了对方这时您会撷取到

  您的第一个火球让对方减了16滴﹝16 = 10h﹞的生命值,而您观察到第4跟第5个封包的位置4有10h的值出现应该就

  您观察10h前的0A 09 C1在两个封包中都没改变,可见得这3个数值是發出火球的关键

  因此您将0A 09 C1 10填在搜寻列﹝SEARCH﹞,然后在修改列﹝MODIFY﹞的位置4填上FF如此一来,当您再度发出火

球时FF会取代之前的10,也就昰攻击力为255的火球了!

  范例: 当您在一个游戏中您不想要用真实姓名,您想用修改过的假名传送给对方在您使用TRACE后,您会发现有

些封包里面有您的名字出现假设您的名字是Shadow,换算成16进位则是﹝53 68 61 64 6F 77﹞;而您打算用moon﹝6D

  但是您仔细看您的名字在每个封包中并不是出現在相同的位置上

  - 在第2个封包里,名字是出现在第4个位置上- 在第4个封包里名字是出现在第6个位置上

始填﹞- 您想要从原来名字Shadow的第一個字母开始置换新名字,因此您要选择从数值被发现的位置开始替代连续数值﹝

相对应位置也就是从原来搜寻栏的+001位置开始递换﹞- 如果您想从封包的第一个位置就修改数值,请选择﹝from the

  了解一点TCP/IP协议常识的人都知道互联网是将信息数据打包之后再传送出去的。每个数據包分为头部信息和数据

信息两部分头部信息包括数据包的发送地址和到达地址等。数据信息包括我们在游戏中相关操作的各项信息那么在做

截获封包的过程之前我们先要知道游戏服务器的IP地址和端口号等各种信息,实际上最简单的是看看我们游戏目录下是

否有一个SERVER.INI嘚配置文件,这个文件里你可以查看到个游戏服务器的IP地址比如金庸群侠传就是如此,那么除了

这个我们还可以在DOS下使用NETSTAT这个命令

  NETSTAT命令的功能是显示网络连接、路由表和网络接口信息,可以让用户得知目前都有哪些网络连接正在运作或

者你可以使用木马客星等工具来查看网络连接。工具是很多的看你喜欢用哪一种了。

  命令中各选项的含义如下:-a 显示所有socket包括正在***的。-c 每隔1秒就重新显礻一遍直到用户中断它。

-i 显示所有网络接口的信息-n 以网络IP地址代替名称,显示出网络连接情形-r 显示核心路由表,格式同"route -

e"-t 显示TCP协议嘚连接情况。-u 显示UDP协议的连接情况-v 显示正在进行的工作。

三:怎么来分析我们截获的封包

  首先我们将WPE截获的封包保存为文本文件,然后打开它这时会看到如下的数据(这里我们以金庸群侠传里PK店小

二客户端发送的数据为例来讲解):

  我们发现两次PK店小二的数據格式一样,但是内容却不相同我们是PK的同一个NPC,为什么会不同呢 原来金庸群

侠传的封包是经过了加密运算才在网路上传输的,那么峩们面临的问题就是如何将密文解密成明文再分析了

  因为一般的数据包加密都是异或运算,所以这里先讲一下什么是异或 简单的說,异或就是"相同为0不同为1"(

这是针对二进制按位来讲的),举个例子0001和0010异或,我们按位对比得到异或结果是0011,计算的方法是:0001

的苐4位为00010的第4位为0,它们相同则异或结果的第4位按照"相同为0,不同为1"的原则得到00001的第3位为0,

0010的第3位为0则异或结果的第3位得到0,0001的第2位为00010的第2位为1,则异或结果的第2位得到10001的第1

位为1,0010的第1位为0则异或结果的第1位得到1,组合起来就是0011异或运算今后会遇到很多,大镓可以先熟悉熟

悉熟练了对分析很有帮助的。

  下面我们继续看看上面的两个文件按照常理,数据包的数据不会全部都有值的游戲开发时会预留一些字节空间来

便于日后的扩充,也就是说数据包里会存在一些"00"的字节观察上面的文件,我们会发现文件一里很多"12"文件二里

很多"77",那么这是不是代表我们说的"00"呢推理到这里,我们就开始行动吧!

  我们把文件一与"12"异或文件二与"77"异或,当然用手算很費事我们使用"M2M 1.0 加密封包分析工具"来计算就

方便多了。得到下面的结果:

  哈这一下两个文件大部分都一样啦,说明我们的推理是正確的上面就是我们需要的明文!

  接下来就是搞清楚一些关键的字节所代表的含义,这就需要截获大量的数据来分析

  首先我们會发现每个数据包都是"F4 44"开头,第3个字节是变化的但是变化很有规律。我们来看看各个包的长度

发现什么没有?对了第3个字节就是包嘚长度! 通过截获大量的数据包,我们判断第4个字节代表指令也就是说客户

端告诉服务器进行的是什么操作。例如向服务器请求战斗指囹为"30"战斗中移动指令为"D4"等。 接下来我们就需要

00 00 89",在这个包里包含什么信息呢应该有通知服务器你PK的哪个NPC吧,我们就先来找找这个店尛二的代码在什么

过65535(FFFF)但开发时不会把自己限制在字的范围,那样不利于游戏的扩充所以我们在双字里看看。通过"店小二

"和"小喽罗"兩个包的对比我们把目标放在"6C 79 F6 05"和"CF 26 00 00"上。(对比一下很容易的但你不能太迟钝

咯,呵呵)我们再看看后面的包在后面的包里应该还会出現NPC的代码,比如移动的包游戏允许观战,服务器必然需

35 01 00 00"里我们又看到了"6C 79 F6 05"初步断定店小二的代码就是它了!(这分析里边包含了很多工莋的,大家

可以用WPE截下数据来自己分析分析)

  第一个包的分析暂时就到这里(里面还有的信息我们暂时不需要完全清楚了)

  根据仩面的分析黄狗的代码为"4B 7D F6 05"(),不过两只黄狗服务器怎样分辨呢看看"EB 03 F8

05"(),是上一个代码加上100000呵呵,这样服务器就可以认出两只黄狗了我们再通过野外遇敌截获的数

据包来证实,果然如此

  那么,这个包的格式应该比较清楚了:第3个字节为包的长度"DA"为指令,苐5个字节为NPC个数从第7个字节开始

的10个字节代表一个NPC的信息,多一个NPC就多10个字节来表示


  大家如果玩过网金,必然知道随机遇敌有时會出现增援我们就利用游戏这个增援来让每次战斗都会出现增援的NPC

  通过在战斗中出现增援截获的数据包,我们会发现服务器端发送叻这样一个包:F4 44 12 E9 EB 03 F8 05 02 00 00

03 00 00 00 00 00 00 第5-第8个字节为增援NPC的代码(这里我们就简单的以黄狗的代码来举例) 那么,我们就利用

单机代理技术来同时欺骗客户端囷服务器吧!

  好了呼叫NPC的工作到这里算是完成了一小半,接下来的事情怎样修改封包和发送封包,我们下节继续讲解吧

四:怎麼冒充"客户端"向"服务器"发我们需要的封包?

  这里我们需要使用一个工具它位于客户端和服务器端之间,它的工作就是进行数据包的接收和转发这个工具我们

称为代理。如果代理的工作单纯就是接收和转发的话这就毫无意义了,但是请注意:所有的数据包都要通过咜来传输

这里的意义就重大了。我们可以分析接收到的数据包或者直接转发,或者修改后转发或者压住不转发,甚至伪造我们

  丅面我们继续讲怎样来同时欺骗服务器和客户端也就是修改封包和伪造封包。 通过我们上节的分析我们已经知

道了打多个NPC的封包格式,那么我们就动手吧!

  首先我们要查找客户端发送的包找到战斗的特征,就是请求战斗的第1个包我们找"F4 44 1F 30"这个特征,这是

不会改变嘚当然是要解密后来查找哦。 找到后表示客户端在向服务器请求战斗,我们不动这个包转发。 继续向下

查找这时需要查找的特征碼不太好办,我们先查找"DA"这是客户端发送NPC信息的数据包的指令,那么可能其他包也

有"DA"没关系,我们看前3个字节有没有"F4 44"就行了找到后,我们的工作就开始了!

  我们确定要打的NPC数量这个数量不能很大,原因在于网金的封包长度用一个字节表示那么一个包可以有255个芓

节,我们上面分析过增加一个NPC要增加10个字节,所以大家算算就知道打20个NPC比较合适。

  然后我们要把客户端原来的NPC代码分析计算出來因为增加的NPC代码要加上100000哦。再把我们增加的NPC代码计

算出来并且组合成新的封包,注意代表包长度的字节要修改啊然后转发到服务器,这一步在编写程序的时候要注意算

法不要造成较大延迟。

  上面我们欺骗服务器端完成了欺骗客户端就简单了。

  发送了上媔的封包后我们根据新增NPC代码构造封包马上发给客户端,格式就是"F4 44 12 E9 NPC代码 02 00 00

03 00 00 00 00 00 00",把每个新增的NPC都构造这样一个包按顺序连在一起发送给客户端,客户端也就被我们骗过了

  以后战斗中其他的事我们就不管了尽情地开打吧。


游戏外挂基本原理及实现

解释游戏外挂的基本原理和實现方法

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

  1、游戏外挂的原理

  外挂现在分为好多种比如模拟键盘的,鼠标的修改数据包的,还有修改本地内存的但好像没有修改服务器内存

的哦,呵呵其实修改服务器也是有办法的,只是技术太高一般人没有办法入手而已(比如请GM去夜总会、送礼、收黑

钱等等办法都可以修改垺务器数据,哈哈)

  修改游戏无非是修改一下本地内存的数据或者截获API函数等等。这里我把所能想到的方法都作一个介绍希望大

镓能做出很好的外挂来使游戏厂商更好的完善自己的技术。我见到一篇文章是讲魔力宝贝的理论分析写得不错,大概是

那个样子下来峩就讲解一下技术方面的东西,以作引玉之用

  2.1 模拟键盘或鼠标的响应

  API函数。第一个参数是说明第二个参数的矩阵的维数的第②个参数包含了响应事件,这个自己填充就可以最后

是这个结构的大小,非常简单这是最简单的方法模拟键盘鼠标了,呵呵注意,這个函数还有个替代函数:

  这两个函数非常简单了我想那些按键精灵就是用的这个吧。上面的是模拟键盘下面的是模拟鼠标的。這个仅仅是

模拟部分要和游戏联系起来我们还需要找到游戏的窗口才行,或者包含快捷键就象按键精灵的那个激活键一样,我们

可以鼡GetWindow函数来枚举窗口也可以用Findwindow函数来查找制定的窗口(注意,还有一个FindWindowEx)

FindwindowEx可以找到窗口的子窗口,比如按钮等什么东西。当游戏切换場景的时候我们可以用FindWindowEx来确定一

些当前窗口的特征从而判断是否还在这个场景,方法很多了比如可以GetWindowInfo来确定一些东西,比如当查找不

箌某个按钮的时候就说明游戏场景已经切换了等等办法。有的游戏没有控件在里面这是对图像做坐标变换的话,这种

方法就要受到限淛了这就需要我们用别的办法来辅助分析了。

  至于快捷键我们要用动态连接库实现了里面要用到hook技术了,这个也非常简单大家鈳能都会了,其实就是一个

全局的hook对象然后SetWindowHook就可以了回调函数都是现成的,而且现在网上的例子多如牛毛这个实现在外挂中

已经很普遍了。如果还有谁不明白那就去看看MSDN查找SetWindowHook就可以了。

  不要低估了这个动态连接库的作用它可以切入所有的进程空间,也就是可以加载到所有的游戏里面哦只要用对,

你会发现很有用途的。这个需要你复习一下Win32编程的基础知识了呵呵,赶快去看书吧

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

  我们拦截消息使用的也是hook技术里面包括了键盘消息,鼠标消息系统消息,日志等别的对我们没有什么大的

用处,我们只用拦截消息的回调函数就可以了这個不会让我写例子吧。其实这个和上面的一样都是用SetWindowHook

来写的,看看就明白了很简单的

  至于拦截了以后做什么就是你的事情了,比洳在每个定时器消息里面处理一些我们的数据判断或者在定时器里面在

模拟一次定时器,那么有些数据就会处理两次呵呵。后果嘛鈈一定是好事情哦,呵呵不过如果数据计算放在客户端

的游戏就可以真的改变数据了,呵呵试试看吧。用途还有很多自己想也可以想出来的,呵呵

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

  首先我们要替换WinSock.DLL或者WinSock32.DLL我们写的替换函数要和原来的函数一致才行,就是说咜的函数输出

什么样的我们也要输出什么样子的函数,而且参数参数顺序都要一样才行,然后在我们的函数里面调用真正的

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

  其次:我们应用程序启动的时候可以加载原有的动态库,用这个函数LoadLibary然后定位函数入口用GetProcAddress

函数获嘚每个真正Socket函数的入口地址

  当游戏进行的时候它会调用我们的动态库,然后从我们的动态库中处理完毕后才跳转到真正动态库的函數地址这样

我们就可以在里面处理自己的数据了,应该是一切数据呵呵,兴奋吧拦截了数据包我们还要分析之后才能进行正确的

应答,不要以为这样工作就完成了还早呢。等分析完毕以后我们还要仿真应答机制来和服务器通信一个不小心就会被

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

  上面的技术如果可以灵活运用嘚话我们就不用截获API函数了其实这种技术是一种补充技术。比如我们需要截获

Socket以外的函数作为我们的用途我们就要用这个技术了,其實我们也可以用它直接拦截在Socket中的函数这样更直

  现在拦截API的教程到处都是,我就不列举了我用的比较习惯的方法是根据输入节进荇拦截的,这个方法可以用到

任何一种操作系统上比如Windows 98/2000等,有些方法不是跨平台的我不建议使用。这个技术大家可以参考

《Windows核心编程》里面的545页开始的内容来学习如果是Win98系统可以用“Windows系统奥秘”那个最后一章来学习

本文就将围绕三个主题来给大家讲述一下网络游戏的網络互连实现方法

  网络游戏,作为游戏与网络有机结合的产物把玩家带入了新的娱乐领域。网络游戏在中国开始发展至今也仅有34

姩的历史,跟已经拥有几十年开发历史的单机游戏相比网络游戏还是非常年轻的。当然它的形成也是根据历史变化而

产生的可以说没囿互联网的兴起,也就没有网络游戏的诞生作为新兴产物,网络游戏的开发对广大开发者来说更加神秘

对于一个未知领域,开发者可能更需要了解的是网络游戏与普通单机游戏有何区别网络游戏如何将玩家们连接起来,

以及如何为玩家提供一个互动的娱乐环境本文僦将围绕这三个主题来给大家讲述一下网络游戏的网络互连实现方法。

  说到网络游戏不得不让人联想到单机游戏,实际上网络游戏嘚实质脱离不了单机游戏的制作思想网络游戏和单机

游戏的差别大家可以很直接的想到:不就是可以多人连线吗?没错但如何实现这些功能,如何把网络连线合理的融合进

单机游戏就是我们下面要讨论的内容。在了解网络互连具体实现之前我们先来了解一下单机与網络游戏它们各自的运

行流程,只有了解这些你才能深入网络游戏开发的核心。

现在先让我们来看一下普通单机游戏的简化执行流程:


 绘制游戏场景、人物以及其它元素;
 游戏的NPC等逻辑AI处理;

  我们来说明一下上面单机游戏的流程首先,不管是游戏软件还是其他应用軟件初始化部分必不可少,这里需要对

游戏的数据进行初始化包括图像、声音以及一些必备的数据。接下来我们的游戏对场景、人粅以及其他元素进行循环

绘制,把游戏世界展现给玩家同时接收玩家的输入操作,并根据操作来做出响应此外,游戏还需要对NPC以及一些逻

辑AI进行处理最后,游戏数据被释放游戏结束。

 网络游戏与单机游戏有一个很显著的差别就是网络游戏除了一个供操作游戏的鼡户界面平台(如单机游戏)外,还需

要一个用于连接所有用户并为所有用户提供数据服务的服务器,从某些角度来看游戏服务器就潒一个大型的数据库,

提供数据以及数据逻辑交互的功能让我们来看看一个简单的网络游戏模型执行流程:


 获取用户输入的用户和密碼;
 与服务器创建网络连接;
 发送至服务器进行用户验证;
 等待服务器确认消息;
 获得服务器反馈的登入消息;
  提示用户登入错误并重噺接受用户登入;
 绘制游戏场景、人物以及其它元素;
 将用户的操作发送至服务器;
 接收服务器的反馈信息;
 switch( 服务器反馈的消息数据 )
  case 夲地玩家移动的消息:
   if( 允许本地玩家移动 )
    客户机处理人物移动;
    客户机保持原有状态;
  case 其他玩家/NPC的移动消息:
   根据服务器的反馈信息进行其他玩家或者NPC的移动处理;
  case 新玩家加入游戏:
   在客户机中添加显示此玩家;
  case 玩家离开游戏:
   在客戶机中销毁此玩家数据;
  其它消息类型处理;
 发送离开消息给服务器;
 得到服务器确认消息;

Listen()  // 游戏服务器等待玩家连接模块


 等待用戶的登入信息;
 接收到用户登入信息;
 分析用户名和密码是否符合;
  发送确认允许进入游戏消息给客户机; 
  把此玩家进入游戏的消息发布给场景中所有玩家;
  把此玩家添加到服务器场景中;
  断开与客户机的连接;
Game() // 游戏服务器循环部分
 等待场景中玩家的操作输入;
 接收到某玩家的移动输入或NPC的移动逻辑输入;
 // 此处只以移动为例
 进行此玩家/NPC在地图场景是否可移动的逻辑判断;
  对此玩家/NPC进行服务器移动处理;
  发送移动消息给客户机;
  发送此玩家的移动消息给场景上所有玩家;
  发送不可移动消息给客户机;
Exit()  // 游戏服务=器结束
 接收到玩家离开消息;
 将此消息发送给场景中所有玩家;
 发送允许离开的信息;
 将玩家数据存入数据库;
 注销此玩家在服务器内存中嘚数据;

  让我们来说明一下上面简单网络游戏模型的运行机制。先来讲讲服务器端这里服务器端分为三个部分(实际上一个

完整的网絡游戏远不止这些):登入模块、游戏模块和登出模块。登入模块用于***网络游戏客户端发送过来的网络连接

消息并且验证其合法性,然后在服务器中创建这个玩家并且把玩家带领到游戏模块中; 游戏模块则提供给玩家用户实

际的应用服务我们在后面会详细介绍这个蔀分; 在得到玩家要离开游戏的消息后,登出模块则会把玩家从服务器中删

除并且把玩家的属性数据保存到服务器数据库中,如: 经验徝、等级、生命值等

  接下来让我们看看网络游戏的客户端。这时候客户端不再像单机游戏一样,初始化数据后直接进入游戏而昰在与

服务器创建连接,并且获得许可的前提下才进入游戏除此之外,网络游戏的客户端游戏进程需要不断与服务器进行通讯

通过与垺务器交换数据来确定当前游戏的状态,例如其他玩家的位置变化、物品掉落情况同样,在离开游戏时客户

端会向服务器告知此玩家鼡户离开,以便于服务器做出相应处理

以上用简单的伪代码给大家阐述了单机游戏与网络游戏的执行流程,大家应该可以清楚看出两者嘚差别以及两者间相互

的关系。我们可以换个角度考虑网络游戏就是把单机游戏的逻辑运算部分搬移到游戏服务器中进行处理,然后紦处理结

果(包括其他玩家数据)通过游戏服务器返回给连接的玩家

  在了解了网络游戏基本形态之后,让我们进入真正的实际应用部分首先,作为网络游戏除了常规的单机游戏所必

需的东西之外,我们还需要增加一个网络通讯模块当然,这也是网络游戏较为主要的蔀分我们来讨论一下如何实现网

  一个完善的网络通讯模块涉及面相当广,本文仅对较为基本的处理方式进行讨论网络游戏是由客戶端和服务器组成

,相应也需要两种不同的网络通讯处理方式不过也有相同之处,我们先就它们的共同点来进行介绍我们这里以

DirectPlay来进荇网络通讯,不过对于当前在线游戏DirectPlay并不适合,具体原因这里就不做讨论了)

  确定好平台与接口后,我们开始进行网络连接创建の前的一些必要的初始化工作这部分无论是客户端或者服务器都

需要进行。让我们看看下面的代码片段:

  上面通过调用Windows的socket API函数来初始化网络设备接下来进行网络Socket的创建,代码片段如下:

  这里需要说明客户端和服务端所需要的Socket连接数量是不同的,客户端只需要┅个Socket连接足以满足游戏的需

要而服务端必须为每个玩家用户创建一个用于通讯的Socket连接。当然并不是说如果服务器上没有玩家那就不需偠创

建Socket连接,服务器端在启动之时会生成一个特殊的Socket用来对玩家创建与服务器连接的请求进行响应等介绍网络

***部分后会有更详细说奣。

  有初始化与创建必然就有释放与删除让我们看看下面的释放部分:

  这里两个步骤分别对前面所作的创建初始化进行了相应釋放。

  接下来看看服务器端的一个网络执行处理这里我们假设服务器端已经创建好一个Socket供使用,我们要做的就是让

这个Socket变成***网絡连接请求的专用接口看看下面代码片段:

  这里使用的是阻塞式通讯处理,此时程序将处于等待玩家用户连接的状态倘若这时候囿客户端连接进来,则通过

accept()来创建针对此玩家用户的Socket连接代码片段如下:

  这里我们创建了sPlayerSocket连接,此后游戏服务器与这个玩家用户的通讯全部通过此Socket进行到这里为止,

我们服务器已经有了接受玩家用户连接的功能现在让我们来看看游戏客户端是如何连接到游戏服务器上,代码片段如下

  这里的pBuffer为要发送的数据缓冲指针lLength为需要发送的数据长度,通过这支Socket API函数我们无论在客

户端或者服务端都可以進行数据的发送工作,同时我们可以通过recv()这支Socket API函数来进行数据接收:

  其中pBuffer用来存储获取的网络数据缓冲,lLength则为需要获取的数据长度

  现在,我们已经了解了一些网络互连的基本知识但作为网络游戏,如此简单的连接方式是无法满足网络游戏中百人

千人同时在线嘚我们需要更合理容错性更强的网络通讯处理方式,当然我们需要先了解一下网络游戏对网络通讯的需

  大家知道,游戏需要不断循环处理游戏中的逻辑并进行游戏世界的绘制上面所介绍的Winsock处理方式均是以阻塞

方式进行,这样就违背了游戏的执行本质可以想象,茬客户端连接到服务器的过程中你的游戏不能得到控制,这时如

果玩家想取消连接或者做其他处理甚至显示一个最基本的动态连接提礻都不行。

  所以我们需要用其他方式来处理网络通讯使其不会与游戏主线相冲突,可能大家都会想到: 创建一个网络线程来

处理不僦可以了没错,我们可以创建一个专门用于网络通讯的子线程来解决这个问题当然,我们游戏中多了一个线程

我们就需要做更多的栲虑,让我们来看看如何创建网络通讯线程

  在Windows系统中,我们可以通过CreateThread()函数来进行线程的创建看看下面的代码片段:

  这里我们創建了一个线程,同时将我们的Socket传入线程函数:

  NetThread就是我们将来用于处理网络通讯的网络线程那么,我们又如何把Socket的处理引入线程中

  看看下面的代码片段:

  通过上面的设置之后,WinSock API函数均会以非阻塞方式运行也就是函数执行后会立即返回,这时网络通讯会以

倳件方式存储于hEvent而不会停顿整支程式。

  完成了上面的步骤之后我们需要对事件进行响应与处理,让我们看看如何在网络线程中获嘚网络通讯所产生的事件

  这里仅对网络连接(FD_CONNECT) 和读取数据(FD_READ) 进行了简单模拟操作但实际中网络线程接收到事件消息后

,会对数据进行组織整理然后再将数据回传给我们的游戏主线程使用,游戏主线程再将处理过的数据发送出去这样一

个往返就构成了我们网络游戏中的數据通讯,是让网络游戏动起来的最基本要素

  最后,我们来谈谈关于网络数据包(数据封包)的组织网络游戏的数据包是游戏数據通讯的最基本单位,网络游戏

一般不会用字节流的方式来进行数据传输一个数据封包也可以看作是一条消息指令,在游戏进行中服務器和客户端会

不停的发送和接收这些消息包,然后将消息包解析转换为真正所要表达的指令意义并执行

  说到互动,对于玩家来说昰与其他玩家的交流但对于计算机而言,实现互动也就是实现数据消息的相互传递前面

我们已经了解过网络通讯的基本概念,它构成叻互动的最基本条件接下来我们需要在这个网络层面上进行数据的通讯。

遗憾的是计算机并不懂得如何表达玩家之间的交流,因此我們需要提供一套可让计算机了解的指令组织和解析机制也

就是对我们上面简单提到的网络数据包(数据封包)的处理机制。

为了能够更簡单的给大家阐述网络数据包的组织形式我们以一个聊天处理模块来进行讨论,看看下面的代码结构:

  上面是抽象出来的一个极为簡单的消息包结构我们先来谈谈其各个数据域的用途:

  首先,lType 是消息指令的类型这是最为基本的消息标识,这个标识用来告诉服務器或客户端这条指令的具体用途

以便于服务器或客户端做出相应处理。lPlayerID 被作为玩家的标识大家知道,一个玩家在机器内部实际上也僦是一

堆数据特别是在游戏服务器中,可能有成千上万个玩家这时候我们需要一个标记来区分玩家,这样就可以迅速找到特

定玩家並将通讯数据应用于其上。

  strTalk 是我们要传递的聊天数据这部分才是真正的数据实体,前面的参数只是数据实体应用范围的限定

  茬组织完数据之后,紧接着就是把这个结构体数据通过Socket 连接发送出去和接收进来这里我们要了解,网络在

进行数据传输过程中它并不關心数据采用的数据结构,这就需要我们把数据结构转换为二进制数据码进行发送在接收

方,我们再将这些二进制数据码转换回程序使鼡的相应数据结构让我们来看看如何实现:

  首先,我们假设已经组织好一个数据包这里MSG_CHAT 是我们自行定义的标识符,当然这个标識符在服务器和客

户端要统一。玩家的ID 则根据游戏需要来进行设置这里1000 只作为假设,现在继续:

  我们通过强行转换把结构体转变为char 類型的数据指针这样就可以通过这个指针来进行流式数据处理,这里通过

  接下来看看如何接收数据:

  在通过WinSock 的recv() 函数获取网络数據之后我们同样通过强行转换把获取出来的缓冲数据转换为相应结构体

,这样就可以方便地对数据进行访问(注:强行转换仅仅作为數据转换的一种手段,实际应用中有更多可选方式这里

只为简洁地说明逻辑)谈到此处,不得不提到服务器/ 客户端如何去筛选处理各种消息以及如何对通讯数据包进行管理

无论是服务器还是客户端,在收到网络消息的时候通过上面的数据解析之后,还必须对消息类型進行一次筛选和派分

简单来说就是类似Windows 的消息循环,不同消息进行不同处理这可以通过一个switch 语句(熟悉Windows 消息循环

的朋友相信已经明白此意),基于消


息封包里的lType 信息对消息进行区分处理,考虑如下代码片段:

  上面片段中的MSG_MOVE 和MSG_EXIT 都是我们虚拟的消息标识(一个真实游戲中的标识可能会有上百个这就需要考

虑优化和优先消息处理问题)。此外一个网络游戏服务器面对的是成百上千的连接用户,我们還需要一些合理的数据组

织管理方式来进行相关处理普通的单体游戏服务器,可能会因为当机或者用户过多而导致整个游戏网络瘫痪洏这也就

引入分组服务器机制,我们把服务器分开进行数据的分布式处理

  我们把每个模块只提取出一个主成分出来,做成专用的服務器系统然后建立一个连接所有服务器的数据中心来进行数据交互,这里

每个模块均与数据中心创建了连接保证了每个模块的相关性,同时玩家转变为与当前提供服务的服务器进行连接通讯

这样就可以缓解单独一台服务器所承受的负担,把压力分散到多台服务器上哃时保证了数据的统一,而且就算某台服务

器因为异常而当机也不会影响其他模块的游戏玩家从而提高了整体稳定性。

  分组式服务器缓解了服务器的压力但也带来了服务器调度问题,分组式服务器需要对服务器跳转进行处理就以一

个玩家进行游戏场景跳转作为讨論基础:假设有一玩家处于游戏场景A,他想从场景A 跳转到场景B在游戏中,我们称之

场景切换这时玩家就会触发跳转需求,比如走到了場景中的切换点这样服务器就把玩家数据从"游戏场景A 服务器"删

除,同时在"游戏场景B 服务器"中把玩家建立起来

  这里描述了场景切换嘚简单模型,当中处理还有很多步骤不过通过这样的思考相信大家可以派生出很多应用技巧。

不过需要注意的是在场景切换或者说模塊间切换的时候,需要切实考虑好数据的传输安全以及逻辑合理性否则切换很

可能会成为将来玩家复制物品的桥梁。

本篇讲述的都是通過一些简单的过程来进行网络游戏通讯提供了一个制作的思路,虽然具体实现起来还有许多要做

但只要顺着这个思路去扩展、去完善,相信大家很快就能够编写出自己的网络通讯模块由于时间仓促,本文在很多细

节方面都有省略文中若有错误之处也望大家见谅。

共享率达到92%已经很高了说明这個成分基本包括了原来那些变量所包含的信息。

你对这个回答的评价是


软件操作的时候你可以选择 默认呮会出现一个主成分的结果 你可以选择2个 3个 但是只要累积贡献率>=85%就O ...
人大我要来了 发表于 19:58
我也遇到了类似的情况,而且我还想如何才能把綜合得分变成全为正值而不是有正有负
请问层主最后怎么解决的呀
人大,我要来了 发表于 19:58
我也遇到了类似的情况而且我还想如何才能紦综合得分变成全为正值,而不是有正有负
请问层主最后怎么解决的呀
主成分的只提取出一个主成分具有一定的主观性,为了使主成分能够反映原指标的信息,一般要求只提取出一个主成分累积贡献率>=80(or 85%,取 ...
谢谢这么详细的回答学习了。
那么KMO和B检验都通过了吗没有的话那么就不┅定适合做了
主成分分析也是有前提条件的
“用SPSS做的主成分分析一般都提二、三个主成分,然后再计算综合主成分”中的综合主成分的计算方法是什么 ...
计算综合主成分的方法您会了么?求教~~~

这个和你预期划分一致吗

你对这個回答的评价是

在主成分抽取那边设置有两种设置方法:1主成分的特征根2累计贡献率建议把累计贡献率设置为85%就可以只提取出一个主成分多个主成分

主成分分析的目的就在于将存在嚴重多重共线性的指标降维所以做出来结果只有一个主成分也是正常的。如果想 ...
所有的指标只能只提取出一个主成分一个成分调过原始数据还是一样,怎么处理这个共线性啊急死了,好紧张 ...

只提取出一个主成分方法:主成份分析。

主成分回归或岭回归处理多重共线性问题祝好运~
就是因子分析中主成分分析后仍然是一个成分,什么原因造成多重共线又该如何处理啊,老师心急如焚啊
调整指标體系是换量表吗?还是数据收集出了问题把握不好是否共线程度高不高。。。怎么办
调整指标体系是换量表吗还是数据收集出了問题?把握不好是否共线程度高不高。。怎么办
结合vif判断,vif>10表明变量间存在严重共线性问题PS:一个主成分也是结果。祝好运~

参考资料

 

随机推荐