【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】
游戏开发中常遇到资源保护的问题。
目前游戏开发中常加密的文件类型有:图片,Lua文件,音频等文件,而其实加密也是一把双刃剑。
需要安全那就得耗费一定的资源去实现它。目前网上也有用TexturePacker工具来加密的,不过针对性还是不够强。
分析一下原理为:
1,转格式:将需要加密的文件转为流的方式;
2,加密:根据自己需要使用加密手段,MD5,AES,甚至可以直接改变位移,加一些自己的特殊字符也可以使文件简单加密,加密完后基本保证
图片类型基本用特殊软件预览不了也打不开,Lua文件加密后一片乱码····;
3,保存自定义格式文件:另存为自己特殊类型的文件名如"xx.d" "xx.xyz"等。
4,图片解密:修改cocos2dx底层库的获取路径处,和加载CCImage纹理处理时的源码修改;
5,特殊Lua文件界面:修改对应Lua加载方法;
基本原理清楚了后我贴几段我自己项目中常用的加密方式:
首先是转格式并且加密的方式
bool PublicCommen::recode_getFileByName(string pFileName){
unsigned long nSize = ;
unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(
pFileName.c_str(),
"rb",&nSize);
unsigned char* newBuf = new unsigned char[nSize];
int newblen = nSize;
if(pBuffer!=NULL&&nSize>)
{
for (int i = ; i<nSize; i++) {
newBuf[i]=pBuffer[i]+MD5;
}
string savepath = pFileName;
savepath = savepath.substr(,savepath.length()-);
savepath = savepath + "xx.X";
FILE *fp = fopen(savepath.c_str(), "wb+");
fwrite(newBuf, , newblen, fp);
fclose(fp);
CCLOG("save file ok. path = %s" ,savepath.c_str());
return true;
}
return false;
}
通常可以自己写一个应用程序遍历一下自定义目录下,需要转的资源文件,对应的把所有资源转换并加密;
里面newBuf[i]=pBuffer[i]+MD5;这段可以自由发挥!解密的时候需要对应!
当然你也可以取巧的放进你的游戏中修改cocos2dx底层的CCFileUtils::fullPathForFilename获取全路径的方法中;
下面说一下解密:
图片的解密需要修改cocos2dx CCTexture2D 的CCTextureCache::addImage类里面修改
CCTexture2D * CCTextureCache::addImage(const char * path)
{
CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL"); CCTexture2D * texture = NULL;
CCImage* pImage = NULL;
// Split up directory and filename
// MUTEX:
// Needed since addImageAsync calls this method from a different thread //pthread_mutex_lock(m_pDictLock); std::string pathKey = path; pathKey = CCFileUtils::sharedFileUtils()->fullPathForFilename(pathKey.c_str());
if (pathKey.size() == )
{
return NULL;
}
texture = (CCTexture2D*)m_pTextures->objectForKey(pathKey.c_str()); std::string fullpath = pathKey; // (CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(path));
if (! texture)
{
std::string lowerCase(pathKey);
for (unsigned int i = ; i < lowerCase.length(); ++i)
{
lowerCase[i] = tolower(lowerCase[i]);
}
// all images are handled by UIImage except PVR extension that is handled by our own handler
do
{
if (std::string::npos != lowerCase.find(".pvr"))
{
texture = this->addPVRImage(fullpath.c_str());
}
else if (std::string::npos != lowerCase.find(".pkm"))
{
// ETC1 file format, only supportted on Android
texture = this->addETCImage(fullpath.c_str());
}
else
{
CCImage::EImageFormat eImageFormat = CCImage::kFmtUnKnown;
if (std::string::npos != lowerCase.find(".png"))
{
eImageFormat = CCImage::kFmtPng;
}
else if (std::string::npos != lowerCase.find(".jpg") || std::string::npos != lowerCase.find(".jpeg"))
{
eImageFormat = CCImage::kFmtJpg;
}
else if (std::string::npos != lowerCase.find(".tif") || std::string::npos != lowerCase.find(".tiff"))
{
eImageFormat = CCImage::kFmtTiff;
}
else if (std::string::npos != lowerCase.find(".webp"))
{
eImageFormat = CCImage::kFmtWebp;
}
else if (std::string::npos != lowerCase.find("XX.X"))
{
eImageFormat = CCImage::xxxxx;
} pImage = new CCImage();
CC_BREAK_IF(NULL == pImage); bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);
CC_BREAK_IF(!bRet); texture = new CCTexture2D(); if( texture &&
texture->initWithImage(pImage) )
{
#if CC_ENABLE_CACHE_TEXTURE_DATA
// cache the texture file name
VolatileTexture::addImageTexture(texture, fullpath.c_str(), eImageFormat);
#endif
m_pTextures->setObject(texture, pathKey.c_str());
texture->release();
}
else
{
CCLOG("cocos2d: Couldn't create texture for file:%s in CCTextureCache", path);
}
}
} while ();
} CC_SAFE_RELEASE(pImage); //pthread_mutex_unlock(m_pDictLock);
return texture;
}
并且在CCImage的图片类型中添加你加密后的图片类型如:CCImage::xxxxx
然后跟到 bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);
CCImage.mm中的CCImage::initWithImageFile方法;
bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)
{
bool bRet = false;
unsigned long nSize = ;
unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(
CCFileUtils::sharedFileUtils()->fullPathForFilename(strPath).c_str(),
"rb",
&nSize);
if(eImgFmt==xxxxxx)
{
for (int i= ; i < nSize; i++) {
pBuffer[i] = pBuffer[i]-MD5;
}
pBuffer[nSize] = pBuffer[nSize]-;
eImgFmt = kFmtPng;
} if (pBuffer != NULL && nSize > )
{
bRet = initWithImageData(pBuffer, nSize, eImgFmt);
}
CC_SAFE_DELETE_ARRAY(pBuffer);
return bRet;
}
其中 pBuffer[i] = pBuffer[i]-MD5;需要和之前加密的时候对应·····自己发挥!
Ok,只要是图片,并且是属于你自定义类型的图片都会得到解密的真实texture。
Lua的解密也是基本一样的思路,不过解密需要单独在需要加载Lua的方法前先解密,要考虑跨平台性
【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】的更多相关文章
- 【cocos2d-x 手游研发小技巧(6)聊天系统+字体高亮】
转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html 聊天系统在手机网游中是最常见的交互工具,大家在一起边玩游戏边聊天岂不乐哉: 废话不多了 ...
- 【cocos2d-x 手游研发小技巧(8)通讯的数据压缩与解压 】
今天说一下手机游戏通讯协议中的数据问题,大量的数据将给服务器端和客户端带来很大的压力,一般来说. 转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-8 ...
- 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】
直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...
- 【cocos2d-x 手游研发小技巧(5)获取网络图片缓存并展示】
今天是年前最后一天上班了,最后一天上班,祝大家马上有各种东西,最后一天也给写一点干货,就是获取网络图片: 经过自己简单封装了一下,实现了获取网络图片,按照比例展示出来,实现方法是cocos2dx - ...
- 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】
cocos2dx在android平台上的游戏开发中往往会遇到一些混编需求,如: 比方有的社区类游戏需要用到更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取 ...
- 【cocos2d-x 手游研发小技巧(3)Android界面分辨率适配方案】
先感叹一下吧~~android的各种分辨率各种适配虐我千百遍,每次新项目我依旧待它如初恋···· 每家公司都有自己项目工程适配的方案,这种东西就是没有最好,只有最适合!!! 这次新项目专项针对andr ...
- 【cocos2d-x 手游研发小技巧(2)循环无限滚动的登陆背景】
原创文章,转载请附上链接:http://www.cnblogs.com/zisou/p/cocos2d-xARPG6.html 首先让大家知道我们想要实现的最终效果是什么样的? 看一个<逆天仙魔 ...
- 【cocos2d-x 手游研发----目录】
感谢大家一直支持我写这样一系列的博客,从中我自己也获益良多,cocos2d-x这样一款非常棒的引擎,是值得我们去学习和分享的,谈到分享,那我就把这套写了差不多一两个月的框架给大家开源下载,写的很一般, ...
- 【cocos2d-x 手游研发----地图活起来了】
谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法. 我做了一个简单的地图的思想,就是地图分层3层:背景层.可行区域层.遮罩层,但是地图就 ...
随机推荐
- day10:vcp考试
Q181. An administrator is deploying ESXi 6.x hosts using Auto Deploy and wants the image profile to ...
- VC2008 类型重定义的问题
Q: 比如"a.h"里定义了类a,类a所有函数的实现都放在"a.cpp"里.然后"b.h"和"c.h"都需要用到类a,所 ...
- DataTable的序列化和反序列化
/// <summary> /// DataTable序列化 /// </summary> /// <param name="dt"></ ...
- yii2中的rules 自定义验证规则详解
yii2的一个强大之处之一就是他的Form组件,既方便又安全.有些小伙伴感觉用yii一段时间了,好嘛,除了比tp"难懂"好像啥都没有. 领导安排搞一个注册的功能,这家伙刷刷刷的又是 ...
- IE8以下支持css3 border-radius渲染方法
这两天在做个集团网站,web前端妹子技术水平不咋样,写个web和wap 真够费劲的,对之前流行的H5和css3 响应式看来不太会用,扔给我一个半成品~~·非说各种canvas和border-radiu ...
- winsock select 学习代码(2)
之前文章的改进版 服务器仅仅接受客户端发送的字符串并显示 客户端可以调节发送数目 但是不能超过64 // SelectServer.cpp : 定义控制台应用程序的入口点. // #include & ...
- javascript札记
bind和unbind对应,live和die对应,千万别用bind绑定,用die解除.还有bind可以多次绑定同一个函数,可能会被执行多次同一个函数 正则表达式的使用 var email_reg = ...
- Netty学习第六节实例一步学习
NIO与传统IO对应使用的类: ServerSocketChannel相当于ServerSocket SocketChannel 相当于Socket Selector是NIO的核心类,是负责监听Ser ...
- jdbcmysql
做java开发难免会用到数据库,操作数据库也是java开发的核心技术.那我们现在就来谈谈javajdbc来操作mysql数据库吧 第一步:我们需要把mysql的驱动引进来这里引驱动就是把mysql-c ...
- 用Node完成AWS S3的Upload流程之全世界最简版
开场: 查了两天文档,Error了38次,最后索性去掉所有附加条件, 连界面也不要了,在命令行里跑通了一坨最干瘪的Upload流程! 还冒着热气…… 在此先做记录,明天可以搭配美美的界面继续调试了. ...