GH-1053 move instance update into the launch task (BaseLauncher)

This commit is contained in:
Petr Mrázek 2015-07-04 20:02:43 +02:00
parent 5628d3d379
commit 526a511f45
18 changed files with 303 additions and 262 deletions

View File

@ -53,7 +53,7 @@ private:
BasePage * m_log_page;
};
ConsoleWindow::ConsoleWindow(BaseLauncher *process, QWidget *parent)
ConsoleWindow::ConsoleWindow(std::shared_ptr<BaseLauncher> process, QWidget *parent)
: QMainWindow(parent), m_proc(process)
{
MultiMCPlatform::fixWM_CLASS(this);
@ -129,11 +129,11 @@ ConsoleWindow::ConsoleWindow(BaseLauncher *process, QWidget *parent)
}
// Set up signal connections
connect(m_proc, SIGNAL(ended(InstancePtr, int, QProcess::ExitStatus)), this,
connect(m_proc.get(), SIGNAL(ended(InstancePtr, int, QProcess::ExitStatus)), this,
SLOT(onEnded(InstancePtr, int, QProcess::ExitStatus)));
connect(m_proc, SIGNAL(prelaunch_failed(InstancePtr, int, QProcess::ExitStatus)), this,
connect(m_proc.get(), SIGNAL(prelaunch_failed(InstancePtr, int, QProcess::ExitStatus)), this,
SLOT(onEnded(InstancePtr, int, QProcess::ExitStatus)));
connect(m_proc, SIGNAL(launch_failed(InstancePtr)), this,
connect(m_proc.get(), SIGNAL(launch_failed(InstancePtr)), this,
SLOT(onLaunchFailed(InstancePtr)));
setMayClose(false);

View File

@ -26,7 +26,7 @@ class ConsoleWindow : public QMainWindow
Q_OBJECT
public:
explicit ConsoleWindow(BaseLauncher *proc, QWidget *parent = 0);
explicit ConsoleWindow(std::shared_ptr<BaseLauncher> proc, QWidget *parent = 0);
virtual ~ConsoleWindow();
/**
@ -56,7 +56,7 @@ protected:
void closeEvent(QCloseEvent *);
private:
BaseLauncher *m_proc = nullptr;
std::shared_ptr<BaseLauncher> m_proc;
bool m_mayclose = true;
QSystemTrayIcon *m_trayIcon = nullptr;
PageContainer *m_container = nullptr;

View File

@ -1698,40 +1698,15 @@ void MainWindow::doLaunch(bool online, BaseProfilerFactory *profiler)
// offline flavored game from here :3
}
case AuthSession::PlayableOnline:
{
// update first if the server actually responded
if (session->auth_server_online)
{
updateInstance(m_selectedInstance, session, profiler);
}
else
{
launchInstance(m_selectedInstance, session, profiler);
}
tryagain = false;
}
}
}
}
void MainWindow::updateInstance(InstancePtr instance, AuthSessionPtr session,
BaseProfilerFactory *profiler)
{
auto updateTask = instance->doUpdate();
if (!updateTask)
{
launchInstance(instance, session, profiler);
return;
}
ProgressDialog tDialog(this);
connect(updateTask.get(), &Task::succeeded, [this, instance, session, profiler]
{ launchInstance(instance, session, profiler); });
connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString)));
tDialog.exec(updateTask.get());
}
void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session,
BaseProfilerFactory *profiler)
void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session, BaseProfilerFactory *profiler)
{
Q_ASSERT_X(instance != NULL, "launchInstance", "instance is NULL");
Q_ASSERT_X(session.get() != nullptr, "launchInstance", "session is NULL");
@ -1744,35 +1719,43 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session,
return;
}
BaseLauncher *proc = instance->prepareForLaunch(session);
auto proc = instance->prepareForLaunch(session);
if (!proc)
return;
proc->setProfiler(profiler);
this->hide();
console = new ConsoleWindow(proc);
connect(console, &ConsoleWindow::isClosing, this, &MainWindow::instanceEnded);
connect(proc.get(), &BaseLauncher::readyForLaunch, this, &MainWindow::readyForLaunch);
proc->setHeader("MultiMC version: " + BuildConfig.printableVersionString() + "\n\n");
proc->arm();
proc->start();
}
void MainWindow::readyForLaunch(std::shared_ptr<BaseLauncher> launcher)
{
auto profiler = launcher->getProfiler();
if (!profiler)
{
proc->launch();
launcher->launch();
return;
}
QString error;
if (!profiler->check(&error))
{
proc->abort();
launcher->abort();
QMessageBox::critical(this, tr("Error"), tr("Couldn't start profiler: %1").arg(error));
return;
}
BaseProfiler *profilerInstance = profiler->createProfiler(instance, this);
BaseProfiler *profilerInstance = profiler->createProfiler(launcher->instance(), this);
connect(profilerInstance, &BaseProfiler::readyToLaunch,
[this, proc](const QString & message)
[this, launcher](const QString & message)
{
QMessageBox msg;
msg.setText(tr("The game launch is delayed until you press the "
@ -1783,10 +1766,10 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session,
msg.addButton(tr("Launch"), QMessageBox::AcceptRole);
msg.setModal(true);
msg.exec();
proc->launch();
launcher->launch();
});
connect(profilerInstance, &BaseProfiler::abortLaunch,
[this, proc](const QString & message)
[this, launcher](const QString & message)
{
QMessageBox msg;
msg.setText(tr("Couldn't start the profiler: %1").arg(message));
@ -1795,17 +1778,17 @@ void MainWindow::launchInstance(InstancePtr instance, AuthSessionPtr session,
msg.addButton(QMessageBox::Ok);
msg.setModal(true);
msg.exec();
proc->abort();
launcher->abort();
});
profilerInstance->beginProfiling(proc);
profilerInstance->beginProfiling(launcher);
}
/*
void MainWindow::onGameUpdateError(QString error)
{
CustomMessageBox::selectable(this, tr("Error updating instance"), error,
QMessageBox::Warning)->show();
}
*/
void MainWindow::taskStart()
{
// Nothing to do here yet.

View File

@ -128,12 +128,7 @@ slots:
*/
void launchInstance(InstancePtr instance, AuthSessionPtr session, BaseProfilerFactory *profiler = 0);
/*!
* Prepares the given instance for launch with the given account.
*/
void updateInstance(InstancePtr instance, AuthSessionPtr account, BaseProfilerFactory *profiler = 0);
void onGameUpdateError(QString error);
void readyForLaunch(std::shared_ptr<BaseLauncher>);
void taskStart();
void taskEnd();
@ -196,7 +191,6 @@ private:
class GroupView *view;
InstanceProxyModel *proxymodel;
NetJobPtr skin_download_job;
MinecraftLauncher *proc;
ConsoleWindow *console;
LabeledToolButton *renameButton;
QToolButton *changeIconButton;

View File

@ -11,12 +11,12 @@
#include <settings/Setting.h>
#include "GuiUtil.h"
LogPage::LogPage(BaseLauncher *proc, QWidget *parent)
LogPage::LogPage(std::shared_ptr<BaseLauncher> proc, QWidget *parent)
: QWidget(parent), ui(new Ui::LogPage), m_process(proc)
{
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
connect(m_process, SIGNAL(log(QString, MessageLevel::Enum)), this,
connect(m_process.get(), SIGNAL(log(QString, MessageLevel::Enum)), this,
SLOT(write(QString, MessageLevel::Enum)));
// create the format and set its font

View File

@ -33,7 +33,7 @@ class LogPage : public QWidget, public BasePage
Q_OBJECT
public:
explicit LogPage(BaseLauncher *proc, QWidget *parent = 0);
explicit LogPage(std::shared_ptr<BaseLauncher> proc, QWidget *parent = 0);
virtual ~LogPage();
virtual QString displayName() const override
{
@ -77,7 +77,7 @@ private slots:
private:
Ui::LogPage *ui;
BaseLauncher *m_process;
std::shared_ptr<BaseLauncher> m_process;
int m_last_scroll_value = 0;
bool m_scroll_active = true;
int m_saved_offset = 0;

View File

@ -138,7 +138,7 @@ public:
virtual std::shared_ptr<Task> doUpdate() = 0;
/// returns a valid process, ready for launch with the given account.
virtual BaseLauncher *prepareForLaunch(AuthSessionPtr account) = 0;
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) = 0;
/// do any necessary cleanups after the instance finishes. also runs before
/// 'prepareForLaunch'

View File

@ -19,6 +19,7 @@
#include "MessageLevel.h"
#include "MMCStrings.h"
#include "java/JavaChecker.h"
#include "tasks/Task.h"
#include <pathutils.h>
#include <QDebug>
#include <QDir>
@ -29,14 +30,108 @@
#define IBUS "@im=ibus"
BaseLauncher* BaseLauncher::create(MinecraftInstancePtr inst)
void BaseLauncher::initializeEnvironment()
{
auto proc = new BaseLauncher(inst);
// prepare the process environment
QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
QStringList ignored =
{
"JAVA_ARGS",
"CLASSPATH",
"CONFIGPATH",
"JAVA_HOME",
"JRE_HOME",
"_JAVA_OPTIONS",
"JAVA_OPTIONS",
"JAVA_TOOL_OPTIONS"
};
for(auto key: rawenv.keys())
{
auto value = rawenv.value(key);
// filter out dangerous java crap
if(ignored.contains(key))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
// filter MultiMC-related things
if(key.startsWith("QT_"))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
#ifdef Q_OS_LINUX
// Do not pass LD_* variables to java. They were intended for MultiMC
if(key.startsWith("LD_"))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
// Strip IBus
// IBus is a Linux IME framework. For some reason, it breaks MC?
if (key == "XMODIFIERS" && value.contains(IBUS))
{
QString save = value;
value.replace(IBUS, "");
qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
}
if(key == "GAME_PRELOAD")
{
m_env.insert("LD_PRELOAD", value);
continue;
}
if(key == "GAME_LIBRARY_PATH")
{
m_env.insert("LD_LIBRARY_PATH", value);
continue;
}
#endif
qDebug() << "Env: " << key << value;
m_env.insert(key, value);
}
#ifdef Q_OS_LINUX
// HACK: Workaround for QTBUG42500
if(!m_env.contains("LD_LIBRARY_PATH"))
{
m_env.insert("LD_LIBRARY_PATH", "");
}
#endif
// export some infos
auto variables = getVariables();
for (auto it = variables.begin(); it != variables.end(); ++it)
{
m_env.insert(it.key(), it.value());
}
}
void BaseLauncher::init()
{
initializeEnvironment();
m_process.setProcessEnvironment(m_env);
connect(&m_process, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_process, &LoggedProcess::stateChanged, this, &BaseLauncher::on_state);
m_prelaunchprocess.setProcessEnvironment(m_env);
connect(&m_prelaunchprocess, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_prelaunchprocess, &LoggedProcess::stateChanged, this, &BaseLauncher::on_pre_state);
m_postlaunchprocess.setProcessEnvironment(m_env);
connect(&m_postlaunchprocess, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_postlaunchprocess, &LoggedProcess::stateChanged, this, &BaseLauncher::on_post_state);
m_instance->setRunning(true);
}
std::shared_ptr<BaseLauncher> BaseLauncher::create(MinecraftInstancePtr inst)
{
std::shared_ptr<BaseLauncher> proc(new BaseLauncher(inst));
proc->init();
return proc;
}
BaseLauncher::BaseLauncher(InstancePtr instance): m_instance(instance)
{
}
@ -158,44 +253,45 @@ QStringList BaseLauncher::javaArguments() const
return args;
}
bool BaseLauncher::checkJava(QString JavaPath)
void BaseLauncher::checkJava()
{
auto realJavaPath = QStandardPaths::findExecutable(JavaPath);
m_javaPath = m_instance->settings()->get("JavaPath").toString();
emit log("Java path is:\n" + m_javaPath + "\n\n");
auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
if (realJavaPath.isEmpty())
{
emit log(tr("The java binary \"%1\" couldn't be found. You may have to set up java "
"if Minecraft fails to launch.").arg(JavaPath),
"if Minecraft fails to launch.").arg(m_javaPath),
MessageLevel::Warning);
}
QFileInfo javaInfo(realJavaPath);
qlonglong javaUnixTime = javaInfo.lastModified().toMSecsSinceEpoch();
auto storedUnixTime = m_instance->settings()->get("JavaTimestamp").toLongLong();
this->m_javaUnixTime = javaUnixTime;
// if they are not the same, check!
if(javaUnixTime != storedUnixTime)
{
QEventLoop ev;
auto checker = std::make_shared<JavaChecker>();
m_JavaChecker = std::make_shared<JavaChecker>();
bool successful = false;
QString errorLog;
QString version;
emit log(tr("Checking Java version..."), MessageLevel::MultiMC);
connect(checker.get(), &JavaChecker::checkFinished,
[&](JavaCheckResult result)
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &BaseLauncher::checkJavaFinished);
m_JavaChecker->m_path = realJavaPath;
m_JavaChecker->performCheck();
}
preLaunch();
}
void BaseLauncher::checkJavaFinished(JavaCheckResult result)
{
successful = result.valid;
errorLog = result.errorLog;
version = result.javaVersion;
ev.exit();
});
checker->m_path = realJavaPath;
checker->performCheck();
ev.exec();
if(!successful)
if(!result.valid)
{
// Error message displayed if java can't start
emit log(tr("Could not start java:"), MessageLevel::Error);
auto lines = errorLog.split('\n');
auto lines = result.errorLog.split('\n');
for(auto line: lines)
{
emit log(line, MessageLevel::Error);
@ -205,79 +301,20 @@ bool BaseLauncher::checkJava(QString JavaPath)
emit launch_failed(m_instance);
// not running, failed
m_instance->setRunning(false);
return false;
return;
}
emit log(tr("Java version is %1!\n").arg(version), MessageLevel::MultiMC);
m_instance->settings()->set("JavaVersion", version);
m_instance->settings()->set("JavaTimestamp", javaUnixTime);
}
return true;
emit log(tr("Java version is %1!\n").arg(result.javaVersion), MessageLevel::MultiMC);
m_instance->settings()->set("JavaVersion", result.javaVersion);
m_instance->settings()->set("JavaTimestamp", m_javaUnixTime);
preLaunch();
}
void BaseLauncher::arm()
void BaseLauncher::executeTask()
{
printHeader();
emit log("Minecraft folder is:\n" + m_process.workingDirectory() + "\n\n");
/*
if (!preLaunch())
{
emit ended(m_instance, 1, QProcess::CrashExit);
return;
}
*/
m_instance->setLastLaunch();
QString JavaPath = m_instance->settings()->get("JavaPath").toString();
emit log("Java path is:\n" + JavaPath + "\n\n");
if(!checkJava(JavaPath))
{
return;
}
QStringList args = javaArguments();
QString allArgs = args.join(", ");
emit log("Java Arguments:\n[" + censorPrivateInfo(allArgs) + "]\n\n");
QString wrapperCommand = m_instance->settings()->get("WrapperCommand").toString();
if(!wrapperCommand.isEmpty())
{
auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
if (realWrapperCommand.isEmpty())
{
emit log(tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand), MessageLevel::Warning);
m_instance->cleanupAfterRun();
emit launch_failed(m_instance);
m_instance->setRunning(false);
return;
}
emit log("Wrapper command is:\n" + wrapperCommand + "\n\n");
args.prepend(JavaPath);
m_process.start(wrapperCommand, args);
}
else
{
m_process.start(JavaPath, args);
}
// instantiate the launcher part
if (!m_process.waitForStarted())
{
//: Error message displayed if instace can't start
emit log(tr("Could not launch minecraft!"), MessageLevel::Error);
m_instance->cleanupAfterRun();
emit launch_failed(m_instance);
// not running, failed
m_instance->setRunning(false);
return;
}
emit log(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
// send the launch script to the launcher part
m_process.write(launchScript.toUtf8());
checkJava();
}
void BaseLauncher::launch()
@ -293,103 +330,6 @@ void BaseLauncher::abort()
}
void BaseLauncher::initializeEnvironment()
{
// prepare the process environment
QProcessEnvironment rawenv = QProcessEnvironment::systemEnvironment();
QStringList ignored =
{
"JAVA_ARGS",
"CLASSPATH",
"CONFIGPATH",
"JAVA_HOME",
"JRE_HOME",
"_JAVA_OPTIONS",
"JAVA_OPTIONS",
"JAVA_TOOL_OPTIONS"
};
for(auto key: rawenv.keys())
{
auto value = rawenv.value(key);
// filter out dangerous java crap
if(ignored.contains(key))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
// filter MultiMC-related things
if(key.startsWith("QT_"))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
#ifdef Q_OS_LINUX
// Do not pass LD_* variables to java. They were intended for MultiMC
if(key.startsWith("LD_"))
{
qDebug() << "Env: ignoring" << key << value;
continue;
}
// Strip IBus
// IBus is a Linux IME framework. For some reason, it breaks MC?
if (key == "XMODIFIERS" && value.contains(IBUS))
{
QString save = value;
value.replace(IBUS, "");
qDebug() << "Env: stripped" << IBUS << "from" << save << ":" << value;
}
if(key == "GAME_PRELOAD")
{
m_env.insert("LD_PRELOAD", value);
continue;
}
if(key == "GAME_LIBRARY_PATH")
{
m_env.insert("LD_LIBRARY_PATH", value);
continue;
}
#endif
qDebug() << "Env: " << key << value;
m_env.insert(key, value);
}
#ifdef Q_OS_LINUX
// HACK: Workaround for QTBUG42500
if(!m_env.contains("LD_LIBRARY_PATH"))
{
m_env.insert("LD_LIBRARY_PATH", "");
}
#endif
// export some infos
auto variables = getVariables();
for (auto it = variables.begin(); it != variables.end(); ++it)
{
m_env.insert(it.key(), it.value());
}
}
void BaseLauncher::init()
{
initializeEnvironment();
m_process.setProcessEnvironment(m_env);
connect(&m_process, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_process, &LoggedProcess::stateChanged, this, &BaseLauncher::on_state);
m_prelaunchprocess.setProcessEnvironment(m_env);
connect(&m_prelaunchprocess, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_prelaunchprocess, &LoggedProcess::stateChanged, this, &BaseLauncher::on_pre_state);
m_postlaunchprocess.setProcessEnvironment(m_env);
connect(&m_postlaunchprocess, &LoggedProcess::log, this, &BaseLauncher::on_log);
connect(&m_postlaunchprocess, &LoggedProcess::stateChanged, this, &BaseLauncher::on_post_state);
// a process has been constructed for the instance. It is running from MultiMC POV
m_instance->setRunning(true);
}
void BaseLauncher::setWorkdir(QString path)
{
QDir mcDir(path);
@ -468,18 +408,98 @@ void BaseLauncher::on_pre_state(LoggedProcess::State state)
emit prelaunch_failed(m_instance, m_prelaunchprocess.exitCode(), m_prelaunchprocess.exitStatus());
// not running, failed
m_instance->setRunning(false);
return;
}
case LoggedProcess::Finished:
{
emit log(tr("Pre-Launch command ran successfully.\n\n"));
m_instance->reload();
}
case LoggedProcess::Skipped:
{
m_instance->reload();
updateInstance();
}
default:
break;
}
}
void BaseLauncher::updateInstance()
{
m_updateTask = m_instance->doUpdate();
if(m_updateTask)
{
connect(m_updateTask.get(), SIGNAL(finished()), this, SLOT(updateFinished()));
m_updateTask->start();
return;
}
makeReady();
}
void BaseLauncher::updateFinished()
{
if(m_updateTask->successful())
{
makeReady();
}
else
{
QString reason = tr("Instance update failed because: %1.\n\n").arg(m_updateTask->failReason());
emit log(reason, MessageLevel::Fatal);
m_instance->cleanupAfterRun();
emit update_failed(m_instance);
emitFailed(reason);
m_instance->setRunning(false);
}
}
void BaseLauncher::makeReady()
{
QStringList args = javaArguments();
QString allArgs = args.join(", ");
emit log("Java Arguments:\n[" + censorPrivateInfo(allArgs) + "]\n\n");
QString wrapperCommand = m_instance->settings()->get("WrapperCommand").toString();
if(!wrapperCommand.isEmpty())
{
auto realWrapperCommand = QStandardPaths::findExecutable(wrapperCommand);
if (realWrapperCommand.isEmpty())
{
emit log(tr("The wrapper command \"%1\" couldn't be found.").arg(wrapperCommand), MessageLevel::Warning);
m_instance->cleanupAfterRun();
emit launch_failed(m_instance);
m_instance->setRunning(false);
return;
}
emit log("Wrapper command is:\n" + wrapperCommand + "\n\n");
args.prepend(m_javaPath);
m_process.start(wrapperCommand, args);
}
else
{
m_process.start(m_javaPath, args);
}
// instantiate the launcher part
if (!m_process.waitForStarted())
{
//: Error message displayed if instace can't start
emit log(tr("Could not launch minecraft!"), MessageLevel::Error);
m_instance->cleanupAfterRun();
emit launch_failed(m_instance);
// not running, failed
m_instance->setRunning(false);
return;
}
emit log(tr("Minecraft process ID: %1\n\n").arg(m_process.processId()), MessageLevel::MultiMC);
// send the launch script to the launcher part
m_process.write(launchScript.toUtf8());
emit readyForLaunch(shared_from_this());
}
void BaseLauncher::on_state(LoggedProcess::State state)
{
QProcess::ExitStatus estat = QProcess::NormalExit;
@ -500,9 +520,14 @@ void BaseLauncher::on_state(LoggedProcess::State state)
// no longer running...
m_instance->setRunning(false);
emit ended(m_instance, exitCode, estat);
break;
}
case LoggedProcess::Skipped:
qWarning() << "Illegal game state: Skipped";
break;
case LoggedProcess::Running:
m_instance->setLastLaunch();
break;
default:
break;
}

