1. 程式人生 > >Cocos2d-x 遊戲資源(圖片、XML、TXT等)打包加密 之 解密讀取

Cocos2d-x 遊戲資源(圖片、XML、TXT等)打包加密 之 解密讀取

自上一篇  Unity3d 遊戲資源打包加密(圖片/XML/TXT等) C#編碼 (一)   介紹如何打包加密遊戲資源已經好幾月,卻沒有詳細說明如何在遊戲中去讀取加密的資源,雖然聰明的程式設計師看一眼就知道如何逆向編碼,但是還是詳細說明一下,以作完結。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

Cocos2d-X 資源加密與解密

加密只有一篇即可,解密分為兩篇,Cocos2d-x 篇 和 Unity3d 篇。

首先,這一篇介紹Cocos2d-x 讀取加密的資源。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn


以下內容需要對Cocos2d-x 稍微深入瞭解。

XML和文件的讀取沒啥好講的,完全不涉及Cocos2d-X。這裡不做介紹,如果想了解,請百度C++/C如何讀取檔案以及各大XML庫如何讀取XML檔案。

下面開始我們的解密之旅。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

Cocos2d-x中CCSprite的Create流程

首先我要提一下,在Cocos2d-X中顯示一張圖片,一般是直接在CCSprite中帶圖片路徑引數去例項化。百分之九十的程式猿們都是這樣用的,簡單粗暴。但是一旦需要自己對圖片進行加密之後,就不能在直接傳入圖片路徑進行例項化,這下該如何是好……

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

嗯,Cocos2d-X的好處這個時候就提現出來了,開源免費,我們想看啥就看啥,想改啥就改啥。

作為一個合格的程式設計師一定要具備看原始碼的能力。

下面來看一下CCSprite的部分原始碼:

class CC_DLL Sprite : public Node, public TextureProtocol
{
public:

    static const int INDEX_NOT_INITIALIZED = -1; /// Sprite invalid index on the SpriteBatchNode

    /// @{
    /// @name Creators

    /**
     * Creates an empty sprite without texture. You can call setTexture method subsequently.
     *
     * @return An autoreleased sprite object.
     */
    static Sprite* create();

    /**
     * Creates a sprite with an image filename.
     *
     * After creation, the rect of sprite will be the size of the image,
     * and the offset will be (0,0).
     *
     * @param   filename A path to image file, e.g., "scene1/monster.png"
     * @return  An autoreleased sprite object.
     */
    static Sprite* create(const std::string& filename);

    /**
     * Creates a sprite with an image filename and a rect.
     *
     * @param   filename A path to image file, e.g., "scene1/monster.png"
     * @param   rect     A subrect of the image file
     * @return  An autoreleased sprite object
     */
    static Sprite* create(const std::string& filename, const Rect& rect);

    /**
     * Creates a sprite with a Texture2D object.
     *
     * After creation, the rect will be the size of the texture, and the offset will be (0,0).
     *
     * @param   texture    A pointer to a Texture2D object.
     * @return  An autoreleased sprite object
     */
    static Sprite* createWithTexture(Texture2D *texture);

