diff options
Diffstat (limited to 'logic')
37 files changed, 1020 insertions, 478 deletions
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp index e166449f..10bb4573 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 +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..fa317ba1 100644 --- a/logic/BaseInstance.h +++ b/logic/BaseInstance.h @@ -21,7 +21,7 @@ #include <settingsobject.h> #include "inifile.h" -#include "lists/InstVersionList.h" +#include "lists/BaseVersionList.h" class QDialog; class BaseUpdate; @@ -134,7 +134,7 @@ public: * \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 BaseVersionList *versionList() const; /*! * \brief Gets this instance's settings object. 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/InstanceVersion.h b/logic/BaseVersion.h index eecd9c4e..be717fee 100644 --- a/logic/InstanceVersion.h +++ b/logic/BaseVersion.h @@ -19,50 +19,27 @@ /*! * An abstract base class for versions. */ -struct InstVersion +struct BaseVersion { /*! - * Checks if this version is less (older) than the given version. - * \param other The version to compare this one to. - * \return True if this version is older than the given version. - */ - virtual bool operator<(const InstVersion &rhs) const - { - return timestamp < rhs.timestamp; - } - - /*! - * Checks if this version is greater (newer) than the given version. - * \param other The version to compare this one to. - * \return True if this version is newer than the given version. - */ - virtual bool operator>( const InstVersion& rhs ) const - { - return timestamp > rhs.timestamp; - } - - /*! * A string used to identify this version in config files. * This should be unique within the version list or shenanigans will occur. */ - QString descriptor; + virtual QString descriptor() = 0; + /*! * The name of this version as it is displayed to the user. * For example: "1.5.1" */ - QString name; + virtual QString name() = 0; + /*! - * Gets the version's timestamp. - * This is primarily used for sorting versions in a list. + * This should return a string that describes + * the kind of version this is (Stable, Beta, Snapshot, whatever) */ - qint64 timestamp; - - virtual QString typeString() const - { - return "InstVersion"; - } + virtual QString typeString() const = 0; }; -typedef QSharedPointer<InstVersion> InstVersionPtr; +typedef QSharedPointer<BaseVersion> BaseVersionPtr; -Q_DECLARE_METATYPE( InstVersionPtr )
\ No newline at end of file +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/InstanceFactory.cpp b/logic/InstanceFactory.cpp index f0630568..b5832ce5 100644 --- a/logic/InstanceFactory.cpp +++ b/logic/InstanceFactory.cpp @@ -22,7 +22,7 @@ #include "LegacyInstance.h" #include "OneSixInstance.h" #include "NostalgiaInstance.h" -#include "InstanceVersion.h" +#include "BaseVersion.h" #include "MinecraftVersion.h" #include "inifile.h" @@ -68,7 +68,7 @@ InstanceFactory::InstLoadError InstanceFactory::loadInstance(BaseInstance *&inst } -InstanceFactory::InstCreateError InstanceFactory::createInstance( BaseInstance*& inst, InstVersionPtr version, const QString& instDir ) +InstanceFactory::InstCreateError InstanceFactory::createInstance( BaseInstance*& inst, BaseVersionPtr version, const QString& instDir ) { QDir rootDir(instDir); @@ -89,19 +89,19 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance( BaseInstance*& case MinecraftVersion::Legacy: m_settings->set("InstanceType", "Legacy"); inst = new LegacyInstance(instDir, m_settings, this); - inst->setIntendedVersionId(version->descriptor); + inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); break; case MinecraftVersion::OneSix: m_settings->set("InstanceType", "OneSix"); inst = new OneSixInstance(instDir, m_settings, this); - inst->setIntendedVersionId(version->descriptor); + inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); break; case MinecraftVersion::Nostalgia: m_settings->set("InstanceType", "Nostalgia"); inst = new NostalgiaInstance(instDir, m_settings, this); - inst->setIntendedVersionId(version->descriptor); + inst->setIntendedVersionId(version->descriptor()); inst->setShouldUseCustomBaseJar(false); break; default: diff --git a/logic/InstanceFactory.h b/logic/InstanceFactory.h index ed54f520..1c527749 100644 --- a/logic/InstanceFactory.h +++ b/logic/InstanceFactory.h @@ -19,9 +19,9 @@ #include <QMap> #include <QList> -#include "InstanceVersion.h" +#include "BaseVersion.h" -class InstVersion; +class BaseVersion; class BaseInstance; /*! @@ -61,7 +61,7 @@ public: * - InstExists if the given instance directory is already an instance. * - CantCreateDir if the given instance directory cannot be created. */ - InstCreateError createInstance(BaseInstance *&inst, InstVersionPtr version, const QString &instDir); + InstCreateError createInstance(BaseInstance *&inst, BaseVersionPtr version, const QString &instDir); /*! * \brief Loads an instance from the given directory. diff --git a/logic/InstanceLauncher.cpp b/logic/InstanceLauncher.cpp index a0557b37..f2f792c9 100644 --- a/logic/InstanceLauncher.cpp +++ b/logic/InstanceLauncher.cpp @@ -3,7 +3,7 @@ #include <iostream> #include "gui/logindialog.h" -#include "gui/taskdialog.h" +#include "gui/ProgressDialog.h" #include "gui/consolewindow.h" #include "logic/tasks/LoginTask.h" #include "logic/MinecraftProcess.h" @@ -48,7 +48,7 @@ void InstanceLauncher::doLogin ( const QString& errorMsg ) { UserInfo uInfo {loginDlg->getUsername(), loginDlg->getPassword() }; - TaskDialog* tDialog = new TaskDialog ( nullptr ); + ProgressDialog* tDialog = new ProgressDialog ( nullptr ); LoginTask* loginTask = new LoginTask ( uInfo, tDialog ); connect ( loginTask, SIGNAL ( succeeded() ),SLOT ( onLoginComplete() ), Qt::QueuedConnection ); connect ( loginTask, SIGNAL ( failed ( QString ) ),SLOT ( doLogin ( QString ) ), Qt::QueuedConnection ); diff --git a/logic/LegacyUpdate.cpp b/logic/LegacyUpdate.cpp index b8e179a5..0f58e3e3 100644 --- a/logic/LegacyUpdate.cpp +++ b/logic/LegacyUpdate.cpp @@ -34,15 +34,15 @@ void LegacyUpdate::lwjglStart() return; } - auto &list = LWJGLVersionList::get(); - if(!list.isLoaded()) + auto list = MMC->lwjgllist(); + if(!list->isLoaded()) { emitFailed("Too soon! Let the LWJGL list load :)"); return; } setStatus("Downloading new LWJGL."); - auto version = list.getVersion(lwjglVersion); + auto version = list->getVersion(lwjglVersion); if(!version) { emitFailed("Game update failed: the selected LWJGL version is invalid."); @@ -59,7 +59,7 @@ void LegacyUpdate::lwjglStart() QNetworkReply * rep = worker->get ( req ); m_reply = QSharedPointer<QNetworkReply> (rep, &QObject::deleteLater); - connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); connect(worker, SIGNAL(finished(QNetworkReply*)), SLOT(lwjglFinished(QNetworkReply*))); //connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); } @@ -97,7 +97,7 @@ void LegacyUpdate::lwjglFinished(QNetworkReply* reply) req.setRawHeader("Host", hostname.toLatin1()); req.setHeader(QNetworkRequest::UserAgentHeader, "Wget/1.14 (linux-gnu)"); QNetworkReply * rep = worker->get(req); - connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); m_reply = QSharedPointer<QNetworkReply> (rep, &QObject::deleteLater); return; } @@ -170,7 +170,7 @@ void LegacyUpdate::extractLwjgl() if (name.contains(nativesDir)) { int lastSlash = name.lastIndexOf('/'); - int lastBackSlash = name.lastIndexOf('/'); + int lastBackSlash = name.lastIndexOf('\\'); if(lastSlash != -1) name = name.mid(lastSlash+1); else if(lastBackSlash != -1) @@ -232,7 +232,7 @@ void LegacyUpdate::jarStart() legacyDownloadJob.reset(dljob); connect(dljob, SIGNAL(succeeded()), SLOT(jarFinished())); connect(dljob, SIGNAL(failed()), SLOT(jarFailed())); - connect(dljob, SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + connect(dljob, SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); legacyDownloadJob->start(); } diff --git a/logic/MinecraftVersion.h b/logic/MinecraftVersion.h index 27977262..53c2f5ef 100644 --- a/logic/MinecraftVersion.h +++ b/logic/MinecraftVersion.h @@ -15,17 +15,16 @@ #pragma once -#include "InstanceVersion.h" +#include "BaseVersion.h" #include <QStringList> -struct MinecraftVersion : public InstVersion +struct MinecraftVersion : public BaseVersion { - // From InstVersion: - /* - QString m_descriptor; - QString m_name; - qint64 m_timestamp; - */ + /*! + * Gets the version's timestamp. + * This is primarily used for sorting versions in a list. + */ + qint64 timestamp; /// The URL that this version will be downloaded from. maybe. QString download_url; @@ -44,6 +43,20 @@ struct MinecraftVersion : public InstVersion /// is this a snapshot? bool is_snapshot = false; + QString m_name; + + QString m_descriptor; + + virtual QString descriptor() + { + return m_descriptor; + } + + virtual QString name() + { + return m_name; + } + virtual QString typeString() const { QStringList pre_final; diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp index c926df60..7b038c46 100644 --- a/logic/OneSixInstance.cpp +++ b/logic/OneSixInstance.cpp @@ -214,6 +214,13 @@ bool OneSixInstance::shouldUpdate() const return true; } +bool OneSixInstance::versionIsCustom() +{ + QString verpath_custom = PathCombine(instanceRoot(), "custom.json"); + QFile versionfile(verpath_custom); + return versionfile.exists(); +} + QString OneSixInstance::currentVersionId() const { return intendedVersionId(); @@ -224,6 +231,13 @@ bool OneSixInstance::reloadFullVersion() I_D(OneSixInstance); QString verpath = PathCombine(instanceRoot(), "version.json"); + { + QString verpath_custom = PathCombine(instanceRoot(), "custom.json"); + QFile versionfile(verpath_custom); + if(versionfile.exists()) + verpath = verpath_custom; + } + QFile versionfile(verpath); if(versionfile.exists() && versionfile.open(QIODevice::ReadOnly)) { @@ -264,7 +278,12 @@ bool OneSixInstance::menuActionEnabled ( QString action_name ) const QString OneSixInstance::getStatusbarDescription() { - return "One Six : " + intendedVersionId(); + QString descr = "One Six : " + intendedVersionId(); + if(versionIsCustom()) + { + descr + " (custom)"; + } + return descr; } QString OneSixInstance::loaderModsDir() const diff --git a/logic/OneSixInstance.h b/logic/OneSixInstance.h index a4c67ed1..72bde630 100644 --- a/logic/OneSixInstance.h +++ b/logic/OneSixInstance.h @@ -41,6 +41,8 @@ public: bool reloadFullVersion(); /// get the current full version info QSharedPointer<OneSixVersion> getFullVersion(); + /// is the current version original, or custom? + bool versionIsCustom(); virtual QString defaultBaseJar() const; virtual QString defaultCustomBaseJar() const; diff --git a/logic/OneSixInstance_p.h b/logic/OneSixInstance_p.h index c098c9e2..7b1ca82e 100644 --- a/logic/OneSixInstance_p.h +++ b/logic/OneSixInstance_p.h @@ -2,6 +2,7 @@ #include "BaseInstance_p.h" #include "OneSixVersion.h" +#include "OneSixLibrary.h" #include "ModList.h" struct OneSixInstancePrivate: public BaseInstancePrivate diff --git a/logic/OneSixLibrary.cpp b/logic/OneSixLibrary.cpp new file mode 100644 index 00000000..a45a4aec --- /dev/null +++ b/logic/OneSixLibrary.cpp @@ -0,0 +1,93 @@ +#include "OneSixLibrary.h" +#include "OneSixRule.h" +#include "OpSys.h" +void OneSixLibrary::finalize() +{ + QStringList parts = m_name.split ( ':' ); + QString relative = parts[0]; + relative.replace ( '.','/' ); + relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2]; + + if ( !m_is_native ) + relative += ".jar"; + else + { + if ( m_native_suffixes.contains ( currentSystem ) ) + { + relative += "-" + m_native_suffixes[currentSystem] + ".jar"; + } + else + { + // really, bad. + relative += ".jar"; + } + } + + m_decentname = parts[1]; + m_decentversion = parts[2]; + m_storage_path = relative; + m_download_path = m_base_url + relative; + + if ( m_rules.empty() ) + { + m_is_active = true; + } + else + { + RuleAction result = Disallow; + for ( auto rule: m_rules ) + { + RuleAction temp = rule->apply ( this ); + if ( temp != Defer ) + result = temp; + } + m_is_active = ( result == Allow ); + } + if ( m_is_native ) + { + m_is_active = m_is_active && m_native_suffixes.contains ( currentSystem ); + m_decenttype = "Native"; + } + else + { + m_decenttype = "Java"; + } +} + +void OneSixLibrary::setName ( QString name ) +{ + m_name = name; +} +void OneSixLibrary::setBaseUrl ( QString base_url ) +{ + m_base_url = base_url; +} +void OneSixLibrary::setIsNative() +{ + m_is_native = true; +} +void OneSixLibrary::addNative ( OpSys os, QString suffix ) +{ + m_is_native = true; + m_native_suffixes[os] = suffix; +} +void OneSixLibrary::setRules ( QList< QSharedPointer< Rule > > rules ) +{ + m_rules = rules; +} +bool OneSixLibrary::isActive() +{ + return m_is_active; +} +bool OneSixLibrary::isNative() +{ + return m_is_native; +} +QString OneSixLibrary::downloadPath() +{ + return m_download_path; +} +QString OneSixLibrary::storagePath() +{ + return m_storage_path; +} diff --git a/logic/OneSixLibrary.h b/logic/OneSixLibrary.h new file mode 100644 index 00000000..ac16d3d3 --- /dev/null +++ b/logic/OneSixLibrary.h @@ -0,0 +1,90 @@ +#pragma once +#include <QString> +#include <QStringList> +#include <QMap> +#include <QSharedPointer> +#include "OpSys.h" + +class Rule; + +class OneSixLibrary +{ +private: + // basic values used internally (so far) + QString m_name; + QString m_base_url; + QList<QSharedPointer<Rule> > m_rules; + + // derived values used for real things + /// a decent name fit for display + QString m_decentname; + /// a decent version fit for display + QString m_decentversion; + /// a decent type fit for display + QString m_decenttype; + /// where to store the lib locally + QString m_storage_path; + /// where to download the lib from + QString m_download_path; + /// is this lib actually active on the current OS? + bool m_is_active; + /// is the library a native? + bool m_is_native; + /// native suffixes per OS + QMap<OpSys, QString> m_native_suffixes; +public: + QStringList extract_excludes; + +public: + /// Constructor + OneSixLibrary(QString name) + { + m_is_native = false; + m_is_active = false; + m_name = name; + m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/"; + } + + /** + * finalize the library, processing the input values into derived values and state + * + * This SHALL be called after all the values are parsed or after any further change. + */ + void finalize(); + + /// Set the library composite name + void setName(QString name); + /// get a decent-looking name + QString name() + { + return m_decentname; + } + /// get a decent-looking version + QString version() + { + return m_decentversion; + } + /// what kind of library is it? (for display) + QString type() + { + return m_decenttype; + } + /// Set the url base for downloads + void setBaseUrl(QString base_url); + + /// Call this to mark the library as 'native' (it's a zip archive with DLLs) + void setIsNative(); + /// Attach a name suffix to the specified OS native + void addNative(OpSys os, QString suffix); + /// Set the load rules + void setRules(QList<QSharedPointer<Rule> > rules); + + /// Returns true if the library should be loaded (or extracted, in case of natives) + bool isActive(); + /// Returns true if the library is native + bool isNative(); + /// Get the URL to download the library from + QString downloadPath(); + /// Get the relative path where the library should be saved + QString storagePath(); +}; diff --git a/logic/OneSixRule.cpp b/logic/OneSixRule.cpp new file mode 100644 index 00000000..85f7d434 --- /dev/null +++ b/logic/OneSixRule.cpp @@ -0,0 +1,10 @@ +#include "OneSixRule.h" + +RuleAction RuleAction_fromString(QString name) +{ + if(name == "allow") + return Allow; + if(name == "disallow") + return Disallow; + return Defer; +}
\ No newline at end of file diff --git a/logic/OneSixRule.h b/logic/OneSixRule.h new file mode 100644 index 00000000..465c963f --- /dev/null +++ b/logic/OneSixRule.h @@ -0,0 +1,70 @@ +#pragma once +#include <QString> +#include <QSharedPointer> + +class OneSixLibrary; +#include "OneSixLibrary.h" + +enum RuleAction +{ + Allow, + Disallow, + Defer +}; + +RuleAction RuleAction_fromString(QString); + +class Rule +{ +protected: + RuleAction m_result; + virtual bool applies(OneSixLibrary * parent) = 0; +public: + Rule(RuleAction result) + :m_result(result) {} + virtual ~Rule(){}; + RuleAction apply(OneSixLibrary * parent) + { + if(applies(parent)) + return m_result; + else + return Defer; + }; +}; + +class OsRule : public Rule +{ +private: + // the OS + OpSys m_system; + // the OS version regexp + QString m_version_regexp; +protected: + virtual bool applies ( OneSixLibrary* ) + { + return (m_system == currentSystem); + } + OsRule(RuleAction result, OpSys system, QString version_regexp) + : Rule(result), m_system(system), m_version_regexp(version_regexp) {} +public: + static QSharedPointer<OsRule> create(RuleAction result, OpSys system, QString version_regexp) + { + return QSharedPointer<OsRule> (new OsRule(result, system, version_regexp)); + } +}; + +class ImplicitRule : public Rule +{ +protected: + virtual bool applies ( OneSixLibrary* ) + { + return true; + } + ImplicitRule(RuleAction result) + : Rule(result) {} +public: + static QSharedPointer<ImplicitRule> create(RuleAction result) + { + return QSharedPointer<ImplicitRule> (new ImplicitRule(result)); + } +}; diff --git a/logic/OneSixUpdate.cpp b/logic/OneSixUpdate.cpp index ce71bde0..298ad28a 100644 --- a/logic/OneSixUpdate.cpp +++ b/logic/OneSixUpdate.cpp @@ -28,6 +28,7 @@ #include "lists/MinecraftVersionList.h" #include "VersionFactory.h" #include "OneSixVersion.h" +#include "OneSixLibrary.h" #include "OneSixInstance.h" #include "pathutils.h" @@ -48,7 +49,7 @@ void OneSixUpdate::executeTask() } // Get a pointer to the version object that corresponds to the instance's version. - targetVersion = MinecraftVersionList::getMainList().findVersion(intendedVersion).dynamicCast<MinecraftVersion>(); + targetVersion = MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast<MinecraftVersion>(); if(targetVersion == nullptr) { // don't do anything if it was invalid @@ -71,44 +72,59 @@ void OneSixUpdate::versionFileStart() setStatus("Getting the version files from Mojang."); QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); - urlstr += targetVersion->descriptor + "/" + targetVersion->descriptor + ".json"; + urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; auto job = new DownloadJob("Version index"); job->add(QUrl(urlstr)); specificVersionDownloadJob.reset(job); connect(specificVersionDownloadJob.data(), SIGNAL(succeeded()), SLOT(versionFileFinished())); connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed())); - connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SLOT(updateDownloadProgress(qint64,qint64))); + connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); specificVersionDownloadJob->start(); } void OneSixUpdate::versionFileFinished() { DownloadPtr DlJob = specificVersionDownloadJob->first(); + OneSixInstance * inst = (OneSixInstance *) m_inst; |
