generated from your-land/yl_template
Implements skin_import into a running server
This commit is contained in:
parent
c820215341
commit
654e63cbc5
@ -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"
|
||||
}
|
||||
|
@ -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)
|
18
chatcommand_import_skins.lua
Normal file
18
chatcommand_import_skins.lua
Normal 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)
|
@ -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")
|
||||
|
15
config.lua
15
config.lua
@ -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"
|
||||
|
@ -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"
|
||||
|
5
init.lua
5
init.lua
@ -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]")
|
||||
|
@ -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()
|
||||
|
186
internal.lua
186
internal.lua
@ -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
|
||||
|
4
mod.conf
4
mod.conf
@ -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
11
overwrite.lua
Normal 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
|
@ -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>"
|
||||
|
Loading…
Reference in New Issue
Block a user