diff options
Diffstat (limited to 'datastorage/init.lua')
-rw-r--r-- | datastorage/init.lua | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/datastorage/init.lua b/datastorage/init.lua new file mode 100644 index 0000000..30677fc --- /dev/null +++ b/datastorage/init.lua @@ -0,0 +1,98 @@ +datastorage = {data = {}} + +local DIR_DELIM = DIR_DELIM or "/" +local data_path = minetest.get_worldpath()..DIR_DELIM.."datastorage"..DIR_DELIM + +function datastorage.save(id) + local data = datastorage.data[id] + -- Check if the container is empty + if not data or not next(data) then return end + for _, sub_data in pairs(data) do + if not next(sub_data) then return end + end + + local file = io.open(data_path..id, "w") + if not file then + -- Most likely the data directory doesn't exist, create it + -- and try again. + if minetest.mkdir then + minetest.mkdir(data_path) + else + -- Using os.execute like this is not very platform + -- independent or safe, but most platforms name their + -- directory creation utility mkdir, the data path is + -- unlikely to contain special characters, and the + -- data path is only mutable by the admin. + os.execute('mkdir "'..data_path..'"') + end + file = io.open(data_path..id, "w") + if not file then return end + end + + local datastr = minetest.serialize(data) + if not datastr then return end + + file:write(datastr) + file:close() + return true +end + +function datastorage.load(id) + local file = io.open(data_path..id, "r") + if not file then return end + + local data = minetest.deserialize(file:read("*all")) + datastorage.data[id] = data + + file:close() + return data +end + +-- Compatability +function datastorage.get_container(player, id) + return datastorage.get(player:get_player_name(), id) +end + +-- Retrieves a value from the data storage +function datastorage.get(id, ...) + local last = datastorage.data[id] + if last == nil then last = datastorage.load(id) end + if last == nil then + last = {} + datastorage.data[id] = last + end + local cur = last + for _, sub_id in ipairs({...}) do + last = cur + cur = cur[sub_id] + if cur == nil then + cur = {} + last[sub_id] = cur + end + end + return cur +end + +-- Saves a container and reomves it from memory +function datastorage.finish(id) + datastorage.save(id) + datastorage.data[id] = nil +end + +-- Compatability +function datastorage.save_container(player) + return datastorage.save(player:get_player_name()) +end + +minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + datastorage.save(player_name) + datastorage.data[player_name] = nil +end) + +minetest.register_on_shutdown(function() + for id in pairs(datastorage.data) do + datastorage.save(id) + end +end) + |