Add chat message callback and send functions
authorPerttu Ahola <celeron55@gmail.com>
Sun, 27 Nov 2011 17:39:36 +0000 (19:39 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Tue, 29 Nov 2011 17:13:56 +0000 (19:13 +0200)
data/builtin.lua
data/mods/default/init.lua
src/scriptapi.cpp
src/scriptapi.h
src/server.cpp

index 6fd19404e16be81e40fd704be11f866b1eec8abf..b1abeb364d7903a690e0078f8cc265fd7c991e53 100644 (file)
@@ -147,3 +147,24 @@ minetest.register_node("ignore", {
        air_equivalent = true,
 })
 
+--
+-- Chat message processing
+--
+
+minetest.registered_on_chat_messages = {}
+
+minetest.on_chat_message = function(name, message)
+       for i,func in ipairs(minetest.registered_on_chat_messages) do
+               ate = func(name, message)
+               if ate then
+                       return true
+               end
+       end
+       return false
+end
+
+minetest.register_on_chat_message = function(func)
+       table.insert(minetest.registered_on_chat_messages, func)
+end
+
+-- END
index ea6bf3da9ab3662127b9679137371c9bc78b5df5..537f62e31d626e948b9e7ce3d4617c58fb4a0ee3 100644 (file)
 -- minetest.register_on_newplayer(func(ObjectRef))
 -- minetest.register_on_respawnplayer(func(ObjectRef))
 -- ^ return true in func to disable regular player placement
+-- minetest.register_on_chat_message(func(name, message))
 -- minetest.setting_get(name)
 -- minetest.setting_getbool(name)
+-- minetest.chat_send_all(text)
+-- minetest.chat_send_player(name, text)
 --
 -- Global objects:
 -- minetest.env - environment reference
@@ -1371,6 +1374,21 @@ end)
 print("setting max_users = " .. dump(minetest.setting_get("max_users")))
 print("setting asdf = " .. dump(minetest.setting_get("asdf")))
 
+minetest.register_on_chat_message(function(name, message)
+       print("on_chat_message: name="..dump(name).." message="..dump(message))
+       local cmd = "/testcommand"
+       if message:sub(0, #cmd) == cmd then
+               print(cmd.." invoked")
+               return true
+       end
+       local cmd = "/help"
+       if message:sub(0, #cmd) == cmd then
+               print("script-overridden help command")
+               minetest.chat_send_all("script-overridden help command")
+               return true
+       end
+end)
+
 --
 -- Done, print some random stuff
 --
index 711a02cbc5e5c616bc772bca243b58b554d1f102..1872085dcf68a0109121efdd50717f5e4fb8280c 100644 (file)
@@ -936,6 +936,31 @@ static int l_setting_getbool(lua_State *L)
        return 1;
 }
 
+// chat_send_all(text)
+static int l_chat_send_all(lua_State *L)
+{
+       const char *text = luaL_checkstring(L, 1);
+       // Get server from registry
+       lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
+       Server *server = (Server*)lua_touserdata(L, -1);
+       // Send
+       server->notifyPlayers(narrow_to_wide(text));
+       return 0;
+}
+
+// chat_send_player(name, text)
+static int l_chat_send_player(lua_State *L)
+{
+       const char *name = luaL_checkstring(L, 1);
+       const char *text = luaL_checkstring(L, 2);
+       // Get server from registry
+       lua_getfield(L, LUA_REGISTRYINDEX, "minetest_server");
+       Server *server = (Server*)lua_touserdata(L, -1);
+       // Send
+       server->notifyPlayer(name, narrow_to_wide(text));
+       return 0;
+}
+
 static const struct luaL_Reg minetest_f [] = {
        {"register_nodedef_defaults", l_register_nodedef_defaults},
        {"register_entity", l_register_entity},
@@ -951,6 +976,8 @@ static const struct luaL_Reg minetest_f [] = {
        {"register_on_respawnplayer", l_register_on_respawnplayer},
        {"setting_get", l_setting_get},
        {"setting_getbool", l_setting_getbool},
+       {"chat_send_all", l_chat_send_all},
+       {"chat_send_player", l_chat_send_player},
        {NULL, NULL}
 };
 
@@ -1594,6 +1621,26 @@ void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj)
        lua_settable(L, objectstable);
 }
 
+bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
+               const std::string &message)
+{
+       realitycheck(L);
+       assert(lua_checkstack(L, 20));
+       StackUnroller stack_unroller(L);
+
+       // Get minetest.on_chat_message builtin function
+       lua_getglobal(L, "minetest");
+       lua_getfield(L, -1, "on_chat_message");
+       luaL_checktype(L, -1, LUA_TFUNCTION);
+
+       // Call function
+       lua_pushstring(L, name.c_str());
+       lua_pushstring(L, message.c_str());
+       if(lua_pcall(L, 2, 1, 0))
+               script_error(L, "error: %s\n", lua_tostring(L, -1));
+       bool ate = lua_toboolean(L, -1);
+       return ate;
+}
 
 /*
        misc
@@ -1791,7 +1838,7 @@ void scriptapi_environment_on_generated(lua_State *L, v3s16 minp, v3s16 maxp)
 {
        realitycheck(L);
        assert(lua_checkstack(L, 20));
-       infostream<<"scriptapi_environment_on_generated"<<std::endl;
+       //infostream<<"scriptapi_environment_on_generated"<<std::endl;
        StackUnroller stack_unroller(L);
 
        // Get minetest.registered_on_generateds
index 9bdf99c62879400a3358573f67a35ad297cd1a85..e6570e764f6171f1e2c9ebb5563310c3d7944343 100644 (file)
@@ -37,6 +37,10 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env);
 void scriptapi_add_object_reference(lua_State *L, ServerActiveObject *cobj);
 void scriptapi_rm_object_reference(lua_State *L, ServerActiveObject *cobj);
 
+// Returns true if script handled message
+bool scriptapi_on_chat_message(lua_State *L, const std::string &name,
+               const std::string &message);
+
 /* environment */
 // On environment step
 void scriptapi_environment_step(lua_State *L, float dtime);
index 0cbf5029425359bc3a9386f298f0bc0560d41584..2c892fa8cf10b6fbfb30063d83e6ebbde935688e 100644 (file)
@@ -3422,6 +3422,13 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                // Get player name of this client
                std::wstring name = narrow_to_wide(player->getName());
                
+               // Run script hook
+               bool ate = scriptapi_on_chat_message(m_lua, player->getName(),
+                               wide_to_narrow(message));
+               // If script ate the message, don't proceed
+               if(ate)
+                       return;
+               
                // Line to send to players
                std::wstring line;
                // Whether to send to the player that sent the line