cocos2d-x CCUserDefault的加密

cocos2dx的源代码中已经添加了base64的算法,就在base文件夹下,有base64.h和base64.cpp

但是代码有一点问题,需要先修改一下:

在int _base64Decode(const unsigned char *input,unsigned int input_len,unsigned char *output,unsigned int *output_len )函数中return之前加上这么一句:

output[output_idx] = '\0';

我也是不太懂为什么官方自带的char*操作函数里连个结束符都不加= =


然后修改CCUserDefault.cpp中的函数

首先所有的set系列函数最终都调用了setValueForKey,所以加密只用修改这个函数就可以了:

static void setValueForKey(const char* pKey,const char* pValue)
{
	char* pEncodeValue = 0;
	base64Encode((const unsigned char*)pValue,strlen(pValue),&pEncodeValue);

    tinyxml2::XMLElement* rootNode;
    tinyxml2::XMLDocument* doc;
    tinyxml2::XMLElement* node;
    // check the params
    if (! pKey || ! pValue)
    {
        return;
    }
    // find the node
	node = getXMLNodeForKey(pKey,&rootNode,&doc);
    // if node exist,change the content
    if (node)
    {
        if (node->FirstChild())
        {
			node->FirstChild()->SetValue(pEncodeValue);
        }
        else
        {
			tinyxml2::XMLText* content = doc->NewText(pEncodeValue);
            node->LinkEndChild(content);
        }
    }
    else
    {
        if (rootNode)
        {
			tinyxml2::XMLElement* tmpNode = doc->NewElement(pKey);//new tinyxml2::XMLElement(pKey);
            rootNode->LinkEndChild(tmpNode);
			tinyxml2::XMLText* content = doc->NewText(pEncodeValue);//new tinyxml2::XMLText(pValue);
            tmpNode->LinkEndChild(content);
        }    
    }

    // save file and free doc
    if (doc)
    {
        doc->SaveFile(FileUtils::getInstance()->getSuitableFOpen(UserDefault::getInstance()->getXMLFilePath()).c_str());
        delete doc;
    }
}

这里只加密了pValue,pKey不加密是因为经过base加密后的字符串结尾都会有'=',但xml中标签里等号是特殊字符,所以直接加密pKey会导致xml文件的损坏。

一个解决方法是在代码中把所有的key映射成另外的名字,比如全部映射成"Data01"、"Data02"……这样


其次是解密,由于get系列函数并没有调用一个共同的getValue函数,所以需要修改所有的get函数,但修改内容是一样的,所以只示范一个:

bool UserDefault::getBoolForKey(const char* pKey,bool defaultValue)
{
    const char* value = nullptr;
    tinyxml2::XMLElement* rootNode;
    tinyxml2::XMLDocument* doc;
    tinyxml2::XMLElement* node;

	node = getXMLNodeForKey(pKey,&doc);
	
    // find the node
    if (node && node->FirstChild())
    {
        value = (const char*)(node->FirstChild()->Value());
    }

    bool ret = defaultValue;

    if (value)
    {
		unsigned char* pDecodeValue = 0;
		base64Decode((const unsigned char*)value,strlen(value),&pDecodeValue);
        ret = (! strcmp((const char*)pDecodeValue,"true"));
    }

    if (doc) delete doc;

    return ret;
}

这样,CCUserDefault的简单加密解密就完成了,重新编译工程,测试你的代码,就可以看到UserDefault.xml文件中已经存储了加密信息,同时读取也不会有什么问题。


最后是一点吐槽,UserDefault顾名思义应该是存储一些用户设置之类的数据,大概是因为这样所以官方尽管引入了base64算法却没有给它加上,我真的很想知道为什么cocos2dx没有专门的管理游戏存档的类= =

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...