bool CModManager::doInstallMod(QString modname, QString archivePath) { QString destDir = CLauncherDirs::get().modsPath() + "/"; if(!QFile(archivePath).exists()) return addError(modname, "Mod archive is missing"); if(localMods.contains(modname)) return addError(modname, "Mod with such name is already installed"); QString modDirName = detectModArchive(archivePath, modname); if(!modDirName.size()) return addError(modname, "Mod archive is invalid or corrupted"); if(!ZipArchive::extract(qstringToPath(archivePath), qstringToPath(destDir))) { removeModDir(destDir + modDirName); return addError(modname, "Failed to extract mod data"); } QVariantMap json = JsonUtils::JsonFromFile(destDir + modDirName + "/mod.json").toMap(); localMods.insert(modname, json); modList->setLocalModList(localMods); modList->modChanged(modname); return true; }
static QString detectModArchive(QString path, QString modName) { auto files = ZipArchive::listFiles(qstringToPath(path)); QString modDirName; for(auto file : files) { QString filename = QString::fromUtf8(file.c_str()); if(filename.toLower().startsWith(modName)) { // archive must contain mod.json file if(filename.toLower() == modName + "/mod.json") modDirName = filename.section('/', 0, 0); } else // all files must be in <modname> directory { return ""; } } return modDirName; }
void JsonToFile(QString filename, QVariant object) { FileStream file(qstringToPath(filename), std::ios::out | std::ios_base::binary); file << toJson(object); }