summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorANAND <ClobberXD@gmail.com>2019-08-08 21:34:46 +0530
committerrubenwardy <rw@rubenwardy.com>2019-08-08 17:04:46 +0100
commitd1c27c7e8037e9f438741ee5f7d3b6bda22d22a0 (patch)
treefa04794d876ec4c912add9fcca36eff4a18df016
parentcc610c74a742511e04dce91b24d09c860ca7fa1b (diff)
downloadminetest-d1c27c7e8037e9f438741ee5f7d3b6bda22d22a0.tar.gz
minetest-d1c27c7e8037e9f438741ee5f7d3b6bda22d22a0.tar.bz2
minetest-d1c27c7e8037e9f438741ee5f7d3b6bda22d22a0.zip
Allow customizing chat message format (#8529)
-rw-r--r--builtin/game/chat.lua (renamed from builtin/game/chatcommands.lua)27
-rw-r--r--builtin/game/init.lua40
-rw-r--r--builtin/settingtypes.txt4
-rw-r--r--doc/lua_api.txt6
-rw-r--r--minetest.conf.example5
-rw-r--r--src/defaultsettings.cpp1
-rw-r--r--src/gettime.h1
-rw-r--r--src/script/cpp_api/s_server.cpp22
-rw-r--r--src/script/cpp_api/s_server.h12
-rw-r--r--src/server.cpp40
10 files changed, 111 insertions, 47 deletions
diff --git a/builtin/game/chatcommands.lua b/builtin/game/chat.lua
index b2a49863e..84559b064 100644
--- a/builtin/game/chatcommands.lua
+++ b/builtin/game/chat.lua
@@ -1,4 +1,29 @@
--- Minetest: builtin/game/chatcommands.lua
+-- Minetest: builtin/game/chat.lua
+
+--
+-- Chat message formatter
+--
+
+-- Implemented in Lua to allow redefinition
+function core.format_chat_message(name, message)
+ local str = core.settings:get("chat_message_format")
+ local error_str = "Invalid chat message format - missing %s"
+ local i
+
+ str, i = str:gsub("@name", name, 1)
+ if i == 0 then
+ error(error_str:format("@name"), 2)
+ end
+
+ str, i = str:gsub("@message", message, 1)
+ if i == 0 then
+ error(error_str:format("@message"), 2)
+ end
+
+ str = str:gsub("@timestamp", os.date("%H:%M:%S", os.time()), 1)
+
+ return str
+end
--
-- Chat command handler
diff --git a/builtin/game/init.lua b/builtin/game/init.lua
index 04f0732e5..271e49be3 100644
--- a/builtin/game/init.lua
+++ b/builtin/game/init.lua
@@ -1,37 +1,37 @@
local scriptpath = core.get_builtin_path()
-local commonpath = scriptpath.."common"..DIR_DELIM
-local gamepath = scriptpath.."game"..DIR_DELIM
+local commonpath = scriptpath .. "common" .. DIR_DELIM
+local gamepath = scriptpath .. "game".. DIR_DELIM
-- Shared between builtin files, but
-- not exposed to outer context
local builtin_shared = {}
-dofile(commonpath.."vector.lua")
+dofile(commonpath .. "vector.lua")
-dofile(gamepath.."constants.lua")
-assert(loadfile(gamepath.."item.lua"))(builtin_shared)
-dofile(gamepath.."register.lua")
+dofile(gamepath .. "constants.lua")
+assert(loadfile(gamepath .. "item.lua"))(builtin_shared)
+dofile(gamepath .. "register.lua")
if core.settings:get_bool("profiler.load") then
- profiler = dofile(scriptpath.."profiler"..DIR_DELIM.."init.lua")
+ profiler = dofile(scriptpath .. "profiler" .. DIR_DELIM .. "init.lua")
end
dofile(commonpath .. "after.lua")
-dofile(gamepath.."item_entity.lua")
-dofile(gamepath.."deprecated.lua")
-dofile(gamepath.."misc.lua")
-dofile(gamepath.."privileges.lua")
-dofile(gamepath.."auth.lua")
+dofile(gamepath .. "item_entity.lua")
+dofile(gamepath .. "deprecated.lua")
+dofile(gamepath .. "misc.lua")
+dofile(gamepath .. "privileges.lua")
+dofile(gamepath .. "auth.lua")
dofile(commonpath .. "chatcommands.lua")
-dofile(gamepath.."chatcommands.lua")
+dofile(gamepath .. "chat.lua")
dofile(commonpath .. "information_formspecs.lua")
-dofile(gamepath.."static_spawn.lua")
-dofile(gamepath.."detached_inventory.lua")
-assert(loadfile(gamepath.."falling.lua"))(builtin_shared)
-dofile(gamepath.."features.lua")
-dofile(gamepath.."voxelarea.lua")
-dofile(gamepath.."forceloading.lua")
-dofile(gamepath.."statbars.lua")
+dofile(gamepath .. "static_spawn.lua")
+dofile(gamepath .. "detached_inventory.lua")
+assert(loadfile(gamepath .. "falling.lua"))(builtin_shared)
+dofile(gamepath .. "features.lua")
+dofile(gamepath .. "voxelarea.lua")
+dofile(gamepath .. "forceloading.lua")
+dofile(gamepath .. "statbars.lua")
profiler = nil
diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt
index 931fe26da..21da565ca 100644
--- a/builtin/settingtypes.txt
+++ b/builtin/settingtypes.txt
@@ -1058,6 +1058,10 @@ disable_anticheat (Disable anticheat) bool false
# This option is only read when server starts.
enable_rollback_recording (Rollback recording) bool false
+# Format of player chat messages. The following strings are valid placeholders:
+# @name, @message, @timestamp (optional)
+chat_message_format (Chat message format) string <@name> @message
+
# A message to be displayed to all clients when the server shuts down.
kick_msg_shutdown (Shutdown message) string Server shutting down.
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 41061ed87..840841e6b 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -4156,6 +4156,12 @@ Chat
* `minetest.chat_send_all(text)`
* `minetest.chat_send_player(name, text)`
+* `minetest.format_chat_message(name, message)`
+ * Used by the server to format a chat message, based on the setting `chat_message_format`.
+ Refer to the documentation of the setting for a list of valid placeholders.
+ * Takes player name and message, and returns the formatted string to be sent to players.
+ * Can be redefined by mods if required, for things like colored names or messages.
+ * **Only** the first occurrence of each placeholder will be replaced.
Environment access
------------------
diff --git a/minetest.conf.example b/minetest.conf.example
index fe9d0e7f9..fc02e70cf 100644
--- a/minetest.conf.example
+++ b/minetest.conf.example
@@ -1277,6 +1277,11 @@
# type: bool
# enable_rollback_recording = false
+# Format of player chat messages. The following strings are valid placeholders:
+# @name, @message, @timestamp (optional)
+# type: string
+chat_message_format = <@name> @message
+
# A message to be displayed to all clients when the server shuts down.
# type: string
# kick_msg_shutdown = Server shutting down.
diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp
index 4c39a44e1..b6ab7c9a0 100644
--- a/src/defaultsettings.cpp
+++ b/src/defaultsettings.cpp
@@ -356,6 +356,7 @@ void set_default_settings(Settings *settings)
settings->setDefault("kick_msg_crash", "This server has experienced an internal error. You will now be disconnected.");
settings->setDefault("ask_reconnect_on_crash", "false");
+ settings->setDefault("chat_message_format", "<@name> @message");
settings->setDefault("profiler_print_interval", "0");
settings->setDefault("active_object_send_range_blocks", "4");
settings->setDefault("active_block_range", "3");
diff --git a/src/gettime.h b/src/gettime.h
index f20728dfd..66efef1d7 100644
--- a/src/gettime.h
+++ b/src/gettime.h
@@ -19,7 +19,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#pragma once
-#include "irrlichttypes.h"
#include <ctime>
#include <string>
diff --git a/src/script/cpp_api/s_server.cpp b/src/script/cpp_api/s_server.cpp
index 3b461a2a3..1ce2f9d45 100644
--- a/src/script/cpp_api/s_server.cpp
+++ b/src/script/cpp_api/s_server.cpp
@@ -168,3 +168,25 @@ void ScriptApiServer::on_shutdown()
runCallbacks(0, RUN_CALLBACKS_MODE_FIRST);
}
+std::string ScriptApiServer::formatChatMessage(const std::string &name,
+ const std::string &message)
+{
+ SCRIPTAPI_PRECHECKHEADER
+
+ // Push function onto stack
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "format_chat_message");
+
+ // Push arguments onto stack
+ lua_pushstring(L, name.c_str());
+ lua_pushstring(L, message.c_str());
+
+ // Actually call the function
+ lua_call(L, 2, 1);
+
+ // Fetch return value
+ std::string ret = lua_tostring(L, -1);
+ lua_pop(L, 1);
+
+ return ret;
+}
diff --git a/src/script/cpp_api/s_server.h b/src/script/cpp_api/s_server.h
index 769939d3f..a4cede84d 100644
--- a/src/script/cpp_api/s_server.h
+++ b/src/script/cpp_api/s_server.h
@@ -36,14 +36,18 @@ public:
// Calls on_shutdown handlers
void on_shutdown();
+ // Calls core.format_chat_message
+ std::string formatChatMessage(const std::string &name,
+ const std::string &message);
+
/* auth */
bool getAuth(const std::string &playername,
- std::string *dst_password,
- std::set<std::string> *dst_privs);
+ std::string *dst_password,
+ std::set<std::string> *dst_privs);
void createAuth(const std::string &playername,
- const std::string &password);
+ const std::string &password);
bool setPassword(const std::string &playername,
- const std::string &password);
+ const std::string &password);
private:
void getAuthHandler();
void readPrivileges(int index, std::set<std::string> &result);
diff --git a/src/server.cpp b/src/server.cpp
index 7e6208711..27388e666 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -1571,7 +1571,7 @@ void Server::SendChatMessage(session_t peer_id, const ChatMessage &message)
}
void Server::SendShowFormspecMessage(session_t peer_id, const std::string &formspec,
- const std::string &formname)
+ const std::string &formname)
{
NetworkPacket pkt(TOCLIENT_SHOW_FORMSPEC, 0 , peer_id);
if (formspec.empty()){
@@ -2863,28 +2863,28 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna
{
// If something goes wrong, this player is to blame
RollbackScopeActor rollback_scope(m_rollback,
- std::string("player:") + name);
+ std::string("player:") + name);
if (g_settings->getBool("strip_color_codes"))
wmessage = unescape_enriched(wmessage);
if (player) {
switch (player->canSendChatMessage()) {
- case RPLAYER_CHATRESULT_FLOODING: {
- std::wstringstream ws;
- ws << L"You cannot send more messages. You are limited to "
- << g_settings->getFloat("chat_message_limit_per_10sec")
- << L" messages per 10 seconds.";
- return ws.str();
- }
- case RPLAYER_CHATRESULT_KICK:
- DenyAccess_Legacy(player->getPeerId(),
- L"You have been kicked due to message flooding.");
- return L"";
- case RPLAYER_CHATRESULT_OK:
- break;
- default:
- FATAL_ERROR("Unhandled chat filtering result found.");
+ case RPLAYER_CHATRESULT_FLOODING: {
+ std::wstringstream ws;
+ ws << L"You cannot send more messages. You are limited to "
+ << g_settings->getFloat("chat_message_limit_per_10sec")
+ << L" messages per 10 seconds.";
+ return ws.str();
+ }
+ case RPLAYER_CHATRESULT_KICK:
+ DenyAccess_Legacy(player->getPeerId(),
+ L"You have been kicked due to message flooding.");
+ return L"";
+ case RPLAYER_CHATRESULT_OK:
+ break;
+ default:
+ FATAL_ERROR("Unhandled chat filtering result found.");
}
}
@@ -2912,10 +2912,8 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna
line += L"-!- You don't have permission to shout.";
broadcast_line = false;
} else {
- line += L"<";
- line += wname;
- line += L"> ";
- line += wmessage;
+ line += narrow_to_wide(m_script->formatChatMessage(name,
+ wide_to_narrow(wmessage)));
}
/*