csvdatad.lua
2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
local sharedata = require "skynet.sharedata"
local skynet = require "skynet"
local lfs = require "lfs"
local redisproxy = require "shared.redisproxy"
require "shared.init"
require "utils.init"
require "csvdata.init"
require "skynet.manager"
require "RedisKeys"
-- local csvdb = {}
local function formatFileName(filename)
	filename = string.trim(filename)
	local basename = filename:match("([^/]+)%.lua$")
	if not basename then return end
	local loadname = filename:match("^src/([^.]+)%.lua$")
	loadname = loadname:gsub('/', '.')
	return basename, loadname
end
local function travCsv(rootPath, pathes)
	pathes = pathes or {}
	local modified = false
	local ok, files, iter = pcall(lfs.dir, rootPath)
	if not ok then return modified end
	for entry in files, iter do
		-- 过滤 . 开始的字符串包括 . .. .git .开头的文件名
		if string.byte(entry, 1) ~= 46 then
			local pathfile = rootPath .. '/' .. entry
			local attrs = lfs.attributes(pathfile)
			if attrs.mode == 'directory' then
				modified = travCsv(pathfile, pathes) or modified
			else
				local basename, loadname = formatFileName(pathfile)
				if basename then
					if tonum(pathes[loadname]) < attrs.modification then
						modified = true
						pathes[loadname] = attrs.modification
					end
					if basename == "init" or basename == "init_adv" then
						require(loadname)
					end
				end
			end
		end
	end
	return modified
end
-- 每分钟检查是否有更改
local file2timeMap = {}
local function handle_timeout()
	if travCsv("src/csvdata", file2timeMap) then
		sharedata.update("csvdata", csvdb)
	end
	skynet.timeout(100*5, handle_timeout)
end
-- 重新加载csvdb
local CMD = {}
function CMD.reload(code)
	csvdb = csvdb or {}
	
	local ok, func = pcall(load, code)
	if ok then
		ok = pcall(func)
	end
	if not ok then
		skynet.error("reload_csvdata error by code " .. code)
		return 'error'
	end
	sharedata.update("csvdata", csvdb)
	return 'ok'
end
--更新已经存在的
function CMD.hotfix(fieldss)
	csvdb = csvdb or {}
	for _, fields in ipairs(fieldss) do
		if #fields >= 3 and (type(fields[#fields]) == 'number' or type(fields[#fields]) == 'string') then
			local temp = csvdb
			local ok = false
			for i = 1, #fields - 1 do
				if type(temp) ~= 'table' then break end
				if type(fields[i]) ~= 'number' and type(fields[i]) ~= 'string' then break end
				if i == #fields - 1 then
					if type(temp[fields[i]]) ~= 'number' and type(temp[fields[i]]) ~= 'string' then break end
					temp[fields[i]] = fields[#fields]
				else
					temp = temp[fields[i]]
				end
			end
		end
	end
	sharedata.update("csvdata", csvdb)
	return 'ok'
end
skynet.start(function ()
	travCsv("src/csvdata", file2timeMap)
	sharedata.new("csvdata", csvdb)
	-- handle_timeout()
	skynet.dispatch("lua", function(_, _, command, ...)
		local f = CMD[command]
		skynet.ret(skynet.pack(f(...)))
	end)
	skynet.register(".CSVDATA")
end)