mirror of
https://github.com/minetest/minetest.git
synced 2024-08-19 04:54:18 +02:00
Notify users to reinstall MTG if worlds exist (#13850)
This commit is contained in:
parent
26bb397852
commit
d05da513be
@ -38,8 +38,18 @@ local dialog_metatable = {
|
|||||||
handle_events = function(self,event)
|
handle_events = function(self,event)
|
||||||
if not self.hidden then return self.eventhandler(self,event) end
|
if not self.hidden then return self.eventhandler(self,event) end
|
||||||
end,
|
end,
|
||||||
hide = function(self) self.hidden = true end,
|
hide = function(self)
|
||||||
show = function(self) self.hidden = false end,
|
if not self.hidden then
|
||||||
|
self.hidden = true
|
||||||
|
self.eventhandler(self, "DialogHide")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
show = function(self)
|
||||||
|
if self.hidden then
|
||||||
|
self.hidden = false
|
||||||
|
self.eventhandler(self, "DialogShow")
|
||||||
|
end
|
||||||
|
end,
|
||||||
delete = function(self)
|
delete = function(self)
|
||||||
if self.parent ~= nil then
|
if self.parent ~= nil then
|
||||||
self.parent:show()
|
self.parent:show()
|
||||||
|
@ -56,6 +56,9 @@ local filter_types_titles = {
|
|||||||
fgettext("Texture packs"),
|
fgettext("Texture packs"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Automatic package installation
|
||||||
|
local auto_install_spec = nil
|
||||||
|
|
||||||
local number_downloading = 0
|
local number_downloading = 0
|
||||||
local download_queue = {}
|
local download_queue = {}
|
||||||
|
|
||||||
@ -532,6 +535,47 @@ function confirm_overwrite.create(package, callback)
|
|||||||
nil)
|
nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function install_or_update_package(this, package)
|
||||||
|
local install_parent
|
||||||
|
if package.type == "mod" then
|
||||||
|
install_parent = core.get_modpath()
|
||||||
|
elseif package.type == "game" then
|
||||||
|
install_parent = core.get_gamepath()
|
||||||
|
elseif package.type == "txp" then
|
||||||
|
install_parent = core.get_texturepath()
|
||||||
|
else
|
||||||
|
error("Unknown package type: " .. package.type)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function on_confirm()
|
||||||
|
local deps = get_raw_dependencies(package)
|
||||||
|
if deps and has_hard_deps(deps) then
|
||||||
|
local dlg = install_dialog.create(package, deps)
|
||||||
|
dlg:set_parent(this)
|
||||||
|
this:hide()
|
||||||
|
dlg:show()
|
||||||
|
else
|
||||||
|
queue_download(package, package.path and REASON_UPDATE or REASON_NEW)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if package.type == "mod" and #pkgmgr.games == 0 then
|
||||||
|
local dlg = messagebox("install_game",
|
||||||
|
fgettext("You need to install a game before you can install a mod"))
|
||||||
|
dlg:set_parent(this)
|
||||||
|
this:hide()
|
||||||
|
dlg:show()
|
||||||
|
elseif not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then
|
||||||
|
local dlg = confirm_overwrite.create(package, on_confirm)
|
||||||
|
dlg:set_parent(this)
|
||||||
|
this:hide()
|
||||||
|
dlg:show()
|
||||||
|
else
|
||||||
|
on_confirm()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function get_file_extension(path)
|
local function get_file_extension(path)
|
||||||
local parts = path:split(".")
|
local parts = path:split(".")
|
||||||
@ -644,6 +688,59 @@ local function sort_and_filter_pkgs()
|
|||||||
store.filter_packages(search_string)
|
store.filter_packages(search_string)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Resolves the package specification stored in auto_install_spec into an actual package.
|
||||||
|
-- May only be called after the package list has been loaded successfully.
|
||||||
|
local function resolve_auto_install_spec()
|
||||||
|
assert(store.load_ok)
|
||||||
|
|
||||||
|
if not auto_install_spec then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local resolved = nil
|
||||||
|
|
||||||
|
for _, pkg in ipairs(store.packages_full_unordered) do
|
||||||
|
if pkg.author == auto_install_spec.author and
|
||||||
|
pkg.name == auto_install_spec.name then
|
||||||
|
resolved = pkg
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not resolved then
|
||||||
|
gamedata.errormessage = fgettext("The package $1/$2 was not found.",
|
||||||
|
auto_install_spec.author, auto_install_spec.name)
|
||||||
|
ui.update()
|
||||||
|
|
||||||
|
auto_install_spec = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
return resolved
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Installs the package specified by auto_install_spec.
|
||||||
|
-- Only does something if:
|
||||||
|
-- a. The package list has been loaded successfully.
|
||||||
|
-- b. The store dialog is currently visible.
|
||||||
|
local function do_auto_install()
|
||||||
|
if not store.load_ok then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local pkg = resolve_auto_install_spec()
|
||||||
|
if not pkg then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local store_dlg = ui.find_by_name("store")
|
||||||
|
if not store_dlg or store_dlg.hidden then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
install_or_update_package(store_dlg, pkg)
|
||||||
|
auto_install_spec = nil
|
||||||
|
end
|
||||||
|
|
||||||
function store.load()
|
function store.load()
|
||||||
if store.load_ok then
|
if store.load_ok then
|
||||||
sort_and_filter_pkgs()
|
sort_and_filter_pkgs()
|
||||||
@ -658,20 +755,21 @@ function store.load()
|
|||||||
{ urlencode = urlencode },
|
{ urlencode = urlencode },
|
||||||
function(result)
|
function(result)
|
||||||
if result then
|
if result then
|
||||||
|
store.load_ok = true
|
||||||
|
store.load_error = false
|
||||||
store.packages = result.packages
|
store.packages = result.packages
|
||||||
store.packages_full = result.packages
|
store.packages_full = result.packages
|
||||||
store.packages_full_unordered = result.packages
|
store.packages_full_unordered = result.packages
|
||||||
store.aliases = result.aliases
|
store.aliases = result.aliases
|
||||||
sort_and_filter_pkgs()
|
|
||||||
|
|
||||||
store.load_ok = true
|
sort_and_filter_pkgs()
|
||||||
store.load_error = false
|
do_auto_install()
|
||||||
else
|
else
|
||||||
store.load_error = true
|
store.load_error = true
|
||||||
end
|
end
|
||||||
|
|
||||||
store.loading = false
|
store.loading = false
|
||||||
core.event_handler("Refresh")
|
ui.update()
|
||||||
end
|
end
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@ -725,11 +823,12 @@ end
|
|||||||
function store.sort_packages()
|
function store.sort_packages()
|
||||||
local ret = {}
|
local ret = {}
|
||||||
|
|
||||||
|
local auto_install_pkg = resolve_auto_install_spec() -- can be nil
|
||||||
|
|
||||||
-- Add installed content
|
-- Add installed content
|
||||||
for i=1, #store.packages_full_unordered do
|
for _, pkg in ipairs(store.packages_full_unordered) do
|
||||||
local package = store.packages_full_unordered[i]
|
if pkg.path and pkg ~= auto_install_pkg then
|
||||||
if package.path then
|
ret[#ret + 1] = pkg
|
||||||
ret[#ret + 1] = package
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -747,13 +846,17 @@ function store.sort_packages()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
-- Add uninstalled content
|
-- Add uninstalled content
|
||||||
for i=1, #store.packages_full_unordered do
|
for _, pkg in ipairs(store.packages_full_unordered) do
|
||||||
local package = store.packages_full_unordered[i]
|
if not pkg.path and pkg ~= auto_install_pkg then
|
||||||
if not package.path then
|
ret[#ret + 1] = pkg
|
||||||
ret[#ret + 1] = package
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Put the package that will be auto-installed at the very top
|
||||||
|
if auto_install_pkg then
|
||||||
|
table.insert(ret, 1, auto_install_pkg)
|
||||||
|
end
|
||||||
|
|
||||||
store.packages_full = ret
|
store.packages_full = ret
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1048,45 +1151,7 @@ function store.handle_submit(this, fields)
|
|||||||
assert(package)
|
assert(package)
|
||||||
|
|
||||||
if fields["install_" .. i] then
|
if fields["install_" .. i] then
|
||||||
local install_parent
|
install_or_update_package(this, package)
|
||||||
if package.type == "mod" then
|
|
||||||
install_parent = core.get_modpath()
|
|
||||||
elseif package.type == "game" then
|
|
||||||
install_parent = core.get_gamepath()
|
|
||||||
elseif package.type == "txp" then
|
|
||||||
install_parent = core.get_texturepath()
|
|
||||||
else
|
|
||||||
error("Unknown package type: " .. package.type)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function on_confirm()
|
|
||||||
local deps = get_raw_dependencies(package)
|
|
||||||
if deps and has_hard_deps(deps) then
|
|
||||||
local dlg = install_dialog.create(package, deps)
|
|
||||||
dlg:set_parent(this)
|
|
||||||
this:hide()
|
|
||||||
dlg:show()
|
|
||||||
else
|
|
||||||
queue_download(package, package.path and REASON_UPDATE or REASON_NEW)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if package.type == "mod" and #pkgmgr.games == 0 then
|
|
||||||
local dlg = messagebox("install_game",
|
|
||||||
fgettext("You need to install a game before you can install a mod"))
|
|
||||||
dlg:set_parent(this)
|
|
||||||
this:hide()
|
|
||||||
dlg:show()
|
|
||||||
elseif not package.path and core.is_dir(install_parent .. DIR_DELIM .. package.name) then
|
|
||||||
local dlg = confirm_overwrite.create(package, on_confirm)
|
|
||||||
dlg:set_parent(this)
|
|
||||||
this:hide()
|
|
||||||
dlg:show()
|
|
||||||
else
|
|
||||||
on_confirm()
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1110,7 +1175,24 @@ function store.handle_submit(this, fields)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function create_store_dlg(type)
|
function store.handle_events(event)
|
||||||
|
if event == "DialogShow" then
|
||||||
|
-- If the store is already loaded, auto-install packages here.
|
||||||
|
do_auto_install()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Creates a ContentDB dialog.
|
||||||
|
---
|
||||||
|
--- @param type string | nil
|
||||||
|
--- Sets initial package filter. "game", "mod", "txp" or nil (no filter).
|
||||||
|
--- @param install_spec table | nil
|
||||||
|
--- Package specification of the form { author = string, name = string }.
|
||||||
|
--- Sets package to install or update automatically.
|
||||||
|
function create_store_dlg(type, install_spec)
|
||||||
search_string = ""
|
search_string = ""
|
||||||
cur_page = 1
|
cur_page = 1
|
||||||
if type then
|
if type then
|
||||||
@ -1125,10 +1207,15 @@ function create_store_dlg(type)
|
|||||||
filter_type = 1
|
filter_type = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Keep the old auto_install_spec if the caller doesn't specify one.
|
||||||
|
if install_spec then
|
||||||
|
auto_install_spec = install_spec
|
||||||
|
end
|
||||||
|
|
||||||
store.load()
|
store.load()
|
||||||
|
|
||||||
return dialog_create("store",
|
return dialog_create("store",
|
||||||
store.get_formspec,
|
store.get_formspec,
|
||||||
store.handle_submit,
|
store.handle_submit,
|
||||||
nil)
|
store.handle_events)
|
||||||
end
|
end
|
||||||
|
114
builtin/mainmenu/dlg_reinstall_mtg.lua
Normal file
114
builtin/mainmenu/dlg_reinstall_mtg.lua
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
--Minetest
|
||||||
|
--Copyright (C) 2023 Gregor Parzefall
|
||||||
|
--
|
||||||
|
--This program is free software; you can redistribute it and/or modify
|
||||||
|
--it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
--the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
--(at your option) any later version.
|
||||||
|
--
|
||||||
|
--This program is distributed in the hope that it will be useful,
|
||||||
|
--but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
--MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
--GNU Lesser General Public License for more details.
|
||||||
|
--
|
||||||
|
--You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
--with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
--51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
function check_reinstall_mtg()
|
||||||
|
if core.settings:get_bool("no_mtg_notification") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local games = core.get_games()
|
||||||
|
for _, game in ipairs(games) do
|
||||||
|
if game.id == "minetest" then
|
||||||
|
core.settings:set_bool("no_mtg_notification", true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local mtg_world_found = false
|
||||||
|
local worlds = core.get_worlds()
|
||||||
|
for _, world in ipairs(worlds) do
|
||||||
|
if world.gameid == "minetest" then
|
||||||
|
mtg_world_found = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not mtg_world_found then
|
||||||
|
core.settings:set_bool("no_mtg_notification", true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
mm_game_theme.reset()
|
||||||
|
|
||||||
|
local maintab = ui.find_by_name("maintab")
|
||||||
|
|
||||||
|
local dlg = create_reinstall_mtg_dlg()
|
||||||
|
dlg:set_parent(maintab)
|
||||||
|
maintab:hide()
|
||||||
|
dlg:show()
|
||||||
|
ui.update()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_formspec(dialogdata)
|
||||||
|
local markup = table.concat({
|
||||||
|
"<big>", fgettext("Minetest Game is no longer installed by default"), "</big>\n",
|
||||||
|
fgettext("For a long time, the Minetest engine shipped with a default game called \"Minetest Game\". " ..
|
||||||
|
"Since Minetest 5.8.0, Minetest ships without a default game."), "\n",
|
||||||
|
fgettext("If you want to continue playing in your Minetest Game worlds, you need to reinstall Minetest Game."),
|
||||||
|
})
|
||||||
|
|
||||||
|
return table.concat({
|
||||||
|
"formspec_version[6]",
|
||||||
|
"size[12.8,7]",
|
||||||
|
"hypertext[0.375,0.375;12.05,5.2;text;", minetest.formspec_escape(markup), "]",
|
||||||
|
"container[0.375,5.825]",
|
||||||
|
"style[dismiss;bgcolor=red]",
|
||||||
|
"button[0,0;4,0.8;dismiss;", fgettext("Dismiss"), "]",
|
||||||
|
"button[4.25,0;8,0.8;reinstall;", fgettext("Reinstall Minetest Game"), "]",
|
||||||
|
"container_end[]",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function buttonhandler(this, fields)
|
||||||
|
if fields.reinstall then
|
||||||
|
-- Don't set "no_mtg_notification" here so that the dialog will be shown
|
||||||
|
-- again if downloading MTG fails for whatever reason.
|
||||||
|
this:delete()
|
||||||
|
|
||||||
|
local maintab = ui.find_by_name("maintab")
|
||||||
|
|
||||||
|
local dlg = create_store_dlg(nil, { author = "Minetest", name = "minetest_game" })
|
||||||
|
dlg:set_parent(maintab)
|
||||||
|
maintab:hide()
|
||||||
|
dlg:show()
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.dismiss then
|
||||||
|
core.settings:set_bool("no_mtg_notification", true)
|
||||||
|
this:delete()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function eventhandler(event)
|
||||||
|
if event == "MenuQuit" then
|
||||||
|
-- Don't allow closing the dialog with ESC, but still allow exiting
|
||||||
|
-- Minetest.
|
||||||
|
core.close()
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function create_reinstall_mtg_dlg()
|
||||||
|
local dlg = dialog_create("dlg_reinstall_mtg", get_formspec,
|
||||||
|
buttonhandler, eventhandler)
|
||||||
|
return dlg
|
||||||
|
end
|
||||||
|
|
||||||
|
|
@ -50,6 +50,7 @@ dofile(menupath .. DIR_DELIM .. "dlg_delete_world.lua")
|
|||||||
dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
|
dofile(menupath .. DIR_DELIM .. "dlg_register.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
dofile(menupath .. DIR_DELIM .. "dlg_rename_modpack.lua")
|
||||||
dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua")
|
dofile(menupath .. DIR_DELIM .. "dlg_version_info.lua")
|
||||||
|
dofile(menupath .. DIR_DELIM .. "dlg_reinstall_mtg.lua")
|
||||||
|
|
||||||
local tabs = {
|
local tabs = {
|
||||||
content = dofile(menupath .. DIR_DELIM .. "tab_content.lua"),
|
content = dofile(menupath .. DIR_DELIM .. "tab_content.lua"),
|
||||||
@ -121,9 +122,11 @@ local function init_globals()
|
|||||||
})
|
})
|
||||||
|
|
||||||
ui.set_default("maintab")
|
ui.set_default("maintab")
|
||||||
check_new_version()
|
|
||||||
tv_main:show()
|
tv_main:show()
|
||||||
ui.update()
|
ui.update()
|
||||||
|
|
||||||
|
check_reinstall_mtg()
|
||||||
|
check_new_version()
|
||||||
end
|
end
|
||||||
|
|
||||||
init_globals()
|
init_globals()
|
||||||
|
@ -2250,6 +2250,10 @@ update_last_checked (Last update check) string
|
|||||||
# Ex: 5.5.0 is 005005000
|
# Ex: 5.5.0 is 005005000
|
||||||
update_last_known (Last known version update) int 0
|
update_last_known (Last known version update) int 0
|
||||||
|
|
||||||
|
# If this is set to true, the user will never (again) be shown the
|
||||||
|
# "reinstall Minetest Game" notification.
|
||||||
|
no_mtg_notification (Don't show "reinstall Minetest Game" notification) bool false
|
||||||
|
|
||||||
# Key for moving the player forward.
|
# Key for moving the player forward.
|
||||||
keymap_forward (Forward key) key KEY_KEY_W
|
keymap_forward (Forward key) key KEY_KEY_W
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user