diff options
Diffstat (limited to 'api/logic/minecraft/legacy')
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyInstance.cpp | 359 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyInstance.h | 115 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyModList.cpp | 533 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyModList.h | 112 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyUpdate.cpp | 399 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyUpdate.h | 70 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyUpgradeTask.cpp | 142 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LegacyUpgradeTask.h | 38 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LwjglVersionList.cpp | 169 | ||||
| -rw-r--r-- | api/logic/minecraft/legacy/LwjglVersionList.h | 116 |
10 files changed, 360 insertions, 1693 deletions
diff --git a/api/logic/minecraft/legacy/LegacyInstance.cpp b/api/logic/minecraft/legacy/LegacyInstance.cpp index 0987d56f..6e318458 100644 --- a/api/logic/minecraft/legacy/LegacyInstance.cpp +++ b/api/logic/minecraft/legacy/LegacyInstance.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ #include "LegacyInstance.h" -#include "minecraft/legacy/LegacyUpdate.h" #include "minecraft/legacy/LegacyModList.h" #include "minecraft/ModList.h" #include "minecraft/WorldList.h" @@ -28,14 +27,12 @@ #include <FileSystem.h> LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) - : MinecraftInstance(globalSettings, settings, rootDir) + : BaseInstance(globalSettings, settings, rootDir) { - m_lwjglFolderSetting = globalSettings->getSetting("LWJGLDir"); settings->registerSetting("NeedsRebuild", true); settings->registerSetting("ShouldUpdate", false); - settings->registerSetting("JarVersion", "Unknown"); - settings->registerSetting("LwjglVersion", "2.9.0"); - settings->registerSetting("IntendedJarVersion", ""); + settings->registerSetting("JarVersion", QString()); + settings->registerSetting("IntendedJarVersion", QString()); /* * custom base jar has no default. it is determined in code... see the accessor methods for *it @@ -68,178 +65,102 @@ QString LegacyInstance::customBaseJar() const return value; } -void LegacyInstance::setCustomBaseJar(QString val) -{ - if (val.isNull() || val.isEmpty() || val == defaultCustomBaseJar()) - m_settings->reset("CustomBaseJar"); - else - m_settings->set("CustomBaseJar", val); -} - -void LegacyInstance::setShouldUseCustomBaseJar(bool val) -{ - m_settings->set("UseCustomBaseJar", val); -} - bool LegacyInstance::shouldUseCustomBaseJar() const { return m_settings->get("UseCustomBaseJar").toBool(); } -shared_qobject_ptr<Task> LegacyInstance::createUpdateTask() +shared_qobject_ptr<Task> LegacyInstance::createUpdateTask(Net::Mode) { - // make sure the jar mods list is initialized by asking for it. - auto list = jarModList(); - // create an update task - return shared_qobject_ptr<Task>(new LegacyUpdate(this, this)); + return nullptr; } -std::shared_ptr<Task> LegacyInstance::createJarModdingTask() +/* +class LegacyJarModTask : public Task { - class JarModTask : public Task + //Q_OBJECT +public: + explicit LegacyJarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst) + { + } + virtual void executeTask() { - public: - explicit JarModTask(std::shared_ptr<LegacyInstance> inst) : Task(nullptr), m_inst(inst) + if (!m_inst->shouldRebuild()) { + emitSucceeded(); + return; } - virtual void executeTask() - { - if (!m_inst->shouldRebuild()) - { - emitSucceeded(); - return; - } - // Get the mod list - auto modList = m_inst->getJarMods(); + // Get the mod list + auto modList = m_inst->getJarMods(); - QFileInfo runnableJar(m_inst->runnableJar()); - QFileInfo baseJar(m_inst->baseJar()); - bool base_is_custom = m_inst->shouldUseCustomBaseJar(); + QFileInfo runnableJar(m_inst->runnableJar()); + QFileInfo baseJar(m_inst->baseJar()); + bool base_is_custom = m_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()) - { - m_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."); - m_inst->setShouldRebuild(true); - m_inst->setShouldUpdate(true); - m_inst->setShouldUseCustomBaseJar(false); - return; - } - } - - if (!baseJar.exists()) + // 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()) { - emitFailed("The base jar " + baseJar.filePath() + " does not exist"); + m_inst->setShouldRebuild(false); + emitSucceeded(); return; } - if (runnableJar.exists() && !QFile::remove(runnableJar.filePath())) + setStatus(tr("Installing mods: Backing up minecraft.jar ...")); + if (!baseJar.exists() && !QFile::copy(runnableJar.filePath(), baseJar.filePath())) { - emitFailed("Failed to delete old minecraft.jar"); + emitFailed("It seems both the active and base jar are gone. A fresh base jar will " + "be used on next run."); + m_inst->setShouldRebuild(true); + m_inst->setShouldUpdate(true); + m_inst->setShouldUseCustomBaseJar(false); return; } + } - setStatus(tr("Installing mods: Opening minecraft.jar ...")); - - QString outputJarPath = runnableJar.filePath(); - QString inputJarPath = baseJar.filePath(); - - if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList)) - { - emitFailed(tr("Failed to create the custom Minecraft jar file.")); - return; - } - m_inst->setShouldRebuild(false); - // inst->UpdateVersion(true); - emitSucceeded(); + if (!baseJar.exists()) + { + emitFailed("The base jar " + baseJar.filePath() + " does not exist"); return; - } - std::shared_ptr<LegacyInstance> m_inst; - }; - return std::make_shared<JarModTask>(std::dynamic_pointer_cast<LegacyInstance>(shared_from_this())); -} -QString LegacyInstance::createLaunchScript(AuthSessionPtr session) -{ - QString launchScript; - - // window size - QString windowParams; - if (settings()->get("LaunchMaximized").toBool()) - { - windowParams = "max"; - } - else - { - windowParams = QString("%1x%2").arg(settings()->get("MinecraftWinWidth").toInt()).arg(settings()->get("MinecraftWinHeight").toInt()); - } - - QString lwjgl = QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath(); - launchScript += "userName " + session->player_name + "\n"; - launchScript += "sessionId " + session->session + "\n"; - launchScript += "windowTitle " + windowTitle() + "\n"; - launchScript += "windowParams " + windowParams + "\n"; - launchScript += "cp bin/minecraft.jar\n"; - launchScript += "cp " + lwjgl + "/lwjgl.jar\n"; - launchScript += "cp " + lwjgl + "/lwjgl_util.jar\n"; - launchScript += "cp " + lwjgl + "/jinput.jar\n"; - launchScript += "natives " + lwjgl + "/natives\n"; - launchScript += "traits legacyLaunch\n"; - launchScript += "launcher onesix\n"; - return launchScript; -} + if (runnableJar.exists() && !QFile::remove(runnableJar.filePath())) + { + emitFailed("Failed to delete old minecraft.jar"); + return; + } -std::shared_ptr<LaunchStep> LegacyInstance::createMainLaunchStep(LaunchTask * parent, AuthSessionPtr session) -{ - auto step = std::make_shared<LauncherPartLaunch>(parent); - step->setWorkingDirectory(minecraftRoot()); - step->setAuthSession(session); - return step; -} + setStatus(tr("Installing mods: Opening minecraft.jar ...")); -QString LegacyInstance::launchMethod() -{ - return "Legacy"; -} + QString outputJarPath = runnableJar.filePath(); + QString inputJarPath = baseJar.filePath(); -QStringList LegacyInstance::validLaunchMethods() -{ - return {"Legacy"}; -} + if(!MMCZip::createModdedJar(inputJarPath, outputJarPath, modList)) + { + emitFailed(tr("Failed to create the custom Minecraft jar file.")); + return; + } + m_inst->setShouldRebuild(false); + // inst->UpdateVersion(true); + emitSucceeded(); + return; -std::shared_ptr<ModList> LegacyInstance::coreModList() const -{ - if (!core_mod_list) - { - core_mod_list.reset(new ModList(coreModsDir())); } - core_mod_list->update(); - return core_mod_list; -} + std::shared_ptr<LegacyInstance> m_inst; +}; +*/ std::shared_ptr<LegacyModList> LegacyInstance::jarModList() const { if (!jar_mod_list) { auto list = new LegacyModList(jarModsDir(), modListFile()); - connect(list, SIGNAL(changed()), SLOT(jarModsChanged())); jar_mod_list.reset(list); } jar_mod_list->update(); @@ -251,39 +172,20 @@ QList<Mod> LegacyInstance::getJarMods() const return jarModList()->allMods(); } -void LegacyInstance::jarModsChanged() +QString LegacyInstance::minecraftRoot() const { - qDebug() << "Jar mods of instance " << name() << " have changed. Jar will be rebuilt."; - setShouldRebuild(true); -} + QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft")); + QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft")); -std::shared_ptr<ModList> LegacyInstance::loaderModList() const -{ - if (!loader_mod_list) - { - loader_mod_list.reset(new ModList(loaderModsDir())); - } - loader_mod_list->update(); - return loader_mod_list; + if (mcDir.exists() && !dotMCDir.exists()) + return mcDir.filePath(); + else + return dotMCDir.filePath(); } -std::shared_ptr<ModList> LegacyInstance::texturePackList() const +QString LegacyInstance::binRoot() const { - if (!texture_pack_list) - { - texture_pack_list.reset(new ModList(texturePacksDir())); - } - texture_pack_list->update(); - return texture_pack_list; -} - -std::shared_ptr<WorldList> LegacyInstance::worldList() const -{ - if (!m_world_list) - { - m_world_list.reset(new WorldList(savesDir())); - } - return m_world_list; + return FS::PathCombine(minecraftRoot(), "bin"); } QString LegacyInstance::jarModsDir() const @@ -340,38 +242,16 @@ bool LegacyInstance::shouldRebuild() const return m_settings->get("NeedsRebuild").toBool(); } -void LegacyInstance::setShouldRebuild(bool val) -{ - m_settings->set("NeedsRebuild", val); -} - QString LegacyInstance::currentVersionId() const { return m_settings->get("JarVersion").toString(); } -QString LegacyInstance::lwjglVersion() const -{ - return m_settings->get("LwjglVersion").toString(); -} - -void LegacyInstance::setLWJGLVersion(QString val) -{ - m_settings->set("LwjglVersion", val); -} - QString LegacyInstance::intendedVersionId() const { return m_settings->get("IntendedJarVersion").toString(); } -bool LegacyInstance::setIntendedVersionId(QString version) -{ - settings()->set("IntendedJarVersion", version); - setShouldUpdate(true); - return true; -} - bool LegacyInstance::shouldUpdate() const { QVariant var = settings()->get("ShouldUpdate"); @@ -382,11 +262,6 @@ bool LegacyInstance::shouldUpdate() const return true; } -void LegacyInstance::setShouldUpdate(bool val) -{ - settings()->set("ShouldUpdate", val); -} - QString LegacyInstance::defaultBaseJar() const { return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar"; @@ -397,9 +272,13 @@ QString LegacyInstance::defaultCustomBaseJar() const return FS::PathCombine(binRoot(), "mcbackup.jar"); } -QString LegacyInstance::lwjglFolder() const +std::shared_ptr<WorldList> LegacyInstance::worldList() const { - return m_lwjglFolderSetting->get().toString(); + if (!m_world_list) + { + m_world_list.reset(new WorldList(savesDir())); + } + return m_world_list; } QString LegacyInstance::typeName() const @@ -407,6 +286,11 @@ QString LegacyInstance::typeName() const return tr("Legacy"); } +QString LegacyInstance::getStatusbarDescription() +{ + return tr("Instance from previous versions."); +} + QStringList LegacyInstance::verboseDescription(AuthSessionPtr session) { QStringList out; @@ -422,48 +306,6 @@ QStringList LegacyInstance::verboseDescription(AuthSessionPtr session) out << ""; } - if(loaderModList()->size()) - { - out << "Mods:"; - for(auto & mod: loaderModList()->allMods()) - { - if(!mod.enabled()) - continue; - if(mod.type() == Mod::MOD_FOLDER) - continue; - // TODO: proper implementation would need to descend into folders. - - out << " " + mod.filename().completeBaseName(); - } - out << ""; - } - - if(coreModList()->size()) - { - out << "Core Mods:"; - for(auto & coremod: coreModList()->allMods()) - { - if(!coremod.enabled()) - continue; - if(coremod.type() == Mod::MOD_FOLDER) - continue; - // TODO: proper implementation would need to descend into folders. - - out << " " + coremod.filename().completeBaseName(); - } - out << ""; - } - - if(jarModList()->size()) - { - out << "Jar Mods:"; - for(auto & jarmod: jarModList()->allMods()) - { - out << " " + jarmod.name() + " (" + jarmod.filename().filePath() + ")"; - } - out << ""; - } - QString windowParams; if (settings()->get("LaunchMaximized").toBool()) { @@ -478,40 +320,3 @@ QStringList LegacyInstance::verboseDescription(AuthSessionPtr session) out << ""; return out; } - -QStringList LegacyInstance::getClassPath() const -{ - QString launchScript; - QString lwjgl = getNativePath(); - QStringList out = - { - "bin/minecraft.jar", - lwjgl + "/lwjgl.jar", - lwjgl + "/lwjgl_util.jar", - lwjgl + "/jinput.jar" - }; - return out; -} - -QString LegacyInstance::getMainClass() const -{ - return "net.minecraft.client.Minecraft"; -} - -QString LegacyInstance::getNativePath() const -{ - return QDir(m_lwjglFolderSetting->get().toString() + "/" + lwjglVersion()).absolutePath(); -} - -QStringList LegacyInstance::getNativeJars() const -{ - return {}; -} - -QStringList LegacyInstance::processMinecraftArgs(AuthSessionPtr account) const -{ - QStringList out; - out.append(account->player_name); - out.append(account->session); - return out; -} diff --git a/api/logic/minecraft/legacy/LegacyInstance.h b/api/logic/minecraft/legacy/LegacyInstance.h index 15d1383f..4a8bc436 100644 --- a/api/logic/minecraft/legacy/LegacyInstance.h +++ b/api/logic/minecraft/legacy/LegacyInstance.h @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,22 +15,27 @@ #pragma once -#include "minecraft/MinecraftInstance.h" +#include "BaseInstance.h" +#include "minecraft/Mod.h" #include "multimc_logic_export.h" class ModList; class LegacyModList; +class WorldList; class Task; - -class MULTIMC_LOGIC_EXPORT LegacyInstance : public MinecraftInstance +/* + * WHY: Legacy instances - from MultiMC 3 and 4 - are here only to provide a way to upgrade them to the current format. + */ +class MULTIMC_LOGIC_EXPORT LegacyInstance : public BaseInstance { Q_OBJECT public: explicit LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir); - virtual void init() override {}; + virtual void init() override {} + virtual void saveNow() override {} /// Path to the instance's minecraft.jar QString runnableJar() const; @@ -38,20 +43,6 @@ public: //! Path to the instance's modlist file. QString modListFile() const; - /* - ////// Edit Instance Dialog stuff ////// - virtual QList<BasePage *> getPages(); - virtual QString dialogTitle(); - */ - - ////// Mod Lists ////// - std::shared_ptr<LegacyModList> jarModList() const ; - virtual QList< Mod > getJarMods() const override; - std::shared_ptr<ModList> coreModList() const; - std::shared_ptr<ModList> loaderModList() const; - std::shared_ptr<ModList> texturePackList() const override; - std::shared_ptr<WorldList> worldList() const override; - ////// Directories ////// QString libDir() const; QString savesDir() const; @@ -61,8 +52,10 @@ public: QString coreModsDir() const; QString resourceDir() const; virtual QString instanceConfigFolder() const override; + QString minecraftRoot() const; // Path to the instance's minecraft directory. + QString binRoot() const; // Path to the instance's minecraft bin directory. - /// Get the curent base jar of this instance. By default, it's the + /// Get the curent base jar of this instance. By default, it's the /// versions/$version/$version.jar QString baseJar() const; @@ -75,13 +68,15 @@ public: * Whether or not custom base jar is used */ bool shouldUseCustomBaseJar() const; - void setShouldUseCustomBaseJar(bool val); /*! * The value of the custom base jar */ QString customBaseJar() const; - void setCustomBaseJar(QString val); + + std::shared_ptr<LegacyModList> jarModList() const; + QList<Mod> getJarMods() const; + std::shared_ptr<WorldList> worldList() const; /*! * Whether or not the instance's minecraft.jar needs to be rebuilt. @@ -89,67 +84,57 @@ public: * re-added to a fresh minecraft.jar file. */ bool shouldRebuild() const; - void setShouldRebuild(bool val); - - virtual QString currentVersionId() const override; - - //! The version of LWJGL that this instance uses. - QString lwjglVersion() const; - //! Where the lwjgl versions foor this instance can be found... HACK HACK HACK - QString lwjglFolder() const; + QString currentVersionId() const; + QString intendedVersionId() const; - /// st the version of LWJGL libs this instance will use - void setLWJGLVersion(QString val); - - virtual QString intendedVersionId() const override; - virtual bool setIntendedVersionId(QString version) override; - - virtual QSet<QString> traits() override + QSet<QString> traits() const override { return {"legacy-instance", "texturepacks"}; }; - virtual bool shouldUpdate() const override; - virtual void setShouldUpdate(bool val) override; - virtual shared_qobject_ptr<Task> createUpdateTask() override; - virtual std::shared_ptr<Task> createJarModdingTask() override; - virtual QString createLaunchScript(AuthSessionPtr session) override; + virtual bool shouldUpdate() const; + virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override; virtual QString typeName() const override; - bool canExport() const override + bool canLaunch() const override + { + return false; + } + bool canEdit() const override { return true; } - - QStringList getClassPath() const override; - QString getMainClass() const override; - - QStringList getNativeJars() const override; - QString getNativePath() const override; - - QString getLocalLibraryPath() const override + bool canExport() const override + { + return false; + } + std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override + { + return nullptr; + } + IPathMatcher::Ptr getLogFileMatcher() override + { + return nullptr; + } + QString getLogFileRoot() override { - return QString(); + return minecraftRoot(); } - QStringList processMinecraftArgs(AuthSessionPtr account) const override; + QString getStatusbarDescription() override; QStringList verboseDescription(AuthSessionPtr session) override; -protected: - std::shared_ptr<LaunchStep> createMainLaunchStep(LaunchTask *parent, AuthSessionPtr session) override; - QStringList validLaunchMethods() override; - QString launchMethod() override; - + QProcessEnvironment createEnvironment() override + { + return QProcessEnvironment(); + } + QMap<QString, QString> getVariables() const override + { + return {}; + } protected: mutable std::shared_ptr<LegacyModList> jar_mod_list; - mutable std::shared_ptr<ModList> core_mod_list; - mutable std::shared_ptr<ModList> loader_mod_list; - mutable std::shared_ptr<ModList> texture_pack_list; mutable std::shared_ptr<WorldList> m_world_list; - std::shared_ptr<Setting> m_lwjglFolderSetting; -protected -slots: - virtual void jarModsChanged(); }; diff --git a/api/logic/minecraft/legacy/LegacyModList.cpp b/api/logic/minecraft/legacy/LegacyModList.cpp index 052f75fd..638b2e21 100644 --- a/api/logic/minecraft/legacy/LegacyModList.cpp +++ b/api/logic/minecraft/legacy/LegacyModList.cpp @@ -1,4 +1,4 @@ -/* Copyright 2013-2017 MultiMC Contributors +/* Copyright 2013-2018 MultiMC Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,55 +15,26 @@ #include "LegacyModList.h" #include <FileSystem.h> -#include <QMimeData> -#include <QUrl> -#include <QUuid> #include <QString> -#include <QFileSystemWatcher> #include <QDebug> LegacyModList::LegacyModList(const QString &dir, const QString &list_file) - : QAbstractListModel(), m_dir(dir), m_list_file(list_file) + : m_dir(dir), m_list_file(list_file) { FS::ensureFolderPathExists(m_dir.absolutePath()); m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs | QDir::NoSymLinks); m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware); - m_list_id = QUuid::createUuid().toString(); - m_watcher = new QFileSystemWatcher(this); - is_watching = false; - connect(m_watcher, SIGNAL(directoryChanged(QString)), this, - SLOT(directoryChanged(QString))); } -void LegacyModList::startWatching() -{ - update(); - is_watching = m_watcher->addPath(m_dir.absolutePath()); - if (is_watching) - { - qDebug() << "Started watching " << m_dir.absolutePath(); - } - else - { - qDebug() << "Failed to start watching " << m_dir.absolutePath(); - } -} - -void LegacyModList::stopWatching() -{ - is_watching = !m_watcher->removePath(m_dir.absolutePath()); - if (!is_watching) + struct OrderItem { - qDebug() << "Stopped watching " << m_dir.absolutePath(); - } - else - { - qDebug() << "Failed to stop watching " << m_dir.absolutePath(); - } -} + QString id; + bool enabled = false; + }; + typedef QList<OrderItem> OrderList; -void LegacyModList::internalSort(QList<Mod> &what) +static void internalSort(QList<Mod> &what) { auto predicate = [](const Mod &left, const Mod &right) { @@ -76,9 +47,43 @@ void LegacyModList::internalSort(QList<Mod> &what) std::sort(what.begin(), what.end(), predicate); } +static OrderList readListFile(const QString &m_list_file) +{ + OrderList itemList; + if (m_list_file.isNull() || m_list_file.isEmpty()) + return itemList; + + QFile textFile(m_list_file); + if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text)) + return OrderList(); + + QTextStream textStream; + textStream.setAutoDetectUnicode(true); + textStream.setDevice(&textFile); + while (true) + { + QString line = textStream.readLine(); + if (line.isNull() || line.isEmpty()) + break; + else + { + OrderItem it; + it.enabled = !line.endsWith(".disabled"); + if (!it.enabled) + { + line.chop(9); + } + it.id = line; + itemList.append(it); + } + } + textFile.close(); + return itemList; +} + bool LegacyModList::update() { - if (!isValid()) + if (!m_dir.exists() || !m_dir.isReadable()) return false; QList<Mod> orderedMods; @@ -88,7 +93,7 @@ bool LegacyModList::update() bool orderOrStateChanged = false; // first, process the ordered items (if any) - OrderList listOrder = readListFile(); + OrderList listOrder = readListFile(m_list_file); for (auto item : listOrder) { QFileInfo infoEnabled(m_dir.filePath(item.id)); @@ -157,460 +162,10 @@ bool LegacyModList::update() } } } - beginResetModel(); mods.swap(orderedMods); - endResetModel(); if (orderOrStateChanged && !m_list_file.isEmpty()) { qDebug() << "Mod list " << m_list_file << " changed!"; - saveListFile(); - emit changed(); - } - return true; -} - -void LegacyModList::directoryChanged(QString path) -{ - update(); -} - -LegacyModList::OrderList LegacyModList::readListFile() -{ - OrderList itemList; - if (m_list_file.isNull() || m_list_file.isEmpty()) - return itemList; - - QFile textFile(m_list_file); - if (!textFile.open(QIODevice::ReadOnly | QIODevice::Text)) - return OrderList(); - - QTextStream textStream; - textStream.setAutoDetectUnicode(true); - textStream.setDevice(&textFile); - while (true) - { - QString line = textStream.readLine(); - if (line.isNull() || line.isEmpty()) - break; - else - { - OrderItem it; - it.enabled = !line.endsWith(".disabled"); - if (!it.enabled) - { - line.chop(9); - } - it.id = line; - itemList.append(it); - } - } - textFile.close(); - return itemList; -} - -bool LegacyModList::saveListFile() -{ - if (m_list_file.isNull() || m_list_file.isEmpty()) - return false; - QFile textFile(m_list_file); - if (!textFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - return false; - QTextStream textStream; - textStream.setGenerateByteOrderMark(true); - textStream.setCodec("UTF-8"); - textStream.setDevice(&textFile); - for (auto mod : mods) - { - textStream << mod.mmc_id(); - if (!mod.enabled()) - textStream << ".disabled"; - textStream << endl; - } - textFile.close(); - return false; -} - -bool LegacyModList::isValid() -{ - return m_dir.exists() && m_dir.isReadable(); -} - -bool LegacyModList::installMod(const QString &filename, int index) -{ - // NOTE: fix for GH-1178: remove trailing slash to avoid issues with using the empty result of QFileInfo::fileName - QFileInfo fileinfo(FS::NormalizePath(filename)); - - qDebug() << "installing: " << fileinfo.absoluteFilePath(); - - if (!fileinfo.exists() || !fileinfo.isReadable() || index < 0) - { - return false; - } - Mod m(fileinfo); - if (!m.valid()) - return false; - - // if it's already there, replace the original mod (in place) - int idx = mods.indexOf(m); - if (idx != -1) - { - int idx2 = mods.indexOf(m, idx + 1); - if (idx2 != -1) - return false; - if (mods[idx].replace(m)) - { - - auto left = this->index(index); - auto right = this->index(index, columnCount(QModelIndex()) - 1); - emit dataChanged(left, right); - saveListFile(); - update(); - return true; - } - return false; - } - - auto type = m.type(); - if (type == Mod::MOD_UNKNOWN) - return false; - if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD) - { - QString newpath = FS::PathCombine(m_dir.path(), fileinfo.fileName()); - if (!QFile::copy(fileinfo.filePath(), newpath)) - return false; - m.repath(newpath); - beginInsertRows(QModelIndex(), index, index); - mods.insert(index, m); - endInsertRows(); - saveListFile(); - update(); - return true; - } - else if (type == Mod::MOD_FOLDER) - { - - QString from = fileinfo.filePath(); - QString to = FS::PathCombine(m_dir.path(), fileinfo.fileName()); - if (!FS::copy(from, to)()) - return false; - m.repath(to); - beginInsertRows(QModelIndex(), index, index); - mods.insert(index, m); - endInsertRows(); - saveListFile(); - update(); - return true; } - return false; -} - -bool LegacyModList::deleteMod(int index) -{ - if (index >= mods.size() || index < 0) - return false; - Mod &m = mods[index]; - if (m.destroy()) - { - beginRemoveRows(QModelIndex(), index, index); - mods.removeAt(index); - endRemoveRows(); - saveListFile(); - emit changed(); - return true; - } - return false; -} - -bool LegacyModList::deleteMods(int first, int last) -{ - for (int i = first; i <= last; i++) - { - Mod &m = mods[i]; - m.destroy(); - } - beginRemoveRows(QModelIndex(), first, last); - mods.erase(mods.begin() + first, mods.begin() + last + 1); - endRemoveRows(); - saveListFile(); - emit changed(); - return true; -} - -bool LegacyModList::moveModTo(int from, int to) -{ - if (from < 0 || from >= mods.size()) - return false; - if (to >= rowCount()) - to = rowCount() - 1; - if (to == -1) - to = rowCount() - 1; - if (from == to) - return false; - int togap = to > from ? to + 1 : to; - beginMoveRows(QModelIndex(), from, from, QModelIndex(), togap); - mods.move(from, to); - endMoveRows(); - saveListFile(); - emit changed(); - return true; -} - -bool LegacyModList::moveModUp(int from) -{ - if (from > 0) - return moveModTo(from, from - 1); - return false; -} - -bool LegacyModList::moveModsUp(int first, int last) -{ - if (first == 0) - return false; - - beginMoveRows(QModelIndex(), first, last, QModelIndex(), first - 1); - mods.move(first - 1, last); - endMoveRows(); - saveListFile(); - emit changed(); return true; } - -bool LegacyModList::moveModDown(int from) -{ - if (from < 0) - return false; - if (from < mods.size() - 1) - return moveModTo(from, from + 1); - return false; -} - -bool LegacyModList::moveModsDown(int first, int last) -{ - if (last == mods.size() - 1) - return false; - - beginMoveRows(QModelIndex(), first, last, QModelIndex(), last + 2); - mods.move(last + 1, first); - endMoveRows(); - saveListFile(); - emit changed(); - return true; -} - -int LegacyModList::columnCount(const QModelIndex &parent) const -{ - return 3; -} - -QVariant LegacyModList::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - - int row = index.row(); - int column = index.column(); - - if (row < 0 || row >= mods.size()) - return QVariant(); - - switch (role) - { - case Qt::DisplayRole: - switch (column) - { - case NameColumn: - return mods[row].name(); - case VersionColumn: - return mods[row].version(); |
