【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 = 0;
    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>0)
    {
        for (int i = 0; i<nSize; i++) {
            newBuf[i]=pBuffer[i]+MD5;
        }
        string savepath = pFileName;
        savepath = savepath.substr(0,savepath.length()-4);
        savepath = savepath + "xx.X";

        FILE *fp = fopen(savepath.c_str(), "wb+");
        fwrite(newBuf, 1, 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() == 0)
    {
        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 = 0; 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 (0);
    }

    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 = 0;
    unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(
                CCFileUtils::sharedFileUtils()->fullPathForFilename(strPath).c_str(),
                "rb",
                &nSize);
    if(eImgFmt==xxxxxx)
    {
        for (int i= 0; i < nSize; i++) {
            pBuffer[i] = pBuffer[i]-MD5;
        }
        pBuffer[nSize] = pBuffer[nSize]-1;
        eImgFmt = kFmtPng;
    }

    if (pBuffer != NULL && nSize > 0)
    {
        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文件加密】

时间: 2024-08-02 03:24:29

【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】的相关文章

【cocos2d-x 手游研发小技巧(17)封装动画插件,序列帧 plist+png】

今天是2014年的最后一天  明天就是2015年了 今天给大家一点干活 我就直接上代码了 #ifndef __ENTITY_ACTION_H__ #define __ENTITY_ACTION_H__ #include "cocos2d.h" #include "cocos-ext.h" #include "game/entity/UISprite.h" class EntityAction : public CCNode { public: E

手游外设,小旗捡了小米的漏吗?

15日,亿万米粉怀着激动的心情迎来了他们的节日,官方营销火力全开,小米note好,海报做地更好,还发布了小米小盒子,两日之后,包含多功能网关.人体感应器.门窗传感器.无线开关.门铃,支持WiFi.Zigbee协议的小米智能家庭套装亮相. 如今小米已把能做的.不能做到都做了,产品线覆盖智能手机.智能家居等多个领域,电视.机顶盒.路由器.手环.净化器.血压仪等等等等,就连插座和灯泡也不放过,可为何小米却漏掉了更具消费市场潜力的手游外设产品呢? 小米不做,就会有别人来抢着做,打着"如何让小米手机游戏体

关于cocos2dx手游lua文件加密的解决方案

很多使用cocos2dx+lua做游戏的同学,都会想到一个问题,我的游戏一旦发布,怎样才能保证的我脚本代码不被破解,不泄露代码.虽然这和开源.共享的原则不合,但是代码也是coder的劳动成果,理应得到保护.特别是商业游戏更是如此,不希望被别人破解掉源码并且进行修改. 今天的话题就是如何实现lua脚本文件的加密和解密. 我在网络上查过,解决方案http://www.ijiami.cn/appprotect_mobile_games然后我经过考虑之后,总结出两种解决方案,供大家参考. 1.轻量级的解

关于cocos2dx手游lua文件加密的解决方式

非常多使用cocos2dx+lua做游戏的同学.都会想到一个问题,我的游戏一旦公布,如何才干保证的我脚本代码不被破解.不泄露代码.尽管这和开源.共享的原则不合.可是代码也是coder的劳动成果,理应得到保护. 特别是商业游戏更是如此,不希望被别人破解掉源代码而且进行改动. 今天的话题就是怎样实现lua脚本文件的加密和解密. 我在网络上查过,都没有成熟的解决方式.然后我经过考虑之后,总结出两种解决方式,供大家參考. 1.轻量级的解决方式.APK打包之前,用工具把全部的lua文件加密,详细是将lua

[转]手游研发数据专业术语科普 游戏热度跟啥有关

From : http://news.131.com/news/yejie/14/0603/1193340_1.html 对于移动游戏来说,不俗的下载量是一个好的开始,但作为一名游戏开发者,或一家游戏公司的投资人,你必须理解下载量之外的更多数据.本文所例举的指标,常被游戏公司用于衡量一款产品成功与否 玩家获取的相关指标 目前,一名新玩家的获取成本介于0.5-2.5美元之间.玩家获取成本的高低,与你选用了哪些获取玩家的渠道,以及游戏类型关系紧密.但从当前市场趋势来看,我们不难注意到,玩家获取成本正

一步之遥手游技能释放技巧 掌握要领效果翻倍

music.douban.com/doulist/35655882/music.douban.com/doulist/35655883/music.douban.com/doulist/35655884/music.douban.com/doulist/35655993/music.douban.com/doulist/35655995/music.douban.com/doulist/35656000/music.douban.com/doulist/35656121/music.douban

iOS开发小技巧--定义宏和pch文件的使用

一.创建pch文件,默认跟项目同名 二.告诉系统,编译的时候要编译pch文件的步骤 三.把经常用到的宏  或者  分类 包含到这里

.Net Core小技巧 - 使用Swagger上传文件

前言 随着前后端分离开发模式的普及,后端人员更多是编写服务端API接口.调用接口实现文件上传是一个常见的功能,同时也需要一个选择文件上传的界面,可以编写前端界面上传,可以使用Postman.curl来模拟上传请求.上述的方式多多少少有点麻烦.Swagger作为Api说明文档及调试工具,如果它能提供文件上传的界面(默认不提供),那会更加方便文件上传提示,本文将介绍如何使用Swagger来上传文件. 步骤 1. 安装Swagger Install-Package Swashbuckle.AspNet

知物由学|游戏开发者如何从容应对Unity手游风险?

"知物由学"是网易云易盾打造的一个品牌栏目,词语出自汉·王充<论衡·实知>.人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道."知物由学"希望通过一篇篇技术干货.趋势解读.人物思考和沉淀给你带来收获的同时,也希望打开你的眼界,成就不一样的你.当然,如果你有不错的认知或分享,也欢迎通过邮件([email protected])投稿. 以下为正文: 3月25日,2018 Unity技术路演首站:移动游戏技术分享日在广州举办.此次活动