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,"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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是