Implements skin_import into a running server

This commit is contained in:
AliasAlreadyTaken 2024-07-23 21:25:48 +02:00
parent c820215341
commit 654e63cbc5
12 changed files with 152 additions and 168 deletions

View File

@ -3,7 +3,10 @@ allow_defined_top = true
globals = {
"minetest",
"core"
"core",
-- We need to overwrite a function of the skins namespace
"skins"
}
read_globals = {
@ -15,6 +18,5 @@ read_globals = {
"dump", "DIR_DELIM", "VoxelArea", "Settings",
-- MTG
"default", "sfinv", "creative",
"skins"
"default", "sfinv", "creative"
}

View File

@ -1,19 +0,0 @@
local chatcommand_cmd = "admin_example"
local chatcommand_definition = {
params = yl_skinsdb_addon.t("chatcommand_admin_parameters"), -- Short parameter description
description = yl_skinsdb_addon.t("chatcommand_admin_description"), -- Full description
privs = {[yl_skinsdb_addon.settings.admin_priv] = true}, -- Require the "privs" privilege to run
func = function(name, param)
local success = true
if success then
return true, yl_skinsdb_addon.t("chatcommand_admin_success_message")
else
return false, yl_skinsdb_addon.t("chatcommand_admin_fail_message")
end
end
-- Called when command is run. Returns boolean success and text output.
-- Special case: The help message is shown to the player if `func`
-- returns false without a text output.
}
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)

View File

@ -0,0 +1,18 @@
local chatcommand_cmd = "import_skins"
local chatcommand_definition = {
params = yl_skinsdb_addon.t("chatcommand_import_skins_parameters"),
description = yl_skinsdb_addon.t("chatcommand_import_skins_description"),
privs = {[yl_skinsdb_addon.settings.admin_priv] = true},
func = function(name, param)
local success, message = yl_skinsdb_addon.load_skins(
yl_skinsdb_addon.settings.path_textures,
yl_skinsdb_addon.callback_dam)
if success then
return true, message
else
return false, message
end
end
}
minetest.register_chatcommand(chatcommand_cmd, chatcommand_definition)

View File

@ -1,2 +1 @@
dofile(yl_skinsdb_addon.modpath .. "chatcommand_admin.lua")
dofile(yl_skinsdb_addon.modpath .. "chatcommand_player.lua")
dofile(yl_skinsdb_addon.modpath .. "chatcommand_import_skins.lua")

View File

@ -1,14 +1,11 @@
-- Setting a configuration, switch the order in which the settings shall take precedence. First valid one taken.
yl_skinsdb_addon.settings = {}
yl_skinsdb_addon.settings.path_textures = minetest.settings:get(
"yl_skinsdb_addon.save_path") or
"worldmods/yl_skins_folder/textures"
yl_skinsdb_addon.settings.debug = true
yl_skinsdb_addon.settings.path_meta = minetest.settings:get(
"yl_skinsdb_addon.save_path") or
"worldmods/yl_skins_folder/meta"
yl_skinsdb_addon.settings.path_textures =
minetest.settings:get("yl_skinsdb_addon.save_path") or "yl_skins/textures"
yl_skinsdb_addon.settings.admin_privs = minetest.settings:get(
"yl_skinsdb_addon.admin_privs") or
"server"
yl_skinsdb_addon.settings.admin_priv = minetest.settings:get(
"yl_skinsdb_addon.admin_privs") or
"server"

View File

