Make FTB instances behave better
* Do not re-create on every reload * Use the version.json/custom.json logic properly * Should be offline-friendly * FTB instances can be copied, turn into normal instances
This commit is contained in:
parent
82c87aa06f
commit
74b5b5f535
36
MultiMC.cpp
36
MultiMC.cpp
@ -34,8 +34,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
using namespace Util::Commandline;
|
using namespace Util::Commandline;
|
||||||
|
|
||||||
MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(argc, argv),
|
MultiMC::MultiMC(int &argc, char **argv, const QString &root)
|
||||||
m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD, VERSION_CHANNEL, VERSION_BUILD_TYPE}
|
: QApplication(argc, argv), m_version{VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD,
|
||||||
|
VERSION_CHANNEL, VERSION_BUILD_TYPE}
|
||||||
{
|
{
|
||||||
setOrganizationName("MultiMC");
|
setOrganizationName("MultiMC");
|
||||||
setApplicationName("MultiMC5");
|
setApplicationName("MultiMC5");
|
||||||
@ -135,8 +136,9 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(arg
|
|||||||
}
|
}
|
||||||
|
|
||||||
// change directory
|
// change directory
|
||||||
QDir::setCurrent(args["dir"].toString().isEmpty() ?
|
QDir::setCurrent(
|
||||||
(root.isEmpty() ? QDir::currentPath() : QDir::current().absoluteFilePath(root))
|
args["dir"].toString().isEmpty()
|
||||||
|
? (root.isEmpty() ? QDir::currentPath() : QDir::current().absoluteFilePath(root))
|
||||||
: args["dir"].toString());
|
: args["dir"].toString());
|
||||||
|
|
||||||
// init the logger
|
// init the logger
|
||||||
@ -174,7 +176,8 @@ MultiMC::MultiMC(int &argc, char **argv, const QString &root) : QApplication(arg
|
|||||||
{
|
{
|
||||||
QLOG_INFO() << "No proxy found.";
|
QLOG_INFO() << "No proxy found.";
|
||||||
}
|
}
|
||||||
else for (auto proxy : proxies)
|
else
|
||||||
|
for (auto proxy : proxies)
|
||||||
{
|
{
|
||||||
QString proxyDesc;
|
QString proxyDesc;
|
||||||
if (proxy.type() == QNetworkProxy::NoProxy)
|
if (proxy.type() == QNetworkProxy::NoProxy)
|
||||||
@ -315,7 +318,8 @@ void MultiMC::initGlobalSettings()
|
|||||||
|
|
||||||
// FTB
|
// FTB
|
||||||
m_settings->registerSetting(new Setting("TrackFTBInstances", false));
|
m_settings->registerSetting(new Setting("TrackFTBInstances", false));
|
||||||
m_settings->registerSetting(new Setting("FTBLauncherRoot",
|
m_settings->registerSetting(new Setting(
|
||||||
|
"FTBLauncherRoot",
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
QDir::home().absoluteFilePath(".ftblauncher")
|
QDir::home().absoluteFilePath(".ftblauncher")
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
@ -329,7 +333,8 @@ void MultiMC::initGlobalSettings()
|
|||||||
if (m_settings->get("FTBRoot").isNull())
|
if (m_settings->get("FTBRoot").isNull())
|
||||||
{
|
{
|
||||||
QString ftbRoot;
|
QString ftbRoot;
|
||||||
QFile f(QDir(m_settings->get("FTBLauncherRoot").toString()).absoluteFilePath("ftblaunch.cfg"));
|
QFile f(QDir(m_settings->get("FTBLauncherRoot").toString())
|
||||||
|
.absoluteFilePath("ftblaunch.cfg"));
|
||||||
QLOG_INFO() << "Attempting to read" << f.fileName();
|
QLOG_INFO() << "Attempting to read" << f.fileName();
|
||||||
if (f.open(QFile::ReadOnly))
|
if (f.open(QFile::ReadOnly))
|
||||||
{
|
{
|
||||||
@ -398,7 +403,6 @@ void MultiMC::initGlobalSettings()
|
|||||||
// The cat
|
// The cat
|
||||||
m_settings->registerSetting(new Setting("TheCat", false));
|
m_settings->registerSetting(new Setting("TheCat", false));
|
||||||
|
|
||||||
|
|
||||||
m_settings->registerSetting(new Setting("InstSortMode", "Name"));
|
m_settings->registerSetting(new Setting("InstSortMode", "Name"));
|
||||||
m_settings->registerSetting(new Setting("SelectedInstance", QString()));
|
m_settings->registerSetting(new Setting("SelectedInstance", QString()));
|
||||||
|
|
||||||
@ -490,13 +494,16 @@ void MultiMC::installUpdates(const QString& updateFilesDir, bool restartOnFinish
|
|||||||
{
|
{
|
||||||
QLOG_INFO() << "Installing updates.";
|
QLOG_INFO() << "Installing updates.";
|
||||||
#if LINUX
|
#if LINUX
|
||||||
// On Linux, the MultiMC executable file is actually in the bin folder inside the installation directory.
|
// On Linux, the MultiMC executable file is actually in the bin folder inside the
|
||||||
|
// installation directory.
|
||||||
// This means that MultiMC's *actual* install path is the parent folder.
|
// This means that MultiMC's *actual* install path is the parent folder.
|
||||||
// We need to tell the updater to run with this directory as the install path, rather than the bin folder where the executable is.
|
// We need to tell the updater to run with this directory as the install path, rather than
|
||||||
|
// the bin folder where the executable is.
|
||||||
// On other operating systems, we'll just use the path to the executable.
|
// On other operating systems, we'll just use the path to the executable.
|
||||||
QString appDir = QFileInfo(MMC->applicationDirPath()).dir().path();
|
QString appDir = QFileInfo(MMC->applicationDirPath()).dir().path();
|
||||||
|
|
||||||
// On Linux, we also need to set the finish command to the launch script, rather than the binary.
|
// On Linux, we also need to set the finish command to the launch script, rather than the
|
||||||
|
// binary.
|
||||||
QString finishCmd = PathCombine(appDir, "MultiMC");
|
QString finishCmd = PathCombine(appDir, "MultiMC");
|
||||||
#else
|
#else
|
||||||
QString appDir = MMC->applicationDirPath();
|
QString appDir = MMC->applicationDirPath();
|
||||||
@ -504,11 +511,13 @@ void MultiMC::installUpdates(const QString& updateFilesDir, bool restartOnFinish
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Build the command we'll use to run the updater.
|
// Build the command we'll use to run the updater.
|
||||||
// Note, the above comment about the app dir path on Linux is irrelevant here because the updater binary is always in the
|
// Note, the above comment about the app dir path on Linux is irrelevant here because the
|
||||||
|
// updater binary is always in the
|
||||||
// same folder as the main binary.
|
// same folder as the main binary.
|
||||||
QString updaterBinary = PathCombine(MMC->applicationDirPath(), UPDATER_BIN);
|
QString updaterBinary = PathCombine(MMC->applicationDirPath(), UPDATER_BIN);
|
||||||
QStringList args;
|
QStringList args;
|
||||||
// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
|
// ./updater --install-dir $INSTALL_DIR --package-dir $UPDATEFILES_DIR --script
|
||||||
|
// $UPDATEFILES_DIR/file_list.xml --wait $PID --mode main
|
||||||
args << "--install-dir" << appDir;
|
args << "--install-dir" << appDir;
|
||||||
args << "--package-dir" << updateFilesDir;
|
args << "--package-dir" << updateFilesDir;
|
||||||
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
args << "--script" << PathCombine(updateFilesDir, "file_list.xml");
|
||||||
@ -535,5 +544,4 @@ QString MultiMC::getExitUpdatePath() const
|
|||||||
return m_updateOnExitPath;
|
return m_updateOnExitPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "MultiMC.moc"
|
#include "MultiMC.moc"
|
||||||
|
@ -170,7 +170,17 @@ InstanceFactory::InstCreateError InstanceFactory::copyInstance(BaseInstance *&ne
|
|||||||
rootDir.removeRecursively();
|
rootDir.removeRecursively();
|
||||||
return InstanceFactory::CantCreateDir;
|
return InstanceFactory::CantCreateDir;
|
||||||
}
|
}
|
||||||
|
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
|
||||||
|
m_settings->registerSetting(new Setting("InstanceType", "Legacy"));
|
||||||
|
QString inst_type = m_settings->get("InstanceType").toString();
|
||||||
|
|
||||||
|
if(inst_type == "OneSixFTB")
|
||||||
|
m_settings->set("InstanceType", "OneSix");
|
||||||
|
if(inst_type == "LegacyFTB")
|
||||||
|
m_settings->set("InstanceType", "Legacy");
|
||||||
|
|
||||||
auto error = loadInstance(newInstance, instDir);
|
auto error = loadInstance(newInstance, instDir);
|
||||||
|
|
||||||
switch (error)
|
switch (error)
|
||||||
{
|
{
|
||||||
case NoLoadError:
|
case NoLoadError:
|
||||||
|
@ -57,7 +57,10 @@ slots:
|
|||||||
emitFailed(tr("Couldn't load the version config"));
|
emitFailed(tr("Couldn't load the version config"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!forge.apply(instance->getFullVersion()))
|
instance->revertCustomVersion();
|
||||||
|
instance->customizeVersion();
|
||||||
|
auto version = instance->getFullVersion();
|
||||||
|
if (!forge.apply(version))
|
||||||
{
|
{
|
||||||
emitFailed(tr("Couldn't install Forge"));
|
emitFailed(tr("Couldn't install Forge"));
|
||||||
return;
|
return;
|
||||||
|
@ -46,7 +46,8 @@ InstanceList::InstanceList(const QString &instDir, QObject *parent)
|
|||||||
QDir::current().mkpath(m_instDir);
|
QDir::current().mkpath(m_instDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(MMC->minecraftlist().get(), &MinecraftVersionList::modelReset, this, &InstanceList::loadList);
|
connect(MMC->minecraftlist().get(), &MinecraftVersionList::modelReset, this,
|
||||||
|
&InstanceList::loadList);
|
||||||
}
|
}
|
||||||
|
|
||||||
InstanceList::~InstanceList()
|
InstanceList::~InstanceList()
|
||||||
@ -281,6 +282,124 @@ void InstanceList::loadGroupList(QMap<QString, QString> &groupMap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FTBRecord
|
||||||
|
{
|
||||||
|
QString dir;
|
||||||
|
QString name;
|
||||||
|
QString logo;
|
||||||
|
QString mcVersion;
|
||||||
|
QString description;
|
||||||
|
};
|
||||||
|
|
||||||
|
void InstanceList::loadForgeInstances(QMap<QString, QString> groupMap)
|
||||||
|
{
|
||||||
|
QList<FTBRecord> records;
|
||||||
|
QDir dir = QDir(MMC->settings()->get("FTBLauncherRoot").toString());
|
||||||
|
QDir dataDir = QDir(MMC->settings()->get("FTBRoot").toString());
|
||||||
|
if (!dir.exists())
|
||||||
|
{
|
||||||
|
QLOG_INFO() << "The FTB launcher directory specified does not exist. Please check your "
|
||||||
|
"settings.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!dataDir.exists())
|
||||||
|
{
|
||||||
|
QLOG_INFO() << "The FTB directory specified does not exist. Please check your settings";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir.cd("ModPacks");
|
||||||
|
QFile f(dir.absoluteFilePath("modpacks.xml"));
|
||||||
|
if (!f.open(QFile::ReadOnly))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// read the FTB packs XML.
|
||||||
|
QXmlStreamReader reader(&f);
|
||||||
|
while (!reader.atEnd())
|
||||||
|
{
|
||||||
|
switch (reader.readNext())
|
||||||
|
{
|
||||||
|
case QXmlStreamReader::StartElement:
|
||||||
|
{
|
||||||
|
if (reader.name() == "modpack")
|
||||||
|
{
|
||||||
|
QXmlStreamAttributes attrs = reader.attributes();
|
||||||
|
FTBRecord record;
|
||||||
|
record.dir = attrs.value("dir").toString();
|
||||||
|
record.name = attrs.value("name").toString();
|
||||||
|
record.logo = attrs.value("logo").toString();
|
||||||
|
record.mcVersion = attrs.value("mcVersion").toString();
|
||||||
|
record.description = attrs.value("description").toString();
|
||||||
|
records.append(record);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QXmlStreamReader::EndElement:
|
||||||
|
break;
|
||||||
|
case QXmlStreamReader::Characters:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.close();
|
||||||
|
|
||||||
|
// process the records we acquired.
|
||||||
|
for (auto record : records)
|
||||||
|
{
|
||||||
|
auto instanceDir = dataDir.absoluteFilePath(record.dir);
|
||||||
|
auto templateDir = dir.absoluteFilePath(record.dir);
|
||||||
|
if (!QFileInfo(instanceDir).exists())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString iconKey = record.logo;
|
||||||
|
iconKey.remove(QRegularExpression("\\..*"));
|
||||||
|
MMC->icons()->addIcon(iconKey, iconKey, PathCombine(templateDir, record.logo), true);
|
||||||
|
|
||||||
|
if (!QFileInfo(PathCombine(instanceDir, "instance.cfg")).exists())
|
||||||
|
{
|
||||||
|
BaseInstance *instPtr = NULL;
|
||||||
|
auto & factory = InstanceFactory::get();
|
||||||
|
auto version = MMC->minecraftlist()->findVersion(record.mcVersion);
|
||||||
|
if (!version)
|
||||||
|
{
|
||||||
|
QLOG_ERROR() << "Can't load instance " << instanceDir
|
||||||
|
<< " because minecraft version " << record.mcVersion
|
||||||
|
<< " can't be resolved.";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto error = factory.createInstance(instPtr, version, instanceDir,
|
||||||
|
InstanceFactory::FTBInstance);
|
||||||
|
|
||||||
|
if (!instPtr || error != InstanceFactory::NoCreateError)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
instPtr->setGroupInitial("FTB");
|
||||||
|
instPtr->setName(record.name);
|
||||||
|
instPtr->setIconKey(iconKey);
|
||||||
|
instPtr->setIntendedVersionId(record.mcVersion);
|
||||||
|
instPtr->setNotes(record.description);
|
||||||
|
continueProcessInstance(instPtr, error, instanceDir, groupMap);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BaseInstance *instPtr = NULL;
|
||||||
|
auto error = InstanceFactory::get().loadInstance(instPtr, instanceDir);
|
||||||
|
if (!instPtr || error != InstanceFactory::NoCreateError)
|
||||||
|
continue;
|
||||||
|
instPtr->setGroupInitial("FTB");
|
||||||
|
instPtr->setName(record.name);
|
||||||
|
instPtr->setIconKey(iconKey);
|
||||||
|
if (instPtr->intendedVersionId() != record.mcVersion)
|
||||||
|
instPtr->setIntendedVersionId(record.mcVersion);
|
||||||
|
instPtr->setNotes(record.description);
|
||||||
|
continueProcessInstance(instPtr, error, instanceDir, groupMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
InstanceList::InstListError InstanceList::loadList()
|
InstanceList::InstListError InstanceList::loadList()
|
||||||
{
|
{
|
||||||
// load the instance groups
|
// load the instance groups
|
||||||
@ -306,69 +425,9 @@ InstanceList::InstListError InstanceList::loadList()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MMC->settings()->get("TrackFTBInstances").toBool() && MMC->minecraftlist()->isLoaded())
|
if (MMC->settings()->get("TrackFTBInstances").toBool())
|
||||||
{
|
{
|
||||||
QDir dir = QDir(MMC->settings()->get("FTBLauncherRoot").toString());
|
loadForgeInstances(groupMap);
|
||||||
QDir dataDir = QDir(MMC->settings()->get("FTBRoot").toString());
|
|
||||||
if (!dir.exists())
|
|
||||||
{
|
|
||||||
QLOG_INFO() << "The FTB launcher directory specified does not exist. Please check your settings.";
|
|
||||||
}
|
|
||||||
else if (!dataDir.exists())
|
|
||||||
{
|
|
||||||
QLOG_INFO() << "The FTB directory specified does not exist. Please check your settings";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dir.cd("ModPacks");
|
|
||||||
QFile f(dir.absoluteFilePath("modpacks.xml"));
|
|
||||||
if (f.open(QFile::ReadOnly))
|
|
||||||
{
|
|
||||||
QXmlStreamReader reader(&f);
|
|
||||||
while (!reader.atEnd())
|
|
||||||
{
|
|
||||||
switch (reader.readNext())
|
|
||||||
{
|
|
||||||
case QXmlStreamReader::StartElement:
|
|
||||||
{
|
|
||||||
if (reader.name() == "modpack")
|
|
||||||
{
|
|
||||||
QXmlStreamAttributes attrs = reader.attributes();
|
|
||||||
const QDir instanceDir = QDir(dataDir.absoluteFilePath(attrs.value("dir").toString()));
|
|
||||||
if (instanceDir.exists())
|
|
||||||
{
|
|
||||||
const QString name = attrs.value("name").toString();
|
|
||||||
const QString iconKey = attrs.value("logo").toString().remove(QRegularExpression("\\..*"));
|
|
||||||
const QString mcVersion = attrs.value("mcVersion").toString();
|
|
||||||
const QString notes = attrs.value("description").toString();
|
|
||||||
QLOG_DEBUG() << dir.absoluteFilePath(attrs.value("logo").toString());
|
|
||||||
MMC->icons()->addIcon(iconKey, iconKey, dir.absoluteFilePath(attrs.value("dir").toString() + QDir::separator() + attrs.value("logo").toString()), true);
|
|
||||||
|
|
||||||
BaseInstance *instPtr = NULL;
|
|
||||||
auto error = InstanceFactory::get().createInstance(instPtr, MMC->minecraftlist()->findVersion(mcVersion), instanceDir.absolutePath(), InstanceFactory::FTBInstance);
|
|
||||||
if (instPtr && error == InstanceFactory::NoCreateError)
|
|
||||||
{
|
|
||||||
instPtr->setGroupInitial("FTB");
|
|
||||||
instPtr->setName(name);
|
|
||||||
instPtr->setIconKey(iconKey);
|
|
||||||
instPtr->setIntendedVersionId(mcVersion);
|
|
||||||
instPtr->setNotes(notes);
|
|
||||||
}
|
|
||||||
continueProcessInstance(instPtr, error, instanceDir, groupMap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case QXmlStreamReader::EndElement:
|
|
||||||
break;
|
|
||||||
case QXmlStreamReader::Characters:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
@ -444,7 +503,8 @@ int InstanceList::getInstIndex(BaseInstance *inst) const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceList::continueProcessInstance(BaseInstance *instPtr, const int error, const QDir &dir, QMap<QString, QString> &groupMap)
|
void InstanceList::continueProcessInstance(BaseInstance *instPtr, const int error,
|
||||||
|
const QDir &dir, QMap<QString, QString> &groupMap)
|
||||||
{
|
{
|
||||||
if (error != InstanceFactory::NoLoadError && error != InstanceFactory::NotAnInstance)
|
if (error != InstanceFactory::NoLoadError && error != InstanceFactory::NotAnInstance)
|
||||||
{
|
{
|
||||||
|
@ -109,6 +109,7 @@ slots:
|
|||||||
* \brief Loads the instance list. Triggers notifications.
|
* \brief Loads the instance list. Triggers notifications.
|
||||||
*/
|
*/
|
||||||
InstListError loadList();
|
InstListError loadList();
|
||||||
|
void loadForgeInstances(QMap<QString, QString> groupMap);
|
||||||
|
|
||||||
private
|
private
|
||||||
slots:
|
slots:
|
||||||
@ -119,7 +120,8 @@ slots:
|
|||||||
private:
|
private:
|
||||||
int getInstIndex(BaseInstance *inst) const;
|
int getInstIndex(BaseInstance *inst) const;
|
||||||
|
|
||||||
void continueProcessInstance(BaseInstance *instPtr, const int error, const QDir &dir, QMap<QString, QString> &groupMap);
|
void continueProcessInstance(BaseInstance *instPtr, const int error, const QDir &dir,
|
||||||
|
QMap<QString, QString> &groupMap);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_instDir;
|
QString m_instDir;
|
||||||
|
Loading…
Reference in New Issue
Block a user