Compare commits
	
		
			21 Commits
		
	
	
		
			minetest-0
			...
			716a9a3f9a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 716a9a3f9a | ||
|  | c53158d159 | ||
|  | da6905fd02 | ||
|  | 8048cb08f1 | ||
|  | 77c00a0823 | ||
|  | 8799ba0bd5 | ||
|  | b5ba66deca | ||
|  | 1fcd3c4a8c | ||
|  | 55704e1657 | ||
|  | ec30267223 | ||
|  | 55dc55f2dd | ||
|  | ada930c099 | ||
|  | 918df53f3b | ||
|  | 664a4a8d81 | ||
|  | 9525b87c4d | ||
|  | abb5422948 | ||
|  | aa82f804b8 | ||
|  | 165c20fcad | ||
|  | 555d682f04 | ||
|  | e5714f272c | ||
|  | fa92207f14 | 
							
								
								
									
										15
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -9,6 +9,7 @@ This Minetest mod offers changeable player skins with a graphical interface for | ||||
| - Skin change menu for sfinv (in minetest_game) and [unified_inventory](https://forum.minetest.net/viewtopic.php?t=12767) | ||||
| - Skins change menu and command line using chat command /skinsdb (set | show | list | list private | list public | ui) | ||||
| - Supported by [smart_inventory](https://forum.minetest.net/viewtopic.php?t=16597) for the skin selection | ||||
| - Supported by [i3](https://github.com/minetest-mods/i3) inventory mod | ||||
| - Skin previews supported in selection | ||||
| - Additional information for each skin | ||||
| - Support for different skins lists: public and a per-player list are currently implemented | ||||
| @@ -18,7 +19,9 @@ This Minetest mod offers changeable player skins with a graphical interface for | ||||
|  | ||||
| ## Installing skins | ||||
|  | ||||
| ### Download from the database | ||||
| ### Download from the [database](http://minetest.fensta.bplaced.net/) | ||||
|  | ||||
| #### Ingame Downloader | ||||
|  | ||||
| 1) Get Minetest 5.1.0-dev-cb00632 or newer | ||||
| 2) Start your world | ||||
| @@ -28,6 +31,16 @@ This Minetest mod offers changeable player skins with a graphical interface for | ||||
|  | ||||
| You might want to run `minetest` in a Terminal/Console window to check the log output instantly. | ||||
|  | ||||
| #### Python Download script | ||||
|  | ||||
| **Requirements:** | ||||
|  | ||||
|  * Python 3 | ||||
|  * `requests` library: `pip3 install requests`   | ||||
|   | ||||
| 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. | ||||
|  | ||||
| ### Manual addition | ||||
|  | ||||
| 1) Copy your skin textures to `textures` as documented in `textures/readme.txt` | ||||
|   | ||||
							
								
								
									
										8
									
								
								api.lua
									
									
									
									
									
								
							
							
						
						| @@ -2,9 +2,11 @@ | ||||
