quick-x已经支持用XXTEA加密方式对脚本文件进行加密。在此基础上,自己做了一些工作,对图片资源进行了XXTEA加密,现分享给大家。
首先我们要有对图片加密的工具。这个参考compile_scripts脚本,写一个用于加密的脚本就可以了。我自己写的脚本放在这里,大家可以下载使用。(之前没用过php,完全是照着廖大的脚本修改成的,有写得不好的地方还请多多包涵,呵呵)
脚本使用的方法和compile_scripts脚本差不多,将zip包里的文件解压到quick-x的bin目录下就可以用了。
在Windows命令行下,输入以下指令(请确认环境变量PATH里有quick-x的bin目录,否则需要自己加运行路径)
1 |
pack_files.bat -i olddir -o newdir -ek XXTEA -es tsts |
以上指令是将olddir目录下的所有文件用XXTEA加密后,放到newdir目录下,其中加密密匙为XXTEA,加密记号为tsts。参数的定义与compile_scripts脚本类似,用-h也可以得到帮助,也不多说了。
MAC下可以用pack_files.sh来加密。
需要注意的是,现在只支持图片的加密。比如AllSprites.plist和AllSprites.png这样的一对纹理文件,只能加密png文件,plist文件加密后是用不了的。(注:现在已经支持plist文件,请看“后篇”里的内容)
文件加密好以后,我们需要修改quick-x的平台代码,使得它能够读取加密后的文件。
载入图片的函数是lib\cocos2d-x\cocos2dx\platform\CCImageCommon_cpp.h里面的CCImage::initWithImageFile()和CCImage::initWithImageFileThreadSafe()。再进一步看,这两个函数里都是使用CCFileUtils::sharedFileUtils()->getFileData()来获得文件数据的,我们只需要在获取数据时把文件数据解密即可。
为此我们需要专门写一个新的getFileData()来代替调用。直接写一个是可以的,放在哪个文件里也不重要。因为我自己有一个HelperFunc模块,专门放自己增加的功能的,所以我就写在这里面了。文件里的相关代码如下:
HelperFunc.h
01 |
#ifndef Cocos2Dx_HelperFunc_h |
02 |
#define Cocos2Dx_HelperFunc_h |
03 |
04 |
#include "cocos2d.h"
|
05 |
06 |
USING_NS_CC; |
07 |
08 |
class CZHelperFunc
|
09 |
{ |
10 |
public:
|
11 |
static unsigned char* getFileData(const char* pszFileName, const char* pszMode, unsignedlong * pSize);
|
12 |
13 |
}; |
14 |
15 |
#endif //Cocos2Dx_HelperFunc_h
|
HelperFunc.cpp
01 |
#include "HelperFunc.h"
|
02 |
#include "cocos2d.h"
|
03 |
extern "C" {
|
04 |
#include "lua.h"
|
05 |
#include "xxtea.h"
|
06 |
} |
07 |
#include "CCLuaEngine.h"
|
08 |
09 |
unsigned char* CZHelperFunc::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
|
10 |
{ |
11 |
unsigned long size;
|
12 |
unsigned char* buf = CCFileUtils::sharedFileUtils()->getFileData(pszFileName, pszMode, &size);
|
13 |
if (NULL==buf) return NULL;
|
14 |
15 |
CCLuaStack* stack = CCLuaEngine::defaultEngine()->getLuaStack();
|
16 |
unsigned char* buffer = NULL;
|
17 |
18 |
bool isXXTEA = stack && stack->m_xxteaEnabled;
|
19 |
for (unsigned int i = 0; isXXTEA && i < stack->m_xxteaSignLen && i < size; ++i)
|
20 |
{
|
21 |
isXXTEA = buf[i] == stack->m_xxteaSign[i];
|
22 |
}
|
23 |
24 |
if (isXXTEA)
|
25 |
{
|
26 |
// decrypt XXTEA
|
27 |
xxtea_long len = 0;
|
28 |
buffer = xxtea_decrypt(buf + stack->m_xxteaSignLen,
|
29 |
(xxtea_long)size - (xxtea_long)stack->m_xxteaSignLen,
|
30 |
(unsigned char*)stack->m_xxteaKey,
|
31 |
(xxtea_long)stack->m_xxteaKeyLen,
|
32 |
&len);
|
33 |
delete []buf;
|
34 |
buf = NULL;
|
35 |
size = len;
|
36 |
}
|
37 |
else
|
38 |
{
|
39 |
buffer = buf;
|
40 |
}
|
41 |
42 |
if (pSize) *pSize = size;
|
43 |
return buffer;
|
44 |
} |
因为上面代码里直接使用了CCLuaStack里的密匙等数据,所以要修改一下lib\cocos2d-x\scripting\lua\cocos2dx_support\CCLuaStack.h,把里面的几个属性改成公有的才能调用。当然我这是偷懒了,安全的做法应该是加几个取值的方法,呵呵。
1 |
public:
|
2 |
bool m_xxteaEnabled;
|
3 |
char *m_xxteaKey;
|
4 |
int m_xxteaKeyLen;
|
5 |
char *m_xxteaSign;
|
6 |
int m_xxteaSignLen;
|
另外,我们需要在程序启动时设置一下密匙和标记,这就要修改AppDelegate.cpp里的AppDelegate::applicationDidFinishLaunching(),在下面这句:
1 |
CCLuaStack *pStack = pEngine->getLuaStack(); |
这句后面加上:
1 |
pStack->setXXTEAKeyAndSign("XXTEA", strlen("XXTEA"), "tsts", trlen("tsts"));
|