@ -1,11 +1,45 @@
This is a skinsDB addon, in a stub, to not infect the rest of our code with GPL.
The only functionality this mod is intended to add is a way to retrofit skins into a running server.
This mod allows to add skins from a folder that is not the textures folder of skinsDB: done
THis mod also allows to retrofit skins into a running server
We need
- a process to clone, push to and update this mod on the server
- a second mod that holds all the textures
- a folder in the world folder that holds all the textures. By default yl_skins
- a chatcommand that reads the files of a directory, compares them to a list we have ingame and then adds new skins to a table, which is then processed by
- a function that actually imports those skins and makes them available to players
- The same function can be used at serverstart to transmit the skins and make them available
###
2024-07-20 08:31:07: ERROR[Main]: ServerError: AsyncErr: Lua: Runtime error from mod 'yl_skinsdb_addon' in callback on_chat_message(): ...5.9.0/minetest-dev/bin/../mods/skinsdb/skin_meta_api.lua:62: attempt to concatenate a nil value
2024-07-20 08:31:07: ERROR[Main]: stack traceback:
2024-07-20 08:31:07: ERROR[Main]: ...5.9.0/minetest-dev/bin/../mods/skinsdb/skin_meta_api.lua:62: in function 'set_hand_from_texture'
2024-07-20 08:31:07: ERROR[Main]: ...test/5.9.0/minetest-dev/bin/../mods/skinsdb/skinlist.lua:83: in function 'register_skin'
2024-07-20 08:31:07: ERROR[Main]: ...lds/Minetest_dev/worldmods/yl_skinsdb_addon/internal.lua:35: in function 'load_skins'
2024-07-20 08:31:07: ERROR[Main]: .../worldmods/yl_skinsdb_addon/chatcommand_import_skins.lua:8: in function 'func'
2024-07-20 08:31:07: ERROR[Main]: ...minetest-dev/bin/../builtin/profiler/instrumentation.lua:124: in function 'func'
2024-07-20 08:31:07: ERROR[Main]: ...minetest/5.9.0/minetest-dev/bin/../builtin/game/chat.lua:79: in function <...minetest/5.9.0/minetest-dev/bin/../builtin/game/chat.lua:52>
2024-07-20 08:31:07: ERROR[Main]: ...st/5.9.0/minetest-dev/bin/../builtin/common/register.lua:26: in function <...st/5.9.0/minetest-dev/bin/../builtin/common/register.lua:12>
###
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="player.LeetPeet.0.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="playerLeetPeet0png"
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="character.warrior_m2.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="characterwarriorm2png"
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="player.AstronomiCow.0.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="playerAstronomiCow0png"
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="player.Dragoni_is_bored.0.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="playerDragoniisbored0png"
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="player.ElishQa.0.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="playerElishQa0png"
2024-07-20 09:05:52: ACTION[Main]: core.get_current_modname()="skinsdb"
2024-07-20 09:05:52: ACTION[Main]: self._texture="player.Athena.0.png"
2024-07-20 09:05:52: ACTION[Main]: self._texture:gsub('[%p%c%s]', '')="playerAthena0png"

View File

@ -18,11 +18,10 @@ dofile(yl_skinsdb_addon.modpath .. "texts.lua")
dofile(yl_skinsdb_addon.modpath .. "information.lua")
dofile(yl_skinsdb_addon.modpath .. "config.lua")
--dofile(yl_skinsdb_addon.modpath .. "setup.lua")
--dofile(yl_skinsdb_addon.modpath .. "privs.lua")
dofile(yl_skinsdb_addon.modpath .. "overwrite.lua")
dofile(yl_skinsdb_addon.modpath .. "internal.lua")
--dofile(yl_skinsdb_addon.modpath .. "api.lua")
dofile(yl_skinsdb_addon.modpath .. "initialize.lua")
--dofile(yl_skinsdb_addon.modpath .. "chatcommands.lua")
dofile(yl_skinsdb_addon.modpath .. "chatcommands.lua")
local mod_end_time = (minetest.get_us_time() - mod_start_time) / 1000000
minetest.log("action", "[MOD] yl_skinsdb_addon loaded in [" .. mod_end_time .. "s]")

View File

@ -1,8 +1,7 @@
-- Use this file to initialize variables once after server start and check everything is in place
local function run_each_serverstart()
yl_skinsdb_addon.data = {}
yl_skinsdb_addon.load_skins(yl_skinsdb_addon.settings.path_textures,
yl_skinsdb_addon.settings.path_meta)
yl_skinsdb_addon.load_skins(yl_skinsdb_addon.settings.path_textures)
end
run_each_serverstart()

View File

