Exemple #1
0
wxThread::ExitCode ModderTask::TaskStart()
{
	// Get the mod list
	ModList *modList = m_inst->GetModList();
	
	wxFileName mcBin = m_inst->GetBinDir();
	wxFileName mcJar = m_inst->GetMCJar();
	wxFileName mcBackup = m_inst->GetMCBackup();
	
	// Nothing to do if there are no jar mods to install, no backup and just the mc jar
	if(mcJar.FileExists() && !mcBackup.FileExists() && modList->empty())
	{
		m_inst->SetNeedsRebuild(false);
		return (ExitCode)1;
	}
	
	SetStatus(_("Installing mods - backing up minecraft.jar..."));
	if (!mcBackup.FileExists() && !wxCopyFile(mcJar.GetFullPath(), mcBackup.GetFullPath()))
	{
		OnFail(_("Failed to back up minecraft.jar"));
		return (ExitCode)0;
	}
	
	if (mcJar.FileExists() && !wxRemoveFile(mcJar.GetFullPath()))
	{
		OnFail(_("Failed to delete old minecraft.jar"));
		return (ExitCode)0;
	}
	
	// TODO: good spot for user cancel check? or not...
	
	TaskStep(); // STEP 1
	SetStatus(_("Installing mods - Opening minecraft.jar"));

	wxFFileOutputStream jarStream(mcJar.GetFullPath());
	wxZipOutputStream zipOut(jarStream);

	// Files already added to the jar.
	// These files will be skipped.
	std::set<wxString> addedFiles;

	// Modify the jar
	TaskStep(); // STEP 2
	SetStatus(_("Installing mods - Adding mod files..."));
	for (ModList::const_reverse_iterator iter = modList->rbegin(); iter != modList->rend(); iter++)
	{
		wxFileName modFileName = iter->GetFileName();
		SetStatus(_("Installing mods - Adding ") + modFileName.GetFullName());
		if (iter->IsZipMod())
		{
			wxFFileInputStream modStream(modFileName.GetFullPath());
			wxZipInputStream zipStream(modStream);
			std::auto_ptr<wxZipEntry> entry;
			while (entry.reset(zipStream.GetNextEntry()), entry.get() != NULL)
			{
				if (entry->IsDir())
					continue;

				wxString name = entry->GetName();
				if (addedFiles.count(name) == 0)
				{
					if (!zipOut.CopyEntry(entry.release(), zipStream))
						break;
					addedFiles.insert(name);
				}
			}
		}
		else
		{
			wxFileName destFileName = modFileName;
			destFileName.MakeRelativeTo(m_inst->GetInstModsDir().GetFullPath());
			wxString destFile = destFileName.GetFullPath();

			if (addedFiles.count(destFile) == 0)
			{
				wxFFileInputStream input(modFileName.GetFullPath());
				zipOut.PutNextEntry(destFile);
				zipOut.Write(input);

				addedFiles.insert(destFile);
			}
		}
	}

	{
		wxFFileInputStream inStream(mcBackup.GetFullPath());
		wxZipInputStream zipIn(inStream);

		std::auto_ptr<wxZipEntry> entry;
		while (entry.reset(zipIn.GetNextEntry()), entry.get() != NULL)
		{
			wxString name = entry->GetName();

			if (!name.Matches("META-INF*") &&
				addedFiles.count(name) == 0)
			{
				if (!zipOut.CopyEntry(entry.release(), zipIn))
					break;
				addedFiles.insert(name);
			}
		}
	}
	
	// Recompress the jar
	TaskStep(); // STEP 3
	SetStatus(_("Installing mods - Recompressing jar..."));

	m_inst->SetNeedsRebuild(false);
	m_inst->UpdateVersion(true);
	return (ExitCode)1;
}
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;
}
Exemple #3
0
void ModderTask::TaskStart()
{
    // Get the mod list
    const ModList *modList = m_inst->GetModList();

    wxFileName mcBin = m_inst->GetBinDir();
    wxFileName mcJar = m_inst->GetMCJar();
    wxFileName mcBackup = m_inst->GetMCBackup();

    SetStatus(_("Installing mods - backing up minecraft.jar..."));
    if (!mcBackup.FileExists() && !wxCopyFile(mcJar.GetFullPath(), mcBackup.GetFullPath()))
    {
        OnFail(_("Failed to back up minecraft.jar"));
        return;
    }

    if (mcJar.FileExists() && !wxRemoveFile(mcJar.GetFullPath()))
    {
        OnFail(_("Failed to delete old minecraft.jar"));
        return;
    }


    if (TestDestroy())
        return;
    TaskStep(); // STEP 1
    SetStatus(_("Installing mods - Opening minecraft.jar"));

    wxFFileOutputStream jarStream(mcJar.GetFullPath());
    wxZipOutputStream zipOut(jarStream);

    {
        wxFFileInputStream inStream(mcBackup.GetFullPath());
        wxZipInputStream zipIn(inStream);

        std::auto_ptr<wxZipEntry> entry;
        while (entry.reset(zipIn.GetNextEntry()), entry.get() != NULL)
            if (!entry->GetName().Matches(_("META-INF*")))
                if (!zipOut.CopyEntry(entry.release(), zipIn))
                    break;
    }

    // Modify the jar
    TaskStep(); // STEP 2
    SetStatus(_("Installing mods - Adding mod files..."));
    for (ConstModIterator iter = modList->begin(); iter != modList->end(); iter++)
    {
        wxFileName modFileName = iter->GetFileName();
        SetStatus(_("Installing mods - Adding ") + modFileName.GetFullName());
        if (iter->IsZipMod())
        {
            wxFFileInputStream modStream(modFileName.GetFullPath());
            TransferZipArchive(modStream, zipOut);
        }
        else
        {
            wxFileName destFileName = modFileName;
            destFileName.MakeRelativeTo(m_inst->GetInstModsDir().GetFullPath());

            wxFFileInputStream input(modFileName.GetFullPath());
            zipOut.PutNextEntry(destFileName.GetFullPath());
            zipOut.Write(input);
        }
    }

    // Recompress the jar
    TaskStep(); // STEP 3
    SetStatus(_("Installing mods - Recompressing jar..."));

    m_inst->SetNeedsRebuild(false);
}