Skip to content

Commit 7ddf67a

Browse files
authoredJul 16, 2017
Chat protocol rewrite (#5117)
* New TOCLIENT_CHAT_MESSAGE packet * Rename old packet to TOCLIENT_CHAT_MESSAGE_OLD for compat * Handle TOCLIENT_CHAT_MESSAGE new structure client side * Client chat queue should use a specific object * SendChatMessage: use the right packet depending on protocol version (not complete yet) * Add chatmessage(type) objects and handle them client side (partially) * Use ChatMessage instead of std::wstring server side * Update with timestamp support
1 parent ecbc972 commit 7ddf67a

16 files changed

+251
-51
lines changed
 

Diff for: ‎src/chatmessage.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Minetest
3+
Copyright (C) 2017 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
4+
5+
This program is free software; you can redistribute it and/or modify
6+
it under the terms of the GNU Lesser General Public License as published by
7+
the Free Software Foundation; either version 2.1 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public License along
16+
with this program; if not, write to the Free Software Foundation, Inc.,
17+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*/
19+
20+
#ifndef MT_CHATMESSAGE_H
21+
#define MT_CHATMESSAGE_H
22+
23+
#include <string>
24+
#include <ctime>
25+
26+
enum ChatMessageType
27+
{
28+
CHATMESSAGE_TYPE_RAW = 0,
29+
CHATMESSAGE_TYPE_NORMAL = 1,
30+
CHATMESSAGE_TYPE_ANNOUNCE = 2,
31+
CHATMESSAGE_TYPE_SYSTEM = 3,
32+
CHATMESSAGE_TYPE_MAX = 4,
33+
};
34+
35+
struct ChatMessage
36+
{
37+
ChatMessage(const std::wstring &m = L"") : message(m) {}
38+
39+
ChatMessage(ChatMessageType t, const std::wstring &m, const std::wstring &s = L"",
40+
std::time_t ts = std::time(0))
41+
: type(t), message(m), sender(s), timestamp(ts)
42+
{
43+
}
44+
45+
ChatMessageType type = CHATMESSAGE_TYPE_RAW;
46+
std::wstring message = L"";
47+
std::wstring sender = L"";
48+
std::time_t timestamp = std::time(0);
49+
};
50+
51+
#endif

Diff for: ‎src/client.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
4747
#include "guiscalingfilter.h"
4848
#include "script/scripting_client.h"
4949
#include "game.h"
50+
#include "chatmessage.h"
5051

5152
extern gui::IGUIEnvironment* guienv;
5253

@@ -1518,12 +1519,34 @@ u16 Client::getHP()
15181519
return player->hp;
15191520
}
15201521

1521-
bool Client::getChatMessage(std::wstring &message)
1522+
bool Client::getChatMessage(std::wstring &res)
15221523
{
1523-
if(m_chat_queue.size() == 0)
1524+
if (m_chat_queue.empty())
15241525
return false;
1525-
message = m_chat_queue.front();
1526+
1527+
ChatMessage *chatMessage = m_chat_queue.front();
15261528
m_chat_queue.pop();
1529+
1530+
res = L"";
1531+
1532+
switch (chatMessage->type) {
1533+
case CHATMESSAGE_TYPE_RAW:
1534+
case CHATMESSAGE_TYPE_ANNOUNCE:
1535+
case CHATMESSAGE_TYPE_SYSTEM:
1536+
res = chatMessage->message;
1537+
break;
1538+
case CHATMESSAGE_TYPE_NORMAL: {
1539+
if (!chatMessage->sender.empty())
1540+
res = L"<" + chatMessage->sender + L"> " + chatMessage->message;
1541+
else
1542+
res = chatMessage->message;
1543+
break;
1544+
}
1545+
default:
1546+
break;
1547+
}
1548+
1549+
delete chatMessage;
15271550
return true;
15281551
}
15291552

@@ -1542,14 +1565,13 @@ void Client::typeChatMessage(const std::wstring &message)
15421565
sendChatMessage(message);
15431566

