diff --git a/config.lua b/config.lua index abb1967..f8565ff 100644 --- a/config.lua +++ b/config.lua @@ -22,3 +22,4 @@ factions_config.faction_diplomacy = minetest.settings:get_bool("factions.faction factions_config.spawn_teleport = minetest.settings:get_bool("factions.spawn_teleport") or false factions_config.protection_style = minetest.settings:get("factions.protection_style") or "2d" factions_config.faction_user_priv = minetest.settings:get("factions.faction_user_priv") or false +factions_config.database = minetest.settings:get("factions.database") or "mod_storage" diff --git a/databases.lua b/databases.lua index 032ef04..64f96cb 100644 --- a/databases.lua +++ b/databases.lua @@ -2,12 +2,27 @@ --! @brief main class for factions factions = {} --- Create cold databases. -factions.root = colddb.Colddb(minetest.get_worldpath() .. "/factions") -factions.factions = factions.root.sub_database("factions") -factions.parcels = factions.root.sub_database("parcels") -factions.players = factions.root.sub_database("players") -factions.player_ips = factions.root.sub_database("ips") +-- database +factions.root = {} +factions.factions = {} +factions.parcels = {} +factions.players = {} +factions.player_ips = {} + +if factions_config.database == "colddb" then + -- Create cold databases. + factions.root = colddb.Colddb(minetest.get_worldpath() .. "/factions") + factions.factions = factions.root.sub_database("factions") + factions.parcels = factions.root.sub_database("parcels") + factions.players = factions.root.sub_database("players") + factions.player_ips = factions.root.sub_database("ips") +elseif factions_config.database == "mod_storage" then + factions.root = storagedb.Storagedb("factions") + factions.factions = factions.root.sub_database("factions") + factions.parcels = factions.root.sub_database("parcels") + factions.players = factions.root.sub_database("players") + factions.player_ips = factions.root.sub_database("ips") +end -- Memory only storage. factions.onlineplayers = {} @@ -145,21 +160,21 @@ end minetest.register_on_mods_loaded(function() minetest.log("Checking faction files.") for k, v in factions.factions.iterate() do - update_data(factions.factions, k, nil, factions.create_faction_table(), true) + --update_data(factions.factions, k, nil, factions.create_faction_table(), true) end minetest.log("Checking parcel files.") for k, v in factions.parcels.iterate() do - update_data(factions.parcels, k, nil, factions.create_parcel_table(), true) + --update_data(factions.parcels, k, nil, factions.create_parcel_table(), true) end minetest.log("Checking player files.") for k, v in factions.players.iterate() do - update_data(factions.players, k, nil, factions.create_player_table(), true) + --update_data(factions.players, k, nil, factions.create_player_table(), true) end minetest.log("Checking ip files.") for k, v in factions.player_ips.iterate() do - update_data(factions.player_ips, k, nil, factions.create_ip_table(), true) + --update_data(factions.player_ips, k, nil, factions.create_ip_table(), true) end end) diff --git a/init.lua b/init.lua index 3ff166b..79cdb39 100644 --- a/init.lua +++ b/init.lua @@ -2,6 +2,7 @@ factions_modpath = minetest.get_modpath("factions") dofile (factions_modpath .. "/config.lua") +dofile (factions_modpath .. "/storagedb.lua") dofile (factions_modpath .. "/databases.lua") dofile (factions_modpath .. "/eventcallbacks.lua") dofile (factions_modpath .. "/diplomacy_events.lua") diff --git a/mod.conf b/mod.conf index 2a4f577..204cf48 100644 --- a/mod.conf +++ b/mod.conf @@ -1,3 +1,3 @@ name = factions description = Mc style faction system. -depends = colddb +optional_depends = colddb diff --git a/settingtypes.txt b/settingtypes.txt index e5ee22c..369e23a 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -52,4 +52,6 @@ factions.faction_user_priv (Enable faction user priv) bool false # Set the way that the parcel protection works (2d, 3d). # 2d limits how far x and z can go but protection on the y goes up and down far. # 3d limits all three axis. -factions.protection_style (Protection style) enum 2d 3d,2d \ No newline at end of file +factions.protection_style (Protection style) enum 2d 3d,2d +# Set the type of database to use. +factions.database (Database) enum mod_storage colddb,mod_storage diff --git a/storagedb.lua b/storagedb.lua new file mode 100644 index 0000000..d7da0c3 --- /dev/null +++ b/storagedb.lua @@ -0,0 +1,193 @@ +local storage = minetest.get_mod_storage() +storagedb = {} + +function storagedb.Storagedb(dir) + local self = {} + + local directory = dir + local mem_pool = {} + local mem_pool_del = {} + local add_to_mem_pool = true + local serializer = minetest.serialize + local deserializer = minetest.deserialize + + -- make tables weak so the garbage-collector will remove unused data + setmetatable(mem_pool, {__mode = "kv"}) + setmetatable(mem_pool_del, {__mode = "kv"}) + + local function storekey(key) + local list = minetest.deserialize(storage:get_string(directory)) + if not list then + list = {} + list[dir .. "/" .. key] = key + else + list[dir .. "/" .. key] = key + end + storage:set_string(directory, minetest.serialize(list)) + end + local function removekey(key) + local list = minetest.deserialize(storage:get_string(directory)) + if not list then + list = {} + else + list[dir .. "/" .. key] = nil + end + storage:set_string(directory, minetest.serialize(list)) + end + local function getkeys() + local list = minetest.deserialize(storage:get_string(directory)) + if not list then + list = {} + end + return list + end + + self.get_memory_pool = function() + return mem_pool + end + self.set_memory_pool = function(pool) + mem_pool = pool + end + self.add_to_memory_pool = function(value) + if value then + add_to_mem_pool = value + end + return add_to_mem_pool + end + self.get_serializer = function() + return serializer, deserializer + end + self.set_serializer = function(coder, decoder) + serializer = coder + deserializer = decoder + end + local function load_into_mem(name, _table) + if add_to_mem_pool then + mem_pool[name] = {mem = _table} + end + end + local function load_table(name) + local f = storage:get_string(string.format("%s/%s", directory, name)) + if f then + local data = deserializer(f) + return data + end + return nil + end + local function save_table(name, _table) + if save_table == nil or name == nil then + return false + end + storekey(name) + storage:set_string(string.format("%s/%s", directory, name), minetest.serialize(_table)) + end + local function save_key(name) + storage:set_string(string.format("%s/%s", directory, name), "") + end + local function load_key(name) + local f = storage:get_string(string.format("%s/%s", directory, name)) + if f ~= "" then + return true + end + return false + end + self.set_mem = function(name, _table) + load_into_mem(name, _table) + mem_pool_del[name] = nil + end + self.save_mem = function(name) + if mem_pool[name] ~= nil then + save_table(name, mem_pool[name].mem) + end + mem_pool_del[name] = nil + end + + self.clear_mem = function(name) + mem_pool[name] = nil + mem_pool_del[name] = nil + end + + self.set = function(name, _table) + save_table(name, _table) + if add_to_mem_pool then + load_into_mem(name, _table) + end + mem_pool_del[name] = nil + end + + self.set_key = function(name) + save_key(name) + if add_to_mem_pool then + load_into_mem(name, "") + end + mem_pool_del[name] = nil + end + + self.get = function(name, callback) + if mem_pool_del[name] then + if callback then + callback(nil) + end + return nil + end + local pm = mem_pool[name] + if pm then + if callback then + callback(pm.mem) + end + return pm.mem + else + local _table = load_table(name) + if _table then + load_into_mem(name, _table) + if callback then + callback(_table) + end + return _table + end + end + mem_pool_del[name] = true + return nil + end + + self.remove = function(name) + mem_pool[name] = nil + mem_pool_del[name] = true + removekey(name) + storage:set_string(string.format("%s/%s", directory, name), "") + end + + self.sub_database = function(path) + local db = storagedb.Storagedb(dir .. "/" .. path) + return db + end + self.to_array = function() + local entries = {} + + for k, v in pairs(getkeys()) do + entries[#entries + 1] = v + end + + return entries + end + self.to_table = function() + local entries = {} + + for k, v in pairs(getkeys()) do + entries[v] = true + end + + return entries + end + self.iterate = function() + local entries = {} + + for k, v in pairs(getkeys()) do + entries[v] = true + end + + return pairs(entries) + end + + return self +end