Cocos2d-x 游戏资源(图片、XML、TXT等)打包加密 之 解密读取

自上一篇  Unity3d 游戏资源打包加密(图片/XML/TXT等) C#编码 (一)   介绍如何打包加密游戏资源已经好几月,却没有详细说明如何在游戏中去读取加密的资源,虽然聪明的程序员看一眼就知道如何逆向编码,但是还是详细说明一下,以作完结。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

Cocos2d-X 资源加密与解密

加密只有一篇即可,解密分为两篇,Cocos2d-x 篇 和 Unity3d 篇。

首先,这一篇介绍Cocos2d-x 读取加密的资源。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

以下内容需要对Cocos2d-x 稍微深入了解。

XML和文档的读取没啥好讲的,完全不涉及Cocos2d-X。这里不做介绍,如果想了解,请百度C++/C如何读取文件以及各大XML库如何读取XML文件。

下面开始我们的解密之旅。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

Cocos2d-x中CCSprite的Create流程

首先我要提一下,在Cocos2d-X中显示一张图片,一般是直接在CCSprite中带图片路径参数去实例化。百分之九十的程序猿们都是这样用的,简单粗暴。但是一旦需要自己对图片进行加密之后,就不能在直接传入图片路径进行实例化,这下该如何是好……

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

嗯,Cocos2d-X的好处这个时候就提现出来了,开源免费,我们想看啥就看啥,想改啥就改啥。

作为一个合格的程序员一定要具备看源代码的能力。

下面来看一下CCSprite的部分源代码:

class CC_DLL Sprite : public Node, public TextureProtocol
{
public:

    static const int INDEX_NOT_INITIALIZED = -1; /// Sprite invalid index on the SpriteBatchNode

    /// @{
    /// @name Creators

    /**
     * Creates an empty sprite without texture. You can call setTexture method subsequently.
     *
     * @return An autoreleased sprite object.
     */
    static Sprite* create();

    /**
     * Creates a sprite with an image filename.
     *
     * After creation, the rect of sprite will be the size of the image,
     * and the offset will be (0,0).
     *
     * @param   filename A path to image file, e.g., "scene1/monster.png"
     * @return  An autoreleased sprite object.
     */
    static Sprite* create(const std::string& filename);

    /**
     * Creates a sprite with an image filename and a rect.
     *
     * @param   filename A path to image file, e.g., "scene1/monster.png"
     * @param   rect     A subrect of the image file
     * @return  An autoreleased sprite object
     */
    static Sprite* create(const std::string& filename, const Rect& rect);

    /**
     * Creates a sprite with a Texture2D object.
     *
     * After creation, the rect will be the size of the texture, and the offset will be (0,0).
     *
     * @param   texture    A pointer to a Texture2D object.
     * @return  An autoreleased sprite object
     */
    static Sprite* createWithTexture(Texture2D *texture);

