aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-06-01 20:51:15 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-06-03 22:31:01 +0300
commitd7447cdf9e4df3c345218886ab2bae0e0cc4fc55 (patch)
tree4ebc1c2fd91d66f8711ed87013af80a4adf53cc0
parentff8d2bbc3682b12d40d1dfb212d39a50c498fb93 (diff)
downloadminetest-d7447cdf9e4df3c345218886ab2bae0e0cc4fc55.tar.gz
minetest-d7447cdf9e4df3c345218886ab2bae0e0cc4fc55.tar.bz2
minetest-d7447cdf9e4df3c345218886ab2bae0e0cc4fc55.zip
Implement sign using form field protocol
-rw-r--r--doc/lua_api.txt4
-rw-r--r--games/minimal/mods/default/init.lua11
-rw-r--r--src/client.cpp36
-rw-r--r--src/client.h5
-rw-r--r--src/clientserver.h16
-rw-r--r--src/content_nodemeta.cpp4
-rw-r--r--src/game.cpp4
-rw-r--r--src/scriptapi.cpp45
-rw-r--r--src/scriptapi.h5
-rw-r--r--src/server.cpp18
10 files changed, 117 insertions, 31 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 58c260425..73d7b3641 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1036,6 +1036,10 @@ Node definition (register_node)
on_dig = func(pos, node, digger),
^ default: minetest.node_dig
^ By default: checks privileges, wears out tool and removes node
+
+ on_receive_fields = func(pos, formname, fields, sender),
+ ^ fields = {name1 = value1, name2 = value2, ...}
+ ^ default: nil
}
Recipe: (register_craft)
diff --git a/games/minimal/mods/default/init.lua b/games/minimal/mods/default/init.lua
index 9573db119..603380d5b 100644
--- a/games/minimal/mods/default/init.lua
+++ b/games/minimal/mods/default/init.lua
@@ -1116,7 +1116,16 @@ minetest.register_node("default:sign_wall", {
--local n = minetest.env:get_node(pos)
local meta = minetest.env:get_meta(pos)
meta:set_string("formspec", "hack:sign_text_input")
- meta:set_string("infotext", "\"${text}\"")
+ meta:set_string("infotext", "\"\"")
+ end,
+ on_receive_fields = function(pos, formname, fields, sender)
+ --print("Sign at "..minetest.pos_to_string(pos).." got "..dump(fields))
+ local meta = minetest.env:get_meta(pos)
+ fields.text = fields.text or ""
+ print((sender:get_player_name() or "").." wrote \""..fields.text..
+ "\" to sign at "..minetest.pos_to_string(pos))
+ meta:set_string("text", fields.text)
+ meta:set_string("infotext", '"'..fields.text..'"')
end,
})
diff --git a/src/client.cpp b/src/client.cpp
index 72667a528..84cae8f97 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -1740,33 +1740,23 @@ void Client::interact(u8 action, const PointedThing& pointed)
Send(0, data, true);
}
-void Client::sendSignNodeText(v3s16 p, std::string text)
+void Client::sendNodemetaFields(v3s16 p, const std::string &formname,
+ const std::map<std::string, std::string> &fields)
{
- /*
- u16 command
- v3s16 p
- u16 textlen
- textdata
- */
std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
-
- // Write command
- writeU16(buf, TOSERVER_SIGNNODETEXT);
- os.write((char*)buf, 2);
-
- // Write p
- writeV3S16(buf, p);
- os.write((char*)buf, 6);
- u16 textlen = text.size();
- // Write text length
- writeS16(buf, textlen);
- os.write((char*)buf, 2);
+ writeU16(os, TOSERVER_NODEMETA_FIELDS);
+ writeV3S16(os, p);
+ 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);
+ }
- // Write text
- os.write((char*)text.c_str(), textlen);
-
// Make data buffer
std::string s = os.str();
SharedBuffer<u8> data((u8*)s.c_str(), s.size());
diff --git a/src/client.h b/src/client.h
index 72ab70abd..0ed3eea3b 100644
--- a/src/client.h
+++ b/src/client.h
@@ -210,11 +210,12 @@ public:
void interact(u8 action, const PointedThing& pointed);
- void sendSignNodeText(v3s16 p, std::string text);
+ void sendNodemetaFields(v3s16 p, 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,
- const std::wstring newpassword);
+ const std::wstring newpassword);
void sendDamage(u8 damage);
void sendRespawn();
diff --git a/src/clientserver.h b/src/clientserver.h
index 461c13cd2..1b5a37848 100644
--- a/src/clientserver.h
+++ b/src/clientserver.h
@@ -415,7 +415,7 @@ enum ToServerCommand
wstring message
*/
- TOSERVER_SIGNNODETEXT = 0x33,
+ TOSERVER_SIGNNODETEXT = 0x33, // obsolete
/*
u16 command
v3s16 p
@@ -484,6 +484,20 @@ enum ToServerCommand
s32[len] sound_id
*/
+ TOSERVER_NODEMETA_FIELDS = 0x3b,
+ /*
+ u16 command
+ v3s16 p
+ 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/content_nodemeta.cpp b/src/content_nodemeta.cpp
index ba4a0e513..a2a341ae0 100644
--- a/src/content_nodemeta.cpp
+++ b/src/content_nodemeta.cpp
@@ -57,7 +57,9 @@ static bool content_nodemeta_deserialize_legacy_body(
else if(id == NODEMETA_SIGN) // SignNodeMetadata
{
meta->setString("text", deSerializeLongString(is));
- meta->setString("infotext","\"${text}\"");
+ //meta->setString("infotext","\"${text}\"");
+ meta->setString("infotext",
+ std::string("\"") + meta->getString("text") + "\"");
meta->setString("formspec","field[text;;${text}]");
return false;
}
diff --git a/src/game.cpp b/src/game.cpp
index 69fc601c3..815a5dd85 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -103,7 +103,9 @@ struct TextDestNodeMetadata : public TextDest
std::string ntext = wide_to_narrow(text);
infostream<<"Changing text of a sign node: "
<<ntext<<std::endl;
- m_client->sendSignNodeText(m_p, ntext);
+ std::map<std::string, std::string> fields;
+ fields["text"] = ntext;
+ m_client->sendNodemetaFields(m_p, "", fields);
}
v3s16 m_p;
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 255d37fc2..f9ec58582 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -141,14 +141,14 @@ static Server* get_server(lua_State *L)
return server;
}
-/*static ServerEnvironment* get_env(lua_State *L)
+static ServerEnvironment* get_env(lua_State *L)
{
// Get environment from registry
lua_getfield(L, LUA_REGISTRYINDEX, "minetest_env");
ServerEnvironment *env = (ServerEnvironment*)lua_touserdata(L, -1);
lua_pop(L, 1);
return env;
-}*/
+}
static void objectref_get(lua_State *L, u16 id)
{
@@ -4973,6 +4973,47 @@ void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node)
script_error(L, "error: %s", lua_tostring(L, -1));
}
+void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
+ const std::string &formname,
+ const std::map<std::string, std::string> &fields,
+ ServerActiveObject *sender)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ StackUnroller stack_unroller(L);
+
+ INodeDefManager *ndef = get_server(L)->ndef();
+
+ // If node doesn't exist, we don't know what callback to call
+ MapNode node = get_env(L)->getMap().getNodeNoEx(p);
+ if(node.getContent() == CONTENT_IGNORE)
+ return;
+
+ // Push callback function on stack
+ if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_receive_fields"))
+ return;
+
+ // Call function
+ // param 1
+ push_v3s16(L, p);
+ // 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);
+ }
+ // param 4
+ objectref_get_or_create(L, sender);
+ if(lua_pcall(L, 4, 0, 0))
+ script_error(L, "error: %s", lua_tostring(L, -1));
+}
+
/*
environment
*/
diff --git a/src/scriptapi.h b/src/scriptapi.h
index cd6a5614c..e6c16eba6 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -24,6 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string>
#include "mapnode.h"
#include <set>
+#include <map>
class Server;
class ServerEnvironment;
@@ -83,6 +84,10 @@ bool scriptapi_node_on_dig(lua_State *L, v3s16 p, MapNode node,
ServerActiveObject *digger);
void scriptapi_node_on_construct(lua_State *L, v3s16 p, MapNode node);
void scriptapi_node_on_destruct(lua_State *L, v3s16 p, MapNode node);
+void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
+ const std::string &formname,
+ const std::map<std::string, std::string> &fields,
+ ServerActiveObject *sender);
/* luaentity */
// Returns true if succesfully added into Lua; false otherwise.
diff --git a/src/server.cpp b/src/server.cpp
index 0ee0ef465..fbeff83bf 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3126,6 +3126,24 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
m_playing_sounds.erase(i++);
}
}
+ else if(command == TOSERVER_NODEMETA_FIELDS)
+ {
+ std::string datastring((char*)&data[2], datasize-2);
+ std::istringstream is(datastring, std::ios_base::binary);
+
+ v3s16 p = readV3S16(is);
+ 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_node_on_receive_fields(m_lua, p, formname, fields,
+ playersao);
+ }
else
{
infostream<<"Server::ProcessData(): Ignoring "