Image resource encryption, Lua file encryption detailed explanation

Image resource encryption, Lua file encryption

The problem of resource protection is often encountered in game development. At present, the file types that are often encrypted in game development are: pictures, Lua files, audio and other files, but encryption is also a double-edged sword.

If you need security, you have to spend a certain amount of resources to implement it. At present, the TexturePacker tool is also used to encrypt on the Internet, but the pertinence is not strong enough.

Analyze the principle as:

1. Format conversion: a way to convert files that need to be encrypted into streams;

2. Encryption: According to your needs, use encryption methods, MD5, AES, and even directly change the displacement. Add some special characters of your own to make the file simple encryption. After encryption, it is basically guaranteed that the picture type cannot be previewed or played with special software. Open, the Lua file is garbled after encryption;

3. Save the custom format file: save as your own special type of file name such as "xx.d" "xx.xyz" and so on.

4. Picture decryption: modify the acquisition path of the cocos2dx underlying library, and modify the source code when loading the CCImage texture processing;

5. Special Lua file interface: modify the corresponding Lua loading method;

After the basic principles are clear, I will talk about some commonly used encryption methods in my projects:

The first is the way of formatting and encryption:

bool PublicCommen::recode_getFileByName(string pFileName){  unsigned long nSize = 0;

unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(

pFileName.c_str(), “rb”,&nSize);

unsigned char* newBuf = new unsigned char[nSize]; int newblen = nSize; if(pBuffer!=NULL&&nSize>0)

{ for (int i = 0; i             newBuf[i]=pBuffer[i]+MD5;

} string savepath = pFileName;

savepath = savepath.substr(0,savepath.length()-4);

savepath = savepath + "xx.X";

FILE *fp = fopen(savepath.c_str(), "wb+");

fwrite(newBuf, 1, newblen, fp);

fclose(fp);

CCLOG("save file ok. path = %s" ,savepath.c_str()); return true;

} return false;

}

Usually you can write an application to traverse the resource files that need to be transferred in the custom directory, and correspondingly convert and encrypt all the resources; inside newBuf[i]=pBuffer[i]+MD5; this paragraph can be played freely! Need to correspond when decrypting!

Of course, you can also use it in your game to modify the CCFileUtils::fullPathForFilename at the bottom of Cocos2d-x to obtain the full path;

Let's talk about decryption:

Decryption of the picture needs to be modified in the CCTextureCache::addImage class of cocos2dx CCTexture2D

CCTexture2D * CCTextureCache::addImage(const char * path)

{

CCAssert(path != NULL, "TextureCache: fileimage MUST not be NULL");

CCTexture2D * texture = NULL;

CCImage* pImage = NULL; // Split up directory and filename // MUTEX: // Needed since addImageAsync calls this method from a different thread //pthread_mutex_lock(m_pDictLock);  std::string pathKey = path;

pathKey = CCFileUtils :: sharedFileUtils () -> fullPathForFilename (pathKey.c_str ()); if (pathKey.size () == 0)

{ return NULL;

}

texture = (CCTexture2D*)m_pTextures->objectForKey(pathKey.c_str());

std::string fullpath = pathKey; // (CCFileUtils::sharedFileUtils()->fullPathFromRelativePath(path)); if (! texture)

{

std::string lowerCase(pathKey); for (unsigned int i = 0; i < lowerCase.length(); ++i)

{

lowerCase[i] = tolower(lowerCase[i]);

} // all images are handled by UIImage except PVR extension that is handled by our own handler do { if (std::string::npos != lowerCase.find(".pvr"))

{

texture = this->addPVRImage(fullpath.c_str());

} else if (std::string::npos != lowerCase.find(“.pkm”))

{ // ETC1 file format, only supportted on Android texture = this->addETCImage(fullpath.c_str());

} else {

CCImage::EImageFormat eImageFormat = CCImage::kFmtUnKnown; if (std::string::npos != lowerCase.find(“.png”))

{

eImageFormat = CCImage::kFmtPng;

} else if (std::string::npos != lowerCase.find(“.jpg”) || std::string::npos != lowerCase.find(“.jpeg”))

{

eImageFormat = CCImage::kFmtJpg;

} else if (std::string::npos != lowerCase.find(“.tif”) || std::string::npos != lowerCase.find(“.tiff”))

{

eImageFormat = CCImage::kFmtTiff;

} else if (std::string::npos != lowerCase.find(“.webp”))

{

eImageFormat = CCImage :: kFmtWebp;

} else if (std::string::npos != lowerCase.find(“XX.X”))

{

eImageFormat = CCImage::xxxxx;

}

pImage = new CCImage();

CC_BREAK_IF(NULL == pImage); bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);

CC_BREAK_IF(!bRet);

texture = new CCTexture2D(); if( texture && texture->initWithImage(pImage) )

{ #if CC_ENABLE_CACHE_TEXTURE_DATA // cache the texture file name  VolatileTexture::addImageTexture(texture, fullpath.c_str(), eImageFormat); #endif m_pTextures->setObject(texture, pathKey.c_str());

texture->release();

} else {

CCLOG(“cocos2d: Couldn’t create texture for file:%s in CCTextureCache”, path);

}

}

} while (0);

}

CC_SAFE_RELEASE(pImage); //pthread_mutex_unlock(m_pDictLock); return texture;

}

And add your encrypted image type in the image type of CCImage, such as: CCImage::xxxxx; then follow

bool bRet = pImage->initWithImageFile(fullpath.c_str(), eImageFormat);

CCImage::initWithImageFile method in CCImage.mm:

bool CCImage::initWithImageFile(const char * strPath, EImageFormat eImgFmt/* = eFmtPng*/)

{ bool bRet = false;

unsigned long nSize = 0;

unsigned char* pBuffer = CCFileUtils::sharedFileUtils()->getFileData(

CCFileUtils::sharedFileUtils()->fullPathForFilename(strPath).c_str(), “rb”, &nSize); if(eImgFmt==xxxxxx)

{ for (int i= 0; i < nSize; i++) {

pBuffer[i] = pBuffer[i]-MD5;

}

pBuffer[nSize] = pBuffer[nSize]-1;

eImgFmt = kFmtPng;

} if (pBuffer != NULL && nSize > 0)

{

bRet = initWithImageData(pBuffer, nSize, eImgFmt);

}

CC_SAFE_DELETE_ARRAY(pBuffer); return bRet;

}

Among them, pBuffer[i] = pBuffer[i]-MD5; ​​need to correspond to the previous encryption time, play by yourself!

Ok, as long as it is a picture, and the picture belongs to your custom type, the real texture will be decrypted.

Lua decryption is basically the same idea, but decryption needs to be decrypted separately before loading the Lua method, and cross-platform is considered.

Guess you like

Origin blog.csdn.net/qq_21743659/article/details/108637132