    /**
     * Creates a sprite with a texture and a rect.
     *
     * After creation, the offset will be (0,0).
     *
     * @param   texture    A pointer to an existing Texture2D object.
     *                      You can use a Texture2D object for many sprites.
     * @param   rect        Only the contents inside the rect of this texture will be applied for this sprite.
     * @param   rotated     Whether or not the rect is rotated
     * @return  An autoreleased sprite object
     */
    static Sprite* createWithTexture(Texture2D *texture, const Rect& rect, bool rotated=false);

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

从源代码中看到,CCSprite不只有传入文件路径这一种实例化的方式,还可以传入一个Texture2D 来实例化。

Texture2D是什么?

学习过OpenGL的朋友就知道,Texture在GL中就是存储纹理数据的一块内存,至于Texture2D,无非就是一块内存。

那内存里面放着什么,肯定就是纹理数据了。

那纹理数据从哪来,肯定是读取文件来的。

那文件是什么,一块数据。

至此流程明了,这一实例化流程和我们的目的一致。

即:用一块数据来实例化一个Texture2D,然后实例化CCSprite。

根据上面的流程,我们下一步要做的就是,实例化一个 Texture2D 。

我们来看Texture2D的源代码

// implementation Texture2D (Image)
bool Texture2D::initWithImage(Image *image)
{
    return initWithImage(image, g_defaultAlphaPixelFormat);
}

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

然后我们需要的就是 实例化一个Image。

在CCImage中,先来看这个函数

bool Image::initWithImageFile(const std::string& path)
{
    bool ret = false;
    _filePath = FileUtils::getInstance()->fullPathForFilename(path);

#ifdef EMSCRIPTEN
    // Emscripten includes a re-implementation of SDL that uses HTML5 canvas
    // operations underneath. Consequently, loading images via IMG_Load (an SDL
    // API) will be a lot faster than running libpng et al as compiled with
    // Emscripten.
    SDL_Surface *iSurf = IMG_Load(fullPath.c_str());

    int size = 4 * (iSurf->w * iSurf->h);
    ret = initWithRawData((const unsigned char*)iSurf->pixels, size, iSurf->w, iSurf->h, 8, true);

    unsigned int *tmp = (unsigned int *)_data;
    int nrPixels = iSurf->w * iSurf->h;
    for(int i = 0; i < nrPixels; i++)
    {
        unsigned char *p = _data + i * 4;
        tmp[i] = CC_RGB_PREMULTIPLY_ALPHA( p[0], p[1], p[2], p[3] );
    }

    SDL_FreeSurface(iSurf);
#else
    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);

    if (!data.isNull())
    {
        ret = initWithImageData(data.getBytes(), data.getSize());
    }
#endif // EMSCRIPTEN

    return ret;
}

这个函数的功能就是,根据传进来的参数-图片路径,读取这个图片路径的文件,获取数据,然后根据这块数据,来实例化 Texture2D 。

好的,终于到了最后一步,直接和内存打交道了。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

下面整理一下CCSprite的实例化流程:

好了,首先我们来按照上面的流程,读取一张未加密图片,例化一个CCSprite 。

读取未加密图片

一贯作风,还是拿HelloWorld 作为例子,以下代码

	Image* image = new Image();

	Data data = FileUtils::getInstance()->getDataFromFile("Deemo.jpg");

	image->initWithImageData(data.getBytes(), data.getSize());

	Texture2D* texutre=new Texture2D();
	texutre->initWithImage(image);

	Sprite* sprite=Sprite::createWithTexture(texutre);

    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize / 2) + origin);

    // add the sprite as a child to this layer
    this->addChild(sprite);

运行成功

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

对图片打包加密

首先我们使用之前编写的资源打包加密工具对图片进行打包加密。

http://download.csdn.net/detail/cp790621656/8393457

在配置文件中添加要打包的文件夹的名字,一行一个。然后运行程序打包,我这里打包 Deemo 这个文件夹,生成了Deemo.UPK 。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

对加密的资源进行解密

上篇博客虽然介绍了打包加密的原理以及贴上了代码,但可能还是不够明了,我这里贴上UPK文件的内存结构图,这样大家对UPK就能一目了然。

好了,知道了UPK的内存结构,我们就可以开始在Cocos2d-X中去读取我们想要的数据了。

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

首先我们读取出文件头