15441567
// Show locally
1545-
if (message[0] != L'/')
1546-
{
1568+
if (message[0] != L'/') {
15471569
// compatibility code
15481570
if (m_proto_ver < 29) {
15491571
LocalPlayer *player = m_env.getLocalPlayer();
15501572
assert(player);
15511573
std::wstring name = narrow_to_wide(player->getName());
1552-
pushToChatQueue((std::wstring)L"<" + name + L"> " + message);
1574+
pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_NORMAL, message, name));
15531575
}
15541576
}
15551577
}
@@ -1806,7 +1828,8 @@ void Client::makeScreenshot()
18061828
} else {
18071829
sstr << "Failed to save screenshot '" << filename << "'";
18081830
}
1809-
pushToChatQueue(narrow_to_wide(sstr.str()));
1831+
pushToChatQueue(new ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1832+
narrow_to_wide(sstr.str())));
18101833
infostream << sstr.str() << std::endl;
18111834
image->drop();
18121835
}

Diff for: ‎src/client.h

+6-4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
4343
#define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
4444

4545
struct MeshMakeData;
46+
struct ChatMessage;
4647
class MapBlockMesh;
4748
class IWritableTextureSource;
4849
class IWritableShaderSource;
@@ -328,7 +329,8 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
328329
void handleCommand_BlockData(NetworkPacket* pkt);
329330
void handleCommand_Inventory(NetworkPacket* pkt);
330331
void handleCommand_TimeOfDay(NetworkPacket* pkt);
331-
void handleCommand_ChatMessage(NetworkPacket* pkt);
332+
void handleCommand_ChatMessageOld(NetworkPacket *pkt);
333+
void handleCommand_ChatMessage(NetworkPacket *pkt);
332334
void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
333335
void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
334336
void handleCommand_Movement(NetworkPacket* pkt);
@@ -520,9 +522,9 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
520522

521523
void makeScreenshot();
522524

523-
inline void pushToChatQueue(const std::wstring &input)
525+
inline void pushToChatQueue(ChatMessage *cec)
524526
{
525-
m_chat_queue.push(input);
527+
m_chat_queue.push(cec);
526528
}
527529

528530
ClientScripting *getScript() { return m_script; }
@@ -629,10 +631,10 @@ class Client : public con::PeerHandler, public InventoryManager, public IGameDef
629631
// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
630632
//s32 m_daynight_i;
631633
//u32 m_daynight_ratio;
632-
std::queue<std::wstring> m_chat_queue;
633634
std::queue<std::wstring> m_out_chat_queue;
634635
u32 m_last_chat_message_sent;
635636
float m_chat_message_allowance = 5.0f;
637+
std::queue<ChatMessage *> m_chat_queue;
636638

637639
// The authentication methods we can use to enter sudo mode (=change password)
638640
u32 m_sudo_auth_methods;

Diff for: ‎src/clientiface.cpp

+26
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,32 @@ void ClientInterface::sendToAll(NetworkPacket *pkt)
693693
}
694694
}
695695

696+
void ClientInterface::sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt,
697+
u16 min_proto_ver)
698+
{
699+
MutexAutoLock clientslock(m_clients_mutex);
700+
for (std::unordered_map<u16, RemoteClient*>::iterator i = m_clients.begin();
701+
i != m_clients.end(); ++i) {
702+
RemoteClient *client = i->second;
703+
NetworkPacket *pkt_to_send = nullptr;
704+
705+
if (client->net_proto_version >= min_proto_ver) {
706+
pkt_to_send = pkt;
707+
} else if (client->net_proto_version != 0) {
708+
pkt_to_send = legacypkt;
709+
} else {
710+
warningstream << "Client with unhandled version to handle: '"
711+
<< client->net_proto_version << "'";
712+
continue;
713+
}
714+
715+
m_con->Send(client->peer_id,
716+
clientCommandFactoryTable[pkt_to_send->getCommand()].channel,
717+
pkt_to_send,
718+
clientCommandFactoryTable[pkt_to_send->getCommand()].reliable);
719+
}
720+
}
721+
696722
RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
697723
{
698724
MutexAutoLock clientslock(m_clients_mutex);

Diff for: ‎src/clientiface.h

+1
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ class ClientInterface {
434434

435435
/* send to all clients */
436436
void sendToAll(NetworkPacket *pkt);
437+
void sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt, u16 min_proto_ver);
437438

438439
/* delete a client */
439440
void DeleteClient(u16 peer_id);

Diff for: ‎src/game.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,7 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
976976
}
977977

978978
// Get new messages from client
979-
std::wstring message;
980-
979+
std::wstring message = L"";
981980
while (client.getChatMessage(message)) {
982981
chat_backend.addUnparsedMessage(message);
983982
}

