Make supplying empty formspec strings close the formspec (#4737)
authororwell96 <mono96.mml@gmail.com>
Tue, 22 Nov 2016 16:15:22 +0000 (17:15 +0100)
committerZeno- <kde.psych@gmail.com>
Tue, 22 Nov 2016 16:15:22 +0000 (02:15 +1000)
This will only happen if the formname matches or if formname is "".

builtin/game/misc.lua
doc/lua_api.txt
src/game.cpp
src/server.cpp

index 1333a75ba21edf6c6b3b1e145229cfdfdb1a61af..040016333286d0f8147c68692d5623ea28d8554f 100644 (file)
@@ -239,3 +239,7 @@ else
 
 end
 
+function core.close_formspec(player_name, formname)
+       return minetest.show_formspec(player_name, formname, "")
+end
+
index 80e66020dfaf7bf97f9bcd320cdb6391ff572a9e..760a829d330d05803b19472b823ba64ab7672f17 100644 (file)
@@ -2316,6 +2316,13 @@ and `minetest.auth_reload` call the authetification handler.
     * `formname`: name passed to `on_player_receive_fields` callbacks.
       It should follow the `"modname:<whatever>"` naming convention
     * `formspec`: formspec to display
+* `minetest.close_formspec(playername, formname)`
+    * `playername`: name of player to close formspec
+    * `formname`: has to exactly match the one given in show_formspec, or the formspec will
+       not close.
+    * calling show_formspec(playername, formname, "") is equal to this expression
+    * to close a formspec regardless of the formname, call 
+      minetest.close_formspec(playername, ""). USE THIS ONLY WHEN ABSOLUTELY NECESSARY!
 * `minetest.formspec_escape(string)`: returns a string
     * escapes the characters "[", "]", "\", "," and ";", which can not be used in formspecs
 * `minetest.explode_table_event(string)`: returns a table
index 16287fe0d807c44ce25d171c0b8e8305da792c1f..6716823482a3e51e43ad29980709f274895eff4d 100644 (file)
@@ -1205,6 +1205,7 @@ static inline void create_formspec_menu(GUIFormSpecMenu **cur_formspec,
                (*cur_formspec)->setFormSource(fs_src);
                (*cur_formspec)->setTextDest(txt_dest);
        }
+       
 }
 
 #ifdef __ANDROID__
@@ -1753,6 +1754,8 @@ private:
        ChatBackend *chat_backend;
 
        GUIFormSpecMenu *current_formspec;
+       //default: "". If other than "", empty show_formspec packets will only close the formspec when the formname matches
+       std::string cur_formname;
 
        EventManager *eventmgr;
        QuicktuneShortcutter *quicktune;
@@ -1841,6 +1844,7 @@ Game::Game() :
        soundmaker(NULL),
        chat_backend(NULL),
        current_formspec(NULL),
+       cur_formname(""),
        eventmgr(NULL),
        quicktune(NULL),
        gui_chat_console(NULL),
@@ -3005,6 +3009,7 @@ void Game::openInventory()
 
        create_formspec_menu(&current_formspec, client, gamedef, texture_src,
                        device, &input->joystick, fs_src, txt_dst, client);
+       cur_formname = "";
 
        InventoryLocation inventoryloc;
        inventoryloc.setCurrentPlayer();
@@ -3484,14 +3489,21 @@ void Game::processClientEvents(CameraOrientation *cam, float *damage_flash)
                        player->hurt_tilt_strength = 0;
 
                } else if (event.type == CE_SHOW_FORMSPEC) {
-                       FormspecFormSource *fs_src =
-                               new FormspecFormSource(*(event.show_formspec.formspec));
-                       TextDestPlayerInventory *txt_dst =
-                               new TextDestPlayerInventory(client, *(event.show_formspec.formname));
-
-                       create_formspec_menu(&current_formspec, client, gamedef,
-                               texture_src, device, &input->joystick,
-                               fs_src, txt_dst, client);
+                       if (*(event.show_formspec.formspec) == "") {
+                               if (current_formspec && ( *(event.show_formspec.formname) == "" || *(event.show_formspec.formname) == cur_formname) ){
+                                       current_formspec->quitMenu();
+                               }
+                       } else {
+                               FormspecFormSource *fs_src =
+                                       new FormspecFormSource(*(event.show_formspec.formspec));
+                               TextDestPlayerInventory *txt_dst =
+                                       new TextDestPlayerInventory(client, *(event.show_formspec.formname));
+
+                               create_formspec_menu(&current_formspec, client, gamedef,
+                                       texture_src, device, &input->joystick,
+                                       fs_src, txt_dst, client);
+                               cur_formname = *(event.show_formspec.formname);
+                       }
 
                        delete(event.show_formspec.formspec);
                        delete(event.show_formspec.formname);
@@ -3955,6 +3967,7 @@ void Game::handlePointingAtNode(GameRunData *runData,
 
                        create_formspec_menu(&current_formspec, client, gamedef,
                                texture_src, device, &input->joystick, fs_src, txt_dst, client);
+                       cur_formname = "";
 
                        current_formspec->setFormSpec(meta->getString("formspec"), inventoryloc);
                } else {
index 48331e4f84b2dad4eaf56c6815d6319468b224e9..fae375425888ea87e45644f1ce877f52f96a4cdb 100644 (file)
@@ -1647,8 +1647,12 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
        DSTACK(FUNCTION_NAME);
 
        NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0 , peer_id);
-
-       pkt.putLongString(FORMSPEC_VERSION_STRING + formspec);
+       if (formspec == "" ){
+               //the client should close the formspec
+               pkt.putLongString("");
+       } else {
+               pkt.putLongString(FORMSPEC_VERSION_STRING + formspec);
+       }
        pkt << formname;
 
        Send(&pkt);