void HelloWorld::InitUPKFileSystem()
{
	std::string fullPath = FileUtils::getInstance()->fullPathForFilename("Deemo.UPK");
	std::ifstream fin(fullPath.c_str(),std::ios::binary);
	if (!fin)
	{
		CCLOG("File Open Error");
		return;
	}
	//首先读取文件数量4byte;
	char fileCountArr[4];

	fin.read(fileCountArr,4);

	int fileCount=0;

	memcpy(&fileCount,fileCountArr,4);

	//然后循环读取文件信息;
	for (int index=0;index<fileCount;index++)
	{
		OneFileInfor oneFileInfor;

		//读取m_id;
		char idArr[4];
		int id=0;
		fin.read(idArr,4);
		memcpy(&id,idArr,4);
		oneFileInfor.m_id=id;

		//读取m_StartPos;
		char startPosArr[4];
		int startPos=0;
		fin.read(startPosArr,4);
		memcpy(&startPos,startPosArr,4);
		oneFileInfor.m_StartPos=startPos;

		//读取m_Size;
		char sizeArr[4];
		int size=0;
		fin.read(sizeArr,4);
		memcpy(&size,sizeArr,4);
		oneFileInfor.m_Size=size;

		//读取m_Path;
		char pathArr[256];
		std::string path;
		fin.read(pathArr,256);
		path=pathArr;
		oneFileInfor.m_Path=path;

		m_allFileInforVec.push_back(oneFileInfor);
	}
	fin.close();

}

然后根据文件路径,查找到对应的OneFileInfor,然后根据m_StartPos进行偏移读取m_Size大小的数据即可。

cocos2d::Data HelloWorld::GetDataFromUPK(const char* filepath)
{
	Data ret;

	//根据文件路径找到文件信息;
	for (int index=0;index<m_allFileInforVec.size();index++)
	{
		OneFileInfor oneFileInfor=m_allFileInforVec[index];
		std::string path=filepath;
		if (oneFileInfor.m_Path==path)
		{
			//找到了文件,开始读取文件数据;
			std::string fullPath = FileUtils::getInstance()->fullPathForFilename("Deemo.UPK");
			std::ifstream fin(fullPath.c_str(),std::ios::binary);
			if (!fin)
			{
				CCLOG("File Open Error");
				return ret;
			}

			char* buffer=NULL;
			buffer=(char*)malloc(oneFileInfor.m_Size);

			fin.seekg(oneFileInfor.m_StartPos,std::ios::beg); //ios::cur从当前位置偏移;ios::beg从文件开头偏移;

			fin.read(buffer,oneFileInfor.m_Size);

			ret.fastSet((unsigned char *)buffer,oneFileInfor.m_Size);

			fin.close();

			break;
		}

	}

	return ret;
}

成功运行转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

工程下载:转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

http://pan.baidu.com/s/1pJkf2mJ
http://download.csdn.net/detail/cp790621656/8609965

转自陈里陈外的博客 http://blog.csdn.net/huutu 星环游戏 http://www.thisisgame.com.cn

时间: 2024-08-26 18:14:35

Cocos2d-x 游戏资源(图片、XML、TXT等)打包加密 之 解密读取的相关文章

Unity3d 游戏资源打包加密(图片/XML/TXT等) C#编码 (一)

本文只是讲述一下过程,采用很简单的打包加密方法,至于需要什么样的加密结果,请大家按照需求去修改,字节偏移.前后颠倒加算法都可以,不过一般无需这么复杂,而且太复杂的加密对于极其追求运行效率的游戏来说,也是一重负担. 对于Unity,虽然Unity自身会进行压缩加密,但是其解密算法在网上随处可见,如果自己觉得游戏里面的资料具有保密性质,请对其进行自行加密. 打包加密的原理: 1.大家都知道文件都是由字节组成的. 2.一张图片之所以看起来很漂亮,是因为其数据按照一定顺序排列. 漂亮的剑灵妹子 我们可以

Unity3D游戏开发之使用disunity提取Unity3D游戏资源

各位朋友,大家好,我是秦元培.今天博主想和分享的是使用disunity提取Unity3D游戏素材.这个工具呢,博主在Unity3D游戏开发之反编译AssetBundle提取游戏资源这篇文章中其实已经提到过了,不过因为有些朋友对如何使用这个工具依然存在问题,所以博主决定特地写一篇文章来讲解如何使用disunity来提取Unity3D游戏中的素材. 准备工作 disunity:负责对Unity3D的数据文件进行解包 Unity3D:负责将导出的数据文件显示出来 Bleander或者3DsMax:负责

