summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/builtin.lua21
-rw-r--r--data/mods/default/init.lua18
-rw-r--r--src/scriptapi.cpp49
-rw-r--r--src/scriptapi.h4
-rw-r--r--src/server.cpp7
5 files changed, 98 insertions, 1 deletions
diff --git a/data/builtin.lua b/data/builtin.lua
index 6fd19404e..b1abeb364 100644
--- a/data/builtin.lua
+++ b/data/builtin.lua
@@ -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
diff --git a/data/mods/default/init.lua b/data/mods/default/init.lua
index ea6bf3da9..537f62e31 100644
--- a/data/mods/default/init.lua
+++ b/data/mods/default/init.lua
@@ -19,8 +19,11 @@
-- 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
--
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 711a02cbc..1872085dc 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -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
diff --git a/src/scriptapi.h b/src/scriptapi.h
index 9bdf99c62..e6570e764 100644
--- a/src/scriptapi.h
+++ b/src/scriptapi.h
@@ -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);
diff --git a/src/server.cpp b/src/server.cpp
index 0cbf50294..2c892fa8c 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -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