minetest.register_on_player_receive_fields()
authorPerttu Ahola <celeron55@gmail.com>
Sun, 22 Jul 2012 14:10:58 +0000 (17:10 +0300)
committerPerttu Ahola <celeron55@gmail.com>
Sun, 22 Jul 2012 14:40:48 +0000 (17:40 +0300)
builtin/misc_register.lua
doc/lua_api.txt
src/client.cpp
src/client.h
src/clientserver.h
src/game.cpp
src/guiFormSpecMenu.h
src/player.cpp
src/scriptapi.cpp
src/scriptapi.h
src/server.cpp

index 8d4e61fefc1e796d37a0cd76ec5c69a8e17f7bde..18ef227556baf709eb8b8770f41bc1e8185c730d 100644 (file)
@@ -299,6 +299,12 @@ local function make_registration()
        return t, registerfunc
 end
 
+local function make_registration_reverse()
+       local t = {}
+       local registerfunc = function(func) table.insert(t, 1, func) end
+       return t, registerfunc
+end
+
 minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
 minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
 minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()
@@ -310,4 +316,5 @@ minetest.registered_on_dieplayers, minetest.register_on_dieplayer = make_registr
 minetest.registered_on_respawnplayers, minetest.register_on_respawnplayer = make_registration()
 minetest.registered_on_joinplayers, minetest.register_on_joinplayer = make_registration()
 minetest.registered_on_leaveplayers, minetest.register_on_leaveplayer = make_registration()
+minetest.registered_on_player_receive_fields, minetest.register_on_player_receive_fields = make_registration_reverse()
 
index d5797d17193a4936c632c8221b1d1a6ef89df566..b6168c34cd79811e8552fcf511ee8addb40fdf70 100644 (file)
@@ -766,6 +766,11 @@ minetest.register_on_joinplayer(func(ObjectRef))
 minetest.register_on_leaveplayer(func(ObjectRef))
 ^ Called when a player leaves the game
 minetest.register_on_chat_message(func(name, message))
+^ Called always when a player says something
+minetest.register_on_player_receive_fields(func(player, formname, fields))
+^ Called when a button is pressed in player's inventory form
+^ Newest functions are called first
+^ If function returns true, remaining functions are not called
 
 Other registration functions:
 minetest.register_chatcommand(cmd, chatcommand definition)
index fdfb49c843552c75821d405d8c64a9a8fd817e64..3a2edede38dd2409300f4c355844984b6237f746 100644 (file)
@@ -1773,6 +1773,29 @@ void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
        Send(0, data, true);
 }
        
