minetest.register_on_player_receive_fields()

This commit is contained in:
Perttu Ahola 2012-07-22 17:10:58 +03:00
parent 506203345b
commit 4cc98d7add
11 changed files with 127 additions and 3 deletions

@ -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()

@ -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)

@ -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);

@ -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,

@ -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

@ -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))

@ -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;
};

@ -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;]"

@ -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
*/

@ -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);

@ -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 "