diff options
| author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-09-19 20:56:13 +0200 |
|---|---|---|
| committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2021-09-19 20:56:13 +0200 |
| commit | c8900e169a1ddceec07a449f1ae7c4322ff02036 (patch) | |
| tree | 5156605fb473d25786426eb6876ba2e7d3b7507b /src/network | |
| parent | 950d2c9b3e10cbace9236e820c8119d1abb9e01f (diff) | |
| parent | e0529da5c84f224c380e6d5e063392cb01f85683 (diff) | |
| download | dragonfireclient-c8900e169a1ddceec07a449f1ae7c4322ff02036.tar.xz | |
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/network')
| -rw-r--r-- | src/network/clientopcodes.cpp | 2 | ||||
| -rw-r--r-- | src/network/clientpackethandler.cpp | 187 | ||||
| -rw-r--r-- | src/network/connection.cpp | 72 | ||||
| -rw-r--r-- | src/network/connection.h | 40 | ||||
| -rw-r--r-- | src/network/connectionthreads.cpp | 41 | ||||
| -rw-r--r-- | src/network/networkpacket.cpp | 9 | ||||
| -rw-r--r-- | src/network/networkpacket.h | 3 | ||||
| -rw-r--r-- | src/network/networkprotocol.h | 14 | ||||
| -rw-r--r-- | src/network/serveropcodes.cpp | 4 | ||||
| -rw-r--r-- | src/network/serverpackethandler.cpp | 54 |
10 files changed, 241 insertions, 185 deletions
diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index 55cfdd4dc..a98a5e7d1 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -204,7 +204,7 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = null_command_factory, // 0x3e null_command_factory, // 0x3f { "TOSERVER_REQUEST_MEDIA", 1, true }, // 0x40 - null_command_factory, // 0x41 + { "TOSERVER_HAVE_MEDIA", 2, true }, // 0x41 null_command_factory, // 0x42 { "TOSERVER_CLIENT_READY", 1, true }, // 0x43 null_command_factory, // 0x44 diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 2fea03fbf..6497bb26a 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -90,7 +90,7 @@ void Client::handleCommand_Hello(NetworkPacket* pkt) // This is only neccessary though when we actually want to add casing support if (m_chosen_auth_mech != AUTH_MECHANISM_NONE) { - // we recieved a TOCLIENT_HELLO while auth was already going on + // we received a TOCLIENT_HELLO while auth was already going on errorstream << "Client: TOCLIENT_HELLO while auth was already going on" << "(chosen_mech=" << m_chosen_auth_mech << ")." << std::endl; if (m_chosen_auth_mech == AUTH_MECHANISM_SRP || @@ -158,7 +158,7 @@ void Client::handleCommand_AcceptSudoMode(NetworkPacket* pkt) m_password = m_new_password; - verbosestream << "Client: Recieved TOCLIENT_ACCEPT_SUDO_MODE." << std::endl; + verbosestream << "Client: Received TOCLIENT_ACCEPT_SUDO_MODE." << std::endl; // send packet to actually set the password startAuth(AUTH_MECHANISM_FIRST_SRP); @@ -263,7 +263,7 @@ void Client::handleCommand_NodemetaChanged(NetworkPacket *pkt) return; std::istringstream is(pkt->readLongString(), std::ios::binary); - std::stringstream sstr; + std::stringstream sstr(std::ios::binary | std::ios::in | std::ios::out); decompressZlib(is, sstr); NodeMetadataList meta_updates_list(false); @@ -684,21 +684,19 @@ void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt) m_media_downloader->addFile(name, sha1_raw); } - try { + { std::string str; - *pkt >> str; Strfnd sf(str); - while(!sf.at_end()) { + while (!sf.at_end()) { std::string baseurl = trim(sf.next(",")); - if (!baseurl.empty()) + if (!baseurl.empty()) { + m_remote_media_servers.emplace_back(baseurl); m_media_downloader->addRemoteServer(baseurl); + } } } - catch(SerializationError& e) { - // not supported by server or turned off - } m_media_downloader->step(this); } @@ -730,31 +728,38 @@ void Client::handleCommand_Media(NetworkPacket* pkt) if (num_files == 0) return; - if (!m_media_downloader || !m_media_downloader->isStarted()) { - const char *problem = m_media_downloader ? - "media has not been requested" : - "all media has been received already"; - errorstream << "Client: Received media but " - << problem << "! " - << " bunch " << bunch_i << "/" << num_bunches - << " files=" << num_files - << " size=" << pkt->getSize() << std::endl; - return; - } + bool init_phase = m_media_downloader && m_media_downloader->isStarted(); - // Mesh update thread must be stopped while - // updating content definitions - sanity_check(!m_mesh_update_thread.isRunning()); + if (init_phase) { + // Mesh update thread must be stopped while + // updating content definitions + sanity_check(!m_mesh_update_thread.isRunning()); + } - for (u32 i=0; i < num_files; i++) { - std::string name; + for (u32 i = 0; i < num_files; i++) { + std::string name, data; *pkt >> name; + data = pkt->readLongString(); - std::string data = pkt->readLongString(); - - m_media_downloader->conventionalTransferDone( - name, data, this); + bool ok = false; + if (init_phase) { + ok = m_media_downloader->conventionalTransferDone(name, data, this); + } else { + // Check pending dynamic transfers, one of them must be it + for (const auto &it : m_pending_media_downloads) { + if (it.second->conventionalTransferDone(name, data, this)) { + ok = true; + break; + } + } + } + if (!ok) { + errorstream << "Client: Received media \"" << name + << "\" but no downloads pending. " << num_bunches << " bunches, " + << num_files << " in this one. (init_phase=" << init_phase + << ")" << std::endl; + } } } @@ -769,12 +774,11 @@ void Client::handleCommand_NodeDef(NetworkPacket* pkt) // Decompress node definitions std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); - std::ostringstream tmp_os; + std::stringstream tmp_os(std::ios::binary | std::ios::in | std::ios::out); decompressZlib(tmp_is, tmp_os); // Deserialize node definitions - std::istringstream tmp_is2(tmp_os.str()); - m_nodedef->deSerialize(tmp_is2); + m_nodedef->deSerialize(tmp_os); m_nodedef_received = true; } @@ -789,12 +793,11 @@ void Client::handleCommand_ItemDef(NetworkPacket* pkt) // Decompress item definitions std::istringstream tmp_is(pkt->readLongString(), std::ios::binary); - std::ostringstream tmp_os; + std::stringstream tmp_os(std::ios::binary | std::ios::in | std::ios::out); decompressZlib(tmp_is, tmp_os); // Deserialize node definitions - std::istringstream tmp_is2(tmp_os.str()); - m_itemdef->deSerialize(tmp_is2); + m_itemdef->deSerialize(tmp_os); m_itemdef_received = true; } @@ -915,6 +918,11 @@ void Client::handleCommand_Privileges(NetworkPacket* pkt) m_privileges.insert(priv); infostream << priv << " "; } + + // Enable basic_debug on server versions before it was added + if (m_proto_ver < 40) + m_privileges.insert("basic_debug"); + infostream << std::endl; } @@ -1078,6 +1086,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) v2s32 size; s16 z_index = 0; std::string text2; + u32 style = 0; *pkt >> server_id >> type >> pos >> name >> scale >> text >> number >> item >> dir >> align >> offset; @@ -1086,6 +1095,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) *pkt >> size; *pkt >> z_index; *pkt >> text2; + *pkt >> style; } catch(PacketError &e) {}; ClientEvent *event = new ClientEvent(); @@ -1106,6 +1116,7 @@ void Client::handleCommand_HudAdd(NetworkPacket* pkt) event->hudadd->size = size; event->hudadd->z_index = z_index; event->hudadd->text2 = text2; + event->hudadd->style = style; m_client_event_queue.push(event); } @@ -1133,17 +1144,29 @@ void Client::handleCommand_HudChange(NetworkPacket* pkt) *pkt >> server_id >> stat; - if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE || - stat == HUD_STAT_ALIGN || stat == HUD_STAT_OFFSET) - *pkt >> v2fdata; - else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT || stat == HUD_STAT_TEXT2) - *pkt >> sdata; - else if (stat == HUD_STAT_WORLD_POS) - *pkt >> v3fdata; - else if (stat == HUD_STAT_SIZE ) - *pkt >> v2s32data; - else - *pkt >> intdata; + // Keep in sync with:server.cpp -> SendHUDChange + switch ((HudElementStat)stat) { + case HUD_STAT_POS: + case HUD_STAT_SCALE: + case HUD_STAT_ALIGN: + case HUD_STAT_OFFSET: + *pkt >> v2fdata; + break; + case HUD_STAT_NAME: + case HUD_STAT_TEXT: + case HUD_STAT_TEXT2: + *pkt >> sdata; + break; + case HUD_STAT_WORLD_POS: + *pkt >> v3fdata; + break; + case HUD_STAT_SIZE: + *pkt >> v2s32data; + break; + default: + *pkt >> intdata; + break; + } ClientEvent *event = new ClientEvent(); event->type = CE_HUDCHANGE; @@ -1507,46 +1530,72 @@ void Client::handleCommand_PlayerSpeed(NetworkPacket *pkt) void Client::handleCommand_MediaPush(NetworkPacket *pkt) { std::string raw_hash, filename, filedata; + u32 token; bool cached; *pkt >> raw_hash >> filename >> cached; - filedata = pkt->readLongString(); + if (m_proto_ver >= 40) + *pkt >> token; + else + filedata = pkt->readLongString(); - if (raw_hash.size() != 20 || filedata.empty() || filename.empty() || + if (raw_hash.size() != 20 || filename.empty() || + (m_proto_ver < 40 && filedata.empty()) || !string_allowed(filename, TEXTURENAME_ALLOWED_CHARS)) { throw PacketError("Illegal filename, data or hash"); } - verbosestream << "Server pushes media file \"" << filename << "\" with " - << filedata.size() << " bytes of data (cached=" << cached - << ")" << std::endl; + verbosestream << "Server pushes media file \"" << filename << "\" "; + if (filedata.empty()) + verbosestream << "to be fetched "; + else + verbosestream << "with " << filedata.size() << " bytes "; + verbosestream << "(cached=" << cached << ")" << std::endl; if (m_media_pushed_files.count(filename) != 0) { - // Silently ignore for synchronization purposes + // Ignore (but acknowledge). Previously this was for sync purposes, + // but even in new versions media cannot be replaced at runtime. + if (m_proto_ver >= 40) + sendHaveMedia({ token }); return; } - // Compute and check checksum of data - std::string computed_hash; - { - SHA1 ctx; - ctx.addBytes(filedata.c_str(), filedata.size()); - unsigned char *buf = ctx.getDigest(); - computed_hash.assign((char*) buf, 20); - free(buf); - } - if (raw_hash != computed_hash) { - verbosestream << "Hash of file data mismatches, ignoring." << std::endl; + if (!filedata.empty()) { + // LEGACY CODEPATH + // Compute and check checksum of data + std::string computed_hash; + { + SHA1 ctx; + ctx.addBytes(filedata.c_str(), filedata.size()); + unsigned char *buf = ctx.getDigest(); + computed_hash.assign((char*) buf, 20); + free(buf); + } + if (raw_hash != computed_hash) { + verbosestream << "Hash of file data mismatches, ignoring." << std::endl; + return; + } + + // Actually load media + loadMedia(filedata, filename, true); + m_media_pushed_files.insert(filename); + + // Cache file for the next time when this client joins the same server + if (cached) + clientMediaUpdateCache(raw_hash, filedata); return; } - // Actually load media - loadMedia(filedata, filename, true); m_media_pushed_files.insert(filename); - // Cache file for the next time when this client joins the same server - if (cached) - clientMediaUpdateCache(raw_hash, filedata); + // create a downloader for this file + auto downloader = new SingleMediaDownloader(cached); + m_pending_media_downloads.emplace_back(token, downloader); + downloader->addFile(filename, raw_hash); + for (const auto &baseurl : m_remote_media_servers) + downloader->addRemoteServer(baseurl); + + downloader->step(this); } /* diff --git a/src/network/connection.cpp b/src/network/connection.cpp index 0ba8c36b2..a4970954f 100644 --- a/src/network/connection.cpp +++ b/src/network/connection.cpp @@ -200,17 +200,12 @@ RPBSearchResult ReliablePacketBuffer::findPacket(u16 seqnum) return i; } -RPBSearchResult ReliablePacketBuffer::notFound() -{ - return m_list.end(); -} - bool ReliablePacketBuffer::getFirstSeqnum(u16& result) { MutexAutoLock listlock(m_list_mutex); if (m_list.empty()) return false; - const BufferedPacket &p = *m_list.begin(); + const BufferedPacket &p = m_list.front(); result = readU16(&p.data[BASE_HEADER_SIZE + 1]); return true; } @@ -220,14 +215,14 @@ BufferedPacket ReliablePacketBuffer::popFirst() MutexAutoLock listlock(m_list_mutex); if (m_list.empty()) throw NotFoundException("Buffer is empty"); - BufferedPacket p = *m_list.begin(); - m_list.erase(m_list.begin()); + BufferedPacket p = std::move(m_list.front()); + m_list.pop_front(); if (m_list.empty()) { m_oldest_non_answered_ack = 0; } else { m_oldest_non_answered_ack = - readU16(&m_list.begin()->data[BASE_HEADER_SIZE + 1]); + readU16(&m_list.front().data[BASE_HEADER_SIZE + 1]); } return p; } @@ -241,15 +236,7 @@ BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum) << " not found in reliable buffer"<<std::endl); throw NotFoundException("seqnum not found in buffer"); } - BufferedPacket p = *r; - - - RPBSearchResult next = r; - ++next; - if (next != notFound()) { - u16 s = readU16(&(next->data[BASE_HEADER_SIZE+1])); - m_oldest_non_answered_ack = s; - } + BufferedPacket p = std::move(*r); m_list.erase(r); @@ -257,12 +244,12 @@ BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum) m_oldest_non_answered_ack = 0; } else { m_oldest_non_answered_ack = - readU16(&m_list.begin()->data[BASE_HEADER_SIZE + 1]); + readU16(&m_list.front().data[BASE_HEADER_SIZE + 1]); } return p; } -void ReliablePacketBuffer::insert(BufferedPacket &p, u16 next_expected) +void ReliablePacketBuffer::insert(const BufferedPacket &p, u16 next_expected) { MutexAutoLock listlock(m_list_mutex); if (p.data.getSize() < BASE_HEADER_SIZE + 3) { @@ -355,7 +342,7 @@ void ReliablePacketBuffer::insert(BufferedPacket &p, u16 next_expected) } /* update last packet number */ - m_oldest_non_answered_ack = readU16(&(*m_list.begin()).data[BASE_HEADER_SIZE+1]); + m_oldest_non_answered_ack = readU16(&m_list.front().data[BASE_HEADER_SIZE+1]); } void ReliablePacketBuffer::incrementTimeouts(float dtime) @@ -367,17 +354,19 @@ void ReliablePacketBuffer::incrementTimeouts(float dtime) } } -std::list<BufferedPacket> ReliablePacketBuffer::getTimedOuts(float timeout, - unsigned int max_packets) +std::list<BufferedPacket> + ReliablePacketBuffer::getTimedOuts(float timeout, u32 max_packets) { MutexAutoLock listlock(m_list_mutex); std::list<BufferedPacket> timed_outs; for (BufferedPacket &bufferedPacket : m_list) { if (bufferedPacket.time >= timeout) { + // caller will resend packet so reset time and increase counter + bufferedPacket.time = 0.0f; + bufferedPacket.resend_count++; + timed_outs.push_back(bufferedPacket); - //this packet will be sent right afterwards reset timeout here - bufferedPacket.time = 0.0f; if (timed_outs.size() >= max_packets) break; } @@ -1051,20 +1040,20 @@ bool UDPPeer::processReliableSendCommand( m_connection->GetProtocolID(), m_connection->GetPeerID(), c.channelnum); - toadd.push(p); + toadd.push(std::move(p)); } if (have_sequence_number) { volatile u16 pcount = 0; while (!toadd.empty()) { - BufferedPacket p = toadd.front(); + BufferedPacket p = std::move(toadd.front()); toadd.pop(); // LOG(dout_con<<connection->getDesc() // << " queuing reliable packet for peer_id: " << c.peer_id // << " channel: " << (c.channelnum&0xFF) // << " seqnum: " << readU16(&p.data[BASE_HEADER_SIZE+1]) // << std::endl) - chan.queued_reliables.push(p); + chan.queued_reliables.push(std::move(p)); pcount++; } sanity_check(chan.queued_reliables.size() < 0xFFFF); @@ -1208,12 +1197,19 @@ Connection::~Connection() } /* Internal stuff */ -void Connection::putEvent(ConnectionEvent &e) + +void Connection::putEvent(const ConnectionEvent &e) { assert(e.type != CONNEVENT_NONE); // Pre-condition m_event_queue.push_back(e); } +void Connection::putEvent(ConnectionEvent &&e) +{ + assert(e.type != CONNEVENT_NONE); // Pre-condition + m_event_queue.push_back(std::move(e)); +} + void Connection::TriggerSend() { m_sendThread->Trigger(); @@ -1299,7 +1295,7 @@ ConnectionEvent Connection::waitEvent(u32 timeout_ms) } } -void Connection::putCommand(ConnectionCommand &c) +void Connection::putCommand(const ConnectionCommand &c) { if (!m_shutting_down) { m_command_queue.push_back(c); @@ -1307,6 +1303,14 @@ void Connection::putCommand(ConnectionCommand &c) } } +void Connection::putCommand(ConnectionCommand &&c) +{ + if (!m_shutting_down) { + m_command_queue.push_back(std::move(c)); + m_sendThread->Trigger(); + } +} + void Connection::Serve(Address bind_addr) { ConnectionCommand c; @@ -1408,7 +1412,7 @@ void Connection::Send(session_t peer_id, u8 channelnum, ConnectionCommand c; c.send(peer_id, channelnum, pkt, reliable); - putCommand(c); + putCommand(std::move(c)); } Address Connection::GetPeerAddress(session_t peer_id) @@ -1508,12 +1512,12 @@ u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd) << "createPeer(): giving peer_id=" << peer_id_new << std::endl); ConnectionCommand cmd; - SharedBuffer<u8> reply(4); + Buffer<u8> reply(4); writeU8(&reply[0], PACKET_TYPE_CONTROL); writeU8(&reply[1], CONTROLTYPE_SET_PEER_ID); writeU16(&reply[2], peer_id_new); cmd.createPeer(peer_id_new,reply); - putCommand(cmd); + putCommand(std::move(cmd)); // Create peer addition event ConnectionEvent e; @@ -1560,7 +1564,7 @@ void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum) writeU16(&ack[2], seqnum); c.ack(peer_id, channelnum, ack); - putCommand(c); + putCommand(std::move(c)); m_sendThread->Trigger(); } diff --git a/src/network/connection.h b/src/network/connection.h index 24cd4fe4a..49bb65c3e 100644 --- a/src/network/connection.h +++ b/src/network/connection.h @@ -19,7 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once -#include "irrlichttypes_bloated.h" +#include "irrlichttypes.h" #include "peerhandler.h" #include "socket.h" #include "constants.h" @@ -29,7 +29,6 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "util/numeric.h" #include "networkprotocol.h" #include <iostream> -#include <fstream> #include <vector> #include <map> @@ -242,20 +241,19 @@ public: BufferedPacket popFirst(); BufferedPacket popSeqnum(u16 seqnum); - void insert(BufferedPacket &p, u16 next_expected); + void insert(const BufferedPacket &p, u16 next_expected); void incrementTimeouts(float dtime); - std::list<BufferedPacket> getTimedOuts(float timeout, - unsigned int max_packets); + std::list<BufferedPacket> getTimedOuts(float timeout, u32 max_packets); void print(); bool empty(); - RPBSearchResult notFound(); u32 size(); private: RPBSearchResult findPacket(u16 seqnum); // does not perform locking + inline RPBSearchResult notFound() { return m_list.end(); } std::list<BufferedPacket> m_list; @@ -329,18 +327,6 @@ struct ConnectionCommand bool raw = false; ConnectionCommand() = default; - ConnectionCommand &operator=(const ConnectionCommand &other) - { - type = other.type; - address = other.address; - peer_id = other.peer_id; - channelnum = other.channelnum; - // We must copy the buffer here to prevent race condition - data = SharedBuffer<u8>(*other.data, other.data.getSize()); - reliable = other.reliable; - raw = other.raw; - return *this; - } void serve(Address address_) { @@ -364,7 +350,7 @@ struct ConnectionCommand void send(session_t peer_id_, u8 channelnum_, NetworkPacket *pkt, bool reliable_); - void ack(session_t peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_) + void ack(session_t peer_id_, u8 channelnum_, const Buffer<u8> &data_) { type = CONCMD_ACK; peer_id = peer_id_; @@ -373,7 +359,7 @@ struct ConnectionCommand reliable = false; } - void createPeer(session_t peer_id_, const SharedBuffer<u8> &data_) + void createPeer(session_t peer_id_, const Buffer<u8> &data_) { type = CONCMD_CREATE_PEER; peer_id = peer_id_; @@ -707,7 +693,7 @@ struct ConnectionEvent ConnectionEvent() = default; - std::string describe() + const char *describe() const { switch(type) { case CONNEVENT_NONE: @@ -724,7 +710,7 @@ struct ConnectionEvent return "Invalid ConnectionEvent"; } - void dataReceived(session_t peer_id_, const SharedBuffer<u8> &data_) + void dataReceived(session_t peer_id_, const Buffer<u8> &data_) { type = CONNEVENT_DATA_RECEIVED; peer_id = peer_id_; @@ -763,7 +749,9 @@ public: /* Interface */ ConnectionEvent waitEvent(u32 timeout_ms); - void putCommand(ConnectionCommand &c); + // Warning: creates an unnecessary copy, prefer putCommand(T&&) if possible + void putCommand(const ConnectionCommand &c); + void putCommand(ConnectionCommand &&c); void SetTimeoutMs(u32 timeout) { m_bc_receive_timeout = timeout; } void Serve(Address bind_addr); @@ -802,11 +790,14 @@ protected: } UDPSocket m_udpSocket; + // Command queue: user -> SendThread MutexedQueue<ConnectionCommand> m_command_queue; bool Receive(NetworkPacket *pkt, u32 timeout); - void putEvent(ConnectionEvent &e); + // Warning: creates an unnecessary copy, prefer putEvent(T&&) if possible + void putEvent(const ConnectionEvent &e); + void putEvent(ConnectionEvent &&e); void TriggerSend(); @@ -815,6 +806,7 @@ protected: return getPeerNoEx(PEER_ID_SERVER) != nullptr; } private: + // Event queue: ReceiveThread -> user MutexedQueue<ConnectionEvent> m_event_queue; session_t m_peer_id = 0; diff --git a/src/network/connectionthreads.cpp b/src/network/connectionthreads.cpp index 7b62bc792..47678dac5 100644 --- a/src/network/connectionthreads.cpp +++ b/src/network/connectionthreads.cpp @@ -174,6 +174,11 @@ void ConnectionSendThread::runTimeouts(float dtime) std::vector<session_t> timeouted_peers; std::vector<session_t> peerIds = m_connection->getPeerIDs(); + const u32 numpeers = m_connection->m_peers.size(); + + if (numpeers == 0) + return; + for (session_t &peerId : peerIds) { PeerHelper peer = m_connection->getPeerNoEx(peerId); @@ -209,7 +214,6 @@ void ConnectionSendThread::runTimeouts(float dtime) float resend_timeout = udpPeer->getResendTimeout(); bool retry_count_exceeded = false; for (Channel &channel : udpPeer->channels) { - std::list<BufferedPacket> timed_outs; // Remove timed out incomplete unreliable split packets channel.incoming_splits.removeUnreliableTimedOuts(dtime, m_timeout); @@ -217,13 +221,8 @@ void ConnectionSendThread::runTimeouts(float dtime) // Increment reliable packet times channel.outgoing_reliables_sent.incrementTimeouts(dtime); - unsigned int numpeers = m_connection->m_peers.size(); - - if (numpeers == 0) - return; - // Re-send timed out outgoing reliables - timed_outs = channel.outgoing_reliables_sent.getTimedOuts(resend_timeout, + auto timed_outs = channel.outgoing_reliables_sent.getTimedOuts(resend_timeout, (m_max_data_packets_per_iteration / numpeers)); channel.UpdatePacketLossCounter(timed_outs.size()); @@ -231,16 +230,14 @@ void ConnectionSendThread::runTimeouts(float dtime) m_iteration_packets_avaialble -= timed_outs.size(); - for (std::list<BufferedPacket>::iterator k = timed_outs.begin(); - k != timed_outs.end(); ++k) { - session_t peer_id = readPeerId(*(k->data)); - u8 channelnum = readChannel(*(k->data)); - u16 seqnum = readU16(&(k->data[BASE_HEADER_SIZE + 1])); + for (const auto &k : timed_outs) { + session_t peer_id = readPeerId(*k.data); + u8 channelnum = readChannel(*k.data); + u16 seqnum = readU16(&(k.data[BASE_HEADER_SIZE + 1])); - channel.UpdateBytesLost(k->data.getSize()); - k->resend_count++; + channel.UpdateBytesLost(k.data.getSize()); - if (k->resend_count > MAX_RELIABLE_RETRY) { + if (k.resend_count > MAX_RELIABLE_RETRY) { retry_count_exceeded = true; timeouted_peers.push_back(peer->id); /* no need to check additional packets if a single one did timeout*/ @@ -249,14 +246,14 @@ void ConnectionSendThread::runTimeouts(float dtime) LOG(derr_con << m_connection->getDesc() << "RE-SENDING timed-out RELIABLE to " - << k->address.serializeString() + << k.address.serializeString() << "(t/o=" << resend_timeout << "): " << "from_peer_id=" << peer_id << ", channel=" << ((int) channelnum & 0xff) << ", seqnum=" << seqnum << std::endl); - rawSend(*k); + rawSend(k); // do not handle rtt here as we can't decide if this packet was // lost or really takes more time to transmit @@ -375,7 +372,7 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum, << " INFO: queueing reliable packet for peer_id: " << peer_id << " channel: " << (u32)channelnum << " seqnum: " << seqnum << std::endl); - channel->queued_reliables.push(p); + channel->queued_reliables.push(std::move(p)); return false; } @@ -717,13 +714,15 @@ void ConnectionSendThread::sendPackets(float dtime) channel.outgoing_reliables_sent.size() < channel.getWindowSize() && peer->m_increment_packets_remaining > 0) { - BufferedPacket p = channel.queued_reliables.front(); + BufferedPacket p = std::move(channel.queued_reliables.front()); channel.queued_reliables.pop(); + LOG(dout_con << m_connection->getDesc() << " INFO: sending a queued reliable packet " << " channel: " << i << ", seqnum: " << readU16(&p.data[BASE_HEADER_SIZE + 1]) << std::endl); + sendAsPacketReliable(p, &channel); peer->m_increment_packets_remaining--; } @@ -911,7 +910,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata, if (data_left) { ConnectionEvent e; e.dataReceived(peer_id, resultdata); - m_connection->putEvent(e); + m_connection->putEvent(std::move(e)); } } catch (ProcessedSilentlyException &e) { @@ -1022,7 +1021,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata, ConnectionEvent e; e.dataReceived(peer_id, resultdata); - m_connection->putEvent(e); + m_connection->putEvent(std::move(e)); } catch (ProcessedSilentlyException &e) { } diff --git a/src/network/networkpacket.cpp b/src/network/networkpacket.cpp index a71e26572..6b8b0f703 100644 --- a/src/network/networkpacket.cpp +++ b/src/network/networkpacket.cpp @@ -549,14 +549,11 @@ NetworkPacket& NetworkPacket::operator<<(video::SColor src) return *this; } -SharedBuffer<u8> NetworkPacket::oldForgePacket() +Buffer<u8> NetworkPacket::oldForgePacket() { - SharedBuffer<u8> sb(m_datasize + 2); + Buffer<u8> sb(m_datasize + 2); writeU16(&sb[0], m_command); + memcpy(&sb[2], m_data.data(), m_datasize); - u8* datas = getU8Ptr(0); - - if (datas != NULL) - memcpy(&sb[2], datas, m_datasize); return sb; } diff --git a/src/network/networkpacket.h b/src/network/networkpacket.h index c7ff03b8e..b1c44f055 100644 --- a/src/network/networkpacket.h +++ b/src/network/networkpacket.h @@ -115,7 +115,8 @@ public: NetworkPacket &operator<<(video::SColor src); // Temp, we remove SharedBuffer when migration finished - SharedBuffer<u8> oldForgePacket(); + // ^ this comment has been here for 4 years + Buffer<u8> oldForgePacket(); private: void checkReadOffset(u32 from_offset, u32 field_size); diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 88a5ac177..8214cc5b1 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -205,6 +205,9 @@ with this program; if not, write to the Free Software Foundation, Inc., Updated set_sky packet Adds new sun, moon and stars packets Minimap modes + PROTOCOL VERSION 40: + Added 'basic_debug' privilege + TOCLIENT_MEDIA_PUSH changed, TOSERVER_HAVE_MEDIA added */ #define LATEST_PROTOCOL_VERSION 40 @@ -315,9 +318,8 @@ enum ToClientCommand /* std::string raw_hash std::string filename + u32 callback_token bool should_be_cached - u32 len - char filedata[len] */ // (oops, there is some gap here) @@ -936,7 +938,13 @@ enum ToServerCommand } */ - TOSERVER_RECEIVED_MEDIA = 0x41, // Obsolete + TOSERVER_HAVE_MEDIA = 0x41, + /* + u8 number of callback tokens + for each: + u32 token + */ + TOSERVER_BREATH = 0x42, // Obsolete TOSERVER_CLIENT_READY = 0x43, diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index aea5d7174..44b65e8da 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -89,7 +89,7 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = null_command_handler, // 0x3e null_command_handler, // 0x3f { "TOSERVER_REQUEST_MEDIA", TOSERVER_STATE_STARTUP, &Server::handleCommand_RequestMedia }, // 0x40 - null_command_handler, // 0x41 + { "TOSERVER_HAVE_MEDIA", TOSERVER_STATE_INGAME, &Server::handleCommand_HaveMedia }, // 0x41 null_command_handler, // 0x42 { "TOSERVER_CLIENT_READY", TOSERVER_STATE_STARTUP, &Server::handleCommand_ClientReady }, // 0x43 null_command_handler, // 0x44 @@ -167,7 +167,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_TIME_OF_DAY", 0, true }, // 0x29 { "TOCLIENT_CSM_RESTRICTION_FLAGS", 0, true }, // 0x2A { "TOCLIENT_PLAYER_SPEED", 0, true }, // 0x2B - { "TOCLIENT_MEDIA_PUSH", 0, true }, // 0x2C (sent over channel 1 too) + { "TOCLIENT_MEDIA_PUSH", 0, true }, // 0x2C (sent over channel 1 too if legacy) null_command_factory, // 0x2D null_command_factory, // 0x2E { "TOCLIENT_CHAT_MESSAGE", 0, true }, // 0x2F diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 708ddbf20..4c609644f 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -362,16 +362,15 @@ void Server::handleCommand_RequestMedia(NetworkPacket* pkt) session_t peer_id = pkt->getPeerId(); infostream << "Sending " << numfiles << " files to " << getPlayerName(peer_id) << std::endl; - verbosestream << "TOSERVER_REQUEST_MEDIA: " << std::endl; + verbosestream << "TOSERVER_REQUEST_MEDIA: requested file(s)" << std::endl; for (u16 i = 0; i < numfiles; i++) { std::string name; *pkt >> name; - tosend.push_back(name); - verbosestream << "TOSERVER_REQUEST_MEDIA: requested file " - << name << std::endl; + tosend.emplace_back(name); + verbosestream << " " << name << std::endl; } sendRequestedMedia(peer_id, tosend); @@ -510,10 +509,6 @@ void Server::process_PlayerPos(RemotePlayer *player, PlayerSAO *playersao, playersao->setWantedRange(wanted_range); player->keyPressed = keyPressed; - player->control.up = (keyPressed & (0x1 << 0)); - player->control.down = (keyPressed & (0x1 << 1)); - player->control.left = (keyPressed & (0x1 << 2)); - player->control.right = (keyPressed & (0x1 << 3)); player->control.jump = (keyPressed & (0x1 << 4)); player->control.aux1 = (keyPressed & (0x1 << 5)); player->control.sneak = (keyPressed & (0x1 << 6)); @@ -832,7 +827,6 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) PlayerHPChangeReason reason(PlayerHPChangeReason::FALL); playersao->setHP((s32)playersao->getHP() - (s32)damage, reason); - SendPlayerHPOrDie(playersao, reason); } } @@ -1117,9 +1111,6 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) float time_from_last_punch = playersao->resetTimeFromLastPunch(); - u16 src_original_hp = pointed_object->getHP(); - u16 dst_origin_hp = playersao->getHP(); - u16 wear = pointed_object->punch(dir, &toolcap, playersao, time_from_last_punch); @@ -1129,18 +1120,6 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) if (changed) playersao->setWieldedItem(selected_item); - // If the object is a player and its HP changed - if (src_original_hp != pointed_object->getHP() && - pointed_object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { - SendPlayerHPOrDie((PlayerSAO *)pointed_object, - PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, playersao)); - } - - // If the puncher is a player and its HP changed - if (dst_origin_hp != playersao->getHP()) - SendPlayerHPOrDie(playersao, - PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, pointed_object)); - return; } // action == INTERACT_START_DIGGING @@ -1821,3 +1800,30 @@ void Server::handleCommand_ModChannelMsg(NetworkPacket *pkt) broadcastModChannelMessage(channel_name, channel_msg, peer_id); } + +void Server::handleCommand_HaveMedia(NetworkPacket *pkt) +{ + std::vector<u32> tokens; + u8 numtokens; + + *pkt >> numtokens; + for (u16 i = 0; i < numtokens; i++) { + u32 n; + *pkt >> n; + tokens.emplace_back(n); + } + + const session_t peer_id = pkt->getPeerId(); + auto player = m_env->getPlayer(peer_id); + + for (const u32 token : tokens) { + auto it = m_pending_dyn_media.find(token); + if (it == m_pending_dyn_media.end()) + continue; + if (it->second.waiting_players.count(peer_id)) { + it->second.waiting_players.erase(peer_id); + if (player) + getScriptIface()->on_dynamic_media_added(token, player->getName()); + } + } +} |
