quick-cocos2d-x数据存储之GameState

因为GameState并没有在framework中加载,所以我们要在开始的代码中去加载,如在MyApp.lua的开头位置加载
GameState=require(cc.PACKAGE_NAME .. ".api.GameState")

local GameState = {}

GameState.ERROR_INVALID_FILE_CONTENTS = -1
GameState.ERROR_HASH_MISS_MATCH       = -2
GameState.ERROR_STATE_FILE_NOT_FOUND  = -3

local crypto = require(cc.PACKAGE_NAME .. ".crypto")
local json   = require(cc.PACKAGE_NAME .. ".json")

local encodeSign    = "=QP="
local stateFilename = "state.txt"
local eventListener = nil
local secretKey     = nil

local function isEncodedContents_(contents)
    return string.sub(contents, 1, string.len(encodeSign)) == encodeSign
end

local function encode_(values)
    local s = json.encode(values)
    local hash = crypto.md5(s..secretKey)
    local contents = json.encode({h = hash, s = s})
    return encodeSign..contents
end

local function decode_(fileContents)
    local contents = string.sub(fileContents, string.len(encodeSign) + 1)
    local j = json.decode(contents)

    if type(j) ~= "table" then
        echoError("GameState.decode_() - invalid contents")
        return {errorCode = GameState.ERROR_INVALID_FILE_CONTENTS}
    end

    local hash,s = j.h, j.s
    local testHash = crypto.md5(s..secretKey)
    if testHash ~= hash then
        echoError("GameState.decode_() - hash miss match")
        return {errorCode = GameState.ERROR_HASH_MISS_MATCH}
    end

    local values = json.decode(s)
    if type(values) ~= "table" then
        echoError("GameState.decode_() - invalid state data")
        return {errorCode = GameState.ERROR_INVALID_FILE_CONTENTS}
    end

    return {values = values}
end

----------------------------------------

function GameState.init(eventListener_, stateFilename_, secretKey_)
    if type(eventListener_) ~= "function" then
        echoError("GameState.init() - invalid eventListener")
        return false
    end

    eventListener = eventListener_

    if type(stateFilename_) == "string" then
        stateFilename = stateFilename_
    end

    if type(secretKey_) == "string" then
        secretKey = secretKey_
    end

    eventListener({
        name     = "init",
        filename = GameState.getGameStatePath(),
        encode   = type(secretKey) == "string"
    })

    return true
end

function GameState.load()
    local filename = GameState.getGameStatePath()

    if not io.exists(filename) then
        echoInfo("GameState.load() - file \"%s\" not found", filename)
        return eventListener({name = "load", errorCode = GameState.ERROR_STATE_FILE_NOT_FOUND})
    end

    local contents = io.readfile(filename)
    echoInfo("GameState.load() - get values from \"%s\"", filename)

    local values
    local encode = false

    if secretKey and isEncodedContents_(contents) then
        local d = decode_(contents)
        if d.errorCode then
            return eventListener({name = "load", errorCode = d.errorCode})
        end

        values = d.values
        encode = true
    else
        values = json.decode(contents)
        if type(values) ~= "table" then
            echoError("GameState.load() - invalid data")
            return eventListener({name = "load", errorCode = GameState.ERROR_INVALID_FILE_CONTENTS})
        end
    end

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

function GameState.save(newValues)
    local values = eventListener({
        name   = "save",
        values = newValues,
        encode = type(secretKey) == "string"
    })
    if type(values) ~= "table" then
        echoError("GameState.save() - listener return invalid data")
        return false
    end

    local filename = GameState.getGameStatePath()
    local ret = false
    if secretKey then
        ret = io.writefile(filename, encode_(values))
    else
        local s = json.encode(values)
        if type(s) == "string" then
            ret = io.writefile(filename, s)
        end
    end

    echoInfo("GameState.save() - update file \"%s\"", filename)
    return ret
end

function GameState.getGameStatePath()
    return string.gsub(device.writablePath, "[\\\\/]+$", "") .. "/" .. stateFilename
end

return GameState

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值