summaryrefslogtreecommitdiffstats
path: root/logic/OneSixUpdate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'logic/OneSixUpdate.cpp')
-rw-r--r--logic/OneSixUpdate.cpp214
1 files changed, 212 insertions, 2 deletions
diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp
index da2fd29c..230ef9a9 100644
--- a/logic/OneSixUpdate.cpp
+++ b/logic/OneSixUpdate.cpp
@@ -259,7 +259,7 @@ void OneSixUpdate::jarlibStart()
auto metacache = MMC->metacache();
auto entry = metacache->resolveEntry("versions", localPath);
job->addNetAction(CacheDownload::make(QUrl(urlstr), entry));
-
+ jarHashOnEntry = entry->md5sum;
jarlibDownloadJob.reset(job);
}
@@ -341,7 +341,36 @@ void OneSixUpdate::jarlibStart()
void OneSixUpdate::jarlibFinished()
{
- assetIndexStart();
+ OneSixInstance *inst = (OneSixInstance *)m_inst;
+ std::shared_ptr<VersionFinal> version = inst->getFullVersion();
+
+ // create stripped jar, if needed
+ if(version->hasJarMods())
+ {
+ //FIXME: good candidate for moving elsewhere (jar location resolving/version caching).
+ QString version_id = version->id;
+ QString localPath = version_id + "/" + version_id + ".jar";
+ QString strippedPath = version_id + "/" + version_id + "-stripped.jar";
+ auto metacache = MMC->metacache();
+ auto entry = metacache->resolveEntry("versions", localPath);
+ auto entryStripped = metacache->resolveEntry("versions", strippedPath);
+
+ QString fullJarPath = entry->getFullPath();
+ QString fullStrippedJarPath = entryStripped->getFullPath();
+
+ if(entry->md5sum != jarHashOnEntry || !QFileInfo::exists(fullStrippedJarPath))
+ {
+ stripJar(fullJarPath, fullStrippedJarPath);
+ }
+ }
+ if(version->traits.contains("legacyFML"))
+ {
+ fmllibsStart();
+ }
+ else
+ {
+ assetIndexStart();
+ }
}
void OneSixUpdate::jarlibFailed()
@@ -350,3 +379,184 @@ void OneSixUpdate::jarlibFailed()
QString failed_all = failed.join("\n");
emitFailed(tr("Failed to download the following files:\n%1\n\nPlease try again.").arg(failed_all));
}
+
+void OneSixUpdate::stripJar(QString origPath, QString newPath)
+{
+ QFileInfo runnableJar(newPath);
+ if (runnableJar.exists() && !QFile::remove(runnableJar.filePath()))
+ {
+ emitFailed("Failed to delete old minecraft.jar");
+ return;
+ }
+
+ // TaskStep(); // STEP 1
+ setStatus(tr("Creating stripped jar: Opening minecraft.jar ..."));
+
+ QuaZip zipOut(runnableJar.filePath());
+ if (!zipOut.open(QuaZip::mdCreate))
+ {
+ QFile::remove(runnableJar.filePath());
+ emitFailed("Failed to open the minecraft.jar for stripping");
+ return;
+ }
+ // Modify the jar
+ setStatus(tr("Creating stripped jar: Adding files..."));
+ if (!MergeZipFiles(&zipOut, origPath))
+ {
+ zipOut.close();
+ QFile::remove(runnableJar.filePath());
+ emitFailed("Failed to add " + origPath + " to the jar.");
+ return;
+ }
+}
+
+bool OneSixUpdate::MergeZipFiles(QuaZip *into, QString from)
+{
+ setStatus(tr("Installing mods: Adding ") + from + " ...");
+
+ QuaZip modZip(from);
+ modZip.open(QuaZip::mdUnzip);
+
+ QuaZipFile fileInsideMod(&modZip);
+ QuaZipFile zipOutFile(into);
+ for (bool more = modZip.goToFirstFile(); more; more = modZip.goToNextFile())
+ {
+ QString filename = modZip.getCurrentFileName();
+ if (filename.contains("META-INF"))
+ {
+ QLOG_INFO() << "Skipping META-INF " << filename << " from " << from;
+ continue;
+ }
+ QLOG_INFO() << "Adding file " << filename << " from " << from;
+
+ if (!fileInsideMod.open(QIODevice::ReadOnly))
+ {
+ QLOG_ERROR() << "Failed to open " << filename << " from " << from;
+ return false;
+ }
+ /*
+ QuaZipFileInfo old_info;
+ fileInsideMod.getFileInfo(&old_info);
+ */
+ QuaZipNewInfo info_out(fileInsideMod.getActualFileName());
+ /*
+ info_out.externalAttr = old_info.externalAttr;
+ */
+ if (!zipOutFile.open(QIODevice::WriteOnly, info_out))
+ {
+ QLOG_ERROR() << "Failed to open " << filename << " in the jar";
+ fileInsideMod.close();
+ return false;
+ }
+ if (!JlCompress::copyData(fileInsideMod, zipOutFile))
+ {
+ zipOutFile.close();
+ fileInsideMod.close();
+ QLOG_ERROR() << "Failed to copy data of " << filename << " into the jar";
+ return false;
+ }
+ zipOutFile.close();
+ fileInsideMod.close();
+ }
+ return true;
+}
+
+
+void OneSixUpdate::fmllibsStart()
+{
+ // Get the mod list
+ OneSixInstance *inst = (OneSixInstance *)m_inst;
+ std::shared_ptr<VersionFinal> fullversion = inst->getFullVersion();
+ bool forge_present = false;
+
+ QString version = inst->intendedVersionId();
+ auto & fmlLibsMapping = g_VersionFilterData.fmlLibsMapping;
+ if (!fmlLibsMapping.contains(version))
+ {
+ assetIndexStart();
+ return;
+ }
+
+ auto &libList = fmlLibsMapping[version];
+
+ // determine if we need some libs for FML or forge
+ setStatus(tr("Checking for FML libraries..."));
+ forge_present = (fullversion->versionFile("net.minecraftforge") != nullptr);
+ // we don't...
+ if (!forge_present)
+ {
+ assetIndexStart();
+ return;
+ }
+
+ // now check the lib folder inside the instance for files.
+ for (auto &lib : libList)
+ {
+ QFileInfo libInfo(PathCombine(inst->libDir(), lib.filename));
+ if (libInfo.exists())
+ continue;
+ fmlLibsToProcess.append(lib);
+ }
+
+ // if everything is in place, there's nothing to do here...
+ if (fmlLibsToProcess.isEmpty())
+ {
+ assetIndexStart();
+ return;
+ }
+
+ // download missing libs to our place
+ setStatus(tr("Dowloading FML libraries..."));
+ auto dljob = new NetJob("FML libraries");
+ auto metacache = MMC->metacache();
+ for (auto &lib : fmlLibsToProcess)
+ {
+ auto entry = metacache->resolveEntry("fmllibs", lib.filename);
+ QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename
+ : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename;
+ dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry));
+ }
+
+ connect(dljob, SIGNAL(succeeded()), SLOT(fmllibsFinished()));
+ connect(dljob, SIGNAL(failed()), SLOT(fmllibsFailed()));
+ connect(dljob, SIGNAL(progress(qint64, qint64)), SIGNAL(progress(qint64, qint64)));
+ legacyDownloadJob.reset(dljob);
+ legacyDownloadJob->start();
+}
+
+void OneSixUpdate::fmllibsFinished()
+{
+ legacyDownloadJob.reset();
+ if(!fmlLibsToProcess.isEmpty())
+ {
+ setStatus(tr("Copying FML libraries into the instance..."));
+ OneSixInstance *inst = (OneSixInstance *)m_inst;
+ auto metacache = MMC->metacache();
+ int index = 0;
+ for (auto &lib : fmlLibsToProcess)
+ {
+ progress(index, fmlLibsToProcess.size());
+ auto entry = metacache->resolveEntry("fmllibs", lib.filename);
+ auto path = PathCombine(inst->libDir(), lib.filename);
+ if(!ensureFilePathExists(path))
+ {
+ emitFailed(tr("Failed creating FML library folder inside the instance."));
+ return;
+ }
+ if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.filename)))
+ {
+ emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
+ return;
+ }
+ index++;
+ }
+ progress(index, fmlLibsToProcess.size());
+ }
+ assetIndexStart();
+}
+
+void OneSixUpdate::fmllibsFailed()
+{
+ emitFailed("Game update failed: it was impossible to fetch the required FML libraries.");
+ return;
+} \ No newline at end of file