Diff for: ‎src/network/clientopcodes.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
7171
null_command_handler,
7272
null_command_handler,
7373
null_command_handler,
74-
null_command_handler,
75-
{ "TOCLIENT_CHAT_MESSAGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ChatMessage }, // 0x30
74+
{ "TOCLIENT_CHAT_MESSAGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ChatMessage }, // 0x2F
75+
{ "TOCLIENT_CHAT_MESSAGE_OLD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ChatMessageOld }, // 0x30
7676
{ "TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ActiveObjectRemoveAdd }, // 0x31
7777
{ "TOCLIENT_ACTIVE_OBJECT_MESSAGES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ActiveObjectMessages }, // 0x32
7878
{ "TOCLIENT_HP", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HP }, // 0x33

Diff for: ‎src/network/clientpackethandler.cpp

+41-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
#include "client.h"
2121

2222
#include "util/base64.h"
23+
#include "chatmessage.h"
2324
#include "clientmedia.h"
2425
#include "log.h"
2526
#include "map.h"
@@ -142,7 +143,9 @@ void Client::handleCommand_AcceptSudoMode(NetworkPacket* pkt)
142143
}
143144
void Client::handleCommand_DenySudoMode(NetworkPacket* pkt)
144145
{
145-
pushToChatQueue(L"Password change denied. Password NOT changed.");
146+
ChatMessage *chatMessage = new ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
147+
L"Password change denied. Password NOT changed.");
148+
pushToChatQueue(chatMessage);
146149
// reset everything and be sad
147150
deleteAuthData();
148151
}
@@ -395,7 +398,7 @@ void Client::handleCommand_TimeOfDay(NetworkPacket* pkt)
395398
<< " dr=" << dr << std::endl;
396399
}
397400

398-
void Client::handleCommand_ChatMessage(NetworkPacket* pkt)
401+
void Client::handleCommand_ChatMessageOld(NetworkPacket *pkt)
399402
{
400403
/*
401404
u16 command
@@ -413,8 +416,43 @@ void Client::handleCommand_ChatMessage(NetworkPacket* pkt)
413416
}
414417

415418
// If chat message not consummed by client lua API
419+
// @TODO send this to CSM using ChatMessage object
416420
if (!moddingEnabled() || !m_script->on_receiving_message(wide_to_utf8(message))) {
417-
pushToChatQueue(message);
421+
pushToChatQueue(new ChatMessage(message));
422+
}
423+
}
424+
425+
void Client::handleCommand_ChatMessage(NetworkPacket *pkt)
426+
{
427+
/*
428+
u8 version
429+
u8 message_type
430+
u16 sendername length
431+
wstring sendername
432+
u16 length
433+
wstring message
434+
*/
435+
436+
ChatMessage *chatMessage = new ChatMessage();
437+
u8 version, message_type;
438+
*pkt >> version >> message_type;
439+
440+
if (version != 1 || message_type >= CHATMESSAGE_TYPE_MAX) {
441+
delete chatMessage;
442+
return;
443+
}
444+
445+
*pkt >> chatMessage->sender >> chatMessage->message >> chatMessage->timestamp;
446+
447+
chatMessage->type = (ChatMessageType) message_type;
448+
449+
// @TODO send this to CSM using ChatMessage object
450+
if (!moddingEnabled() || !m_script->on_receiving_message(
451+
wide_to_utf8(chatMessage->message))) {
452+
pushToChatQueue(chatMessage);
453+
} else {
454+
// Message was consumed by CSM and should not handled by client, destroying
455+
delete chatMessage;
418456
}
419457
}
420458

Diff for: ‎src/network/networkpacket.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,12 @@ NetworkPacket& NetworkPacket::operator<<(u64 src)
275275
return *this;
276276
}
277277

278+
NetworkPacket& NetworkPacket::operator<<(std::time_t src)
279+
{
280+
*this << (u64) src;
281+
return *this;
282+
}
283+
278284
NetworkPacket& NetworkPacket::operator<<(float src)
279285
{
280286
checkDataSize(4);
@@ -360,6 +366,16 @@ NetworkPacket& NetworkPacket::operator>>(u64& dst)
360366
return *this;
361367
}
362368

369+
NetworkPacket& NetworkPacket::operator>>(std::time_t& dst)
370+
{
371+
checkReadOffset(m_read_offset, 8);
372+
373+
dst = readU64(&m_data[m_read_offset]);
374+
375+
m_read_offset += 8;
376+
return *this;
377+
}
378+
363379
NetworkPacket& NetworkPacket::operator>>(float& dst)
364380
{
365381
checkReadOffset(m_read_offset, 4);

Diff for: ‎src/network/networkpacket.h

+3
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ class NetworkPacket
8484
NetworkPacket& operator>>(u64& dst);
8585
NetworkPacket& operator<<(u64 src);
8686

87+
NetworkPacket& operator>>(std::time_t& dst);
88+
NetworkPacket& operator<<(std::time_t src);
89+
8790
NetworkPacket& operator>>(float& dst);
8891
NetworkPacket& operator<<(float src);
8992

Diff for: ‎src/network/networkprotocol.h

+20-2
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,17 @@ with this program; if not, write to the Free Software Foundation, Inc.,
160160
instead of guessing based on the active object list.
161161
PROTOCOL VERSION 34:
162162
Add sound pitch
163+
PROTOCOL VERSION 35:
164+
Rename TOCLIENT_CHAT_MESSAGE to TOCLIENT_CHAT_MESSAGE_OLD (0x30)
165+
Add TOCLIENT_CHAT_MESSAGE (0x2F)
166+
This chat message is a signalisation message containing various informations:
167+
* timestamp
168+
* sender
169+
* type (RAW, NORMAL, ANNOUNCE, SYSTEM)
170+
* content
163171
*/
164172

165-
#define LATEST_PROTOCOL_VERSION 34
173+
#define LATEST_PROTOCOL_VERSION 35
166174

167175
// Server's supported network protocol range
168176
#define SERVER_PROTOCOL_VERSION_MIN 24
@@ -307,7 +315,17 @@ enum ToClientCommand
307315

308316
// (oops, there is some gap here)
309317

310-
TOCLIENT_CHAT_MESSAGE = 0x30,
318+
TOCLIENT_CHAT_MESSAGE = 0x2F,
319+
/*
320+
u8 version
321+
u8 message_type
322+
u16 sendername length
323+
wstring sendername
324+
u16 length
325+
wstring message
326+
*/
327+
328+
TOCLIENT_CHAT_MESSAGE_OLD = 0x30, // Deprecated by proto v35
311329
/*
312330
u16 length
313331
wstring message

Diff for: ‎src/network/serveropcodes.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
160160
null_command_factory,
161161
null_command_factory,
162162
null_command_factory,
163-
null_command_factory,
164-
{ "TOCLIENT_CHAT_MESSAGE", 0, true }, // 0x30
163+
{ "TOCLIENT_CHAT_MESSAGE", 0, true }, // 0x2F
164+
{ "TOCLIENT_CHAT_MESSAGE_OLD", 0, true }, // 0x30
165165
{ "TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD", 0, true }, // 0x31
166166
{ "TOCLIENT_ACTIVE_OBJECT_MESSAGES", 0, true }, // 0x32 Special packet, sent by 0 (rel) and 1 (unrel) channel
167167
{ "TOCLIENT_HP", 0, true }, // 0x33

Diff for: ‎src/network/serverpackethandler.cpp

+20-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1717
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1818
*/
1919

20+
#include <chatmessage.h>
2021
#include "server.h"
2122
#include "log.h"
2223

@@ -644,8 +645,10 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
644645

645646
// Warnings about protocol version can be issued here
646647
if (getClient(pkt->getPeerId())->net_proto_version < LATEST_PROTOCOL_VERSION) {
647-
SendChatMessage(pkt->getPeerId(), L"# Server: WARNING: YOUR CLIENT'S "
648-
L"VERSION MAY NOT BE FULLY COMPATIBLE WITH THIS SERVER!");
648+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
649+
L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE "
650+
L"WITH THIS SERVER!"));
651+
649652
}
650653
}
651654

