@@ -65,13 +65,17 @@ bool ClientNetworkContentSocketHandler::
for (uint j = 0; j < sizeof(ci->md5sum); j++) {
ci->md5sum[j] = p->Recv_uint8();
}
uint dependency_count = p->Recv_uint8();
ci->dependencies.reserve(dependency_count);
for (uint i = 0; i < dependency_count; i++) ci->dependencies.push_back((ContentID)p->Recv_uint32());
for (uint i = 0; i < dependency_count; i++) {
ContentID dependency_cid = (ContentID)p->Recv_uint32();
ci->dependencies.push_back(dependency_cid);
this->reverse_dependency_map.insert({ dependency_cid, ci->id });
uint tag_count = p->Recv_uint8();
ci->tags.reserve(tag_count);
for (uint i = 0; i < tag_count; i++) ci->tags.push_back(p->Recv_string(NETWORK_CONTENT_TAG_LENGTH));
if (!ci->IsValid()) {
@@ -165,14 +169,16 @@ bool ClientNetworkContentSocketHandler::
return true;
this->infos.push_back(ci);
/* Incoming data means that we might need to reconsider dependencies */
for (ContentInfo *ici : this->infos) {
this->CheckDependencyState(ici);
ConstContentVector parents;
this->ReverseLookupTreeDependency(parents, ci);
for (const ContentInfo *ici : parents) {
this->CheckDependencyState(const_cast<ContentInfo *>(ici));
this->OnReceiveContentInfo(ci);
@@ -830,13 +836,13 @@ void ClientNetworkContentSocketHandler::
/**
* Get the content info based on a ContentID
* @param cid the ContentID to search for
* @return the ContentInfo or nullptr if not found
*/
ContentInfo *ClientNetworkContentSocketHandler::GetContent(ContentID cid)
ContentInfo *ClientNetworkContentSocketHandler::GetContent(ContentID cid) const
{
for (ContentInfo *ci : this->infos) {
if (ci->id == cid) return ci;
return nullptr;
@@ -920,21 +926,16 @@ void ClientNetworkContentSocketHandler::
* Reverse lookup the dependencies of (direct) parents over a given child.
* @param parents list to store all parents in (is not cleared)
* @param child the child to search the parents' dependencies for
void ClientNetworkContentSocketHandler::ReverseLookupDependency(ConstContentVector &parents, const ContentInfo *child) const
for (const ContentInfo *ci : this->infos) {
if (ci == child) continue;
auto range = this->reverse_dependency_map.equal_range(child->id);
for (auto &dependency : ci->dependencies) {
if (dependency == child->id) {
parents.push_back(ci);
break;
for (auto iter = range.first; iter != range.second; ++iter) {
parents.push_back(GetContent(iter->second));
* Reverse lookup the dependencies of all parents over a given child.
* @param tree list to store all parents in (is not cleared)
@@ -1053,12 +1054,13 @@ void ClientNetworkContentSocketHandler::
void ClientNetworkContentSocketHandler::Clear()
for (ContentInfo *c : this->infos) delete c;
this->infos.clear();
this->requested.clear();
this->reverse_dependency_map.clear();
/*** CALLBACK ***/
void ClientNetworkContentSocketHandler::OnConnect(bool success)
@@ -9,12 +9,13 @@
#ifndef NETWORK_CONTENT_H
#define NETWORK_CONTENT_H
#include "core/tcp_content.h"
#include "core/tcp_http.h"
#include <unordered_map>
/** Vector with content info */
typedef std::vector<ContentInfo *> ContentVector;
/** Vector with constant content info */
typedef std::vector<const ContentInfo *> ConstContentVector;
@@ -65,12 +66,13 @@ struct ContentCallback {
class ClientNetworkContentSocketHandler : public NetworkContentSocketHandler, ContentCallback, HTTPCallback {
protected:
typedef std::vector<ContentID> ContentIDList; ///< List of content IDs to (possibly) select.
std::vector<ContentCallback *> callbacks; ///< Callbacks to notify "the world"
ContentIDList requested; ///< ContentIDs we already requested (so we don't do it again)
ContentVector infos; ///< All content info we received
std::unordered_multimap<ContentID, ContentID> reverse_dependency_map; ///< Content reverse dependency map
std::vector<char> http_response; ///< The HTTP response to the requests we've been doing
int http_response_index; ///< Where we are, in the response, with handling it
FILE *curFile; ///< Currently downloaded file
ContentInfo *curInfo; ///< Information about the currently downloaded file
bool isConnecting; ///< Whether we're connecting
@@ -78,13 +80,13 @@ protected:
friend class NetworkContentConnecter;
bool Receive_SERVER_INFO(Packet *p) override;
bool Receive_SERVER_CONTENT(Packet *p) override;
ContentInfo *GetContent(ContentID cid);
ContentInfo *GetContent(ContentID cid) const;
void DownloadContentInfo(ContentID cid);
void OnConnect(bool success) override;
void OnDisconnect() override;
void OnReceiveContentInfo(const ContentInfo *ci) override;
void OnDownloadProgress(const ContentInfo *ci, int bytes) override;
Status change: