游戏开发中常遇到资源保护的问题。

目前游戏开发中常加密的文件类型有:图片,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文件加密】的更多相关文章

  1. 【cocos2d-x 手游研发小技巧(6)聊天系统+字体高亮】

    转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-6.html 聊天系统在手机网游中是最常见的交互工具,大家在一起边玩游戏边聊天岂不乐哉: 废话不多了 ...

  2. 【cocos2d-x 手游研发小技巧(8)通讯的数据压缩与解压 】

    今天说一下手机游戏通讯协议中的数据问题,大量的数据将给服务器端和客户端带来很大的压力,一般来说. 转载请注明出处:http://www.cnblogs.com/zisou/p/cocos2dxJQ-8 ...

  3. 【cocos2d-x 手游研发小技巧(1)自定义制作怪物伤害数值】

    直插主题了,今天写了一下午,早就想要写这类似东西的,首先我不会选用CCLabelAtlas了,我直接用帧图片做. 首先我们要准备素材,我先把素材帖出来给大家: 这个是一张比较全的素材图,它包含了扣血的 ...

  4. 【cocos2d-x 手游研发小技巧(5)获取网络图片缓存并展示】

    今天是年前最后一天上班了,最后一天上班,祝大家马上有各种东西,最后一天也给写一点干货,就是获取网络图片: 经过自己简单封装了一下,实现了获取网络图片,按照比例展示出来,实现方法是cocos2dx - ...

  5. 【cocos2d-x 手游研发小技巧(4)与Android混编实现换“头像图片”】

    cocos2dx在android平台上的游戏开发中往往会遇到一些混编需求,如: 比方有的社区类游戏需要用到更换玩家的“头像”操作,其实就是调用android servers服务里面的本地图片,以及选取 ...

  6. 【cocos2d-x 手游研发小技巧(3)Android界面分辨率适配方案】

    先感叹一下吧~~android的各种分辨率各种适配虐我千百遍,每次新项目我依旧待它如初恋···· 每家公司都有自己项目工程适配的方案,这种东西就是没有最好,只有最适合!!! 这次新项目专项针对andr ...

  7. 【cocos2d-x 手游研发小技巧(2)循环无限滚动的登陆背景】

    原创文章,转载请附上链接:http://www.cnblogs.com/zisou/p/cocos2d-xARPG6.html 首先让大家知道我们想要实现的最终效果是什么样的? 看一个<逆天仙魔 ...

  8. 【cocos2d-x 手游研发----目录】

    感谢大家一直支持我写这样一系列的博客,从中我自己也获益良多,cocos2d-x这样一款非常棒的引擎,是值得我们去学习和分享的,谈到分享,那我就把这套写了差不多一两个月的框架给大家开源下载,写的很一般, ...

  9. 【cocos2d-x 手游研发----地图活起来了】

    谈到地图不少人都说要做地图编辑器了,但是我暂时绕过这一步,如果不用寻路地图就不能移动?寻路就是会绕过障碍物的算法. 我做了一个简单的地图的思想,就是地图分层3层:背景层.可行区域层.遮罩层,但是地图就 ...

随机推荐

  1. swift UIAlertController使用 UIAlertController的宽度 为270

    添加子控件 1. 有标题, alert标题高度大概 是 40, 子控件的 Y一般在40 ,如果中间有换行, \n 的高度大概是30 2.alert的宽度 是270, 设置frame 的时候注意 /// ...

  2. URL去重

    import socket dictlist ={}; def ReadHost(): hosts = []; obn = open('d:/sss.txt', 'rb'); for line in ...

  3. PS抠发丝技巧 「选择并遮住…」

    PS抠发丝技巧 「选择并遮住…」 现在的海报设计,大多数都有模特MM,然而MM的头发实用太多了,有的还飘起来…… 对于设计师(特别是淘宝美工)没有一个强大.快速.实用的抠发丝技巧真的混不去哦.而PS ...

  4. Jmeter 如何让变量中包含变量

    在运行Jmeter的过程中,有时候,我们可能会引用一个变量,而这个变量又是由另外一个变量组成的: 譬如我在脚本中要引用变量MappingData1,按照正常的情况,直接就是用${MappingData ...

  5. 模型参数_grid

    from sklearn import datasetsfrom sklearn.model_selection import train_test_splitfrom sklearn.preproc ...

  6. 社交类APP原型模板分享——Tinder

    Tinder是国外的一款手机交友APP,作用是基于用户的地理位置,每天“推荐”一定距离内的四个对象,根据用户在 Facebook 上面的共同好友数量.共同兴趣和关系网给出评分,得分最高的推荐对象优先展 ...

  7. 2018.10.21 codeforces1071B. Minimum path(dp+贪心+bfs)

    传送门 唉考试的时候写错了两个细节调了一个多小时根本没调出来. 下来又调了半个小时才过. 其实很简单. 我们先dpdpdp出最开始最多多少个连续的aaa. 然后对于没法继续连续下去的用贪心+bfsbf ...

  8. 2018.10.19 NOIP训练 桌子(快速幂优化dp)

    传送门 勉强算一道dp好题. 显然第kkk列和第k+nk+nk+n列放的棋子数是相同的. 因此只需要统计出前nnn列的选法数. 对于前mmm%nnn列,一共有(m−1)/n+1(m-1)/n+1(m− ...

  9. org.hibernate.HibernateException: /hibernate.cfg.xml not found等三个问题

    初次配置hibernate在myeclipse上: 出现三个问题,怎么都不好使,比对代码,没有问题,查看路径还是没有问题: 1.org.hibernate.HibernateException: /h ...

  10. spring 课程

    官网 参考文档 // 1. Spring_HelloWorld 20:22 // 2. Spring_IOC&DI概述 08:07 // 3. Spring_配置 Bean 21:58 // ...