2D网络游戏开发(网络篇)(七)1

来源:互联网 发布:打车软件司机端 编辑:程序博客网 时间:2024/04/30 02:26
2D网络游戏开发(网络篇)(七)
 
作者:akinggw
 
在前面的章节中,我们讲解了如何在服务器和客户端之间如何传输信息,今天,我们将讲解在它们之间如何传输文件。这个功能很重要,比如,在网络游戏中,为了保持游戏的新颖,游戏每次开始时都需要更新数据。
而我们今天的内容就是讲解如何在客户端和服务器之间传输文件。
这个系统的名字叫自动补丁系统(autopatcher),它不包括在raknet库文件中。是一个分开的类,在后面,我们将讲解它的使用。
Autopatcher系统主要的工作就是在两个和两个以上的系统之间传输一些它们之前没有的,或是改变了的文件。它主要的工作就是传输文件,压缩这些传输文件,保证文件传输安全和文件操作。它并不提供基本的连接或用户接口,(这些你可以采用raknet中的功能完成)。Autopatcher通常用于商业游戏。
每个系统都需要建立autopatcher类实例。Autopatcher类包含四个文件Autopatcher.cpp, Autopatcher.h, DownloadableFileDescriptor.cpp, and DownloadableFileDescriptor.h。再次重申,Autopatcher并不包含在raknet库文件中,所以调试的时候有点不同。
这些文件都包含在Source/Autopatcher目录下,在编译时,要包含这个文件夹下的所有文件。因为在实际的游戏编程中可能需要修改这些文件。
接下来,就是要告诉autopatcher哪些文件可以被下载。这件事可以用SetFileDownloadable(char *filename, bool checkFileSignature)函数来设置。这个函数的作用就是将文件读入到内存,如果文件很大,就需要压缩它,最后将这些可下载文件添加到一个中心列表上。函数的第一个参数是文件的路径。第二个参数是一个bool值,这个参数的目的就是用于数字签名,用于检测文件在传输过程中是否被修改。如果设置成真的话,就将有一个和我们的文件名相同的文件XX.sha来描述我们的文件。你可以调用CreateFileSignature函数来建立这个签名文件。如何文件签名检测失败,SetFileDownloadable将返回SET_FILE_DOWNLOADABLE_FILE_NO_SIGNATURE_FILE或者SET_FILE_DOWNLOADABLE_FILE_SIGNATURE_CHECK_FAILED.
假如这些系统都已经连接,如果你想下载的话,就可以调用RequestDownloadableFileList函数来建立下载系统;如果你只想更新的话,就可以调用SendDownloadableFileList来建立你的更新系统。
当你得到你的Packet::data中的第一个字节包含下面的包ID时:
 
ID_AUTOPATCHER_FILE_LIST
ID_AUTOPATCHER_REQUEST_FILES
ID_AUTOPATCHER_SET_DOWNLOAD_LIST
ID_AUTOPATCHER_WRITE_FILE
 
就将将那整个包发送给相应的函数:
 
void OnAutopatcherFileList(Packet *packet,bool onlyAcceptFilesIfRequested);
void OnAutopatcherRequestFiles(Packet *packet);
void OnAutopatcherSetDownloadList(Packet *packet);
void OnAutopatcherWriteFile(Packet *packet);
 
下面,我们来具体地看一下,代码是如何实现的。
 
首先,你需要在你的项目中设置一个参数,因为autopatcher在压缩文件的时候使用了zlib这个压缩包。因此,在编译文件时,你应该加载它。我使用的是dev c++,因此,我需要现下载一个zlib.devpak,然后安装它,在项目设置中,包含它们的库文件:
lib/RakNet.a
lib/libws2_32.a
lib/libz.a
 
如果你使用VC,也需要同样的操作。
项目设置好了以后,就需要在代码中包含autopatcher的头文件:
 
#include "Autopatcher.h"
#include "Autopatcher.cpp"
#include "DownloadableFileDescriptor.h"
#include "DownloadableFileDescriptor.cpp"
 
这个例子在raknet的example文件下。
然后定义一个AutoPatcher 实例:
 
AutoPatcher autoPatcher;
 
你需要写一个函数来分析你所下载文件的信息:
 
unsigned int ShowDownloadStatus(AutoPatcher *autoPatcher)
{
char fileName[256];
unsigned numberOfDownloadingFiles;
unsigned fileLength, compressedFileLength;
bool dataIsCompressed;
 
numberOfDownloadingFiles = autoPatcher->GetDownloadStatus(fileName, &fileLength, &dataIsCompressed, &compressedFileLength);
if (numberOfDownloadingFiles>0)
{
       printf("n%i 有多少个文件在下载列表中n", numberOfDownloadingFiles);
       printf("当前文件: %s (%i 字节数)n", fileName, fileLength);
        if (dataIsCompressed==false)
               printf("文件无压缩传输。n");
        else
               printf("文件被压缩成了 %i 字节n",compressedFileLength);
}
else
       printf("当前没有可下载的文件n");   
 
return numberOfDownloadingFiles;
}
这个函数最后返回我们要下载的文件的个数。
 
其中,GetDownloadStatus函数原型如下:
 
unsigned int AutoPatcher::GetDownloadStatus ( char * filename, 
 unsigned * fileLength, 
 bool * fileDataIsCompressed, 
 unsigned * compressedFileLength
 )  
这个函数返回下载列表中有多少个文件。
第一个参数filename , 当前已下载的文件;
第二个参数fileLength, 当前已下载文件的长度;
第三个参数fileDatalsCompressed, 文件是否压缩;
第四个参数compressedFileLength, 如果文件压缩,返回它的大小。
 
这个函数返回下载列表中文件的个数。
 
我们在这个例子中使用的是peer to peer方式,这样做的好处是为了使其简单,关于c/s的方式,还在进一步研究当中。
原创粉丝点击