Formspecs: Close on metadata removal (#8348)

Formspecs will now close as soon the formspec string in the node metadata turns invalid.
This commit is contained in:
SmallJoker 2019-06-10 13:01:07 +02:00 committed by GitHub
parent e40be619f2
commit e2f8f4da83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 85 additions and 39 deletions

@ -827,10 +827,6 @@ private:
ChatBackend *chat_backend = nullptr; ChatBackend *chat_backend = nullptr;
GUIFormSpecMenu *current_formspec = nullptr;
//default: "". If other than "", empty show_formspec packets will only close the formspec when the formname matches
std::string cur_formname;
EventManager *eventmgr = nullptr; EventManager *eventmgr = nullptr;
QuicktuneShortcutter *quicktune = nullptr; QuicktuneShortcutter *quicktune = nullptr;
bool registration_confirmation_shown = false; bool registration_confirmation_shown = false;
@ -1143,8 +1139,9 @@ void Game::shutdown()
driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS); driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
} }
#endif #endif
if (current_formspec) auto formspec = m_game_ui->getFormspecGUI();
current_formspec->quitMenu(); if (formspec)
formspec->quitMenu();
showOverlayMessage(N_("Shutting down..."), 0, 0, false); showOverlayMessage(N_("Shutting down..."), 0, 0, false);
@ -1163,10 +1160,7 @@ void Game::shutdown()
g_menumgr.deletingMenu(g_menumgr.m_stack.front()); g_menumgr.deletingMenu(g_menumgr.m_stack.front());
} }
if (current_formspec) { m_game_ui->deleteFormspec();
current_formspec->drop();
current_formspec = NULL;
}
chat_backend->addMessage(L"", L"# Disconnected."); chat_backend->addMessage(L"", L"# Disconnected.");
chat_backend->addMessage(L"", L""); chat_backend->addMessage(L"", L"");
@ -1853,8 +1847,9 @@ void Game::processUserInput(f32 dtime)
input->step(dtime); input->step(dtime);
#ifdef __ANDROID__ #ifdef __ANDROID__
if (current_formspec != NULL) auto formspec = m_game_ui->getFormspecGUI();
current_formspec->getAndroidUIInput(); if (formspec)
formspec->getAndroidUIInput();
else else
handleAndroidChatInput(); handleAndroidChatInput();
#endif #endif
@ -2050,10 +2045,11 @@ void Game::openInventory()
if (!client->moddingEnabled() if (!client->moddingEnabled()
|| !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) { || !client->getScript()->on_inventory_open(fs_src->m_client->getInventory(inventoryloc))) {
TextDest *txt_dst = new TextDestPlayerInventory(client); TextDest *txt_dst = new TextDestPlayerInventory(client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->updateFormspec("");
GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend()); txt_dst, client->getFormspecPrepend());
cur_formname = "";
current_formspec->setFormSpec(fs_src->getForm(), inventoryloc); formspec->setFormSpec(fs_src->getForm(), inventoryloc);
} }
} }
@ -2581,9 +2577,10 @@ void Game::handleClientEvent_Deathscreen(ClientEvent *event, CameraOrientation *
void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam) void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation *cam)
{ {
if (event->show_formspec.formspec->empty()) { if (event->show_formspec.formspec->empty()) {
if (current_formspec && (event->show_formspec.formname->empty() auto formspec = m_game_ui->getFormspecGUI();
|| *(event->show_formspec.formname) == cur_formname)) { if (formspec && (event->show_formspec.formname->empty()
current_formspec->quitMenu(); || *(event->show_formspec.formname) == m_game_ui->getFormspecName())) {
formspec->quitMenu();
} }
} else { } else {
FormspecFormSource *fs_src = FormspecFormSource *fs_src =
@ -2591,9 +2588,9 @@ void Game::handleClientEvent_ShowFormSpec(ClientEvent *event, CameraOrientation
TextDestPlayerInventory *txt_dst = TextDestPlayerInventory *txt_dst =
new TextDestPlayerInventory(client, *(event->show_formspec.formname)); new TextDestPlayerInventory(client, *(event->show_formspec.formname));
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, auto *&formspec = m_game_ui->updateFormspec(*(event->show_formspec.formname));
GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
cur_formname = *(event->show_formspec.formname);
} }
delete event->show_formspec.formspec; delete event->show_formspec.formspec;
@ -2605,7 +2602,7 @@ void Game::handleClientEvent_ShowLocalFormSpec(ClientEvent *event, CameraOrienta
FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec); FormspecFormSource *fs_src = new FormspecFormSource(*event->show_formspec.formspec);
LocalFormspecHandler *txt_dst = LocalFormspecHandler *txt_dst =
new LocalFormspecHandler(*event->show_formspec.formname, client); new LocalFormspecHandler(*event->show_formspec.formname, client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, GUIFormSpecMenu::create(m_game_ui->getFormspecGUI(), client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
delete event->show_formspec.formspec; delete event->show_formspec.formspec;
@ -3272,11 +3269,11 @@ void Game::handlePointingAtNode(const PointedThing &pointed,
&client->getEnv().getClientMap(), nodepos); &client->getEnv().getClientMap(), nodepos);
TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client); TextDest *txt_dst = new TextDestNodeMetadata(nodepos, client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->updateFormspec("");
GUIFormSpecMenu::create(formspec, client, &input->joystick, fs_src,
txt_dst, client->getFormspecPrepend()); txt_dst, client->getFormspecPrepend());
cur_formname.clear();
current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc); formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
} else { } else {
// Report right click to server // Report right click to server
@ -3844,15 +3841,29 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
1. Delete formspec menu reference if menu was removed 1. Delete formspec menu reference if menu was removed
2. Else, make sure formspec menu is on top 2. Else, make sure formspec menu is on top
*/ */
if (current_formspec) { auto formspec = m_game_ui->getFormspecGUI();
if (current_formspec->getReferenceCount() == 1) { do { // breakable. only runs for one iteration
current_formspec->drop(); if (!formspec)
current_formspec = NULL; break;
} else if (isMenuActive()) {
guiroot->bringToFront(current_formspec); if (formspec->getReferenceCount() == 1) {
m_game_ui->deleteFormspec();
break;
}
auto &loc = formspec->getFormspecLocation();
if (loc.type == InventoryLocation::NODEMETA) {
NodeMetadata *meta = client->getEnv().getClientMap().getNodeMetadata(loc.p);
if (!meta || meta->getString("formspec").empty()) {
formspec->quitMenu();
break;
} }
} }
if (isMenuActive())
guiroot->bringToFront(formspec);
} while (false);
/* /*
Drawing begins Drawing begins
*/ */
@ -4048,7 +4059,7 @@ void Game::extendedResourceCleanup()
void Game::showDeathFormspec() void Game::showDeathFormspec()
{ {
static std::string formspec = static std::string formspec_str =
std::string(FORMSPEC_VERSION_STRING) + std::string(FORMSPEC_VERSION_STRING) +
SIZE_TAG SIZE_TAG
"bgcolor[#320000b4;true]" "bgcolor[#320000b4;true]"
@ -4059,12 +4070,13 @@ void Game::showDeathFormspec()
/* Create menu */ /* Create menu */
/* Note: FormspecFormSource and LocalFormspecHandler * /* Note: FormspecFormSource and LocalFormspecHandler *
* are deleted by guiFormSpecMenu */ * are deleted by guiFormSpecMenu */
FormspecFormSource *fs_src = new FormspecFormSource(formspec); FormspecFormSource *fs_src = new FormspecFormSource(formspec_str);
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_DEATH_SCREEN", client);
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, fs_src, auto *&formspec = m_game_ui->getFormspecGUI();
txt_dst, client->getFormspecPrepend()); GUIFormSpecMenu::create(formspec, client, &input->joystick,
current_formspec->setFocus("btn_respawn"); fs_src, txt_dst, client->getFormspecPrepend());
formspec->setFocus("btn_respawn");
} }
#define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name()) #define GET_KEY_NAME(KEY) gettext(getKeySetting(#KEY).name())
@ -4188,10 +4200,11 @@ void Game::showPauseMenu()
FormspecFormSource *fs_src = new FormspecFormSource(os.str()); FormspecFormSource *fs_src = new FormspecFormSource(os.str());
LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU"); LocalFormspecHandler *txt_dst = new LocalFormspecHandler("MT_PAUSE_MENU");
GUIFormSpecMenu::create(current_formspec, client, &input->joystick, auto *&formspec = m_game_ui->getFormspecGUI();
GUIFormSpecMenu::create(formspec, client, &input->joystick,
fs_src, txt_dst, client->getFormspecPrepend()); fs_src, txt_dst, client->getFormspecPrepend());
current_formspec->setFocus("btn_continue"); formspec->setFocus("btn_continue");
current_formspec->doPause = true; formspec->doPause = true;
} }
/****************************************************************************/ /****************************************************************************/

