Support custom props, custom media
The config stuff is in place, just doesn't have an interface yet.
This commit is contained in:
parent
8777428dd1
commit
1adb4e5e27
18
README.md
18
README.md
@ -14,6 +14,8 @@ You will get a folder in your worldpath containing a skeletal mod:
|
||||
|
||||
- All media files referenced by the items, split into textures/sounds/models.
|
||||
- An `exported.lua` file with each definition.
|
||||
- A `mediasource.json` file that identifies the mod source of each media file included, for help tracing licensing and attribution.
|
||||
- A `defripper.json` file that stores the configuration, and can be used to "rehydrate" the configuation in another world with the same mods installed, making it possible to incrementally extend the extracted data without needing to keep the entire original world around.
|
||||
|
||||
You will need to provide your own `init.lua`, `mod.conf` and other infrastructure, but the exported definitions are kept in a separate file so you can safely overwrite it later (e.g. if you add definitions) without destroying your custom logic.
|
||||
|
||||
@ -58,4 +60,18 @@ Minetest "items" includes all nodes, craftitems and tools. The definition rippe
|
||||
|
||||
- For each of these commands, if the `defripper_node_inv` setting is `true` (default `false`), it will descend into node meta inventories and rip items found there as well.
|
||||
- `/defripper_here [rx [ry [rz]]]` - rip all nodes/items within a cuboid/rectanguloid centered around the player, right now.
|
||||
- `/defripper_step [rx [ry [rz [step]]]]` - rip all nodes/items within a cuboid/rectanguloid centered around the player, continuously, every time the player moves `step` nodes, until the server is restarted or command is re-run to change it. `/defripper_step 0` disables it.
|
||||
- `/defripper_step [rx [ry [rz [step]]]]` - rip all nodes/items within a cuboid/rectanguloid centered around the player, continuously, every time the player moves `step` nodes, until the server is restarted or command is re-run to change it. `/defripper_step 0` disables it.
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Recreating World for Updates
|
||||
|
||||
It is not necessary to keep the original world you used defripper on to update your definitions, so long as you can recreate that world with the same mods.
|
||||
|
||||
- The defripper export contains its config, and you can copy it all back into the corresponding dir in the recreated world to restore state.
|
||||
- defripper will warn you if there are any mods you're missing when trying to re-export. Finding the correct version, when forks exist, is still your responsibility, so you may want to keep note of which versions things were based on.
|
||||
- Media files are NOT updated by default if they already exist in the dump, so you can use alternative or texturepack versions if you want. New ones are still added, and unused ones are still pruned. If you want to force an update, remove the affected media from the export.
|
||||
|
||||
### Custom Property Filtering
|
||||
|
||||
- TBD
|
4
TODO
4
TODO
@ -1,9 +1,5 @@
|
||||
------------------------------------------------------------------------
|
||||
|
||||
- Add some kind of warning when things are expected but missing, like
|
||||
exported items that aren't found, in case a player recreated the
|
||||
sampling world but forgot some mods.
|
||||
|
||||
- Commands to manage "extra media", for things that are related to a
|
||||
definition but actually directly linked, like door open/close sounds
|
||||
that may be wanted to use the door post-export. Using defripper's
|
||||
|
25
commands.lua
25
commands.lua
@ -1,8 +1,10 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local ipairs, minetest, next, pairs, pcall, string, tonumber, vector
|
||||
= ipairs, minetest, next, pairs, pcall, string, tonumber, vector
|
||||
local string_format, string_gsub, string_match
|
||||
= string.format, string.gsub, string.match
|
||||
local ipairs, minetest, next, pairs, pcall, string, table, tonumber,
|
||||
vector
|
||||
= ipairs, minetest, next, pairs, pcall, string, table, tonumber,
|
||||
vector
|
||||
local string_format, string_gsub, string_match, table_concat
|
||||
= string.format, string.gsub, string.match, table.concat
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local include = ...
|
||||
@ -13,8 +15,19 @@ local modname = minetest.get_current_modname()
|
||||
|
||||
local function save_export_report()
|
||||
savedb()
|
||||
local defs, media = exportall()
|
||||
return true, string_format("exported %d defs and %d media", defs, media)
|
||||
local result = exportall()
|
||||
local lines = {
|
||||
string_format("exported %d def(s) and %d media",
|
||||
result.exported_defs, result.exported_media)
|
||||
}
|
||||
for k, v in pairs(result.missing_defs) do
|
||||
lines[#lines + 1] = string_format("WARNING: %d def(s) missing from mod %q", v, k)
|
||||
end
|
||||
for k, v in pairs(result.missing_media) do
|
||||
lines[#lines + 1] = string_format("WARNING: %d medial file(s) missing from %q", v, k)
|
||||
end
|
||||
|
||||
return true, table_concat(lines, "\n")
|
||||
end
|
||||
|
||||
minetest.register_chatcommand(modname, {
|
||||
|
10
configdb.lua
10
configdb.lua
@ -49,7 +49,9 @@ end
|
||||
------------------------------------------------------------------------
|
||||
|
||||
local allkeys = {
|
||||
items = true
|
||||
items = {},
|
||||
media = {},
|
||||
props = false,
|
||||
}
|
||||
setmetatable(configdb, {
|
||||
__newindex = function(t, k, v)
|
||||
@ -59,9 +61,9 @@ setmetatable(configdb, {
|
||||
return rawset(t, k, v)
|
||||
end
|
||||
})
|
||||
for k in pairs(allkeys) do
|
||||
if not configdb[k] then
|
||||
configdb[k] = {}
|
||||
for k, v in pairs(allkeys) do
|
||||
if v and not configdb[k] then
|
||||
configdb[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,6 +45,11 @@ local nodekeys = {
|
||||
walkable = true,
|
||||
wield_image = true,
|
||||
}
|
||||
for k, v in pairs(nodekeys) do
|
||||
if v == true then
|
||||
nodekeys[k] = function(def) return rawget(def, k) end
|
||||
end
|
||||
end
|
||||
|
||||
local blocked = {
|
||||
air = true,
|
||||
@ -70,18 +75,26 @@ local function exportall()
|
||||
.. "\n\nlocal reg = ...\n\n")
|
||||
|
||||
local filtered = {}
|
||||
for k, v in pairs(minetest.registered_items) do
|
||||
if not blocked[k] and configdb.items[k] then
|
||||
local t = {}
|
||||
for k2, v2 in pairs(nodekeys) do
|
||||
if type(v2) == "function" then
|
||||
t[k2] = deepcopy(v2(v))
|
||||
else
|
||||
t[k2] = deepcopy(rawget(v, k2))
|
||||
do
|
||||
local props = configdb.props or nodekeys
|
||||
for k, v in pairs(minetest.registered_items) do
|
||||
if not blocked[k] and configdb.items[k] then
|
||||
local t = {}
|
||||
for k2, v2 in pairs(nodekeys) do
|
||||
if props[k2] then
|
||||
t[k2] = deepcopy(v2(v))
|
||||
end
|
||||
end
|
||||
t._raw_name = k
|
||||
filtered[k] = t
|
||||
end
|
||||
t._raw_name = k
|
||||
filtered[k] = t
|
||||
end
|
||||
end
|
||||
local missing_defs = {}
|
||||
for k in pairs(configdb.items) do
|
||||
if not (blocked[k] or filtered[k]) then
|
||||
local mod = string_gsub(k, ":.*", "")
|
||||
missing_defs[mod] = (missing_defs[mod] or 0) + 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -162,6 +175,13 @@ local function exportall()
|
||||
end
|
||||
end
|
||||
|
||||
local missing_media = {}
|
||||
for k, v in pairs(configdb.media) do
|
||||
if not ripmedia(mymedia, k, outdir, v) then
|
||||
missing_media[v] = (missing_media[v] or 0) + 1
|
||||
end
|
||||
end
|
||||
|
||||
local mediaqty = 0
|
||||
if next(mymedia) then
|
||||
local _, first = next(mymedia)
|
||||
@ -189,7 +209,12 @@ local function exportall()
|
||||
attrf:close()
|
||||
end
|
||||
|
||||
return count, mediaqty
|
||||
return {
|
||||
exported_defs = count,
|
||||
exported_media = mediaqty,
|
||||
missing_defs = missing_defs,
|
||||
missing_media = missing_media
|
||||
}
|
||||
end
|
||||
|
||||
return exportall
|
||||
|
@ -36,6 +36,7 @@ end
|
||||
|
||||
local function ripmedia(reffed, thing, dest, rel, test)
|
||||
test = test or function(a, b) return a == b end
|
||||
local foundany
|
||||
if type(thing) == "string" then
|
||||
for _, s in ipairs(string_gsub(thing, "[\\[:,=&{()]", "^"):split("^")) do
|
||||
for k, v in pairs(mediacache) do
|
||||
@ -43,15 +44,18 @@ local function ripmedia(reffed, thing, dest, rel, test)
|
||||
local fulldest = getdir(dest .. "/" .. rel) .. "/" .. k
|
||||
cpfile(v, fulldest)
|
||||
reffed[fulldest] = v
|
||||
foundany = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
elseif type(thing) == "table" then
|
||||
if thing.name then return ripmedia(reffed, thing.name, dest, rel, test) end
|
||||
for _, v in pairs(thing) do
|
||||
ripmedia(reffed, v, dest, rel, test)
|
||||
foundany = ripmedia(reffed, v, dest, rel, test) or foundany
|
||||
end
|
||||
end
|
||||
return foundany
|
||||
end
|
||||
|
||||
return getdir, ripmedia
|
||||
|
8
init.lua
8
init.lua
@ -1,6 +1,6 @@
|
||||
-- LUALOCALS < ---------------------------------------------------------
|
||||
local loadfile, minetest, unpack
|
||||
= loadfile, minetest, unpack
|
||||
local error, loadfile, minetest, unpack
|
||||
= error, loadfile, minetest, unpack
|
||||
-- LUALOCALS > ---------------------------------------------------------
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
@ -12,7 +12,9 @@ do
|
||||
include = function(n)
|
||||
local found = included[n]
|
||||
if found ~= nil then return unpack(found) end
|
||||
found = {loadfile(modpath .. "/" .. n .. ".lua")(include)}
|
||||
local func, err = loadfile(modpath .. "/" .. n .. ".lua")
|
||||
if not func then error(err) end
|
||||
found = {func(include)}
|
||||
included[n] = found
|
||||
return unpack(found)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user