Some more updater fixes
Paths were wrong - still used work directory instead of root
This commit is contained in:
parent
76f58eb42c
commit
613c01dab5
37
MultiMC.cpp
37
MultiMC.cpp
@ -261,6 +261,7 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &data_dir_override)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
connect(this, SIGNAL(aboutToQuit()), SLOT(onExit()));
|
||||||
m_status = MultiMC::Initialized;
|
m_status = MultiMC::Initialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,8 +511,21 @@ std::shared_ptr<JavaVersionList> MultiMC::javalist()
|
|||||||
return m_javalist;
|
return m_javalist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish)
|
void MultiMC::installUpdates(const QString updateFilesDir, UpdateFlags flags)
|
||||||
{
|
{
|
||||||
|
// if we are going to update on exit, save the params now
|
||||||
|
if(flags & OnExit)
|
||||||
|
{
|
||||||
|
m_updateOnExitPath = updateFilesDir;
|
||||||
|
m_updateOnExitFlags = flags & ~OnExit;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// otherwise if there already were some params for on exit update, clear them and continue
|
||||||
|
else if(m_updateOnExitPath.size())
|
||||||
|
{
|
||||||
|
m_updateOnExitFlags = None;
|
||||||
|
m_updateOnExitPath.clear();
|
||||||
|
}
|
||||||
QLOG_INFO() << "Installing updates.";
|
QLOG_INFO() << "Installing updates.";
|
||||||
#ifdef WINDOWS
|
#ifdef WINDOWS
|
||||||
QString finishCmd = MMC->applicationFilePath();
|
QString finishCmd = MMC->applicationFilePath();
|
||||||
@ -533,16 +547,15 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish
|
|||||||
args << "--package-dir" << updateFilesDir;
|
args << "--package-dir" << updateFilesDir;
|
||||||
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
||||||
args << "--wait" << QString::number(MMC->applicationPid());
|
args << "--wait" << QString::number(MMC->applicationPid());
|
||||||
#ifdef MultiMC_UPDATER_DRY_RUN
|
if(flags & DryRun)
|
||||||
args << "--dry-run";
|
args << "--dry-run";
|
||||||
#endif
|
if (flags & RestartOnFinish)
|
||||||
if (restartOnFinish)
|
|
||||||
args << "--finish-cmd" << finishCmd;
|
args << "--finish-cmd" << finishCmd;
|
||||||
|
|
||||||
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
|
QLOG_INFO() << "Running updater with command" << updaterBinary << args.join(" ");
|
||||||
QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
|
QFile::setPermissions(updaterBinary, (QFileDevice::Permission)0x7755);
|
||||||
|
|
||||||
if (!QProcess::startDetached(updaterBinary, args))
|
if (!QProcess::startDetached(updaterBinary, args/*, root()*/))
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "Failed to start the updater process!";
|
QLOG_ERROR() << "Failed to start the updater process!";
|
||||||
return;
|
return;
|
||||||
@ -552,14 +565,12 @@ void MultiMC::installUpdates(const QString &updateFilesDir, bool restartOnFinish
|
|||||||
MMC->quit();
|
MMC->quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiMC::setUpdateOnExit(const QString &updateFilesDir)
|
void MultiMC::onExit()
|
||||||
{
|
{
|
||||||
m_updateOnExitPath = updateFilesDir;
|
if(m_updateOnExitPath.size())
|
||||||
}
|
{
|
||||||
|
installUpdates(m_updateOnExitPath, m_updateOnExitFlags);
|
||||||
QString MultiMC::getExitUpdatePath() const
|
}
|
||||||
{
|
|
||||||
return m_updateOnExitPath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MultiMC::openJsonEditor(const QString &filename)
|
bool MultiMC::openJsonEditor(const QString &filename)
|
||||||
|
38
MultiMC.h
38
MultiMC.h
@ -6,6 +6,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "logger/QsLog.h"
|
#include "logger/QsLog.h"
|
||||||
#include "logger/QsLogDest.h"
|
#include "logger/QsLogDest.h"
|
||||||
|
#include <QFlag>
|
||||||
|
|
||||||
class MinecraftVersionList;
|
class MinecraftVersionList;
|
||||||
class LWJGLVersionList;
|
class LWJGLVersionList;
|
||||||
@ -32,9 +33,19 @@ enum InstSortMode
|
|||||||
// Sort alphabetically by name.
|
// Sort alphabetically by name.
|
||||||
Sort_Name,
|
Sort_Name,
|
||||||
// Sort by which instance was launched most recently.
|
// Sort by which instance was launched most recently.
|
||||||
Sort_LastLaunch,
|
Sort_LastLaunch
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum UpdateFlag
|
||||||
|
{
|
||||||
|
None = 0x0,
|
||||||
|
RestartOnFinish = 0x1,
|
||||||
|
DryRun = 0x2,
|
||||||
|
OnExit = 0x4
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(UpdateFlags, UpdateFlag);
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateFlags);
|
||||||
|
|
||||||
class MultiMC : public QApplication
|
class MultiMC : public QApplication
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -43,7 +54,7 @@ public:
|
|||||||
{
|
{
|
||||||
Failed,
|
Failed,
|
||||||
Succeeded,
|
Succeeded,
|
||||||
Initialized,
|
Initialized
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -110,21 +121,7 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<JavaVersionList> javalist();
|
std::shared_ptr<JavaVersionList> javalist();
|
||||||
|
|
||||||
/*!
|
void installUpdates(const QString updateFilesDir, UpdateFlags flags = None);
|
||||||
* Installs update from the given update files directory.
|
|
||||||
*/
|
|
||||||
void installUpdates(const QString &updateFilesDir, bool restartOnFinish = false);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Sets MultiMC to install updates from the given directory when it exits.
|
|
||||||
*/
|
|
||||||
void setUpdateOnExit(const QString &updateFilesDir);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Gets the path to install updates from on exit.
|
|
||||||
* If this is an empty string, no updates should be installed on exit.
|
|
||||||
*/
|
|
||||||
QString getExitUpdatePath() const;
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Opens a json file using either a system default editor, or, if note empty, the editor
|
* Opens a json file using either a system default editor, or, if note empty, the editor
|
||||||
@ -155,6 +152,12 @@ public:
|
|||||||
return origcwdPath;
|
return origcwdPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/**
|
||||||
|
* Do all the things that should be done before we exit
|
||||||
|
*/
|
||||||
|
void onExit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initLogger();
|
void initLogger();
|
||||||
|
|
||||||
@ -187,6 +190,7 @@ private:
|
|||||||
QsLogging::DestinationPtr m_debugDestination;
|
QsLogging::DestinationPtr m_debugDestination;
|
||||||
|
|
||||||
QString m_updateOnExitPath;
|
QString m_updateOnExitPath;
|
||||||
|
UpdateFlags m_updateOnExitFlags = None;
|
||||||
|
|
||||||
QString rootPath;
|
QString rootPath;
|
||||||
QString binPath;
|
QString binPath;
|
||||||
|
@ -568,10 +568,14 @@ void MainWindow::downloadUpdates(QString repo, int versionId, bool installOnExit
|
|||||||
// If the task succeeds, install the updates.
|
// If the task succeeds, install the updates.
|
||||||
if (updateDlg.exec(&updateTask))
|
if (updateDlg.exec(&updateTask))
|
||||||
{
|
{
|
||||||
|
UpdateFlags baseFlags = None;
|
||||||
|
#ifdef MultiMC_UPDATER_DRY_RUN
|
||||||
|
baseFlags |= DryRun;
|
||||||
|
#endif
|
||||||
if (installOnExit)
|
if (installOnExit)
|
||||||
MMC->setUpdateOnExit(updateTask.updateFilesDir());
|
MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | OnExit);
|
||||||
else
|
else
|
||||||
MMC->installUpdates(updateTask.updateFilesDir(), true);
|
MMC->installUpdates(updateTask.updateFilesDir(), baseFlags | RestartOnFinish);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,12 +290,11 @@ DownloadUpdateTask::processFileLists(NetJob *job,
|
|||||||
// delete anything in the current one version's list that isn't in the new version's list.
|
// delete anything in the current one version's list that isn't in the new version's list.
|
||||||
for (VersionFileEntry entry : currentVersion)
|
for (VersionFileEntry entry : currentVersion)
|
||||||
{
|
{
|
||||||
QFileInfo toDelete(entry.path);
|
QFileInfo toDelete(PathCombine(MMC->root(), entry.path));
|
||||||
if (!toDelete.exists())
|
if (!toDelete.exists())
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath()
|
QLOG_ERROR() << "Expected file " << toDelete.absoluteFilePath()
|
||||||
<< " doesn't exist!";
|
<< " doesn't exist!";
|
||||||
QLOG_ERROR() << "CWD: " << QDir::currentPath();
|
|
||||||
}
|
}
|
||||||
bool keep = false;
|
bool keep = false;
|
||||||
|
|
||||||
@ -314,7 +313,6 @@ DownloadUpdateTask::processFileLists(NetJob *job,
|
|||||||
// If the loop reaches the end and we didn't find a match, delete the file.
|
// If the loop reaches the end and we didn't find a match, delete the file.
|
||||||
if (!keep)
|
if (!keep)
|
||||||
{
|
{
|
||||||
QFileInfo toDelete(entry.path);
|
|
||||||
if (toDelete.exists())
|
if (toDelete.exists())
|
||||||
ops.append(UpdateOperation::DeleteOp(entry.path));
|
ops.append(UpdateOperation::DeleteOp(entry.path));
|
||||||
}
|
}
|
||||||
@ -326,8 +324,9 @@ DownloadUpdateTask::processFileLists(NetJob *job,
|
|||||||
// TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
|
// TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
|
||||||
// way to do this in the background.
|
// way to do this in the background.
|
||||||
QString fileMD5;
|
QString fileMD5;
|
||||||
QFile entryFile(entry.path);
|
QString realEntryPath = PathCombine(MMC->root(), entry.path);
|
||||||
QFileInfo entryInfo(entry.path);
|
QFile entryFile(realEntryPath);
|
||||||
|
QFileInfo entryInfo(realEntryPath);
|
||||||
|
|
||||||
bool needs_upgrade = false;
|
bool needs_upgrade = false;
|
||||||
if (!entryFile.exists())
|
if (!entryFile.exists())
|
||||||
@ -339,49 +338,52 @@ DownloadUpdateTask::processFileLists(NetJob *job,
|
|||||||
bool pass = true;
|
bool pass = true;
|
||||||
if (!entryInfo.isReadable())
|
if (!entryInfo.isReadable())
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "File " << entry.path << " is not readable.";
|
QLOG_ERROR() << "File " << realEntryPath << " is not readable.";
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
if (!entryInfo.isWritable())
|
if (!entryInfo.isWritable())
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "File " << entry.path << " is not writable.";
|
QLOG_ERROR() << "File " << realEntryPath << " is not writable.";
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
if (!entryFile.open(QFile::ReadOnly))
|
if (!entryFile.open(QFile::ReadOnly))
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "File " << entry.path << " cannot be opened for reading.";
|
QLOG_ERROR() << "File " << realEntryPath << " cannot be opened for reading.";
|
||||||
pass = false;
|
pass = false;
|
||||||
}
|
}
|
||||||
if (!pass)
|
if (!pass)
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "CWD: " << QDir::currentPath();
|
QLOG_ERROR() << "ROOT: " << MMC->root();
|
||||||
ops.clear();
|
ops.clear();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QCryptographicHash hash(QCryptographicHash::Md5);
|
if(!needs_upgrade)
|
||||||
auto foo = entryFile.readAll();
|
|
||||||
|
|
||||||
hash.addData(foo);
|
|
||||||
fileMD5 = hash.result().toHex();
|
|
||||||
if ((fileMD5 != entry.md5))
|
|
||||||
{
|
{
|
||||||
QLOG_DEBUG() << "MD5Sum does not match!";
|
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||||
QLOG_DEBUG() << "Expected:'" << entry.md5 << "'";
|
auto foo = entryFile.readAll();
|
||||||
QLOG_DEBUG() << "Got: '" << fileMD5 << "'";
|
|
||||||
needs_upgrade = true;
|
hash.addData(foo);
|
||||||
|
fileMD5 = hash.result().toHex();
|
||||||
|
if ((fileMD5 != entry.md5))
|
||||||
|
{
|
||||||
|
QLOG_DEBUG() << "MD5Sum does not match!";
|
||||||
|
QLOG_DEBUG() << "Expected:'" << entry.md5 << "'";
|
||||||
|
QLOG_DEBUG() << "Got: '" << fileMD5 << "'";
|
||||||
|
needs_upgrade = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip file. it doesn't need an upgrade.
|
// skip file. it doesn't need an upgrade.
|
||||||
if (!needs_upgrade)
|
if (!needs_upgrade)
|
||||||
{
|
{
|
||||||
QLOG_DEBUG() << "File" << entry.path << " does not need updating.";
|
QLOG_DEBUG() << "File" << realEntryPath << " does not need updating.";
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// yep. this file actually needs an upgrade. PROCEED.
|
// yep. this file actually needs an upgrade. PROCEED.
|
||||||
QLOG_DEBUG() << "Found file" << entry.path << " that needs updating.";
|
QLOG_DEBUG() << "Found file" << realEntryPath << " that needs updating.";
|
||||||
|
|
||||||
// if it's the updater we want to treat it separately
|
// if it's the updater we want to treat it separately
|
||||||
bool isUpdater = entry.path.endsWith("updater") || entry.path.endsWith("updater.exe");
|
bool isUpdater = entry.path.endsWith("updater") || entry.path.endsWith("updater.exe");
|
||||||
|
8
main.cpp
8
main.cpp
@ -10,13 +10,7 @@ int main_gui(MultiMC &app)
|
|||||||
mainWin.show();
|
mainWin.show();
|
||||||
mainWin.checkMigrateLegacyAssets();
|
mainWin.checkMigrateLegacyAssets();
|
||||||
mainWin.checkSetDefaultJava();
|
mainWin.checkSetDefaultJava();
|
||||||
auto exitCode = app.exec();
|
return app.exec();
|
||||||
|
|
||||||
// Update if necessary.
|
|
||||||
if (!app.getExitUpdatePath().isEmpty())
|
|
||||||
app.installUpdates(app.getExitUpdatePath(), false);
|
|
||||||
|
|
||||||
return exitCode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
@ -271,15 +271,15 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
|
|||||||
{
|
{
|
||||||
std::string sourceFile = file.source;
|
std::string sourceFile = file.source;
|
||||||
std::string destPath = file.dest;
|
std::string destPath = file.dest;
|
||||||
std::string target = file.linkTarget;
|
std::string absDestPath = FileUtils::makeAbsolute(destPath.c_str(), m_installDir.c_str());
|
||||||
|
|
||||||
LOG(Info,"Installing file " + sourceFile + " to " + destPath);
|
LOG(Info,"Installing file " + sourceFile + " to " + absDestPath);
|
||||||
|
|
||||||
// backup the existing file if any
|
// backup the existing file if any
|
||||||
backupFile(destPath);
|
backupFile(absDestPath);
|
||||||
|
|
||||||
// create the target directory if it does not exist
|
// create the target directory if it does not exist
|
||||||
std::string destDir = FileUtils::dirname(destPath.c_str());
|
std::string destDir = FileUtils::dirname(absDestPath.c_str());
|
||||||
if (!FileUtils::fileExists(destDir.c_str()))
|
if (!FileUtils::fileExists(destDir.c_str()))
|
||||||
{
|
{
|
||||||
LOG(Info,"Destination path missing. Creating " + destDir);
|
LOG(Info,"Destination path missing. Creating " + destDir);
|
||||||
@ -295,10 +295,10 @@ void UpdateInstaller::installFile(const UpdateScriptFile& file)
|
|||||||
}
|
}
|
||||||
if(!m_dryRun)
|
if(!m_dryRun)
|
||||||
{
|
{
|
||||||
FileUtils::copyFile(sourceFile.c_str(),destPath.c_str());
|
FileUtils::copyFile(sourceFile.c_str(),absDestPath.c_str());
|
||||||
|
|
||||||
// set the permissions on the newly extracted file
|
// set the permissions on the newly extracted file
|
||||||
FileUtils::chmod(destPath.c_str(),file.permissions);
|
FileUtils::chmod(absDestPath.c_str(),file.permissions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +326,7 @@ void UpdateInstaller::uninstallFiles()
|
|||||||
std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
|
std::vector<std::string>::const_iterator iter = m_script->filesToUninstall().begin();
|
||||||
for (;iter != m_script->filesToUninstall().end();iter++)
|
for (;iter != m_script->filesToUninstall().end();iter++)
|
||||||
{
|
{
|
||||||
std::string path = m_installDir + '/' + iter->c_str();
|
std::string path = FileUtils::makeAbsolute(iter->c_str(), m_installDir.c_str());
|
||||||
if (FileUtils::fileExists(path.c_str()))
|
if (FileUtils::fileExists(path.c_str()))
|
||||||
{
|
{
|
||||||
LOG(Info,"Uninstalling " + path);
|
LOG(Info,"Uninstalling " + path);
|
||||||
|
@ -41,7 +41,6 @@ class UpdateScriptFile
|
|||||||
std::string source;
|
std::string source;
|
||||||
/// The path to copy to.
|
/// The path to copy to.
|
||||||
std::string dest;
|
std::string dest;
|
||||||
std::string linkTarget;
|
|
||||||
|
|
||||||
/** The permissions for this file, specified
|
/** The permissions for this file, specified
|
||||||
* using the standard Unix mode_t values.
|
* using the standard Unix mode_t values.
|
||||||
|
Loading…
Reference in New Issue
Block a user