add u_skins mod
20
worldmods/u_skins/README
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
minetest-u_skins
|
||||||
|
================
|
||||||
|
|
||||||
|
Skins mod for minetest unified_inventory by Dean Montgomery - feel free to merge it into skinsdb or unified_inventory git.
|
||||||
|
|
||||||
|
Requires latest unified_inventory from:
|
||||||
|
https://github.com/minetest-technic/unified_inventory
|
||||||
|
|
||||||
|
This is the "u_skindb" branch, it is ment to download the skins from addi's skin database (http://minetest.fensta.bplaced.net).
|
||||||
|
|
||||||
|
To re-download the latest skins you may want to run:
|
||||||
|
"./update_from_db.py" OR
|
||||||
|
"./update_from_db2.py"
|
||||||
|
script, then "./generate_previews.sh" before using the mod.
|
||||||
|
|
||||||
|
|
||||||
|
Credits:
|
||||||
|
MirceaKitsune (WTFPL) + bundled script by Zeg9 (WTFPL too):
|
||||||
|
skin_previews.blend
|
||||||
|
RealyBadAngel unified_inventory and Zeg9 skinsdb
|
0
worldmods/u_skins/modpack.txt
Normal file
2
worldmods/u_skins/u_skins/depends.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
unified_inventory?
|
||||||
|
default
|
151
worldmods/u_skins/u_skins/init.lua
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
-- Unified Skins for Minetest - based modified Bags from unfied_inventory and skins from inventory_plus
|
||||||
|
|
||||||
|
-- Copyright (c) 2012 cornernote, Dean Montgomery
|
||||||
|
-- License: GPLv3
|
||||||
|
u_skins = {}
|
||||||
|
u_skins.type = { SPRITE=0, MODEL=1 }
|
||||||
|
u_skins.pages = {}
|
||||||
|
u_skins.u_skins = {}
|
||||||
|
|
||||||
|
u_skins.get_type = function(texture)
|
||||||
|
if not texture then return end
|
||||||
|
if string.sub(texture,0,string.len("character")) == "character" then
|
||||||
|
return u_skins.type.MODEL
|
||||||
|
end
|
||||||
|
if string.sub(texture,0,string.len("player")) == "player" then
|
||||||
|
return u_skins.type.SPRITE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
u_skins.modpath = minetest.get_modpath("u_skins")
|
||||||
|
dofile(u_skins.modpath.."/skinlist.lua")
|
||||||
|
dofile(u_skins.modpath.."/meta.lua")
|
||||||
|
dofile(u_skins.modpath.."/players.lua")
|
||||||
|
|
||||||
|
|
||||||
|
u_skins.update_player_skin = function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
if u_skins.get_type(u_skins.u_skins[name]) == u_skins.type.SPRITE then
|
||||||
|
player:set_properties({
|
||||||
|
visual = "upright_sprite",
|
||||||
|
textures = {u_skins.u_skins[name]..".png",u_skins.u_skins[name].."_back.png"},
|
||||||
|
visual_size = {x=1, y=2},
|
||||||
|
})
|
||||||
|
elseif u_skins.get_type(u_skins.u_skins[name]) == u_skins.type.MODEL then
|
||||||
|
player:set_properties({
|
||||||
|
visual = "mesh",
|
||||||
|
textures = {u_skins.u_skins[name]..".png"},
|
||||||
|
visual_size = {x=1, y=1},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
u_skins.save()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Display Current Skin
|
||||||
|
unified_inventory.register_page("u_skins", {
|
||||||
|
get_formspec = function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]"
|
||||||
|
if u_skins.get_type(u_skins.u_skins[name]) == u_skins.type.MODEL then
|
||||||
|
formspec = formspec
|
||||||
|
.. "image[0,.75;1,2;"..u_skins.u_skins[name].."_preview.png]"
|
||||||
|
.. "image[1,.75;1,2;"..u_skins.u_skins[name].."_preview_back.png]"
|
||||||
|
.. "label[6,.5;Raw texture:]"
|
||||||
|
.. "image[6,1;2,1;"..u_skins.u_skins[name]..".png]"
|
||||||
|
|
||||||
|
else
|
||||||
|
formspec = formspec
|
||||||
|
.. "image[0,.75;1,2;"..u_skins.u_skins[name]..".png]"
|
||||||
|
.. "image[1,.75;1,2;"..u_skins.u_skins[name].."_back.png]"
|
||||||
|
end
|
||||||
|
local meta = u_skins.meta[u_skins.u_skins[name]]
|
||||||
|
if meta then
|
||||||
|
if meta.name then
|
||||||
|
formspec = formspec .. "label[2,.5;Name: "..meta.name.."]"
|
||||||
|
end
|
||||||
|
if meta.author then
|
||||||
|
formspec = formspec .. "label[2,1;Author: "..meta.author.."]"
|
||||||
|
end
|
||||||
|
if meta.description then
|
||||||
|
formspec = formspec .. "label[2,1.5;"..meta.description.."]"
|
||||||
|
end
|
||||||
|
if meta.comment then
|
||||||
|
formspec = formspec .. 'label[2,2;"'..meta.comment..'"]'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
formspec = formspec .. "button[.75,3;6.5,.5;u_skins_page_0;Change]"
|
||||||
|
return {formspec=formspec}
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
unified_inventory.register_button("u_skins", {
|
||||||
|
type = "image",
|
||||||
|
image = "u_skins_button.png",
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Create all of the skin-picker pages.
|
||||||
|
for x = 0, math.floor(#u_skins.list/16+1) do
|
||||||
|
unified_inventory.register_page("u_skins_page_"..x, {
|
||||||
|
get_formspec = function(player)
|
||||||
|
local page = u_skins.pages[player:get_player_name()]
|
||||||
|
if page == nil then page = 0 end
|
||||||
|
local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]"
|
||||||
|
local index = 0
|
||||||
|
local skip = 0 -- Skip u_skins, used for pages
|
||||||
|
-- skin thumbnails
|
||||||
|
for i, skin in ipairs(u_skins.list) do
|
||||||
|
if skip < page*16 then skip = skip + 1 else
|
||||||
|
if index < 16 then
|
||||||
|
formspec = formspec .. "image_button["..(index%8)..","..((math.floor(index/8))*2)..";1,2;"..skin
|
||||||
|
if u_skins.get_type(skin) == u_skins.type.MODEL then
|
||||||
|
formspec = formspec .. "_preview"
|
||||||
|
end
|
||||||
|
formspec = formspec .. ".png;u_skins_set_"..i..";]"
|
||||||
|
end
|
||||||
|
index = index +1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- prev next page buttons
|
||||||
|
if page > 0 then
|
||||||
|
formspec = formspec .. "button[0,4;1,.5;u_skins_page_"..(page-1)..";<<]"
|
||||||
|
else
|
||||||
|
formspec = formspec .. "button[0,4;1,.5;u_skins_page_"..page..";<<]"
|
||||||
|
end
|
||||||
|
formspec = formspec .. "button[.75,4;6.5,.5;u_skins_page_"..page..";Page "..(page+1).."/"..math.floor(#u_skins.list/16+1).."]" -- a button is used so text is centered
|
||||||
|
if index > 16 then
|
||||||
|
formspec = formspec .. "button[7,4;1,.5;u_skins_page_"..(page+1)..";>>]"
|
||||||
|
else
|
||||||
|
formspec = formspec .. "button[7,4;1,.5;u_skins_page_"..page..";>>]"
|
||||||
|
end
|
||||||
|
return {formspec=formspec}
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- click button handlers
|
||||||
|
minetest.register_on_player_receive_fields(function(player,formname,fields)
|
||||||
|
if fields.u_skins then
|
||||||
|
unified_inventory.set_inventory_formspec(player,"craft")
|
||||||
|
end
|
||||||
|
for field, _ in pairs(fields) do
|
||||||
|
if string.sub(field,0,string.len("u_skins_set_")) == "u_skins_set_" then
|
||||||
|
u_skins.u_skins[player:get_player_name()] = u_skins.list[tonumber(string.sub(field,string.len("u_skins_set_")+1))]
|
||||||
|
u_skins.update_player_skin(player)
|
||||||
|
unified_inventory.set_inventory_formspec(player,"u_skins")
|
||||||
|
end
|
||||||
|
if string.sub(field,0,string.len("u_skins_page_")) == "u_skins_page_" then
|
||||||
|
u_skins.pages[player:get_player_name()] = tonumber(string.sub(field,string.len("u_skins_page_")+1))
|
||||||
|
unified_inventory.set_inventory_formspec(player,"u_skins_page_"..u_skins.pages[player:get_player_name()])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- set defaults
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
if not u_skins.u_skins[player:get_player_name()] then
|
||||||
|
u_skins.u_skins[player:get_player_name()] = "character_1"
|
||||||
|
end
|
||||||
|
u_skins.update_player_skin(player)
|
||||||
|
end)
|
||||||
|
|
15
worldmods/u_skins/u_skins/meta.lua
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
u_skins.meta = {}
|
||||||
|
for _, i in ipairs(u_skins.list) do
|
||||||
|
u_skins.meta[i] = {}
|
||||||
|
local f = io.open(u_skins.modpath.."/meta/"..i..".txt")
|
||||||
|
local data = nil
|
||||||
|
if f then
|
||||||
|
data = minetest.deserialize("return {"..f:read('*all').."}")
|
||||||
|
f:close()
|
||||||
|
end
|
||||||
|
data = data or {}
|
||||||
|
u_skins.meta[i].name = data.name or ""
|
||||||
|
u_skins.meta[i].author = data.author or ""
|
||||||
|
u_skins.meta[i].description = data.description or nil
|
||||||
|
u_skins.meta[i].comment = data.comment or nil
|
||||||
|
end
|
3
worldmods/u_skins/u_skins/meta/character_1.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = "Sam 0",
|
||||||
|
author = "Jordach",
|
||||||
|
comment = "CC BY-SA 3.0"
|
3
worldmods/u_skins/u_skins/meta/character_2.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = "Jayne",
|
||||||
|
author = "Andromeda",
|
||||||
|
comment = "CC BY-SA 3.0",
|
3
worldmods/u_skins/u_skins/meta/character_3.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
name = "Arctic Fox",
|
||||||
|
author = "Andromeda",
|
||||||
|
comment = "CC BY-SA 3.0",
|
2
worldmods/u_skins/u_skins/meta/placeholder.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
This file is here so the "meta" directory is created by git.
|
||||||
|
Please run the update_from_db.py script to fill this, or use the "master" branch of the mod.
|
28
worldmods/u_skins/u_skins/players.lua
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
u_skins.file = minetest.get_worldpath() .. "/u_skins.mt"
|
||||||
|
u_skins.load = function()
|
||||||
|
local input = io.open(u_skins.file, "r")
|
||||||
|
local data = nil
|
||||||
|
if input then
|
||||||
|
data = input:read('*all')
|
||||||
|
end
|
||||||
|
if data and data ~= "" then
|
||||||
|
local lines = string.split(data,"\n")
|
||||||
|
for _, line in ipairs(lines) do
|
||||||
|
data = string.split(line, ' ', 2)
|
||||||
|
u_skins.u_skins[data[1]] = data[2]
|
||||||
|
end
|
||||||
|
io.close(input)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
u_skins.load()
|
||||||
|
|
||||||
|
u_skins.save = function()
|
||||||
|
local output = io.open(u_skins.file,'w')
|
||||||
|
for name, skin in pairs(u_skins.u_skins) do
|
||||||
|
if name and skin then
|
||||||
|
output:write(name .. " " .. skin .. "\n")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
io.close(output)
|
||||||
|
end
|
||||||
|
|
25
worldmods/u_skins/u_skins/skinlist.lua
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
u_skins.list = {}
|
||||||
|
u_skins.add = function(skin)
|
||||||
|
table.insert(u_skins.list,skin)
|
||||||
|
end
|
||||||
|
|
||||||
|
local id
|
||||||
|
|
||||||
|
id = 1
|
||||||
|
while true do
|
||||||
|
local f = io.open(minetest.get_modpath("u_skins").."/textures/player_"..id..".png")
|
||||||
|
if (not f) then break end
|
||||||
|
f:close()
|
||||||
|
u_skins.add("player_"..id)
|
||||||
|
id = id +1
|
||||||
|
end
|
||||||
|
|
||||||
|
id = 1
|
||||||
|
while true do
|
||||||
|
local f = io.open(minetest.get_modpath("u_skins").."/textures/character_"..id..".png")
|
||||||
|
if (not f) then break end
|
||||||
|
f:close()
|
||||||
|
u_skins.add("character_"..id)
|
||||||
|
id = id +1
|
||||||
|
end
|
||||||
|
|
BIN
worldmods/u_skins/u_skins/textures/character_1.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
worldmods/u_skins/u_skins/textures/character_1_preview.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
worldmods/u_skins/u_skins/textures/character_2.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
worldmods/u_skins/u_skins/textures/character_2_preview.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
worldmods/u_skins/u_skins/textures/character_3.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
worldmods/u_skins/u_skins/textures/character_3_preview.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
worldmods/u_skins/u_skins/textures/u_skins_button.png
Normal file
After Width: | Height: | Size: 338 B |
BIN
worldmods/u_skins/u_skins/textures/ui_misc_form.png
Normal file
After Width: | Height: | Size: 9.1 KiB |
46
worldmods/u_skins/update_from_db.py
Executable file
@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
from http.client import HTTPConnection
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
|
||||||
|
server = "minetest.fensta.bplaced.net"
|
||||||
|
skinsdir = "u_skins/textures/"
|
||||||
|
metadir = "u_skins/meta/"
|
||||||
|
i = 1
|
||||||
|
pages = 0
|
||||||
|
|
||||||
|
c = HTTPConnection(server)
|
||||||
|
def addpage(page):
|
||||||
|
global i, pages
|
||||||
|
print( "Page: "+str(page))
|
||||||
|
try:
|
||||||
|
c.request("GET","/api/get.json.php?getlist&page="+str(page)+"&outformat=base64")
|
||||||
|
r = c.getresponse()
|
||||||
|
except StandardError:
|
||||||
|
c.request("GET","/api/get.json.php?getlist&page="+str(page)+"&outformat=base64")
|
||||||
|
r = c.getresponse()
|
||||||
|
if r.status != 200:
|
||||||
|
print("Error", r.status)
|
||||||
|
exit(r.status)
|
||||||
|
data = r.read().decode()
|
||||||
|
l = json.loads(data)
|
||||||
|
if not l["success"]:
|
||||||
|
print("Success != True")
|
||||||
|
exit(1)
|
||||||
|
pages = int(l["pages"])
|
||||||
|
for s in l["skins"]:
|
||||||
|
f = open(skinsdir+"character_"+str(i)+".png",'wb')
|
||||||
|
f.write(base64.b64decode(s["img"]))
|
||||||
|
f.close()
|
||||||
|
f = open(metadir+"character_"+str(i)+".txt",'w')
|
||||||
|
f.write('name = "'+s["name"]+'",\n')
|
||||||
|
f.write('author = "'+s["author"]+'",\n')
|
||||||
|
f.write('comment = "'+s["license"]+'",\n')
|
||||||
|
f.close()
|
||||||
|
i = i + 1
|
||||||
|
addpage(1)
|
||||||
|
if pages > 1:
|
||||||
|
for p in range(pages-1):
|
||||||
|
addpage(p+2)
|
||||||
|
print("Skins have been updated. Please run ./generate_previews.sh")
|
||||||
|
|
45
worldmods/u_skins/update_from_db2.py
Executable file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
#from http.client import HTTPConnection
|
||||||
|
import json
|
||||||
|
import base64
|
||||||
|
import requests
|
||||||
|
|
||||||
|
server = "minetest.fensta.bplaced.net"
|
||||||
|
skinsdir = "u_skins/textures/"
|
||||||
|
metadir = "u_skins/meta/"
|
||||||
|
i = 1
|
||||||
|
pages = 0
|
||||||
|
|
||||||
|
#c = HTTPConnection(server)
|
||||||
|
def addpage(page):
|
||||||
|
global i, pages
|
||||||
|
print( "Page: "+str(page))
|
||||||
|
try:
|
||||||
|
#c.request("GET","/api/get.json.php?getlist&page="+str(page)+"&outformat=base64")
|
||||||
|
#r = c.getresponse()
|
||||||
|
r = requests.get("http://"+str(server)+"/api/get.json.php?getlist&page="+str(page)+"&outformat=base64")
|
||||||
|
except StandardError:
|
||||||
|
print("Error", r.status)
|
||||||
|
exit(r.status)
|
||||||
|
data = r.text
|
||||||
|
l = json.loads(data)
|
||||||
|
if not l["success"]:
|
||||||
|
print("Success != True")
|
||||||
|
exit(1)
|
||||||
|
pages = int(l["pages"])
|
||||||
|
for s in l["skins"]:
|
||||||
|
f = open(skinsdir+"character_"+str(i)+".png",'wb')
|
||||||
|
f.write(base64.b64decode(s["img"]))
|
||||||
|
f.close()
|
||||||
|
f = open(metadir+"character_"+str(i)+".txt",'w')
|
||||||
|
f.write('name = "'+s["name"]+'",\n')
|
||||||
|
f.write('author = "'+s["author"]+'",\n')
|
||||||
|
f.write('comment = "'+s["license"]+'",\n')
|
||||||
|
f.close()
|
||||||
|
i = i + 1
|
||||||
|
addpage(1)
|
||||||
|
if pages > 1:
|
||||||
|
for p in range(pages-1):
|
||||||
|
addpage(p+2)
|
||||||
|
print("Skins have been updated. Please run ./generate_previews.sh")
|
||||||
|
|