加密就不用說了,看上一篇2.X加密的方式,怎麼弄都可以。的保證解密規則就行;
現在重點說3.X解密:
在新的3.X引擎中官方整合了大部分獲取資源的方法,最終合成一個getdata;
可以從源碼,和堆棧調用中看到:
CCFileUtils.cpp:
Data FileUtils::getDataFromFile(const std::string& filename)
{
return getData(filename, false);
}
getDataFromFile目前只調用getData(filename,false);
Data getData(const std::string& filename, bool forString)
這個函數是一個非類成員靜態函數。
forString是用來標識是否是一個文本文件,如果是那麼buffer需要多一個字節。
這個其實不重要,因為我們處理的最終buffer是獲取完全的
所以直接改代碼:
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";
std::string lastname = FileUtils::getInstance()->fullPathForFilename(filename);
lastname = lastname.substr(lastname.length()-5,lastname.length());
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
{
if(lastname == "_jm.d")
{
for (int i = 0; i<readsize; i++) {
buffer[i]=MD5(buffer[i]);
}
buffer[readsize]=buffer[readsize]-MD5size;
}
ret.fastSet(buffer, readsize);
}
return ret;
}
紅色代碼是我們自定義加密的文件解密,不管你用什麼加密,或者修改地址擾碼,只要保證加密解密格式相同;
OK,解密就算完成了,但是注意還有資源類型需要判斷,在2.X中,處理了EImageFormat的判斷,可以定義資源類型
但是還是建議還是不要去大改源碼,3.2以上版本已經非常簡潔強大了
3.X中整合了Format後,也有資源類型另外一種方式定義_fileType = detectFormat(unpackedData, unpackedLen);
我們解密後的資源類型在3.X中是行不通的,是Format::UNKOWN;
那麼就在不大改的情況下重載函數方式解決這個問題:
重載initWithImageData,在CCImage.h中CCImage.cpp中
.h添加:
/*
jmflag 加密標識
*/
bool initWithImageData(const unsigned char * data, ssize_t dataLen,bool jmflag);
.cpp添加:
bool Image::initWithImageData(const unsigned char * data, ssize_t dataLen,bool jmflag)
{
bool ret = false;
do
{
CC_BREAK_IF(! data || dataLen <= 0);
unsigned char* unpackedData = nullptr;
ssize_t unpackedLen = 0;
//detecgt and unzip the compress file
if (ZipUtils::isCCZBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateCCZBuffer(data, dataLen, &unpackedData);
}
else if (ZipUtils::isGZipBuffer(data, dataLen))
{
unpackedLen = ZipUtils::inflateMemory(const_cast<unsigned char*>(data), dataLen, &unpackedData);
}
else
{
unpackedData = const_cast<unsigned char*>(data);
unpackedLen = dataLen;
}
if(jmflag == true)
{
_fileType=Format::PNG;
}
ret = initWithPngData(unpackedData, unpackedLen);
if(unpackedData != data)
{
free(unpackedData);
}
} while (0);
return ret;
}
另外在initWithImageFile函數中得修改調用方法
CCImage.cpp:
Data data = FileUtils::getInstance()->getDataFromFile(_filePath);
if (!data.isNull())
{
std::string lastname = _filePath;
lastname = lastname.substr(lastname.length()-5,lastname.length());
if(lastname=="_jm.d")
{
ret = initWithImageData(data.getBytes(), data.getSize(),true);
}
else
{
ret = initWithImageData(data.getBytes(), data.getSize());
}
}
OK,自定義類型的資源解密就搞定了,但這只處理了PNG圖片類型的加密,其他圖片類型資源可以按照這種方式處理。
好了,那麼有同學問,那麼JS,Lua腳本的解密呢?
看這裡
ScirptingCore.cpp:
// Check whether '.jsc' files exist to avoid outputing log which says 'couldn't find .jsc file'.
CCLOG("byteCodePath > %s",byteCodePath.c_str());
if (futil->isFileExist(byteCodePath))
{
Data data = futil->getDataFromFile(byteCodePath);
if (!data.isNull())
{
script = JS_DecodeScript(cx, data.getBytes(), static_cast<uint32_t>(data.getSize()), nullptr, nullptr);
}
}
Data data = futil->getDataFromFile(byteCodePath);
對於腳本語言的加載讀取還是上面我們已經改過的getDataFromFile方法噢!
那就等於我們不用處理了,只需要考慮加密就行了。
PS一下廣告時間:
本人游戲官網:www.tapheros.com
我目前在錄制cocos2dx-3.X系列的實戰項目視頻,可以完全來說是商業項目視頻講解,讓你愛上更有趣的游戲開發方式;
9秒課堂會第一時間上線我們的實戰視頻!
可以讓大家更快速的掌握cocos2dx-Js的游戲實戰開發!現在用腳本做游戲已然成為一個大的趨勢;
而且在手游游戲行業飛速發展的今天,如果不用一種快速上手的腳本語言做游戲開發豈不是會Out了
另外希望大家支持我們的游戲開發群:【41131516】