View File

@ -22,8 +22,12 @@
#include "LoggedProcess.h"
/* HACK: MINECRAFT: split! */
#include "minecraft/MinecraftInstance.h"
#include "java/JavaChecker.h"
#include "QObjectPtr.h"
#include "tasks/Task.h"
class BaseLauncher: public QObject
class BaseProfilerFactory;
class BaseLauncher: public Task, public std::enable_shared_from_this<BaseLauncher>
{
Q_OBJECT
protected:
@ -31,7 +35,7 @@ protected:
void init();
public: /* methods */
static BaseLauncher *create(MinecraftInstancePtr inst);
static std::shared_ptr<BaseLauncher> create(MinecraftInstancePtr inst);
virtual ~BaseLauncher() {};
InstancePtr instance()
@ -47,6 +51,16 @@ public: /* methods */
void setWorkdir(QString path);
BaseProfilerFactory * getProfiler()
{
return m_profiler;
}
void setProfiler(BaseProfilerFactory * profiler)
{
m_profiler = profiler;
}
void killProcess();
qint64 pid();
@ -54,7 +68,7 @@ public: /* methods */
/**
* @brief prepare the process for launch (for multi-stage launch)
*/
virtual void arm();
virtual void executeTask() override;
/**
* @brief launch the armed instance
@ -85,6 +99,8 @@ public: /* HACK: MINECRAFT: split! */
protected: /* methods */
void preLaunch();
void updateInstance();
void makeReady();
void postLaunch();
QString substituteVariables(const QString &cmd) const;
void initializeEnvironment();
@ -106,6 +122,11 @@ signals:
*/
void prelaunch_failed(InstancePtr, int code, QProcess::ExitStatus status);
/**
* @brief emitted when the instance update fails
*/
void update_failed(InstancePtr);
/**
* @brief emitted when the PostLaunchCommand fails
*/
@ -116,6 +137,11 @@ signals:
*/
void ended(InstancePtr, int code, QProcess::ExitStatus status);
/**
* @brief emitted when the launch preparations are done
*/
void readyForLaunch(std::shared_ptr<BaseLauncher> launcher);
/**
* @brief emitted when we want to log something
* @param text the text to log
@ -132,6 +158,8 @@ protected slots:
void on_state(LoggedProcess::State state);
void on_post_state(LoggedProcess::State state);
void checkJavaFinished(JavaCheckResult result);
protected:
InstancePtr m_instance;
@ -139,16 +167,27 @@ protected:
LoggedProcess m_postlaunchprocess;
LoggedProcess m_process;
QProcessEnvironment m_env;
BaseProfilerFactory * m_profiler = nullptr;
bool killed = false;
QString m_header;
// for java checker and launch
QString m_javaPath;
qlonglong m_javaUnixTime;
protected: /* HACK: MINECRAFT: split! */
AuthSessionPtr m_session;
QString launchScript;
QString m_nativeFolder;
std::shared_ptr<JavaChecker> m_JavaChecker;
std::shared_ptr<Task> m_updateTask;
protected: /* HACK: MINECRAFT: split! */
bool checkJava(QString path);
void checkJava();
QStringList javaArguments() const;
private slots:
void updateFinished();
};
class BaseProfilerFactory;