+void Client::sendInventoryFields(const std::string &formname, 
+               const std::map<std::string, std::string> &fields)
+{
+       std::ostringstream os(std::ios_base::binary);
+
+       writeU16(os, TOSERVER_INVENTORY_FIELDS);
+       os<<serializeString(formname);
+       writeU16(os, fields.size());
+       for(std::map<std::string, std::string>::const_iterator
+                       i = fields.begin(); i != fields.end(); i++){
+               const std::string &name = i->first;
+               const std::string &value = i->second;
+               os<<serializeString(name);
+               os<<serializeLongString(value);
+       }
+
+       // Make data buffer
+       std::string s = os.str();
+       SharedBuffer<u8> data((u8*)s.c_str(), s.size());
+       // Send as reliable
+       Send(0, data, true);
+}
+
 void Client::sendInventoryAction(InventoryAction *a)
 {
        std::ostringstream os(std::ios_base::binary);
index 18a0009a83123b62682ad5fc9cd5c6fa2ae03538..f751220f7c48f3c7ade5faf47f731b98abb00641 100644 (file)
@@ -212,6 +212,8 @@ public:
 
        void sendNodemetaFields(v3s16 p, const std::string &formname,
                        const std::map<std::string, std::string> &fields);
+       void sendInventoryFields(const std::string &formname,
+                       const std::map<std::string, std::string> &fields);
        void sendInventoryAction(InventoryAction *a);
        void sendChatMessage(const std::wstring &message);
        void sendChangePassword(const std::wstring oldpassword,
index 07e7b831d4b62388860aea3091e1490e2dd94449..5214068441947b34306275fb4c89f36bb8e9109d 100644 (file)
@@ -58,7 +58,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
        PROTOCOL_VERSION 11:
                TileDef in ContentFeatures
                Nodebox drawtype
-               Added after a release: TOCLIENT_INVENTORY_FORMSPEC
+               (some dev snapshot)
+               TOCLIENT_INVENTORY_FORMSPEC
+               (0.4.0, 0.4.1)
+               TOSERVER_INVENTORY_FIELDS
 */
 
 #define PROTOCOL_VERSION 11
@@ -510,6 +513,19 @@ enum ToServerCommand
                        u8[len] field value
        */
 
+       TOSERVER_INVENTORY_FIELDS = 0x3c,
+       /*
+               u16 command
+               u16 len
+               u8[len] form name (reserved for future use)
+               u16 number of fields
+               for each field:
+                       u16 len
+                       u8[len] field name
+                       u32 len
+                       u8[len] field value
+       */
+
        TOSERVER_REQUEST_MEDIA = 0x40,
        /*
                u16 command
index 3ba90789ada36fe53b1a06bdb469d37f067f7fbb..19c4707de65a51e384e6355d541d5f2cd07190a8 100644 (file)
@@ -111,6 +111,20 @@ struct TextDestNodeMetadata : public TextDest
        Client *m_client;
 };
 
+struct TextDestPlayerInventory : public TextDest
+{
+       TextDestPlayerInventory(Client *client)
+       {
+               m_client = client;
+       }
+       void gotText(std::map<std::string, std::string> fields)
+       {
+               m_client->sendInventoryFields("", fields);
+       }
+
+       Client *m_client;
+};
+
 /* Respawn menu callback */
 
 class MainRespawnInitiator: public IRespawnInitiator
@@ -1507,6 +1521,7 @@ void the_game(
                        assert(src);
                        menu->setFormSpec(src->getForm(), inventoryloc);
                        menu->setFormSource(src);
+                       menu->setTextDest(new TextDestPlayerInventory(&client));
                        menu->drop();
                }
                else if(input->wasKeyDown(EscapeKey))
index a60629153f1c3dd1b182d1dff42d631807f7d3cb..0830165a502bcf4f507ba7cbcd25369eee809997 100644 (file)
@@ -33,7 +33,7 @@ struct TextDest
 {
        virtual ~TextDest() {};
        // This is deprecated I guess? -celeron55
-       virtual void gotText(std::wstring text) = 0;
+       virtual void gotText(std::wstring text){}
        virtual void gotText(std::map<std::string, std::string> fields) = 0;
 };
 
index 6dd90e9577b37e12c03c4f197c4a6b6c5997114f..2e084b415a4b51c8607616bad815a21d5ba35b8f 100644 (file)
@@ -50,7 +50,7 @@ Player::Player(IGameDef *gamedef):
        inventory.addList("craftresult", 1);
 
        // Can be redefined via Lua
-       inventory_formspec =  "invsize[8,7.5;]"
+       inventory_formspec =  "size[8,7.5]"
                //"image[1,0.6;1,2;player.png]"
                "list[current_player;main;0,3.5;8,4;]"
                "list[current_player;craft;3,0;3,3;]"
index a72e66b4f315f9bc84158f916986341e2c1a92e1..6cb701689ae434c6a1199f7d8042638b1a0cfc61 100644 (file)
@@ -5238,6 +5238,40 @@ bool scriptapi_set_password(lua_State *L, const std::string &playername,
        return lua_toboolean(L, -1);
 }
 
+/*
+       player
+*/
+
+void scriptapi_on_player_receive_fields(lua_State *L, 
+               ServerActiveObject *player,
+               const std::string &formname,
+               const std::map<std::string, std::string> &fields)
+{
+       realitycheck(L);
+       assert(lua_checkstack(L, 20));
+       StackUnroller stack_unroller(L);
+
+       // Get minetest.registered_on_chat_messages
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "registered_on_player_receive_fields");
+       // Call callbacks
+       // param 1
+       objectref_get_or_create(L, player);
+       // param 2
+       lua_pushstring(L, formname.c_str());
+       // param 3
+       lua_newtable(L);
+       for(std::map<std::string, std::string>::const_iterator
+                       i = fields.begin(); i != fields.end(); i++){
+               const std::string &name = i->first;
+               const std::string &value = i->second;
+               lua_pushstring(L, name.c_str());
+               lua_pushlstring(L, value.c_str(), value.size());
+               lua_settable(L, -3);
+       }
+       scriptapi_run_callbacks(L, 3, RUN_CALLBACKS_MODE_OR_SC);
+}
+
 /*
        item callbacks and node callbacks
 */
index 12a1172a7e2149d3242356ac57ba6f80a659e548..2fe662ddc1aaad52957d323d63cfc2ac3c08c68e 100644 (file)
@@ -69,6 +69,12 @@ void scriptapi_create_auth(lua_State *L, const std::string &playername,
 bool scriptapi_set_password(lua_State *L, const std::string &playername,
                const std::string &password);
 
+/* player */
+void scriptapi_on_player_receive_fields(lua_State *L, 
+               ServerActiveObject *player,
+               const std::string &formname,
+               const std::map<std::string, std::string> &fields);
+
 /* item callbacks */
 bool scriptapi_item_on_drop(lua_State *L, ItemStack &item,
                ServerActiveObject *dropper, v3f pos);
index 2a6c6054f56bca4bc5c50cce4271732ae8fec108..893d03b24118a8e42d1d162d485f9f5a58f533b3 100644 (file)
@@ -3248,6 +3248,22 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                scriptapi_node_on_receive_fields(m_lua, p, formname, fields,
                                playersao);
        }
+       else if(command == TOSERVER_INVENTORY_FIELDS)
+       {
+               std::string datastring((char*)&data[2], datasize-2);
+               std::istringstream is(datastring, std::ios_base::binary);
+               
+               std::string formname = deSerializeString(is);
+               int num = readU16(is);
+               std::map<std::string, std::string> fields;
+               for(int k=0; k<num; k++){
+                       std::string fieldname = deSerializeString(is);
+                       std::string fieldvalue = deSerializeLongString(is);
+                       fields[fieldname] = fieldvalue;
+               }
+
+               scriptapi_on_player_receive_fields(m_lua, playersao, formname, fields);
+       }
        else
        {
                infostream<<"Server::ProcessData(): Ignoring "