@@ -1077,11 +1080,11 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt)
10771080
std::string name = player->getName();
10781081
std::wstring wname = narrow_to_wide(name);
10791082

1080-
std::wstring answer_to_sender = handleChat(name, wname, message,
1081-
true, dynamic_cast<RemotePlayer *>(player));
1083+
std::wstring answer_to_sender = handleChat(name, wname, message, true, player);
10821084
if (!answer_to_sender.empty()) {
10831085
// Send the answer to sender
1084-
SendChatMessage(pkt->getPeerId(), answer_to_sender);
1086+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_NORMAL,
1087+
answer_to_sender, wname));
10851088
}
10861089
}
10871090

@@ -1171,7 +1174,8 @@ void Server::handleCommand_Password(NetworkPacket* pkt)
11711174
infostream<<"Server: " << player->getName() <<
11721175
" supplied invalid password hash" << std::endl;
11731176
// Wrong old password supplied!!
1174-
SendChatMessage(pkt->getPeerId(), L"Invalid new password hash supplied. Password NOT changed.");
1177+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1178+
L"Invalid new password hash supplied. Password NOT changed."));
11751179
return;
11761180
}
11771181

@@ -1186,18 +1190,21 @@ void Server::handleCommand_Password(NetworkPacket* pkt)
11861190
if (oldpwd != checkpwd) {
11871191
infostream << "Server: invalid old password" << std::endl;
11881192
// Wrong old password supplied!!
1189-
SendChatMessage(pkt->getPeerId(), L"Invalid old password supplied. Password NOT changed.");
1193+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1194+
L"Invalid old password supplied. Password NOT changed."));
11901195
return;
11911196
}
11921197

