// // BigFile.cpp // HelloLua // // Created by mac on 14-11-27. // // #include "BigFile.h" #include "cocos2d.h" #include #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "platform/CCCommon.h" #include "jni/Java_org_cocos2dx_lib_Cocos2dxHelper.h" #include "platform/android/jni/JniHelper.h" #include #include #include #include "platform/android/CCFileUtils-android.h" #else #endif USING_NS_CC; #define CONFIGFILENAME "bin/Data/mainData" BigFile* BigFile::s_sharedBigFile = NULL; bool BigFile::inited = false; BigFile::BigFile(bool useCache) { _useCache = useCache; b_configInited = false; _confFilePath= FileUtils::getInstance()->fullPathForFilename(CONFIGFILENAME); b_IsHunXiao = _confFilePath != ""; if (b_IsHunXiao) { _assertDir = ""; size_t pos = _confFilePath.find(CONFIGFILENAME); if (pos != string::npos){ _assertDir = _confFilePath.substr(0, pos); } CCLOG("BigFile: assetDir:%s",_assertDir.c_str()); } setupPackName(); setupConfFileRoot(); } BigFile* BigFile::getInstance() { if (s_sharedBigFile == NULL){ s_sharedBigFile = new BigFile(false); inited = true; } return s_sharedBigFile; } void BigFile::setupPackName(){ #if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID _packname = _getAndroidPackageName(); #else _packname = _getIOSAppId(); #endif CCLOG("packName:%s", _packname.c_str()); } void BigFile::setupConfFileRoot(){ if (b_IsHunXiao) { Data datas = FileUtils::getInstance()->getDataFromFile(_confFilePath); unsigned char* data = datas.getBytes(); ssize_t len = datas.getSize(); rc4_crypt(data,len); string err = ""; string cfg(data,data+len); // CCLOG("cfg:%s",cfg.c_str()); _confFileRoot = Json::parse(cfg, err); if (err == ""){ CCLOG("BigFile: Setup mainData Succeed!"); _pathCfgRoot = _confFileRoot["path"]; _decCfgRoot = _confFileRoot["decode"]; } else{ CCLOG("BigFile: Setup failed:%s", err.c_str()); } b_configInited = true; } } void BigFile::targetFileNameFromDirAndFile(string& directory, string& filename){ if (b_IsHunXiao) { if(b_configInited){ string oldPath = directory+filename; #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) oldPath = oldPath.substr(strlen("assets/")); #endif Json arrayObj=_pathCfgRoot[oldPath]; if(!arrayObj.is_null()){ filename = arrayObj["fileName"].string_value(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) directory = "assets/"; #else directory = ""; #endif filename = directory + filename; size_t pos = filename.find_last_of("/"); if (pos != string::npos){ directory = filename.substr(0, pos+1); filename = filename.substr(pos+1); } CCLOG("BigFile: 地址重定向:%s -> %s \n",oldPath.c_str(), (directory+filename).c_str()); } else{ // CCLOG("BigFile: 找不到这货:%s",oldPath.c_str()); } } } } bool BigFile::needDecode(string filepath){ bool ret = false; if (b_IsHunXiao) { filepath.find(_assertDir); size_t pos = filepath.find(_assertDir); if (pos != string::npos){ string fileName = filepath.substr(_assertDir.length()); //check if encrypted... Json needRc4=_decCfgRoot[fileName]; if(!needRc4.is_null()){ ret = true; } } } return ret; } void BigFile::clearDataCache(){ if(_useCache){ _cachedDataDicMutex.lock(); for (auto & item : _cachedDataDic) { free(get<0>(item.second)); } _cachedDataDic.clear(); _cachedDataDicMutex.unlock(); } } void BigFile::saveDataToCache(string path, unsigned char* buffer, ssize_t size){ if(_useCache){ _cachedDataDicMutex.lock(); path = path.substr(path.rfind('/')+1); unsigned char *tmp=NULL; tmp = (unsigned char*)malloc(size); memcpy(tmp, buffer, size); _cachedDataDic[path] = tuple{tmp, size}; _cachedDataDicMutex.unlock(); } } const unsigned char* BigFile::getDataFromCache(string path, ssize_t *size){ if (_useCache) { _cachedDataDicMutex.lock(); path = path.substr(path.rfind('/')+1); if (_cachedDataDic.find(path) != _cachedDataDic.end()) { auto &item = _cachedDataDic[path]; *size = get<1>(item); unsigned char * buffer = get<0>(item); CCLOG("load from cache: %s",path.c_str()); return buffer; } _cachedDataDicMutex.unlock(); } return NULL; } void BigFile::rc4_crypt(unsigned char *Data, ssize_t Len) { //加解密 const char * key = _packname.c_str(); int x,y,j=0; int box[256]; for (int i = 0; i < 256; ++i) { box[i]=i; } for (int i = 0; i < 256; ++i) { j=(key[i % strlen(key)] + box[i] + j)%256; x=box[i]; box[i]=box[j]; box[j]=x; } for (int i = 0; i < Len; ++i) { y = i%256; j = (box[y] + j) %256; x = box[y]; box[y] = box[j]; box[j] = x; Data[i]=Data[i] ^ box[(box[y] + box[j]) %256]; } }