diff options
Diffstat (limited to 'logic')
75 files changed, 4531 insertions, 1928 deletions
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index e166449f..6a6b195b 100644 --- a/logic/BaseInstance.cpp +++ b/logic/BaseInstance.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "MultiMC.h" #include "BaseInstance.h" #include "BaseInstance_p.h" @@ -131,9 +132,9 @@ InstanceList *BaseInstance::instList() const return NULL; } -InstVersionList *BaseInstance::versionList() const +std::shared_ptr<BaseVersionList> BaseInstance::versionList() const { - return &MinecraftVersionList::getMainList(); + return MMC->minecraftlist(); } SettingsObject &BaseInstance::settings() const diff --git a/logic/BaseInstance.h b/logic/BaseInstance.h index cc9422be..b083c24a 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -3,7 +3,7 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software @@ -21,7 +21,8 @@ #include <settingsobject.h> #include "inifile.h" -#include "lists/InstVersionList.h" +#include "lists/BaseVersionList.h" +#include "net/LoginTask.h" class QDialog; class BaseUpdate; @@ -32,9 +33,9 @@ class BaseInstancePrivate; /*! * \brief Base class for instances. - * This class implements many functions that are common between instances and + * This class implements many functions that are common between instances and * provides a standard interface for all instances. - * + * * To create a new instance type, create a new class inheriting from this class * and implement the pure virtual functions. */ @@ -43,66 +44,72 @@ class BaseInstance : public QObject Q_OBJECT protected: /// no-touchy! - BaseInstance(BaseInstancePrivate * d, const QString &rootDir, SettingsObject * settings, QObject *parent = 0); + BaseInstance(BaseInstancePrivate *d, const QString &rootDir, SettingsObject *settings, + QObject *parent = 0); + public: /// virtual destructor to make sure the destruction is COMPLETE virtual ~BaseInstance() {}; - - /// nuke thoroughly - deletes the instance contents, notifies the list/model which is responsible of cleaning up the husk + + /// nuke thoroughly - deletes the instance contents, notifies the list/model which is + /// responsible of cleaning up the husk void nuke(); - - /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to be unique. + + /// The instance's ID. The ID SHALL be determined by MMC internally. The ID IS guaranteed to + /// be unique. QString id() const; - + /// get the type of this instance QString instanceType() const; - + /// Path to the instance's root directory. QString instanceRoot() const; - + /// Path to the instance's minecraft directory. QString minecraftRoot() const; - + QString name() const; void setName(QString val); - + QString iconKey() const; void setIconKey(QString val); - + QString notes() const; void setNotes(QString val); - + QString group() const; void setGroupInitial(QString val); void setGroupPost(QString val); - - + virtual QString intendedVersionId() const = 0; virtual bool setIntendedVersionId(QString version) = 0; - + + virtual bool versionIsCustom() = 0; + /*! * The instance's current version. - * This value represents the instance's current version. If this value is + * This value represents the instance's current version. If this value is * different from the intendedVersion, the instance should be updated. * \warning Don't change this value unless you know what you're doing. */ virtual QString currentVersionId() const = 0; - //virtual void setCurrentVersionId(QString val) = 0; - + // virtual void setCurrentVersionId(QString val) = 0; + /*! * Whether or not Minecraft should be downloaded when the instance is launched. */ virtual bool shouldUpdate() const = 0; virtual void setShouldUpdate(bool val) = 0; - /// Get the curent base jar of this instance. By default, it's the versions/$version/$version.jar + /// Get the curent base jar of this instance. By default, it's the + /// versions/$version/$version.jar QString baseJar() const; /// the default base jar of this instance virtual QString defaultBaseJar() const = 0; /// the default custom base jar of this instance virtual QString defaultCustomBaseJar() const = 0; - + /*! * Whether or not custom base jar is used */ @@ -113,7 +120,7 @@ public: */ QString customBaseJar() const; void setCustomBaseJar(QString val); - + /** * Gets the time that the instance was last launched. * Stored in milliseconds since epoch. @@ -121,53 +128,54 @@ public: qint64 lastLaunch() const; /// Sets the last launched time to 'val' milliseconds since epoch void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch()); - + /*! - * \brief Gets the instance list that this instance is a part of. - * Returns NULL if this instance is not in a list + * \brief Gets the instance list that this instance is a part of. + * Returns NULL if this instance is not in a list * (the parent is not an InstanceList). - * \return A pointer to the InstanceList containing this instance. + * \return A pointer to the InstanceList containing this instance. */ InstanceList *instList() const; - + /*! * \brief Gets a pointer to this instance's version list. * \return A pointer to the available version list for this instance. */ - virtual InstVersionList *versionList() const; - + virtual std::shared_ptr<BaseVersionList> versionList() const; + /*! * \brief Gets this instance's settings object. * This settings object stores instance-specific settings. * \return A pointer to this instance's settings object. */ virtual SettingsObject &settings() const; - + /// returns a valid update task if update is needed, NULL otherwise - virtual BaseUpdate* doUpdate() = 0; - + virtual BaseUpdate *doUpdate() = 0; + /// returns a valid minecraft process, ready for launch - virtual MinecraftProcess* prepareForLaunch(QString user, QString session) = 0; - - /// do any necessary cleanups after the instance finishes. also runs before 'prepareForLaunch' + virtual MinecraftProcess *prepareForLaunch(LoginResponse response) = 0; + + /// do any necessary cleanups after the instance finishes. also runs before + /// 'prepareForLaunch' virtual void cleanupAfterRun() = 0; - + /// create a mod edit dialog for the instance - virtual QDialog * createModEditDialog ( QWidget* parent ) = 0; - + virtual QDialog *createModEditDialog(QWidget *parent) = 0; + /// is a particular action enabled with this instance selected? virtual bool menuActionEnabled(QString action_name) const = 0; - + virtual QString getStatusbarDescription() = 0; - + /// FIXME: this really should be elsewhere... virtual QString instanceConfigFolder() const = 0; - + signals: /*! * \brief Signal emitted when properties relevant to the instance view change */ - void propertiesChanged(BaseInstance * inst); + void propertiesChanged(BaseInstance *inst); /*! * \brief Signal emitted when groups are affected in any way */ @@ -175,12 +183,11 @@ signals: /*! * \brief The instance just got nuked. Hurray! */ - void nuked(BaseInstance * inst); - + void nuked(BaseInstance *inst); + protected: - QSharedPointer<BaseInstancePrivate> inst_d; + std::shared_ptr<BaseInstancePrivate> inst_d; }; // pointer for lazy people -typedef QSharedPointer<BaseInstance> InstancePtr; - +typedef std::shared_ptr<BaseInstance> InstancePtr; diff --git a/logic/BaseInstance_p.h b/logic/BaseInstance_p.h index a30916a4..06c0c0ba 100644 --- a/logic/BaseInstance_p.h +++ b/logic/BaseInstance_p.h @@ -4,7 +4,7 @@ class BaseInstance; -#define I_D(Class) Class##Private * const d = (Class##Private * const) inst_d.data() +#define I_D(Class) Class##Private * const d = (Class##Private * const) inst_d.get() struct BaseInstancePrivate { diff --git a/logic/BaseUpdate.cpp b/logic/BaseUpdate.cpp index b086ab14..02b29d32 100644 --- a/logic/BaseUpdate.cpp +++ b/logic/BaseUpdate.cpp @@ -7,7 +7,5 @@ BaseUpdate::BaseUpdate ( BaseInstance* inst, QObject* parent ) : Task ( parent ) void BaseUpdate::updateDownloadProgress(qint64 current, qint64 total) { - // The progress on the current file is current / total - float currentDLProgress = (float) current / (float) total; - setProgress((int)(currentDLProgress * 100)); // convert to percentage + emit progress(current, total); }
\ No newline at end of file diff --git a/logic/BaseVersion.h b/logic/BaseVersion.h new file mode 100644 index 00000000..01745c46 --- /dev/null +++ b/logic/BaseVersion.h @@ -0,0 +1,45 @@ +/* Copyright 2013 MultiMC Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include <memory> + +/*! + * An abstract base class for versions. + */ +struct BaseVersion +{ + /*! + * A string used to identify this version in config files. + * This should be unique within the version list or shenanigans will occur. + */ + virtual QString descriptor() = 0; + + /*! + * The name of this version as it is displayed to the user. + * For example: "1.5.1" + */ + virtual QString name() = 0; + + /*! + * This should return a string that describes + * the kind of version this is (Stable, Beta, Snapshot, whatever) + */ + virtual QString typeString() const = 0; +}; + +typedef std::shared_ptr<BaseVersion> BaseVersionPtr; + +Q_DECLARE_METATYPE( BaseVersionPtr )
\ No newline at end of file diff --git a/logic/EnabledItemFilter.cpp b/logic/EnabledItemFilter.cpp new file mode 100644 index 00000000..6ecd0271 --- /dev/null +++ b/logic/EnabledItemFilter.cpp @@ -0,0 +1,30 @@ +#include "EnabledItemFilter.h" + +EnabledItemFilter::EnabledItemFilter(QObject* parent) + :QSortFilterProxyModel(parent) +{ + +} + +void EnabledItemFilter::setActive(bool active) +{ + m_active = active; + invalidateFilter(); +} + +bool EnabledItemFilter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + if(!m_active) + return true; + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + if(sourceModel()->flags(index) & Qt::ItemIsEnabled) + { + return true; + } + return false; +} + +bool EnabledItemFilter::lessThan(const QModelIndex& left, const QModelIndex& right) const +{ + return QSortFilterProxyModel::lessThan(left, right); +} diff --git a/logic/EnabledItemFilter.h b/logic/EnabledItemFilter.h new file mode 100644 index 00000000..cb6d4041 --- /dev/null +++ b/logic/EnabledItemFilter.h @@ -0,0 +1,16 @@ +#pragma once +#include <QSortFilterProxyModel> + +class EnabledItemFilter : public QSortFilterProxyModel +{ + Q_OBJECT +public: + EnabledItemFilter(QObject *parent = 0); + void setActive(bool active); + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const; +private: + bool m_active = false; +};
\ No newline at end of file diff --git a/logic/ForgeInstaller.cpp b/logic/ForgeInstaller.cpp new file mode 100644 index 00000000..a946dd44 --- /dev/null +++ b/logic/ForgeInstaller.cpp @@ -0,0 +1,140 @@ +#include "ForgeInstaller.h" +#include "OneSixVersion.h" +#include "OneSixLibrary.h" +#include "net/HttpMetaCache.h" +#include <quazip.h> +#include <quazipfile.h> +#include <pathutils.h> +#include <QStringList> +#include "MultiMC.h" + +ForgeInstaller::ForgeInstaller(QString filename, QString universal_url) +{ + std::shared_ptr<OneSixVersion> newVersion; + m_universal_url = universal_url; + + QuaZip zip(filename); + if (!zip.open(QuaZip::mdUnzip)) + return; + + QuaZipFile file(&zip); + + // read the install profile + if (!zip.setCurrentFile("install_profile.json")) + return; + + QJsonParseError jsonError; + if (!file.open(QIODevice::ReadOnly)) + return; + QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError); + file.close(); + if (jsonError.error != QJsonParseError::NoError) + return; + + if (!jsonDoc.isObject()) + return; + + QJsonObject root = jsonDoc.object(); + + auto installVal = root.value("install"); + auto versionInfoVal = root.value("versionInfo"); + if (!installVal.isObject() || !versionInfoVal.isObject()) + return; + + // read the forge version info + { + newVersion = OneSixVersion::fromJson(versionInfoVal.toObject()); + if (!newVersion) + return; + } + + QJsonObject installObj = installVal.toObject(); + QString libraryName = installObj.value("path").toString(); + internalPath = installObj.value("filePath").toString(); + + // where do we put the library? decode the mojang path + OneSixLibrary lib(libraryName); + lib.finalize(); + + auto cacheentry = MMC->metacache()->resolveEntry("libraries", lib.storagePath()); + finalPath = "libraries/" + lib.storagePath(); + if (!ensureFilePathExists(finalPath)) + return; + + if (!zip.setCurrentFile(internalPath)) + return; + if (!file.open(QIODevice::ReadOnly)) + return; + { + QByteArray data = file.readAll(); + // extract file + QSaveFile extraction(finalPath); + if (!extraction.open(QIODevice::WriteOnly)) + return; + if (extraction.write(data) != data.size()) + return; + if (!extraction.commit()) + return; + QCryptographicHash md5sum(QCryptographicHash::Md5); + md5sum.addData(data); + + cacheentry->stale = false; + cacheentry->md5sum = md5sum.result().toHex().constData(); + MMC->metacache()->updateEntry(cacheentry); + } + file.close(); + + m_forge_version = newVersion; + realVersionId = m_forge_version->id = installObj.value("minecraft").toString(); +} + +bool ForgeInstaller::apply(std::shared_ptr<OneSixVersion> to) +{ + if (!m_forge_version) + return false; + to->externalUpdateStart(); + int sliding_insert_window = 0; + { + // for each library in the version we are adding (except for the blacklisted) + QSet<QString> blacklist{"lwjgl", "lwjgl_util", "lwjgl-platform"}; + for (auto lib : m_forge_version->libraries) + { + QString libName = lib->name(); + // WARNING: This could actually break. + // if this is the actual forge lib, set an absolute url for the download + if (libName.contains("minecraftforge")) + { + lib->setAbsoluteUrl(m_universal_url); + } + else if (libName.contains("scala")) + { + lib->setHint("forge-pack-xz"); + } + if (blacklist.contains(libName)) + continue; + + // find an entry that matches this one + bool found = false; + for (auto tolib : to->libraries) + { + if (tolib->name() != libName) + continue; + found = true; + // replace lib + tolib = lib; + break; + } + if (!found) + { + // add lib + to->libraries.insert(sliding_insert_window, lib); + sliding_insert_window++; + } + } + to->mainClass = m_forge_version->mainClass; + to->minecraftArguments = m_forge_version->minecraftArguments; + to->processArguments = m_forge_version->processArguments; + } + to->externalUpdateFinish(); + return to->toOriginalFile(); +} diff --git a/logic/ForgeInstaller.h b/logic/ForgeInstaller.h new file mode 100644 index 00000000..f6f22a2a --- /dev/null +++ b/logic/ForgeInstaller.h @@ -0,0 +1,25 @@ +#pragma once +#include <QString> +#include <memory> |