11931198
bool success = m_script->setPassword(playername, newpwd);
11941199
if (success) {
11951200
actionstream << player->getName() << " changes password" << std::endl;
1196-
SendChatMessage(pkt->getPeerId(), L"Password change successful.");
1201+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1202+
L"Password change successful."));
11971203
} else {
11981204
actionstream << player->getName() << " tries to change password but "
11991205
<< "it fails" << std::endl;
1200-
SendChatMessage(pkt->getPeerId(), L"Password change failed or unavailable.");
1206+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1207+
L"Password change failed or unavailable."));
12011208
}
12021209
}
12031210

@@ -1853,11 +1860,13 @@ void Server::handleCommand_FirstSrp(NetworkPacket* pkt)
18531860
bool success = m_script->setPassword(playername, pw_db_field);
18541861
if (success) {
18551862
actionstream << playername << " changes password" << std::endl;
1856-
SendChatMessage(pkt->getPeerId(), L"Password change successful.");
1863+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1864+
L"Password change successful."));
18571865
} else {
18581866
actionstream << playername << " tries to change password but "
18591867
<< "it fails" << std::endl;
1860-
SendChatMessage(pkt->getPeerId(), L"Password change failed or unavailable.");
1868+
SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
1869+
L"Password change failed or unavailable."));
18611870
}
18621871
}
18631872
}

Diff for: ‎src/script/lua_api/l_client.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
1919
*/
2020

2121
#include "l_client.h"
22+
#include "chatmessage.h"
2223
#include "clientenvironment.h"
2324
#include "common/c_content.h"
2425
#include "common/c_converter.h"
@@ -80,7 +81,7 @@ int ModApiClient::l_display_chat_message(lua_State *L)
8081
return 0;
8182

8283
std::string message = luaL_checkstring(L, 1);
83-
getClient(L)->pushToChatQueue(utf8_to_wide(message));
84+
getClient(L)->pushToChatQueue(new ChatMessage(utf8_to_wide(message)));
8485
lua_pushboolean(L, true);
8586
return 1;
8687
}

Diff for: ‎src/server.cpp

+28-16
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
6060
#include "util/sha1.h"
6161
#include "util/hex.h"
6262
#include "database.h"
63+
#include "chatmessage.h"
6364

6465
class ClientNotFoundException : public BaseException
6566
{
@@ -304,7 +305,8 @@ Server::~Server()
304305
infostream<<"Server destructing"<<std::endl;
305306

306307
// Send shutdown message
307-
SendChatMessage(PEER_ID_INEXISTENT, L"*** Server shutting down");
308+
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE,
309+
L"*** Server shutting down"));
308310

309311
{
310312
MutexAutoLock envlock(m_env_mutex);
@@ -1107,7 +1109,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
11071109
// Note things in chat if not in simple singleplayer mode
11081110
if (!m_simple_singleplayer_mode && g_settings->getBool("show_statusline_on_connect")) {
11091111
// Send information about server to player in chat
1110-
SendChatMessage(peer_id, getStatusString());
1112+
SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, getStatusString()));
11111113
}
11121114
Address addr = getPeerAddress(player->peer_id);
11131115
std::string ip_str = addr.serializeString();
@@ -1615,21 +1617,29 @@ void Server::SendInventory(PlayerSAO* playerSAO)
16151617
Send(&pkt);
16161618
}
16171619

