From c18ba89e5c9306fa5e231da75ea3aaed20ef8dc3 Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Sun, 29 Sep 2013 22:25:38 +0100 Subject: [PATCH] Issue #73. Metadata editor not yet updated. --- src/backend/generators.h | 37 +++++++++++++++++++++ src/backend/metadata.cpp | 70 ++++++++++++++++++++++++++++++++++++++++ src/backend/metadata.h | 25 ++++++++++++++ src/backend/parsers.h | 32 ++++++++++++++++++ 4 files changed, 164 insertions(+) diff --git a/src/backend/generators.h b/src/backend/generators.h index f3689235..9ebe5ef5 100644 --- a/src/backend/generators.h +++ b/src/backend/generators.h @@ -411,6 +411,32 @@ namespace boss { } } + std::set dirtyInfo = it->DirtyInfo(); + for (std::set::const_iterator jt=dirtyInfo.begin(), endjt=dirtyInfo.end(); jt != endjt; ++jt) { + boost::format f; + if (jt->ITMs() > -1 && jt->UDRs() > -1 && jt->DeletedNavmeshes() > -1) + f = boost::format(boost::locale::translate("Contains %1% ITM records, %2% UDR records and %3% deleted navmeshes. Needs %4% cleaning, a guide is available \"%5% here\".")) % jt->ITMs() % jt->UDRs() % jt->DeletedNavmeshes() % jt->CleaningUtility() % jt->CleaningGuideURL(); + else if (jt->ITMs() == -1 && jt->UDRs() == -1 && jt->DeletedNavmeshes() == -1) + f = boost::format(boost::locale::translate("Needs %1% cleaning, a guide is available \"%2% here\".")) % jt->CleaningUtility() % jt->CleaningGuideURL(); + + else if (jt->ITMs() == -1 && jt->UDRs() > -1 && jt->DeletedNavmeshes() > -1) + f = boost::format(boost::locale::translate("Contains %1% UDR records and %2% deleted navmeshes. Needs %3% cleaning, a guide is available \"%4% here\".")) % jt->UDRs() % jt->DeletedNavmeshes() % jt->CleaningUtility() % jt->CleaningGuideURL(); + else if (jt->ITMs() == -1 && jt->UDRs() == -1 && jt->DeletedNavmeshes() > -1) + f = boost::format(boost::locale::translate("Contains %1% deleted navmeshes. Needs %2% cleaning, a guide is available \"%3% here\".")) % jt->DeletedNavmeshes() % jt->CleaningUtility() % jt->CleaningGuideURL(); + else if (jt->ITMs() == -1 && jt->UDRs() > -1 && jt->DeletedNavmeshes() == -1) + f = boost::format(boost::locale::translate("Contains %1% UDR records. Needs %2% cleaning, a guide is available \"%3% here\".")) % jt->UDRs() % jt->CleaningUtility() % jt->CleaningGuideURL(); + + else if (jt->ITMs() > -1 && jt->UDRs() == -1 && jt->DeletedNavmeshes() > -1) + f = boost::format(boost::locale::translate("Contains %1% ITM records and %2% deleted navmeshes. Needs %3% cleaning, a guide is available \"%4% here\".")) % jt->ITMs() % jt->DeletedNavmeshes() % jt->CleaningUtility() % jt->CleaningGuideURL(); + else if (jt->ITMs() > -1 && jt->UDRs() == -1 && jt->DeletedNavmeshes() == -1) + f = boost::format(boost::locale::translate("Contains %1% ITM records. Needs %2% cleaning, a guide is available \"%3% here\".")) % jt->ITMs() % jt->CleaningUtility() % jt->CleaningGuideURL(); + + else if (jt->ITMs() > -1 && jt->UDRs() > -1 && jt->DeletedNavmeshes() == -1) + f = boost::format(boost::locale::translate("Contains %1% ITM records and %2% UDR records. Needs %3% cleaning, a guide is available \"%4% here\".")) % jt->ITMs() % jt->UDRs() % jt->CleaningUtility() % jt->CleaningGuideURL(); + + messages.push_back(boss::Message(boss::g_message_warn, f.str())); + } + AppendMessages(plugin, messages, warnNo, errorNo); } } @@ -651,6 +677,17 @@ namespace YAML { out << EndSeq; } + inline Emitter& operator << (Emitter& out, const boss::DirtData& rhs) { + out << BeginMap + << Key << "crc" << Value << rhs.CRC() + << Key << "itm" << Value << rhs.ITMs() + << Key << "udr" << Value << rhs.UDRs() + << Key << "nav" << Value << rhs.DeletedNavmeshes() + << Key << "util" << Value << rhs.CleaningUtility() + << Key << "guide" << Value << rhs.CleaningGuideURL() + << EndMap; + } + inline Emitter& operator << (Emitter& out, const boss::Game& rhs) { out << BeginMap << Key << "folder" << Value << rhs.FolderName() diff --git a/src/backend/metadata.cpp b/src/backend/metadata.cpp index 287a484c..adef585a 100644 --- a/src/backend/metadata.cpp +++ b/src/backend/metadata.cpp @@ -74,6 +74,39 @@ namespace boss { return id; } + DirtData::DirtData() : _crc(0), _itm(-1), _udr(-1), _nav(-1) {} + + DirtData::DirtData(uint32_t crc, int itm, int udr, int nav, const std::string& utility, const std::string& guideURL) : _crc(crc), _itm(itm), _udr(udr), _nav(nav), _utility(utility), _guideURL(guideURL) {} + + bool DirtData::operator < (const DirtData& rhs) const { + return _crc < rhs.CRC(); + } + + uint32_t DirtData::CRC() const { + return _crc; + } + + int DirtData::ITMs() const { + return _itm; + } + + int DirtData::UDRs() const { + return _udr; + } + + int DirtData::DeletedNavmeshes() const { + return _nav; + } + + std::string DirtData::CleaningUtility() const { + return _utility; + } + + std::string DirtData::CleaningGuideURL() const { + return _guideURL; + } + + ConditionStruct::ConditionStruct() {} ConditionStruct::ConditionStruct(const string& condition) : _condition(condition) {} @@ -405,6 +438,9 @@ namespace boss { std::list pMessages = plugin.Messages(); messages.insert(messages.end(), pMessages.begin(), pMessages.end()); + set dirtyInfo = plugin.DirtyInfo(); + _dirtyInfo.insert(dirtyInfo.begin(), dirtyInfo.end()); + return; } @@ -441,6 +477,11 @@ namespace boss { set_symmetric_difference(bashTags.begin(), bashTags.end(), tags.begin(), tags.end(), inserter(tagDiff, tagDiff.begin())); p.Tags(tagDiff); + set dirtyInfo = plugin.DirtyInfo(); + set dirtDiff; + set_symmetric_difference(dirtyInfo.begin(), dirtyInfo.end(), _dirtyInfo.begin(), _dirtyInfo.end(), inserter(dirtDiff, dirtDiff.begin())); + p.DirtyInfo(dirtDiff); + return p; } @@ -476,6 +517,10 @@ namespace boss { return tags; } + std::set Plugin::DirtyInfo() const { + return _dirtyInfo; + } + void Plugin::Name(const std::string& n) { name = n; } @@ -508,6 +553,10 @@ namespace boss { tags = t; } + void Plugin::DirtyInfo(const std::set& dirtyInfo) { + _dirtyInfo = dirtyInfo; + } + void Plugin::EvalAllConditions(boss::Game& game, const unsigned int language) { for (set::iterator it = loadAfter.begin(); it != loadAfter.end();) { if (!it->EvalCondition(game)) @@ -543,6 +592,27 @@ namespace boss { else ++it; } + + //First need to get plugin's CRC. + uint32_t crc = 0; + boost::unordered_map::iterator it = game.crcCache.find(boost::to_lower_copy(name)); + if (it != game.crcCache.end()) + crc = it->second; + else if (boost::filesystem::exists(game.DataPath() / name)) { + crc = GetCrc32(game.DataPath() / name); + game.crcCache.emplace(boost::to_lower_copy(name), crc); + } else if (boost::filesystem::exists(game.DataPath() / (name + ".ghost"))) { + crc = GetCrc32(game.DataPath() / (name + ".ghost")); + game.crcCache.emplace(boost::to_lower_copy(name), crc); + } else + _dirtyInfo.clear(); + + for (set::iterator it = _dirtyInfo.begin(); it != _dirtyInfo.end();) { + if (it->CRC() != crc) + _dirtyInfo.erase(it++); + else + ++it; + } } bool Plugin::HasNameOnly() const { diff --git a/src/backend/metadata.h b/src/backend/metadata.h index df20d3be..b49e0e73 100644 --- a/src/backend/metadata.h +++ b/src/backend/metadata.h @@ -52,6 +52,28 @@ namespace boss { uint32_t id; }; + class DirtData { + public: + DirtData(); + DirtData(uint32_t crc, int itm, int udr, int nav, const std::string& utility, const std::string& guideURL); + + bool operator < (const DirtData& rhs) const; + + uint32_t CRC() const; + int ITMs() const; + int UDRs() const; + int DeletedNavmeshes() const; + std::string CleaningUtility() const; + std::string CleaningGuideURL() const; + private: + uint32_t _crc; + int _itm; + int _udr; + int _nav; + std::string _utility; + std::string _guideURL; + }; + class ConditionStruct { public: ConditionStruct(); @@ -149,6 +171,7 @@ namespace boss { std::set Incs() const; std::list Messages() const; std::set Tags() const; + std::set DirtyInfo() const; const std::set& FormIDs() const; std::vector Masters() const; @@ -164,6 +187,7 @@ namespace boss { void Incs(const std::set& incs); void Messages(const std::list& messages); void Tags(const std::set& tags); + void DirtyInfo(const std::set& info); void EvalAllConditions(boss::Game& game, const unsigned int language); bool HasNameOnly() const; @@ -191,6 +215,7 @@ namespace boss { std::set incompatibilities; std::list messages; std::set tags; + std::set _dirtyInfo; std::vector masters; std::set formIDs; diff --git a/src/backend/parsers.h b/src/backend/parsers.h index ee2c8fa1..37c95d76 100644 --- a/src/backend/parsers.h +++ b/src/backend/parsers.h @@ -109,6 +109,38 @@ namespace YAML { } }; + template<> + struct convert { + static Node encode(const boss::DirtData& rhs) { + Node node; + node["crc"] = rhs.CRC(); + node["itm"] = rhs.ITMs(); + node["udr"] = rhs.UDRs(); + node["nav"] = rhs.DeletedNavmeshes(); + node["util"] = rhs.CleaningUtility(); + node["guide"] = rhs.CleaningGuideURL(); + + return node; + } + + static bool decode(const Node& node, boss::DirtData& rhs) { + if (!node.IsMap() || !node["crc"] || !node["util"] || !node["guide"]) + return false; + + uint32_t crc = node["crc"].as(); + int itm = node["itm"].as(); + int udr = node["udr"].as(); + int nav = node["nav"].as(); + + std::string util = node["util"].as(); + std::string guide = node["guide"].as(); + + rhs = boss::DirtData(crc, itm, udr, nav, util, guide); + + return true; + } + }; + template<> struct convert { static Node encode(const boss::MessageContent& rhs) {