    /**
     * Creates a sprite with a texture and a rect.
     *
     * After creation, the offset will be (0,0).
     *
     * @param   texture    A pointer to an existing Texture2D object.
     *                      You can use a Texture2D object for many sprites.
     * @param   rect        Only the contents inside the rect of this texture will be applied for this sprite.
     * @param   rotated     Whether or not the rect is rotated
     * @return  An autoreleased sprite object
     */
    static Sprite* createWithTexture(Texture2D *texture, const Rect& rect, bool rotated=false);
轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn
從原始碼中看到,CCSprite不只有傳入檔案路徑這一種例項化的方式,還可以傳入一個Texture2D 來例項化。

Texture2D是什麼?

學習過OpenGL的朋友就知道,Texture在GL中就是儲存紋理資料的一塊記憶體,至於Texture2D,無非就是一塊記憶體。

那記憶體裡面放著什麼,肯定就是紋理資料了。

那紋理資料從哪來,肯定是讀取檔案來的。

那檔案是什麼,一塊資料。

至此流程明瞭,這一例項化流程和我們的目的一致。

即:用一塊資料來例項化一個Texture2D,然後例項化CCSprite。

根據上面的流程,我們下一步要做的就是,例項化一個 Texture2D 。

我們來看Texture2D的原始碼

// implementation Texture2D (Image)
bool Texture2D::initWithImage(Image *image)
{
    return initWithImage(image, g_defaultAlphaPixelFormat);
}

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

然後我們需要的就是 例項化一個Image。

在CCImage中,先來看這個函式

bool Image::initWithImageFile(const std::string& path)
{
    bool ret = false;
    _filePath = FileUtils::getInstance()->fullPathForFilename(path);

#ifdef EMSCRIPTEN
    // Emscripten includes a re-implementation of SDL that uses HTML5 canvas
    // operations underneath. Consequently, loading images via IMG_Load (an SDL
    // API) will be a lot faster than running libpng et al as compiled with
    // Emscripten.
    SDL_Surface *iSurf = IMG_Load(fullPath.c_str());

    int size = 4 * (iSurf->w * iSurf->h);
    ret = initWithRawData((const unsigned char*)iSurf->pixels, size, iSurf->w, iSurf->h, 8, true);

    unsigned int *tmp = (unsigned int *)_data;
    int nrPixels = iSurf->w * iSurf->h;
    for(int i = 0; i < nrPixels; i++)
    {
        unsigned char *p = _data + i * 4;
        tmp[i] = CC_RGB_PREMULTIPLY_ALPHA( p[0], p[1], p[2], p[3] );
    }

    SDL_FreeSurface(iSurf);
#else
    Data data = FileUtils::getInstance()->getDataFromFile(_filePath);

    if (!data.isNull())
    {
        ret = initWithImageData(data.getBytes(), data.getSize());
    }
#endif // EMSCRIPTEN

    return ret;
}

這個函式的功能就是,根據傳進來的引數-圖片路徑,讀取這個圖片路徑的檔案,獲取資料,然後根據這塊資料,來例項化 Texture2D 。

好的,終於到了最後一步,直接和記憶體打交道了。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

下面整理一下CCSprite的例項化流程:


好了,首先我們來按照上面的流程,讀取一張未加密圖片,例化一個CCSprite 。

讀取未加密圖片

一貫作風,還是拿HelloWorld 作為例子,以下程式碼

	Image* image = new Image();

	Data data = FileUtils::getInstance()->getDataFromFile("Deemo.jpg");

	image->initWithImageData(data.getBytes(), data.getSize());

	Texture2D* texutre=new Texture2D();
	texutre->initWithImage(image);

	Sprite* sprite=Sprite::createWithTexture(texutre);

    // position the sprite on the center of the screen
    sprite->setPosition(Vec2(visibleSize / 2) + origin);

