(轉)quick-cocos2d-x圖片資源加密
摘要: 在quick-cocos2d-x上實現的一種圖片資源加密的方法,現已經加入官方最新版本之中
###quick-x已經支持用XXTEA加密方式對腳本文件進行加密。在此基礎上,自己做了一些工作,對圖片資源進行了XXTEA加密,現分享給大家。 ###(2014.5.30加註:quick-x的2.2.3版本已經集成了我遞交的pr,現在官方版本代碼與文章中類似)
###首先我們要有對圖片加密的工具。這個參考compile_scripts腳本,寫一個用於加密的腳本就可以了。我自己寫的腳本放在這裏,大家可以下載使用。(之前沒用過php,完全是照著廖大的腳本修改成的,有寫得不好的地方還請多多包涵,呵呵)
###腳本使用的方法和compile_scripts腳本差不多,將zip包裏的文件解壓到quick-x的bin目錄下就可以用了。
###在Windows命令行下,輸入以下指令(請確認環境變量PATH裏有quick-x的bin目錄,否則需要自己加運行路徑)
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
#ifndef Cocos2Dx_HelperFunc_h
#define Cocos2Dx_HelperFunc_h
NS_CC_BEGIN
class CZHelperFunc
{
public:
static unsigned char* getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize);
};
NS_CC_END
#endif //Cocos2Dx_HelperFunc_h
HelperFunc.cpp
#include "cocos2d.h"
extern "C" {
#include "lua.h"
#include "xxtea.h"
}
#include "CCLuaEngine.h"
#include "HelperFunc.h"
USING_NS_CC;
unsigned char* CZHelperFunc::getFileData(const char* pszFileName, const char* pszMode, unsigned long * pSize)
{
unsigned long size;
unsigned char* buf = CCFileUtils::sharedFileUtils()->getFileData(pszFileName, pszMode, &size);
if (NULL==buf) return NULL;
CCLuaStack* stack = CCLuaEngine::defaultEngine()->getLuaStack();
unsigned char* buffer = NULL;
bool isXXTEA = stack && stack->m_xxteaEnabled;
for (unsigned int i = 0; isXXTEA && i < stack->m_xxteaSignLen && i < size; ++i)
{
isXXTEA = buf[i] == stack->m_xxteaSign[i];
}
if (isXXTEA)
{
// decrypt XXTEA
xxtea_long len = 0;
buffer = xxtea_decrypt(buf + stack->m_xxteaSignLen,
(xxtea_long)size - (xxtea_long)stack->m_xxteaSignLen,
(unsigned char*)stack->m_xxteaKey,
(xxtea_long)stack->m_xxteaKeyLen,
&len);
delete []buf;
buf = NULL;
size = len;
}
else
{
buffer = buf;
}
if (pSize) *pSize = size;
return buffer;
}
###因為上面代碼裏直接使用了CCLuaStack裏的密匙等數據,所以要修改一下lib\cocos2d-x\scripting\lua\cocos2dx_support\CCLuaStack.h,把裏面的幾個屬性改成公有的才能調用。當然我這是偷懶了,安全的做法應該是加幾個取值的方法,呵呵。
public:
bool m_xxteaEnabled;
char *m_xxteaKey;
int m_xxteaKeyLen;
char *m_xxteaSign;
int m_xxteaSignLen;
###另外,我們需要在程序啟動時設置一下密匙和標記,這就要修改AppDelegate.cpp裏的AppDelegate::applicationDidFinishLaunching(),在下面這句:
CCLuaStack *pStack = pEngine->getLuaStack();
###這句後面加上:
pStack->setXXTEAKeyAndSign("XXTEA", strlen("XXTEA"), "tsts", strlen("tsts"));
###註意最新版本的quick-x裏,player的AppDelegate.cpp修改的地方是StartupCall::startup()函數。
###現在把CCImageCommon_cpp.h裏的CCFileUtils::sharedFileUtils()->getFileData改為CZHelperFunc::getFileData就可以了。當然,必須包含HelperFunc.h這個頭文件才能編譯通過。
###(註:initWithImageFileThreadSafe函數裏有一段代碼是在Android平臺上使用getFileDataForAsync來取文件內容,我開始這裏沒做修改也能在Android上正常運行,可能是因為我沒使用到這一載入功能。其實這段代碼可以直接去掉,都用CZHelperFunc::getFileData來處理就好。最簡單的修改是將“#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)"改成"#if 0"就可以了)
###經過以上修改,quick-x就能夠使用加密後的圖片資源了。但這只解決了Windows平臺(player)和Android平臺,其他的修改請看續篇。
後篇: 讓quick-cocos2d-x支持加密的plist文件 quick-cocos2d-x圖片資源加密(續)
原文地址:https://my.oschina.net/SunLightJuly/blog/184061
(轉)quick-cocos2d-x圖片資源加密