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()
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()
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)
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);
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,
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
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
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
assert(src);
menu->setFormSpec(src->getForm(), inventoryloc);
menu->setFormSource(src);
+ menu->setTextDest(new TextDestPlayerInventory(&client));
menu->drop();
}
else if(input->wasKeyDown(EscapeKey))
{
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;
};
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;]"
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
*/
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);
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 "