    // add the sprite as a child to this layer
    this->addChild(sprite);

執行成功


轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

對圖片打包加密

首先我們使用之前編寫的資源打包加密工具對圖片進行打包加密。

http://download.csdn.net/detail/cp790621656/8393457

在配置檔案中新增要打包的資料夾的名字,一行一個。然後執行程式打包,我這裡打包 Deemo 這個資料夾,生成了Deemo.UPK 。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

對加密的資源進行解密

上篇部落格雖然介紹了打包加密的原理以及貼上了程式碼,但可能還是不夠明瞭,我這裡貼上UPK檔案的記憶體結構圖,這樣大家對UPK就能一目瞭然。


好了,知道了UPK的記憶體結構,我們就可以開始在Cocos2d-X中去讀取我們想要的資料了。

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

首先我們讀取出檔案頭

void HelloWorld::InitUPKFileSystem()
{
	std::string fullPath = FileUtils::getInstance()->fullPathForFilename("Deemo.UPK");
	std::ifstream fin(fullPath.c_str(),std::ios::binary);
	if (!fin)
	{
		CCLOG("File Open Error");
		return;
	}
	//首先讀取檔案數量4byte;
	char fileCountArr[4];

	fin.read(fileCountArr,4);

	int fileCount=0;

	memcpy(&fileCount,fileCountArr,4);

	//然後迴圈讀取檔案資訊;
	for (int index=0;index<fileCount;index++)
	{
		OneFileInfor oneFileInfor;

		//讀取m_id;
		char idArr[4];
		int id=0;
		fin.read(idArr,4);
		memcpy(&id,idArr,4);
		oneFileInfor.m_id=id;

		//讀取m_StartPos;
		char startPosArr[4];
		int startPos=0;
		fin.read(startPosArr,4);
		memcpy(&startPos,startPosArr,4);
		oneFileInfor.m_StartPos=startPos;

		//讀取m_Size;
		char sizeArr[4];
		int size=0;
		fin.read(sizeArr,4);
		memcpy(&size,sizeArr,4);
		oneFileInfor.m_Size=size;

		//讀取m_Path;
		char pathArr[256];
		std::string path;
		fin.read(pathArr,256);
		path=pathArr;
		oneFileInfor.m_Path=path;

		m_allFileInforVec.push_back(oneFileInfor);
	}
	fin.close();

}

然後根據檔案路徑,查詢到對應的OneFileInfor,然後根據m_StartPos進行偏移讀取m_Size大小的資料即可。
cocos2d::Data HelloWorld::GetDataFromUPK(const char* filepath)
{
	Data ret;

	//根據檔案路徑找到檔案資訊;
	for (int index=0;index<m_allFileInforVec.size();index++)
	{
		OneFileInfor oneFileInfor=m_allFileInforVec[index];
		std::string path=filepath;
		if (oneFileInfor.m_Path==path)
		{
			//找到了檔案,開始讀取檔案資料;
			std::string fullPath = FileUtils::getInstance()->fullPathForFilename("Deemo.UPK");
			std::ifstream fin(fullPath.c_str(),std::ios::binary);
			if (!fin)
			{
				CCLOG("File Open Error");
				return ret;
			}

			char* buffer=NULL;
			buffer=(char*)malloc(oneFileInfor.m_Size);

			fin.seekg(oneFileInfor.m_StartPos,std::ios::beg); //ios::cur從當前位置偏移;ios::beg從檔案開頭偏移;

			fin.read(buffer,oneFileInfor.m_Size);

			ret.fastSet((unsigned char *)buffer,oneFileInfor.m_Size);

			fin.close();

			break;
		}
		
	}
	
	return ret;
}

成功執行轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

工程下載:轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

http://pan.baidu.com/s/1pJkf2mJ

http://download.csdn.net/detail/cp790621656/8609965

轉自陳裡陳外的部落格 http://blog.csdn.net/huutu 星環遊戲 http://www.thisisgame.com.cn

相關推薦

Cocos2d-x 遊戲資源(圖片XMLTXT)打包加密 解密讀取

自上一篇  Unity3d 遊戲資源打包加密(圖片/XML/TXT等) C#編碼 (一)   介紹如何打包加密遊戲資源已經好幾月,卻沒有詳細說明如何在遊戲中去讀取加密的資源,雖然聰明的程式設計師看一眼就知道如何逆向編碼,但是還是詳細說明一下,以作完結。 轉自陳裡陳外的部落

Cocos2d-x 遊戲資源 圖片 XML TXT 打包加密 解密讀取

                自上一篇  Unity3d 遊戲資源打包加密(圖片/XML/TXT等) C#編碼 (一)

quick-cocos2d-x遊戲開發【2】——項目結構分析創建新場景

fileutil 遊戲 log world plain ack 設計 avi sca 創建完一個新項目之後,我們能夠簡單的看一看這個項目的文件組成,有這麽一個文件層次結構 幾個proj.*目錄就不用說了,是相應的平臺的解決方式,res專門存放我們的遊戲資源

Cocos2d-x開發---改變父節點顏色透明度影響子節點

