Much change, very jarmod.

This commit is contained in:
Petr Mrázek 2014-05-05 00:10:59 +02:00
parent aade36860c
commit 4c3bd416c6
46 changed files with 3735 additions and 142 deletions

View file

@ -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;
}