【轉】quick-cocos2d-x數據存儲之GameState

quick-cocos2d-x數據存儲之GameState


GameState是quick-cocos2d-x中特有的一個用戶信息存儲類,相對於CCUserDefault而言,它增加了數據校驗的功能,當數據被人爲的改變之後,會被檢測出來,下面介紹它的主要用法。


一、初始化

因爲GameState並沒有在framework中加載,所以我們要在開始的代碼中去加載,如在MyApp.lua的開頭位置加載

GameState=require(cc.PACKAGE_NAME .. ".api.GameState")


二、提供的方法

1、GameState.init(eventListener_, stateFilename_, secretKey_)

這個方法是初始化GameState,在場景初始化之前調用一次即可,如在MyApp.lua的MyApp:ctor()中調用。

eventListener_是載入或保存時調用的函數,可以寫個匿名函數,後面會重點介紹;

stateFilename_是保存的文件名,如果留空或非字符串(string)則是默認的state.txt,該文件會被保存到device.writablePath下;

secretKey_是校驗文件時所用到的密鑰,GameState保存的數據格式爲{h = hash, s = s},s是我們要保存的數據(一個table),h則是要校驗的一個md5碼。如果secretKey_留空或爲非字符串(string)則不加校驗碼,直接保存數據,跟CCUserDefault一樣了。

2、GameState.load()

載入並返回數據,一般此方法只調用一些就行,在遊戲加載前調用並保存到一個全局變量GameData。

3、GameState.save(newValues)

保存數據,newValues是一個table。GameState.init對應於保存一個文件,此文件的內容就是newValues,所以我們需要更新數據的時候應該改變上面的GameData,然後保存GameData。

4、GameState.getGameStatePath()

保存的文件的完整路徑。


三、eventListener(value)

此函數就是GameState.init中的第一個參數,value爲一個table,此函數在載入或保存時都會被調用,相當於一個監聽器。不同的情況下value的值會不一樣。注意:eventListener一定要有返回值。

1、GameState.load()中用到的eventListener

1)  如果在這個函數中載入數據時有異常發生,value值爲{name = "load", errorCode = errorCode},name有兩種值,"load"和"save",分別對應載入和保存;errorCode分爲三種:

GameState.ERROR_INVALID_FILE_CONTENTS //不合法的文件內容,即取出來的內容不是一個table  -1

GameState.ERROR_HASH_MISS_MATCH //文件被人爲更改過  -2 

GameState.ERROR_STATE_FILE_NOT_FOUND //文件不存在   -3

這個時候eventListener可返回nil。

2)  如果載入的數據是正確的,value值爲

{
        name   = "load",
        values = values,
        encode = encode,
        time   = os.time()
 }

values就是取出的數據;encode數據是否加密過;time當前取出的時間。這個時候eventListener返回value.values即可。

2、GameState.save(newValues)中用到的eventListener

這時value值爲{
        name   = "save",
        values = newValues,
        encode = type(secretKey) == "string"
    }

values就是要保存的數據;encode數據是否要加密。這個時候eventListener返回value.values即可。

當然,以上的情況你都可以做一些其它的事,如彈出錯誤的窗口,或打印出已加載或已保存的數據。


四、加密數據

GameState保存的還是明文數據,只是加了校驗碼,如果我們不想被用戶知道保存了什麼信息,可加密了再保存,這個在eventListener中“過濾”一下就行了。


五、示例

下面是一個完整的加載、初始化、載入,保存及加解密的過程代碼:

//MyApp.lua(加載、初始化、載入,加解密)

...

require("framework.cc.init")
GameState=require(cc.PACKAGE_NAME .. ".api.GameState")

-- global var

GameData={}
...

function MyApp:ctor()
    -- init GameState
    GameState.init(function(param)
        local returnValue=nil
        if param.errorCode then
            CCLuaLog("error")
        else
            -- crypto
            if param.name=="save" then
                local str=json.encode(param.values)
                str=crypto.encryptXXTEA(str, "abcd")  --使用 XXTEA 算法加密內容 str:明文字符串 "296":祕鑰字符串 str返回值:加密後的字符串
                returnValue={data=str}
            elseif param.name=="load" then
                local str=crypto.decryptXXTEA(param.values.data, "abcd")  --使用 XXTEA 算法解密內容 param.values.data 加密字符串 "296":祕鑰字符串 str返回值:明文字符串
                returnValue=json.decode(str)
            end
            -- returnValue=param.values
        end
        return returnValue
    end, "data.txt","1234")
    if io.exists(GameState.getGameStatePath()) then
        GameData=GameState.load()
    end

.....
end

....

//保存的時候
GameData.aaa="bbb" --.aaa名字是隨便起的,就是存到文件裏的名字
GameState.save(GameData)




發佈了27 篇原創文章 · 獲贊 2 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章