       引擎版本為:2.1.4        引擎中諸如CCSprite 設定顏色的時候是使用基類:CCNodeRGBA中的setColor 方法的。該方法的程式碼: void CCNodeRGBA::setColor(const ccColor3B& color) { _displ

Java 將Excel轉為圖片htmlXPSXMLCSV

通過文件格式轉換,可滿足不同辦公場合對文件操作的需求。本文將介紹轉換Excel文件為其他常見文件格式的方法。通過文中的方法,可支援將Excel轉換為包括PDF、圖片、html、XPS、XML、CSV、PCL、ODS、PostScript、以及Office Excel不同版本,如,version97-2003,

cocos2d-x-3.1 國際化strings.xml解決亂碼問題 (coco2d-x 學習筆記四)

source ron 文件 亂碼問題 resource -s type fileutil ani 今天寫程序的時候發現輸出文字亂碼,盡管在實際開發中把字符串寫在代碼裏是不好的做法。可是有時候也是為了方便,遇到此問題第一時間在腦子裏面聯想到android下的strings

Cocos2d-x學習資源集錦+有獎抽樓活動

活躍 ocs 重要 cvs vs2013 develop cocos2d 規則 英文 大家好,事實上我是這個遊戲開發版塊的新任版主之中的一個,可能大家的焦點都在candycat1992女版主身上,所以我認為我應該冒個泡。 俗話說,新版主上任,三把"水"(是你自己說的吧,

HTMLXMLXHTML 有什麽區別?

簡單介紹 粗體 創建 小寫字母 hyper intern spa htm 控件 HTML即是超文本標記語言(Hyper Text Markup Language),是最早寫網頁的語言,但是由於時間早,規範不是很好,大小寫混寫且編碼不規範,是語法較為松散的、不嚴

Java動態代理XML正則

類的方法 編寫 編碼 new 就是 返回 st2 spl 5.2.1 15.1 動態代理 在之後學習Spring框架時,Spring框架有一大核心思想,就是AOP,(Aspact-Oriented-Programming 面向切面編程) 而AOP的原理就是J

常用模塊(三)——shelvexmlhashlibconfigparser

new .config 映射 法規 加密 生成xml oot 結束 一定的 常用模塊(三) 一、shelve模塊 1、shelve模塊也是一種序列化模塊,內部使用的是pickle模塊,所以也存在跨平臺性差的問題 2、特點:    只要提供一個文件名即可    讀寫的方式和字

python學習的第21天模塊picklejsonxmlshelveconfigparser

簡化 我們 計算機 pri 區別 type 簽名 pass 企業 一、pickle *** 1、作用;專門用於python語言的序列化 PS;(1)什麽是序列化? 指的是將內存中的數據結構轉化為一種中間格式,並存儲到硬盤上 (2)

cocos2d x遊戲開發系列教程 坦克大戰遊戲子彈的碰撞檢測處理

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d x遊戲開發系列教程 坦克大戰遊戲虛擬手柄控制坦克移動

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d x遊戲開發系列教程 中國象棋03 主介面

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d x遊戲開發系列教程 坦克大戰遊戲坦克和地圖碰撞的檢測上

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d x遊戲開發系列教程 坦克大戰遊戲敵方坦克AI的編寫

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

python學習的第21天模組picklejsonxmlshelveconfigparser

一、pickle  *** 1、作用;專門用於python語言的序列化 PS;(1)什麼是序列化?                指的是將記憶體中的資料結構轉化為一種中間格式,並存儲到硬碟上   &nb

cocos2d-x遊戲開發系列教程-中國象棋05-開始遊戲

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

cocos2d-x遊戲開發系列教程-中國象棋04-擺棋

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Cocos2d-x遊戲匯出android工程,提取cocos的so檔案

  Cocos2d-x遊戲匯出android工程,提取cocos的so檔案   原本cocos遊戲的android工程編譯時,需要將cocos的庫檔案進行編譯,這些檔案大部分是cpp檔案, 使用ndk-build工具編譯cpp檔案非常慢,而且非常耗cpu