1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Dynamic_Add_Media v2 (#11550)

This commit is contained in:
sfan5 2021-09-09 16:51:35 +02:00 committed by GitHub
parent bcb6565483
commit bbfae0cc67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 796 additions and 246 deletions

View file

@ -670,21 +670,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);
}
@ -716,31 +714,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();
if (init_phase) {
// Mesh update thread must be stopped while
// updating content definitions
sanity_check(!m_mesh_update_thread.isRunning());
}
// 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;
}
}
}
@ -1497,46 +1502,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);
}
/*