@ -302,3 +302,15 @@ void GameUI::toggleProfiler()
showTranslatedStatusText("Profiler hidden"); showTranslatedStatusText("Profiler hidden");
} }
} }
void GameUI::deleteFormspec()
{
if (m_formspec)
m_formspec->quitMenu();
delete m_formspec;
m_formspec = nullptr;
m_formname.clear();
}

@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once #pragma once
#include <IGUIEnvironment.h> #include <IGUIEnvironment.h>
#include "gui/guiFormSpecMenu.h"
#include "util/enriched_string.h" #include "util/enriched_string.h"
#include "util/pointedthing.h" #include "util/pointedthing.h"
#include "game.h" #include "game.h"
@ -88,6 +89,16 @@ public:
void toggleHud(); void toggleHud();
void toggleProfiler(); void toggleProfiler();
GUIFormSpecMenu *&updateFormspec(const std::string &formname)
{
m_formname = formname;
return m_formspec;
}
const std::string &getFormspecName() { return m_formname; }
GUIFormSpecMenu *&getFormspecGUI() { return m_formspec; }
void deleteFormspec();
private: private:
Flags m_flags; Flags m_flags;
@ -107,4 +118,9 @@ private:
gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text gui::IGUIStaticText *m_guitext_profiler = nullptr; // Profiler text
u8 m_profiler_current_page = 0; u8 m_profiler_current_page = 0;
const u8 m_profiler_max_page = 3; const u8 m_profiler_max_page = 3;
// Default: "". If other than "": Empty show_formspec packets will only
// close the formspec when the formname matches
std::string m_formname;
GUIFormSpecMenu *m_formspec = nullptr;
}; };

@ -304,6 +304,11 @@ public:
regenerateGui(m_screensize_old); regenerateGui(m_screensize_old);
} }
const InventoryLocation &getFormspecLocation()
{
return m_current_inventory_location;
}
void setFormspecPrepend(const std::string &formspecPrepend) void setFormspecPrepend(const std::string &formspecPrepend)
{ {
m_formspec_prepend = formspecPrepend; m_formspec_prepend = formspecPrepend;