Sync from quickmods
This commit is contained in:
parent
36efcf8d3c
commit
20cb97a35a
@ -251,12 +251,12 @@ MultiMC::MultiMC(int &argc, char **argv, bool root_override) : QApplication(argc
|
|||||||
std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory()));
|
std::shared_ptr<BaseProfilerFactory>(new JVisualVMFactory()));
|
||||||
for (auto profiler : m_profilers.values())
|
for (auto profiler : m_profilers.values())
|
||||||
{
|
{
|
||||||
profiler->registerSettings(m_settings.get());
|
profiler->registerSettings(m_settings);
|
||||||
}
|
}
|
||||||
m_tools.insert("mcedit", std::shared_ptr<BaseDetachedToolFactory>(new MCEditFactory()));
|
m_tools.insert("mcedit", std::shared_ptr<BaseDetachedToolFactory>(new MCEditFactory()));
|
||||||
for (auto tool : m_tools.values())
|
for (auto tool : m_tools.values())
|
||||||
{
|
{
|
||||||
tool->registerSettings(m_settings.get());
|
tool->registerSettings(m_settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
// launch instance, if that's what should be done
|
// launch instance, if that's what should be done
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
#include "libutil_config.h"
|
#include "libutil_config.h"
|
||||||
|
|
||||||
class QUrl;
|
class QUrl;
|
||||||
@ -10,10 +12,12 @@ namespace Util
|
|||||||
struct Version
|
struct Version
|
||||||
{
|
{
|
||||||
Version(const QString &str);
|
Version(const QString &str);
|
||||||
|
Version() {}
|
||||||
|
|
||||||
bool operator<(const Version &other) const;
|
bool operator<(const Version &other) const;
|
||||||
bool operator<=(const Version &other) const;
|
bool operator<=(const Version &other) const;
|
||||||
bool operator>(const Version &other) const;
|
bool operator>(const Version &other) const;
|
||||||
|
bool operator>=(const Version &other) const;
|
||||||
bool operator==(const Version &other) const;
|
bool operator==(const Version &other) const;
|
||||||
bool operator!=(const Version &other) const;
|
bool operator!=(const Version &other) const;
|
||||||
|
|
||||||
@ -24,9 +28,34 @@ struct Version
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_string;
|
QString m_string;
|
||||||
|
struct Section
|
||||||
|
{
|
||||||
|
explicit Section(const QString &str, const int num) : numValid(true), number(num), string(str) {}
|
||||||
|
explicit Section(const QString &str) : numValid(false), string(str) {}
|
||||||
|
explicit Section() {}
|
||||||
|
bool numValid;
|
||||||
|
int number;
|
||||||
|
QString string;
|
||||||
|
|
||||||
|
inline bool operator!=(const Section &other) const
|
||||||
|
{
|
||||||
|
return (numValid && other.numValid) ? (number != other.number) : (string != other.string);
|
||||||
|
}
|
||||||
|
inline bool operator<(const Section &other) const
|
||||||
|
{
|
||||||
|
return (numValid && other.numValid) ? (number < other.number) : (string < other.string);
|
||||||
|
}
|
||||||
|
inline bool operator>(const Section &other) const
|
||||||
|
{
|
||||||
|
return (numValid && other.numValid) ? (number > other.number) : (string > other.string);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
QList<Section> m_sections;
|
||||||
|
|
||||||
|
void parse();
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBUTIL_EXPORT QUrl expandQMURL(const QString &in);
|
|
||||||
LIBUTIL_EXPORT bool versionIsInInterval(const QString &version, const QString &interval);
|
LIBUTIL_EXPORT bool versionIsInInterval(const QString &version, const QString &interval);
|
||||||
|
LIBUTIL_EXPORT bool versionIsInInterval(const Version &version, const QString &interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,42 +7,20 @@
|
|||||||
|
|
||||||
Util::Version::Version(const QString &str) : m_string(str)
|
Util::Version::Version(const QString &str) : m_string(str)
|
||||||
{
|
{
|
||||||
|
parse();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Util::Version::operator<(const Version &other) const
|
bool Util::Version::operator<(const Version &other) const
|
||||||
{
|
{
|
||||||
QStringList parts1 = m_string.split('.');
|
const int size = qMax(m_sections.size(), other.m_sections.size());
|
||||||
QStringList parts2 = other.m_string.split('.');
|
for (int i = 0; i < size; ++i)
|
||||||
|
|
||||||
while (!parts1.isEmpty() && !parts2.isEmpty())
|
|
||||||
{
|
{
|
||||||
QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst();
|
const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i);
|
||||||
QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst();
|
const Section sec2 =
|
||||||
bool ok1 = false;
|
(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i);
|
||||||
bool ok2 = false;
|
if (sec1 != sec2)
|
||||||
int int1 = part1.toInt(&ok1);
|
|
||||||
int int2 = part2.toInt(&ok2);
|
|
||||||
if (ok1 && ok2)
|
|
||||||
{
|
{
|
||||||
if (int1 == int2)
|
return sec1 < sec2;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return int1 < int2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (part1 == part2)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return part1 < part2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,77 +32,35 @@ bool Util::Version::operator<=(const Util::Version &other) const
|
|||||||
}
|
}
|
||||||
bool Util::Version::operator>(const Version &other) const
|
bool Util::Version::operator>(const Version &other) const
|
||||||
{
|
{
|
||||||
QStringList parts1 = m_string.split('.');
|
const int size = qMax(m_sections.size(), other.m_sections.size());
|
||||||
QStringList parts2 = other.m_string.split('.');
|
for (int i = 0; i < size; ++i)
|
||||||
|
|
||||||
while (!parts1.isEmpty() && !parts2.isEmpty())
|
|
||||||
{
|
{
|
||||||
QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst();
|
const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i);
|
||||||
QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst();
|
const Section sec2 =
|
||||||
bool ok1 = false;
|
(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i);
|
||||||
bool ok2 = false;
|
if (sec1 != sec2)
|
||||||
int int1 = part1.toInt(&ok1);
|
|
||||||
int int2 = part2.toInt(&ok2);
|
|
||||||
if (ok1 && ok2)
|
|
||||||
{
|
{
|
||||||
if (int1 == int2)
|
return sec1 > sec2;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return int1 > int2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (part1 == part2)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return part1 > part2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool Util::Version::operator>=(const Version &other) const
|
||||||
|
{
|
||||||
|
return *this > other || *this == other;
|
||||||
|
}
|
||||||
bool Util::Version::operator==(const Version &other) const
|
bool Util::Version::operator==(const Version &other) const
|
||||||
{
|
{
|
||||||
QStringList parts1 = m_string.split('.');
|
const int size = qMax(m_sections.size(), other.m_sections.size());
|
||||||
QStringList parts2 = other.m_string.split('.');
|
for (int i = 0; i < size; ++i)
|
||||||
|
|
||||||
while (!parts1.isEmpty() && !parts2.isEmpty())
|
|
||||||
{
|
{
|
||||||
QString part1 = parts1.isEmpty() ? "0" : parts1.takeFirst();
|
const Section sec1 = (i >= m_sections.size()) ? Section("0", 0) : m_sections.at(i);
|
||||||
QString part2 = parts2.isEmpty() ? "0" : parts2.takeFirst();
|
const Section sec2 =
|
||||||
bool ok1 = false;
|
(i >= other.m_sections.size()) ? Section("0", 0) : other.m_sections.at(i);
|
||||||
bool ok2 = false;
|
if (sec1 != sec2)
|
||||||
int int1 = part1.toInt(&ok1);
|
|
||||||
int int2 = part2.toInt(&ok2);
|
|
||||||
if (ok1 && ok2)
|
|
||||||
{
|
{
|
||||||
if (int1 == int2)
|
return false;
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (part1 == part2)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,45 +71,41 @@ bool Util::Version::operator!=(const Version &other) const
|
|||||||
return !operator==(other);
|
return !operator==(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
QUrl Util::expandQMURL(const QString &in)
|
void Util::Version::parse()
|
||||||
{
|
{
|
||||||
QUrl inUrl(in);
|
m_sections.clear();
|
||||||
if (inUrl.scheme() == "github")
|
|
||||||
|
QStringList parts = m_string.split('.');
|
||||||
|
|
||||||
|
for (const auto part : parts)
|
||||||
{
|
{
|
||||||
// needed because QUrl makes the host all lower cases
|
bool ok = false;
|
||||||
const QString repo = in.mid(in.indexOf(inUrl.host(), 0, Qt::CaseInsensitive), inUrl.host().size());
|
int num = part.toInt(&ok);
|
||||||
QUrl out;
|
if (ok)
|
||||||
out.setScheme("https");
|
{
|
||||||
out.setHost("raw.github.com");
|
m_sections.append(Section(part, num));
|
||||||
out.setPath(QString("/%1/%2/%3%4")
|
}
|
||||||
.arg(inUrl.userInfo(), repo,
|
else
|
||||||
inUrl.fragment().isEmpty() ? "master" : inUrl.fragment(), inUrl.path()));
|
{
|
||||||
return out;
|
m_sections.append(Section(part));
|
||||||
}
|
}
|
||||||
else if (inUrl.scheme() == "mcf")
|
|
||||||
{
|
|
||||||
QUrl out;
|
|
||||||
out.setScheme("http");
|
|
||||||
out.setHost("www.minecraftforum.net");
|
|
||||||
out.setPath(QString("/topic/%1-").arg(inUrl.path()));
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return in;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Util::versionIsInInterval(const QString &version, const QString &interval)
|
bool Util::versionIsInInterval(const QString &version, const QString &interval)
|
||||||
{
|
{
|
||||||
if (interval.isEmpty() || version == interval)
|
return versionIsInInterval(Util::Version(version), interval);
|
||||||
|
}
|
||||||
|
bool Util::versionIsInInterval(const Version &version, const QString &interval)
|
||||||
|
{
|
||||||
|
if (interval.isEmpty() || version.toString() == interval)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interval notation is used
|
// Interval notation is used
|
||||||
QRegularExpression exp(
|
QRegularExpression exp(
|
||||||
"(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)])");
|
"(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)]),?");
|
||||||
QRegularExpressionMatch match = exp.match(interval);
|
QRegularExpressionMatch match = exp.match(interval);
|
||||||
if (match.hasMatch())
|
if (match.hasMatch())
|
||||||
{
|
{
|
||||||
@ -185,11 +117,12 @@ bool Util::versionIsInInterval(const QString &version, const QString &interval)
|
|||||||
// check if in range (bottom)
|
// check if in range (bottom)
|
||||||
if (!bottom.isEmpty())
|
if (!bottom.isEmpty())
|
||||||
{
|
{
|
||||||
if ((start == '[') && !(version >= bottom))
|
const auto bottomVersion = Util::Version(bottom);
|
||||||
|
if ((start == '[') && !(version >= bottomVersion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((start == '(') && !(version > bottom))
|
else if ((start == '(') && !(version > bottomVersion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -198,11 +131,12 @@ bool Util::versionIsInInterval(const QString &version, const QString &interval)
|
|||||||
// check if in range (top)
|
// check if in range (top)
|
||||||
if (!top.isEmpty())
|
if (!top.isEmpty())
|
||||||
{
|
{
|
||||||
if ((end == ']') && !(version <= top))
|
const auto topVersion = Util::Version(top);
|
||||||
|
if ((end == ']') && !(version <= topVersion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if ((end == ')') && !(version < top))
|
else if ((end == ')') && !(version < topVersion))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,9 @@
|
|||||||
#include "gui/pages/global/MultiMCPage.h"
|
#include "gui/pages/global/MultiMCPage.h"
|
||||||
#include "gui/pages/global/ExternalToolsPage.h"
|
#include "gui/pages/global/ExternalToolsPage.h"
|
||||||
#include "gui/pages/global/AccountListPage.h"
|
#include "gui/pages/global/AccountListPage.h"
|
||||||
#include "pages/global/ProxyPage.h"
|
#include "gui/pages/global/ProxyPage.h"
|
||||||
#include "pages/global/JavaPage.h"
|
#include "gui/pages/global/JavaPage.h"
|
||||||
#include "pages/global/MinecraftPage.h"
|
#include "gui/pages/global/MinecraftPage.h"
|
||||||
|
|
||||||
#include "gui/ConsoleWindow.h"
|
#include "gui/ConsoleWindow.h"
|
||||||
#include "pagedialog/PageDialog.h"
|
#include "pagedialog/PageDialog.h"
|
||||||
@ -91,6 +91,7 @@
|
|||||||
#include "logic/net/NetJob.h"
|
#include "logic/net/NetJob.h"
|
||||||
|
|
||||||
#include "logic/BaseInstance.h"
|
#include "logic/BaseInstance.h"
|
||||||
|
#include "logic/OneSixInstance.h"
|
||||||
#include "logic/InstanceFactory.h"
|
#include "logic/InstanceFactory.h"
|
||||||
#include "logic/MinecraftProcess.h"
|
#include "logic/MinecraftProcess.h"
|
||||||
#include "logic/OneSixUpdate.h"
|
#include "logic/OneSixUpdate.h"
|
||||||
|
@ -387,7 +387,7 @@
|
|||||||
</action>
|
</action>
|
||||||
<action name="actionEditInstance">
|
<action name="actionEditInstance">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Edit Mods</string>
|
<string>Edit Instance</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconText">
|
<property name="iconText">
|
||||||
<string>Edit Instance</string>
|
<string>Edit Instance</string>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
bool lastfirst(QModelIndexList &list, int &first, int &last)
|
bool lastfirst(QModelIndexList &list, int &first, int &last)
|
||||||
{
|
{
|
||||||
if (!list.size())
|
if (list.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
first = last = list[0].row();
|
first = last = list[0].row();
|
||||||
for (auto item : list)
|
for (auto item : list)
|
||||||
@ -37,4 +37,4 @@ void showWebsiteForMod(QWidget *parentDlg, Mod &m)
|
|||||||
QObject::tr("The mod author didn't provide a website link for this mod."),
|
QObject::tr("The mod author didn't provide a website link for this mod."),
|
||||||
QMessageBox::Warning);
|
QMessageBox::Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,15 +38,6 @@ NewInstanceDialog::NewInstanceDialog(QWidget *parent)
|
|||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
resize(minimumSizeHint());
|
resize(minimumSizeHint());
|
||||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
/*
|
|
||||||
if (!MinecraftVersionList::getMainList().isLoaded())
|
|
||||||
{
|
|
||||||
TaskDialog *taskDlg = new TaskDialog(this);
|
|
||||||
Task *loadTask = MinecraftVersionList::getMainList().getLoadTask();
|
|
||||||
loadTask->setParent(taskDlg);
|
|
||||||
taskDlg->exec(loadTask);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
setSelectedVersion(MMC->minecraftlist()->getLatestStable(), true);
|
setSelectedVersion(MMC->minecraftlist()->getLatestStable(), true);
|
||||||
InstIconKey = "infinity";
|
InstIconKey = "infinity";
|
||||||
ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
|
ui->iconButton->setIcon(MMC->icons()->getIcon(InstIconKey));
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
#include "logic/BaseVersion.h"
|
#include "logic/BaseVersion.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
|
@ -113,16 +113,10 @@ void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItemV4 &option
|
|||||||
void drawBadges(QPainter *painter, const QStyleOptionViewItemV4 &option, BaseInstance *instance)
|
void drawBadges(QPainter *painter, const QStyleOptionViewItemV4 &option, BaseInstance *instance)
|
||||||
{
|
{
|
||||||
QList<QString> pixmaps;
|
QList<QString> pixmaps;
|
||||||
for (auto flag : instance->flags())
|
const BaseInstance::InstanceFlags flags = instance->flags();
|
||||||
|
if (flags & BaseInstance::VersionBrokenFlag)
|
||||||
{
|
{
|
||||||
switch (flag)
|
pixmaps.append("broken");
|
||||||
{
|
|
||||||
case BaseInstance::VersionBrokenFlag:
|
|
||||||
pixmaps.append("broken");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// begin easter eggs
|
// begin easter eggs
|
||||||
@ -160,7 +154,7 @@ void drawBadges(QPainter *painter, const QStyleOptionViewItemV4 &option, BaseIns
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QPixmap pixmap = ListViewDelegate::requestPixmap(it.next()).scaled(
|
const QPixmap pixmap = ListViewDelegate::requestBadgePixmap(it.next()).scaled(
|
||||||
itemSide, itemSide, Qt::KeepAspectRatio, Qt::FastTransformation);
|
itemSide, itemSide, Qt::KeepAspectRatio, Qt::FastTransformation);
|
||||||
painter->drawPixmap(option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
|
painter->drawPixmap(option.rect.width() - x * itemSide + qMax(x - 1, 0) * spacing - itemSide,
|
||||||
y * itemSide + qMax(y - 1, 0) * spacing, itemSide, itemSide,
|
y * itemSide + qMax(y - 1, 0) * spacing, itemSide, itemSide,
|
||||||
@ -354,7 +348,7 @@ QSize ListViewDelegate::sizeHint(const QStyleOptionViewItem &option,
|
|||||||
return sz;
|
return sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap ListViewDelegate::requestPixmap(const QString &key)
|
QPixmap ListViewDelegate::requestBadgePixmap(const QString &key)
|
||||||
{
|
{
|
||||||
if (!m_pixmapCache.contains(key))
|
if (!m_pixmapCache.contains(key))
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@ class ListViewDelegate : public QStyledItemDelegate
|
|||||||
public:
|
public:
|
||||||
explicit ListViewDelegate(QObject *parent = 0);
|
explicit ListViewDelegate(QObject *parent = 0);
|
||||||
|
|
||||||
static QPixmap requestPixmap(const QString &key);
|
static QPixmap requestBadgePixmap(const QString &key);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
void paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <cmdutils.h>
|
#include <cmdutils.h>
|
||||||
#include "logic/minecraft/MinecraftVersionList.h"
|
#include "logic/minecraft/MinecraftVersionList.h"
|
||||||
#include "logic/icons/IconList.h"
|
#include "logic/icons/IconList.h"
|
||||||
|
#include "logic/InstanceList.h"
|
||||||
|
|
||||||
BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir,
|
BaseInstance::BaseInstance(BaseInstancePrivate *d_in, const QString &rootDir,
|
||||||
SettingsObject *settings_obj, QObject *parent)
|
SettingsObject *settings_obj, QObject *parent)
|
||||||
@ -143,10 +144,12 @@ QString BaseInstance::minecraftRoot() const
|
|||||||
|
|
||||||
InstanceList *BaseInstance::instList() const
|
InstanceList *BaseInstance::instList() const
|
||||||
{
|
{
|
||||||
if (parent()->inherits("InstanceList"))
|
return qobject_cast<InstanceList *>(parent());
|
||||||
return (InstanceList *)parent();
|
}
|
||||||
else
|
|
||||||
return NULL;
|
InstancePtr BaseInstance::getSharedPtr()
|
||||||
|
{
|
||||||
|
return instList()->getInstanceById(id());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<BaseVersionList> BaseInstance::versionList() const
|
std::shared_ptr<BaseVersionList> BaseInstance::versionList() const
|
||||||
@ -160,13 +163,12 @@ SettingsObject &BaseInstance::settings() const
|
|||||||
return *d->m_settings;
|
return *d->m_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<BaseInstance::InstanceFlag> BaseInstance::flags() const
|
BaseInstance::InstanceFlags BaseInstance::flags() const
|
||||||
{
|
{
|
||||||
I_D(const BaseInstance);
|
I_D(const BaseInstance);
|
||||||
return QSet<InstanceFlag>(d->m_flags);
|
return d->m_flags;
|
||||||
}
|
}
|
||||||
|
void BaseInstance::setFlags(const InstanceFlags &flags)
|
||||||
void BaseInstance::setFlags(const QSet<InstanceFlag> &flags)
|
|
||||||
{
|
{
|
||||||
I_D(BaseInstance);
|
I_D(BaseInstance);
|
||||||
if (flags != d->m_flags)
|
if (flags != d->m_flags)
|
||||||
@ -176,10 +178,24 @@ void BaseInstance::setFlags(const QSet<InstanceFlag> &flags)
|
|||||||
emit propertiesChanged(this);
|
emit propertiesChanged(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void BaseInstance::setFlag(const BaseInstance::InstanceFlag flag)
|
||||||
|
{
|
||||||
|
I_D(BaseInstance);
|
||||||
|
d->m_flags |= flag;
|
||||||
|
emit flagsChanged();
|
||||||
|
emit propertiesChanged(this);
|
||||||
|
}
|
||||||
|
void BaseInstance::unsetFlag(const BaseInstance::InstanceFlag flag)
|
||||||
|
{
|
||||||
|
I_D(BaseInstance);
|
||||||
|
d->m_flags &= ~flag;
|
||||||
|
emit flagsChanged();
|
||||||
|
emit propertiesChanged(this);
|
||||||
|
}
|
||||||
|
|
||||||
bool BaseInstance::canLaunch() const
|
bool BaseInstance::canLaunch() const
|
||||||
{
|
{
|
||||||
return !flags().contains(VersionBrokenFlag);
|
return !(flags() & VersionBrokenFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BaseInstance::reload()
|
bool BaseInstance::reload()
|
||||||
|
@ -34,6 +34,10 @@ class OneSixUpdate;
|
|||||||
class InstanceList;
|
class InstanceList;
|
||||||
class BaseInstancePrivate;
|
class BaseInstancePrivate;
|
||||||
|
|
||||||
|
// pointer for lazy people
|
||||||
|
class BaseInstance;
|
||||||
|
typedef std::shared_ptr<BaseInstance> InstancePtr;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Base class for instances.
|
* \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
|
||||||
@ -163,6 +167,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
InstanceList *instList() const;
|
InstanceList *instList() const;
|
||||||
|
|
||||||
|
InstancePtr getSharedPtr();
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Gets a pointer to this instance's version list.
|
* \brief Gets a pointer to this instance's version list.
|
||||||
* \return A pointer to the available version list for this instance.
|
* \return A pointer to the available version list for this instance.
|
||||||
@ -193,11 +199,14 @@ public:
|
|||||||
|
|
||||||
enum InstanceFlag
|
enum InstanceFlag
|
||||||
{
|
{
|
||||||
NoFlags = 0x00,
|
VersionBrokenFlag = 0x01,
|
||||||
VersionBrokenFlag = 0x01
|
UpdateAvailable = 0x02
|
||||||
};
|
};
|
||||||
QSet<InstanceFlag> flags() const;
|
Q_DECLARE_FLAGS(InstanceFlags, InstanceFlag)
|
||||||
void setFlags(const QSet<InstanceFlag> &flags);
|
InstanceFlags flags() const;
|
||||||
|
void setFlags(const InstanceFlags &flags);
|
||||||
|
void setFlag(const InstanceFlag flag);
|
||||||
|
void unsetFlag(const InstanceFlag flag);
|
||||||
|
|
||||||
bool canLaunch() const;
|
bool canLaunch() const;
|
||||||
|
|
||||||
@ -226,7 +235,6 @@ protected:
|
|||||||
std::shared_ptr<BaseInstancePrivate> inst_d;
|
std::shared_ptr<BaseInstancePrivate> inst_d;
|
||||||
};
|
};
|
||||||
|
|
||||||
// pointer for lazy people
|
Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>)
|
||||||
typedef std::shared_ptr<BaseInstance> InstancePtr;
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
|
Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags)
|
||||||
|
@ -31,6 +31,6 @@ public:
|
|||||||
QString m_rootDir;
|
QString m_rootDir;
|
||||||
QString m_group;
|
QString m_group;
|
||||||
std::shared_ptr<SettingsObject> m_settings;
|
std::shared_ptr<SettingsObject> m_settings;
|
||||||
QSet<BaseInstance::InstanceFlag> m_flags;
|
BaseInstance::InstanceFlags m_flags;
|
||||||
bool m_isRunning = false;
|
bool m_isRunning = false;
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
struct BaseVersion
|
struct BaseVersion
|
||||||
{
|
{
|
||||||
|
virtual ~BaseVersion() {}
|
||||||
/*!
|
/*!
|
||||||
* A string used to identify this version in config files.
|
* A string used to identify this version in config files.
|
||||||
* This should be unique within the version list or shenanigans will occur.
|
* This should be unique within the version list or shenanigans will occur.
|
||||||
|
@ -52,19 +52,19 @@ InstanceFactory::InstLoadError InstanceFactory::loadInstance(InstancePtr &inst,
|
|||||||
// FIXME: replace with a map lookup, where instance classes register their types
|
// FIXME: replace with a map lookup, where instance classes register their types
|
||||||
if (inst_type == "OneSix" || inst_type == "Nostalgia")
|
if (inst_type == "OneSix" || inst_type == "Nostalgia")
|
||||||
{
|
{
|
||||||
inst.reset(new OneSixInstance(instDir, m_settings, this));
|
inst.reset(new OneSixInstance(instDir, m_settings));
|
||||||
}
|
}
|
||||||
else if (inst_type == "Legacy")
|
else if (inst_type == "Legacy")
|
||||||
{
|
{
|
||||||
inst.reset(new LegacyInstance(instDir, m_settings, this));
|
inst.reset(new LegacyInstance(instDir, m_settings));
|
||||||
}
|
}
|
||||||
else if (inst_type == "LegacyFTB")
|
else if (inst_type == "LegacyFTB")
|
||||||
{
|
{
|
||||||
inst.reset(new LegacyFTBInstance(instDir, m_settings, this));
|
inst.reset(new LegacyFTBInstance(instDir, m_settings));
|
||||||
}
|
}
|
||||||
else if (inst_type == "OneSixFTB")
|
else if (inst_type == "OneSixFTB")
|
||||||
{
|
{
|
||||||
inst.reset(new OneSixFTBInstance(instDir, m_settings, this));
|
inst.reset(new OneSixFTBInstance(instDir, m_settings));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -82,11 +82,15 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in
|
|||||||
QLOG_DEBUG() << instDir.toUtf8();
|
QLOG_DEBUG() << instDir.toUtf8();
|
||||||
if (!rootDir.exists() && !rootDir.mkpath("."))
|
if (!rootDir.exists() && !rootDir.mkpath("."))
|
||||||
{
|
{
|
||||||
|
QLOG_ERROR() << "Can't create instance folder" << instDir;
|
||||||
return InstanceFactory::CantCreateDir;
|
return InstanceFactory::CantCreateDir;
|
||||||
}
|
}
|
||||||
auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version);
|
auto mcVer = std::dynamic_pointer_cast<MinecraftVersion>(version);
|
||||||
if (!mcVer)
|
if (!mcVer)
|
||||||
|
{
|
||||||
|
QLOG_ERROR() << "Can't create instance for non-existing MC version";
|
||||||
return InstanceFactory::NoSuchVersion;
|
return InstanceFactory::NoSuchVersion;
|
||||||
|
}
|
||||||
|
|
||||||
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
|
auto m_settings = new INISettingsObject(PathCombine(instDir, "instance.cfg"));
|
||||||
m_settings->registerSetting("InstanceType", "Legacy");
|
m_settings->registerSetting("InstanceType", "Legacy");
|
||||||
@ -94,7 +98,7 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in
|
|||||||
if (type == NormalInst)
|
if (type == NormalInst)
|
||||||
{
|
{
|
||||||
m_settings->set("InstanceType", "OneSix");
|
m_settings->set("InstanceType", "OneSix");
|
||||||
inst.reset(new OneSixInstance(instDir, m_settings, this));
|
inst.reset(new OneSixInstance(instDir, m_settings));
|
||||||
inst->setIntendedVersionId(version->descriptor());
|
inst->setIntendedVersionId(version->descriptor());
|
||||||
inst->setShouldUseCustomBaseJar(false);
|
inst->setShouldUseCustomBaseJar(false);
|
||||||
}
|
}
|
||||||
@ -103,14 +107,14 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in
|
|||||||
if(mcVer->usesLegacyLauncher())
|
if(mcVer->usesLegacyLauncher())
|
||||||
{
|
{
|
||||||
m_settings->set("InstanceType", "LegacyFTB");
|
m_settings->set("InstanceType", "LegacyFTB");
|
||||||
inst.reset(new LegacyFTBInstance(instDir, m_settings, this));
|
inst.reset(new LegacyFTBInstance(instDir, m_settings));
|
||||||
inst->setIntendedVersionId(version->descriptor());
|
inst->setIntendedVersionId(version->descriptor());
|
||||||
inst->setShouldUseCustomBaseJar(false);
|
inst->setShouldUseCustomBaseJar(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_settings->set("InstanceType", "OneSixFTB");
|
m_settings->set("InstanceType", "OneSixFTB");
|
||||||
inst.reset(new OneSixFTBInstance(instDir, m_settings, this));
|
inst.reset(new OneSixFTBInstance(instDir, m_settings));
|
||||||
inst->setIntendedVersionId(version->descriptor());
|
inst->setIntendedVersionId(version->descriptor());
|
||||||
inst->setShouldUseCustomBaseJar(false);
|
inst->setShouldUseCustomBaseJar(false);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ struct BaseVersion;
|
|||||||
class BaseInstance;
|
class BaseInstance;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* The \bInstanceFactory\b is a singleton that manages loading and creating instances.
|
* The \b InstanceFactory\b is a singleton that manages loading and creating instances.
|
||||||
*/
|
*/
|
||||||
class InstanceFactory : public QObject
|
class InstanceFactory : public QObject
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ LegacyFTBInstance::LegacyFTBInstance(const QString &rootDir, SettingsObject *set
|
|||||||
|
|
||||||
QString LegacyFTBInstance::getStatusbarDescription()
|
QString LegacyFTBInstance::getStatusbarDescription()
|
||||||
{
|
{
|
||||||
if (flags().contains(VersionBrokenFlag))
|
if (flags() & VersionBrokenFlag)
|
||||||
{
|
{
|
||||||
return "Legacy FTB: " + intendedVersionId() + " (broken)";
|
return "Legacy FTB: " + intendedVersionId() + " (broken)";
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ QString LegacyInstance::defaultCustomBaseJar() const
|
|||||||
|
|
||||||
QString LegacyInstance::getStatusbarDescription()
|
QString LegacyInstance::getStatusbarDescription()
|
||||||
{
|
{
|
||||||
if (flags().contains(VersionBrokenFlag))
|
if (flags() & VersionBrokenFlag)
|
||||||
{
|
{
|
||||||
return tr("Legacy : %1 (broken)").arg(intendedVersionId());
|
return tr("Legacy : %1 (broken)").arg(intendedVersionId());
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,26 @@
|
|||||||
#include "MMCJson.h"
|
#include "MMCJson.h"
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
QJsonDocument MMCJson::parseDocument(const QByteArray &data, const QString &what)
|
||||||
|
{
|
||||||
|
QJsonParseError error;
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(data, &error);
|
||||||
|
if (error.error != QJsonParseError::NoError)
|
||||||
|
{
|
||||||
|
throw JSONValidationError(what + " is not valid JSON: " + error.errorString() + " at " + error.offset);
|
||||||
|
}
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
bool MMCJson::ensureBoolean(const QJsonValue val, const QString what)
|
bool MMCJson::ensureBoolean(const QJsonValue val, const QString what)
|
||||||
{
|
{
|
||||||
if (!val.isBool())
|
if (!val.isBool())
|
||||||
throw JSONValidationError(what + " is not boolean");
|
throw JSONValidationError(what + " is not boolean");
|
||||||
return val.isBool();
|
return val.toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue MMCJson::ensureExists(QJsonValue val, const QString what)
|
QJsonValue MMCJson::ensureExists(QJsonValue val, const QString what)
|
||||||
@ -24,6 +37,15 @@ QJsonArray MMCJson::ensureArray(const QJsonValue val, const QString what)
|
|||||||
return val.toArray();
|
return val.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QJsonArray MMCJson::ensureArray(const QJsonDocument &val, const QString &what)
|
||||||
|
{
|
||||||
|
if (!val.isArray())
|
||||||
|
{
|
||||||
|
throw JSONValidationError(what + " is not an array");
|
||||||
|
}
|
||||||
|
return val.array();
|
||||||
|
}
|
||||||
|
|
||||||
double MMCJson::ensureDouble(const QJsonValue val, const QString what)
|
double MMCJson::ensureDouble(const QJsonValue val, const QString what)
|
||||||
{
|
{
|
||||||
if (!val.isDouble())
|
if (!val.isDouble())
|
||||||
@ -60,9 +82,36 @@ QString MMCJson::ensureString(const QJsonValue val, const QString what)
|
|||||||
return val.toString();
|
return val.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QUrl MMCJson::ensureUrl(const QJsonValue &val, const QString &what)
|
||||||
|
{
|
||||||
|
const QUrl url = QUrl(ensureString(val, what));
|
||||||
|
if (!url.isValid())
|
||||||
|
{
|
||||||
|
throw JSONValidationError(what + " is not an url");
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument MMCJson::parseFile(const QString &filename, const QString &what)
|
||||||
|
{
|
||||||
|
QFile f(filename);
|
||||||
|
if (!f.open(QFile::ReadOnly))
|
||||||
|
{
|
||||||
|
throw FileOpenError(f);
|
||||||
|
}
|
||||||
|
return parseDocument(f.readAll(), what);
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMCJson::ensureInteger(const QJsonValue val, QString what, const int def)
|
||||||
|
{
|
||||||
|
if (val.isUndefined())
|
||||||
|
return def;
|
||||||
|
return ensureInteger(val, what);
|
||||||
|
}
|
||||||
|
|
||||||
void MMCJson::writeString(QJsonObject &to, QString key, QString value)
|
void MMCJson::writeString(QJsonObject &to, QString key, QString value)
|
||||||
{
|
{
|
||||||
if(value.size())
|
if (!value.isEmpty())
|
||||||
{
|
{
|
||||||
to.insert(key, value);
|
to.insert(key, value);
|
||||||
}
|
}
|
||||||
@ -70,7 +119,7 @@ void MMCJson::writeString(QJsonObject &to, QString key, QString value)
|
|||||||
|
|
||||||
void MMCJson::writeStringList(QJsonObject &to, QString key, QStringList values)
|
void MMCJson::writeStringList(QJsonObject &to, QString key, QStringList values)
|
||||||
{
|
{
|
||||||
if(values.size())
|
if (!values.isEmpty())
|
||||||
{
|
{
|
||||||
QJsonArray array;
|
QJsonArray array;
|
||||||
for(auto value: values)
|
for(auto value: values)
|
||||||
@ -81,3 +130,13 @@ void MMCJson::writeStringList(QJsonObject &to, QString key, QStringList values)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList MMCJson::ensureStringList(const QJsonValue val, QString what)
|
||||||
|
{
|
||||||
|
const QJsonArray array = ensureArray(val, what);
|
||||||
|
QStringList out;
|
||||||
|
for (const auto value : array)
|
||||||
|
{
|
||||||
|
out.append(ensureString(value));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
@ -9,17 +9,29 @@
|
|||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
#include <QFile>
|
||||||
|
#include <memory>
|
||||||
#include "MMCError.h"
|
#include "MMCError.h"
|
||||||
|
|
||||||
class JSONValidationError : public MMCError
|
class JSONValidationError : public MMCError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JSONValidationError(QString cause) : MMCError(cause) {};
|
JSONValidationError(QString cause) : MMCError(cause) {}
|
||||||
virtual ~JSONValidationError() noexcept {}
|
};
|
||||||
|
class FileOpenError : public MMCError
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileOpenError(const QFile &file) : MMCError(QObject::tr("Error opening %1: %2").arg(file.fileName(), file.errorString())) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace MMCJson
|
namespace MMCJson
|
||||||
{
|
{
|
||||||
|
/// parses the data into a json document. throws if there's a parse error
|
||||||
|
QJsonDocument parseDocument(const QByteArray &data, const QString &what);
|
||||||
|
|
||||||
|
/// tries to open and then parses the specified file. throws if there's an error
|
||||||
|
QJsonDocument parseFile(const QString &filename, const QString &what);
|
||||||
|
|
||||||
/// make sure the value exists. throw otherwise.
|
/// make sure the value exists. throw otherwise.
|
||||||
QJsonValue ensureExists(QJsonValue val, const QString what = "value");
|
QJsonValue ensureExists(QJsonValue val, const QString what = "value");
|
||||||
|
|
||||||
@ -27,39 +39,63 @@ QJsonValue ensureExists(QJsonValue val, const QString what = "value");
|
|||||||
QJsonObject ensureObject(const QJsonValue val, const QString what = "value");
|
QJsonObject ensureObject(const QJsonValue val, const QString what = "value");
|
||||||
|
|
||||||
/// make sure the document is converted into an object. throw otherwise.
|
/// make sure the document is converted into an object. throw otherwise.
|
||||||
QJsonObject ensureObject(const QJsonDocument val, const QString what = "value");
|
QJsonObject ensureObject(const QJsonDocument val, const QString what = "document");
|
||||||
|
|
||||||
/// make sure the value is converted into an array. throw otherwise.
|
/// make sure the value is converted into an array. throw otherwise.
|
||||||
QJsonArray ensureArray(const QJsonValue val, QString what = "value");
|
QJsonArray ensureArray(const QJsonValue val, QString what = "value");
|
||||||
|
|
||||||
|
/// make sure the document is converted into an array. throw otherwise.
|
||||||
|
QJsonArray ensureArray(const QJsonDocument &val, const QString &what = "document");
|
||||||
|
|
||||||
/// make sure the value is converted into a string. throw otherwise.
|
/// make sure the value is converted into a string. throw otherwise.
|
||||||
QString ensureString(const QJsonValue val, QString what = "value");
|
QString ensureString(const QJsonValue val, QString what = "value");
|
||||||
|
|
||||||
|
/// make sure the value is converted into a string that's parseable as an url. throw otherwise.
|
||||||
|
QUrl ensureUrl(const QJsonValue &val, const QString &what = "value");
|
||||||
|
|
||||||
/// make sure the value is converted into a boolean. throw otherwise.
|
/// make sure the value is converted into a boolean. throw otherwise.
|
||||||
bool ensureBoolean(const QJsonValue val, QString what = "value");
|
bool ensureBoolean(const QJsonValue val, QString what = "value");
|
||||||
|
|
||||||
/// make sure the value is converted into an integer. throw otherwise.
|
/// make sure the value is converted into an integer. throw otherwise.
|
||||||
int ensureInteger(const QJsonValue val, QString what = "value");
|
int ensureInteger(const QJsonValue val, QString what = "value");
|
||||||
|
|
||||||
|
/// make sure the value is converted into an integer. throw otherwise. this version will return the default value if the field is undefined.
|
||||||
|
int ensureInteger(const QJsonValue val, QString what, const int def);
|
||||||
|
|
||||||
/// make sure the value is converted into a double precision floating number. throw otherwise.
|
/// make sure the value is converted into a double precision floating number. throw otherwise.
|
||||||
double ensureDouble(const QJsonValue val, QString what = "value");
|
double ensureDouble(const QJsonValue val, QString what = "value");
|
||||||
|
|
||||||
|
QStringList ensureStringList(const QJsonValue val, QString what);
|
||||||
|
|
||||||
void writeString(QJsonObject & to, QString key, QString value);
|
void writeString(QJsonObject & to, QString key, QString value);
|
||||||
|
|
||||||
void writeStringList (QJsonObject & to, QString key, QStringList values);
|
void writeStringList(QJsonObject & to, QString key, QStringList values);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void writeObjectList (QJsonObject & to, QString key, QList<T> values)
|
void writeObjectList(QJsonObject & to, QString key, QList<std::shared_ptr<T>> values)
|
||||||
{
|
{
|
||||||
if(values.size())
|
if (!values.isEmpty())
|
||||||
{
|
{
|
||||||
QJsonArray array;
|
QJsonArray array;
|
||||||
for(auto value: values)
|
for (auto value: values)
|
||||||
{
|
{
|
||||||
array.append(value->toJson());
|
array.append(value->toJson());
|
||||||
}
|
}
|
||||||
to.insert(key, array);
|
to.insert(key, array);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <typename T>
|
||||||
|
void writeObjectList(QJsonObject & to, QString key, QList<T> values)
|
||||||
|
{
|
||||||
|
if (!values.isEmpty())
|
||||||
|
{
|
||||||
|
QJsonArray array;
|
||||||
|
for (auto value: values)
|
||||||
|
{
|
||||||
|
array.append(value.toJson());
|
||||||
|
}
|
||||||
|
to.insert(key, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ bool OneSixFTBInstance::providesVersionFile() const
|
|||||||
|
|
||||||
QString OneSixFTBInstance::getStatusbarDescription()
|
QString OneSixFTBInstance::getStatusbarDescription()
|
||||||
{
|
{
|
||||||
if (flags().contains(VersionBrokenFlag))
|
if (flags() & VersionBrokenFlag)
|
||||||
{
|
{
|
||||||
return "OneSix FTB: " + intendedVersionId() + " (broken)";
|
return "OneSix FTB: " + intendedVersionId() + " (broken)";
|
||||||
}
|
}
|
||||||
|
@ -418,7 +418,7 @@ void OneSixInstance::reloadVersion()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
d->version->reload(externalPatches());
|
d->version->reload(externalPatches());
|
||||||
d->m_flags.remove(VersionBrokenFlag);
|
unsetFlag(VersionBrokenFlag);
|
||||||
emit versionReloaded();
|
emit versionReloaded();
|
||||||
}
|
}
|
||||||
catch (VersionIncomplete &error)
|
catch (VersionIncomplete &error)
|
||||||
@ -427,7 +427,7 @@ void OneSixInstance::reloadVersion()
|
|||||||
catch (MMCError &error)
|
catch (MMCError &error)
|
||||||
{
|
{
|
||||||
d->version->clear();
|
d->version->clear();
|
||||||
d->m_flags.insert(VersionBrokenFlag);
|
setFlag(VersionBrokenFlag);
|
||||||
// TODO: rethrow to show some error message(s)?
|
// TODO: rethrow to show some error message(s)?
|
||||||
emit versionReloaded();
|
emit versionReloaded();
|
||||||
throw;
|
throw;
|
||||||
@ -464,7 +464,7 @@ QString OneSixInstance::getStatusbarDescription()
|
|||||||
{
|
{
|
||||||
traits.append(tr("custom"));
|
traits.append(tr("custom"));
|
||||||
}
|
}
|
||||||
if (flags().contains(VersionBrokenFlag))
|
if (flags() & VersionBrokenFlag)
|
||||||
{
|
{
|
||||||
traits.append(tr("broken"));
|
traits.append(tr("broken"));
|
||||||
}
|
}
|
||||||
@ -569,3 +569,8 @@ QStringList OneSixInstance::extraArguments() const
|
|||||||
}
|
}
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<OneSixInstance> OneSixInstance::getSharedPtr()
|
||||||
|
{
|
||||||
|
return std::dynamic_pointer_cast<OneSixInstance>(BaseInstance::getSharedPtr());
|
||||||
|
}
|
||||||
|
@ -96,8 +96,11 @@ public:
|
|||||||
virtual bool providesVersionFile() const;
|
virtual bool providesVersionFile() const;
|
||||||
|
|
||||||
bool reload() override;
|
bool reload() override;
|
||||||
|
|
||||||
virtual QStringList extraArguments() const override;
|
virtual QStringList extraArguments() const override;
|
||||||
|
|
||||||
|
std::shared_ptr<OneSixInstance> getSharedPtr();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void versionReloaded();
|
void versionReloaded();
|
||||||
|
|
||||||
@ -105,3 +108,5 @@ private:
|
|||||||
QStringList processMinecraftArgs(AuthSessionPtr account);
|
QStringList processMinecraftArgs(AuthSessionPtr account);
|
||||||
QDir reconstructAssets(std::shared_ptr<InstanceVersion> version);
|
QDir reconstructAssets(std::shared_ptr<InstanceVersion> version);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(std::shared_ptr<OneSixInstance>)
|
||||||
|
@ -29,11 +29,11 @@ class ForgeInstaller : public BaseInstaller
|
|||||||
friend class ForgeInstallTask;
|
friend class ForgeInstallTask;
|
||||||
public:
|
public:
|
||||||
ForgeInstaller();
|
ForgeInstaller();
|
||||||
virtual ~ForgeInstaller(){};
|
virtual ~ForgeInstaller(){}
|
||||||
virtual ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
|
virtual ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
|
||||||
|
virtual QString id() const override { return "net.minecraftforge"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual QString id() const override { return "net.minecraftforge"; }
|
|
||||||
void prepare(const QString &filename, const QString &universalUrl);
|
void prepare(const QString &filename, const QString &universalUrl);
|
||||||
bool add(OneSixInstance *to) override;
|
bool add(OneSixInstance *to) override;
|
||||||
bool addLegacy(OneSixInstance *to);
|
bool addLegacy(OneSixInstance *to);
|
||||||
|
@ -38,3 +38,5 @@ struct ForgeVersion : public BaseVersion
|
|||||||
QString installer_filename;
|
QString installer_filename;
|
||||||
bool is_recommended = false;
|
bool is_recommended = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(ForgeVersionPtr)
|
||||||
|
@ -59,22 +59,10 @@ public:
|
|||||||
{
|
{
|
||||||
return javacheckers.size();
|
return javacheckers.size();
|
||||||
}
|
}
|
||||||
virtual void getProgress(qint64 ¤t, qint64 &total)
|
|
||||||
{
|
|
||||||
current = current_progress;
|
|
||||||
total = total_progress;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual QString getStatus() const
|
|
||||||
{
|
|
||||||
return m_job_name;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual bool isRunning() const
|
virtual bool isRunning() const
|
||||||
{
|
{
|
||||||
return m_running;
|
return m_running;
|
||||||
}
|
}
|
||||||
;
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
|
@ -28,13 +28,10 @@ public:
|
|||||||
|
|
||||||
void prepare(LiteLoaderVersionPtr version);
|
void prepare(LiteLoaderVersionPtr version);
|
||||||
bool add(OneSixInstance *to) override;
|
bool add(OneSixInstance *to) override;
|
||||||
|
virtual QString id() const override { return "com.mumfrey.liteloader"; }
|
||||||
|
|
||||||
ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
|
ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual QString id() const override
|
|
||||||
{
|
|
||||||
return "com.mumfrey.liteloader";
|
|
||||||
}
|
|
||||||
LiteLoaderVersionPtr m_version;
|
LiteLoaderVersionPtr m_version;
|
||||||
};
|
};
|
||||||
|
@ -111,3 +111,5 @@ protected:
|
|||||||
CacheDownloadPtr listDownload;
|
CacheDownloadPtr listDownload;
|
||||||
LiteLoaderVersionList *m_list;
|
LiteLoaderVersionList *m_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(LiteLoaderVersionPtr)
|
||||||
|
@ -264,6 +264,14 @@ QList<std::shared_ptr<OneSixLibrary> > InstanceVersion::getActiveNormalLibs()
|
|||||||
{
|
{
|
||||||
if (lib->isActive() && !lib->isNative())
|
if (lib->isActive() && !lib->isNative())
|
||||||
{
|
{
|
||||||
|
for (auto other : output)
|
||||||
|
{
|
||||||
|
if (other->rawName() == lib->rawName())
|
||||||
|
{
|
||||||
|
QLOG_WARN() << "Multiple libraries with name" << lib->rawName() << "in library list!";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
output.append(lib);
|
output.append(lib);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,10 +140,10 @@ public:
|
|||||||
QString appletClass;
|
QString appletClass;
|
||||||
|
|
||||||
/// the list of libs - both active and inactive, native and java
|
/// the list of libs - both active and inactive, native and java
|
||||||
QList<std::shared_ptr<OneSixLibrary>> libraries;
|
QList<OneSixLibraryPtr> libraries;
|
||||||
|
|
||||||
/// same, but only vanilla.
|
/// same, but only vanilla.
|
||||||
QList<std::shared_ptr<OneSixLibrary>> vanillaLibraries;
|
QList<OneSixLibraryPtr> vanillaLibraries;
|
||||||
|
|
||||||
/// traits, collected from all the version files (version files can only add)
|
/// traits, collected from all the version files (version files can only add)
|
||||||
QSet<QString> traits;
|
QSet<QString> traits;
|
||||||
|
@ -116,15 +116,10 @@ void MinecraftVersionList::loadBuiltinList()
|
|||||||
{
|
{
|
||||||
QLOG_INFO() << "Loading builtin version list.";
|
QLOG_INFO() << "Loading builtin version list.";
|
||||||
// grab the version list data from internal resources.
|
// grab the version list data from internal resources.
|
||||||
QResource versionList(":/versions/minecraft.json");
|
const QJsonDocument doc =
|
||||||
QFile filez(versionList.absoluteFilePath());
|
MMCJson::parseFile(":/versions/minecraft.json",
|
||||||
filez.open(QIODevice::ReadOnly);
|
"builtin version list");
|
||||||
auto data = filez.readAll();
|
const QJsonObject root = doc.object();
|
||||||
|
|
||||||
// parse the data as json
|
|
||||||
QJsonParseError jsonError;
|
|
||||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
|
|
||||||
QJsonObject root = jsonDoc.object();
|
|
||||||
|
|
||||||
// parse all the versions
|
// parse all the versions
|
||||||
for (const auto version : MMCJson::ensureArray(root.value("versions")))
|
for (const auto version : MMCJson::ensureArray(root.value("versions")))
|
||||||
|
@ -48,5 +48,4 @@ public:
|
|||||||
/// Constructor
|
/// Constructor
|
||||||
OneSixLibrary(RawLibraryPtr base);
|
OneSixLibrary(RawLibraryPtr base);
|
||||||
static OneSixLibraryPtr fromRawLibrary(RawLibraryPtr lib);
|
static OneSixLibraryPtr fromRawLibrary(RawLibraryPtr lib);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -288,6 +288,11 @@ static const int currentOrderFileVersion = 1;
|
|||||||
bool VersionBuilder::readOverrideOrders(OneSixInstance *instance, PatchOrder &order)
|
bool VersionBuilder::readOverrideOrders(OneSixInstance *instance, PatchOrder &order)
|
||||||
{
|
{
|
||||||
QFile orderFile(instance->instanceRoot() + "/order.json");
|
QFile orderFile(instance->instanceRoot() + "/order.json");
|
||||||
|
if (!orderFile.exists())
|
||||||
|
{
|
||||||
|
QLOG_WARN() << "Order file doesn't exist. Ignoring.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!orderFile.open(QFile::ReadOnly))
|
if (!orderFile.open(QFile::ReadOnly))
|
||||||
{
|
{
|
||||||
QLOG_ERROR() << "Couldn't open" << orderFile.fileName()
|
QLOG_ERROR() << "Couldn't open" << orderFile.fileName()
|
||||||
|
@ -22,8 +22,7 @@ int findLibraryByName(QList<OneSixLibraryPtr> haystack, const GradleSpecifier &n
|
|||||||
int retval = -1;
|
int retval = -1;
|
||||||
for (int i = 0; i < haystack.size(); ++i)
|
for (int i = 0; i < haystack.size(); ++i)
|
||||||
{
|
{
|
||||||
|
if (haystack.at(i)->rawName().matchName(needle))
|
||||||
if(haystack.at(i)->rawName().matchName(needle))
|
|
||||||
{
|
{
|
||||||
// only one is allowed.
|
// only one is allowed.
|
||||||
if (retval != -1)
|
if (retval != -1)
|
||||||
@ -67,7 +66,7 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi
|
|||||||
out->mcVersion = root.value("mcVersion").toString();
|
out->mcVersion = root.value("mcVersion").toString();
|
||||||
out->filename = filename;
|
out->filename = filename;
|
||||||
|
|
||||||
auto readString = [root](const QString & key, QString & variable)
|
auto readString = [root](const QString &key, QString &variable)
|
||||||
{
|
{
|
||||||
if (root.contains(key))
|
if (root.contains(key))
|
||||||
{
|
{
|
||||||
@ -75,15 +74,14 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto readStringRet = [root](const QString & key)->QString
|
auto readStringRet = [root](const QString &key) -> QString
|
||||||
{
|
{
|
||||||
if (root.contains(key))
|
if (root.contains(key))
|
||||||
{
|
{
|
||||||
return ensureString(root.value(key));
|
return ensureString(root.value(key));
|
||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
};
|
||||||
;
|
|
||||||
|
|
||||||
// FIXME: This should be ignored when applying.
|
// FIXME: This should be ignored when applying.
|
||||||
if (!isFTB)
|
if (!isFTB)
|
||||||
|
@ -53,16 +53,42 @@ void ByteArrayDownload::downloadError(QNetworkReply::NetworkError error)
|
|||||||
QLOG_ERROR() << "Error getting URL:" << m_url.toString().toLocal8Bit()
|
QLOG_ERROR() << "Error getting URL:" << m_url.toString().toLocal8Bit()
|
||||||
<< "Network error: " << error;
|
<< "Network error: " << error;
|
||||||
m_status = Job_Failed;
|
m_status = Job_Failed;
|
||||||
|
m_errorString = m_reply->errorString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ByteArrayDownload::downloadFinished()
|
void ByteArrayDownload::downloadFinished()
|
||||||
{
|
{
|
||||||
|
if (m_followRedirects)
|
||||||
|
{
|
||||||
|
QVariant redirect = m_reply->header(QNetworkRequest::LocationHeader);
|
||||||
|
QString redirectURL;
|
||||||
|
if(redirect.isValid())
|
||||||
|
{
|
||||||
|
redirectURL = redirect.toString();
|
||||||
|
}
|
||||||
|
// FIXME: This is a hack for https://bugreports.qt-project.org/browse/QTBUG-41061
|
||||||
|
else if(m_reply->hasRawHeader("Location"))
|
||||||
|
{
|
||||||
|
auto data = m_reply->rawHeader("Location");
|
||||||
|
if(data.size() > 2 && data[0] == '/' && data[1] == '/')
|
||||||
|
redirectURL = m_reply->url().scheme() + ":" + data;
|
||||||
|
}
|
||||||
|
if (!redirectURL.isEmpty())
|
||||||
|
{
|
||||||
|
m_url = QUrl(redirect.toString());
|
||||||
|
QLOG_INFO() << "Following redirect to " << m_url.toString();
|
||||||
|
start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the download succeeded
|
// if the download succeeded
|
||||||
if (m_status != Job_Failed)
|
if (m_status != Job_Failed)
|
||||||
{
|
{
|
||||||
// nothing went wrong...
|
// nothing went wrong...
|
||||||
m_status = Job_Finished;
|
m_status = Job_Finished;
|
||||||
m_data = m_reply->readAll();
|
m_data = m_reply->readAll();
|
||||||
|
m_content_type = m_reply->header(QNetworkRequest::ContentTypeHeader).toString();
|
||||||
m_reply.reset();
|
m_reply.reset();
|
||||||
emit succeeded(m_index_within_job);
|
emit succeeded(m_index_within_job);
|
||||||
return;
|
return;
|
||||||
|
@ -31,6 +31,10 @@ public:
|
|||||||
/// if not saving to file, downloaded data is placed here
|
/// if not saving to file, downloaded data is placed here
|
||||||
QByteArray m_data;
|
QByteArray m_data;
|
||||||
|
|
||||||
|
QString m_errorString;
|
||||||
|
|
||||||
|
bool m_followRedirects = false;
|
||||||
|
|
||||||
public
|
public
|
||||||
slots:
|
slots:
|
||||||
virtual void start();
|
virtual void start();
|
||||||
|
@ -101,6 +101,30 @@ void CacheDownload::downloadError(QNetworkReply::NetworkError error)
|
|||||||
}
|
}
|
||||||
void CacheDownload::downloadFinished()
|
void CacheDownload::downloadFinished()
|
||||||
{
|
{
|
||||||
|
if (m_followRedirects)
|
||||||
|
{
|
||||||
|
QVariant redirect = m_reply->header(QNetworkRequest::LocationHeader);
|
||||||
|
QString redirectURL;
|
||||||
|
if(redirect.isValid())
|
||||||
|
{
|
||||||
|
redirectURL = redirect.toString();
|
||||||
|
}
|
||||||
|
// FIXME: This is a hack for https://bugreports.qt-project.org/browse/QTBUG-41061
|
||||||
|
else if(m_reply->hasRawHeader("Location"))
|
||||||
|
{
|
||||||
|
auto data = m_reply->rawHeader("Location");
|
||||||
|
if(data.size() > 2 && data[0] == '/' && data[1] == '/')
|
||||||
|
redirectURL = m_reply->url().scheme() + ":" + data;
|
||||||
|
}
|
||||||
|
if (!redirectURL.isEmpty())
|
||||||
|
{
|
||||||
|
m_url = QUrl(redirect.toString());
|
||||||
|
QLOG_INFO() << "Following redirect to " << m_url.toString();
|
||||||
|
start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if the download succeeded
|
// if the download succeeded
|
||||||
if (m_status == Job_Failed)
|
if (m_status == Job_Failed)
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,8 @@ private:
|
|||||||
bool wroteAnyData = false;
|
bool wroteAnyData = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
bool m_followRedirects = false;
|
||||||
|
|
||||||
explicit CacheDownload(QUrl url, MetaEntryPtr entry);
|
explicit CacheDownload(QUrl url, MetaEntryPtr entry);
|
||||||
static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry)
|
static CacheDownloadPtr make(QUrl url, MetaEntryPtr entry)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,9 @@ public:
|
|||||||
/// the network reply
|
/// the network reply
|
||||||
std::shared_ptr<QNetworkReply> m_reply;
|
std::shared_ptr<QNetworkReply> m_reply;
|
||||||
|
|
||||||
|
/// the content of the content-type header
|
||||||
|
QString m_content_type;
|
||||||
|
|
||||||
/// source URL
|
/// source URL
|
||||||
QUrl m_url;
|
QUrl m_url;
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ class NetJob : public ProgressProvider
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit NetJob(QString job_name) : ProgressProvider(), m_job_name(job_name) {};
|
explicit NetJob(QString job_name) : ProgressProvider(), m_job_name(job_name) {}
|
||||||
virtual ~NetJob() {};
|
virtual ~NetJob() {}
|
||||||
template <typename T> bool addNetAction(T action)
|
template <typename T> bool addNetAction(T action)
|
||||||
{
|
{
|
||||||
NetActionPtr base = std::static_pointer_cast<NetAction>(action);
|
NetActionPtr base = std::static_pointer_cast<NetAction>(action);
|
||||||
@ -62,7 +62,10 @@ public:
|
|||||||
{
|
{
|
||||||
return downloads[index];
|
return downloads[index];
|
||||||
}
|
}
|
||||||
;
|
const NetActionPtr at(const int index)
|
||||||
|
{
|
||||||
|
return downloads.at(index);
|
||||||
|
}
|
||||||
NetActionPtr first()
|
NetActionPtr first()
|
||||||
{
|
{
|
||||||
if (downloads.size())
|
if (downloads.size())
|
||||||
@ -73,21 +76,10 @@ public:
|
|||||||
{
|
{
|
||||||
return downloads.size();
|
return downloads.size();
|
||||||
}
|
}
|
||||||
virtual void getProgress(qint64 ¤t, qint64 &total)
|
|
||||||
{
|
|
||||||
current = current_progress;
|
|
||||||
total = total_progress;
|
|
||||||
}
|
|
||||||
;
|
|
||||||
virtual QString getStatus() const
|
|
||||||
{
|
|
||||||
return m_job_name;
|
|
||||||
}
|
|
||||||
virtual bool isRunning() const
|
virtual bool isRunning() const
|
||||||
{
|
{
|
||||||
return m_running;
|
return m_running;
|
||||||
}
|
}
|
||||||
;
|
|
||||||
QStringList getFailedFiles();
|
QStringList getFailedFiles();
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
|
@ -32,9 +32,7 @@ signals:
|
|||||||
void status(QString status);
|
void status(QString status);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~ProgressProvider() {};
|
virtual ~ProgressProvider() {}
|
||||||
virtual QString getStatus() const = 0;
|
|
||||||
virtual void getProgress(qint64 ¤t, qint64 &total) = 0;
|
|
||||||
virtual bool isRunning() const = 0;
|
virtual bool isRunning() const = 0;
|
||||||
public
|
public
|
||||||
slots:
|
slots:
|
||||||
|
@ -1,31 +1,7 @@
|
|||||||
#include "SequentialTask.h"
|
#include "SequentialTask.h"
|
||||||
|
|
||||||
SequentialTask::SequentialTask(QObject *parent) :
|
SequentialTask::SequentialTask(QObject *parent) : Task(parent), m_currentIndex(-1)
|
||||||
Task(parent), m_currentIndex(-1)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QString SequentialTask::getStatus() const
|
|
||||||
{
|
|
||||||
if (m_queue.isEmpty() || m_currentIndex >= m_queue.size())
|
|
||||||
{
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
return m_queue.at(m_currentIndex)->getStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SequentialTask::getProgress(qint64 ¤t, qint64 &total)
|
|
||||||
{
|
|
||||||
current = 0;
|
|
||||||
total = 0;
|
|
||||||
for (int i = 0; i < m_queue.size(); ++i)
|
|
||||||
{
|
|
||||||
qint64 subCurrent, subTotal;
|
|
||||||
m_queue.at(i)->getProgress(subCurrent, subTotal);
|
|
||||||
current += subCurrent;
|
|
||||||
total += subTotal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequentialTask::addTask(std::shared_ptr<ProgressProvider> task)
|
void SequentialTask::addTask(std::shared_ptr<ProgressProvider> task)
|
||||||
@ -55,10 +31,9 @@ void SequentialTask::startNext()
|
|||||||
std::shared_ptr<ProgressProvider> next = m_queue[m_currentIndex];
|
std::shared_ptr<ProgressProvider> next = m_queue[m_currentIndex];
|
||||||
connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
|
connect(next.get(), SIGNAL(failed(QString)), this, SLOT(subTaskFailed(QString)));
|
||||||
connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
|
connect(next.get(), SIGNAL(status(QString)), this, SLOT(subTaskStatus(QString)));
|
||||||
connect(next.get(), SIGNAL(progress(qint64,qint64)), this, SLOT(subTaskProgress()));
|
connect(next.get(), SIGNAL(progress(qint64, qint64)), this, SLOT(subTaskProgress(qint64, qint64)));
|
||||||
connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
|
connect(next.get(), SIGNAL(succeeded()), this, SLOT(startNext()));
|
||||||
next->start();
|
next->start();
|
||||||
emit status(getStatus());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SequentialTask::subTaskFailed(const QString &msg)
|
void SequentialTask::subTaskFailed(const QString &msg)
|
||||||
@ -69,16 +44,16 @@ void SequentialTask::subTaskStatus(const QString &msg)
|
|||||||
{
|
{
|
||||||
setStatus(msg);
|
setStatus(msg);
|
||||||
}
|
}
|
||||||
void SequentialTask::subTaskProgress()
|
void SequentialTask::subTaskProgress(qint64 current, qint64 total)
|
||||||
{
|
{
|
||||||
qint64 current, total;
|
if(total == 0)
|
||||||
getProgress(current, total);
|
|
||||||
if (total == 0)
|
|
||||||
{
|
{
|
||||||
setProgress(0);
|
setProgress(0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
auto dcurrent = (double) current;
|
||||||
{
|
auto dtotal = (double) total;
|
||||||
setProgress(100 * current / total);
|
auto partial = ((dcurrent / dtotal) * 100.0f)/* / double(m_queue.size())*/;
|
||||||
}
|
// auto bigpartial = double(m_currentIndex) * 100.0f / double(m_queue.size());
|
||||||
|
setProgress(partial);
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,6 @@ class SequentialTask : public Task
|
|||||||
public:
|
public:
|
||||||
explicit SequentialTask(QObject *parent = 0);
|
explicit SequentialTask(QObject *parent = 0);
|
||||||
|
|
||||||
virtual QString getStatus() const;
|
|
||||||
virtual void getProgress(qint64 ¤t, qint64 &total);
|
|
||||||
|
|
||||||
void addTask(std::shared_ptr<ProgressProvider> task);
|
void addTask(std::shared_ptr<ProgressProvider> task);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -24,7 +21,7 @@ slots:
|
|||||||
void startNext();
|
void startNext();
|
||||||
void subTaskFailed(const QString &msg);
|
void subTaskFailed(const QString &msg);
|
||||||
void subTaskStatus(const QString &msg);
|
void subTaskStatus(const QString &msg);
|
||||||
void subTaskProgress();
|
void subTaskProgress(qint64 current, qint64 total);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQueue<std::shared_ptr<ProgressProvider> > m_queue;
|
QQueue<std::shared_ptr<ProgressProvider> > m_queue;
|
||||||
|
@ -20,29 +20,16 @@ Task::Task(QObject *parent) : ProgressProvider(parent)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString Task::getStatus() const
|
|
||||||
{
|
|
||||||
return m_statusString;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Task::setStatus(const QString &new_status)
|
void Task::setStatus(const QString &new_status)
|
||||||
{
|
{
|
||||||
m_statusString = new_status;
|
|
||||||
emit status(new_status);
|
emit status(new_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Task::setProgress(int new_progress)
|
void Task::setProgress(int new_progress)
|
||||||
{
|
{
|
||||||
m_progress = new_progress;
|
|
||||||
emit progress(new_progress, 100);
|
emit progress(new_progress, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Task::getProgress(qint64 ¤t, qint64 &total)
|
|
||||||
{
|
|
||||||
current = m_progress;
|
|
||||||
total = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Task::start()
|
void Task::start()
|
||||||
{
|
{
|
||||||
m_running = true;
|
m_running = true;
|
||||||
@ -61,6 +48,7 @@ void Task::emitFailed(QString reason)
|
|||||||
|
|
||||||
void Task::emitSucceeded()
|
void Task::emitSucceeded()
|
||||||
{
|
{
|
||||||
|
if (!m_running) { return; } // Don't succeed twice.
|
||||||
m_running = false;
|
m_running = false;
|
||||||
m_succeeded = true;
|
m_succeeded = true;
|
||||||
QLOG_INFO() << "Task succeeded";
|
QLOG_INFO() << "Task succeeded";
|
||||||
|
@ -26,8 +26,6 @@ public:
|
|||||||
explicit Task(QObject *parent = 0);
|
explicit Task(QObject *parent = 0);
|
||||||
virtual ~Task() {};
|
virtual ~Task() {};
|
||||||
|
|
||||||
virtual QString getStatus() const;
|
|
||||||
virtual void getProgress(qint64 ¤t, qint64 &total);
|
|
||||||
virtual bool isRunning() const;
|
virtual bool isRunning() const;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -50,6 +48,7 @@ slots:
|
|||||||
protected:
|
protected:
|
||||||
virtual void executeTask() = 0;
|
virtual void executeTask() = 0;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
virtual void emitSucceeded();
|
virtual void emitSucceeded();
|
||||||
virtual void emitFailed(QString reason);
|
virtual void emitFailed(QString reason);
|
||||||
|
|
||||||
@ -59,9 +58,8 @@ slots:
|
|||||||
void setProgress(int progress);
|
void setProgress(int progress);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QString m_statusString;
|
|
||||||
int m_progress = 0;
|
|
||||||
bool m_running = false;
|
bool m_running = false;
|
||||||
bool m_succeeded = false;
|
bool m_succeeded = false;
|
||||||
QString m_failReason = "";
|
QString m_failReason = "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public:
|
|||||||
|
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
|
|
||||||
virtual void registerSettings(SettingsObject *settings) = 0;
|
virtual void registerSettings(std::shared_ptr<SettingsObject> settings) = 0;
|
||||||
|
|
||||||
virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0;
|
virtual BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) = 0;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ void JProfiler::beginProfilingImpl(MinecraftProcess *process)
|
|||||||
m_profilerProcess = profiler;
|
m_profilerProcess = profiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JProfilerFactory::registerSettings(SettingsObject *settings)
|
void JProfilerFactory::registerSettings(std::shared_ptr<SettingsObject> settings)
|
||||||
{
|
{
|
||||||
settings->registerSetting("JProfilerPath");
|
settings->registerSetting("JProfilerPath");
|
||||||
settings->registerSetting("JProfilerPort", 42042);
|
settings->registerSetting("JProfilerPort", 42042);
|
||||||
|
@ -16,7 +16,7 @@ class JProfilerFactory : public BaseProfilerFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name() const override { return "JProfiler"; }
|
QString name() const override { return "JProfiler"; }
|
||||||
void registerSettings(SettingsObject *settings) override;
|
void registerSettings(std::shared_ptr<SettingsObject> settings) override;
|
||||||
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
||||||
bool check(QString *error) override;
|
bool check(QString *error) override;
|
||||||
bool check(const QString &path, QString *error) override;
|
bool check(const QString &path, QString *error) override;
|
||||||
|
@ -37,7 +37,7 @@ void JVisualVM::beginProfilingImpl(MinecraftProcess *process)
|
|||||||
m_profilerProcess = profiler;
|
m_profilerProcess = profiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JVisualVMFactory::registerSettings(SettingsObject *settings)
|
void JVisualVMFactory::registerSettings(std::shared_ptr<SettingsObject> settings)
|
||||||
{
|
{
|
||||||
QString defaultValue = QStandardPaths::findExecutable("jvisualvm");
|
QString defaultValue = QStandardPaths::findExecutable("jvisualvm");
|
||||||
if (defaultValue.isNull())
|
if (defaultValue.isNull())
|
||||||
|
@ -16,7 +16,7 @@ class JVisualVMFactory : public BaseProfilerFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name() const override { return "JVisualVM"; }
|
QString name() const override { return "JVisualVM"; }
|
||||||
void registerSettings(SettingsObject *settings) override;
|
void registerSettings(std::shared_ptr<SettingsObject> settings) override;
|
||||||
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
||||||
bool check(QString *error) override;
|
bool check(QString *error) override;
|
||||||
bool check(const QString &path, QString *error) override;
|
bool check(const QString &path, QString *error) override;
|
||||||
|
@ -43,7 +43,7 @@ void MCEditTool::runImpl()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCEditFactory::registerSettings(SettingsObject *settings)
|
void MCEditFactory::registerSettings(std::shared_ptr<SettingsObject> settings)
|
||||||
{
|
{
|
||||||
settings->registerSetting("MCEditPath");
|
settings->registerSetting("MCEditPath");
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ class MCEditFactory : public BaseDetachedToolFactory
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QString name() const override { return "MCEdit"; }
|
QString name() const override { return "MCEdit"; }
|
||||||
void registerSettings(SettingsObject *settings) override;
|
void registerSettings(std::shared_ptr<SettingsObject> settings) override;
|
||||||
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
BaseExternalTool *createTool(InstancePtr instance, QObject *parent = 0) override;
|
||||||
bool check(QString *error) override;
|
bool check(QString *error) override;
|
||||||
bool check(const QString &path, QString *error) override;
|
bool check(const QString &path, QString *error) override;
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
<file>herobrine.png</file>
|
<file>herobrine.png</file>
|
||||||
<file>derp.png</file>
|
<file>derp.png</file>
|
||||||
|
|
||||||
|
<!-- Update. GPLv2, https://code.google.com/p/gnome-colors/ -->
|
||||||
|
<file>updateavailable.png</file>
|
||||||
|
|
||||||
<!-- Source: http://www.iconarchive.com/show/cat-icons-by-fasticon/Cat-Brown-icon.html -->
|
<!-- Source: http://www.iconarchive.com/show/cat-icons-by-fasticon/Cat-Brown-icon.html -->
|
||||||
<file>kitten.png</file>
|
<file>kitten.png</file>
|
||||||
<!-- Source: http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/Filesystem-file-broken-icon.html -->
|
<!-- Source: http://www.iconarchive.com/show/crystal-clear-icons-by-everaldo/Filesystem-file-broken-icon.html -->
|
||||||
|
BIN
resources/instances/updateavailable.png
Normal file
BIN
resources/instances/updateavailable.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
@ -24,6 +24,7 @@ endmacro()
|
|||||||
add_unit_test(pathutils tst_pathutils.cpp)
|
add_unit_test(pathutils tst_pathutils.cpp)
|
||||||
add_unit_test(gradlespecifier tst_gradlespecifier.cpp)
|
add_unit_test(gradlespecifier tst_gradlespecifier.cpp)
|
||||||
add_unit_test(userutils tst_userutils.cpp)
|
add_unit_test(userutils tst_userutils.cpp)
|
||||||
|
add_unit_test(modutils tst_modutils.cpp)
|
||||||
add_unit_test(inifile tst_inifile.cpp)
|
add_unit_test(inifile tst_inifile.cpp)
|
||||||
add_unit_test(UpdateChecker tst_UpdateChecker.cpp)
|
add_unit_test(UpdateChecker tst_UpdateChecker.cpp)
|
||||||
add_unit_test(DownloadUpdateTask tst_DownloadUpdateTask.cpp)
|
add_unit_test(DownloadUpdateTask tst_DownloadUpdateTask.cpp)
|
||||||
|
@ -9,29 +9,30 @@
|
|||||||
|
|
||||||
#include "test_config.h"
|
#include "test_config.h"
|
||||||
|
|
||||||
struct TestsInternal
|
class TestsInternal
|
||||||
{
|
{
|
||||||
static QByteArray readFile(const QString &fileName)
|
public:
|
||||||
{
|
static QByteArray readFile(const QString &fileName)
|
||||||
QFile f(fileName);
|
{
|
||||||
f.open(QFile::ReadOnly);
|
QFile f(fileName);
|
||||||
return f.readAll();
|
f.open(QFile::ReadOnly);
|
||||||
}
|
return f.readAll();
|
||||||
static QString readFileUtf8(const QString &fileName)
|
}
|
||||||
{
|
static QString readFileUtf8(const QString &fileName)
|
||||||
return QString::fromUtf8(readFile(fileName));
|
{
|
||||||
}
|
return QString::fromUtf8(readFile(fileName));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MULTIMC_GET_TEST_FILE(file) TestsInternal::readFile(QFINDTESTDATA( file ))
|
#define MULTIMC_GET_TEST_FILE(file) TestsInternal::readFile(QFINDTESTDATA(file))
|
||||||
#define MULTIMC_GET_TEST_FILE_UTF8(file) TestsInternal::readFileUtf8(QFINDTESTDATA( file ))
|
#define MULTIMC_GET_TEST_FILE_UTF8(file) TestsInternal::readFileUtf8(QFINDTESTDATA(file))
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# define _MMC_EXTRA_ARGV , "-platform", "offscreen"
|
#define _MMC_EXTRA_ARGV , "-platform", "offscreen"
|
||||||
# define _MMC_EXTRA_ARGC 2
|
#define _MMC_EXTRA_ARGC 2
|
||||||
#else
|
#else
|
||||||
# define _MMC_EXTRA_ARGV
|
#define _MMC_EXTRA_ARGV
|
||||||
# define _MMC_EXTRA_ARGC 0
|
#define _MMC_EXTRA_ARGC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
153
tests/tst_modutils.cpp
Normal file
153
tests/tst_modutils.cpp
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QTest>
|
||||||
|
|
||||||
|
#include "modutils.h"
|
||||||
|
#include "TestUtil.h"
|
||||||
|
|
||||||
|
class ModUtilsTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
void setupVersions()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("first");
|
||||||
|
QTest::addColumn<QString>("second");
|
||||||
|
QTest::addColumn<bool>("lessThan");
|
||||||
|
QTest::addColumn<bool>("equal");
|
||||||
|
|
||||||
|
QTest::newRow("equal, explicit") << "1.2.0" << "1.2.0" << false << true;
|
||||||
|
QTest::newRow("equal, implicit 1") << "1.2" << "1.2.0" << false << true;
|
||||||
|
QTest::newRow("equal, implicit 2") << "1.2.0" << "1.2" << false << true;
|
||||||
|
QTest::newRow("equal, two-digit") << "1.42" << "1.42" << false << true;
|
||||||
|
|
||||||
|
QTest::newRow("lessThan, explicit 1") << "1.2.0" << "1.2.1" << true << false;
|
||||||
|
QTest::newRow("lessThan, explicit 2") << "1.2.0" << "1.3.0" << true << false;
|
||||||
|
QTest::newRow("lessThan, explicit 3") << "1.2.0" << "2.2.0" << true << false;
|
||||||
|
QTest::newRow("lessThan, implicit 1") << "1.2" << "1.2.1" << true << false;
|
||||||
|
QTest::newRow("lessThan, implicit 2") << "1.2" << "1.3.0" << true << false;
|
||||||
|
QTest::newRow("lessThan, implicit 3") << "1.2" << "2.2.0" << true << false;
|
||||||
|
QTest::newRow("lessThan, two-digit") << "1.41" << "1.42" << true << false;
|
||||||
|
|
||||||
|
QTest::newRow("greaterThan, explicit 1") << "1.2.1" << "1.2.0" << false << false;
|
||||||
|
QTest::newRow("greaterThan, explicit 2") << "1.3.0" << "1.2.0" << false << false;
|
||||||
|
QTest::newRow("greaterThan, explicit 3") << "2.2.0" << "1.2.0" << false << false;
|
||||||
|
QTest::newRow("greaterThan, implicit 1") << "1.2.1" << "1.2" << false << false;
|
||||||
|
QTest::newRow("greaterThan, implicit 2") << "1.3.0" << "1.2" << false << false;
|
||||||
|
QTest::newRow("greaterThan, implicit 3") << "2.2.0" << "1.2" << false << false;
|
||||||
|
QTest::newRow("greaterThan, two-digit") << "1.42" << "1.41" << false << false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
void cleanupTestCase()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_versionIsInInterval_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("version");
|
||||||
|
QTest::addColumn<QString>("interval");
|
||||||
|
QTest::addColumn<bool>("result");
|
||||||
|
|
||||||
|
QTest::newRow("empty, true") << "1.2.3" << "" << true;
|
||||||
|
QTest::newRow("one version, true") << "1.2.3" << "1.2.3" << true;
|
||||||
|
QTest::newRow("one version, false") << "1.2.3" << "1.2.2" << false;
|
||||||
|
|
||||||
|
QTest::newRow("one version inclusive <-> infinity, true") << "1.2.3" << "[1.2.3,)" << true;
|
||||||
|
QTest::newRow("one version exclusive <-> infinity, true") << "1.2.3" << "(1.2.2,)" << true;
|
||||||
|
QTest::newRow("one version inclusive <-> infitity, false") << "1.2.3" << "[1.2.4,)" << false;
|
||||||
|
QTest::newRow("one version exclusive <-> infinity, false") << "1.2.3" << "(1.2.3,)" << false;
|
||||||
|
|
||||||
|
QTest::newRow("infinity <-> one version inclusive, true") << "1.2.3" << "(,1.2.3]" << true;
|
||||||
|
QTest::newRow("infinity <-> one version exclusive, true") << "1.2.3" << "(,1.2.4)" << true;
|
||||||
|
QTest::newRow("infinity <-> one version inclusive, false") << "1.2.3" << "(,1.2.2]" << false;
|
||||||
|
QTest::newRow("infinity <-> one version exclusive, false") << "1.2.3" << "(,1.2.3)" << false;
|
||||||
|
|
||||||
|
QTest::newRow("inclusive <-> inclusive, true") << "1.2.3" << "[1.2.2,1.2.3]" << true;
|
||||||
|
QTest::newRow("inclusive <-> exclusive, true") << "1.2.3" << "[1.2.3,1.2.4)" << true;
|
||||||
|
QTest::newRow("exclusive <-> inclusive, true") << "1.2.3" << "(1.2.2,1.2.3]" << true;
|
||||||
|
QTest::newRow("exclusive <-> exclusive, true") << "1.2.3" << "(1.2.2,1.2.4)" << true;
|
||||||
|
QTest::newRow("inclusive <-> inclusive, false") << "1.2.3" << "[1.0.0,1.2.2]" << false;
|
||||||
|
QTest::newRow("inclusive <-> exclusive, false") << "1.2.3" << "[1.0.0,1.2.3)" << false;
|
||||||
|
QTest::newRow("exclusive <-> inclusive, false") << "1.2.3" << "(1.2.3,2.0.0]" << false;
|
||||||
|
QTest::newRow("exclusive <-> exclusive, false") << "1.2.3" << "(1.0.0,1.2.3)" << false;
|
||||||
|
}
|
||||||
|
void test_versionIsInInterval()
|
||||||
|
{
|
||||||
|
QFETCH(QString, version);
|
||||||
|
QFETCH(QString, interval);
|
||||||
|
QFETCH(bool, result);
|
||||||
|
|
||||||
|
QCOMPARE(Util::versionIsInInterval(version, interval), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_versionCompareLessThan_data()
|
||||||
|
{
|
||||||
|
setupVersions();
|
||||||
|
}
|
||||||
|
void test_versionCompareLessThan()
|
||||||
|
{
|
||||||
|
QFETCH(QString, first);
|
||||||
|
QFETCH(QString, second);
|
||||||
|
QFETCH(bool, lessThan);
|
||||||
|
QFETCH(bool, equal);
|
||||||
|
|
||||||
|
const auto v1 = Util::Version(first);
|
||||||
|
const auto v2 = Util::Version(second);
|
||||||
|
|
||||||
|
QCOMPARE(v1 < v2, lessThan);
|
||||||
|
}
|
||||||
|
void test_versionCompareGreaterThan_data()
|
||||||
|
{
|
||||||
|
setupVersions();
|
||||||
|
}
|
||||||
|
void test_versionCompareGreaterThan()
|
||||||
|
{
|
||||||
|
QFETCH(QString, first);
|
||||||
|
QFETCH(QString, second);
|
||||||
|
QFETCH(bool, lessThan);
|
||||||
|
QFETCH(bool, equal);
|
||||||
|
|
||||||
|
const auto v1 = Util::Version(first);
|
||||||
|
const auto v2 = Util::Version(second);
|
||||||
|
|
||||||
|
QCOMPARE(v1 > v2, !lessThan && !equal);
|
||||||
|
}
|
||||||
|
void test_versionCompareEqual_data()
|
||||||
|
{
|
||||||
|
setupVersions();
|
||||||
|
}
|
||||||
|
void test_versionCompareEqual()
|
||||||
|
{
|
||||||
|
QFETCH(QString, first);
|
||||||
|
QFETCH(QString, second);
|
||||||
|
QFETCH(bool, lessThan);
|
||||||
|
QFETCH(bool, equal);
|
||||||
|
|
||||||
|
const auto v1 = Util::Version(first);
|
||||||
|
const auto v2 = Util::Version(second);
|
||||||
|
|
||||||
|
QCOMPARE(v1 == v2, equal);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN(ModUtilsTest)
|
||||||
|
|
||||||
|
#include "tst_modutils.moc"
|
Loading…
Reference in New Issue
Block a user