diff options
| author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-02-10 19:50:36 +0100 |
|---|---|---|
| committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-02-10 19:50:36 +0100 |
| commit | 1fbbb768252f872dfa961d3a73460d996164d527 (patch) | |
| tree | e9faf93dbd894b253ac3d1f0895b7468e8fee50d /src/network | |
| parent | 74f5f033e04c0d8694815fedb795838d4926cbc9 (diff) | |
| parent | 9736b9cea5f841bb0e9bb2c9c05c3b2560327064 (diff) | |
| download | dragonfireclient-1fbbb768252f872dfa961d3a73460d996164d527.tar.xz | |
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/network')
| -rw-r--r-- | src/network/networkexceptions.h | 8 | ||||
| -rw-r--r-- | src/network/networkpacket.cpp | 49 | ||||
| -rw-r--r-- | src/network/networkpacket.h | 2 | ||||
| -rw-r--r-- | src/network/serverpackethandler.cpp | 40 |
4 files changed, 56 insertions, 43 deletions
diff --git a/src/network/networkexceptions.h b/src/network/networkexceptions.h index f4913928c..58a3bb490 100644 --- a/src/network/networkexceptions.h +++ b/src/network/networkexceptions.h @@ -56,12 +56,6 @@ public: InvalidIncomingDataException(const char *s) : BaseException(s) {} }; -class InvalidOutgoingDataException : public BaseException -{ -public: - InvalidOutgoingDataException(const char *s) : BaseException(s) {} -}; - class NoIncomingDataException : public BaseException { public: @@ -103,4 +97,4 @@ class SendFailedException : public BaseException { public: SendFailedException(const std::string &s) : BaseException(s) {} -};
\ No newline at end of file +}; diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index 6d0abb12c..a71e26572 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -50,7 +50,7 @@ void NetworkPacket::checkReadOffset(u32 from_offset, u32 field_size) } } -void NetworkPacket::putRawPacket(u8 *data, u32 datasize, session_t peer_id) +void NetworkPacket::putRawPacket(const u8 *data, u32 datasize, session_t peer_id) { // If a m_command is already set, we are rewriting on same packet // This is not permitted @@ -145,6 +145,8 @@ void NetworkPacket::putLongString(const std::string &src) putRawString(src.c_str(), msgsize); } +static constexpr bool NEED_SURROGATE_CODING = sizeof(wchar_t) > 2; + NetworkPacket& NetworkPacket::operator>>(std::wstring& dst) { checkReadOffset(m_read_offset, 2); @@ -160,9 +162,16 @@ NetworkPacket& NetworkPacket::operator>>(std::wstring& dst) checkReadOffset(m_read_offset, strLen * 2); dst.reserve(strLen); - for(u16 i=0; i<strLen; i++) { - wchar_t c16 = readU16(&m_data[m_read_offset]); - dst.append(&c16, 1); + for (u16 i = 0; i < strLen; i++) { + wchar_t c = readU16(&m_data[m_read_offset]); + if (NEED_SURROGATE_CODING && c >= 0xD800 && c < 0xDC00 && i+1 < strLen) { + i++; + m_read_offset += sizeof(u16); + + wchar_t c2 = readU16(&m_data[m_read_offset]); + c = 0x10000 + ( ((c & 0x3ff) << 10) | (c2 & 0x3ff) ); + } + dst.push_back(c); m_read_offset += sizeof(u16); } @@ -175,15 +184,37 @@ NetworkPacket& NetworkPacket::operator<<(const std::wstring &src) throw PacketError("String too long"); } - u16 msgsize = src.size(); + if (!NEED_SURROGATE_CODING || src.size() == 0) { + *this << static_cast<u16>(src.size()); + for (u16 i = 0; i < src.size(); i++) + *this << static_cast<u16>(src[i]); - *this << msgsize; + return *this; + } - // Write string - for (u16 i=0; i<msgsize; i++) { - *this << (u16) src[i]; + // write dummy value, to be overwritten later + const u32 len_offset = m_read_offset; + u32 written = 0; + *this << static_cast<u16>(0xfff0); + + for (u16 i = 0; i < src.size(); i++) { + wchar_t c = src[i]; + if (c > 0xffff) { + // Encode high code-points as surrogate pairs + u32 n = c - 0x10000; + *this << static_cast<u16>(0xD800 | (n >> 10)) + << static_cast<u16>(0xDC00 | (n & 0x3ff)); + written += 2; + } else { + *this << static_cast<u16>(c); + written++; + } } + if (written > WIDE_STRING_MAX_LEN) + throw PacketError("String too long"); + writeU16(&m_data[len_offset], written); + return *this; } diff --git a/src/network/networkpacket.h b/src/network/networkpacket.h index e77bfb744..c7ff03b8e 100644 --- a/src/network/networkpacket.h +++ b/src/network/networkpacket.h @@ -34,7 +34,7 @@ public: ~NetworkPacket(); - void putRawPacket(u8 *data, u32 datasize, session_t peer_id); + void putRawPacket(const u8 *data, u32 datasize, session_t peer_id); void clear(); // Getters diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index c636d01e1..270b8e01f 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -56,12 +56,12 @@ void Server::handleCommand_Init(NetworkPacket* pkt) session_t peer_id = pkt->getPeerId(); RemoteClient *client = getClient(peer_id, CS_Created); + Address addr; std::string addr_s; try { - Address address = getPeerAddress(peer_id); - addr_s = address.serializeString(); - } - catch (con::PeerNotFoundException &e) { + addr = m_con->GetPeerAddress(peer_id); + addr_s = addr.serializeString(); + } catch (con::PeerNotFoundException &e) { /* * no peer for this packet found * most common reason is peer timeout, e.g. peer didn't @@ -73,13 +73,14 @@ void Server::handleCommand_Init(NetworkPacket* pkt) return; } - // If net_proto_version is set, this client has already been handled if (client->getState() > CS_Created) { verbosestream << "Server: Ignoring multiple TOSERVER_INITs from " << addr_s << " (peer_id=" << peer_id << ")" << std::endl; return; } + client->setCachedAddress(addr); + verbosestream << "Server: Got TOSERVER_INIT from " << addr_s << " (peer_id=" << peer_id << ")" << std::endl; @@ -437,18 +438,20 @@ void Server::handleCommand_GotBlocks(NetworkPacket* pkt) u8 count; *pkt >> count; - RemoteClient *client = getClient(pkt->getPeerId()); - if ((s16)pkt->getSize() < 1 + (int)count * 6) { throw con::InvalidIncomingDataException ("GOTBLOCKS length is too short"); } + m_clients.lock(); + RemoteClient *client = m_clients.lockedGetClientNoEx(pkt->getPeerId()); + for (u16 i = 0; i < count; i++) { v3s16 p; *pkt >> p; client->GotBlock(p); } + m_clients.unlock(); } void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, @@ -749,21 +752,8 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt) void Server::handleCommand_ChatMessage(NetworkPacket* pkt) { - /* - u16 command - u16 length - wstring message - */ - u16 len; - *pkt >> len; - std::wstring message; - for (u16 i = 0; i < len; i++) { - u16 tmp_wchar; - *pkt >> tmp_wchar; - - message += (wchar_t)tmp_wchar; - } + *pkt >> message; session_t peer_id = pkt->getPeerId(); RemotePlayer *player = m_env->getPlayer(peer_id); @@ -775,15 +765,13 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt) return; } - // Get player name of this client std::string name = player->getName(); - std::wstring wname = narrow_to_wide(name); - std::wstring answer_to_sender = handleChat(name, wname, message, true, player); + std::wstring answer_to_sender = handleChat(name, message, true, player); if (!answer_to_sender.empty()) { // Send the answer to sender - SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_NORMAL, - answer_to_sender, wname)); + SendChatMessage(peer_id, ChatMessage(CHATMESSAGE_TYPE_SYSTEM, + answer_to_sender)); } } |