View File

@ -43,7 +43,7 @@ public:
{
return instanceRoot();
};
virtual BaseLauncher* prepareForLaunch(AuthSessionPtr)
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr)
{
return nullptr;
}

View File

@ -95,7 +95,7 @@ std::shared_ptr<Task> LegacyInstance::doUpdate()
return std::shared_ptr<Task>(new LegacyUpdate(this, this));
}
BaseLauncher *LegacyInstance::prepareForLaunch(AuthSessionPtr account)
std::shared_ptr<BaseLauncher> LegacyInstance::prepareForLaunch(AuthSessionPtr account)
{
QString launchScript;
QIcon icon = ENV.icons()->getIcon(iconKey());

View File

@ -111,7 +111,7 @@ public:
virtual void setShouldUpdate(bool val) override;
virtual std::shared_ptr<Task> doUpdate() override;
virtual BaseLauncher *prepareForLaunch(AuthSessionPtr account) override;
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) override;
virtual void cleanupAfterRun() override;
virtual QString getStatusbarDescription() override;

View File

@ -123,7 +123,7 @@ QStringList OneSixInstance::processMinecraftArgs(AuthSessionPtr session)
return parts;
}
BaseLauncher *OneSixInstance::prepareForLaunch(AuthSessionPtr session)
std::shared_ptr<BaseLauncher> OneSixInstance::prepareForLaunch(AuthSessionPtr session)
{
QString launchScript;
QIcon icon = ENV.icons()->getIcon(iconKey());

View File

@ -49,7 +49,7 @@ public:
virtual QString instanceConfigFolder() const override;
virtual std::shared_ptr<Task> doUpdate() override;
virtual BaseLauncher *prepareForLaunch(AuthSessionPtr account) override;
virtual std::shared_ptr<BaseLauncher> prepareForLaunch(AuthSessionPtr account) override;
virtual void cleanupAfterRun() override;

View File

@ -7,7 +7,7 @@ BaseProfiler::BaseProfiler(SettingsObjectPtr settings, InstancePtr instance, QOb
{
}
void BaseProfiler::beginProfiling(BaseLauncher *process)
void BaseProfiler::beginProfiling(std::shared_ptr<BaseLauncher> process)
{
beginProfilingImpl(process);
}

View File

@ -15,13 +15,13 @@ public:
public
slots:
void beginProfiling(BaseLauncher *process);
void beginProfiling(std::shared_ptr<BaseLauncher> process);
void abortProfiling();
protected:
QProcess *m_profilerProcess;
virtual void beginProfilingImpl(BaseLauncher *process) = 0;
virtual void beginProfilingImpl(std::shared_ptr<BaseLauncher> process) = 0;
virtual void abortProfilingImpl();
signals:

View File

@ -18,7 +18,7 @@ private slots:
void profilerFinished(int exit, QProcess::ExitStatus status);
protected:
void beginProfilingImpl(BaseLauncher *process);
void beginProfilingImpl(std::shared_ptr<BaseLauncher> process);
private:
int listeningPort = 0;
@ -48,7 +48,7 @@ void JProfiler::profilerFinished(int exit, QProcess::ExitStatus status)
}
}
void JProfiler::beginProfilingImpl(BaseLauncher *process)
void JProfiler::beginProfilingImpl(std::shared_ptr<BaseLauncher> process)
{
listeningPort = globalSettings->get("JProfilerPort").toInt();
QProcess *profiler = new QProcess(this);

View File

@ -18,7 +18,7 @@ private slots:
void profilerFinished(int exit, QProcess::ExitStatus status);
protected:
void beginProfilingImpl(BaseLauncher *process);
void beginProfilingImpl(std::shared_ptr<BaseLauncher> process);
};
@ -45,7 +45,7 @@ void JVisualVM::profilerFinished(int exit, QProcess::ExitStatus status)
}
}
void JVisualVM::beginProfilingImpl(BaseLauncher *process)
void JVisualVM::beginProfilingImpl(std::shared_ptr<BaseLauncher> process)
{
QProcess *profiler = new QProcess(this);
QStringList profilerArgs =