一起学android之对资源图片进行比例缩放 (27)

效果图: 在平时加载图片时,我会使用SetImageBitmap.setImageResource.BitmapFactory.decodeResource来设置一张图 片通过以上方法来设置图片时,会通过Java层的createBitmap来完成,这样的话会消耗很多内存,容易导致 OOM(Out Of Memory),因此推荐使用BitmapFactory.Options这个类来设置一张资源图. 参看以下代码: public class MainActivity extends Activity

Unity 提取游戏资源之ktx转换

从雨松的博文<Unity3D研究院之mac上从.ipa中提取unity3D游戏资源(六十六)>可以学到提取Unity的游戏资源,其中有用到一个工具:PVRTexTool 因为这个工具的官网不好下载,故将其上传到CSDN,下载地址:http://download.csdn.net/detail/akof1314/7660209 提取出来的资源,其中的ktx资源,用PVRTexToolGUI.exe可以打开查看,可以发现都是上下颠倒,且被拉伸 直接转为png格式的批处理脚本为: 1 2 3 4 5

cocos2dx游戏资源加密之XXTEA

在手机游戏当中,游戏的资源加密保护是一件很重要的事情. 我花了两天的时间整理了自己在游戏当中的资源加密问题,实现了跨平台的资源流加密,这个都是巨人的肩膀之上的. 大概的思路是这样的,游戏资源通过XXTEA加密方法对流的加密方式,有自己的密钥和标识,通过标识可知是否有加密,密钥是自己程序当中的.除非有密钥,否则很难通过解出正确的文件.经过加密后,加密文件也就是游戏资源放在resource的自己文件夹中,否则在xcode编译到趁机是会识别不了文件.在程序中cocos2dx底层加入解密过程,就可以把文

[Unity Asset]AssetBundle系列——游戏资源打包

转载:http://www.cnblogs.com/sifenkesi/p/3557231.html 将本地资源打包,然后放到资源服务器上供游戏客户端下载或更新.服务器上包含以下资源列表:(1)游戏内容资源assetbundle(2)资源维护列表,包含每个资源的名字(完整路径名)和对应的版本号[资源名,版本号],如下表所示(VersionNum.xml): <VersionNum> <File FileName="Assets.Resources.BigLevelTexture

Android实战简易教程-第九枪(BitmapFactory.Options对资源图片进行缩放)

我们知道,我们编写的应用程序都是有一定内存限制的,程序占用了过高的内存就容易出现OOM(OutOfMemory)异常.因此在展示高分辨率图片的时候,最好先将图片进行压缩,压缩后的图片大小应该和用来展示它的控件大小相近,这样可以兼顾显示效果和内存占用. BitmapFactory.Options这个类,有一个字段叫做 inJustDecodeBounds .SDK中对这个成员的说明是这样的: If set to true, the decoder will return null (no bitm

【转】Unity3D AssetBundles 动态加载游戏资源

AssetBundles are files which you can export from Unity to contain assets of your choice. These files use a proprietary compressed format and can be loaded on demand in your application. This allows you to stream content like models, textures, audio c

《双星物语》游戏资源格式分析与解包

作为一款 2001 年发行的老游戏,封包算法应该不会很复杂才对,抱着这样想法的博主,尝试着去分析游戏资源包的封包格式,最后成功将资源解包,下面我们来看看双星物语的游戏资源包封包格式: 游戏资源包以 dat 作为扩展名,一共有两个,分别是 wav.dat 和 BIN.dat,其中 wav.dat 体积较小,先从它下手,用十六进制编辑器打开后,可以看到整齐的文件头部,经过观察发现,整个资源包以[包头][文件类型信息][文件信息][文件数据]这样子的结构组织而成: 首先是[包头],大小为 8 字节,前