cocos2dx-lua 3.4 之 图片资源加密!
2017-01-11 16:21
477 查看
一、前言
1.我将要给大家分享的是XXTEA加密方式,对图片资源进行加密。2.需要工具:quick-lua中已经集成图片加密工具,但是我没有用quick,所以单独把这个加密文件夹拎出来了。点击下载加密工具。
http://pan.baidu.com/s/1pLyI6NL
二、修改CCFileUtils.h和cpp文件
1.找到frameworks\cocos2d-x\cocos\platform\CCFileUtils.h,添加一个结构体ResEncryptData:class CC_DLL FileUtils { public: //=====添加代码 static struct ResEncryptData{ ResEncryptData(){ allowNoEncrpt = true; key = "key123456"; sign = "sign520"; } std::string key; std::string sign; bool allowNoEncrpt; }encryptData; static unsigned char* decryptBuffer(unsigned char* buf, unsigned long size, unsigned long *newSize); //=====添加结束 /** * Gets the instance of FileUtils. */ static FileUtils* getInstance(); /** * Destroys the instance of FileUtils. */ static void destroyInstance();2.找到frameworks\cocos2d-x\cocos\platform\CCFileUtils.cpp,添加对应的实现代码:
//头文件声明===== #include "xxtea/xxtea.h" #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #include "xxtea/xxtea.cpp" #endif unsigned char* FileUtils::decryptBuffer(unsigned char* buf, unsigned long size, unsigned long *newSize){ unsigned char *m_xxteaKey = (unsigned char *)FileUtils::encryptData.key.c_str(); unsigned char *m_xxteaSign = (unsigned char *)FileUtils::encryptData.sign.c_str(); xxtea_long m_xxteaSignLen = FileUtils::encryptData.sign.length(); xxtea_long m_xxteaKeyLen = FileUtils::encryptData.key.length(); if (NULL==buf) return NULL; unsigned char* buffer = NULL; bool isXXTEA = true; for (unsigned int i = 0; isXXTEA && i < m_xxteaSignLen && i < size; ++i) { if(buf[i] != m_xxteaSign[i]){ isXXTEA = false; break; } } if(m_xxteaSignLen == 0){ isXXTEA = false; } if (isXXTEA) { // decrypt XXTEA xxtea_long len = 0; buffer = xxtea_decrypt(buf + m_xxteaSignLen, (xxtea_long)size - (xxtea_long)m_xxteaSignLen, (unsigned char*)m_xxteaKey, (xxtea_long)m_xxteaKeyLen, &len); delete []buf; buf = NULL; size = len; } else { if(FileUtils::getInstance()->encryptData.allowNoEncrpt) {buffer = buf;} } *newSize = size; return buffer; }
3.在上面那个文件中:frameworks\cocos2d-x\cocos\platform\CCFileUtils.cpp,修改getData函数:
static Data getData(const std::string& filename, bool forString) { if (filename.empty()) { return Data::Null; } Data ret; unsigned char* buffer = nullptr; size_t size = 0; size_t readsize; const char* mode = nullptr; if (forString) mode = "rt"; else mode = "rb"; do { // Read the file from hardware std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename); FILE *fp = fopen(fullPath.c_str(), mode); CC_BREAK_IF(!fp); fseek(fp,0,SEEK_END); size = ftell(fp); fseek(fp,0,SEEK_SET); if (forString) { buffer = (unsigned char*)malloc(sizeof(unsigned char) * (size + 1)); buffer[size] = '\0'; } else { buffer = (unsigned char*)malloc(sizeof(unsigned char) * size); } readsize = fread(buffer, sizeof(unsigned char), size, fp); fclose(fp); if (forString && readsize < size) { buffer[readsize] = '\0'; } } while (0); if (nullptr == buffer || 0 == readsize) { std::string msg = "Get data from file("; msg.append(filename).append(") failed!"); CCLOG("%s", msg.c_str()); } else { //ret.fastSet(buffer, readsize); //======新的改动 unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(buffer, readsize, &newSize); ret.fastSet(newBuffer, newSize); }
4.在上面那个文件中:frameworks\cocos2d-x\cocos\platform\CCFileUtils.cpp,修改getFileData函数:
unsigned char* FileUtils::getFileData(const std::string& filename, const char* mode, ssize_t *size) { unsigned char * buffer = nullptr; CCASSERT(!filename.empty() && size != nullptr && mode != nullptr, "Invalid parameters."); *size = 0; do { // read the file from hardware const std::string fullPath = fullPathForFilename(filename); FILE *fp = fopen(fullPath.c_str(), mode); CC_BREAK_IF(!fp); fseek(fp,0,SEEK_END); *size = ftell(fp); fseek(fp,0,SEEK_SET); buffer = (unsigned char*)malloc(*size); *size = fread(buffer,sizeof(unsigned char), *size,fp); fclose(fp); } while (0); if (!buffer) { std::string msg = "Get data from file("; msg.append(filename).append(") failed!"); CCLOG("%s", msg.c_str()); }else{ //新的改动========= unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(buffer, *size, &newSize); *size = newSize; buffer = newBuffer; } return buffer; }
三、修改CCFileUtils-win32.cpp文件
1.找到frameworks\cocos2d-x\cocos\platform\win32\CCFileUtils-win32.cpp,添加对应的代码:static Data getData(const std::string& filename, bool forString) { if (filename.empty()) { return Data::Null; } unsigned char *buffer = nullptr; size_t size = 0; do { // read the file from hardware std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename); WCHAR wszBuf[CC_MAX_PATH] = {0}; MultiByteToWideChar(CP_UTF8, 0, fullPath.c_str(), -1, wszBuf, sizeof(wszBuf)/sizeof(wszBuf[0])); HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, nullptr); CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE); size = ::GetFileSize(fileHandle, nullptr); if (forString) { buffer = (unsigned char*) malloc(size + 1); buffer[size] = '\0'; } else { buffer = (unsigned char*) malloc(size); } DWORD sizeRead = 0; BOOL successed = FALSE; successed = ::ReadFile(fileHandle, buffer, size, &sizeRead, nullptr); ::CloseHandle(fileHandle); if (!successed) { // should determine buffer value, or it will cause memory leak if (buffer) { free(buffer); buffer = nullptr; } } } while (0); Data ret; if (buffer == nullptr || size == 0) { std::string msg = "Get data from file("; // Gets error code. DWORD errorCode = ::GetLastError(); char errorCodeBuffer[20] = {0}; snprintf(errorCodeBuffer, sizeof(errorCodeBuffer), "%d", errorCode); msg = msg + filename + ") failed, error code is " + errorCodeBuffer; CCLOG("%s", msg.c_str()); if (buffer) free(buffer); } else { //新的改动 unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(buffer, size, &newSize); //ret.fastSet(buffer, size); ret.fastSet(newBuffer, newSize); } return ret; } unsigned char* FileUtilsWin32::getFileData(const std::string& filename, const char* mode, ssize_t* size) { unsigned char * pBuffer = nullptr; *size = 0; do { // read the file from hardware std::string fullPath = fullPathForFilename(filename); WCHAR wszBuf[CC_MAX_PATH] = {0}; MultiByteToWideChar(CP_UTF8, 0, fullPath.c_str(), -1, wszBuf, sizeof(wszBuf)/sizeof(wszBuf[0])); HANDLE fileHandle = ::CreateFileW(wszBuf, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, nullptr); CC_BREAK_IF(fileHandle == INVALID_HANDLE_VALUE); *size = ::GetFileSize(fileHandle, nullptr); pBuffer = (unsigned char*) malloc(*size); DWORD sizeRead = 0; BOOL successed = FALSE; successed = ::ReadFile(fileHandle, pBuffer, *size, &sizeRead, nullptr); ::CloseHandle(fileHandle); if (!successed) { free(pBuffer); pBuffer = nullptr; } } while (0); if (! pBuffer) { std::string msg = "Get data from file("; // Gets error code. DWORD errorCode = ::GetLastError(); char errorCodeBuffer[20] = {0}; snprintf(errorCodeBuffer, sizeof(errorCodeBuffer), "%d", errorCode); msg = msg + filename + ") failed, error code is " + errorCodeBuffer; CCLOG("%s", msg.c_str()); }else{ //新的改动 unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(pBuffer, *size, &newSize); *size = newSize; pBuffer = newBuffer; } return pBuffer; }
四、修改CCFileUtils-android.cpp文件
1.找到frameworks\cocos2d-x\cocos\platform\android\CCFileUtils-android.cpp,添加对应的代码:Data FileUtilsAndroid::getData(const std::string& filename, bool forString) { if (filename.empty()) { return Data::Null; } unsigned char* data = nullptr; ssize_t size = 0; string fullPath = fullPathForFilename(filename); cocosplay::updateAssets(fullPath); if (fullPath[0] != '/') { string relativePath = string(); size_t position = fullPath.find("assets/"); if (0 == position) { // "assets/" is at the beginning of the path and we don't want it relativePath += fullPath.substr(strlen("assets/")); } else { relativePath += fullPath; } CCLOGINFO("relative path = %s", relativePath.c_str()); if (nullptr == FileUtilsAndroid::assetmanager) { LOGD("... FileUtilsAndroid::assetmanager is nullptr"); return Data::Null; } // read asset data AAsset* asset = AAssetManager_open(FileUtilsAndroid::assetmanager, relativePath.c_str(), AASSET_MODE_UNKNOWN); if (nullptr == asset) { LOGD("asset is nullptr"); return Data::Null; } off_t fileSize = AAsset_getLength(asset); if (forString) { data = (unsigned char*) malloc(fileSize + 1); data[fileSize] = '\0'; } else { data = (unsigned char*) malloc(fileSize); } int bytesread = AAsset_read(asset, (void*)data, fileSize); size = bytesread; AAsset_close(asset); } else { do { // read rrom other path than user set it //CCLOG("GETTING FILE ABSOLUTE DATA: %s", filename); const char* mode = nullptr; if (forString) mode = "rt"; else mode = "rb"; FILE *fp = fopen(fullPath.c_str(), mode); CC_BREAK_IF(!fp); long fileSize; fseek(fp,0,SEEK_END); fileSize = ftell(fp); fseek(fp,0,SEEK_SET); if (forString) { data = (unsigned char*) malloc(fileSize + 1); data[fileSize] = '\0'; } else { data = (unsigned char*) malloc(fileSize); } fileSize = fread(data,sizeof(unsigned char), fileSize,fp); fclose(fp); size = fileSize; } while (0); } Data ret; if (data == nullptr || size == 0) { std::string msg = "Get data from file("; msg.append(filename).append(") failed!"); CCLOG("%s", msg.c_str()); } else { //新的改动========== unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(data, size, &newSize); // ret.fastSet(data, size); ret.fastSet(newBuffer, newSize); cocosplay::notifyFileLoaded(fullPath); } return ret; } unsigned char* FileUtilsAndroid::getFileData(const std::string& filename, const char* mode, ssize_t * size) { unsigned char * data = 0; if ( filename.empty() || (! mode) ) { return 0; } string fullPath = fullPathForFilename(filename); cocosplay::updateAssets(fullPath); if (fullPath[0] != '/') { string relativePath = string(); size_t position = fullPath.find("assets/"); if (0 == position) { // "assets/" is at the beginning of the path and we don't want it relativePath += fullPath.substr(strlen("assets/")); } else { relativePath += fullPath; } LOGD("relative path = %s", relativePath.c_str()); if (nullptr == FileUtilsAndroid::assetmanager) { LOGD("... FileUtilsAndroid::assetmanager is nullptr"); return nullptr; } // read asset data AAsset* asset = AAssetManager_open(FileUtilsAndroid::assetmanager, relativePath.c_str(), AASSET_MODE_UNKNOWN); if (nullptr == asset) { LOGD("asset is nullptr"); return nullptr; } off_t fileSize = AAsset_getLength(asset); data = (unsigned char*) malloc(fileSize); int bytesread = AAsset_read(asset, (void*)data, fileSize); if (size) { *size = bytesread; } AAsset_close(asset); } else { do { // read rrom other path than user set it //CCLOG("GETTING FILE ABSOLUTE DATA: %s", filename); FILE *fp = fopen(fullPath.c_str(), mode); CC_BREAK_IF(!fp); long fileSize; fseek(fp,0,SEEK_END); fileSize = ftell(fp); fseek(fp,0,SEEK_SET); data = (unsigned char*) malloc(fileSize); fileSize = fread(data,sizeof(unsigned char), fileSize,fp); fclose(fp); if (size) { *size = fileSize; } } while (0); } if (! data) { std::string msg = "Get data from file("; msg.append(filename).append(") failed!"); CCLOG("%s", msg.c_str()); } else { //新的改动 unsigned long newSize = 0; unsigned char *newBuffer = FileUtils::decryptBuffer(data, *size, &newSize); *size = newSize; data = newBuffer; cocosplay::notifyFileLoaded(fullPath); } return data; }
五、修改CCFileUtils-apple.mm文件
1.找到frameworks\cocos2d-x\cocos\platform\apple\CCFileUtils-apple.cpp,修改对应的代码:getValueMapFromFile。以便读取plist文件,是因为ios读取plist文件方式和android和win32不同。ValueMap FileUtilsApple::getValueMapFromFile(const std::string& filename) { //====新的改动 std::string fullPath = fullPathForFilename(filename); Data d = FileUtils::getDataFromFile(filename); unsigned long fileSize = d.getSize(); unsigned char* pFileData = d.getBytes(); NSData *data = [[[NSData alloc] initWithBytes:pFileData length:fileSize] autorelease]; NSPropertyListFormat format; NSString *error; NSMutableDictionary *dict = (NSMutableDictionary *)[ NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListMutableContainersAndLeaves format:&format errorDescription:&error]; //====改动结束 //std::string fullPath = fullPathForFilename(filename); //NSString* path = [NSString stringWithUTF8String:fullPath.c_str()]; //NSDictionary* dict = [NSDictionary dictionaryWithContentsOfFile:path]; ValueMap ret; if (dict != nil) { for (id key in [dict allKeys]) { id value = [dict objectForKey:key]; addValueToDict(key, value, ret); } } return ret; }
六、大功告成!
1.重新编译c++代码,把res文件夹替换成加密后的文件夹,即可正常运行。2.注意key和sign要和你的AppDelegate中设置的key和sign一样:
LuaStack* stack = LuaEngine::getInstance()->getLuaStack(); stack->setXXTEAKeyAndSign(key, strlen(key), sign, strlen(sign));
相关文章推荐
- cocos2dx-lua or quick 2dx 中的图片资源加密
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- 函数项目【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)函数项目
- cocos2dx 3.4 lua加密 和 解密
- cocos2dx-Lua引擎游戏脚本及图片资源解密与DUMP
- 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
- 转 图片资源加密,Lua文件加密
- [置顶] 使用python对cocos2dx的手游图片资源进行加密
- 图片资源加密,Lua文件加密
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- cocos2dx 3.4 lua加密 setXXTEAKeyAndSign
- 【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- 【cocos2d-x 手游研发小技巧(7)图片资源加密,Lua文件加密】
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)
- 【COCOS2DX-LUA 脚本开发之十二】Hybrid模式-利用AssetsManager实现在线更新脚本文件lua、js、图片等资源(免去平台审核周期)
- 使用python对cocos2dx的手游图片资源进行加密
- Cocos2d-lua 3.10 图片资源加密