游戏策划配表并自动更新到数据库

  在游戏开发中,数值是必不可少的,数值一般由策划设计导出,然后开发再将数值应用于游戏代码中。但是策划的需求是经常会变的,这就导致数值会频道的修正,如果没次都去更新代码来导入这会给开发带来很多不必要的麻烦,所以设计一套配表系统和自动读取导入的小工具就显得很有必要。
  下面这套小工具是基于公司的一套lua手游服务端开发的配表工具。配表采用csv文件来实现,csv可以用excel打开,方便策划们直观的配置游戏数据。同时csv文件是逗号分隔文件,程序方面也很容易进行解析。先贴上一段lua解析csv文件的代码(暂时没有实现读取子文件夹内文件的功能,可以自行添加)

for file in lfs.dir(csv_file_path) do
    if file ~= "." and file ~= ".." then
        local real_file = csv_file_path .."/".. file
        --获取标题和内容
        local parsed_csv_titles,parsed_csv_table =    parse_csv:load_csv_file(real_file)
    end
end
local M = {}
local log = require("log"):new("parse_csv")

function split(str, reps)  
    local resultStrsList = {};  
    string.gsub(str, '[^' .. reps ..']+', function(w) table.insert(resultStrsList, w) end );  
    return resultStrsList;  
end  

--一行一行取用数据  
local function get_row_content(file)  
    local content;  
    local check = false  
    local count = 0  
    while true do  
        local t = file:read()  
        if not t then  
            if count == 0 then  
                check = true  
            end  
        break  
    end

    if not content then  
        content = t  
    else  
        content = content..t  
    end  

    local i = 1  
    while true do    
        local index = string.find(t, "\"", i)    
        if not index then break end    
            i = index + 1    
            count = count + 1    
        end    

        if count % 2 == 0 then   
            check = true   
            break   
        end    
    end    

    if not check then    
        assert(1~=1)   
    end  
    --返回去掉空格的一行数据,还有方法没看明白,以后再修改  
    return content and (string.gsub(content, " ", ""))  
end  

function M:load_csv_file(filePath)  
    -- 读取文件  
    local alls = {}  
    local file = io.open(filePath, "r")  

    while true do  
        local line = get_row_content(file)  
        if not line then  
            break  
        end  
        table.insert(alls, line)  
    end  
    --[[ 从第3行开始保存(第一行是中文注释,第二行是标题,后面的行才是内容) 用二维数组保存:arr[ID][属性标题字符串] ]]  
    local titles = split(alls[2], ",")  
    local ID = 1  
    local arrs = {}  
    for i = 3, #alls, 1 do  
        -- 一行中,每一列的内容,第一位为ID  
        local content = split(alls[i], ",")
        ID = tonumber(content[1])
        --保存ID,以便遍历取用,原来遍历可以使用in pairs来执行,所以这个不需要了
        --table.insert(arrs, i-1, ID)  
        arrs[ID] = {}  
        -- 以标题作为索引,保存每一列的内容,取值的时候这样取:arrs[1].Title  
        for j = 1, #titles, 1 do  
            arrs[ID][titles[j]] = content[j]
        end
    end
    --[[
    for l = 1, #titles, 1 do  
        log:info("title = " ..titles[l])
    end

    for k = 1, #arrs,1 do
        log:info("key = " ..arrs[k].card_id .. " value = " ..arrs[k].card_type)
    end
    --]]
    --返回标题和内容
    return titles,arrs
end

return M

  
  对于解析出来的数据,我们还需要导入到数据库,这里我采用的是mongodb数据库,每次更新完配表,策划只需要点击客户端工具上面的“更新数据库”按钮即可完成服务端的自动更新。客户端工具仅仅是发送一个rpc请求给服务器,让服务器完成配表的读取与导入,客户端实现很简单就不贴代码了。服务端更新数据库代码如下:
  

for l = 1, #parsed_csv_titles, 1 do  
    log:info("title = " ..parsed_csv_titles[l])
end

for i = 1, #parsed_csv_table,1 do
    --循环构造出插入的子语句
    local state = {}
    for j = 1, #parsed_csv_titles, 1 do
        local key = parsed_csv_titles[j]
        local value = parsed_csv_table[i][key]
        state[key] = value
   --     log:info(parsed_csv_titles[j] .. "=" ..parsed_csv_table[i][parsed_csv_titles[j]] .. " ")
    end

    --先查询该条目是否存在,如果存在则更新,否则插入
    card_index = parsed_csv_table[i].card_index
    mdb:update(db, collection, {card_index = card_index},state)
end 

实现效果:
这里写图片描述

这里写图片描述
这里写图片描述

客户端exe工具:
https://pan.baidu.com/s/1dFrEDl3

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页