@ -1,137 +1,81 @@
-- The functions and variables in this file are only for use in the mod itself.
-- Those that do real work should be local and wrapped in public functions
local function log(text)
local logmessage = yl_skinsdb_addon.t("log_prefix", yl_skinsdb_addon.modname, text)
if yl_skinsdb_addon.settings.debug then minetest.log("action", logmessage) end
local logmessage = yl_skinsdb_addon.t("log_prefix",
yl_skinsdb_addon.modname, text)
if yl_skinsdb_addon.settings.debug then
minetest.log("action", logmessage)
end
return logmessage
end
function yl_skinsdb_addon.log(text) return log(text) end
--[[
local function load_skins(path_textures, callback_dam)
-- Load skins from the current mod directory
local path_skins = yl_skinsdb_addon.worldpath .. path_textures
local dir_list = minetest.get_dir_list(path_skins)
local imported_skins_list = {}
local success
local good, bad, total = 0, 0, 0
local function get_savepath()
local savepath = yl_skinsdb_addon.worldpath .. yl_skinsdb_addon.settings.save_path
log(yl_skinsdb_addon.t("log_prefix", dump(savepath)))
return savepath
end
local function get_filepath(filename)
local path_to_file = get_savepath() .. DIR_DELIM .. filename .. ".json"
log(yl_skinsdb_addon.t("get_filepath", dump(filename), dump(path_to_file)))
return path_to_file
end
local function save_json(filename, content)
if type(filename) ~= "string" or type(content) ~= "table" then
return false
end
local savepath = get_filepath(filename)
local savecontent = minetest.write_json(content)
return minetest.safe_file_write(savepath, savecontent)
end
local function load_json(path)
local file = io.open(path, "r")
if not file then
return false, yl_skinsdb_addon.t("error_cannot_open_file", dump(path))
if (not next(dir_list)) then
log("Skins not found in " .. dump(path_skins))
return false, "Skins not found in " .. dump(path_skins)
end
local content = file:read("*all")
file:close()
if not content then
return false, yl_skinsdb_addon.t("error_cannot_read_file", dump(path))
end
return true, minetest.parse_json(content)
end
-- Public functions wrap the private ones, so they can be exchanged easily
function yl_skinsdb_addon.load(filename, ...) return load_json(filename, ...) end
function yl_skinsdb_addon.save(filename, content, ...)
return save_json(filename, content, ...)
end
]] --
-- Load skins
--
function yl_skinsdb_addon.load_skins(textures, meta)
local path_textures = yl_skinsdb_addon.worldpath .. textures
local path_meta = yl_skinsdb_addon.worldpath .. meta
local skins_dir_list = minetest.get_dir_list(path_textures)
for _, fn in pairs(skins_dir_list) do
local name, sort_id, is_preview, playername
local nameparts = string.gsub(fn, "[.]", skins.fsep):split(skins.fsep)
-- check allowed prefix and file extension
if (nameparts[1] == 'player' or nameparts[1] == 'character') and
nameparts[#nameparts]:lower() == 'png' then
-- cut filename extension
table.remove(nameparts, #nameparts)
-- check preview suffix
if nameparts[#nameparts] == 'preview' then
is_preview = true
table.remove(nameparts, #nameparts)
end
-- Build technically skin name
name = table.concat(nameparts, '_')
-- Handle metadata from file name
if not is_preview then
-- Get player name
if nameparts[1] == "player" then
playername = nameparts[2]
table.remove(nameparts, 1)
sort_id = 0
else
sort_id = 5000
end
-- Get sort index
if tonumber(nameparts[#nameparts]) then
sort_id = sort_id + nameparts[#nameparts]
end
end
local skin_obj = skins.get(name) or skins.new(name)
if is_preview then
skin_obj:set_preview(fn)
for _, filename in pairs(dir_list) do
if (yl_skinsdb_addon.data[filename] == nil) then
local dam_options = {filepath = path_skins .. DIR_DELIM .. filename}
yl_skinsdb_addon.data[filename] = true
local success_dam = minetest.dynamic_add_media(dam_options,
callback_dam)
-- TODO: Either move everything below to the callback OR
-- evne worse, only go on after each file was delivered to each player
-- That means having a file of players and marking each as "received"
-- only after the last player got the file, make the skin happen
local success_rs, message_rs =
skins.register_skin(path_skins, filename)
if success_rs == true then
imported_skins_list[filename] = "import"
log("Added skin " .. dump(filename))
good = good + 1
else
skin_obj:set_texture(fn)
skin_obj:set_meta("_sort_id", sort_id)
if playername then
skin_obj:set_meta("assignment", "player:" .. playername)
skin_obj:set_meta("playername", playername)
end
local file = io.open(path_textures .. DIR_DELIM .. fn, "r")
local skin_format = skins.get_skin_format(file)
skin_obj:set_meta("format", skin_format)
file:close()
skin_obj:set_hand_from_texture()
file = io.open(path_meta .. DIR_DELIM .. name .. ".txt", "r")
if file then
local data = string.split(file:read("*all"), "\n", 3)
file:close()
skin_obj:set_meta("name", data[1])
skin_obj:set_meta("author", data[2])
skin_obj:set_meta("license", data[3])
else
-- remove player / character prefix if further naming given
if nameparts[2] and not tonumber(nameparts[2]) then
table.remove(nameparts, 1)
end
skin_obj:set_meta("name", table.concat(nameparts, ' '))
end
imported_skins_list[filename] = "noimport"
log("Cannot add skin " .. dump(filename) .. " Reason: " ..
dump(message_rs))
bad = bad + 1
end
else
imported_skins_list[filename] = "exists"
log("Cannot add skin " .. dump(filename) .. " already exists.")
bad = bad + 1
end
total = total + 1
end
local return_message = "Total: " .. tostring(total) .. ", good: " ..
tostring(good) .. ", bad: " .. tostring(bad) ..
"\n"
for k, state in pairs(imported_skins_list) do
if (state == "import") then
return_message = return_message .. "Import success: " .. k .. "\n"
elseif (state == "noimport") then
return_message = return_message .. "Import failed: " .. k .. "\n"
end
end
if (good > 0) then
success = true
else
success = false
end
return success, return_message
end
function yl_skinsdb_addon.load_skins(path_textures, callback)
return load_skins(path_textures, callback)
end
function yl_skinsdb_addon.callback_dam(name) log("Adds skin for " .. dump(name)) end

View File

@ -1,5 +1,5 @@
name = yl_skinsdb_addon
description = An addon to skinsdb to retrofit skins
depends = skinsdb, yl_skins_folder
depends = skinsdb
author = AliasAlreadyTaken
title = YL Skins Addon
title = YL SkinsDB Addon

11
overwrite.lua Normal file
View File

@ -0,0 +1,11 @@
local skins = skins.skin_class
local old_skins_skin_class_set_hand_from_texture = skins.set_hand_from_texture
function skins:set_hand_from_texture()
if (core.get_current_modname() ~= nil) then
return old_skins_skin_class_set_hand_from_texture(self)
end
-- local hand = core.get_current_modname()..':'..self._texture:gsub('[%p%c%s]', '')
-- local hand = "skinsdb:playerLeetPeet0png"
-- self:set_hand(hand)
end

View File

@ -15,10 +15,10 @@ texts["get_filepath"] = "get_filepath : @1"
texts["information_additional"] = "An addon to skinsdb to retrofit skins"
texts["chatcommand_admin_description"] = "Admin Chatcommand description"
texts["chatcommand_admin_parameters"] = "<name> <privilege>"
texts["chatcommand_admin_success_message"] = "Sucess message"
texts["chatcommand_admin_fail_message"] = "Fail message"
texts["chatcommand_import_skins_parameters"] = "Admin Chatcommand description"
texts["chatcommand_import_skins_description"] = "<name> <privilege>"
texts["chatcommand_import_skins_success_message"] = "Sucess message"
texts["chatcommand_import_skins_fail_message"] = "Fail message"
texts["chatcommand_player_description"] = "Player Chatcommand description"
texts["chatcommand_player_parameters"] = "<name> <privilege>"