unsigned int CArchiveScanner::GetArchiveCompleteChecksum(const std::string& name) const { const std::vector<std::string>& ars = GetAllArchivesUsedBy(name); unsigned int checksum = 0; for (unsigned int a = 0; a < ars.size(); a++) { checksum ^= GetSingleArchiveChecksum(ars[a]); } LOG_S(LOG_SECTION_ARCHIVESCANNER, "archive checksum %s: %d/%u", name.c_str(), checksum, checksum); return checksum; }
unsigned int CArchiveScanner::GetArchiveCompleteChecksum(const std::string& name) { const std::vector<std::string> ars = GetAllArchivesUsedBy(name); unsigned int checksum = 0; for (const std::string& depName: ars) { const std::string& archive = ArchiveFromName(depName); checksum ^= GetSingleArchiveChecksum(GetArchivePath(archive) + archive); } LOG_S(LOG_SECTION_ARCHIVESCANNER, "archive checksum %s: %d/%u", name.c_str(), checksum, checksum); return checksum; }
std::vector<std::string> CArchiveScanner::GetAllArchivesUsedBy(const std::string& root, int depth) const { LOG_S(LOG_SECTION_ARCHIVESCANNER, "GetArchives: %s (depth %u)", root.c_str(), depth); // Protect against circular dependencies // (worst case depth is if all archives form one huge dependency chain) if ((unsigned)depth > archiveInfos.size()) { throw content_error("Circular dependency"); } std::vector<std::string> ret; std::string resolvedName = ArchiveNameResolver::GetGame(root); std::string lcname = StringToLower(ArchiveFromName(resolvedName)); std::map<std::string, ArchiveInfo>::const_iterator aii = archiveInfos.find(lcname); if (aii == archiveInfos.end()) { #ifdef UNITSYNC // unresolved dep, add it, so unitsync still shows this file ret.push_back(lcname); return ret; #else throw content_error("Archive \"" + lcname + "\" not found"); #endif } // Check if this archive has been replaced while (aii->second.replaced.length() > 0) { // FIXME instead of this, call this function recursively, to get the propper error handling aii = archiveInfos.find(aii->second.replaced); if (aii == archiveInfos.end()) { #ifdef UNITSYNC // unresolved dep, add it, so unitsync still shows this file ret.push_back(lcname); return ret; #else throw content_error("Unknown error parsing archive replacements"); #endif } } // add depth-first ret.push_back(aii->second.path + aii->second.origName); for (const std::string& dep: aii->second.archiveData.GetDependencies()) { const std::vector<std::string>& deps = GetAllArchivesUsedBy(dep, depth + 1); for (const std::string& depSub: deps) { AddDependency(ret, depSub); } } return ret; }