【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层:背景层.可行区域层.遮罩层,但是地图就 ...
随机推荐
- .net调用web邮箱发送邮件(转载)
public static void SendEmail() { System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient( ...
- Collections.shuffle()源码分析
Java.util.Collections类下有一个静态的shuffle()方法,如下: 1)static void shuffle(List<?> list) 使用默认随机源对列表进行 ...
- IBM关闭触摸板的方法
开始按Enter进入BIOS > Configure > Keyboard/Mouse > TouchPad,设置为DisabledF10保存退出
- 深入了解 php 底层机制 (-)洪定坤
- asp.net core 视图组件化
视图组件可以通过partial view或viewcomponent实现 partialview https://docs.microsoft.com/zh-cn/aspnet/core/mvc/vi ...
- 如何使用webpack打包前端项目
webpack概述 随着前端体积越来越大,功能越来越丰富,这时候就需要将前端工程化,而 webpack就是用于将前端各种文件打包起来. 一个简单的webpack应该包含以下几个概念 · 入口起点 · ...
- 莫烦python课程里面的bug修复;课程爬虫小练习爬百度百科
我今天弄了一下午修改这个代码,最后还是弄好了.原因是正则表达式的筛选不够准确,有时候是会带http:baidu这些东西的.所以需要一个正则表达式的断言,然后还有一点是如果his里面只有一个元素就不要再 ...
- 关闭文件描述符-close
头文件:#include<unistd.h> 原型:int close(int fd); 返回值:成功返回0,失败返回-1.
- 【JAVA】通过HttpURLConnection 上传和下载文件(二)
HttpURLConnection文件上传 HttpURLConnection采用模拟浏览器上传的数据格式,上传给服务器 上传代码如下: package com.util; import java.i ...
- c++中如何定义编译期间常量,即这个常量可以用于定义数组下标
在c++中,类里面的成员变量不仅仅可以被const修饰,还可以被static const修饰,此时一个内建类型(如int ,char ,long等)的static const 可以看做是一个编译期间的 ...