]> git.lizzy.rs Git - minetest.git/blobdiff - src/network/clientpackethandler.cpp
Replace std::list<session_t> in networking code (#10215)
[minetest.git] / src / network / clientpackethandler.cpp
index e000acc928d767a56d6c27386a5bf522a14e30a2..8d87ff8f215e7ebb98031df8fc7dc80b248d4e2b 100644 (file)
@@ -39,6 +39,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "script/scripting_client.h"
 #include "util/serialize.h"
 #include "util/srp.h"
+#include "util/sha1.h"
 #include "tileanimation.h"
 #include "gettext.h"
 #include "skyparams.h"
@@ -207,6 +208,9 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
                m_access_denied_reconnect = reconnect & 1;
        } else if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) {
                *pkt >> m_access_denied_reason;
+       } else if (denyCode == SERVER_ACCESSDENIED_TOO_MANY_USERS) {
+               m_access_denied_reason = accessDeniedStrings[denyCode];
+               m_access_denied_reconnect = true;
        } else if (denyCode < SERVER_ACCESSDENIED_MAX) {
                m_access_denied_reason = accessDeniedStrings[denyCode];
        } else {
@@ -1471,6 +1475,51 @@ void Client::handleCommand_PlayerSpeed(NetworkPacket *pkt)
        player->addVelocity(added_vel);
 }
 
+void Client::handleCommand_MediaPush(NetworkPacket *pkt)
+{
+       std::string raw_hash, filename, filedata;
+       bool cached;
+
+       *pkt >> raw_hash >> filename >> cached;
+       filedata = pkt->readLongString();
+
+       if (raw_hash.size() != 20 || filedata.empty() || filename.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;
+
+       if (m_media_pushed_files.count(filename) != 0) {
+               // Silently ignore for synchronization purposes
+               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;
+               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);
+}
+
 /*
  * Mod channels
  */