38 Commits

Author SHA1 Message Date
8d5870c54c Merge branch 'master' into contentdb 2025-04-16 19:36:38 +02:00
bc69b03d0b Update hand overrides to v5.12.0-dev changes
Luanti commit e037873 changed how the tool range and caps are taken into account.
Hence, skin hands now overwrite the long-range hand (`""`) provided by the creative mod.
We want to preserve the tool range and capabilities, thus this commit.
2025-04-11 17:20:05 +02:00
247bcdd058 Fix client-side out-of-bounds '[combine' warnings 2025-03-16 18:49:54 +01:00
a0ed992121 Update player_api model registration
Ensures correct eye position and collision box.
Values taken from the player_api 'character.b3d' model.
2025-03-16 18:38:45 +01:00
bde2f1e3f2 Merge branch 'master' into contentdb 2024-09-28 11:15:10 +02:00
3cf80c9272 skinlist: Allow textures containing '-' characters
Fixes issue #110
Thanks to Bastrabun for the code suggestion
2024-09-28 11:12:31 +02:00
df62f2042d skinlist: avoid 'Too many open files' errors
Due to application-specific file descriptor limits,
the garbage collector cannot close the descriptors in time,
resulting in unexpected file open errors.
2024-07-22 18:41:15 +02:00
b7cd514cea API: make skins.register_skin public (#106) 2024-07-07 18:51:48 +02:00
11bb5bad0e Add migration code to player skins using '.' delimiters (#105)
Previously, the players would have their selected skin reset after renaming
the skin textures to the dot separator. This commit implements skin name
migration to ease the transition for server owners.

See 'skins.__fuzzy_match_skin_name' for a detailed explanation.
2024-06-15 15:16:52 +02:00
59f0dcaf3f Merge branch 'master' into contentdb 2024-01-06 12:33:21 +01:00
c6f9a26970 Explain what this branch is 2023-04-02 20:44:19 +02:00
353f36d551 Merge branch 'master' into contentdb 2023-04-02 20:42:50 +02:00
d4b398eae2 Merge remote-tracking branch 'origin/master' into contentdb 2023-01-16 07:47:27 +01:00
ea7aacc9e7 update filenames of default textures to reflect metadata
Signed-off-by: Nissa <and-nissa@protonmail.com>
2022-12-31 09:21:40 +01:00
743e2cfc9c rename male default textures in consistency with female textures
Signed-off-by: Nissa <and-nissa@protonmail.com>
2022-12-31 09:21:40 +01:00
abc3df86e3 Merge remote-tracking branch 'origin/master' into HEAD 2022-12-30 11:19:46 +01:00
41524201d1 Merge remote-tracking branch 'origin/master' into contentdb 2022-03-31 08:18:52 +02:00
41be19fc7a Merge remote-tracking branch 'origin/master' into contentdb 2022-03-06 11:56:53 +01:00
ad189102d5 fix Undeclared global variable "unified_inventory" accessed 2022-03-05 12:53:55 +01:00
e0765da839 adjustments from code review 2022-03-05 12:44:48 +01:00
482a13b495 implement skinned 1st person view hand 2022-02-16 10:24:03 +01:00
56353133e1 Added russian (ru) translation 2022-02-03 07:38:25 +01:00
443cda2183 Added ukrainian (uk) translation 2022-02-03 07:38:25 +01:00
fab418b56f Log player skin changes (#64) 2022-02-03 07:38:25 +01:00
00f6a8137e Merge branch 'master' into contentdb 2022-01-04 11:42:00 +01:00
9b8fb79030 update_skins.py
Remove leading zeros again
2020-09-10 14:29:07 +02:00
02323fc427 updater/update_skins.py: Do not download preview files by default 2020-09-10 14:29:07 +02:00
3aebed6fed api.lua: Fix deprecation warnings 2020-09-10 14:29:07 +02:00
63555ed0be Add python skin update script (#48) 2020-09-10 14:29:07 +02:00
7b59880736 fix chrash when using /skinsdb set without parameter or /skinsdb list public 2020-09-10 14:29:07 +02:00
8e1e525340 Fix corrupted data in Windows systems (#47)
The base64 data from the decoder to the file writer is in binary, using only the "w" flag would work in most unix systems but its incorrect and for all systems with crazy line_feed/Carrier_return or any character conversion the right way to save a binary data is using the "wb" flag.
2020-09-10 14:29:07 +02:00
af8212a1bd Merge branch 'master' into contentdb 2020-02-12 08:10:09 +01:00
361d0222ca remove _preview.png files 2020-02-10 07:13:49 +01:00
436809f8fa Merge branch 'master' into contentdb 2020-02-10 07:12:23 +01:00
04b43a5969 Merge branch 'master' into contentdb 2020-01-14 14:58:47 +01:00
dcca582ef3 Merge branch 'master' into contentdb 2020-01-08 08:13:16 +01:00
f1d0f0789d add skins credit to README.md 2019-08-09 07:00:02 +02:00
5c13010014 add sirrobzeroone skins for contentdb 2019-08-09 06:57:34 +02:00
25 changed files with 126 additions and 34 deletions

4
.gitignore vendored
View File

@ -1,4 +1,4 @@
textures/character_*.png #textures/character_*.png
textures/player_*.png textures/player_*.png
meta/character_*.txt #meta/character_*.txt
meta/player_*.txt meta/player_*.txt

25
API.md
View File

@ -27,6 +27,31 @@ Get all allowed skins for player. All public and all player's private skins. If
Get all skins with metadata key is set to value. Example: Get all skins with metadata key is set to value. Example:
skins.get_skinlist_with_meta("playername", playername) - Get all private skins (w.o. public) for playername skins.get_skinlist_with_meta("playername", playername) - Get all private skins (w.o. public) for playername
## skins.register_skin(path, filename)
Registers a new skin based on the texture file path specified by `path` and `filename`.
* `path` (string): points to the parent directory of the texture `filename`.
Generally, this should be in the format `mymod.modpath .. "/textures"`.
* `filename` (string): full file name, without any path specifications.
The file name must adhere to [one of the accepted naming formats](textures/readme.txt).
Note: this function takes the following files into consideration:
1. `<path>/<filename>` (required)
* Main skin texture
2. `<path>/<filenamestem><separator>preview.png` (optional)
* Pre-generated preview image
3. `<path>/../meta/<filenamestem>.txt` (optional)
* Metadata regarding the skin
Return values:
* On failure: `false, reason`
* `reason` (string): human readable reason string (similar to `io.open` errors)
* On success: `true, key`
* `key`: unique skins key for use with e.g. `skins.get(key)` for subsequent
fine-tuning of the skin registration.
## skins.new(key, object) ## skins.new(key, object)
Create and register a new skin object for given key Create and register a new skin object for given key

View File

@ -1,4 +1,4 @@
# skinsdb # skinsdb - User-facing branch that includes a few basic skins
This Minetest mod offers changeable player skins with a graphical interface for multiple inventory mods. This Minetest mod offers changeable player skins with a graphical interface for multiple inventory mods.
@ -38,9 +38,9 @@ You might want to run `minetest` in a Terminal/Console window to check the log o
**Requirements:** **Requirements:**
* Python 3 * Python 3
* `requests` library: `pip3 install requests` * `requests` library: `pip3 install requests`
Go to the updater folder of this mod and run `python3 update_skins.py` Go to the updater folder of this mod and run `python3 update_skins.py`
The Script will download all the skins from the database for you. The Script will download all the skins from the database for you.
### Manual addition ### Manual addition
@ -66,3 +66,4 @@ The Script will download all the skins from the database for you.
- bell07 (source code) - bell07 (source code)
- stujones11 (player models) - stujones11 (player models)
- jordan4ibanez (1st person view hand) - jordan4ibanez (1st person view hand)
- sirrobzeroone (skins)

View File

@ -72,6 +72,7 @@ minetest.register_on_shutdown(function()
end end
end) end)
-- See also: 3d_armor/init.lua
player_api.register_model("skinsdb_3d_armor_character_5.b3d", { player_api.register_model("skinsdb_3d_armor_character_5.b3d", {
animation_speed = 30, animation_speed = 30,
textures = { textures = {
@ -82,16 +83,21 @@ player_api.register_model("skinsdb_3d_armor_character_5.b3d", {
}, },
animations = { animations = {
stand = {x=0, y=79}, stand = {x=0, y=79},
lay = {x=162, y=166}, lay = {x=162, y=166, eye_height = 0.3, override_local = true,
collisionbox = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6}},
walk = {x=168, y=187}, walk = {x=168, y=187},
mine = {x=189, y=198}, mine = {x=189, y=198},
walk_mine = {x=200, y=219}, walk_mine = {x=200, y=219},
sit = {x=81, y=160}, sit = {x=81, y=160, eye_height = 0.8, override_local = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}},
-- compatibility w/ the emote mod -- compatibility w/ the emote mod
wave = {x = 192, y = 196, override_local = true}, wave = {x = 192, y = 196, override_local = true},
point = {x = 196, y = 196, override_local = true}, point = {x = 196, y = 196, override_local = true},
freeze = {x = 205, y = 205, override_local = true}, freeze = {x = 205, y = 205, override_local = true},
}, },
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
-- stepheight: use default
eye_height = 1.47,
}) })
-- Register default character.png if not part of this mod -- Register default character.png if not part of this mod

View File

@ -0,0 +1,3 @@
Castaway female
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Castaway male
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Farmer female
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Farmer male
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Prince
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Princess
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Rogue female
sirrobzeroone
CC0/Public Domain

View File

@ -0,0 +1,3 @@
Rogue male
sirrobzeroone
CC0/Public Domain

View File

@ -1,5 +1,5 @@
name = skinsdb name = skinsdb
description = Player skin mod, supporting unified_inventory, sfinv and smart_inventory description = Player skin mod, supporting unified_inventory, sfinv and smart_inventory
depends = player_api depends = player_api
optional_depends = unified_inventory,3d_armor,clothing,sfinv,hand_monoid optional_depends = unified_inventory, 3d_armor, clothing, creative, sfinv, hand_monoid
min_minetest_version = 5.4.0 min_minetest_version = 5.4.0

View File

@ -49,23 +49,25 @@ function skin_class:set_texture(value)
self._texture = value self._texture = value
end end
--- Retrieves the character texture
function skin_class:get_texture() function skin_class:get_texture()
return self._texture return self._texture
end end
--- Assigns an existing hand item (/node) name to this skin
function skin_class:set_hand(hand) function skin_class:set_hand(hand)
self._hand = hand self._hand = hand
end end
function skin_class:get_hand()
return self._hand
end
--- Registers a new hand item based on the skin meta
local ALPHA_CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true local ALPHA_CLIP = minetest.features.use_texture_alpha_string_modes and "clip" or true
function skin_class:set_hand_from_texture() function skin_class:set_hand_from_texture()
local hand = core.get_current_modname()..':'..self._texture:gsub('[%p%c%s]', '') local hand = core.get_current_modname()..':'..self._texture:gsub('[%p%c%s]', '')
local hand_def = {} local hand_def = {}
for k,v in pairs(minetest.registered_items[""]) do
if k ~= "mod_origin" and k ~= "type" and k ~= "wield_image" then
hand_def[k] = v
end
end
hand_def.tiles = {self:get_texture()} hand_def.tiles = {self:get_texture()}
hand_def.visual_scale = 1 hand_def.visual_scale = 1
hand_def.wield_scale = {x=1,y=1,z=1} hand_def.wield_scale = {x=1,y=1,z=1}
@ -77,13 +79,39 @@ function skin_class:set_hand_from_texture()
hand_def.mesh = "skinsdb_hand_18.b3d" hand_def.mesh = "skinsdb_hand_18.b3d"
end end
hand_def.use_texture_alpha = ALPHA_CLIP hand_def.use_texture_alpha = ALPHA_CLIP
minetest.register_node(hand, hand_def)
core.register_node(hand, table.copy(hand_def))
self._hand_def = hand_def -- for wieldhand overrides
self:set_hand(hand) self:set_hand(hand)
end end
function skin_class:get_hand() -- creative (and other mods?) may overwrite the wieldhand very late.
return self._hand -- Grab the most recent definition and use them as default for our skin hands.
end core.register_on_mods_loaded(function()
local default_hand_def = {}
for k, v in pairs(core.registered_items[""]) do
if k ~= "mod_origin"
and k ~= "name"
and k ~= "type"
and k ~= "wield_image"
and string.sub(k, 1, 1) ~= "_" then
default_hand_def[k] = v
end
end
for _, meta in pairs(skins.meta) do
local def = core.registered_nodes[meta._hand]
if def then
local new_def = table.copy(default_hand_def)
-- Overwrite the hand with our fields from `set_hand_from_texture`
for k, v in pairs(meta._hand_def) do
new_def[k] = v
end
core.override_item(meta._hand, new_def)
end
meta._hand_def = nil -- no longer needed, free up RAM
end
end)
function skin_class:set_preview(value) function skin_class:set_preview(value)
self._preview = value self._preview = value
@ -109,7 +137,7 @@ function skin_class:get_preview()
--Right Leg --Right Leg
skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
-- 64x skins have non-mirrored arms and legs -- 64x64 skins have non-mirrored arms and legs
local left_arm local left_arm
local left_leg local left_leg
@ -126,17 +154,21 @@ function skin_class:get_preview()
--Left Leg --Left Leg
skin = skin .. left_leg skin = skin .. left_leg
-- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out if self:get_meta("format") == "1.8" then
--Chest Overlay -- Add overlays for 64x64 skins. This check is needed to avoid
skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^" -- client-side out-of-bounds "[combine" warnings.
--Right Arm Overlay
skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^" --Chest Overlay
--Right Leg Overlay skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^"
skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" --Right Arm Overlay
--Left Arm Overlay skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^"
skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^" --Right Leg Overlay
--Left Leg Overlay skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^"
skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))" --Left Arm Overlay
skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^"
--Left Leg Overlay
skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))"
end
-- Full Preview -- Full Preview
skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)" skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)"

