summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-07-22 17:10:58 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-07-22 17:40:48 +0300
commit4cc98d7add7b697ac302a6136bbeb95ef78cec45 (patch)
treeefcdd9352f25c99557a1acd5177b6d586ecba881
parent506203345ba2795aa0af68a434f4b77cf50e664a (diff)
downloadminetest-4cc98d7add7b697ac302a6136bbeb95ef78cec45.tar.gz
minetest-4cc98d7add7b697ac302a6136bbeb95ef78cec45.tar.bz2
minetest-4cc98d7add7b697ac302a6136bbeb95ef78cec45.zip
minetest.register_on_player_receive_fields()
-rw-r--r--builtin/misc_register.lua7
-rw-r--r--doc/lua_api.txt5
-rw-r--r--src/client.cpp23
-rw-r--r--src/client.h2
-rw-r--r--src/clientserver.h18
-rw-r--r--src/game.cpp15
-rw-r--r--src/guiFormSpecMenu.h2
-rw-r--r--src/player.cpp2
-rw-r--r--src/scriptapi.cpp34
-rw-r--r--src/scriptapi.h6
-rw-r--r--src/server.cpp16
11 files changed, 127 insertions, 3 deletions
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<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);
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<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,
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<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))
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<std::string, std::string> 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
@@ -5239,6 +5239,40 @@ bool scriptapi_set_password(lua_State *L, const std::string &playername,
}
/*
+ 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
*/
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<std::string, std::string> &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<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 "