| local storage = minetest.get_mod_storage() | ||||
|  | ||||
| function skins.get_player_skin(player) | ||||
| 	if player:get_attribute("skinsdb:skin_key") then | ||||
| 		storage:set_string(player:get_player_name(), player:get_attribute("skinsdb:skin_key")) | ||||
| 		player:set_attribute("skinsdb:skin_key", nil) | ||||
| 	local meta = player:get_meta() | ||||
| 	if meta:get("skinsdb:skin_key") then | ||||
| 		-- Move player data prior July 2018 to mod storage | ||||
| 		storage:set_string(player:get_player_name(), meta:get_string("skinsdb:skin_key")) | ||||
| 		meta:set_string("skinsdb:skin_key", "") | ||||
| 	end | ||||
| 	local skin = storage:get_string(player:get_player_name()) | ||||
| 	return skins.get(skin) or skins.get(skins.default) | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| local S = skins.S | ||||
| local S = minetest.get_translator("skinsdb") | ||||
|  | ||||
| local function show_selection_formspec(player) | ||||
| 	local context = skins.get_formspec_context(player) | ||||
| @@ -36,12 +36,15 @@ minetest.register_chatcommand("skinsdb", { | ||||
| 		end | ||||
|  | ||||
| 		if command == "set" then | ||||
| 			if parameter then | ||||
| 				local success = skins.set_player_skin(player, parameter) | ||||
| 				if success then | ||||
| 					return true, S("skin set to").." "..parameter | ||||
| 				else | ||||
| 					return false, S("invalid skin").." "..parameter | ||||
| 				end | ||||
| 			else return false, S("Requires skin key") | ||||
| 			end | ||||
| 		elseif command == "list" then | ||||
| 			local list | ||||
| 			if parameter == "private" then | ||||
|   | ||||
| @@ -1,6 +0,0 @@ | ||||
| default | ||||
| intllib? | ||||
| unified_inventory? | ||||
| 3d_armor? | ||||
| clothing? | ||||
| sfinv? | ||||
							
								
								
									
										104
									
								
								formspecs.lua
									
									
									
									
									
								
							
							
						
						| @@ -1,4 +1,5 @@ | ||||
| local S = skins.S | ||||
| local S = minetest.get_translator("skinsdb") | ||||
| local ui = unified_inventory | ||||
|  | ||||
| function skins.get_formspec_context(player) | ||||
| 	if player then | ||||
| @@ -11,36 +12,91 @@ function skins.get_formspec_context(player) | ||||
| end | ||||
|  | ||||
| -- Show skin info | ||||
| function skins.get_skin_info_formspec(skin) | ||||
| function skins.get_skin_info_formspec(skin, perplayer_formspec) | ||||
| 	local texture = skin:get_texture() | ||||
| 	local m_name = skin:get_meta_string("name") | ||||
| 	local m_author = skin:get_meta_string("author") | ||||
| 	local m_license = skin:get_meta_string("license") | ||||
| 	local m_format = skin:get_meta("format") | ||||
| 	-- overview page | ||||
| 	local formspec = "image[0,.75;1,2;"..skin:get_preview().."]" | ||||
| 	local raw_size = m_format == "1.8" and "2,2" or "2,1" | ||||
|  | ||||
| 	local lxoffs = 0.8 | ||||
| 	local cxoffs = 2 | ||||
| 	local rxoffs = 5.5 | ||||
|  | ||||
| 	if type(perplayer_formspec) == "table" then -- we're using Unified Inventory | ||||
| 		lxoffs = 1.5 | ||||
| 		cxoffs = 3.75 | ||||
| 		rxoffs = 7.5 | ||||
| 	end | ||||
|  | ||||
| 	local formspec = "image["..lxoffs..",.6;1,2;"..minetest.formspec_escape(skin:get_preview()).."]" | ||||
| 	if texture then | ||||
| 		formspec = formspec.."label[6,.5;"..S("Raw texture")..":]" | ||||
| 		.."image[6,1;2,1;"..skin:get_texture().."]" | ||||
| 		formspec = formspec.."label["..rxoffs..",.5;"..S("Raw texture")..":]" | ||||
| 		.."image["..rxoffs..",1;"..raw_size..";"..texture.."]" | ||||
| 	end | ||||
| 	if m_name ~= "" then | ||||
| 		formspec = formspec.."label[2,.5;"..S("Name")..": "..minetest.formspec_escape(m_name).."]" | ||||
| 		formspec = formspec.."label["..cxoffs..",.5;"..S("Name")..": "..minetest.formspec_escape(m_name).."]" | ||||
| 	end | ||||
| 	if m_author ~= "" then | ||||
| 		formspec = formspec.."label[2,1;"..S("Author")..": "..minetest.formspec_escape(m_author).."]" | ||||
| 		formspec = formspec.."label["..cxoffs..",1;"..S("Author")..": "..minetest.formspec_escape(m_author).."]" | ||||
| 	end | ||||
| 	if m_license ~= "" then | ||||
| 		formspec = formspec.."label[2,1.5;"..S("License")..": "..minetest.formspec_escape(m_license).."]" | ||||
| 		formspec = formspec.."label["..cxoffs..",1.5;"..S("License")..": "..minetest.formspec_escape(m_license).."]" | ||||
| 	end | ||||
| 	return formspec | ||||
| end | ||||
|  | ||||
| function skins.get_skin_selection_formspec(player, context, y_delta) | ||||
| function skins.get_skin_selection_formspec(player, context, perplayer_formspec) | ||||
| 	context.skins_list = skins.get_skinlist_for_player(player:get_player_name()) | ||||
| 	context.total_pages = 1 | ||||
| 	local xoffs = 0 | ||||
| 	local yoffs = 4 | ||||
| 	local xspc = 1 | ||||
| 	local yspc = 2 | ||||
| 	local skinwidth = 1 | ||||
| 	local skinheight = 2 | ||||
| 	local xscale = 1 | ||||
| 	local btn_y = 8.15 | ||||
| 	local drop_y = 8 | ||||
| 	local btn_width = 1 | ||||
| 	local droppos = 1 | ||||
| 	local droplen = 6.25 | ||||
| 	local btn_right = 7 | ||||
| 	local maxdisp = 16 | ||||
|  | ||||
| 	local ctrls_height = 0.5 | ||||
|  | ||||
| 	if type(perplayer_formspec) == "table" then -- it's being used under Unified Inventory | ||||
| 		xoffs =  perplayer_formspec.std_inv_x | ||||
| 		xspc =   ui.imgscale | ||||
| 		yspc =   ui.imgscale*2 | ||||
| 		skinwidth =  ui.imgscale*0.9 | ||||
| 		skinheight = ui.imgscale*1.9 | ||||
| 		xscale = ui.imgscale | ||||
| 		btn_width = ui.imgscale | ||||
| 		droppos = xoffs + btn_width + 0.1 | ||||
| 		droplen = ui.imgscale * 6 - 0.2 | ||||
| 		btn_right = droppos + droplen + 0.1 | ||||
|  | ||||
| 		if perplayer_formspec.pagecols == 4 then -- and we're in lite mode | ||||
| 			yoffs =  1 | ||||
| 			maxdisp = 8 | ||||
| 			drop_y = yoffs + skinheight + 0.1 | ||||
| 		else | ||||
| 			yoffs =  0.2 | ||||
| 			drop_y = yoffs + skinheight*2 + 0.2 | ||||
| 		end | ||||
|  | ||||
| 		btn_y = drop_y | ||||
|  | ||||
| 	end | ||||
|  | ||||
| 	for i, skin in ipairs(context.skins_list ) do | ||||
| 		local page = math.floor((i-1) / 16)+1 | ||||
| 		local page = math.floor((i-1) / maxdisp)+1 | ||||
| 		skin:set_meta("inv_page", page) | ||||
| 		skin:set_meta("inv_page_index", (i-1)%16+1) | ||||
| 		skin:set_meta("inv_page_index", (i-1)%maxdisp+1) | ||||
| 		context.total_pages = page | ||||
| 	end | ||||
| 	context.skins_page = context.skins_page or skins.get_player_skin(player):get_meta("inv_page") or 1 | ||||
| @@ -48,22 +104,25 @@ function skins.get_skin_selection_formspec(player, context, y_delta) | ||||
|  | ||||
| 	local page = context.skins_page | ||||
| 	local formspec = "" | ||||
| 	for i = (page-1)*16+1, page*16 do | ||||
| 	 | ||||
| 	for i = (page-1)*maxdisp+1, page*maxdisp do | ||||
| 		local skin = context.skins_list[i] | ||||
| 		if not skin then | ||||
| 			break | ||||
| 		end | ||||
|  | ||||
| 		local index_p = skin:get_meta("inv_page_index") | ||||
| 		local x = (index_p-1) % 8 | ||||
| 		local x = ((index_p-1) % 8) * xspc + xoffs | ||||
| 		local y | ||||
| 		if index_p > 8 then | ||||
| 			y = y_delta + 1.9 | ||||
| 			y = yoffs + yspc | ||||
| 		else | ||||
| 			y = y_delta | ||||
| 			y = yoffs | ||||
| 		end | ||||
| 		formspec = formspec.."image_button["..x..","..y..";1,2;".. | ||||
| 			skin:get_preview()..";skins_set$"..i..";]".. | ||||
| 		formspec = formspec.. | ||||
| 			string.format("image_button[%f,%f;%f,%f;%s;skins_set$%i;]", | ||||
| 				x, y, skinwidth, skinheight, | ||||
| 				minetest.formspec_escape(skin:get_preview()), i).. | ||||
| 			"tooltip[skins_set$"..i..";"..minetest.formspec_escape(skin:get_meta_string("name")).."]" | ||||
| 	end | ||||
|  | ||||
| @@ -84,10 +143,13 @@ function skins.get_skin_selection_formspec(player, context, y_delta) | ||||
| 			if pg > 1 then page_list = page_list.."," end | ||||
| 			page_list = page_list..pagename | ||||
| 		end | ||||
| 		formspec = formspec | ||||
| 			.."button[0,"..(y_delta+4.0)..";1,.5;skins_page$"..page_prev..";<<]" | ||||
| 			.."dropdown[0.9,"..(y_delta+3.88)..";6.5,.5;skins_selpg;"..page_list..";"..page.."]" | ||||
| 			.."button[7,"..(y_delta+4.0)..";1,.5;skins_page$"..page_next..";>>]" | ||||
| 		formspec = formspec.. | ||||
| 			string.format("button[%f,%f;%f,%f;skins_page$%i;<<]", | ||||
| 				xoffs, btn_y, btn_width, ctrls_height, page_prev).. | ||||
| 			string.format("button[%f,%f;%f,%f;skins_page$%i;>>]", | ||||
| 				btn_right, btn_y, btn_width, ctrls_height, page_next).. | ||||
| 			string.format("dropdown[%f,%f;%f,%f;skins_selpg;%s;%i]", | ||||
| 				droppos, drop_y, droplen, ctrls_height, page_list, page) | ||||
| 	end | ||||
| 	return formspec | ||||
| end | ||||
|   | ||||
							
								
								
									
										42
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						| @@ -3,19 +3,11 @@ | ||||
| -- Copyright (c) 2012 cornernote, Dean Montgomery | ||||
| -- Rework 2017 by bell07 | ||||
| -- License: GPLv3 | ||||
| -- Boilerplate to support localized strings if intllib mod is installed. | ||||
|  | ||||
| skins = {} | ||||
| skins.modpath = minetest.get_modpath(minetest.get_current_modname()) | ||||
| skins.default = "character" | ||||
|  | ||||
| local S | ||||
| if minetest.get_modpath("intllib") then | ||||
| 	skins.S = intllib.Getter() | ||||
| else | ||||
| 	skins.S = function(s) return s end | ||||
| end | ||||
|  | ||||
| dofile(skins.modpath.."/skin_meta_api.lua") | ||||
| dofile(skins.modpath.."/api.lua") | ||||
| dofile(skins.modpath.."/skinlist.lua") | ||||
| @@ -73,9 +65,7 @@ minetest.register_on_leaveplayer(function(player) | ||||
| 	skins.ui_context[player:get_player_name()] = nil | ||||
| end) | ||||
|  | ||||
| if minetest.global_exists("player_api") then | ||||
| 	-- Minetest-5 and above compatible | ||||
| 	player_api.register_model("skinsdb_3d_armor_character_5.b3d", { | ||||
| player_api.register_model("skinsdb_3d_armor_character_5.b3d", { | ||||
| 	animation_speed = 30, | ||||
| 	textures = { | ||||
| 		"blank.png", | ||||
| @@ -91,24 +81,14 @@ if minetest.global_exists("player_api") then | ||||
| 		walk_mine = {x=200, y=219}, | ||||
| 		sit = {x=81, y=160}, | ||||
| 	}, | ||||
| 	}) | ||||
| else | ||||
| 	-- Minetest-0.4 compatible | ||||
| 	default.player_register_model("skinsdb_3d_armor_character.b3d", { | ||||
| 		animation_speed = 30, | ||||
| 		textures = { | ||||
| 			"blank.png", | ||||
| 			"blank.png", | ||||
| 			"blank.png", | ||||
| 			"blank.png", | ||||
| 		}, | ||||
| 		animations = { | ||||
| 			stand = {x=0, y=79}, | ||||
| 			lay = {x=162, y=166}, | ||||
| 			walk = {x=168, y=187}, | ||||
| 			mine = {x=189, y=198}, | ||||
| 			walk_mine = {x=200, y=219}, | ||||
| 			sit = {x=81, y=160}, | ||||
| 		}, | ||||
| 	}) | ||||
| }) | ||||
|  | ||||
| -- Register default character.png if not part of this mod | ||||
| local default_skin_obj = skins.get(skins.default) | ||||
| if not default_skin_obj then | ||||
| 	default_skin_obj = skins.new(skins.default) | ||||
| 	default_skin_obj:set_texture("character.png") | ||||
| 	default_skin_obj:set_meta("format", '1.0') | ||||
| 	default_skin_obj:set_meta("_sort_id", 0) | ||||
| 	default_skin_obj:set_meta("name", "Sam") | ||||
| end | ||||
|   | ||||
| @@ -1,16 +0,0 @@ | ||||
| # Translation by Xanthin | ||||
|  | ||||
| Raw texture = Rohtextur | ||||
| Name = Name | ||||
| Author = Autor | ||||
| Change = Wechseln | ||||
| Page = Seite | ||||
| License = Lizenz | ||||
| Description = Beschreibung | ||||
| Show, list or set player's skin = Anzeigen oder setzen der Spieler-Skins | ||||
| Player not found = Spieler nicht da | ||||
| unknown command = unbekannter Befehl | ||||
| see /help skinsdb for supported parameters = Lese /help für erlaubte Parameter | ||||
| skin set to = Skin ist jetzt | ||||
| invalid skin = unbekannter Skin | ||||
| unknown parameter = unbekannter Parameter | ||||
| @@ -1,18 +0,0 @@ | ||||
| # Template | ||||
|  | ||||
| Raw texture = Texture | ||||
| Name = Nom | ||||
| Author = Auteur | ||||
| Change = Changer | ||||
| Page = Page | ||||
| License = Licence | ||||
| Description = Description | ||||
| Show, list or set player's skin = Afficher, lister ou définir le skin du joueur  | ||||
| Player not found = Joueur non trouvé | ||||
| unknown command = commande inconnue | ||||
| see /help skinsdb for supported parameters = voir /help skinsdb pour les paramètres supportés | ||||
| skin set to = skin définie sur | ||||
| invalid skin = skin peau invalide | ||||
| unknown parameter = paramètre inconnu | ||||
| unknown skin = skin inconnue | ||||
|  | ||||
| @@ -1,17 +0,0 @@ | ||||
| # Malay translation by muhdnurhidayat | ||||
|  | ||||
| Raw texture = Tekstur mentah | ||||
| Name = Nama | ||||
| Author = Pencipta | ||||
| Change = Ubah | ||||
| Page = Halaman | ||||
| License = Lesen  | ||||
| Description = Keterangan | ||||
| Show, list or set player's skin = Tunjukkan, senaraikan atau tetapkan kulit pemain | ||||
| Player not found = Pemain tidak dijumpai | ||||
| unknown command = perintah tidak diketahui | ||||
| see /help skinsdb for supported parameters = lihat /help skinsdb untuk parameter yang disokong | ||||
| skin set to = kulit ditetapkan kepada | ||||
| invalid skin = kulit tidak sah | ||||
| unknown parameter = parameter tidak diketahui | ||||
| unknown skin = kulit tidak diketahui | ||||
							
								
								
									
										19
									
								
								locale/skinsdb.de.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| # textdomain: skinsdb | ||||
| # Translation by Xanthin | ||||
|  | ||||
| Raw texture=Rohtextur | ||||
| Name=Name | ||||
| Author=Autor | ||||
| Change=Wechseln | ||||
| Page=Seite | ||||
| License=Lizenz | ||||
| Description=Beschreibung | ||||
| Show, list or set player's skin=Anzeigen oder setzen der Spieler-Skins | ||||
| Player not found=Spieler nicht da | ||||
| unknown command=unbekannter Befehl | ||||
| see /help skinsdb for supported parameters=Lese /help für erlaubte Parameter | ||||
| skin set to=Skin ist jetzt | ||||
| invalid skin=unbekannter Skin | ||||
| unknown parameter=unbekannter Parameter | ||||
| Skins=Aussehen | ||||
| Requires skin key=Benötigt Skin-Name | ||||
							
								
								
									
										18
									
								
								locale/skinsdb.fr.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,18 @@ | ||||
| # textdomain: skinsdb | ||||
|  | ||||
| Raw texture=Texture | ||||
| Name=Nom | ||||
| Author=Auteur | ||||
| Change=Changer | ||||
| Page=Page | ||||
| License=Licence | ||||
| Description=Description | ||||
| Show, list or set player's skin=Afficher, lister ou définir le skin du joueur | ||||
| Player not found=Joueur non trouvé | ||||
| unknown command=commande inconnue | ||||
| see /help skinsdb for supported parameters=voir /help skinsdb pour les paramètres supportés | ||||
| skin set to=skin définie sur | ||||
| invalid skin=skin peau invalide | ||||
| unknown parameter=paramètre inconnu | ||||
| unknown skin=skin inconnue | ||||
|  | ||||
							
								
								
									
										18
									
								
								locale/skinsdb.ms.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,18 @@ | ||||
| # textdomain: skinsdb | ||||
| # Malay translation by muhdnurhidayat | ||||
|  | ||||
| Raw texture=Tekstur mentah | ||||
| Name=Nama | ||||
| Author=Pencipta | ||||
| Change=Ubah | ||||
| Page=Halaman | ||||
| License=Lesen | ||||
| Description=Keterangan | ||||
| Show, list or set player's skin=Tunjukkan, senaraikan atau tetapkan kulit pemain | ||||
| Player not found=Pemain tidak dijumpai | ||||
| unknown command=perintah tidak diketahui | ||||
| see /help skinsdb for supported parameters=lihat /help skinsdb untuk parameter yang disokong | ||||
| skin set to=kulit ditetapkan kepada | ||||
| invalid skin=kulit tidak sah | ||||
| unknown parameter=parameter tidak diketahui | ||||
| unknown skin=kulit tidak diketahui | ||||
							
								
								
									
										20
									
								
								locale/skinsdb.zh_CN.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,20 @@ | ||||
| # textdomain: skinsdb | ||||
| #Translation by IFRFSX(BingFengFSX) | ||||
|  | ||||
| Raw texture=自然状态的纹理 | ||||
| Name=名称 | ||||
| Author=作者 | ||||
| Change=更换 | ||||
| Page=页面 | ||||
| License=许可证 | ||||
| Description=说明 | ||||
| Show, list or set player's skin=显示,列出或者设置玩家的皮肤 | ||||
| Player not found=玩家未找到 | ||||
| unknown command=未知命令 | ||||
| see /help skinsdb for supported parameters=有关skinsdb支持的参数,参见 /help | ||||
| skin set to=皮肤设置为 | ||||
| invalid skin=无效皮肤 | ||||
| unknown parameter=未知参数 | ||||
| unknown skin=未知皮肤 | ||||
| Downloads the specified range of skins and shuts down the server=下载指定范围的皮肤并关闭服务器 | ||||
| Skins=皮肤 | ||||
							
								
								
									
										19
									
								
								locale/skinsdb.zh_TW.tr
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,19 @@ | ||||
| # textdomain: skinsdb | ||||
| #Translation by IFRFSX(BingFengFSX) | ||||
| Raw texture=自然狀態的紋理 | ||||
| Name=名稱 | ||||
| Author=作者 | ||||
| Change=更換 | ||||
| Page=頁面 | ||||
| License=許可證 | ||||
| Description=說明 | ||||
| Show,list or set player's skin=顯示,列出或者設定玩家的皮膚 | ||||
| Player not found=玩家未找到 | ||||
| unknown command=未知命令 | ||||
| see /help skinsdb for supported parameters=有關skinsdb支持的參數,參見/help | ||||
| skin set to=皮膚設定為 | ||||
| invalid skin=無效皮膚 | ||||
| unknown parameter=未知參數 | ||||
| unknown skin=未知皮膚 | ||||
| Downloads the specified range of skins and shuts down the server=下載指定範圍的皮膚並關閉服務器 | ||||
| Skins=皮膚 | ||||
| @@ -1,17 +1,20 @@ | ||||
| # Template | ||||
| # textdomain: skinsdb | ||||
|  | ||||
| Raw texture =  | ||||
| Name =  | ||||
| Author =  | ||||
| Change =  | ||||
| Page =  | ||||
| License =  | ||||
| Description = | ||||
| Show, list or set player's skin = | ||||
| Player not found = | ||||
| unknown command = | ||||
| see /help skinsdb for supported parameters = | ||||
| skin set to = | ||||
| invalid skin = | ||||
| unknown parameter = | ||||
| unknown skin = | ||||
| Raw texture= | ||||
| Name= | ||||
| Author= | ||||
| Change= | ||||
| Page= | ||||
| License= | ||||
| Description= | ||||
| Show, list or set player's skin= | ||||
| Player not found= | ||||
| unknown command= | ||||
| see /help skinsdb for supported parameters= | ||||
| skin set to= | ||||
| invalid skin= | ||||
| unknown parameter= | ||||
| unknown skin= | ||||
| Downloads the specified range of skins and shuts down the server= | ||||
| Skins= | ||||
| Requires skin key= | ||||
|   | ||||
| @@ -1,18 +0,0 @@ | ||||
| #Translation by IFRFSX(BingFengFSX) | ||||
|  | ||||
| Raw texture = 自然状态的纹理 | ||||
| Name = 名称 | ||||
| Author = 作者 | ||||
| Change = 更换 | ||||
| Page = 页面 | ||||
| License = 许可证 | ||||
| Description = 说明 | ||||
| Show, list or set player's skin = 显示,列出或者设置玩家的皮肤 | ||||
| Player not found = 玩家未找到 | ||||
| unknown command = 未知命令 | ||||
| see /help skinsdb for supported parameters = 有关skinsdb支持的参数,参见 /help | ||||
| skin set to = 皮肤设置为 | ||||
| invalid skin = 无效皮肤 | ||||
| unknown parameter = 未知参数 | ||||
| unknown skin = 未知皮肤 | ||||
| Downloads the specified range of skins and shuts down the server = 下载指定范围的皮肤并关闭服务器 | ||||
| @@ -1,3 +0,0 @@ | ||||
| Sam 0 | ||||
| Jordach | ||||
| CC BY-SA 3.0 | ||||
							
								
								
									
										4
									
								
								mod.conf
									
									
									
									
									
								
							
							
						
						| @@ -1 +1,5 @@ | ||||
| name = skinsdb | ||||
| description = Player skin mod, supporting unified_inventory, sfinv and smart_inventory | ||||
| depends = player_api | ||||
| optional_depends = unified_inventory,3d_armor,clothing,sfinv | ||||
| min_minetest_version = 5.4.0 | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| local S = skins.S | ||||
| local S = minetest.get_translator("skinsdb") | ||||
|  | ||||
| -- generate the current formspec | ||||
| local function get_formspec(player, context) | ||||
| @@ -9,7 +9,7 @@ local function get_formspec(player, context) | ||||
| end | ||||
|  | ||||
| sfinv.register_page("skins:overview", { | ||||
| 	title = "Skins", | ||||
| 	title = S("Skins"), | ||||
| 	get = function(self, player, context) | ||||
| 		-- collect skins data | ||||
| 		return sfinv.make_formspec(player, context, get_formspec(player, context)) | ||||
|   | ||||
| @@ -56,7 +56,58 @@ function skin_class:set_preview(value) | ||||
| end | ||||
|  | ||||
| function skin_class:get_preview() | ||||
| 	return self._preview or "player.png" | ||||
| 	if self._preview then | ||||
| 		return self._preview | ||||
| 	end | ||||
|  | ||||
| 	local player_skin = "("..self:get_texture()..")" | ||||
| 	local skin = "" | ||||
|  | ||||
| 	-- Consistent on both sizes: | ||||
| 	--Chest | ||||
| 	skin = skin .. "([combine:16x32:-16,-12=" .. player_skin .. "^[mask:skindb_mask_chest.png)^" | ||||
| 	--Head | ||||
| 	skin = skin .. "([combine:16x32:-4,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^" | ||||
| 	--Hat | ||||
| 	skin = skin .. "([combine:16x32:-36,-8=" .. player_skin .. "^[mask:skindb_mask_head.png)^" | ||||
| 	--Right Arm | ||||
| 	skin = skin .. "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^" | ||||
| 	--Right Leg | ||||
| 	skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" | ||||
|  | ||||
| 	-- 64x skins have non-mirrored arms and legs | ||||
| 	local left_arm | ||||
| 	local left_leg | ||||
|  | ||||
| 	if self:get_meta("format") == "1.8" then | ||||
| 		left_arm = "([combine:16x32:-24,-44=" .. player_skin .. "^[mask:(skindb_mask_rarm.png^[transformFX))^" | ||||
| 		left_leg = "([combine:16x32:-12,-32=" .. player_skin .. "^[mask:(skindb_mask_rleg.png^[transformFX))^" | ||||
| 	else | ||||
| 		left_arm = "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:skindb_mask_rarm.png^[transformFX)^" | ||||
| 		left_leg = "([combine:16x32:0,0=" .. player_skin .. "^[mask:skindb_mask_rleg.png^[transformFX)^" | ||||
| 	end | ||||
|  | ||||
| 	-- Left Arm | ||||
| 	skin = skin .. left_arm | ||||
| 	--Left Leg | ||||
| 	skin = skin .. left_leg | ||||
|  | ||||
| 	-- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out | ||||
| 	--Chest Overlay | ||||
| 	skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:skindb_mask_chest.png)^" | ||||
| 	--Right Arm Overlay | ||||
| 	skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:skindb_mask_rarm.png)^" | ||||
| 	--Right Leg Overlay | ||||
| 	skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:skindb_mask_rleg.png)^" | ||||
| 	--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))" | ||||
|  | ||||
| 	-- Full Preview | ||||
| 	skin = "(((" .. skin .. ")^[resize:64x128)^[mask:skindb_transform.png)" | ||||
|  | ||||
| 	return skin | ||||
| end | ||||
|  | ||||
| function skin_class:apply_skin_to_player(player) | ||||
| @@ -73,13 +124,9 @@ function skin_class:apply_skin_to_player(player) | ||||
|  | ||||
| 	local playername = player:get_player_name() | ||||
| 	local ver = self:get_meta("format") or "1.0" | ||||
| 	if minetest.global_exists("player_api") then | ||||
| 		-- Minetest-5 compatible | ||||
|  | ||||
| 	player_api.set_model(player, "skinsdb_3d_armor_character_5.b3d") | ||||
| 	else | ||||
| 		-- Minetest-0.4 compatible | ||||
| 		default.player_set_model(player, "skinsdb_3d_armor_character.b3d") | ||||
| 	end | ||||
|  | ||||
| 	local v10_texture = "blank.png" | ||||
| 	local v18_texture = "blank.png" | ||||
| 	local armor_texture = "blank.png" | ||||
| @@ -114,23 +161,12 @@ function skin_class:apply_skin_to_player(player) | ||||
| 		end | ||||
| 	end | ||||
|  | ||||
| 	if minetest.global_exists("player_api") then | ||||
| 		-- Minetest-5 compatible | ||||
| 	player_api.set_textures(player, { | ||||
| 			v10_texture, | ||||
| 			v18_texture, | ||||
| 			armor_texture, | ||||
| 			wielditem_texture, | ||||
| 		}) | ||||
| 	else | ||||
| 		-- Minetest-0.4 compatible | ||||
| 		default.player_set_textures(player, { | ||||
| 				v10_texture, | ||||
| 				v18_texture, | ||||
| 				armor_texture, | ||||
| 				wielditem_texture, | ||||
| 			}) | ||||
| 	end | ||||
|  | ||||
| 	player:set_properties({ | ||||
| 		visual_size = { | ||||
| @@ -149,5 +185,6 @@ end | ||||
| function skin_class:is_applicable_for_player(playername) | ||||
| 	local assigned_player = self:get_meta("playername") | ||||
| 	return assigned_player == nil or assigned_player == true or | ||||
| 			(assigned_player:lower() == playername:lower()) | ||||
|  			playername and (minetest.check_player_privs(playername, {server=true}) or | ||||
| 			assigned_player:lower() == playername:lower()) | ||||
| end | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| local skins_dir_list = minetest.get_dir_list(skins.modpath.."/textures") | ||||
|  | ||||
| for _, fn in pairs(skins_dir_list) do | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| -- Skins update script | ||||
|  | ||||
| local S = skins.S | ||||
| local S = minetest.get_translator("skinsdb") | ||||
| local _ID_ = "Lua Skins Updater" | ||||
|  | ||||
| local internal = {} | ||||
| @@ -75,7 +75,7 @@ end | ||||
|  | ||||
| -- Insecure workaround since meta/ and textures/ cannot be written to | ||||
| local function unsafe_file_write(path, contents) | ||||
| 	local f = ie.io.open(path, "w") | ||||
| 	local f = ie.io.open(path, "wb") | ||||
| 	f:write(contents) | ||||
| 	f:close() | ||||
| end | ||||
|   | ||||
| Before Width: | Height: | Size: 1.6 KiB | 
| Before Width: | Height: | Size: 604 B | 
| Before Width: | Height: | Size: 673 B | 
| @@ -7,6 +7,7 @@ One or multiple private skins for player "nick": | ||||
| 	player_[nick].png or | ||||
| 	player_[nick]_[number-or-name].png | ||||
|  | ||||
| Preview files for public and private skins: | ||||
| Preview files for public and private skins. | ||||
| Optional, overrides the generated preview | ||||
| 	character_*_preview.png or | ||||
| 	player_*_*_preview.png | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								textures/skindb_mask_chest.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 114 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/skindb_mask_head.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 139 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/skindb_mask_rarm.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 118 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/skindb_mask_rleg.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 118 B | 
							
								
								
									
										
											BIN
										
									
								
								textures/skindb_transform.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 191 B | 
| Before Width: | Height: | Size: 309 B After Width: | Height: | Size: 250 B | 
| Before Width: | Height: | Size: 5.3 KiB | 
| @@ -1,10 +1,13 @@ | ||||
| local S = skins.S | ||||
| local S = minetest.get_translator("skinsdb") | ||||
|  | ||||
| unified_inventory.register_page("skins", { | ||||
| 	get_formspec = function(player) | ||||
| 	get_formspec = function(player, perplayer_formspec) | ||||
| 		local skin = skins.get_player_skin(player) | ||||
| 		local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]"..skins.get_skin_info_formspec(skin).. | ||||
| 				"button[.75,3;6.5,.5;skins_page;"..S("Change").."]" | ||||
| 		local boffs = (type(perplayer_formspec) == "table") and 2 or 0.75 | ||||
|  | ||||
| 		local formspec = perplayer_formspec.standard_inv_bg.. | ||||
| 			skins.get_skin_info_formspec(skin, perplayer_formspec).. | ||||
| 			"button["..boffs..",3;6.5,.5;skins_page;"..S("Change").."]" | ||||
| 		return {formspec=formspec} | ||||
| 	end, | ||||
| }) | ||||
| @@ -12,18 +15,19 @@ unified_inventory.register_page("skins", { | ||||
| unified_inventory.register_button("skins", { | ||||
| 	type = "image", | ||||
| 	image = "skins_button.png", | ||||
| 	tooltip = S("Skins"), | ||||
| }) | ||||
|  | ||||
| local function get_formspec(player) | ||||
| local function get_formspec(player, perplayer_formspec) | ||||
| 	local context = skins.get_formspec_context(player) | ||||
| 	local formspec = "background[0.06,0.99;7.92,7.52;ui_misc_form.png]".. | ||||
| 			skins.get_skin_selection_formspec(player, context, -0.2) | ||||
| 	local formspec = perplayer_formspec.standard_inv_bg.. | ||||
| 			skins.get_skin_selection_formspec(player, context, perplayer_formspec) | ||||
| 	return formspec | ||||
| end | ||||
|  | ||||
| unified_inventory.register_page("skins_page", { | ||||
| 	get_formspec = function(player) | ||||
| 		return {formspec=get_formspec(player)} | ||||
| 	get_formspec = function(player, perplayer_formspec) | ||||
| 		return {formspec=get_formspec(player, perplayer_formspec)} | ||||
| 	end | ||||
| }) | ||||
|  | ||||
|   | ||||
							
								
								
									
										54
									
								
								updater/update_skins.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,54 @@ | ||||
| import sys, requests, base64 | ||||
|  | ||||
| download_preview = ( len (sys.argv) > 1 and sys.argv[1] == "with_preview" ) | ||||
|  | ||||
|  | ||||
| print("Downloading skins from minetest.fensta.bplaced.net ...") | ||||
| # Requesting all skins and their raw texture using the API | ||||
| r = requests.get('http://minetest.fensta.bplaced.net/api/v2/get.json.php?getlist&page=1&per_page=999999999') | ||||
|  | ||||
| if r.status_code != 200: | ||||
|     sys.exit("Request failed!") | ||||
|  | ||||
| data = r.json() | ||||
| count = 0 | ||||
|  | ||||
| if download_preview: | ||||
|     print("Writing to file and downloading previews ...") | ||||
| else: | ||||
|     print("Writing skins") | ||||
|  | ||||
|  | ||||
| for json in data["skins"]: | ||||
|     id = str(json["id"]) | ||||
|  | ||||
|     # Texture file | ||||
|     raw_data = base64.b64decode(json["img"]) | ||||
|     file = open("../textures/character_" + id + ".png", "wb") | ||||
|     file.write(bytearray(raw_data)) | ||||
|     file.close() | ||||
|  | ||||
|     # Meta file | ||||
|     name = str(json["name"]) | ||||
|     author = str(json["author"]) | ||||
|     license = str(json["license"]) | ||||
|     file = open("../meta/character_" + id + ".txt", "w") | ||||
|     file.write(name + "\n" + author + "\n" + license + "\n") | ||||
|     file.close() | ||||
|     print("Added #%s Name: %s Author: %s License: %s" % (id, name, author, license)) | ||||
|     count += 1 | ||||
|  | ||||
|     if download_preview: | ||||
|         # Downloading the preview of the skin | ||||
|         r2 = requests.get('http://minetest.fensta.bplaced.net/skins/1/' + id + ".png") | ||||
|         if r2.status_code == 200: | ||||
|             # Preview file | ||||
|             preview = r2.content | ||||
|             file = open("../textures/character_" + id + "_preview.png", "wb") | ||||
|             file.write(bytearray(preview)) | ||||
|             file.close() | ||||
|         else: | ||||
|             print("Failed to download skin preview #" + id) | ||||
|  | ||||
|  | ||||
| print("Fetched " + str(count) + " skins!") | ||||