void LegacyUpdate::jarStart() { LegacyInstance *inst = (LegacyInstance *)m_inst; if (!inst->shouldUpdate() || inst->shouldUseCustomBaseJar()) { ModTheJar(); return; } setStatus(tr("Checking for jar updates...")); // Make directories QDir binDir(inst->binDir()); if (!binDir.exists() && !binDir.mkpath(".")) { emitFailed("Failed to create bin folder."); return; } // Build a list of URLs that will need to be downloaded. setStatus(tr("Downloading new minecraft.jar ...")); QString version_id = inst->intendedVersionId(); QString localPath = version_id + "/" + version_id + ".jar"; QString urlstr = "http://" + URLConstants::AWS_DOWNLOAD_VERSIONS + localPath; auto dljob = new NetJob("Minecraft.jar for version " + version_id); auto metacache = MMC->metacache(); auto entry = metacache->resolveEntry("versions", localPath); dljob->addNetAction(CacheDownload::make(QUrl(urlstr), entry)); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); connect(dljob, SIGNAL(failed()), SLOT(jarFailed())); connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); legacyDownloadJob.reset(dljob); legacyDownloadJob->start(); }
void LegacyUpdate::ModTheJar() { LegacyInstance *inst = (LegacyInstance *)m_inst; if (!inst->shouldRebuild()) { emitSucceeded(); return; } // Get the mod list auto modList = inst->jarModList(); QFileInfo runnableJar(inst->runnableJar()); QFileInfo baseJar(inst->baseJar()); bool base_is_custom = inst->shouldUseCustomBaseJar(); // Nothing to do if there are no jar mods to install, no backup and just the mc jar if (base_is_custom) { // yes, this can happen if the instance only has the runnable jar and not the base jar // it *could* be assumed that such an instance is vanilla, but that wouldn't be safe // because that's not something mmc4 guarantees if (runnableJar.isFile() && !baseJar.exists() && modList->empty()) { inst->setShouldRebuild(false); emitSucceeded(); return; } setStatus(tr("Installing mods: Backing up minecraft.jar ...")); if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath())) { emitFailed("It seems both the active and base jar are gone. A fresh base jar will " "be used on next run."); inst->setShouldRebuild(true); inst->setShouldUpdate(true); inst->setShouldUseCustomBaseJar(false); return; } } if (!baseJar.exists()) { emitFailed("The base jar " + baseJar.filePath() + " does not exist"); return; } if (runnableJar.exists() && !QFile::remove(runnableJar.filePath())) { emitFailed("Failed to delete old minecraft.jar"); return; } // TaskStep(); // STEP 1 setStatus(tr("Installing mods: Opening minecraft.jar ...")); QuaZip zipOut(runnableJar.filePath()); if (!zipOut.open(QuaZip::mdCreate)) { QFile::remove(runnableJar.filePath()); emitFailed("Failed to open the minecraft.jar for modding"); return; } // Files already added to the jar. // These files will be skipped. QSet<QString> addedFiles; // Modify the jar setStatus(tr("Installing mods: Adding mod files...")); for (int i = modList->size() - 1; i >= 0; i--) { auto &mod = modList->operator[](i); // do not merge disabled mods. if (!mod.enabled()) continue; if (mod.type() == Mod::MOD_ZIPFILE) { if (!MergeZipFiles(&zipOut, mod.filename(), addedFiles, LegacyUpdate::KeepMetainf)) { zipOut.close(); QFile::remove(runnableJar.filePath()); emitFailed("Failed to add " + mod.filename().fileName() + " to the jar."); return; } } else if (mod.type() == Mod::MOD_SINGLEFILE) { auto filename = mod.filename(); if (!JlCompress::compressFile(&zipOut, filename.absoluteFilePath(), filename.fileName())) { zipOut.close(); QFile::remove(runnableJar.filePath()); emitFailed("Failed to add " + filename.fileName() + " to the jar"); return; } addedFiles.insert(filename.fileName()); QLOG_INFO() << "Adding file " << filename.fileName() << " from " << filename.absoluteFilePath(); } else if (mod.type() == Mod::MOD_FOLDER) { auto filename = mod.filename(); QString what_to_zip = filename.absoluteFilePath(); QDir dir(what_to_zip); dir.cdUp(); QString parent_dir = dir.absolutePath(); if (!JlCompress::compressSubDir(&zipOut, what_to_zip, parent_dir, true, addedFiles)) { zipOut.close(); QFile::remove(runnableJar.filePath()); emitFailed("Failed to add " + filename.fileName() + " to the jar"); return; } QLOG_INFO() << "Adding folder " << filename.fileName() << " from " << filename.absoluteFilePath(); } } if (!MergeZipFiles(&zipOut, baseJar, addedFiles, LegacyUpdate::IgnoreMetainf)) { zipOut.close(); QFile::remove(runnableJar.filePath()); emitFailed("Failed to insert minecraft.jar contents."); return; } // Recompress the jar zipOut.close(); if (zipOut.getZipError() != 0) { QFile::remove(runnableJar.filePath()); emitFailed("Failed to finalize minecraft.jar!"); return; } inst->setShouldRebuild(false); // inst->UpdateVersion(true); emitSucceeded(); return; }