1618-
void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
1620+
void Server::SendChatMessage(u16 peer_id, const ChatMessage &message)
16191621
{
16201622
DSTACK(FUNCTION_NAME);
1623+
1624+
NetworkPacket legacypkt(TOCLIENT_CHAT_MESSAGE_OLD, 0, peer_id);
1625+
legacypkt << message.message;
1626+
1627+
NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id);
1628+
u8 version = 1;
1629+
u8 type = message.type;
1630+
pkt << version << type << std::wstring(L"") << message.message << message.timestamp;
1631+
16211632
if (peer_id != PEER_ID_INEXISTENT) {
1622-
NetworkPacket pkt(TOCLIENT_CHAT_MESSAGE, 0, peer_id);
1633+
RemotePlayer *player = m_env->getPlayer(peer_id);
1634+
if (!player)
1635+
return;
16231636

1624-
if (m_clients.getProtocolVersion(peer_id) < 27)
1625-
pkt << unescape_enriched(message);
1637+
if (player->protocol_version < 35)
1638+
Send(&legacypkt);
16261639
else
1627-
pkt << message;
1628-
1629-
Send(&pkt);
1640+
Send(&pkt);
16301641
} else {
1631-
for (u16 id : m_clients.getClientIDs())
1632-
SendChatMessage(id, message);
1642+
m_clients.sendToAllCompat(&pkt, &legacypkt, 35);
16331643
}
16341644
}
16351645

@@ -2811,8 +2821,10 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
28112821
}
28122822

28132823
// Send leave chat message to all remaining clients
2814-
if(message.length() != 0)
2815-
SendChatMessage(PEER_ID_INEXISTENT,message);
2824+
if (!message.empty()) {
2825+
SendChatMessage(PEER_ID_INEXISTENT,
2826+
ChatMessage(CHATMESSAGE_TYPE_ANNOUNCE, message));
2827+
}
28162828
}
28172829

28182830
void Server::UpdateCrafting(RemotePlayer *player)
@@ -2934,7 +2946,7 @@ std::wstring Server::handleChat(const std::string &name, const std::wstring &wna
29342946
for (u16 i = 0; i < clients.size(); i++) {
29352947
u16 cid = clients[i];
29362948
if (cid != peer_id_to_avoid_sending)
2937-
SendChatMessage(cid, line);
2949+
SendChatMessage(cid, ChatMessage(line));
29382950
}
29392951
}
29402952
return L"";
@@ -3096,7 +3108,7 @@ void Server::notifyPlayer(const char *name, const std::wstring &msg)
30963108
if (player->peer_id == PEER_ID_INEXISTENT)
30973109
return;
30983110

3099-
SendChatMessage(player->peer_id, msg);
3111+
SendChatMessage(player->peer_id, ChatMessage(msg));
31003112
}
31013113

31023114
bool Server::showFormspec(const char *playername, const std::string &formspec,
@@ -3271,7 +3283,7 @@ bool Server::overrideDayNightRatio(RemotePlayer *player, bool do_override,
32713283

32723284
void Server::notifyPlayers(const std::wstring &msg)
32733285
{
3274-
SendChatMessage(PEER_ID_INEXISTENT,msg);
3286+
SendChatMessage(PEER_ID_INEXISTENT, ChatMessage(msg));
32753287
}
32763288

32773289
void Server::spawnParticle(const std::string &playername, v3f pos,

Diff for: ‎src/server.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3838
#include "clientiface.h"
3939
#include "remoteplayer.h"
4040
#include "network/networkpacket.h"
41+
#include "chatmessage.h"
4142
#include <string>
4243
#include <list>
4344
#include <map>
@@ -388,7 +389,7 @@ class Server : public con::PeerHandler, public MapEventReceiver,
388389
void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
389390

390391

391-
void SendChatMessage(u16 peer_id, const std::wstring &message);
392+
void SendChatMessage(u16 peer_id, const ChatMessage &message);
392393
void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
393394
void SendPlayerHP(u16 peer_id);
394395

0 commit comments

Comments
 (0)
Please sign in to comment.