diff options
-rw-r--r-- | data/builtin.lua | 21 | ||||
-rw-r--r-- | data/mods/default/init.lua | 18 | ||||
-rw-r--r-- | src/scriptapi.cpp | 49 | ||||
-rw-r--r-- | src/scriptapi.h | 4 | ||||
-rw-r--r-- | src/server.cpp | 7 |
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 |