Player skin mod, supporting unified_inventory, sfinv and smart_inventory https://content.minetest.net/packages/bell07/skinsdb/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
3.6 KiB

  1. local skins_dir_list = minetest.get_dir_list(skins.modpath.."/textures")
  2. for _, fn in pairs(skins_dir_list) do
  3. local name, sort_id, assignment, is_preview, playername
  4. local nameparts = string.gsub(fn, "[.]", "_"):split("_")
  5. -- check allowed prefix and file extension
  6. if (nameparts[1] == 'player' or nameparts[1] == 'character') and
  7. nameparts[#nameparts]:lower() == 'png' then
  8. -- cut filename extension
  9. table.remove(nameparts, #nameparts)
  10. -- check preview suffix
  11. if nameparts[#nameparts] == 'preview' then
  12. is_preview = true
  13. table.remove(nameparts, #nameparts)
  14. end
  15. -- Build technically skin name
  16. name = table.concat(nameparts, '_')
  17. -- Handle metadata from file name
  18. if not is_preview then
  19. -- Get player name
  20. if nameparts[1] == "player" then
  21. playername = nameparts[2]
  22. table.remove(nameparts, 1)
  23. sort_id = 0
  24. else
  25. sort_id = 5000
  26. end
  27. -- Get sort index
  28. if tonumber(nameparts[#nameparts]) then
  29. sort_id = sort_id + nameparts[#nameparts]
  30. end
  31. end
  32. local skin_obj = skins.get(name) or skins.new(name)
  33. if is_preview then
  34. skin_obj:set_preview(fn)
  35. else
  36. skin_obj:set_texture(fn)
  37. skin_obj:set_meta("_sort_id", sort_id)
  38. if playername then
  39. skin_obj:set_meta("assignment", "player:"..playername)
  40. skin_obj:set_meta("playername", playername)
  41. end
  42. local file = io.open(skins.modpath.."/textures/"..fn, "r")
  43. skin_obj:set_meta("format", skins.get_skin_format(file))
  44. file:close()
  45. file = io.open(skins.modpath.."/meta/"..name..".txt", "r")
  46. if file then
  47. local data = string.split(file:read("*all"), "\n", 3)
  48. file:close()
  49. skin_obj:set_meta("name", data[1])
  50. skin_obj:set_meta("author", data[2])
  51. skin_obj:set_meta("license", data[3])
  52. else
  53. -- remove player / character prefix if further naming given
  54. if nameparts[2] and not tonumber(nameparts[2]) then
  55. table.remove(nameparts, 1)
  56. end
  57. skin_obj:set_meta("name", table.concat(nameparts, ' '))
  58. end
  59. end
  60. end
  61. end
  62. local function skins_sort(skinslist)
  63. table.sort(skinslist, function(a,b)
  64. local a_id = a:get_meta("_sort_id") or 10000
  65. local b_id = b:get_meta("_sort_id") or 10000
  66. if a_id ~= b_id then
  67. return a:get_meta("_sort_id") < b:get_meta("_sort_id")
  68. else
  69. return a:get_meta("name") < b:get_meta("name")
  70. end
  71. end)
  72. end
  73. -- (obsolete) get skinlist. If assignment given ("mod:wardrobe" or "player:bell07") select skins matches the assignment. select_unassigned selects the skins without any assignment too
  74. function skins.get_skinlist(assignment, select_unassigned)
  75. minetest.log("deprecated", "skins.get_skinlist() is deprecated. Use skins.get_skinlist_for_player() instead")
  76. local skinslist = {}
  77. for _, skin in pairs(skins.meta) do
  78. if not assignment or
  79. assignment == skin:get_meta("assignment") or
  80. (select_unassigned and skin:get_meta("assignment") == nil) then
  81. table.insert(skinslist, skin)
  82. end
  83. end
  84. skins_sort(skinslist)
  85. return skinslist
  86. end
  87. -- Get skinlist for player. If no player given, public skins only selected
  88. function skins.get_skinlist_for_player(playername)
  89. local skinslist = {}
  90. for _, skin in pairs(skins.meta) do
  91. if skin:is_applicable_for_player(playername) and skin:get_meta("in_inventory_list") ~= false then
  92. table.insert(skinslist, skin)
  93. end
  94. end
  95. skins_sort(skinslist)
  96. return skinslist
  97. end
  98. -- Get skinlist selected by metadata
  99. function skins.get_skinlist_with_meta(key, value)
  100. assert(key, "key parameter for skins.get_skinlist_with_meta() missed")
  101. local skinslist = {}
  102. for _, skin in pairs(skins.meta) do
  103. if skin:get_meta(key) == value then
  104. table.insert(skinslist, skin)
  105. end
  106. end
  107. skins_sort(skinslist)
  108. return skinslist
  109. end