diff --git a/builtin/misc_register.lua b/builtin/misc_register.lua index 8d4e61fef..18ef22755 100644 --- a/builtin/misc_register.lua +++ b/builtin/misc_register.lua @@ -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() diff --git a/doc/lua_api.txt b/doc/lua_api.txt index d5797d171..b6168c34c 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -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) diff --git a/src/client.cpp b/src/client.cpp index fdfb49c84..3a2edede3 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -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 &fields) +{ + std::ostringstream os(std::ios_base::binary); + + writeU16(os, TOSERVER_INVENTORY_FIELDS); + os<::const_iterator + i = fields.begin(); i != fields.end(); i++){ + const std::string &name = i->first; + const std::string &value = i->second; + os< 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); diff --git a/src/client.h b/src/client.h index 18a0009a8..f751220f7 100644 --- a/src/client.h +++ b/src/client.h @@ -212,6 +212,8 @@ public: void sendNodemetaFields(v3s16 p, const std::string &formname, const std::map &fields); + void sendInventoryFields(const std::string &formname, + const std::map &fields); void sendInventoryAction(InventoryAction *a); void sendChatMessage(const std::wstring &message); void sendChangePassword(const std::wstring oldpassword, diff --git a/src/clientserver.h b/src/clientserver.h index 07e7b831d..521406844 100644 --- a/src/clientserver.h +++ b/src/clientserver.h @@ -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 diff --git a/src/game.cpp b/src/game.cpp index 3ba90789a..19c4707de 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -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 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)) diff --git a/src/guiFormSpecMenu.h b/src/guiFormSpecMenu.h index a60629153..0830165a5 100644 --- a/src/guiFormSpecMenu.h +++ b/src/guiFormSpecMenu.h @@ -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 fields) = 0; }; diff --git a/src/player.cpp b/src/player.cpp index 6dd90e957..2e084b415 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -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;]" diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp index a72e66b4f..6cb701689 100644 --- a/src/scriptapi.cpp +++ b/src/scriptapi.cpp @@ -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 &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::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 */ diff --git a/src/scriptapi.h b/src/scriptapi.h index 12a1172a7..2fe662ddc 100644 --- a/src/scriptapi.h +++ b/src/scriptapi.h @@ -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 &fields); + /* item callbacks */ bool scriptapi_item_on_drop(lua_State *L, ItemStack &item, ServerActiveObject *dropper, v3f pos); diff --git a/src/server.cpp b/src/server.cpp index 2a6c6054f..893d03b24 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -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 fields; + for(int k=0; k