From a945db9de33e803489ba0243d7da50b5112f8c4a Mon Sep 17 00:00:00 2001 From: SmallJoker Date: Mon, 10 Jun 2019 21:28:35 +0200 Subject: [PATCH] Add skins updater chat command (#29) * Add skins updater chat command * Update docs --- README.md | 9 +++--- init.lua | 4 +-- skins_updater.lua | 72 ++++++++++++++++++++++++++++++++++------------- 3 files changed, 58 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5eae6cc..ad6a4b2 100644 --- a/README.md +++ b/README.md @@ -21,11 +21,10 @@ This Minetest mod offers changeable player skins with a graphical interface for ### Download from the database 1) Get Minetest 5.1.0-dev-cb00632 or newer -2) Uncomment the lines in `init.lua` mentioning `skins_updater.lua` -3) Start your world and wait until it reports that the skins were downloaded. -4) Let the Minetest server shut down -5) Comment the lines in `init.lua` again -6) Start the server again +2) Start your world +3) Run `/skinsdb_download_skins ` +4) Wait for the Minetest server to shut down +5) Start the server again You might want to run `minetest` in a Terminal/Console window to check the log output instantly. diff --git a/init.lua b/init.lua index afa0aa6..2e1cea4 100644 --- a/init.lua +++ b/init.lua @@ -31,11 +31,11 @@ if minetest.get_modpath("sfinv") then end -- ie.loadfile does not exist? ---[[skins.ie = minetest.request_insecure_environment() +skins.ie = minetest.request_insecure_environment() skins.http = minetest.request_http_api() dofile(skins.modpath.."/skins_updater.lua") skins.ie = nil -skins.http = nil]] +skins.http = nil -- 3d_armor compatibility if minetest.global_exists("armor") then diff --git a/skins_updater.lua b/skins_updater.lua index 1b0f039..16f6253 100644 --- a/skins_updater.lua +++ b/skins_updater.lua @@ -1,18 +1,49 @@ -- Skins update script --- Load it in init.lua or write a frontend GUI/chatcommand for it. Good luck. +local S = skins.S local _ID_ = "Lua Skins Updater" -local _SKIN_PAGE_START_ = 1 -- Starting page to fetch the skins -local _SKIN_PAGE_END_ = nil -- End page number (nil = all skins) +local internal = {} +internal.errors = {} + +-- Binary downloads are required if not core.features.httpfetch_binary_data then - error(_ID_ .. " requires the feature 'httpfetch_binary_data'. Update Minetest.") + internal.errors[#internal.errors + 1] = + "Feature 'httpfetch_binary_data' is missing. Update Minetest." end +-- Insecure environment for saving textures and meta local ie, http = skins.ie, skins.http if not ie or not http then - error(_ID_ .. " requires the insecure environment. " .. - "Please add skinsdb to `secure.trusted_mods` in minetest.conf") + internal.errors[#internal.errors + 1] = "Insecure environment is required. " .. + "Please add skinsdb to `secure.trusted_mods` in minetest.conf" +end + +minetest.register_chatcommand("skinsdb_download_skins", { + params = " ", + description = S("Downloads the specified range of skins and shuts down the server"), + privs = {server=true}, + func = function(name, param) + if #internal.errors > 0 then + return false, "Cannot run " .. _ID_ .. ":\n\t" .. + table.concat(internal.errors, "\n\t") + end + + local parts = string.split(param, " ") + local start = tonumber(parts[1]) + local len = tonumber(parts[2]) + if not (start and len and len > 0) then + return false, "Invalid page number or amount of pages" + end + + internal.get_pages_count(internal.fetch_function, start, len) + return true, "Started downloading..." + end, +}) + + +if #internal.errors > 0 then + return -- Nonsense to load something that's not working end -- http://minetest.fensta.bplaced.net/api/apidoku.md @@ -76,20 +107,21 @@ local function safe_single_skin(skin) end -- Get total pages since it'll just return the last page all over again -local function get_pages_count(callback) - fetch_url(page_url:format(1) .. "&per_page=5", function(data) +internal.get_pages_count = function(callback, ...) + local vars = {...} + fetch_url(page_url:format(1) .. "&per_page=1", function(data) local list = core.parse_json(data) - print(dump(list)) - callback(list.pages) + -- "per_page" defaults to 20 if left away (docs say something else, though) + callback(math.ceil(list.pages / 20), unpack(vars)) end) end --- Just fetch them all. YOLO -get_pages_count(function(pages_total) - local start_page = _SKIN_PAGE_START_ or 1 - local end_page = math.min(pages_total, _SKIN_PAGE_END_ or pages_total) +-- Function to fetch a range of pages +internal.fetch_function = function(pages_total, start_page, len) + start_page = math.max(start_page, 1) + local end_page = math.min(start_page + len - 1, pages_total) - for page_n = 1, end_page do + for page_n = start_page, end_page do local page_cpy = page_n fetch_url(page_url:format(page_n), function(data) core.log("action", ("%s: Page %i"):format(_ID_, page_cpy)) @@ -105,11 +137,11 @@ get_pages_count(function(pages_total) end if page_cpy == end_page then - core.log("action", _ID_ .. " finished downloading all skins. " .. - "Please comment out this script to reduce server traffic.") - core.request_shutdown("Reloading skinsdb media cache after download", - true, 3 --[[give some time for pending requests]]) + local log = _ID_ .. " finished downloading all skins. " .. + "Shutting down server to reload media cache" + core.log("action", log) + core.request_shutdown(log, true, 3 --[[give some time for pending requests]]) end end) end -end) \ No newline at end of file +end