View File

@ -6,7 +6,7 @@ local dbgprint = false and print or function() end
function skins.register_skin(path, filename) function skins.register_skin(path, filename)
-- See "textures/readme.txt" for allowed formats -- See "textures/readme.txt" for allowed formats
local prefix, sep, identifier, extension = filename:match("^(%a+)([_.])([%w_.]+)%.(%a+)$") local prefix, sep, identifier, extension = filename:match("^(%a+)([_.])([%w_.-]+)%.(%a+)$")
--[[ --[[
prefix: "character" or "player" prefix: "character" or "player"
sep: "." (new) or "_" (legacy) sep: "." (new) or "_" (legacy)
@ -92,6 +92,7 @@ function skins.register_skin(path, filename)
skin_obj:set_meta("name", data[1]) skin_obj:set_meta("name", data[1])
skin_obj:set_meta("author", data[2]) skin_obj:set_meta("author", data[2])
skin_obj:set_meta("license", data[3]) skin_obj:set_meta("license", data[3])
file:close() -- do not rely on delayed GC
end end
end end
@ -102,6 +103,7 @@ function skins.register_skin(path, filename)
if fh then if fh then
dbgprint("Found preview", preview_name) dbgprint("Found preview", preview_name)
skin_obj:set_preview(preview_name) skin_obj:set_preview(preview_name)
fh:close() -- do not rely on delayed GC
end end
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -6,6 +6,7 @@ List of accepted texture names
Public skin available for all users: Public skin available for all users:
character.[number or name].png character.[number or name].png
^ The allowed characters in "[number or name]" are "[A-z0-9_.-]+".
One or multiple private skins for player "[nick]": One or multiple private skins for player "[nick]":
player.[nick].png player.[nick].png

View File

@ -9,12 +9,14 @@ local function run_unittest()
-- ----- -- -----
-- `.`: Simple register + retrieve operations -- `.`: Simple register + retrieve operations
skins.register_skin(PATH, "player.DotSep.png") assert(skins.register_skin(PATH, "player.DotSep.png"))
skins.register_skin(PATH, "player._DotSep_666_.1.png") assert(skins.register_skin(PATH, "player._DotSep_666_.1.png"))
assert(skins.register_skin(PATH, "character._DotSep_With-Dash-.png"))
assert(get_skin("player.DotSep")) assert(get_skin("player.DotSep"))
assert(get_skin("player._DotSep_666_.1")) assert(get_skin("player._DotSep_666_.1"))
assert(get_skin("player.DotSep.1") == nil) assert(get_skin("player.DotSep.1") == nil)
assert(get_skin("character._DotSep_With-Dash-"))
-- ----- -- -----
-- Ambiguous skin names (filenames without extension). Register + retrieve -- Ambiguous skin names (filenames without extension). Register + retrieve
@ -42,7 +44,6 @@ local function run_unittest()
assert(get_skin("player_Com_Pat_42") == "player._Com_Pat_42") assert(get_skin("player_Com_Pat_42") == "player._Com_Pat_42")
assert(get_skin("player_Com_Pat_42_1") == "player._Com_Pat_42.1") assert(get_skin("player_Com_Pat_42_1") == "player._Com_Pat_42.1")
error("Unittest passed! Please disable them now.") error("Unittest passed! Please disable them now.")
end end