Compare commits

...

No commits in common. "master" and "v7" have entirely different histories.
master ... v7

5 changed files with 72 additions and 57 deletions

43
.gitignore vendored Normal file
View file

@ -0,0 +1,43 @@
# ---> Lua
# Compiled Lua sources
luac.out
# luarocks build files
*.src.rock
*.zip
*.tar.gz
# Object files
*.o
*.os
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# libskinupload
A Minetest mod that allows players to upload custom skins to a server.

View file

@ -41,17 +41,6 @@ if minetest.get_modpath("u_skins") then
end
end
-- Shim for Nodecore
if minetest.global_exists("nodecore") then
local _player_skin = nodecore.player_skin
function nodecore.player_skin(player, options, ...)
local pname = options and options.playername or player and player:get_player_name()
local skin = pname and libskinupload.get_skin(pname)
return skin or _player_skin(player, options, ...)
end
end
-- Polyfill for older versions
if not minetest.hypertext_escape then
local hypertext_escapes = {
@ -66,7 +55,12 @@ if not minetest.hypertext_escape then
end
local function player_model(p, tx, slim_arms)
return p:get_properties().mesh..";"..tx..",blank.png,blank.png,blank.png"
if mcl then
return (slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d")..";"..tx..",blank.png"
elseif it then
return "player.b3d;"..tx
end
return "character.b3d;"..tx..",blank.png"
end
local db = minetest.get_mod_storage()
@ -92,14 +86,12 @@ else
for _, x in pairs(dl) do
minetest.log("action", "Merging file "..x.."...")
local id = x:match "libskinupload_uploaded_skin_(%d*).json"
if id then
local file = io.open(storage_dir_meta..x)
local data = file:read("a")
file:close()
out = out..(i == 0 and ("\""..id.."\":") or (",\""..id.."\":"))..data
i = i +1
end
end
local f = io.open(meta_file, "w+")
f:write(out.."}")
f:flush()
@ -141,11 +133,9 @@ function libskinupload.add_skin_media(id, fname, cb)
else
meta = libskinupload.get_skin_meta(x)
end
if not meta.p then
mcl_skins.register_simple_skin{texture = x, slim_arms = meta.msa or false}
end
end
end
if not optimize_media then
for _, x in ipairs(minetest.get_dir_list(storage_dir, false)) do
@ -165,6 +155,10 @@ minetest.register_privilege("skin_review", {
give_to_singleplayer = false,
give_to_admin = false
})
minetest.register_privilege("no_skin_upload", {
give_to_singleplayer = false,
give_to_admin = false
})
libskinupload.notifications = minetest.deserialize(db:get_string("notifications")) or {}
libskinupload.reviewers = minetest.deserialize(db:get_string("reviewers")) or {}
@ -225,21 +219,12 @@ minetest.register_on_joinplayer(function(p)
if minetest.check_player_privs(p, {skin_review = true}) then
local newskins = db:get_int("newrequests")
if newskins > 0 then minetest.chat_send_player(p:get_player_name(), minetest.colorize("#579a1e", "[libskinupload] "..newskins.." new skin request"..(newskins == 1 and " has" or "s have").." been submitted. Run /skinreview to see "..(newskins == 1 and "it" or "them")..".")) end
elseif p:get_player_name() == "singleplayer" then
minetest.change_player_privs(p:get_player_name(), {skin_review = true})
end
end)
function libskinupload.can_player_upload_skins(p)
if db:get("upload_permitted:"..p:get_player_name()) == "false" then
return false
end
return true
end
function libskinupload.queue(p, req)
local data = req.data
if not libskinupload.can_player_upload_skins(p) then
if minetest.check_player_privs(p, {no_skin_upload = true}) then
minetest.chat_send_player(p:get_player_name(), "Insufficient permissions.")
return "No permission."
end
@ -368,10 +353,6 @@ local upload_state = {}
function libskinupload.show_upload_dialog(name, args)
if not args or type(args) == "string" then args = {err = ""} end
local p = minetest.get_player_by_name(name)
if not libskinupload.can_player_upload_skins(p) then
minetest.chat_send_player(name, "Insufficient privileges.")
return
end
if not upload_state[name] then upload_state[name] = {} end
local m = upload_state[name]
local size = (minetest.get_player_window_information(name) or {}).max_formspec_size or {x = 20, y = 11.5}
@ -424,11 +405,12 @@ function libskinupload.show_upload_dialog(name, args)
style[help:hovered;bgcolor=#0000;border=false;bgimg=]\
style[help:pressed;bgcolor=#0000;border=false;bgimg=]\
button[0,0;"..size.x..","..size.y..";help;]\
hypertext["..(size.x /4)..","..(size.y /4)..";"..(size.x /2)..","..(size.y /2)..";;<tag name=clr color=#ffbc5b>"..minetest.formspec_escape("To upload a skin, paste the base64-encoded image into the Data field below. This can be obtained from a terminal by running <clr><b>`base64 -i <filepath>`</b></clr> (e.g. <clr><b>`base64 -i ~/Desktop/skins/my_skin.png`</b></clr>) and copying the output. Alternatively, you can use a web tool (search <clr>'base64-encode an image'</clr> or similar). Once a request is sbmitted, it will need to be reviewed. You will be notified when your request is accepted or denied. Note that you can only have one skin request pending approval at a time; if you send another request before the previous one is approved or rejected, the later request will overwrite the previous one.\nIf the preview for the skin you're uploading looks wrong, the image was probably in a layout that won't work with the player model. Usually, this is because you're trying to upload a Minecraft skin, which is incompatible with most Minetest player models. In that case, you can fix it by simply cropping off the bottom 32 pixels of the original 64x64 image and trying again.").."]" or ""))
hypertext["..(size.x /4)..","..(size.y /4)..";"..(size.x /2)..","..(size.y /2)..";;<tag name=clr color=#ffbc5b>"..minetest.formspec_escape("To upload a skin, paste the base64-encoded image into the Data field below. This can be obtained from a terminal by running <clr><b>`base64 -i <filepath>`</b></clr> (e.g. <clr><b>`base64 -i ~/Desktop/skins/my_skin.png`</b></clr>) and copying the output. Alternatively, you can use a web tool (search <clr>'base64-encode an image'</clr> or similar). Once a request is sbmitted, it will need to be reviewed. You will be notified when your request is accepted or denied. Note that you can only have one skin request pending approval at a time; if you send another request before the previous one is approved or rejected, the later request will overwrite the previous one.").."]" or ""))
end
minetest.register_chatcommand("skinupload", {
description = "Show the skin upload dialog.",
func = libskinupload.show_upload_dialog
func = libskinupload.show_upload_dialog,
privs = {no_skin_upload = false}
})
local review_state = {}
@ -781,7 +763,7 @@ minetest.register_chatcommand("skinlimit", {
params = "<name> <limit>",
description = "Set the maximum concurrent skin requests allowed for player <name> to <limit>.",
func = function(name, args)
local pn, num = args:match "([%w_-]+)%s+(%d+)"
local pn, num = args:match "(%w+)%s+(%d+)"
num = tonumber(num)
if pn and pn ~= "" and num and num > 0 then
db:set_int("reqmax:"..pn, num)
@ -814,7 +796,7 @@ end
minetest.register_chatcommand("skinmanage", {
privs = {skin_review = true},
params = "cull | list | meta <id> | grant <name> | revoke <name> | privs <name> | alter <id> <newkey>=<newvalue>[,<newkey2>=<newvalue2>]*",
params = "cull | list | (meta <id>) | alter <id> <newkey>=<newvalue>[,<newkey2>=<newvalue2>]*",
func = function(name, args)
if args == "cull" then
local i = 0
@ -883,17 +865,6 @@ minetest.register_chatcommand("skinmanage", {
elseif args:match "^remove_fragmented_meta" then
minetest.rmdir(storage_dir_meta, true)
minetest.chat_send_player(name, "Removed all fragmented meta.")
elseif args:match "^grant" then
local pname = args:match "grant%s+([%w_-]+)"
db:set_string("upload_permitted:"..pname, "")
minetest.chat_send_player(name, "Granted skin upload privileges to player "..pname..".")
elseif args:match "^revoke" then
local pname = args:match "revoke%s+([%w_-]+)"
db:set_string("upload_permitted:"..pname, "false")
minetest.chat_send_player(name, "Revoked skin upload privileges from player "..pname..".")
elseif args:match "^privs" then
local pname = args:match "privs%s+([%w_-]+)"
minetest.chat_send_player(name, "Player "..pname.." is "..(db:get("upload_permitted:"..pname) == "false" and "not " or "").."allowed to upload skins.")
else
minetest.chat_send_player(name, "Invalid arguments, see /help skinmanage for accepted subcommands.")
end
@ -957,8 +928,7 @@ function libskinupload.get_skin_id(name)
end
function libskinupload.get_skin(name)
local id = db:get("skin:"..name)
return id and "libskinupload_uploaded_skin_"..id..".png"
return "libskinupload_uploaded_skin_"..db:get_string("skin:"..name)..".png"
end
function libskinupload.get_skin_meta(skin)
@ -982,7 +952,6 @@ function libskinupload.get_skin_meta(skin)
else
local res = minetest.parse_json(f:read("a"))
f:close()
if not res then return {n = "Unnamed", d = "Nondescript", c = "<Unknown>"} end
return res[string.gsub(string.sub(skin, string.len("libskinupload_uploaded_skin_."), -1), ".png", "")] or {n = "Unnamed", d = "Nondescript", c = "<Unknown>"}
end
end
@ -1062,7 +1031,7 @@ end
minetest.register_on_player_receive_fields(function(p, name, data)
if name == "libskinupload:upload" then
if not libskinupload.can_player_upload_skins(p) then
if minetest.check_player_privs(p, {no_skin_upload = true}) then
minetest.chat_send_player(p:get_player_name(), "Insufficient permissions.")
minetest.close_formspec(p:get_player_name(), name)
return true

View file

@ -1,2 +1,2 @@
name = libskinupload
optional_depends = unified_inventory, u_skins, mcl_skins, 3d_armor, nc_player_model
optional_depends = unified_inventory, u_skins, mcl_skins, 3d_armor