Use better save formats

* Save using Settings API
* Support for Minetest modstorage API
* Auto import from old format
master
octacian 2017-07-02 12:15:11 -07:00
parent 2943f1be9a
commit 7a6d676b36
2 changed files with 106 additions and 25 deletions

View File

@ -6,9 +6,9 @@ Static Spawnpoint [spawnpoint]
* [Download Latest Version](https://github.com/octacian/spawnpoint/archive/master.zip)
* ...or browse the code on [GitHub](https://github.com/octacian/spawnpoint)
This is a rather simple mod introducing two commands to set a static spawnpoint and to teleport to it. Yes, I know you can set this in `minetest.conf`, however, doing so causes the spawnpoint to be the same across all of your worlds (very inconvenient). Instead of using `minetest.conf`, this mod stores the spawnpoint (and other settings) as a multi-line string within a file called `spawnpoint.conf` in the world directory. This allows each and every world to have a different spawnpoint.
This is a rather simple mod introducing two commands to set a static spawnpoint and to teleport to it. Yes, I know you can set this in `minetest.conf`, however, doing so causes the spawnpoint to be the same across all of your worlds (very inconvenient). Instead of using `minetest.conf`, this mod stores the spawnpoint (and other settings) within the world directory itself. This allows each and every world to have a different spawnpoint and configuration.
The most unique thing about this spawn mod is that it includes a feature allowing you to set the time between executing the command until the player is actually teleported. By default, the teleportation will be interrupted if the player moves within that time. The time and the feature requiring players to stand still can be configured as documented below in the configuration section.
The most unique thing about this spawn mod is that it includes a feature allowing you to set the time between executing the command until the player is actually teleported. You can also enable a setting which causes the teleportation to be interrupted if the player moves within the original time.
### Commands
- `/spawnpoint`: Display spawnpoint position if set (also see configuration section)
@ -18,9 +18,14 @@ The most unique thing about this spawn mod is that it includes a feature allowin
__Note:__ If no spawnpoint is specified and a player attempts to execute `/spawn`, he/she will be told "No spawnpoint set!"
### Configuration
The different "variables" of SpawnPoint can be configured per-world using the `/spawnpoint` command (requires server privilege). By default this command displays the spawnpoint, but when providing a setting name as well, the value of the setting is returned (assuming such a setting exists). If a setting name and value is provided, the setting is changed. Valid setting names are listed below.
The different "variables" of SpawnPoint can be configured per-world using the `/spawnpoint` command (requires server privilege). This command displays the spawnpoint if no parameters are provided, but when a setting name is provided, the value of the setting is returned (assuming such a setting exists). If a setting name and value is provided, the setting is changed. Valid setting names are listed below.
* `time`: Time before teleportation is completed (if `0` teleportation is immediate)
* `do_not_move`: Whether a player should be required to not move to allow teleportation to be successful
* `pos`: Position in the format `(<x>,<y>,<z>)` - can only be set via `/setspawn` or manually in configuration files
Screenshot was taken at spawn on the awesome [HOMETOWN](https://forum.minetest.net/viewtopic.php?f=10&t=16699) server!
This per-world configuration (including the spawn position itself) is stored in the world directory. If Minetest 0.4.16's new modstorage is available, SpawnPoint will use that to store configuration. Otherwise, configuration will be handled by the Minetest `Settings` API and placed in a `spawnpoint.conf` file. If you would like to configure SpawnPoint manually, create a `spawnpoint.conf` file in the world directory and assign values to the applicable settings as documented above, each setting on a new line in the format `setting_name = setting_value`.
Initially, SpawnPoint stored all settings in a multi-line `spawnpoint.conf` file, however, this made very little sense as setting weren't named. With the new configuration scheme as documented above, compatibility code has been implemented causing all the old settings to be imported into the newest format possible. When the formatted settings method is used with `spawnpoint.conf`, all configuration is automatically imported to Minetest modstorage as well when it becomes available. After importing takes place from `spawnpoint.conf`, the file is removed.
Screenshot was taken at spawn on the awesome [HOMETOWN](https://forum.minetest.net/viewtopic.php?f=10&t=16699) server!

118
init.lua
View File

@ -2,7 +2,13 @@
spawnpoint = {}
local storage
local path = minetest.get_worldpath().."/spawnpoint.conf"
local data = Settings(path)
if minetest.get_mod_storage then
storage = minetest.get_mod_storage()
end
-- [function] Log
function spawnpoint.log(content, log_type)
@ -38,34 +44,102 @@ end)
-- HELPER FUNCTIONS --
----------------------
-- [local function] Count table contents
local function count(t)
local count = 0
for _, i in pairs(t) do
count = count + 1
end
return count
end
-- [local function] Check if table is empty
local function is_empty(t)
if t.fields then
return count(t.fields) == 0
else
return count(t) == 0
end
end
-- [function] Load
function spawnpoint.load()
local res = io.open(path, "r")
if res then
res = res:read("*all"):split("\n", true)
if data and not is_empty(data:to_table()) then
spawnpoint.time = tonumber(data:get("time"))
spawnpoint.do_not_move = data:get_bool("do_not_move")
spawnpoint.time = tonumber(res[1]) or 3
spawnpoint.do_not_move = not not res[2] or true
if res[3] then
spawnpoint.pos = minetest.string_to_pos(res[3])
local pos = data:get("pos")
if pos then
spawnpoint.pos = minetest.string_to_pos(pos)
end
if storage then
os.remove(path)
end
minetest.log("Loaded via Settings")
elseif storage and not is_empty(storage:to_table()) then
local pos = storage:get_string("pos")
if pos then
spawnpoint.pos = minetest.string_to_pos(pos)
end
local do_not_move = storage:get_string("do_not_move")
if do_not_move == "true" or do_not_move == true then
spawnpoint.do_not_move = true
else
spawnpoint.do_not_move = false
end
spawnpoint.time = storage:get_float("time")
minetest.log("Loaded via modstorage")
else
spawnpoint.time = 3
spawnpoint.do_not_move = true
local f = io.open(path, "r")
if f then
local res = f:read("*all"):split("\n", true)
spawnpoint.time = tonumber(res[1])
if res[2] == "true" or res[2] == true then
spawnpoint.do_not_move = true
else
spawnpoint.do_not_move = false
end
if res[3] then
spawnpoint.pos = minetest.string_to_pos(res[3])
end
f:close()
-- Clear file
os.remove(path)
end
end
end
-- [function] Save
function spawnpoint.save()
local str = tostring(spawnpoint.time)..
"\n"..tostring(spawnpoint.do_not_move) or ""
if storage then
storage:set_float("time", spawnpoint.time)
storage:set_string("do_not_move", tostring(spawnpoint.do_not_move))
if spawnpoint.pos then
str = str.."\n"..minetest.pos_to_string(spawnpoint.pos)
if spawnpoint.pos then
storage:set_string("pos", minetest.pos_to_string(spawnpoint.pos))
end
minetest.log("Saved via modstorage")
return true
elseif data then
data:set("time", tostring(spawnpoint.time))
data:set_bool("do_not_move", spawnpoint.do_not_move)
if spawnpoint.pos then
data:set("pos", minetest.pos_to_string(spawnpoint.pos))
end
data:write()
minetest.log("Saved via settings")
return true
end
io.open(path, "w"):write(str)
end
-- [function] Set
@ -76,6 +150,7 @@ function spawnpoint.set(pos)
if type(pos) == "table" then
spawnpoint.pos = pos
spawnpoint.save()
end
end
@ -242,21 +317,22 @@ minetest.register_chatcommand("spawnpoint", {
local num = tonumber(p[2])
if not num then
return true, "SpawnPoint->time: "..spawnpoint.time
return true, "SpawnPoint->time: "..dump(spawnpoint.time)
elseif num == spawnpoint.time then
return false, "Time already set to "..p[2].."!"
else
spawnpoint.time = num
return true, "Set time to "..tostring(num)
spawnpoint.save()
return true, "Set time to "..dump(num)
end
elseif p[1] == "do_not_move" then
local move = minetest.is_yes(p[2])
minetest.log("action", dump(p[2])..", "..dump(move))
if move == nil then
return true, "SpawnPoint->do_not_move: "..tostring(spawnpoint.do_not_move)
return true, "SpawnPoint->do_not_move: "..dump(spawnpoint.do_not_move)
else
spawnpoint.do_not_move = move
return true, "Set do_not_move to "..tostring(move)
spawnpoint.save()
return true, "Set do_not_move to "..dump(move)
end
end
end