bool Materials::loadExtensions(FileName directoryName, wxString& error, wxArrayString& warnings) { directoryName.Mkdir(0755, wxPATH_MKDIR_FULL); // Create if it doesn't exist wxDir ext_dir(directoryName.GetPath()); if(!ext_dir.IsOpened()) { error = "Could not open extensions directory."; return false; } wxString filename; if(!ext_dir.GetFirst(&filename)) { // No extensions found return true; } StringVector clientVersions; do { FileName fn; fn.SetPath(directoryName.GetPath()); fn.SetFullName(filename); if(fn.GetExt() != "xml") { continue; } pugi::xml_document doc; pugi::xml_parse_result result = doc.load_file(fn.GetFullPath().mb_str()); if(!result) { warnings.push_back("Could not open " + filename + " (file not found or syntax error)"); continue; } pugi::xml_node extensionNode = doc.child("materialsextension"); if(!extensionNode) { warnings.push_back(filename + ": Invalid rootheader."); continue; } pugi::xml_attribute attribute; if(!(attribute = extensionNode.attribute("name"))) { warnings.push_back(filename + ": Couldn't read extension name."); continue; } const std::string& extensionName = attribute.as_string(); if(!(attribute = extensionNode.attribute("author"))) { warnings.push_back(filename + ": Couldn't read extension name."); continue; } const std::string& extensionAuthor = attribute.as_string(); if(!(attribute = extensionNode.attribute("description"))) { warnings.push_back(filename + ": Couldn't read extension name."); continue; } const std::string& extensionDescription = attribute.as_string(); if(extensionName.empty() || extensionAuthor.empty() || extensionDescription.empty()) { warnings.push_back(filename + ": Couldn't read extension attributes (name, author, description)."); continue; } std::string extensionUrl = extensionNode.attribute("url").as_string(); extensionUrl.erase(std::remove(extensionUrl.begin(), extensionUrl.end(), '\'')); std::string extensionAuthorLink = extensionNode.attribute("authorurl").as_string(); extensionAuthorLink.erase(std::remove(extensionAuthorLink.begin(), extensionAuthorLink.end(), '\'')); MaterialsExtension* materialExtension = newd MaterialsExtension(extensionName, extensionAuthor, extensionDescription); materialExtension->url = extensionUrl; materialExtension->author_url = extensionAuthorLink; if((attribute = extensionNode.attribute("client"))) { clientVersions.clear(); const std::string& extensionClientString = attribute.as_string(); size_t lastPosition = 0; size_t position = extensionClientString.find(';'); while(position != std::string::npos) { clientVersions.push_back(extensionClientString.substr(lastPosition, position - lastPosition)); lastPosition = position + 1; position = extensionClientString.find(';', lastPosition); } clientVersions.push_back(extensionClientString.substr(lastPosition)); for(const std::string& version : clientVersions) { materialExtension->addVersion(version); } std::sort(materialExtension->version_list.begin(), materialExtension->version_list.end(), VersionComparisonPredicate); auto duplicate = std::unique(materialExtension->version_list.begin(), materialExtension->version_list.end()); while(duplicate != materialExtension->version_list.end()) { materialExtension->version_list.erase(duplicate); duplicate = std::unique(materialExtension->version_list.begin(), materialExtension->version_list.end()); } } else { warnings.push_back(filename + ": Extension is not available for any version."); } extensions.push_back(materialExtension); if(materialExtension->isForVersion(g_gui.GetCurrentVersionID())) { unserializeMaterials(filename, extensionNode, error, warnings); } } while(ext_dir.GetNext(&filename)); return true; }
bool Materials::loadExtensions(FileName directoryName, wxString& error, wxArrayString& warnings) { directoryName.Mkdir(0755, wxPATH_MKDIR_FULL); // Create if it doesn't exist wxDir ext_dir(directoryName.GetPath()); if(ext_dir.IsOpened() == false) { error = wxT("Could not open extensions directory."); return false; } wxString filename; if(!ext_dir.GetFirst(&filename)) { // No extensions found return true; } do { FileName fn; fn.SetPath(directoryName.GetPath()); fn.SetFullName(filename); if(fn.GetExt() != wxT("xml")) continue; xmlDocPtr doc = xmlParseFile(fn.GetFullPath().mb_str()); if(doc) { xmlNodePtr root = xmlDocGetRootElement(doc); if(xmlStrcmp(root->name,(const xmlChar*)"materialsextension") != 0){ xmlFreeDoc(doc); warnings.push_back(filename + wxT(": Invalid rootheader.")); continue; } std::string ext_name, ext_url, ext_author, ext_author_link, ext_desc, ext_client_str; StringVector clientVersions; if( !readXMLValue(root, "name", ext_name) || !readXMLValue(root, "author", ext_author) || !readXMLValue(root, "description", ext_desc)) { warnings.push_back(filename + wxT(": Couldn't read extension attributes (name, author, description).")); continue; } readXMLValue(root, "url", ext_url); ext_url.erase(std::remove(ext_url.begin(), ext_url.end(), '\''), ext_url.end()); readXMLValue(root, "authorurl", ext_author_link); ext_author_link.erase(std::remove(ext_author_link.begin(), ext_author_link.end(), '\''), ext_author_link.end()); MaterialsExtension* me = newd MaterialsExtension(ext_name, ext_author, ext_desc); me->url = ext_url; me->author_url = ext_author_link; if(readXMLValue(root, "client", ext_client_str)) { size_t last_pos = std::numeric_limits<size_t>::max(); size_t pos; do { size_t to_pos = (last_pos == std::numeric_limits<size_t>::max()? 0 : last_pos+1); pos = ext_client_str.find(';', to_pos); if(size_t(pos) != std::string::npos) { clientVersions.push_back(ext_client_str.substr(to_pos, pos-(to_pos))); last_pos = pos; } else { clientVersions.push_back(ext_client_str.substr(to_pos)); break; } } while(true); for(StringVector::iterator iter = clientVersions.begin(); iter != clientVersions.end(); ++iter) { me->addVersion(*iter); } std::sort(me->version_list.begin(), me->version_list.end(), VersionComparisonPredicate); me->version_list.erase(std::unique(me->version_list.begin(), me->version_list.end()), me->version_list.end()); } else { warnings.push_back(filename + wxT(": Extension is not available for any version.")); } extensions.push_back(me); if(me->isForVersion(gui.GetCurrentVersionID())) { unserializeMaterials(filename, root, error, warnings); } } else { warnings.push_back(wxT("Could not open ") + filename + wxT(" (file not found or syntax error)")); continue; } } while(ext_dir.GetNext(&filename)); return true; }